View Javadoc
1   package sun.jvm.hotspot.utilities;
2   
3   import java.util.Observable;
4   import java.util.Observer;
5   
6   import sun.jvm.hotspot.debugger.Address;
7   import sun.jvm.hotspot.oops.ArrayKlass;
8   import sun.jvm.hotspot.oops.CIntField;
9   import sun.jvm.hotspot.oops.Oop;
10  import sun.jvm.hotspot.runtime.VM;
11  import sun.jvm.hotspot.runtime.VMObject;
12  import sun.jvm.hotspot.types.AddressField;
13  import sun.jvm.hotspot.types.Type;
14  import sun.jvm.hotspot.types.TypeDataBase;
15  import sun.jvm.hotspot.types.WrongTypeException;
16  
17  /**
18   * The base class for the mirrors of the Array<T> C++ classes.
19   */
20  public abstract class GenericArray extends VMObject {
21    static {
22      VM.registerVMInitializedObserver(new Observer() {
23        public void update(Observable o, Object data) {
24          initialize(VM.getVM().getTypeDataBase());
25        }
26      });
27    }
28  
29    private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
30      // Array<int> is arbitrarily chosen to get the fields in Array<T>.
31      Type type = db.lookupType("Array<int>");
32      lengthField = new CIntField(type.getCIntegerField("_length"), 0);
33    }
34  
35    private static long sizeOfArray;
36    private static CIntField lengthField;
37  
38    private long dataFieldOffset;
39  
40    public GenericArray(Address addr, long dataOffset) {
41      super(addr);
42      dataFieldOffset = dataOffset;
43    }
44  
45    public int length() {
46      return (int)lengthField.getValue(this);
47    }
48  
49    // for compatibility with TypeArray
50    public int getLength() {
51      return length();
52    }
53  
54    /**
55     * Gets the element at the given index.
56     */
57    protected long getIntegerAt(int index) {
58      if (index < 0 || index >= length()) throw new ArrayIndexOutOfBoundsException(index + " " + length());
59  
60      Type elemType = getElemType();
61      if (!getElemType().isCIntegerType()) throw new RuntimeException("elemType must be of CInteger type");
62  
63      Address data = getAddress().addOffsetTo(dataFieldOffset);
64      long elemSize = elemType.getSize();
65  
66      return data.getCIntegerAt(index * elemSize, elemSize, false);
67    }
68  
69    protected Address getAddressAt(int index) {
70      if (index < 0 || index >= length()) throw new ArrayIndexOutOfBoundsException(index);
71  
72      Type elemType = getElemType();
73      if (getElemType().isCIntegerType()) throw new RuntimeException("elemType must not be of CInteger type");
74  
75      Address data = getAddress().addOffsetTo(dataFieldOffset);
76      long elemSize = elemType.getSize();
77  
78      return data.getAddressAt(index * elemSize);
79    }
80  
81    private long byteSizeof(int length) { return sizeOfArray + length * getElemType().getSize(); }
82  
83    public long getSize() {
84      return VM.getVM().alignUp(byteSizeof(length()), VM.getVM().getBytesPerWord()) / VM.getVM().getBytesPerWord();
85    }
86  
87    /**
88     * The element type of this array.
89     */
90    public abstract Type getElemType();
91  }