12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 package sun.jvm.hotspot.oops;
26
27 import java.io.*;
28 import java.util.*;
29 import sun.jvm.hotspot.classfile.ClassLoaderData;
30 import sun.jvm.hotspot.debugger.*;
31 import sun.jvm.hotspot.memory.*;
32 import sun.jvm.hotspot.runtime.*;
33 import sun.jvm.hotspot.types.*;
34 import sun.jvm.hotspot.utilities.*;
35
36 // An InstanceKlass is the VM level representation of a Java class.
37
38 public class InstanceKlass extends Klass {
39 static {
40 VM.registerVMInitializedObserver(new Observer() {
41 public void update(Observable o, Object data) {
42 initialize(VM.getVM().getTypeDataBase());
43 }
44 });
45 }
46
47 // field offset constants
48 private static int ACCESS_FLAGS_OFFSET;
49 private static int NAME_INDEX_OFFSET;
50 private static int SIGNATURE_INDEX_OFFSET;
51 private static int INITVAL_INDEX_OFFSET;
52 private static int LOW_OFFSET;
53 private static int HIGH_OFFSET;
54 private static int FIELD_SLOTS;
55 private static short FIELDINFO_TAG_SIZE;
56 private static short FIELDINFO_TAG_MASK;
57 private static short FIELDINFO_TAG_OFFSET;
58
59 // ClassState constants
60 private static int CLASS_STATE_ALLOCATED;
61 private static int CLASS_STATE_LOADED;
62 private static int CLASS_STATE_LINKED;
63 private static int CLASS_STATE_BEING_INITIALIZED;
64 private static int CLASS_STATE_FULLY_INITIALIZED;
65 private static int CLASS_STATE_INITIALIZATION_ERROR;
66
67 private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
68 Type type = db.lookupType("InstanceKlass");
69 arrayKlasses = new MetadataField(type.getAddressField("_array_klasses"), 0);
70 methods = type.getAddressField("_methods");
71 defaultMethods = type.getAddressField("_default_methods");
72 methodOrdering = type.getAddressField("_method_ordering");
73 localInterfaces = type.getAddressField("_local_interfaces");
74 transitiveInterfaces = type.getAddressField("_transitive_interfaces");
75 fields = type.getAddressField("_fields");
76 javaFieldsCount = new CIntField(type.getCIntegerField("_java_fields_count"), 0);
77 constants = new MetadataField(type.getAddressField("_constants"), 0);
78 classLoaderData = type.getAddressField("_class_loader_data");
79 sourceDebugExtension = type.getAddressField("_source_debug_extension");
80 innerClasses = type.getAddressField("_inner_classes");
81 sourceFileNameIndex = new CIntField(type.getCIntegerField("_source_file_name_index"), 0);
82 nonstaticFieldSize = new CIntField(type.getCIntegerField("_nonstatic_field_size"), 0);
83 staticFieldSize = new CIntField(type.getCIntegerField("_static_field_size"), 0);
84 staticOopFieldCount = new CIntField(type.getCIntegerField("_static_oop_field_count"), 0);
85 nonstaticOopMapSize = new CIntField(type.getCIntegerField("_nonstatic_oop_map_size"), 0);
86 isMarkedDependent = new CIntField(type.getCIntegerField("_is_marked_dependent"), 0);
87 initState = new CIntField(type.getCIntegerField("_init_state"), 0);
88 itableLen = new CIntField(type.getCIntegerField("_itable_len"), 0);
89 if (VM.getVM().isJvmtiSupported()) {
90 breakpoints = type.getAddressField("_breakpoints");
91 }
92 genericSignatureIndex = new CIntField(type.getCIntegerField("_generic_signature_index"), 0);
93 majorVersion = new CIntField(type.getCIntegerField("_major_version"), 0);
94 minorVersion = new CIntField(type.getCIntegerField("_minor_version"), 0);
95 headerSize = type.getSize();
96
97 // read field offset constants
98 ACCESS_FLAGS_OFFSET = db.lookupIntConstant("FieldInfo::access_flags_offset").intValue();
99 NAME_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::name_index_offset").intValue();
100 SIGNATURE_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::signature_index_offset").intValue();
101 INITVAL_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::initval_index_offset").intValue();
102 LOW_OFFSET = db.lookupIntConstant("FieldInfo::low_packed_offset").intValue();
103 HIGH_OFFSET = db.lookupIntConstant("FieldInfo::high_packed_offset").intValue();
104 FIELD_SLOTS = db.lookupIntConstant("FieldInfo::field_slots").intValue();
105 FIELDINFO_TAG_SIZE = db.lookupIntConstant("FIELDINFO_TAG_SIZE").shortValue();
106 FIELDINFO_TAG_MASK = db.lookupIntConstant("FIELDINFO_TAG_MASK").shortValue();
107 FIELDINFO_TAG_OFFSET = db.lookupIntConstant("FIELDINFO_TAG_OFFSET").shortValue();
108
109 // read ClassState constants
110 CLASS_STATE_ALLOCATED = db.lookupIntConstant("InstanceKlass::allocated").intValue();
111 CLASS_STATE_LOADED = db.lookupIntConstant("InstanceKlass::loaded").intValue();
112 CLASS_STATE_LINKED = db.lookupIntConstant("InstanceKlass::linked").intValue();
113 CLASS_STATE_BEING_INITIALIZED = db.lookupIntConstant("InstanceKlass::being_initialized").intValue();
114 CLASS_STATE_FULLY_INITIALIZED = db.lookupIntConstant("InstanceKlass::fully_initialized").intValue();
115 CLASS_STATE_INITIALIZATION_ERROR = db.lookupIntConstant("InstanceKlass::initialization_error").intValue();
116
117 }
118
119 public InstanceKlass(Address addr) {
120 super(addr);
121 if (getJavaFieldsCount() != getAllFieldsCount()) {
122 // Exercise the injected field logic
123 for (int i = getJavaFieldsCount(); i < getAllFieldsCount(); i++) {
124 getFieldName(i);
125 getFieldSignature(i);
126 }
127 }
128 }
129
130 private static MetadataField arrayKlasses;
131 private static AddressField methods;
132 private static AddressField defaultMethods;
133 private static AddressField methodOrdering;
134 private static AddressField localInterfaces;
135 private static AddressField transitiveInterfaces;
136 private static AddressField fields;
137 private static CIntField javaFieldsCount;
138 private static MetadataField constants;
139 private static AddressField classLoaderData;
140 private static AddressField sourceDebugExtension;
141 private static AddressField innerClasses;
142 private static CIntField sourceFileNameIndex;
143 private static CIntField nonstaticFieldSize;
144 private static CIntField staticFieldSize;
145 private static CIntField staticOopFieldCount;
146 private static CIntField nonstaticOopMapSize;
147 private static CIntField isMarkedDependent;
148 private static CIntField initState;
149 private static CIntField itableLen;
150 private static AddressField breakpoints;
151 private static CIntField genericSignatureIndex;
152 private static CIntField majorVersion;
153 private static CIntField minorVersion;
154
155 // type safe enum for ClassState from instanceKlass.hpp
156 public static class ClassState {
157 public static final ClassState ALLOCATED = new ClassState("allocated");
158 public static final ClassState LOADED = new ClassState("loaded");
159 public static final ClassState LINKED = new ClassState("linked");
160 public static final ClassState BEING_INITIALIZED = new ClassState("beingInitialized");
161 public static final ClassState FULLY_INITIALIZED = new ClassState("fullyInitialized");
162 public static final ClassState INITIALIZATION_ERROR = new ClassState("initializationError");
163
164 private ClassState(String value) {
165 this.value = value;
166 }
167
168 public String toString() {
169 return value;
170 }
171
226 if (isInitialized()) {
227 if (Assert.ASSERTS_ENABLED) {
228 Assert.that(isLinked(), "Class status is not consistent");
229 }
230 result |= JVMDIClassStatus.INITIALIZED;
231 }
232
233 if (isInErrorState()) {
234 result |= JVMDIClassStatus.ERROR;
235 }
236 return result;
237 }
238
239 // Byteside of the header
240 private static long headerSize;
241
242 public long getObjectSize(Oop object) {
243 return getSizeHelper() * VM.getVM().getAddressSize();
244 }
245
246 public long getSize() {
247 long wordLength = VM.getVM().getBytesPerWord();
248 long size = getHeaderSize() +
249 (getVtableLen() +
250 getItableLen() +
251 getNonstaticOopMapSize()) * wordLength;
252 if (isInterface()) {
253 size += wordLength;
254 }
255 return alignSize(size);
256 }
257
258 public static long getHeaderSize() { return headerSize; }
259
260 public short getFieldAccessFlags(int index) {
261 return getFields().at(index * FIELD_SLOTS + ACCESS_FLAGS_OFFSET);
262 }
263
264 public short getFieldNameIndex(int index) {
265 if (index >= getJavaFieldsCount()) throw new IndexOutOfBoundsException("not a Java field;");
266 return getFields().at(index * FIELD_SLOTS + NAME_INDEX_OFFSET);
267 }
268
269 public Symbol getFieldName(int index) {
270 int nameIndex = getFields().at(index * FIELD_SLOTS + NAME_INDEX_OFFSET);
271 if (index < getJavaFieldsCount()) {
272 return getConstants().getSymbolAt(nameIndex);
273 } else {
274 return vmSymbols.symbolAt(nameIndex);
275 }
276 }
277
|
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 package sun.jvm.hotspot.oops;
26
27 import java.io.*;
28 import java.util.*;
29 import sun.jvm.hotspot.classfile.ClassLoaderData;
30 import sun.jvm.hotspot.debugger.*;
31 import sun.jvm.hotspot.memory.*;
32 import sun.jvm.hotspot.memory.Dictionary;
33 import sun.jvm.hotspot.runtime.*;
34 import sun.jvm.hotspot.types.*;
35 import sun.jvm.hotspot.utilities.*;
36
37 // An InstanceKlass is the VM level representation of a Java class.
38
39 public class InstanceKlass extends Klass {
40 static {
41 VM.registerVMInitializedObserver(new Observer() {
42 public void update(Observable o, Object data) {
43 initialize(VM.getVM().getTypeDataBase());
44 }
45 });
46 }
47
48 // field offset constants
49 private static int ACCESS_FLAGS_OFFSET;
50 private static int NAME_INDEX_OFFSET;
51 private static int SIGNATURE_INDEX_OFFSET;
52 private static int INITVAL_INDEX_OFFSET;
53 private static int LOW_OFFSET;
54 private static int HIGH_OFFSET;
55 private static int FIELD_SLOTS;
56 private static short FIELDINFO_TAG_SIZE;
57 private static short FIELDINFO_TAG_MASK;
58 private static short FIELDINFO_TAG_OFFSET;
59
60 // ClassState constants
61 private static int CLASS_STATE_ALLOCATED;
62 private static int CLASS_STATE_LOADED;
63 private static int CLASS_STATE_LINKED;
64 private static int CLASS_STATE_BEING_INITIALIZED;
65 private static int CLASS_STATE_FULLY_INITIALIZED;
66 private static int CLASS_STATE_INITIALIZATION_ERROR;
67
68 // _misc_flags constants
69 private static int MISC_REWRITTEN;
70 private static int MISC_HAS_NONSTATIC_FIELDS;
71 private static int MISC_SHOULD_VERIFY_CLASS;
72 private static int MISC_IS_ANONYMOUS;
73 private static int MISC_IS_CONTENDED;
74 private static int MISC_HAS_DEFAULT_METHODS;
75 private static int MISC_DECLARES_DEFAULT_METHODS;
76 private static int MISC_HAS_BEEN_REDEFINED;
77 private static int MISC_HAS_PASSED_FINGERPRINT_CHECK;
78 private static int MISC_IS_SCRATCH_CLASS;
79 private static int MISC_IS_SHARED_BOOT_CLASS;
80 private static int MISC_IS_SHARED_PLATFORM_CLASS;
81 private static int MISC_IS_SHARED_APP_CLASS;
82
83 private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
84 Type type = db.lookupType("InstanceKlass");
85 arrayKlasses = new MetadataField(type.getAddressField("_array_klasses"), 0);
86 methods = type.getAddressField("_methods");
87 defaultMethods = type.getAddressField("_default_methods");
88 methodOrdering = type.getAddressField("_method_ordering");
89 localInterfaces = type.getAddressField("_local_interfaces");
90 transitiveInterfaces = type.getAddressField("_transitive_interfaces");
91 fields = type.getAddressField("_fields");
92 javaFieldsCount = new CIntField(type.getCIntegerField("_java_fields_count"), 0);
93 constants = new MetadataField(type.getAddressField("_constants"), 0);
94 classLoaderData = type.getAddressField("_class_loader_data");
95 sourceDebugExtension = type.getAddressField("_source_debug_extension");
96 innerClasses = type.getAddressField("_inner_classes");
97 sourceFileNameIndex = new CIntField(type.getCIntegerField("_source_file_name_index"), 0);
98 nonstaticFieldSize = new CIntField(type.getCIntegerField("_nonstatic_field_size"), 0);
99 staticFieldSize = new CIntField(type.getCIntegerField("_static_field_size"), 0);
100 staticOopFieldCount = new CIntField(type.getCIntegerField("_static_oop_field_count"), 0);
101 nonstaticOopMapSize = new CIntField(type.getCIntegerField("_nonstatic_oop_map_size"), 0);
102 isMarkedDependent = new CIntField(type.getCIntegerField("_is_marked_dependent"), 0);
103 initState = new CIntField(type.getCIntegerField("_init_state"), 0);
104 itableLen = new CIntField(type.getCIntegerField("_itable_len"), 0);
105 if (VM.getVM().isJvmtiSupported()) {
106 breakpoints = type.getAddressField("_breakpoints");
107 }
108 genericSignatureIndex = new CIntField(type.getCIntegerField("_generic_signature_index"), 0);
109 miscFlags = new CIntField(type.getCIntegerField("_misc_flags"), 0);
110 majorVersion = new CIntField(type.getCIntegerField("_major_version"), 0);
111 minorVersion = new CIntField(type.getCIntegerField("_minor_version"), 0);
112 headerSize = type.getSize();
113
114 // read field offset constants
115 ACCESS_FLAGS_OFFSET = db.lookupIntConstant("FieldInfo::access_flags_offset").intValue();
116 NAME_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::name_index_offset").intValue();
117 SIGNATURE_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::signature_index_offset").intValue();
118 INITVAL_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::initval_index_offset").intValue();
119 LOW_OFFSET = db.lookupIntConstant("FieldInfo::low_packed_offset").intValue();
120 HIGH_OFFSET = db.lookupIntConstant("FieldInfo::high_packed_offset").intValue();
121 FIELD_SLOTS = db.lookupIntConstant("FieldInfo::field_slots").intValue();
122 FIELDINFO_TAG_SIZE = db.lookupIntConstant("FIELDINFO_TAG_SIZE").shortValue();
123 FIELDINFO_TAG_MASK = db.lookupIntConstant("FIELDINFO_TAG_MASK").shortValue();
124 FIELDINFO_TAG_OFFSET = db.lookupIntConstant("FIELDINFO_TAG_OFFSET").shortValue();
125
126 // read ClassState constants
127 CLASS_STATE_ALLOCATED = db.lookupIntConstant("InstanceKlass::allocated").intValue();
128 CLASS_STATE_LOADED = db.lookupIntConstant("InstanceKlass::loaded").intValue();
129 CLASS_STATE_LINKED = db.lookupIntConstant("InstanceKlass::linked").intValue();
130 CLASS_STATE_BEING_INITIALIZED = db.lookupIntConstant("InstanceKlass::being_initialized").intValue();
131 CLASS_STATE_FULLY_INITIALIZED = db.lookupIntConstant("InstanceKlass::fully_initialized").intValue();
132 CLASS_STATE_INITIALIZATION_ERROR = db.lookupIntConstant("InstanceKlass::initialization_error").intValue();
133
134 MISC_REWRITTEN = db.lookupIntConstant("InstanceKlass::_misc_rewritten").intValue();
135 MISC_HAS_NONSTATIC_FIELDS = db.lookupIntConstant("InstanceKlass::_misc_has_nonstatic_fields").intValue();
136 MISC_SHOULD_VERIFY_CLASS = db.lookupIntConstant("InstanceKlass::_misc_should_verify_class").intValue();
137 MISC_IS_ANONYMOUS = db.lookupIntConstant("InstanceKlass::_misc_is_anonymous").intValue();
138 MISC_IS_CONTENDED = db.lookupIntConstant("InstanceKlass::_misc_is_contended").intValue();
139 MISC_HAS_DEFAULT_METHODS = db.lookupIntConstant("InstanceKlass::_misc_has_default_methods").intValue();
140 MISC_DECLARES_DEFAULT_METHODS = db.lookupIntConstant("InstanceKlass::_misc_declares_default_methods").intValue();
141 MISC_HAS_BEEN_REDEFINED = db.lookupIntConstant("InstanceKlass::_misc_has_been_redefined").intValue();
142 MISC_HAS_PASSED_FINGERPRINT_CHECK = db.lookupIntConstant("InstanceKlass::_misc_has_passed_fingerprint_check").intValue();
143 MISC_IS_SCRATCH_CLASS = db.lookupIntConstant("InstanceKlass::_misc_is_scratch_class").intValue();
144 MISC_IS_SHARED_BOOT_CLASS = db.lookupIntConstant("InstanceKlass::_misc_is_shared_boot_class").intValue();
145 MISC_IS_SHARED_PLATFORM_CLASS = db.lookupIntConstant("InstanceKlass::_misc_is_shared_platform_class").intValue();
146 MISC_IS_SHARED_APP_CLASS = db.lookupIntConstant("InstanceKlass::_misc_is_shared_app_class").intValue();
147 }
148
149 public InstanceKlass(Address addr) {
150 super(addr);
151 if (getJavaFieldsCount() != getAllFieldsCount()) {
152 // Exercise the injected field logic
153 for (int i = getJavaFieldsCount(); i < getAllFieldsCount(); i++) {
154 getFieldName(i);
155 getFieldSignature(i);
156 }
157 }
158 }
159
160 private static MetadataField arrayKlasses;
161 private static AddressField methods;
162 private static AddressField defaultMethods;
163 private static AddressField methodOrdering;
164 private static AddressField localInterfaces;
165 private static AddressField transitiveInterfaces;
166 private static AddressField fields;
167 private static CIntField javaFieldsCount;
168 private static MetadataField constants;
169 private static AddressField classLoaderData;
170 private static AddressField sourceDebugExtension;
171 private static AddressField innerClasses;
172 private static CIntField sourceFileNameIndex;
173 private static CIntField nonstaticFieldSize;
174 private static CIntField staticFieldSize;
175 private static CIntField staticOopFieldCount;
176 private static CIntField nonstaticOopMapSize;
177 private static CIntField isMarkedDependent;
178 private static CIntField initState;
179 private static CIntField itableLen;
180 private static AddressField breakpoints;
181 private static CIntField genericSignatureIndex;
182 private static CIntField miscFlags;
183 private static CIntField majorVersion;
184 private static CIntField minorVersion;
185
186 // type safe enum for ClassState from instanceKlass.hpp
187 public static class ClassState {
188 public static final ClassState ALLOCATED = new ClassState("allocated");
189 public static final ClassState LOADED = new ClassState("loaded");
190 public static final ClassState LINKED = new ClassState("linked");
191 public static final ClassState BEING_INITIALIZED = new ClassState("beingInitialized");
192 public static final ClassState FULLY_INITIALIZED = new ClassState("fullyInitialized");
193 public static final ClassState INITIALIZATION_ERROR = new ClassState("initializationError");
194
195 private ClassState(String value) {
196 this.value = value;
197 }
198
199 public String toString() {
200 return value;
201 }
202
257 if (isInitialized()) {
258 if (Assert.ASSERTS_ENABLED) {
259 Assert.that(isLinked(), "Class status is not consistent");
260 }
261 result |= JVMDIClassStatus.INITIALIZED;
262 }
263
264 if (isInErrorState()) {
265 result |= JVMDIClassStatus.ERROR;
266 }
267 return result;
268 }
269
270 // Byteside of the header
271 private static long headerSize;
272
273 public long getObjectSize(Oop object) {
274 return getSizeHelper() * VM.getVM().getAddressSize();
275 }
276
277 public long getSize() { // in number of bytes
278 long wordLength = VM.getVM().getBytesPerWord();
279 long size = getHeaderSize() +
280 (getVtableLen() +
281 getItableLen() +
282 getNonstaticOopMapSize()) * wordLength;
283 if (isInterface()) {
284 size += wordLength;
285 }
286 if (isAnonymous()) {
287 size += wordLength;
288 }
289 if (hasStoredFingerprint()) {
290 size += 8; // uint64_t
291 }
292 return alignSize(size);
293 }
294
295 private int getMiscFlags() {
296 return (int) miscFlags.getValue(this);
297 }
298
299 public boolean isAnonymous() {
300 return (getMiscFlags() & MISC_IS_ANONYMOUS) != 0;
301 }
302
303 public static boolean shouldStoreFingerprint() {
304 VM vm = VM.getVM();
305 if (vm.getCommandLineBooleanFlag("EnableJVMCI") && !vm.getCommandLineBooleanFlag("UseJVMCICompiler")) {
306 return true;
307 }
308 if (vm.getCommandLineBooleanFlag("DumpSharedSpaces")) {
309 return true;
310 }
311 return false;
312 }
313
314 public boolean hasStoredFingerprint() {
315 return shouldStoreFingerprint() || isShared();
316 }
317
318 public boolean isShared() {
319 VM vm = VM.getVM();
320 if (vm.isSharingEnabled()) {
321 // This is not the same implementation as the C++ function MetaspaceObj::is_shared()
322 // bool MetaspaceObj::is_shared() const {
323 // return MetaspaceShared::is_in_shared_space(this);
324 // }
325 // However, MetaspaceShared::is_in_shared_space is complicated and hard to emulate in
326 // Java code, so let's do this by looking up from the shared dictionary. Of course,
327 // this works for shared InstanceKlass only and does not work for other types of
328 // MetaspaceObj in the CDS shared archive.
329 Dictionary sharedDictionary = vm.getSystemDictionary().sharedDictionary();
330 if (sharedDictionary != null) {
331 if (sharedDictionary.contains(this, null)) {
332 return true;
333 }
334 }
335 }
336 return false;
337 }
338
339 public static long getHeaderSize() { return headerSize; }
340
341 public short getFieldAccessFlags(int index) {
342 return getFields().at(index * FIELD_SLOTS + ACCESS_FLAGS_OFFSET);
343 }
344
345 public short getFieldNameIndex(int index) {
346 if (index >= getJavaFieldsCount()) throw new IndexOutOfBoundsException("not a Java field;");
347 return getFields().at(index * FIELD_SLOTS + NAME_INDEX_OFFSET);
348 }
349
350 public Symbol getFieldName(int index) {
351 int nameIndex = getFields().at(index * FIELD_SLOTS + NAME_INDEX_OFFSET);
352 if (index < getJavaFieldsCount()) {
353 return getConstants().getSymbolAt(nameIndex);
354 } else {
355 return vmSymbols.symbolAt(nameIndex);
356 }
357 }
358
|