34 public class Klass extends Metadata implements ClassConstants {
35 static {
36 VM.registerVMInitializedObserver(new Observer() {
37 public void update(Observable o, Object data) {
38 initialize(VM.getVM().getTypeDataBase());
39 }
40 });
41 }
42
43 // anon-enum constants for _layout_helper.
44 public static int LH_INSTANCE_SLOW_PATH_BIT;
45 public static int LH_LOG2_ELEMENT_SIZE_SHIFT;
46 public static int LH_ELEMENT_TYPE_SHIFT;
47 public static int LH_HEADER_SIZE_SHIFT;
48 public static int LH_ARRAY_TAG_SHIFT;
49 public static int LH_ARRAY_TAG_TYPE_VALUE;
50 public static int LH_ARRAY_TAG_OBJ_VALUE;
51
52 private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
53 Type type = db.lookupType("Klass");
54 javaMirror = new OopField(type.getOopField("_java_mirror"), 0);
55 superField = new MetadataField(type.getAddressField("_super"), 0);
56 layoutHelper = new IntField(type.getJIntField("_layout_helper"), 0);
57 name = type.getAddressField("_name");
58 accessFlags = new CIntField(type.getCIntegerField("_access_flags"), 0);
59 try {
60 traceIDField = type.getField("_trace_id");
61 } catch(Exception e) {
62 }
63 subklass = new MetadataField(type.getAddressField("_subklass"), 0);
64 nextSibling = new MetadataField(type.getAddressField("_next_sibling"), 0);
65 nextLink = new MetadataField(type.getAddressField("_next_link"), 0);
66 vtableLen = new CIntField(type.getCIntegerField("_vtable_len"), 0);
67 classLoaderData = type.getAddressField("_class_loader_data");
68
69 LH_INSTANCE_SLOW_PATH_BIT = db.lookupIntConstant("Klass::_lh_instance_slow_path_bit").intValue();
70 LH_LOG2_ELEMENT_SIZE_SHIFT = db.lookupIntConstant("Klass::_lh_log2_element_size_shift").intValue();
71 LH_ELEMENT_TYPE_SHIFT = db.lookupIntConstant("Klass::_lh_element_type_shift").intValue();
72 LH_HEADER_SIZE_SHIFT = db.lookupIntConstant("Klass::_lh_header_size_shift").intValue();
73 LH_ARRAY_TAG_SHIFT = db.lookupIntConstant("Klass::_lh_array_tag_shift").intValue();
74 LH_ARRAY_TAG_TYPE_VALUE = db.lookupIntConstant("Klass::_lh_array_tag_type_value").intValue();
75 LH_ARRAY_TAG_OBJ_VALUE = db.lookupIntConstant("Klass::_lh_array_tag_obj_value").intValue();
76 }
77
78
79 public Klass(Address addr) {
80 super(addr);
81 }
82
83 // jvmdi support - see also class_status in VM code
84 public int getClassStatus() {
85 return 0; // overridden in derived classes
86 }
87
88 public boolean isKlass() { return true; }
89
90 // Fields
91 private static OopField javaMirror;
92 private static MetadataField superField;
93 private static IntField layoutHelper;
94 private static AddressField name;
95 private static CIntField accessFlags;
96 private static MetadataField subklass;
97 private static MetadataField nextSibling;
98 private static MetadataField nextLink;
99 private static sun.jvm.hotspot.types.Field traceIDField;
100 private static CIntField vtableLen;
101 private static AddressField classLoaderData;
102
103 private Address getValue(AddressField field) {
104 return addr.getAddressAt(field.getOffset());
105 }
106
107 protected Symbol getSymbol(AddressField field) {
108 return Symbol.create(addr.getAddressAt(field.getOffset()));
109 }
110
111 // Accessors for declared fields
112 public Instance getJavaMirror() { return (Instance) javaMirror.getValue(this); }
113 public Klass getSuper() { return (Klass) superField.getValue(this); }
114 public Klass getJavaSuper() { return null; }
115 public int getLayoutHelper() { return (int) layoutHelper.getValue(this); }
116 public Symbol getName() { return getSymbol(name); }
117 public long getAccessFlags() { return accessFlags.getValue(this); }
118 // Convenience routine
119 public AccessFlags getAccessFlagsObj(){ return new AccessFlags(getAccessFlags()); }
120 public Klass getSubklassKlass() { return (Klass) subklass.getValue(this); }
121 public Klass getNextSiblingKlass() { return (Klass) nextSibling.getValue(this); }
122 public Klass getNextLinkKlass() { return (Klass) nextLink.getValue(this); }
123 public long getVtableLen() { return vtableLen.getValue(this); }
124
125 public ClassLoaderData getClassLoaderData() { return ClassLoaderData.instantiateWrapperFor(classLoaderData.getValue(getAddress())); }
126 public Oop getClassLoader() { return getClassLoaderData().getClassLoader(); }
127
128 public long traceID() {
129 if (traceIDField == null) return 0;
130 return traceIDField.getJLong(addr);
131 }
132
168 boolean computeSubtypeOf(Klass k) {
169 return isSubclassOf(k);
170 }
171
172 // Find LCA (Least Common Ancester) in class heirarchy
173 public Klass lca( Klass k2 ) {
174 Klass k1 = this;
175 while ( true ) {
176 if ( k1.isSubtypeOf(k2) ) return k2;
177 if ( k2.isSubtypeOf(k1) ) return k1;
178 k1 = k1.getSuper();
179 k2 = k2.getSuper();
180 }
181 }
182
183 public void printValueOn(PrintStream tty) {
184 tty.print("Klass");
185 }
186
187 public void iterateFields(MetadataVisitor visitor) {
188 visitor.doOop(javaMirror, true);
189 visitor.doMetadata(superField, true);
190 visitor.doInt(layoutHelper, true);
191 // visitor.doOop(name, true);
192 visitor.doCInt(accessFlags, true);
193 visitor.doMetadata(subklass, true);
194 visitor.doMetadata(nextSibling, true);
195 visitor.doCInt(vtableLen, true);
196 }
197
198 public long getObjectSize() {
199 throw new RuntimeException("should not reach here");
200 }
201
202 /** Array class with specific rank */
203 public Klass arrayKlass(int rank) { return arrayKlassImpl(false, rank); }
204 /** Array class with this klass as element type */
205 public Klass arrayKlass() { return arrayKlassImpl(false); }
206 /** These will return null instead of allocating on the heap */
207 public Klass arrayKlassOrNull(int rank) { return arrayKlassImpl(true, rank); }
208 public Klass arrayKlassOrNull() { return arrayKlassImpl(true); }
|
34 public class Klass extends Metadata implements ClassConstants {
35 static {
36 VM.registerVMInitializedObserver(new Observer() {
37 public void update(Observable o, Object data) {
38 initialize(VM.getVM().getTypeDataBase());
39 }
40 });
41 }
42
43 // anon-enum constants for _layout_helper.
44 public static int LH_INSTANCE_SLOW_PATH_BIT;
45 public static int LH_LOG2_ELEMENT_SIZE_SHIFT;
46 public static int LH_ELEMENT_TYPE_SHIFT;
47 public static int LH_HEADER_SIZE_SHIFT;
48 public static int LH_ARRAY_TAG_SHIFT;
49 public static int LH_ARRAY_TAG_TYPE_VALUE;
50 public static int LH_ARRAY_TAG_OBJ_VALUE;
51
52 private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
53 Type type = db.lookupType("Klass");
54 javaMirror = type.getAddressField("_java_mirror");
55 superField = new MetadataField(type.getAddressField("_super"), 0);
56 layoutHelper = new IntField(type.getJIntField("_layout_helper"), 0);
57 name = type.getAddressField("_name");
58 accessFlags = new CIntField(type.getCIntegerField("_access_flags"), 0);
59 try {
60 traceIDField = type.getField("_trace_id");
61 } catch(Exception e) {
62 }
63 subklass = new MetadataField(type.getAddressField("_subklass"), 0);
64 nextSibling = new MetadataField(type.getAddressField("_next_sibling"), 0);
65 nextLink = new MetadataField(type.getAddressField("_next_link"), 0);
66 vtableLen = new CIntField(type.getCIntegerField("_vtable_len"), 0);
67 classLoaderData = type.getAddressField("_class_loader_data");
68
69 LH_INSTANCE_SLOW_PATH_BIT = db.lookupIntConstant("Klass::_lh_instance_slow_path_bit").intValue();
70 LH_LOG2_ELEMENT_SIZE_SHIFT = db.lookupIntConstant("Klass::_lh_log2_element_size_shift").intValue();
71 LH_ELEMENT_TYPE_SHIFT = db.lookupIntConstant("Klass::_lh_element_type_shift").intValue();
72 LH_HEADER_SIZE_SHIFT = db.lookupIntConstant("Klass::_lh_header_size_shift").intValue();
73 LH_ARRAY_TAG_SHIFT = db.lookupIntConstant("Klass::_lh_array_tag_shift").intValue();
74 LH_ARRAY_TAG_TYPE_VALUE = db.lookupIntConstant("Klass::_lh_array_tag_type_value").intValue();
75 LH_ARRAY_TAG_OBJ_VALUE = db.lookupIntConstant("Klass::_lh_array_tag_obj_value").intValue();
76 }
77
78
79 public Klass(Address addr) {
80 super(addr);
81 }
82
83 // jvmdi support - see also class_status in VM code
84 public int getClassStatus() {
85 return 0; // overridden in derived classes
86 }
87
88 public boolean isKlass() { return true; }
89
90 // Fields
91 private static AddressField javaMirror;
92 private static MetadataField superField;
93 private static IntField layoutHelper;
94 private static AddressField name;
95 private static CIntField accessFlags;
96 private static MetadataField subklass;
97 private static MetadataField nextSibling;
98 private static MetadataField nextLink;
99 private static sun.jvm.hotspot.types.Field traceIDField;
100 private static CIntField vtableLen;
101 private static AddressField classLoaderData;
102
103 private Address getValue(AddressField field) {
104 return addr.getAddressAt(field.getOffset());
105 }
106
107 protected Symbol getSymbol(AddressField field) {
108 return Symbol.create(addr.getAddressAt(field.getOffset()));
109 }
110
111 // Accessors for declared fields
112 public Instance getJavaMirror() {
113 Address handle = javaMirror.getValue(getAddress());
114 if (handle != null) {
115 // Load through the handle
116 OopHandle refs = handle.getOopHandleAt(0);
117 return (Instance)VM.getVM().getObjectHeap().newOop(refs);
118 }
119 return null;
120 }
121 public Klass getSuper() { return (Klass) superField.getValue(this); }
122 public Klass getJavaSuper() { return null; }
123 public int getLayoutHelper() { return (int) layoutHelper.getValue(this); }
124 public Symbol getName() { return getSymbol(name); }
125 public long getAccessFlags() { return accessFlags.getValue(this); }
126 // Convenience routine
127 public AccessFlags getAccessFlagsObj(){ return new AccessFlags(getAccessFlags()); }
128 public Klass getSubklassKlass() { return (Klass) subklass.getValue(this); }
129 public Klass getNextSiblingKlass() { return (Klass) nextSibling.getValue(this); }
130 public Klass getNextLinkKlass() { return (Klass) nextLink.getValue(this); }
131 public long getVtableLen() { return vtableLen.getValue(this); }
132
133 public ClassLoaderData getClassLoaderData() { return ClassLoaderData.instantiateWrapperFor(classLoaderData.getValue(getAddress())); }
134 public Oop getClassLoader() { return getClassLoaderData().getClassLoader(); }
135
136 public long traceID() {
137 if (traceIDField == null) return 0;
138 return traceIDField.getJLong(addr);
139 }
140
176 boolean computeSubtypeOf(Klass k) {
177 return isSubclassOf(k);
178 }
179
180 // Find LCA (Least Common Ancester) in class heirarchy
181 public Klass lca( Klass k2 ) {
182 Klass k1 = this;
183 while ( true ) {
184 if ( k1.isSubtypeOf(k2) ) return k2;
185 if ( k2.isSubtypeOf(k1) ) return k1;
186 k1 = k1.getSuper();
187 k2 = k2.getSuper();
188 }
189 }
190
191 public void printValueOn(PrintStream tty) {
192 tty.print("Klass");
193 }
194
195 public void iterateFields(MetadataVisitor visitor) {
196 // visitor.doOop(javaMirror, true);
197 visitor.doMetadata(superField, true);
198 visitor.doInt(layoutHelper, true);
199 // visitor.doOop(name, true);
200 visitor.doCInt(accessFlags, true);
201 visitor.doMetadata(subklass, true);
202 visitor.doMetadata(nextSibling, true);
203 visitor.doCInt(vtableLen, true);
204 }
205
206 public long getObjectSize() {
207 throw new RuntimeException("should not reach here");
208 }
209
210 /** Array class with specific rank */
211 public Klass arrayKlass(int rank) { return arrayKlassImpl(false, rank); }
212 /** Array class with this klass as element type */
213 public Klass arrayKlass() { return arrayKlassImpl(false); }
214 /** These will return null instead of allocating on the heap */
215 public Klass arrayKlassOrNull(int rank) { return arrayKlassImpl(true, rank); }
216 public Klass arrayKlassOrNull() { return arrayKlassImpl(true); }
|