Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Nächste Überarbeitung
Vorhergehende Überarbeitung
software:deep:dev:crosscompiler:arrays [2013-12-16 11:41] – Externe Bearbeitung 127.0.0.1software:deep:dev:crosscompiler:arrays [Unbekanntes Datum] (aktuell) – gelöscht - Externe Bearbeitung (Unbekanntes Datum) 127.0.0.1
Zeile 1: Zeile 1:
-====== Arrays ====== 
-The following figure demonstrates how arrays are implemented in the memory.  
-[{{ .:array1.png?250&direct | //Implementation of an array//}}] 
-An array extends //java/lang/object//. The field //Tag// points to the type descriptor of this array (//[ClassA// for this example). The single array elements themselves are of type //ClassA// and have a //Tag// which points to the type descriptor of //ClassA//. For this reason arrays of base types like ([B, [S ...) need a einen class descritor as well. \\ 
-The field //length// denotes the number of elements of the array (16 bit). //heap// is used for the garbage collection ([[deep:rts:heap|Heap Manager and Garbage Collection]]). In between there is a byte which contains an array bit. This is used for type checking. The //P// bit is for garbage collection. It is set for arrays of primitive types\\ 
-When accessing array elements the code generator inserts code to check if the element index is in the range 0 to //length//.\\ 
-If the field //length// is used in Java the Bytecode instruktion //arraylength// is used. This instruktion has to be translated such as the //length// field is accessed. 
  
-===== Generating Arrays ===== 
-The Java code  
-<code java> 
-  static int[]a1 = new int[4]; 
-</code> 
-will be translated into Bytecode 
-<code> 
-  0  iconst_4 
-  1  newarray int  
-  3  putstatic Test.a1 : int[]  
-</code> 
-When regular objects are created the constructor of the supertype is automatically inserted into the Bytecode. When arrays are created there is no such call. The constructor of //Object// has to be inserted by the code generator and the heap manager has to add the size of //java/lang/Object// to the size of the array. As long as //java/lang/Object// has no fields the size is 0 and we can also omit the call of the constructor.\\ 
-In the Bytecode //newarray// has a type (here //int//). When generating the SSA the reference to this type //[I// has to be fetched from the object directory.   
-\\ 
-For  
-<code java> 
-  static Object[] a1 = new ClassA[4]; 
-</code> 
-the Bytecode looks like: 
-<code> 
-  0  iconst_4 
-  1  anewarray ch/ntb/junitTarget/comp/objects/ClassA 
-  4  putstatic ch/ntb/junitTarget/comp/objects/InheritanceTest.a1: Ljava/lang/Object[]; 
-</code> 
-Here, as well, the reference to //[ClassA// has to be fetched from the object directory when generating the SSA. There are cases when there is no entry for //[ClassA//. This is the case when there is never a type check for the type //[ClassA//. Then the SSA has a reference to null and the //Tag// can be 0 as well.  
- 
-===== Mehrdimensionale Arrays ===== 
-Betrachten wir den folgenden Fall 
-<code java> 
-int[][] a = new int[2][3] 
-</code> 
-Im Speicher ergibt sich folgende Situation 
-[{{ .:array2.png?450&direct | //Zweidimensionales Arrays//}}] 
-[[I und [I sind die entsprechenden Typdescriptoren. 
-Bei einem Arrayzugriff muss also zuerst in der ersten Dimension eine Referenz geladen werden und damit ein zweiter Arrayzugriff gemacht werden.  
- 
-==== Erzeugung von mehrdimensionalen Arrays von Basistypen ==== 
-Der folgende Code  
-<code java> 
-  short[][] a = new short[2][3] 
-</code> 
-führt auf den Bytecode 
-<code> 
-0 iconst_2 
-1 iconst_3 
-2 multianewarray short[][] 
-6 putstatic ch/ntb/inf/deep/runtime/mpc555/test/ArrayTest3.a1: short[][] 
-</code> 
-Wenn aber ein Array gleich initialisiert wird, z.B. mit  
-<code java> 
-  short[][] a2 = {{1,2},{3,4}}; 
-</code> 
-führt das auf den Bytecode 
-<code> 
-9 iconst_2 
-10 anewarray [S 
-13 dup 
-14 iconst_0 
-15 iconst_2 
-16 newarray short 
-18 dup 
-19 iconst_0 
-20 iconst_1 
-21 sastore 
-22 dup 
-23 iconst_1 
-24 iconst_2 
-25 sastore 
-26 aastore 
-27 dup 
-28 iconst_1 
-29 iconst_2 
-30 newarray short 
-usw. 
-</code> 
-Das Problem ist im ersten Fall, dass nur der Typdescriptor von [[I gelinkt würde. [I muss ebenfalls erzeugt werden. Im Heapmanager muss die Methode //multianewarray// das Array allozieren und insbesondere auch die Referenzen auf [[I und [I setzen. Die Referenz auf [[I wird als Parameter übergeben. Im Typdescriptor von [[I steht die Referenz auf [I. Die muss dort geholt werden und am richtigen Ort im Object gespeichert werden. \\ 
-Die gleichen Überlegungen gelten auch für Arrays mit höheren Dimensionen. Auch dort wird //multianewarray// nur in besonderen Situationen verwendet. 
-==== Erzeugung von mehrdimensionalen Arrays von Objekten ==== 
-Hier gelten grundsätzlich die gleichen Bedingungen wie oben.  
-Der folgende Javacode  
-<code java> 
-  ClassA[][][] a1 = new ClassA[3][2][2]; 
-</code> 
-wird in den Bytecode 
-<code> 
-  0 iconst_3 
-  1 iconst_2 
-  2 iconst_2 
-  3 multianewarray Lch/ntb/junitTarget/comp/arrays/A[][][]; 
-  7 astore_1 [a1] 
-</code> 
-übersetzt. Hier wird also bereits also bereits die korrekte Referenz auf //[[[ClassA;// in die SSA aufgenommen. Der Heapmanager muss wie bei den Basistypen aus dem Typdescriptor von //[[[ClassA;// die weiteren Typdescriptoren //[[ClassA;//, //[ClassA;// und //ClassA;// rekursiv holen.