deep

a Cross Development Platform for Java

User Tools

Site Tools


dev:crosscompiler:arrays

This is an old revision of the document!


Arrays

The following figure demonstrates how arrays are implemented in the memory.

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 (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

  static int[]a1 = new int[4];

will be translated into Bytecode

  0  iconst_4
  1  newarray int 
  3  putstatic Test.a1 : int[] 

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

  static Object[] a1 = new ClassA[4];

the Bytecode looks like:

  0  iconst_4
  1  anewarray ch/ntb/junitTarget/comp/objects/ClassA
  4  putstatic ch/ntb/junitTarget/comp/objects/InheritanceTest.a1: Ljava/lang/Object[];

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.

Multidimensional Arrays

Let us consider the following case:

int[][] a = new int[2][3]

The memory will look like

2-dimensional Array

[[I and [I are the corresponding type descriptors. When accessing an element one has to access a reference in the first dimension followed by the element access in the second dimension.

Generating an

Der folgende Code

  short[][] a = new short[2][3]

führt auf den Bytecode

0 iconst_2
1 iconst_3
2 multianewarray short[][]
6 putstatic ch/ntb/inf/deep/runtime/mpc555/test/ArrayTest3.a1: short[][]

Wenn aber ein Array gleich initialisiert wird, z.B. mit

  short[][] a2 = {{1,2},{3,4}};

führt das auf den Bytecode

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.

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

  ClassA[][][] a1 = new ClassA[3][2][2];

wird in den Bytecode

  0 iconst_3
  1 iconst_2
  2 iconst_2
  3 multianewarray Lch/ntb/junitTarget/comp/arrays/A[][][];
  7 astore_1 [a1]

ü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.

dev/crosscompiler/arrays.1427614898.txt.gz · Last modified: 2016/02/25 13:33 (external edit)