comparison agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java @ 6725:da91efe96a93

6964458: Reimplement class meta-data storage to use native memory Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author coleenp
date Sat, 01 Sep 2012 13:25:18 -0400
parents 04ade88d9712
children bd7a7ce2e264
comparison
equal deleted inserted replaced
6724:36d1d483d5d6 6725:da91efe96a93
24 24
25 package sun.jvm.hotspot.oops; 25 package sun.jvm.hotspot.oops;
26 26
27 import java.io.*; 27 import java.io.*;
28 import java.util.*; 28 import java.util.*;
29 import sun.jvm.hotspot.classfile.ClassLoaderData;
29 import sun.jvm.hotspot.debugger.*; 30 import sun.jvm.hotspot.debugger.*;
30 import sun.jvm.hotspot.memory.*; 31 import sun.jvm.hotspot.memory.*;
31 import sun.jvm.hotspot.runtime.*; 32 import sun.jvm.hotspot.runtime.*;
32 import sun.jvm.hotspot.types.*; 33 import sun.jvm.hotspot.types.*;
33 import sun.jvm.hotspot.utilities.*; 34 import sun.jvm.hotspot.utilities.*;
51 private static int LOW_OFFSET; 52 private static int LOW_OFFSET;
52 private static int HIGH_OFFSET; 53 private static int HIGH_OFFSET;
53 private static int FIELD_SLOTS; 54 private static int FIELD_SLOTS;
54 55
55 // ClassState constants 56 // ClassState constants
56 private static int CLASS_STATE_UNPARSABLE_BY_GC;
57 private static int CLASS_STATE_ALLOCATED; 57 private static int CLASS_STATE_ALLOCATED;
58 private static int CLASS_STATE_LOADED; 58 private static int CLASS_STATE_LOADED;
59 private static int CLASS_STATE_LINKED; 59 private static int CLASS_STATE_LINKED;
60 private static int CLASS_STATE_BEING_INITIALIZED; 60 private static int CLASS_STATE_BEING_INITIALIZED;
61 private static int CLASS_STATE_FULLY_INITIALIZED; 61 private static int CLASS_STATE_FULLY_INITIALIZED;
62 private static int CLASS_STATE_INITIALIZATION_ERROR; 62 private static int CLASS_STATE_INITIALIZATION_ERROR;
63 63
64 private static synchronized void initialize(TypeDataBase db) throws WrongTypeException { 64 private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
65 Type type = db.lookupType("instanceKlass"); 65 Type type = db.lookupType("InstanceKlass");
66 arrayKlasses = new OopField(type.getOopField("_array_klasses"), Oop.getHeaderSize()); 66 arrayKlasses = new MetadataField(type.getAddressField("_array_klasses"), 0);
67 methods = new OopField(type.getOopField("_methods"), Oop.getHeaderSize()); 67 methods = type.getAddressField("_methods");
68 methodOrdering = new OopField(type.getOopField("_method_ordering"), Oop.getHeaderSize()); 68 methodOrdering = type.getAddressField("_method_ordering");
69 localInterfaces = new OopField(type.getOopField("_local_interfaces"), Oop.getHeaderSize()); 69 localInterfaces = type.getAddressField("_local_interfaces");
70 transitiveInterfaces = new OopField(type.getOopField("_transitive_interfaces"), Oop.getHeaderSize()); 70 transitiveInterfaces = type.getAddressField("_transitive_interfaces");
71 fields = new OopField(type.getOopField("_fields"), Oop.getHeaderSize()); 71 fields = type.getAddressField("_fields");
72 javaFieldsCount = new CIntField(type.getCIntegerField("_java_fields_count"), Oop.getHeaderSize()); 72 javaFieldsCount = new CIntField(type.getCIntegerField("_java_fields_count"), 0);
73 constants = new OopField(type.getOopField("_constants"), Oop.getHeaderSize()); 73 constants = new MetadataField(type.getAddressField("_constants"), 0);
74 classLoader = new OopField(type.getOopField("_class_loader"), Oop.getHeaderSize()); 74 classLoaderData = type.getAddressField("_class_loader_data");
75 protectionDomain = new OopField(type.getOopField("_protection_domain"), Oop.getHeaderSize()); 75 protectionDomain = new OopField(type.getOopField("_protection_domain"), 0);
76 signers = new OopField(type.getOopField("_signers"), Oop.getHeaderSize()); 76 signers = new OopField(type.getOopField("_signers"), 0);
77 sourceFileName = type.getAddressField("_source_file_name"); 77 sourceFileName = type.getAddressField("_source_file_name");
78 sourceDebugExtension = type.getAddressField("_source_debug_extension"); 78 sourceDebugExtension = type.getAddressField("_source_debug_extension");
79 innerClasses = new OopField(type.getOopField("_inner_classes"), Oop.getHeaderSize()); 79 innerClasses = type.getAddressField("_inner_classes");
80 nonstaticFieldSize = new CIntField(type.getCIntegerField("_nonstatic_field_size"), Oop.getHeaderSize()); 80 nonstaticFieldSize = new CIntField(type.getCIntegerField("_nonstatic_field_size"), 0);
81 staticFieldSize = new CIntField(type.getCIntegerField("_static_field_size"), Oop.getHeaderSize()); 81 staticFieldSize = new CIntField(type.getCIntegerField("_static_field_size"), 0);
82 staticOopFieldCount = new CIntField(type.getCIntegerField("_static_oop_field_count"), Oop.getHeaderSize()); 82 staticOopFieldCount = new CIntField(type.getCIntegerField("_static_oop_field_count"), 0);
83 nonstaticOopMapSize = new CIntField(type.getCIntegerField("_nonstatic_oop_map_size"), Oop.getHeaderSize()); 83 nonstaticOopMapSize = new CIntField(type.getCIntegerField("_nonstatic_oop_map_size"), 0);
84 isMarkedDependent = new CIntField(type.getCIntegerField("_is_marked_dependent"), Oop.getHeaderSize()); 84 isMarkedDependent = new CIntField(type.getCIntegerField("_is_marked_dependent"), 0);
85 initState = new CIntField(type.getCIntegerField("_init_state"), Oop.getHeaderSize()); 85 initState = new CIntField(type.getCIntegerField("_init_state"), 0);
86 vtableLen = new CIntField(type.getCIntegerField("_vtable_len"), Oop.getHeaderSize()); 86 vtableLen = new CIntField(type.getCIntegerField("_vtable_len"), 0);
87 itableLen = new CIntField(type.getCIntegerField("_itable_len"), Oop.getHeaderSize()); 87 itableLen = new CIntField(type.getCIntegerField("_itable_len"), 0);
88 breakpoints = type.getAddressField("_breakpoints"); 88 breakpoints = type.getAddressField("_breakpoints");
89 genericSignature = type.getAddressField("_generic_signature"); 89 genericSignature = type.getAddressField("_generic_signature");
90 majorVersion = new CIntField(type.getCIntegerField("_major_version"), Oop.getHeaderSize()); 90 majorVersion = new CIntField(type.getCIntegerField("_major_version"), 0);
91 minorVersion = new CIntField(type.getCIntegerField("_minor_version"), Oop.getHeaderSize()); 91 minorVersion = new CIntField(type.getCIntegerField("_minor_version"), 0);
92 headerSize = alignObjectOffset(Oop.getHeaderSize() + type.getSize()); 92 headerSize = Oop.alignObjectOffset(type.getSize());
93 93
94 // read field offset constants 94 // read field offset constants
95 ACCESS_FLAGS_OFFSET = db.lookupIntConstant("FieldInfo::access_flags_offset").intValue(); 95 ACCESS_FLAGS_OFFSET = db.lookupIntConstant("FieldInfo::access_flags_offset").intValue();
96 NAME_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::name_index_offset").intValue(); 96 NAME_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::name_index_offset").intValue();
97 SIGNATURE_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::signature_index_offset").intValue(); 97 SIGNATURE_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::signature_index_offset").intValue();
98 INITVAL_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::initval_index_offset").intValue(); 98 INITVAL_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::initval_index_offset").intValue();
99 LOW_OFFSET = db.lookupIntConstant("FieldInfo::low_offset").intValue(); 99 LOW_OFFSET = db.lookupIntConstant("FieldInfo::low_offset").intValue();
100 HIGH_OFFSET = db.lookupIntConstant("FieldInfo::high_offset").intValue(); 100 HIGH_OFFSET = db.lookupIntConstant("FieldInfo::high_offset").intValue();
101 FIELD_SLOTS = db.lookupIntConstant("FieldInfo::field_slots").intValue(); 101 FIELD_SLOTS = db.lookupIntConstant("FieldInfo::field_slots").intValue();
102 // read ClassState constants 102 // read ClassState constants
103 CLASS_STATE_UNPARSABLE_BY_GC = db.lookupIntConstant("instanceKlass::unparsable_by_gc").intValue(); 103 CLASS_STATE_ALLOCATED = db.lookupIntConstant("InstanceKlass::allocated").intValue();
104 CLASS_STATE_ALLOCATED = db.lookupIntConstant("instanceKlass::allocated").intValue(); 104 CLASS_STATE_LOADED = db.lookupIntConstant("InstanceKlass::loaded").intValue();
105 CLASS_STATE_LOADED = db.lookupIntConstant("instanceKlass::loaded").intValue(); 105 CLASS_STATE_LINKED = db.lookupIntConstant("InstanceKlass::linked").intValue();
106 CLASS_STATE_LINKED = db.lookupIntConstant("instanceKlass::linked").intValue(); 106 CLASS_STATE_BEING_INITIALIZED = db.lookupIntConstant("InstanceKlass::being_initialized").intValue();
107 CLASS_STATE_BEING_INITIALIZED = db.lookupIntConstant("instanceKlass::being_initialized").intValue(); 107 CLASS_STATE_FULLY_INITIALIZED = db.lookupIntConstant("InstanceKlass::fully_initialized").intValue();
108 CLASS_STATE_FULLY_INITIALIZED = db.lookupIntConstant("instanceKlass::fully_initialized").intValue(); 108 CLASS_STATE_INITIALIZATION_ERROR = db.lookupIntConstant("InstanceKlass::initialization_error").intValue();
109 CLASS_STATE_INITIALIZATION_ERROR = db.lookupIntConstant("instanceKlass::initialization_error").intValue(); 109
110 110 }
111 } 111
112 112 public InstanceKlass(Address addr) {
113 InstanceKlass(OopHandle handle, ObjectHeap heap) { 113 super(addr);
114 super(handle, heap);
115 if (getJavaFieldsCount() != getAllFieldsCount()) { 114 if (getJavaFieldsCount() != getAllFieldsCount()) {
116 // Exercise the injected field logic 115 // Exercise the injected field logic
117 for (int i = getJavaFieldsCount(); i < getAllFieldsCount(); i++) { 116 for (int i = getJavaFieldsCount(); i < getAllFieldsCount(); i++) {
118 getFieldName(i); 117 getFieldName(i);
119 getFieldSignature(i); 118 getFieldSignature(i);
120 } 119 }
121 } 120 }
122 } 121 }
123 122
124 private static OopField arrayKlasses; 123 private static MetadataField arrayKlasses;
125 private static OopField methods; 124 private static AddressField methods;
126 private static OopField methodOrdering; 125 private static AddressField methodOrdering;
127 private static OopField localInterfaces; 126 private static AddressField localInterfaces;
128 private static OopField transitiveInterfaces; 127 private static AddressField transitiveInterfaces;
129 private static OopField fields; 128 private static AddressField fields;
130 private static CIntField javaFieldsCount; 129 private static CIntField javaFieldsCount;
131 private static OopField constants; 130 private static MetadataField constants;
132 private static OopField classLoader; 131 private static AddressField classLoaderData;
133 private static OopField protectionDomain; 132 private static OopField protectionDomain;
134 private static OopField signers; 133 private static OopField signers;
135 private static AddressField sourceFileName; 134 private static AddressField sourceFileName;
136 private static AddressField sourceDebugExtension; 135 private static AddressField sourceDebugExtension;
137 private static OopField innerClasses; 136 private static AddressField innerClasses;
138 private static CIntField nonstaticFieldSize; 137 private static CIntField nonstaticFieldSize;
139 private static CIntField staticFieldSize; 138 private static CIntField staticFieldSize;
140 private static CIntField staticOopFieldCount; 139 private static CIntField staticOopFieldCount;
141 private static CIntField nonstaticOopMapSize; 140 private static CIntField nonstaticOopMapSize;
142 private static CIntField isMarkedDependent; 141 private static CIntField isMarkedDependent;
148 private static CIntField majorVersion; 147 private static CIntField majorVersion;
149 private static CIntField minorVersion; 148 private static CIntField minorVersion;
150 149
151 // type safe enum for ClassState from instanceKlass.hpp 150 // type safe enum for ClassState from instanceKlass.hpp
152 public static class ClassState { 151 public static class ClassState {
153 public static final ClassState UNPARSABLE_BY_GC = new ClassState("unparsable_by_gc");
154 public static final ClassState ALLOCATED = new ClassState("allocated"); 152 public static final ClassState ALLOCATED = new ClassState("allocated");
155 public static final ClassState LOADED = new ClassState("loaded"); 153 public static final ClassState LOADED = new ClassState("loaded");
156 public static final ClassState LINKED = new ClassState("linked"); 154 public static final ClassState LINKED = new ClassState("linked");
157 public static final ClassState BEING_INITIALIZED = new ClassState("beingInitialized"); 155 public static final ClassState BEING_INITIALIZED = new ClassState("beingInitialized");
158 public static final ClassState FULLY_INITIALIZED = new ClassState("fullyInitialized"); 156 public static final ClassState FULLY_INITIALIZED = new ClassState("fullyInitialized");
170 } 168 }
171 169
172 public int getInitStateAsInt() { return (int) initState.getValue(this); } 170 public int getInitStateAsInt() { return (int) initState.getValue(this); }
173 public ClassState getInitState() { 171 public ClassState getInitState() {
174 int state = getInitStateAsInt(); 172 int state = getInitStateAsInt();
175 if (state == CLASS_STATE_UNPARSABLE_BY_GC) { 173 if (state == CLASS_STATE_ALLOCATED) {
176 return ClassState.UNPARSABLE_BY_GC;
177 } else if (state == CLASS_STATE_ALLOCATED) {
178 return ClassState.ALLOCATED; 174 return ClassState.ALLOCATED;
179 } else if (state == CLASS_STATE_LOADED) { 175 } else if (state == CLASS_STATE_LOADED) {
180 return ClassState.LOADED; 176 return ClassState.LOADED;
181 } else if (state == CLASS_STATE_LINKED) { 177 } else if (state == CLASS_STATE_LINKED) {
182 return ClassState.LINKED; 178 return ClassState.LINKED;
240 236
241 public long getObjectSize(Oop object) { 237 public long getObjectSize(Oop object) {
242 return getSizeHelper() * VM.getVM().getAddressSize(); 238 return getSizeHelper() * VM.getVM().getAddressSize();
243 } 239 }
244 240
241 public long getSize() {
242 return Oop.alignObjectSize(getHeaderSize() + Oop.alignObjectOffset(getVtableLen()) +
243 Oop.alignObjectOffset(getItableLen()) + Oop.alignObjectOffset(getNonstaticOopMapSize()));
244 }
245
245 public static long getHeaderSize() { return headerSize; } 246 public static long getHeaderSize() { return headerSize; }
246 247
247 public short getFieldAccessFlags(int index) { 248 public short getFieldAccessFlags(int index) {
248 return getFields().getShortAt(index * FIELD_SLOTS + ACCESS_FLAGS_OFFSET); 249 return getFields().at(index * FIELD_SLOTS + ACCESS_FLAGS_OFFSET);
249 } 250 }
250 251
251 public short getFieldNameIndex(int index) { 252 public short getFieldNameIndex(int index) {
252 if (index >= getJavaFieldsCount()) throw new IndexOutOfBoundsException("not a Java field;"); 253 if (index >= getJavaFieldsCount()) throw new IndexOutOfBoundsException("not a Java field;");
253 return getFields().getShortAt(index * FIELD_SLOTS + NAME_INDEX_OFFSET); 254 return getFields().at(index * FIELD_SLOTS + NAME_INDEX_OFFSET);
254 } 255 }
255 256
256 public Symbol getFieldName(int index) { 257 public Symbol getFieldName(int index) {
257 int nameIndex = getFields().getShortAt(index * FIELD_SLOTS + NAME_INDEX_OFFSET); 258 int nameIndex = getFields().at(index * FIELD_SLOTS + NAME_INDEX_OFFSET);
258 if (index < getJavaFieldsCount()) { 259 if (index < getJavaFieldsCount()) {
259 return getConstants().getSymbolAt(nameIndex); 260 return getConstants().getSymbolAt(nameIndex);
260 } else { 261 } else {
261 return vmSymbols.symbolAt(nameIndex); 262 return vmSymbols.symbolAt(nameIndex);
262 } 263 }
263 } 264 }
264 265
265 public short getFieldSignatureIndex(int index) { 266 public short getFieldSignatureIndex(int index) {
266 if (index >= getJavaFieldsCount()) throw new IndexOutOfBoundsException("not a Java field;"); 267 if (index >= getJavaFieldsCount()) throw new IndexOutOfBoundsException("not a Java field;");
267 return getFields().getShortAt(index * FIELD_SLOTS + SIGNATURE_INDEX_OFFSET); 268 return getFields().at(index * FIELD_SLOTS + SIGNATURE_INDEX_OFFSET);
268 } 269 }
269 270
270 public Symbol getFieldSignature(int index) { 271 public Symbol getFieldSignature(int index) {
271 int signatureIndex = getFields().getShortAt(index * FIELD_SLOTS + SIGNATURE_INDEX_OFFSET); 272 int signatureIndex = getFields().at(index * FIELD_SLOTS + SIGNATURE_INDEX_OFFSET);
272 if (index < getJavaFieldsCount()) { 273 if (index < getJavaFieldsCount()) {
273 return getConstants().getSymbolAt(signatureIndex); 274 return getConstants().getSymbolAt(signatureIndex);
274 } else { 275 } else {
275 return vmSymbols.symbolAt(signatureIndex); 276 return vmSymbols.symbolAt(signatureIndex);
276 } 277 }
277 } 278 }
278 279
279 public short getFieldGenericSignatureIndex(int index) { 280 public short getFieldGenericSignatureIndex(int index) {
280 int len = (int)getFields().getLength(); 281 int len = getFields().length();
281 int allFieldsCount = getAllFieldsCount(); 282 int allFieldsCount = getAllFieldsCount();
282 int generic_signature_slot = allFieldsCount * FIELD_SLOTS; 283 int generic_signature_slot = allFieldsCount * FIELD_SLOTS;
283 for (int i = 0; i < allFieldsCount; i++) { 284 for (int i = 0; i < allFieldsCount; i++) {
284 short flags = getFieldAccessFlags(i); 285 short flags = getFieldAccessFlags(i);
285 AccessFlags access = new AccessFlags(flags); 286 AccessFlags access = new AccessFlags(flags);
286 if (i == index) { 287 if (i == index) {
287 if (access.fieldHasGenericSignature()) { 288 if (access.fieldHasGenericSignature()) {
288 return getFields().getShortAt(generic_signature_slot); 289 return getFields().at(generic_signature_slot);
289 } else { 290 } else {
290 return 0; 291 return 0;
291 } 292 }
292 } else { 293 } else {
293 if (access.fieldHasGenericSignature()) { 294 if (access.fieldHasGenericSignature()) {
306 return null; 307 return null;
307 } 308 }
308 309
309 public short getFieldInitialValueIndex(int index) { 310 public short getFieldInitialValueIndex(int index) {
310 if (index >= getJavaFieldsCount()) throw new IndexOutOfBoundsException("not a Java field;"); 311 if (index >= getJavaFieldsCount()) throw new IndexOutOfBoundsException("not a Java field;");
311 return getFields().getShortAt(index * FIELD_SLOTS + INITVAL_INDEX_OFFSET); 312 return getFields().at(index * FIELD_SLOTS + INITVAL_INDEX_OFFSET);
312 } 313 }
313 314
314 public int getFieldOffset(int index) { 315 public int getFieldOffset(int index) {
315 TypeArray fields = getFields(); 316 U2Array fields = getFields();
316 return VM.getVM().buildIntFromShorts(fields.getShortAt(index * FIELD_SLOTS + LOW_OFFSET), 317 return VM.getVM().buildIntFromShorts(fields.at(index * FIELD_SLOTS + LOW_OFFSET),
317 fields.getShortAt(index * FIELD_SLOTS + HIGH_OFFSET)); 318 fields.at(index * FIELD_SLOTS + HIGH_OFFSET));
318 } 319 }
319 320
320 // Accessors for declared fields 321 // Accessors for declared fields
321 public Klass getArrayKlasses() { return (Klass) arrayKlasses.getValue(this); } 322 public Klass getArrayKlasses() { return (Klass) arrayKlasses.getValue(this); }
322 public ObjArray getMethods() { return (ObjArray) methods.getValue(this); } 323 public MethodArray getMethods() { return new MethodArray(methods.getValue(getAddress())); }
323 public TypeArray getMethodOrdering() { return (TypeArray) methodOrdering.getValue(this); } 324 public KlassArray getLocalInterfaces() { return new KlassArray(localInterfaces.getValue(getAddress())); }
324 public ObjArray getLocalInterfaces() { return (ObjArray) localInterfaces.getValue(this); } 325 public KlassArray getTransitiveInterfaces() { return new KlassArray(transitiveInterfaces.getValue(getAddress())); }
325 public ObjArray getTransitiveInterfaces() { return (ObjArray) transitiveInterfaces.getValue(this); }
326 public TypeArray getFields() { return (TypeArray) fields.getValue(this); }
327 public int getJavaFieldsCount() { return (int) javaFieldsCount.getValue(this); } 326 public int getJavaFieldsCount() { return (int) javaFieldsCount.getValue(this); }
328 public int getAllFieldsCount() { 327 public int getAllFieldsCount() {
329 int len = (int)getFields().getLength(); 328 int len = getFields().length();
330 int allFieldsCount = 0; 329 int allFieldsCount = 0;
331 for (; allFieldsCount*FIELD_SLOTS < len; allFieldsCount++) { 330 for (; allFieldsCount*FIELD_SLOTS < len; allFieldsCount++) {
332 short flags = getFieldAccessFlags(allFieldsCount); 331 short flags = getFieldAccessFlags(allFieldsCount);
333 AccessFlags access = new AccessFlags(flags); 332 AccessFlags access = new AccessFlags(flags);
334 if (access.fieldHasGenericSignature()) { 333 if (access.fieldHasGenericSignature()) {
336 } 335 }
337 } 336 }
338 return allFieldsCount; 337 return allFieldsCount;
339 } 338 }
340 public ConstantPool getConstants() { return (ConstantPool) constants.getValue(this); } 339 public ConstantPool getConstants() { return (ConstantPool) constants.getValue(this); }
341 public Oop getClassLoader() { return classLoader.getValue(this); } 340 public ClassLoaderData getClassLoaderData() { return ClassLoaderData.instantiateWrapperFor(classLoaderData.getValue(getAddress())); }
341 public Oop getClassLoader() { return getClassLoaderData().getClassLoader(); }
342 public Oop getProtectionDomain() { return protectionDomain.getValue(this); } 342 public Oop getProtectionDomain() { return protectionDomain.getValue(this); }
343 public ObjArray getSigners() { return (ObjArray) signers.getValue(this); } 343 public ObjArray getSigners() { return (ObjArray) signers.getValue(this); }
344 public Symbol getSourceFileName() { return getSymbol(sourceFileName); } 344 public Symbol getSourceFileName() { return getSymbol(sourceFileName); }
345 public String getSourceDebugExtension(){ return CStringUtilities.getString(sourceDebugExtension.getValue(getHandle())); } 345 public String getSourceDebugExtension(){ return CStringUtilities.getString(sourceDebugExtension.getValue(getAddress())); }
346 public TypeArray getInnerClasses() { return (TypeArray) innerClasses.getValue(this); }
347 public long getNonstaticFieldSize() { return nonstaticFieldSize.getValue(this); } 346 public long getNonstaticFieldSize() { return nonstaticFieldSize.getValue(this); }
348 public long getStaticOopFieldCount() { return staticOopFieldCount.getValue(this); } 347 public long getStaticOopFieldCount() { return staticOopFieldCount.getValue(this); }
349 public long getNonstaticOopMapSize() { return nonstaticOopMapSize.getValue(this); } 348 public long getNonstaticOopMapSize() { return nonstaticOopMapSize.getValue(this); }
350 public boolean getIsMarkedDependent() { return isMarkedDependent.getValue(this) != 0; } 349 public boolean getIsMarkedDependent() { return isMarkedDependent.getValue(this) != 0; }
351 public long getVtableLen() { return vtableLen.getValue(this); } 350 public long getVtableLen() { return vtableLen.getValue(this); }
381 380
382 // refer to compute_modifier_flags in VM code. 381 // refer to compute_modifier_flags in VM code.
383 public long computeModifierFlags() { 382 public long computeModifierFlags() {
384 long access = getAccessFlags(); 383 long access = getAccessFlags();
385 // But check if it happens to be member class. 384 // But check if it happens to be member class.
386 TypeArray innerClassList = getInnerClasses(); 385 U2Array innerClassList = getInnerClasses();
387 int length = ( innerClassList == null)? 0 : (int) innerClassList.getLength(); 386 int length = (innerClassList == null)? 0 : (int) innerClassList.length();
388 if (length > 0) { 387 if (length > 0) {
389 if (Assert.ASSERTS_ENABLED) { 388 if (Assert.ASSERTS_ENABLED) {
390 Assert.that(length % InnerClassAttributeOffset.innerClassNextOffset == 0 || 389 Assert.that(length % InnerClassAttributeOffset.innerClassNextOffset == 0 ||
391 length % InnerClassAttributeOffset.innerClassNextOffset == EnclosingMethodAttributeOffset.enclosing_method_attribute_size, 390 length % InnerClassAttributeOffset.innerClassNextOffset == EnclosingMethodAttributeOffset.enclosing_method_attribute_size,
392 "just checking"); 391 "just checking");
393 } 392 }
394 for (int i = 0; i < length; i += InnerClassAttributeOffset.innerClassNextOffset) { 393 for (int i = 0; i < length; i += InnerClassAttributeOffset.innerClassNextOffset) {
395 if (i == length - EnclosingMethodAttributeOffset.enclosing_method_attribute_size) { 394 if (i == length - EnclosingMethodAttributeOffset.enclosing_method_attribute_size) {
396 break; 395 break;
397 } 396 }
398 int ioff = innerClassList.getShortAt(i + 397 int ioff = innerClassList.at(i +
399 InnerClassAttributeOffset.innerClassInnerClassInfoOffset); 398 InnerClassAttributeOffset.innerClassInnerClassInfoOffset);
400 // 'ioff' can be zero. 399 // 'ioff' can be zero.
401 // refer to JVM spec. section 4.7.5. 400 // refer to JVM spec. section 4.7.5.
402 if (ioff != 0) { 401 if (ioff != 0) {
403 // only look at classes that are already loaded 402 // only look at classes that are already loaded
404 // since we are looking for the flags for our self. 403 // since we are looking for the flags for our self.
405 ConstantPool.CPSlot classInfo = getConstants().getSlotAt(ioff); 404 ConstantPool.CPSlot classInfo = getConstants().getSlotAt(ioff);
406 Symbol name = null; 405 Symbol name = null;
407 if (classInfo.isOop()) { 406 if (classInfo.isResolved()) {
408 name = ((Klass) classInfo.getOop()).getName(); 407 name = classInfo.getKlass().getName();
409 } else if (classInfo.isMetaData()) { 408 } else if (classInfo.isUnresolved()) {
410 name = classInfo.getSymbol(); 409 name = classInfo.getSymbol();
411 } else { 410 } else {
412 throw new RuntimeException("should not reach here"); 411 throw new RuntimeException("should not reach here");
413 } 412 }
414 413
415 if (name.equals(getName())) { 414 if (name.equals(getName())) {
416 // This is really a member class 415 // This is really a member class
417 access = innerClassList.getShortAt(i + 416 access = innerClassList.at(i +
418 InnerClassAttributeOffset.innerClassAccessFlagsOffset); 417 InnerClassAttributeOffset.innerClassAccessFlagsOffset);
419 break; 418 break;
420 } 419 }
421 } 420 }
422 } // for inner classes 421 } // for inner classes
438 public boolean isInnerOrLocalClassName(Symbol sym) { 437 public boolean isInnerOrLocalClassName(Symbol sym) {
439 return isInInnerClasses(sym, true); 438 return isInInnerClasses(sym, true);
440 } 439 }
441 440
442 private boolean isInInnerClasses(Symbol sym, boolean includeLocals) { 441 private boolean isInInnerClasses(Symbol sym, boolean includeLocals) {
443 TypeArray innerClassList = getInnerClasses(); 442 U2Array innerClassList = getInnerClasses();
444 int length = ( innerClassList == null)? 0 : (int) innerClassList.getLength(); 443 int length = ( innerClassList == null)? 0 : (int) innerClassList.length();
445 if (length > 0) { 444 if (length > 0) {
446 if (Assert.ASSERTS_ENABLED) { 445 if (Assert.ASSERTS_ENABLED) {
447 Assert.that(length % InnerClassAttributeOffset.innerClassNextOffset == 0 || 446 Assert.that(length % InnerClassAttributeOffset.innerClassNextOffset == 0 ||
448 length % InnerClassAttributeOffset.innerClassNextOffset == EnclosingMethodAttributeOffset.enclosing_method_attribute_size, 447 length % InnerClassAttributeOffset.innerClassNextOffset == EnclosingMethodAttributeOffset.enclosing_method_attribute_size,
449 "just checking"); 448 "just checking");
450 } 449 }
451 for (int i = 0; i < length; i += InnerClassAttributeOffset.innerClassNextOffset) { 450 for (int i = 0; i < length; i += InnerClassAttributeOffset.innerClassNextOffset) {
452 if (i == length - EnclosingMethodAttributeOffset.enclosing_method_attribute_size) { 451 if (i == length - EnclosingMethodAttributeOffset.enclosing_method_attribute_size) {
453 break; 452 break;
454 } 453 }
455 int ioff = innerClassList.getShortAt(i + 454 int ioff = innerClassList.at(i +
456 InnerClassAttributeOffset.innerClassInnerClassInfoOffset); 455 InnerClassAttributeOffset.innerClassInnerClassInfoOffset);
457 // 'ioff' can be zero. 456 // 'ioff' can be zero.
458 // refer to JVM spec. section 4.7.5. 457 // refer to JVM spec. section 4.7.5.
459 if (ioff != 0) { 458 if (ioff != 0) {
460 ConstantPool.CPSlot iclassInfo = getConstants().getSlotAt(ioff); 459 ConstantPool.CPSlot iclassInfo = getConstants().getSlotAt(ioff);
461 Symbol innerName = null; 460 Symbol innerName = getConstants().getKlassNameAt(ioff);
462 if (iclassInfo.isOop()) {
463 innerName = ((Klass) iclassInfo.getOop()).getName();
464 } else if (iclassInfo.isMetaData()) {
465 innerName = iclassInfo.getSymbol();
466 } else {
467 throw new RuntimeException("should not reach here");
468 }
469
470 Symbol myname = getName(); 461 Symbol myname = getName();
471 int ooff = innerClassList.getShortAt(i + 462 int ooff = innerClassList.at(i +
472 InnerClassAttributeOffset.innerClassOuterClassInfoOffset); 463 InnerClassAttributeOffset.innerClassOuterClassInfoOffset);
473 // for anonymous classes inner_name_index of InnerClasses 464 // for anonymous classes inner_name_index of InnerClasses
474 // attribute is zero. 465 // attribute is zero.
475 int innerNameIndex = innerClassList.getShortAt(i + 466 int innerNameIndex = innerClassList.at(i +
476 InnerClassAttributeOffset.innerClassInnerNameOffset); 467 InnerClassAttributeOffset.innerClassInnerNameOffset);
477 // if this is not a member (anonymous, local etc.), 'ooff' will be zero 468 // if this is not a member (anonymous, local etc.), 'ooff' will be zero
478 // refer to JVM spec. section 4.7.5. 469 // refer to JVM spec. section 4.7.5.
479 if (ooff == 0) { 470 if (ooff == 0) {
480 if (includeLocals) { 471 if (includeLocals) {
486 } 477 }
487 } 478 }
488 } else { 479 } else {
489 ConstantPool.CPSlot oclassInfo = getConstants().getSlotAt(ooff); 480 ConstantPool.CPSlot oclassInfo = getConstants().getSlotAt(ooff);
490 Symbol outerName = null; 481 Symbol outerName = null;
491 if (oclassInfo.isOop()) { 482 if (oclassInfo.isResolved()) {
492 outerName = ((Klass) oclassInfo.getOop()).getName(); 483 outerName = oclassInfo.getKlass().getName();
493 } else if (oclassInfo.isMetaData()) { 484 } else if (oclassInfo.isUnresolved()) {
494 outerName = oclassInfo.getSymbol(); 485 outerName = oclassInfo.getSymbol();
495 } else { 486 } else {
496 throw new RuntimeException("should not reach here"); 487 throw new RuntimeException("should not reach here");
497 } 488 }
498 489
511 502
512 public boolean implementsInterface(Klass k) { 503 public boolean implementsInterface(Klass k) {
513 if (Assert.ASSERTS_ENABLED) { 504 if (Assert.ASSERTS_ENABLED) {
514 Assert.that(k.isInterface(), "should not reach here"); 505 Assert.that(k.isInterface(), "should not reach here");
515 } 506 }
516 ObjArray interfaces = getTransitiveInterfaces(); 507 KlassArray interfaces = getTransitiveInterfaces();
517 final int len = (int) interfaces.getLength(); 508 final int len = interfaces.length();
518 for (int i = 0; i < len; i++) { 509 for (int i = 0; i < len; i++) {
519 if (interfaces.getObjAt(i).equals(k)) return true; 510 if (interfaces.getAt(i).equals(k)) return true;
520 } 511 }
521 return false; 512 return false;
522 } 513 }
523 514
524 boolean computeSubtypeOf(Klass k) { 515 boolean computeSubtypeOf(Klass k) {
531 522
532 public void printValueOn(PrintStream tty) { 523 public void printValueOn(PrintStream tty) {
533 tty.print("InstanceKlass for " + getName().asString()); 524 tty.print("InstanceKlass for " + getName().asString());
534 } 525 }
535 526
536 public void iterateFields(OopVisitor visitor, boolean doVMFields) { 527 public void iterateFields(MetadataVisitor visitor) {
537 super.iterateFields(visitor, doVMFields); 528 super.iterateFields(visitor);
538 if (doVMFields) { 529 visitor.doMetadata(arrayKlasses, true);
539 visitor.doOop(arrayKlasses, true); 530 // visitor.doOop(methods, true);
540 visitor.doOop(methods, true); 531 // visitor.doOop(localInterfaces, true);
541 visitor.doOop(methodOrdering, true); 532 // visitor.doOop(transitiveInterfaces, true);
542 visitor.doOop(localInterfaces, true);
543 visitor.doOop(transitiveInterfaces, true);
544 visitor.doOop(fields, true);
545 visitor.doOop(constants, true);
546 visitor.doOop(classLoader, true);
547 visitor.doOop(protectionDomain, true); 533 visitor.doOop(protectionDomain, true);
548 visitor.doOop(signers, true); 534 visitor.doOop(signers, true);
549 visitor.doOop(innerClasses, true);
550 visitor.doCInt(nonstaticFieldSize, true); 535 visitor.doCInt(nonstaticFieldSize, true);
551 visitor.doCInt(staticFieldSize, true); 536 visitor.doCInt(staticFieldSize, true);
552 visitor.doCInt(staticOopFieldCount, true); 537 visitor.doCInt(staticOopFieldCount, true);
553 visitor.doCInt(nonstaticOopMapSize, true); 538 visitor.doCInt(nonstaticOopMapSize, true);
554 visitor.doCInt(isMarkedDependent, true); 539 visitor.doCInt(isMarkedDependent, true);
555 visitor.doCInt(initState, true); 540 visitor.doCInt(initState, true);
556 visitor.doCInt(vtableLen, true); 541 visitor.doCInt(vtableLen, true);
557 visitor.doCInt(itableLen, true); 542 visitor.doCInt(itableLen, true);
558 } 543 }
559 }
560 544
561 /* 545 /*
562 * Visit the static fields of this InstanceKlass with the obj of 546 * Visit the static fields of this InstanceKlass with the obj of
563 * the visitor set to the oop holding the fields, which is 547 * the visitor set to the oop holding the fields, which is
564 * currently the java mirror. 548 * currently the java mirror.
626 return null; 610 return null;
627 } 611 }
628 612
629 /** Find field in direct superinterfaces. */ 613 /** Find field in direct superinterfaces. */
630 public Field findInterfaceField(Symbol name, Symbol sig) { 614 public Field findInterfaceField(Symbol name, Symbol sig) {
631 ObjArray interfaces = getLocalInterfaces(); 615 KlassArray interfaces = getLocalInterfaces();
632 int n = (int) interfaces.getLength(); 616 int n = interfaces.length();
633 for (int i = 0; i < n; i++) { 617 for (int i = 0; i < n; i++) {
634 InstanceKlass intf1 = (InstanceKlass) interfaces.getObjAt(i); 618 InstanceKlass intf1 = (InstanceKlass) interfaces.getAt(i);
635 if (Assert.ASSERTS_ENABLED) { 619 if (Assert.ASSERTS_ENABLED) {
636 Assert.that(intf1.isInterface(), "just checking type"); 620 Assert.that(intf1.isInterface(), "just checking type");
637 } 621 }
638 // search for field in current interface 622 // search for field in current interface
639 Field f = intf1.findLocalField(name, sig); 623 Field f = intf1.findLocalField(name, sig);
725 List allFields = getImmediateFields(); 709 List allFields = getImmediateFields();
726 710
727 // transitiveInterfaces contains all interfaces implemented 711 // transitiveInterfaces contains all interfaces implemented
728 // by this class and its superclass chain with no duplicates. 712 // by this class and its superclass chain with no duplicates.
729 713
730 ObjArray interfaces = getTransitiveInterfaces(); 714 KlassArray interfaces = getTransitiveInterfaces();
731 int n = (int) interfaces.getLength(); 715 int n = interfaces.length();
732 for (int i = 0; i < n; i++) { 716 for (int i = 0; i < n; i++) {
733 InstanceKlass intf1 = (InstanceKlass) interfaces.getObjAt(i); 717 InstanceKlass intf1 = (InstanceKlass) interfaces.getAt(i);
734 if (Assert.ASSERTS_ENABLED) { 718 if (Assert.ASSERTS_ENABLED) {
735 Assert.that(intf1.isInterface(), "just checking type"); 719 Assert.that(intf1.isInterface(), "just checking type");
736 } 720 }
737 allFields.addAll(intf1.getImmediateFields()); 721 allFields.addAll(intf1.getImmediateFields());
738 } 722 }
757 */ 741 */
758 public List getImmediateMethods() { 742 public List getImmediateMethods() {
759 // Contains a Method for each method declared in this class/interface 743 // Contains a Method for each method declared in this class/interface
760 // not including inherited methods. 744 // not including inherited methods.
761 745
762 ObjArray methods = getMethods(); 746 MethodArray methods = getMethods();
763 int length = (int)methods.getLength(); 747 int length = methods.length();
764 Object[] tmp = new Object[length]; 748 Object[] tmp = new Object[length];
765 749
766 TypeArray methodOrdering = getMethodOrdering(); 750 IntArray methodOrdering = getMethodOrdering();
767 if (methodOrdering.getLength() != length) { 751 if (methodOrdering.length() != length) {
768 // no ordering info present 752 // no ordering info present
769 for (int index = 0; index < length; index++) { 753 for (int index = 0; index < length; index++) {
770 tmp[index] = methods.getObjAt(index); 754 tmp[index] = methods.at(index);
771 } 755 }
772 } else { 756 } else {
773 for (int index = 0; index < length; index++) { 757 for (int index = 0; index < length; index++) {
774 int originalIndex = getMethodOrdering().getIntAt(index); 758 int originalIndex = methodOrdering.at(index);
775 tmp[originalIndex] = methods.getObjAt(index); 759 tmp[originalIndex] = methods.at(index);
776 } 760 }
777 } 761 }
778 762
779 return Arrays.asList(tmp); 763 return Arrays.asList(tmp);
780 } 764 }
784 */ 768 */
785 public List getDirectImplementedInterfaces() { 769 public List getDirectImplementedInterfaces() {
786 // Contains an InstanceKlass for each interface in this classes 770 // Contains an InstanceKlass for each interface in this classes
787 // 'implements' clause. 771 // 'implements' clause.
788 772
789 ObjArray interfaces = getLocalInterfaces(); 773 KlassArray interfaces = getLocalInterfaces();
790 int length = (int) interfaces.getLength(); 774 int length = interfaces.length();
791 List directImplementedInterfaces = new ArrayList(length); 775 List directImplementedInterfaces = new ArrayList(length);
792 776
793 for (int index = 0; index < length; index ++) { 777 for (int index = 0; index < length; index ++) {
794 directImplementedInterfaces.add(interfaces.getObjAt(index)); 778 directImplementedInterfaces.add(interfaces.getAt(index));
795 } 779 }
796 780
797 return directImplementedInterfaces; 781 return directImplementedInterfaces;
798 } 782 }
799
800
801 public long getObjectSize() {
802 long bodySize = alignObjectOffset(getVtableLen() * getHeap().getOopSize())
803 + alignObjectOffset(getItableLen() * getHeap().getOopSize())
804 + (getNonstaticOopMapSize()) * getHeap().getOopSize();
805 return alignObjectSize(headerSize + bodySize);
806 }
807 783
808 public Klass arrayKlassImpl(boolean orNull, int n) { 784 public Klass arrayKlassImpl(boolean orNull, int n) {
809 // FIXME: in reflective system this would need to change to 785 // FIXME: in reflective system this would need to change to
810 // actually allocate 786 // actually allocate
811 if (getArrayKlasses() == null) { return null; } 787 if (getArrayKlasses() == null) { return null; }
839 /** Find method in vtable. */ 815 /** Find method in vtable. */
840 public Method findMethod(Symbol name, Symbol sig) { 816 public Method findMethod(Symbol name, Symbol sig) {
841 return findMethod(getMethods(), name, sig); 817 return findMethod(getMethods(), name, sig);
842 } 818 }
843 819
844 /** Breakpoint support (see methods on methodOop for details) */ 820 /** Breakpoint support (see methods on Method* for details) */
845 public BreakpointInfo getBreakpoints() { 821 public BreakpointInfo getBreakpoints() {
846 Address addr = getHandle().getAddressAt(Oop.getHeaderSize() + breakpoints.getOffset()); 822 Address addr = getAddress().getAddressAt(breakpoints.getOffset());
847 return (BreakpointInfo) VMObjectFactory.newObject(BreakpointInfo.class, addr); 823 return (BreakpointInfo) VMObjectFactory.newObject(BreakpointInfo.class, addr);
848 } 824 }
825
826 public IntArray getMethodOrdering() {
827 Address addr = getAddress().getAddressAt(methodOrdering.getOffset());
828 return (IntArray) VMObjectFactory.newObject(IntArray.class, addr);
829 }
830
831 public U2Array getFields() {
832 Address addr = getAddress().getAddressAt(fields.getOffset());
833 return (U2Array) VMObjectFactory.newObject(U2Array.class, addr);
834 }
835
836 public U2Array getInnerClasses() {
837 Address addr = getAddress().getAddressAt(innerClasses.getOffset());
838 return (U2Array) VMObjectFactory.newObject(U2Array.class, addr);
839 }
840
849 841
850 //---------------------------------------------------------------------- 842 //----------------------------------------------------------------------
851 // Internals only below this point 843 // Internals only below this point
852 // 844 //
853 845
926 return new BooleanField(this, index); 918 return new BooleanField(this, index);
927 } 919 }
928 throw new RuntimeException("Illegal field type at index " + index); 920 throw new RuntimeException("Illegal field type at index " + index);
929 } 921 }
930 922
931 private static Method findMethod(ObjArray methods, Symbol name, Symbol signature) { 923 private static Method findMethod(MethodArray methods, Symbol name, Symbol signature) {
932 int len = (int) methods.getLength(); 924 int len = methods.length();
933 // methods are sorted, so do binary search 925 // methods are sorted, so do binary search
934 int l = 0; 926 int l = 0;
935 int h = len - 1; 927 int h = len - 1;
936 while (l <= h) { 928 while (l <= h) {
937 int mid = (l + h) >> 1; 929 int mid = (l + h) >> 1;
938 Method m = (Method) methods.getObjAt(mid); 930 Method m = methods.at(mid);
939 int res = m.getName().fastCompare(name); 931 int res = m.getName().fastCompare(name);
940 if (res == 0) { 932 if (res == 0) {
941 // found matching name; do linear search to find matching signature 933 // found matching name; do linear search to find matching signature
942 // first, quick check for common case 934 // first, quick check for common case
943 if (m.getSignature().equals(signature)) return m; 935 if (m.getSignature().equals(signature)) return m;
944 // search downwards through overloaded methods 936 // search downwards through overloaded methods
945 int i; 937 int i;
946 for (i = mid - 1; i >= l; i--) { 938 for (i = mid - 1; i >= l; i--) {
947 Method m1 = (Method) methods.getObjAt(i); 939 Method m1 = methods.at(i);
948 if (!m1.getName().equals(name)) break; 940 if (!m1.getName().equals(name)) break;
949 if (m1.getSignature().equals(signature)) return m1; 941 if (m1.getSignature().equals(signature)) return m1;
950 } 942 }
951 // search upwards 943 // search upwards
952 for (i = mid + 1; i <= h; i++) { 944 for (i = mid + 1; i <= h; i++) {
953 Method m1 = (Method) methods.getObjAt(i); 945 Method m1 = methods.at(i);
954 if (!m1.getName().equals(name)) break; 946 if (!m1.getName().equals(name)) break;
955 if (m1.getSignature().equals(signature)) return m1; 947 if (m1.getSignature().equals(signature)) return m1;
956 } 948 }
957 // not found 949 // not found
958 if (Assert.ASSERTS_ENABLED) { 950 if (Assert.ASSERTS_ENABLED) {
975 } 967 }
976 } 968 }
977 return null; 969 return null;
978 } 970 }
979 971
980 private static int linearSearch(ObjArray methods, Symbol name, Symbol signature) { 972 private static int linearSearch(MethodArray methods, Symbol name, Symbol signature) {
981 int len = (int) methods.getLength(); 973 int len = (int) methods.length();
982 for (int index = 0; index < len; index++) { 974 for (int index = 0; index < len; index++) {
983 Method m = (Method) methods.getObjAt(index); 975 Method m = methods.at(index);
984 if (m.getSignature().equals(signature) && m.getName().equals(name)) { 976 if (m.getSignature().equals(signature) && m.getName().equals(name)) {
985 return index; 977 return index;
986 } 978 }
987 } 979 }
988 return -1; 980 return -1;