1 /*
2 * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
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 *
36 import sun.jvm.hotspot.utilities.Observable;
37 import sun.jvm.hotspot.utilities.Observer;
38
39 // An InstanceKlass is the VM level representation of a Java class.
40
41 public class InstanceKlass extends Klass {
42 static {
43 VM.registerVMInitializedObserver(new Observer() {
44 public void update(Observable o, Object data) {
45 initialize(VM.getVM().getTypeDataBase());
46 }
47 });
48 }
49
50 // internal field flags constants
51 static int FIELD_FLAG_IS_INITIALIZED;
52 static int FIELD_FLAG_IS_INJECTED;
53 static int FIELD_FLAG_IS_GENERIC;
54 static int FIELD_FLAG_IS_STABLE;
55 static int FIELD_FLAG_IS_CONTENDED;
56
57 // ClassState constants
58 private static int CLASS_STATE_ALLOCATED;
59 private static int CLASS_STATE_LOADED;
60 private static int CLASS_STATE_LINKED;
61 private static int CLASS_STATE_BEING_INITIALIZED;
62 private static int CLASS_STATE_FULLY_INITIALIZED;
63 private static int CLASS_STATE_INITIALIZATION_ERROR;
64
65 public long getAccessFlags() { return accessFlags.getValue(this); }
66 // Convenience routine
67 public AccessFlags getAccessFlagsObj() { return new AccessFlags(getAccessFlags()); }
68
69 public boolean isPublic() { return getAccessFlagsObj().isPublic(); }
70 public boolean isFinal() { return getAccessFlagsObj().isFinal(); }
71 public boolean isInterface() { return getAccessFlagsObj().isInterface(); }
72 public boolean isAbstract() { return getAccessFlagsObj().isAbstract(); }
73 public boolean isSuper() { return getAccessFlagsObj().isSuper(); }
74 public boolean isSynthetic() { return getAccessFlagsObj().isSynthetic(); }
75
76 private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
77 Type type = db.lookupType("InstanceKlass");
78 annotations = type.getAddressField("_annotations");
79 arrayKlasses = new MetadataField(type.getAddressField("_array_klasses"), 0);
80 methods = type.getAddressField("_methods");
81 defaultMethods = type.getAddressField("_default_methods");
82 methodOrdering = type.getAddressField("_method_ordering");
83 localInterfaces = type.getAddressField("_local_interfaces");
84 transitiveInterfaces = type.getAddressField("_transitive_interfaces");
85 fieldinfoStream = type.getAddressField("_fieldinfo_stream");
86 constants = new MetadataField(type.getAddressField("_constants"), 0);
87 sourceDebugExtension = type.getAddressField("_source_debug_extension");
88 innerClasses = type.getAddressField("_inner_classes");
89 nestMembers = type.getAddressField("_nest_members");
90 nonstaticFieldSize = new CIntField(type.getCIntegerField("_nonstatic_field_size"), 0);
91 staticFieldSize = new CIntField(type.getCIntegerField("_static_field_size"), 0);
92 staticOopFieldCount = new CIntField(type.getCIntegerField("_static_oop_field_count"), 0);
93 nonstaticOopMapSize = new CIntField(type.getCIntegerField("_nonstatic_oop_map_size"), 0);
94 initState = new CIntField(type.getCIntegerField("_init_state"), 0);
95 itableLen = new CIntField(type.getCIntegerField("_itable_len"), 0);
96 nestHostIndex = new CIntField(type.getCIntegerField("_nest_host_index"), 0);
97 if (VM.getVM().isJvmtiSupported()) {
98 breakpoints = type.getAddressField("_breakpoints");
99 }
100 headerSize = type.getSize();
101 accessFlags = new CIntField(type.getCIntegerField("_access_flags"), 0);
102
103 // read internal field flags constants
104 FIELD_FLAG_IS_INITIALIZED = db.lookupIntConstant("FieldInfo::FieldFlags::_ff_initialized");
105 FIELD_FLAG_IS_INJECTED = db.lookupIntConstant("FieldInfo::FieldFlags::_ff_injected");
106 FIELD_FLAG_IS_GENERIC = db.lookupIntConstant("FieldInfo::FieldFlags::_ff_generic");
107 FIELD_FLAG_IS_STABLE = db.lookupIntConstant("FieldInfo::FieldFlags::_ff_stable");
108 FIELD_FLAG_IS_CONTENDED = db.lookupIntConstant("FieldInfo::FieldFlags::_ff_contended");
109
110
111 // read ClassState constants
112 CLASS_STATE_ALLOCATED = db.lookupIntConstant("InstanceKlass::allocated").intValue();
113 CLASS_STATE_LOADED = db.lookupIntConstant("InstanceKlass::loaded").intValue();
114 CLASS_STATE_LINKED = db.lookupIntConstant("InstanceKlass::linked").intValue();
115 CLASS_STATE_BEING_INITIALIZED = db.lookupIntConstant("InstanceKlass::being_initialized").intValue();
116 CLASS_STATE_FULLY_INITIALIZED = db.lookupIntConstant("InstanceKlass::fully_initialized").intValue();
117 CLASS_STATE_INITIALIZATION_ERROR = db.lookupIntConstant("InstanceKlass::initialization_error").intValue();
118 // We need a new fieldsCache each time we attach.
119 fieldsCache = new WeakHashMap<Address, Field[]>();
120 }
121
122 public InstanceKlass(Address addr) {
123 super(addr);
124
125 // If the class hasn't yet reached the "loaded" init state, then don't go any further
126 // or we'll run into problems trying to look at fields that are not yet setup.
127 // Attempted lookups of this InstanceKlass via ClassLoaderDataGraph, ClassLoaderData,
128 // and Dictionary will all refuse to return it. The main purpose of allowing this
|
1 /*
2 * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
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 *
36 import sun.jvm.hotspot.utilities.Observable;
37 import sun.jvm.hotspot.utilities.Observer;
38
39 // An InstanceKlass is the VM level representation of a Java class.
40
41 public class InstanceKlass extends Klass {
42 static {
43 VM.registerVMInitializedObserver(new Observer() {
44 public void update(Observable o, Object data) {
45 initialize(VM.getVM().getTypeDataBase());
46 }
47 });
48 }
49
50 // internal field flags constants
51 static int FIELD_FLAG_IS_INITIALIZED;
52 static int FIELD_FLAG_IS_INJECTED;
53 static int FIELD_FLAG_IS_GENERIC;
54 static int FIELD_FLAG_IS_STABLE;
55 static int FIELD_FLAG_IS_CONTENDED;
56 static int FIELD_FLAG_IS_NULL_FREE_INLINE;
57 static int FIELD_FLAG_IS_FLAT;
58 static int FIELD_FLAG_IS_NULL_MARKER;
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 public long getAccessFlags() { return accessFlags.getValue(this); }
69 // Convenience routine
70 public AccessFlags getAccessFlagsObj() { return new AccessFlags(getAccessFlags()); }
71
72 public boolean isPublic() { return getAccessFlagsObj().isPublic(); }
73 public boolean isFinal() { return getAccessFlagsObj().isFinal(); }
74 public boolean isInterface() { return getAccessFlagsObj().isInterface(); }
75 public boolean isAbstract() { return getAccessFlagsObj().isAbstract(); }
76 public boolean isSuper() { return getAccessFlagsObj().isSuper(); }
77 public boolean isSynthetic() { return getAccessFlagsObj().isSynthetic(); }
78
79 public boolean supportsInlineTypes() {
80 return majorVersion() >= VALUE_TYPES_MAJOR_VERSION && minorVersion() == JAVA_PREVIEW_MINOR_VERSION;
81 }
82
83 private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
84 Type type = db.lookupType("InstanceKlass");
85 annotations = type.getAddressField("_annotations");
86 arrayKlasses = new MetadataField(type.getAddressField("_array_klasses"), 0);
87 methods = type.getAddressField("_methods");
88 defaultMethods = type.getAddressField("_default_methods");
89 methodOrdering = type.getAddressField("_method_ordering");
90 localInterfaces = type.getAddressField("_local_interfaces");
91 transitiveInterfaces = type.getAddressField("_transitive_interfaces");
92 fieldinfoStream = type.getAddressField("_fieldinfo_stream");
93 constants = new MetadataField(type.getAddressField("_constants"), 0);
94 sourceDebugExtension = type.getAddressField("_source_debug_extension");
95 innerClasses = type.getAddressField("_inner_classes");
96 nestMembers = type.getAddressField("_nest_members");
97 nonstaticFieldSize = new CIntField(type.getCIntegerField("_nonstatic_field_size"), 0);
98 staticFieldSize = new CIntField(type.getCIntegerField("_static_field_size"), 0);
99 staticOopFieldCount = new CIntField(type.getCIntegerField("_static_oop_field_count"), 0);
100 nonstaticOopMapSize = new CIntField(type.getCIntegerField("_nonstatic_oop_map_size"), 0);
101 initState = new CIntField(type.getCIntegerField("_init_state"), 0);
102 itableLen = new CIntField(type.getCIntegerField("_itable_len"), 0);
103 nestHostIndex = new CIntField(type.getCIntegerField("_nest_host_index"), 0);
104 if (VM.getVM().isJvmtiSupported()) {
105 breakpoints = type.getAddressField("_breakpoints");
106 }
107 headerSize = type.getSize();
108 accessFlags = new CIntField(type.getCIntegerField("_access_flags"), 0);
109
110 // read internal field flags constants
111 FIELD_FLAG_IS_INITIALIZED = db.lookupIntConstant("FieldInfo::FieldFlags::_ff_initialized");
112 FIELD_FLAG_IS_INJECTED = db.lookupIntConstant("FieldInfo::FieldFlags::_ff_injected");
113 FIELD_FLAG_IS_GENERIC = db.lookupIntConstant("FieldInfo::FieldFlags::_ff_generic");
114 FIELD_FLAG_IS_STABLE = db.lookupIntConstant("FieldInfo::FieldFlags::_ff_stable");
115 FIELD_FLAG_IS_CONTENDED = db.lookupIntConstant("FieldInfo::FieldFlags::_ff_contended");
116 FIELD_FLAG_IS_NULL_FREE_INLINE = db.lookupIntConstant("FieldInfo::FieldFlags::_ff_null_free_inline_type");
117 FIELD_FLAG_IS_FLAT = db.lookupIntConstant("FieldInfo::FieldFlags::_ff_flat");
118 FIELD_FLAG_IS_NULL_MARKER = db.lookupIntConstant("FieldInfo::FieldFlags::_ff_null_marker");
119
120
121 // read ClassState constants
122 CLASS_STATE_ALLOCATED = db.lookupIntConstant("InstanceKlass::allocated").intValue();
123 CLASS_STATE_LOADED = db.lookupIntConstant("InstanceKlass::loaded").intValue();
124 CLASS_STATE_LINKED = db.lookupIntConstant("InstanceKlass::linked").intValue();
125 CLASS_STATE_BEING_INITIALIZED = db.lookupIntConstant("InstanceKlass::being_initialized").intValue();
126 CLASS_STATE_FULLY_INITIALIZED = db.lookupIntConstant("InstanceKlass::fully_initialized").intValue();
127 CLASS_STATE_INITIALIZATION_ERROR = db.lookupIntConstant("InstanceKlass::initialization_error").intValue();
128 // We need a new fieldsCache each time we attach.
129 fieldsCache = new WeakHashMap<Address, Field[]>();
130 }
131
132 public InstanceKlass(Address addr) {
133 super(addr);
134
135 // If the class hasn't yet reached the "loaded" init state, then don't go any further
136 // or we'll run into problems trying to look at fields that are not yet setup.
137 // Attempted lookups of this InstanceKlass via ClassLoaderDataGraph, ClassLoaderData,
138 // and Dictionary will all refuse to return it. The main purpose of allowing this
|