Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende Überarbeitung | ||
software:deep:dev:crosscompiler:cfr [2014-02-10 13:20] – graf | software:deep:dev:crosscompiler:cfr [Unbekanntes Datum] (aktuell) – gelöscht - Externe Bearbeitung (Unbekanntes Datum) 127.0.0.1 | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
- | ====== Class File Reader ====== | ||
- | ===== Course of Action ===== | ||
- | ==== Build ==== | ||
- | System classes as indicated by the configuration are loaded first. After this the root classes are loaded. For each class all other classes which are referenced in the constant pool and which have a class file (arrays may be referenced but have no class files) are kept in an import list and subsequently loaded. \\ | ||
- | System classes are classes like the kernel or heap. They must be loaded in any case. | ||
- | |||
- | ==== Constant Pool ==== | ||
- | In the first run all entries are read. During the second run objects of type //item// are created if necessary and references are resolved. For every class, method or field an object is inserted in the object directory. In the third run the constant pool is reduced and includes now only references to the object directory.\\ | ||
- | [{{ .: | ||
- | Each item has the fields //index//, //offset// and // | ||
- | |||
- | Special consideration has to be paided for references to arrays. If an array is created as in | ||
- | <code java> | ||
- | ClassA[] obj = new ClassA[]; | ||
- | </ | ||
- | there will be a reference to // | ||
- | <code java> | ||
- | Object obj = new ClassA[]; | ||
- | </ | ||
- | and in the Bytecode we only have //anewarray ClassA//. For this case we must make sure that an array descriptor is created as well. The same is true for arrays of base types.\\ | ||
- | For each class an array // | ||
- | |||
- | ==== Bytecode Analysis ==== | ||
- | The Bytecode of all methods are analyzed and the attribute flags of all classes and methods are properly set. For this purpose each object of the object directory has a field // | ||
- | <code java> | ||
- | byte apfPublic = 0, | ||
- | apfPrivate = 1, | ||
- | apfProtected = 2, | ||
- | apfStatic = 3, | ||
- | ... | ||
- | byte dpfBase = 15; | ||
- | dpfClassLoaded = dpfBase+0, | ||
- | dpfRootClass = dpfBase+1, | ||
- | ... | ||
- | </ | ||
- | For instance, each class will be marked if an instance of it is ever created or a class will be marked if one of its methods is ever called with // | ||
- | |||
- | ==== Stubs ==== | ||
- | When reading the constant pool of a class many fields or methods of other classes are needed for whom entries in the object directory were not yet created. For these stubs are created. At the end all stubs have to be replaced by their real object. | ||
- | |||
- | ==== Finish ==== | ||
- | At the end all stubs have to be replaced, miscellaneous class information is added, fields and methods are sorted. | ||
- | |||
- | ===== Classes, Interfaces and Arrays ===== | ||
- | Generally all items are linked in lists (using the field //next//). All root classes are listed in a array // | ||
- | * // | ||
- | * // | ||
- | * // | ||
- | * typeChkInterfaces: | ||
- | |||
- | There a a special case where an interface nedds a type descriptor. This happens when type testing for an array of interfaces, see [[.: | ||
- | <code java> | ||
- | Object o = new InterfaceA[10]; | ||
- | if (o instanceof InterfaceA[]) ... | ||
- | </ | ||
- | Such interfaces are listed and linked with the field // | ||
- | |||
- | [{{ .: | ||
- | |||
- | Arrays have // | ||
- | \\ | ||
- | \\ | ||
- | |||
- | |||
- | ===== Fields ===== | ||
- | When parsing the constant pool all fields are denoted with the tag // | ||
- | |||
- | The class file reader adds all fields of a class in three linked lists: | ||
- | * Instance fields -> Class.instFields | ||
- | * Class fields -> Class.classFields | ||
- | * Constant fields -> Class.constFields (don't go into the target image!) | ||
- | The three lists are again linked among each other. The last entry of the // | ||
- | * First instance field which is a reference -> firstInstReference | ||
- | * First class field which is a reference -> firstClassReference | ||
- | |||
- | The figure below shows an example for a class with two instance and two class fields as well as two constant fields. One of the instance fields is of a primitive type and one is a reference. Both class fields are of type reference. | ||
- | |||
- | [{{ .: | ||
- | \\ | ||
- | For efficiency reasons all fields of an object or a class (defined as //static//) with the same size in memory should be placed together, which is done by sorting. For this purpose there are three static arrays in // | ||
- | |||
- | ===== Constants ===== | ||
- | When parsing the constant pool all constants can be found in there. According to their tag different objects are created for them. | ||
- | * Integer, Long, Float, Double: //new StdConstant//, | ||
- | * String: //new StringLiteral//, | ||
- | |||
- | When parsing the fields a check is made whether the attribute // | ||
- | Let's take a look at an example: | ||
- | <code java> | ||
- | static final int a = 1; | ||
- | </ | ||
- | For the class field //a// an object of type // | ||
- | Important: The assignment of a value to a variable declared as //final// can be made when declaring it or in the constructor. This leads to the following cases. | ||
- | <code java> | ||
- | class ClassA { | ||
- | static final int a; | ||
- | static final int b = 2000000; | ||
- | static final String str1 = " | ||
- | static final String[] str2 = {" | ||
- | static final Object obj = new Object(); | ||
- | final int c = 3000000; | ||
- | final int d; | ||
- | static final double e = 0.1; | ||
- | static final double[] f = {0.5, 0,6}; | ||
- | |||
- | ClassA() {d = 4000000;} | ||
- | | ||
- | static {a = 2000000;} | ||
- | } | ||
- | |||
- | interface ITest3 { | ||
- | int x = 100; | ||
- | String str3 = " | ||
- | String[] str4 = {" | ||
- | } | ||
- | </ | ||
- | * Case a: Attributes //static// and //final// are set. In the constant pool we have a=(class=ClassA, | ||
- | * Case b: Is not listed as field at all. Present as constant only in the constant pool. An object // | ||
- | * Case obj: Attributes //static// and //final// are set. In the constant pool we have c=(class=ClassA, | ||
- | * Case str2 and f: Attributes //static// and //final// are set. In // | ||
- | * Case c: //final// is set. In the constant pool we have c=(classe=ClassA, | ||
- | * Case d: //final// is set. In the constant pool we have d=(class=ClassA, | ||
- | * Case e: same as case b | ||
- | |||
- | For interfaces we get: | ||
- | * Case x: same as case b | ||
- | * Case str3: same as case str1 | ||
- | * Case str4: same as case str2 | ||
- | |||
- | Important: When generating the SSA loading of a constant is translated with // | ||
- | |||
- | ===== Methods ===== | ||
- | All reference types can have methods, even arrays as they inherit from // |