82 // [A] In most of the cases, the module bootstrap code will update the static field
83 // to point to part of the archived module graph. E.g.,
84 // - java/lang/System::bootLayer
85 // - jdk/internal/loader/ClassLoaders::BOOT_LOADER
86 // [B] A final static String that's explicitly initialized inside <clinit>, but
87 // its value is deterministic and is always the same string literal.
88 // [C] A non-final static string that is assigned a string literal during class
89 // initialization; this string is never changed during -Xshare:dump.
90 // [D] Simple caches whose value doesn't matter.
91 // [E] Other cases (see comments in-line below).
92
93 CDSHeapVerifier::CDSHeapVerifier() : _archived_objs(0), _problems(0)
94 {
95 # define ADD_EXCL(...) { static const char* e[] = {__VA_ARGS__, nullptr}; add_exclusion(e); }
96
97 // Unfortunately this needs to be manually maintained. If
98 // test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchivedEnumTest.java fails,
99 // you might need to fix the core library code, or fix the ADD_EXCL entries below.
100 //
101 // class field type
102 ADD_EXCL("java/lang/ClassLoader", "scl"); // A
103 ADD_EXCL("java/lang/Module", "ALL_UNNAMED_MODULE", // A
104 "ALL_UNNAMED_MODULE_SET", // A
105 "EVERYONE_MODULE", // A
106 "EVERYONE_SET"); // A
107
108 // This is the same as java/util/ImmutableCollections::EMPTY_SET, which is archived
109 ADD_EXCL("java/lang/reflect/AccessFlag$Location", "EMPTY_SET"); // E
110
111 ADD_EXCL("java/lang/System", "bootLayer"); // A
112
113 ADD_EXCL("java/util/Collections", "EMPTY_LIST"); // E
114
115 // A dummy object used by HashSet. The value doesn't matter and it's never
116 // tested for equality.
117 ADD_EXCL("java/util/HashSet", "PRESENT"); // E
118 ADD_EXCL("jdk/internal/loader/BuiltinClassLoader", "packageToModule"); // A
119 ADD_EXCL("jdk/internal/loader/ClassLoaders", "BOOT_LOADER", // A
120 "APP_LOADER", // A
121 "PLATFORM_LOADER"); // A
122 ADD_EXCL("jdk/internal/module/Builder", "cachedVersion"); // D
128
129 // This just points to an empty Map
130 ADD_EXCL("jdk/internal/reflect/Reflection", "methodFilterMap"); // E
131
132 // Integer for 0 and 1 are in java/lang/Integer$IntegerCache and are archived
133 ADD_EXCL("sun/invoke/util/ValueConversions", "ONE_INT", // E
134 "ZERO_INT"); // E
135
136 if (CDSConfig::is_dumping_method_handles()) {
137 ADD_EXCL("java/lang/invoke/InvokerBytecodeGenerator", "MEMBERNAME_FACTORY", // D
138 "CD_Object_array", // E same as <...>ConstantUtils.CD_Object_array::CD_Object
139 "INVOKER_SUPER_DESC"); // E same as java.lang.constant.ConstantDescs::CD_Object
140
141 ADD_EXCL("java/lang/invoke/MethodHandleImpl$ArrayAccessor",
142 "OBJECT_ARRAY_GETTER", // D
143 "OBJECT_ARRAY_SETTER", // D
144 "OBJECT_ARRAY_LENGTH"); // D
145
146 }
147
148 # undef ADD_EXCL
149
150 ClassLoaderDataGraph::classes_do(this);
151 }
152
153 CDSHeapVerifier::~CDSHeapVerifier() {
154 if (_problems > 0) {
155 log_error(cds, heap)("Scanned %d objects. Found %d case(s) where "
156 "an object points to a static field that "
157 "may hold a different value at runtime.", _archived_objs, _problems);
158 log_error(cds, heap)("Please see cdsHeapVerifier.cpp and aotClassInitializer.cpp for details");
159 MetaspaceShared::unrecoverable_writing_error();
160 }
161 }
162
163 class CDSHeapVerifier::CheckStaticFields : public FieldClosure {
164 CDSHeapVerifier* _verifier;
165 InstanceKlass* _ik; // The class whose static fields are being checked.
166 const char** _exclusions;
167 public:
168 CheckStaticFields(CDSHeapVerifier* verifier, InstanceKlass* ik)
169 : _verifier(verifier), _ik(ik) {
170 _exclusions = _verifier->find_exclusion(_ik);
171 }
172
173 void do_field(fieldDescriptor* fd) {
174 if (fd->field_type() != T_OBJECT) {
175 return;
176 }
177
178 if (fd->signature()->equals("Ljdk/internal/access/JavaLangAccess;")) {
179 // A few classes have static fields that point to SharedSecrets.getJavaLangAccess().
|
82 // [A] In most of the cases, the module bootstrap code will update the static field
83 // to point to part of the archived module graph. E.g.,
84 // - java/lang/System::bootLayer
85 // - jdk/internal/loader/ClassLoaders::BOOT_LOADER
86 // [B] A final static String that's explicitly initialized inside <clinit>, but
87 // its value is deterministic and is always the same string literal.
88 // [C] A non-final static string that is assigned a string literal during class
89 // initialization; this string is never changed during -Xshare:dump.
90 // [D] Simple caches whose value doesn't matter.
91 // [E] Other cases (see comments in-line below).
92
93 CDSHeapVerifier::CDSHeapVerifier() : _archived_objs(0), _problems(0)
94 {
95 # define ADD_EXCL(...) { static const char* e[] = {__VA_ARGS__, nullptr}; add_exclusion(e); }
96
97 // Unfortunately this needs to be manually maintained. If
98 // test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchivedEnumTest.java fails,
99 // you might need to fix the core library code, or fix the ADD_EXCL entries below.
100 //
101 // class field type
102 ADD_EXCL("java/lang/ClassLoader$Holder", "scl"); // A
103 ADD_EXCL("java/lang/Module", "ALL_UNNAMED_MODULE", // A
104 "ALL_UNNAMED_MODULE_SET", // A
105 "EVERYONE_MODULE", // A
106 "EVERYONE_SET"); // A
107
108 // This is the same as java/util/ImmutableCollections::EMPTY_SET, which is archived
109 ADD_EXCL("java/lang/reflect/AccessFlag$Location", "EMPTY_SET"); // E
110
111 ADD_EXCL("java/lang/System", "bootLayer"); // A
112
113 ADD_EXCL("java/util/Collections", "EMPTY_LIST"); // E
114
115 // A dummy object used by HashSet. The value doesn't matter and it's never
116 // tested for equality.
117 ADD_EXCL("java/util/HashSet", "PRESENT"); // E
118 ADD_EXCL("jdk/internal/loader/BuiltinClassLoader", "packageToModule"); // A
119 ADD_EXCL("jdk/internal/loader/ClassLoaders", "BOOT_LOADER", // A
120 "APP_LOADER", // A
121 "PLATFORM_LOADER"); // A
122 ADD_EXCL("jdk/internal/module/Builder", "cachedVersion"); // D
128
129 // This just points to an empty Map
130 ADD_EXCL("jdk/internal/reflect/Reflection", "methodFilterMap"); // E
131
132 // Integer for 0 and 1 are in java/lang/Integer$IntegerCache and are archived
133 ADD_EXCL("sun/invoke/util/ValueConversions", "ONE_INT", // E
134 "ZERO_INT"); // E
135
136 if (CDSConfig::is_dumping_method_handles()) {
137 ADD_EXCL("java/lang/invoke/InvokerBytecodeGenerator", "MEMBERNAME_FACTORY", // D
138 "CD_Object_array", // E same as <...>ConstantUtils.CD_Object_array::CD_Object
139 "INVOKER_SUPER_DESC"); // E same as java.lang.constant.ConstantDescs::CD_Object
140
141 ADD_EXCL("java/lang/invoke/MethodHandleImpl$ArrayAccessor",
142 "OBJECT_ARRAY_GETTER", // D
143 "OBJECT_ARRAY_SETTER", // D
144 "OBJECT_ARRAY_LENGTH"); // D
145
146 }
147
148 if (CDSConfig::is_dumping_packages()) {
149 ADD_EXCL("java/lang/Package$VersionInfo", "NULL_VERSION_INFO"); // D
150 }
151
152 // These are used by BuiltinClassLoader::negativeLookupCache, etc but seem to be
153 // OK. TODO - we should completely disable the caching unless ArchiveLoaderLookupCache
154 // is enabled
155 ADD_EXCL("java/lang/Boolean", "TRUE", // E
156 "FALSE"); // E
157
158 # undef ADD_EXCL
159
160 ClassLoaderDataGraph::classes_do(this);
161 }
162
163 CDSHeapVerifier::~CDSHeapVerifier() {
164 if (_problems > 0) {
165 log_error(cds, heap)("Scanned %d objects. Found %d case(s) where "
166 "an object points to a static field that "
167 "may hold a different value at runtime.", _archived_objs, _problems);
168 log_error(cds, heap)("Please see cdsHeapVerifier.cpp and aotClassInitializer.cpp for details");
169 //MetaspaceShared::unrecoverable_writing_error(); // FIXME -- leyden+JEP483 merge
170 }
171 }
172
173 class CDSHeapVerifier::CheckStaticFields : public FieldClosure {
174 CDSHeapVerifier* _verifier;
175 InstanceKlass* _ik; // The class whose static fields are being checked.
176 const char** _exclusions;
177 public:
178 CheckStaticFields(CDSHeapVerifier* verifier, InstanceKlass* ik)
179 : _verifier(verifier), _ik(ik) {
180 _exclusions = _verifier->find_exclusion(_ik);
181 }
182
183 void do_field(fieldDescriptor* fd) {
184 if (fd->field_type() != T_OBJECT) {
185 return;
186 }
187
188 if (fd->signature()->equals("Ljdk/internal/access/JavaLangAccess;")) {
189 // A few classes have static fields that point to SharedSecrets.getJavaLangAccess().
|