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