1 | /* |
2 | * Copyright (c) 2014, 2019, 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 | * |
23 | */ |
24 | |
25 | #include "precompiled.hpp" |
26 | #include "classfile/classFileStream.hpp" |
27 | #include "classfile/classListParser.hpp" |
28 | #include "classfile/classLoader.hpp" |
29 | #include "classfile/classLoaderData.inline.hpp" |
30 | #include "classfile/classLoaderDataGraph.hpp" |
31 | #include "classfile/classLoaderExt.hpp" |
32 | #include "classfile/dictionary.hpp" |
33 | #include "classfile/javaClasses.hpp" |
34 | #include "classfile/symbolTable.hpp" |
35 | #include "classfile/systemDictionary.hpp" |
36 | #include "classfile/systemDictionaryShared.hpp" |
37 | #include "classfile/verificationType.hpp" |
38 | #include "classfile/vmSymbols.hpp" |
39 | #include "logging/log.hpp" |
40 | #include "memory/allocation.hpp" |
41 | #include "memory/filemap.hpp" |
42 | #include "memory/metadataFactory.hpp" |
43 | #include "memory/metaspaceClosure.hpp" |
44 | #include "memory/oopFactory.hpp" |
45 | #include "memory/resourceArea.hpp" |
46 | #include "memory/universe.hpp" |
47 | #include "memory/dynamicArchive.hpp" |
48 | #include "oops/instanceKlass.hpp" |
49 | #include "oops/klass.inline.hpp" |
50 | #include "oops/objArrayOop.inline.hpp" |
51 | #include "oops/oop.inline.hpp" |
52 | #include "oops/typeArrayOop.inline.hpp" |
53 | #include "runtime/handles.inline.hpp" |
54 | #include "runtime/java.hpp" |
55 | #include "runtime/javaCalls.hpp" |
56 | #include "runtime/mutexLocker.hpp" |
57 | #include "utilities/hashtable.inline.hpp" |
58 | #include "utilities/resourceHash.hpp" |
59 | #include "utilities/stringUtils.hpp" |
60 | |
61 | |
62 | objArrayOop SystemDictionaryShared::_shared_protection_domains = NULL; |
63 | objArrayOop SystemDictionaryShared::_shared_jar_urls = NULL; |
64 | objArrayOop SystemDictionaryShared::_shared_jar_manifests = NULL; |
65 | DEBUG_ONLY(bool SystemDictionaryShared::_no_class_loading_should_happen = false;) |
66 | |
67 | class DumpTimeSharedClassInfo: public CHeapObj<mtClass> { |
68 | bool _excluded; |
69 | public: |
70 | struct DTConstraint { |
71 | Symbol* _name; |
72 | Symbol* _from_name; |
73 | DTConstraint() : _name(NULL), _from_name(NULL) {} |
74 | DTConstraint(Symbol* n, Symbol* fn) : _name(n), _from_name(fn) {} |
75 | }; |
76 | |
77 | InstanceKlass* _klass; |
78 | int _id; |
79 | int _clsfile_size; |
80 | int _clsfile_crc32; |
81 | GrowableArray<DTConstraint>* _verifier_constraints; |
82 | GrowableArray<char>* _verifier_constraint_flags; |
83 | |
84 | DumpTimeSharedClassInfo() { |
85 | _klass = NULL; |
86 | _id = -1; |
87 | _clsfile_size = -1; |
88 | _clsfile_crc32 = -1; |
89 | _excluded = false; |
90 | _verifier_constraints = NULL; |
91 | _verifier_constraint_flags = NULL; |
92 | } |
93 | |
94 | void add_verification_constraint(InstanceKlass* k, Symbol* name, |
95 | Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object); |
96 | |
97 | bool is_builtin() { |
98 | return SystemDictionaryShared::is_builtin(_klass); |
99 | } |
100 | |
101 | int num_constraints() { |
102 | if (_verifier_constraint_flags != NULL) { |
103 | return _verifier_constraint_flags->length(); |
104 | } else { |
105 | return 0; |
106 | } |
107 | } |
108 | |
109 | void metaspace_pointers_do(MetaspaceClosure* it) { |
110 | it->push(&_klass); |
111 | if (_verifier_constraints != NULL) { |
112 | for (int i = 0; i < _verifier_constraints->length(); i++) { |
113 | DTConstraint* cons = _verifier_constraints->adr_at(i); |
114 | it->push(&cons->_name); |
115 | it->push(&cons->_from_name); |
116 | } |
117 | } |
118 | } |
119 | |
120 | void set_excluded() { |
121 | _excluded = true; |
122 | } |
123 | |
124 | bool is_excluded() { |
125 | // _klass may become NULL due to DynamicArchiveBuilder::set_to_null |
126 | return _excluded || _klass == NULL; |
127 | } |
128 | }; |
129 | |
130 | class DumpTimeSharedClassTable: public ResourceHashtable< |
131 | InstanceKlass*, |
132 | DumpTimeSharedClassInfo, |
133 | primitive_hash<InstanceKlass*>, |
134 | primitive_equals<InstanceKlass*>, |
135 | 15889, // prime number |
136 | ResourceObj::C_HEAP> |
137 | { |
138 | int _builtin_count; |
139 | int _unregistered_count; |
140 | public: |
141 | DumpTimeSharedClassInfo* find_or_allocate_info_for(InstanceKlass* k) { |
142 | DumpTimeSharedClassInfo* p = get(k); |
143 | if (p == NULL) { |
144 | assert(!SystemDictionaryShared::no_class_loading_should_happen(), |
145 | "no new classes can be loaded while dumping archive" ); |
146 | put(k, DumpTimeSharedClassInfo()); |
147 | p = get(k); |
148 | assert(p != NULL, "sanity" ); |
149 | p->_klass = k; |
150 | } |
151 | return p; |
152 | } |
153 | |
154 | class CountClassByCategory : StackObj { |
155 | DumpTimeSharedClassTable* _table; |
156 | public: |
157 | CountClassByCategory(DumpTimeSharedClassTable* table) : _table(table) {} |
158 | bool do_entry(InstanceKlass* k, DumpTimeSharedClassInfo& info) { |
159 | if (!info.is_excluded()) { |
160 | if (info.is_builtin()) { |
161 | ++ _table->_builtin_count; |
162 | } else { |
163 | ++ _table->_unregistered_count; |
164 | } |
165 | } |
166 | return true; // keep on iterating |
167 | } |
168 | }; |
169 | |
170 | void update_counts() { |
171 | _builtin_count = 0; |
172 | _unregistered_count = 0; |
173 | CountClassByCategory counter(this); |
174 | iterate(&counter); |
175 | } |
176 | |
177 | int count_of(bool is_builtin) const { |
178 | if (is_builtin) { |
179 | return _builtin_count; |
180 | } else { |
181 | return _unregistered_count; |
182 | } |
183 | } |
184 | }; |
185 | |
186 | class RunTimeSharedClassInfo { |
187 | public: |
188 | struct CrcInfo { |
189 | int _clsfile_size; |
190 | int _clsfile_crc32; |
191 | }; |
192 | |
193 | // This is different than DumpTimeSharedClassInfo::DTConstraint. We use |
194 | // u4 instead of Symbol* to save space on 64-bit CPU. |
195 | struct RTConstraint { |
196 | u4 _name; |
197 | u4 _from_name; |
198 | }; |
199 | |
200 | InstanceKlass* _klass; |
201 | int _num_constraints; |
202 | |
203 | // optional CrcInfo _crc; (only for UNREGISTERED classes) |
204 | // optional RTConstraint _verifier_constraints[_num_constraints] |
205 | // optional char _verifier_constraint_flags[_num_constraints] |
206 | |
207 | private: |
208 | static size_t () { |
209 | return sizeof(RunTimeSharedClassInfo); |
210 | } |
211 | static size_t crc_size(InstanceKlass* klass) { |
212 | if (!SystemDictionaryShared::is_builtin(klass)) { |
213 | return sizeof(CrcInfo); |
214 | } else { |
215 | return 0; |
216 | } |
217 | } |
218 | static size_t verifier_constraints_size(int num_constraints) { |
219 | return sizeof(RTConstraint) * num_constraints; |
220 | } |
221 | static size_t verifier_constraint_flags_size(int num_constraints) { |
222 | return sizeof(char) * num_constraints; |
223 | } |
224 | |
225 | public: |
226 | static size_t byte_size(InstanceKlass* klass, int num_constraints) { |
227 | return header_size_size() + |
228 | crc_size(klass) + |
229 | verifier_constraints_size(num_constraints) + |
230 | verifier_constraint_flags_size(num_constraints); |
231 | } |
232 | |
233 | private: |
234 | size_t crc_offset() const { |
235 | return header_size_size(); |
236 | } |
237 | size_t verifier_constraints_offset() const { |
238 | return crc_offset() + crc_size(_klass); |
239 | } |
240 | size_t verifier_constraint_flags_offset() const { |
241 | return verifier_constraints_offset() + verifier_constraints_size(_num_constraints); |
242 | } |
243 | |
244 | void check_constraint_offset(int i) const { |
245 | assert(0 <= i && i < _num_constraints, "sanity" ); |
246 | } |
247 | |
248 | public: |
249 | CrcInfo* crc() const { |
250 | assert(crc_size(_klass) > 0, "must be" ); |
251 | return (CrcInfo*)(address(this) + crc_offset()); |
252 | } |
253 | RTConstraint* verifier_constraints() { |
254 | assert(_num_constraints > 0, "sanity" ); |
255 | return (RTConstraint*)(address(this) + verifier_constraints_offset()); |
256 | } |
257 | RTConstraint* verifier_constraint_at(int i) { |
258 | check_constraint_offset(i); |
259 | return verifier_constraints() + i; |
260 | } |
261 | |
262 | char* verifier_constraint_flags() { |
263 | assert(_num_constraints > 0, "sanity" ); |
264 | return (char*)(address(this) + verifier_constraint_flags_offset()); |
265 | } |
266 | |
267 | static u4 object_delta_u4(Symbol* sym) { |
268 | if (DynamicDumpSharedSpaces) { |
269 | sym = DynamicArchive::original_to_target(sym); |
270 | } |
271 | return MetaspaceShared::object_delta_u4(sym); |
272 | } |
273 | |
274 | void init(DumpTimeSharedClassInfo& info) { |
275 | _klass = info._klass; |
276 | if (!SystemDictionaryShared::is_builtin(_klass)) { |
277 | CrcInfo* c = crc(); |
278 | c->_clsfile_size = info._clsfile_size; |
279 | c->_clsfile_crc32 = info._clsfile_crc32; |
280 | } |
281 | _num_constraints = info.num_constraints(); |
282 | if (_num_constraints > 0) { |
283 | RTConstraint* constraints = verifier_constraints(); |
284 | char* flags = verifier_constraint_flags(); |
285 | int i; |
286 | for (i = 0; i < _num_constraints; i++) { |
287 | constraints[i]._name = object_delta_u4(info._verifier_constraints->at(i)._name); |
288 | constraints[i]._from_name = object_delta_u4(info._verifier_constraints->at(i)._from_name); |
289 | } |
290 | for (i = 0; i < _num_constraints; i++) { |
291 | flags[i] = info._verifier_constraint_flags->at(i); |
292 | } |
293 | } |
294 | if (DynamicDumpSharedSpaces) { |
295 | _klass = DynamicArchive::original_to_target(info._klass); |
296 | } |
297 | } |
298 | |
299 | bool matches(int clsfile_size, int clsfile_crc32) const { |
300 | return crc()->_clsfile_size == clsfile_size && |
301 | crc()->_clsfile_crc32 == clsfile_crc32; |
302 | } |
303 | |
304 | Symbol* get_constraint_name(int i) { |
305 | return (Symbol*)(SharedBaseAddress + verifier_constraint_at(i)->_name); |
306 | } |
307 | Symbol* get_constraint_from_name(int i) { |
308 | return (Symbol*)(SharedBaseAddress + verifier_constraint_at(i)->_from_name); |
309 | } |
310 | |
311 | char get_constraint_flag(int i) { |
312 | check_constraint_offset(i); |
313 | return verifier_constraint_flags()[i]; |
314 | } |
315 | |
316 | private: |
317 | // ArchiveCompactor::allocate() has reserved a pointer immediately before |
318 | // archived InstanceKlasses. We can use this slot to do a quick |
319 | // lookup of InstanceKlass* -> RunTimeSharedClassInfo* without |
320 | // building a new hashtable. |
321 | // |
322 | // info_pointer_addr(klass) --> 0x0100 RunTimeSharedClassInfo* |
323 | // InstanceKlass* klass --> 0x0108 <C++ vtbl> |
324 | // 0x0110 fields from Klass ... |
325 | static RunTimeSharedClassInfo** info_pointer_addr(InstanceKlass* klass) { |
326 | return &((RunTimeSharedClassInfo**)klass)[-1]; |
327 | } |
328 | |
329 | public: |
330 | static RunTimeSharedClassInfo* get_for(InstanceKlass* klass) { |
331 | return *info_pointer_addr(klass); |
332 | } |
333 | static void set_for(InstanceKlass* klass, RunTimeSharedClassInfo* record) { |
334 | if (DynamicDumpSharedSpaces) { |
335 | klass = DynamicArchive::original_to_buffer(klass); |
336 | *info_pointer_addr(klass) = DynamicArchive::buffer_to_target(record); |
337 | } else { |
338 | *info_pointer_addr(klass) = record; |
339 | } |
340 | } |
341 | |
342 | // Used by RunTimeSharedDictionary to implement OffsetCompactHashtable::EQUALS |
343 | static inline bool EQUALS( |
344 | const RunTimeSharedClassInfo* value, Symbol* key, int len_unused) { |
345 | return (value->_klass->name() == key); |
346 | } |
347 | }; |
348 | |
349 | class RunTimeSharedDictionary : public OffsetCompactHashtable< |
350 | Symbol*, |
351 | const RunTimeSharedClassInfo*, |
352 | RunTimeSharedClassInfo::EQUALS> {}; |
353 | |
354 | static DumpTimeSharedClassTable* _dumptime_table = NULL; |
355 | // SystemDictionaries in the base layer static archive |
356 | static RunTimeSharedDictionary _builtin_dictionary; |
357 | static RunTimeSharedDictionary _unregistered_dictionary; |
358 | // SystemDictionaries in the top layer dynamic archive |
359 | static RunTimeSharedDictionary _dynamic_builtin_dictionary; |
360 | static RunTimeSharedDictionary _dynamic_unregistered_dictionary; |
361 | |
362 | oop SystemDictionaryShared::shared_protection_domain(int index) { |
363 | return _shared_protection_domains->obj_at(index); |
364 | } |
365 | |
366 | oop SystemDictionaryShared::shared_jar_url(int index) { |
367 | return _shared_jar_urls->obj_at(index); |
368 | } |
369 | |
370 | oop SystemDictionaryShared::shared_jar_manifest(int index) { |
371 | return _shared_jar_manifests->obj_at(index); |
372 | } |
373 | |
374 | |
375 | Handle SystemDictionaryShared::get_shared_jar_manifest(int shared_path_index, TRAPS) { |
376 | Handle manifest ; |
377 | if (shared_jar_manifest(shared_path_index) == NULL) { |
378 | SharedClassPathEntry* ent = FileMapInfo::shared_path(shared_path_index); |
379 | long size = ent->manifest_size(); |
380 | if (size <= 0) { |
381 | return Handle(); |
382 | } |
383 | |
384 | // ByteArrayInputStream bais = new ByteArrayInputStream(buf); |
385 | const char* src = ent->manifest(); |
386 | assert(src != NULL, "No Manifest data" ); |
387 | typeArrayOop buf = oopFactory::new_byteArray(size, CHECK_NH); |
388 | typeArrayHandle bufhandle(THREAD, buf); |
389 | ArrayAccess<>::arraycopy_from_native(reinterpret_cast<const jbyte*>(src), |
390 | buf, typeArrayOopDesc::element_offset<jbyte>(0), size); |
391 | |
392 | Handle bais = JavaCalls::construct_new_instance(SystemDictionary::ByteArrayInputStream_klass(), |
393 | vmSymbols::byte_array_void_signature(), |
394 | bufhandle, CHECK_NH); |
395 | |
396 | // manifest = new Manifest(bais) |
397 | manifest = JavaCalls::construct_new_instance(SystemDictionary::Jar_Manifest_klass(), |
398 | vmSymbols::input_stream_void_signature(), |
399 | bais, CHECK_NH); |
400 | atomic_set_shared_jar_manifest(shared_path_index, manifest()); |
401 | } |
402 | |
403 | manifest = Handle(THREAD, shared_jar_manifest(shared_path_index)); |
404 | assert(manifest.not_null(), "sanity" ); |
405 | return manifest; |
406 | } |
407 | |
408 | Handle SystemDictionaryShared::get_shared_jar_url(int shared_path_index, TRAPS) { |
409 | Handle url_h; |
410 | if (shared_jar_url(shared_path_index) == NULL) { |
411 | JavaValue result(T_OBJECT); |
412 | const char* path = FileMapInfo::shared_path_name(shared_path_index); |
413 | Handle path_string = java_lang_String::create_from_str(path, CHECK_(url_h)); |
414 | Klass* classLoaders_klass = |
415 | SystemDictionary::jdk_internal_loader_ClassLoaders_klass(); |
416 | JavaCalls::call_static(&result, classLoaders_klass, |
417 | vmSymbols::toFileURL_name(), |
418 | vmSymbols::toFileURL_signature(), |
419 | path_string, CHECK_(url_h)); |
420 | |
421 | atomic_set_shared_jar_url(shared_path_index, (oop)result.get_jobject()); |
422 | } |
423 | |
424 | url_h = Handle(THREAD, shared_jar_url(shared_path_index)); |
425 | assert(url_h.not_null(), "sanity" ); |
426 | return url_h; |
427 | } |
428 | |
429 | Handle SystemDictionaryShared::get_package_name(Symbol* class_name, TRAPS) { |
430 | ResourceMark rm(THREAD); |
431 | Handle pkgname_string; |
432 | char* pkgname = (char*) ClassLoader::package_from_name((const char*) class_name->as_C_string()); |
433 | if (pkgname != NULL) { // Package prefix found |
434 | StringUtils::replace_no_expand(pkgname, "/" , "." ); |
435 | pkgname_string = java_lang_String::create_from_str(pkgname, |
436 | CHECK_(pkgname_string)); |
437 | } |
438 | return pkgname_string; |
439 | } |
440 | |
441 | // Define Package for shared app classes from JAR file and also checks for |
442 | // package sealing (all done in Java code) |
443 | // See http://docs.oracle.com/javase/tutorial/deployment/jar/sealman.html |
444 | void SystemDictionaryShared::define_shared_package(Symbol* class_name, |
445 | Handle class_loader, |
446 | Handle manifest, |
447 | Handle url, |
448 | TRAPS) { |
449 | assert(SystemDictionary::is_system_class_loader(class_loader()), "unexpected class loader" ); |
450 | // get_package_name() returns a NULL handle if the class is in unnamed package |
451 | Handle pkgname_string = get_package_name(class_name, CHECK); |
452 | if (pkgname_string.not_null()) { |
453 | Klass* app_classLoader_klass = SystemDictionary::jdk_internal_loader_ClassLoaders_AppClassLoader_klass(); |
454 | JavaValue result(T_OBJECT); |
455 | JavaCallArguments args(3); |
456 | args.set_receiver(class_loader); |
457 | args.push_oop(pkgname_string); |
458 | args.push_oop(manifest); |
459 | args.push_oop(url); |
460 | JavaCalls::call_virtual(&result, app_classLoader_klass, |
461 | vmSymbols::defineOrCheckPackage_name(), |
462 | vmSymbols::defineOrCheckPackage_signature(), |
463 | &args, |
464 | CHECK); |
465 | } |
466 | } |
467 | |
468 | // Define Package for shared app/platform classes from named module |
469 | void SystemDictionaryShared::define_shared_package(Symbol* class_name, |
470 | Handle class_loader, |
471 | ModuleEntry* mod_entry, |
472 | TRAPS) { |
473 | assert(mod_entry != NULL, "module_entry should not be NULL" ); |
474 | Handle module_handle(THREAD, mod_entry->module()); |
475 | |
476 | Handle pkg_name = get_package_name(class_name, CHECK); |
477 | assert(pkg_name.not_null(), "Package should not be null for class in named module" ); |
478 | |
479 | Klass* classLoader_klass; |
480 | if (SystemDictionary::is_system_class_loader(class_loader())) { |
481 | classLoader_klass = SystemDictionary::jdk_internal_loader_ClassLoaders_AppClassLoader_klass(); |
482 | } else { |
483 | assert(SystemDictionary::is_platform_class_loader(class_loader()), "unexpected classloader" ); |
484 | classLoader_klass = SystemDictionary::jdk_internal_loader_ClassLoaders_PlatformClassLoader_klass(); |
485 | } |
486 | |
487 | JavaValue result(T_OBJECT); |
488 | JavaCallArguments args(2); |
489 | args.set_receiver(class_loader); |
490 | args.push_oop(pkg_name); |
491 | args.push_oop(module_handle); |
492 | JavaCalls::call_virtual(&result, classLoader_klass, |
493 | vmSymbols::definePackage_name(), |
494 | vmSymbols::definePackage_signature(), |
495 | &args, |
496 | CHECK); |
497 | } |
498 | |
499 | // Get the ProtectionDomain associated with the CodeSource from the classloader. |
500 | Handle SystemDictionaryShared::get_protection_domain_from_classloader(Handle class_loader, |
501 | Handle url, TRAPS) { |
502 | // CodeSource cs = new CodeSource(url, null); |
503 | Handle cs = JavaCalls::construct_new_instance(SystemDictionary::CodeSource_klass(), |
504 | vmSymbols::url_code_signer_array_void_signature(), |
505 | url, Handle(), CHECK_NH); |
506 | |
507 | // protection_domain = SecureClassLoader.getProtectionDomain(cs); |
508 | Klass* secureClassLoader_klass = SystemDictionary::SecureClassLoader_klass(); |
509 | JavaValue obj_result(T_OBJECT); |
510 | JavaCalls::call_virtual(&obj_result, class_loader, secureClassLoader_klass, |
511 | vmSymbols::getProtectionDomain_name(), |
512 | vmSymbols::getProtectionDomain_signature(), |
513 | cs, CHECK_NH); |
514 | return Handle(THREAD, (oop)obj_result.get_jobject()); |
515 | } |
516 | |
517 | // Returns the ProtectionDomain associated with the JAR file identified by the url. |
518 | Handle SystemDictionaryShared::get_shared_protection_domain(Handle class_loader, |
519 | int shared_path_index, |
520 | Handle url, |
521 | TRAPS) { |
522 | Handle protection_domain; |
523 | if (shared_protection_domain(shared_path_index) == NULL) { |
524 | Handle pd = get_protection_domain_from_classloader(class_loader, url, THREAD); |
525 | atomic_set_shared_protection_domain(shared_path_index, pd()); |
526 | } |
527 | |
528 | // Acquire from the cache because if another thread beats the current one to |
529 | // set the shared protection_domain and the atomic_set fails, the current thread |
530 | // needs to get the updated protection_domain from the cache. |
531 | protection_domain = Handle(THREAD, shared_protection_domain(shared_path_index)); |
532 | assert(protection_domain.not_null(), "sanity" ); |
533 | return protection_domain; |
534 | } |
535 | |
536 | // Returns the ProtectionDomain associated with the moduleEntry. |
537 | Handle SystemDictionaryShared::get_shared_protection_domain(Handle class_loader, |
538 | ModuleEntry* mod, TRAPS) { |
539 | ClassLoaderData *loader_data = mod->loader_data(); |
540 | if (mod->shared_protection_domain() == NULL) { |
541 | Symbol* location = mod->location(); |
542 | if (location != NULL) { |
543 | Handle location_string = java_lang_String::create_from_symbol( |
544 | location, CHECK_NH); |
545 | Handle url; |
546 | JavaValue result(T_OBJECT); |
547 | if (location->starts_with("jrt:/" )) { |
548 | url = JavaCalls::construct_new_instance(SystemDictionary::URL_klass(), |
549 | vmSymbols::string_void_signature(), |
550 | location_string, CHECK_NH); |
551 | } else { |
552 | Klass* classLoaders_klass = |
553 | SystemDictionary::jdk_internal_loader_ClassLoaders_klass(); |
554 | JavaCalls::call_static(&result, classLoaders_klass, vmSymbols::toFileURL_name(), |
555 | vmSymbols::toFileURL_signature(), |
556 | location_string, CHECK_NH); |
557 | url = Handle(THREAD, (oop)result.get_jobject()); |
558 | } |
559 | |
560 | Handle pd = get_protection_domain_from_classloader(class_loader, url, |
561 | CHECK_NH); |
562 | mod->set_shared_protection_domain(loader_data, pd); |
563 | } |
564 | } |
565 | |
566 | Handle protection_domain(THREAD, mod->shared_protection_domain()); |
567 | assert(protection_domain.not_null(), "sanity" ); |
568 | return protection_domain; |
569 | } |
570 | |
571 | // Initializes the java.lang.Package and java.security.ProtectionDomain objects associated with |
572 | // the given InstanceKlass. |
573 | // Returns the ProtectionDomain for the InstanceKlass. |
574 | Handle SystemDictionaryShared::init_security_info(Handle class_loader, InstanceKlass* ik, TRAPS) { |
575 | Handle pd; |
576 | |
577 | if (ik != NULL) { |
578 | int index = ik->shared_classpath_index(); |
579 | assert(index >= 0, "Sanity" ); |
580 | SharedClassPathEntry* ent = FileMapInfo::shared_path(index); |
581 | Symbol* class_name = ik->name(); |
582 | |
583 | if (ent->is_modules_image()) { |
584 | // For shared app/platform classes originated from the run-time image: |
585 | // The ProtectionDomains are cached in the corresponding ModuleEntries |
586 | // for fast access by the VM. |
587 | ResourceMark rm; |
588 | ClassLoaderData *loader_data = |
589 | ClassLoaderData::class_loader_data(class_loader()); |
590 | PackageEntryTable* pkgEntryTable = loader_data->packages(); |
591 | TempNewSymbol pkg_name = InstanceKlass::package_from_name(class_name, CHECK_(pd)); |
592 | if (pkg_name != NULL) { |
593 | PackageEntry* pkg_entry = pkgEntryTable->lookup_only(pkg_name); |
594 | if (pkg_entry != NULL) { |
595 | ModuleEntry* mod_entry = pkg_entry->module(); |
596 | pd = get_shared_protection_domain(class_loader, mod_entry, THREAD); |
597 | define_shared_package(class_name, class_loader, mod_entry, CHECK_(pd)); |
598 | } |
599 | } |
600 | } else { |
601 | // For shared app/platform classes originated from JAR files on the class path: |
602 | // Each of the 3 SystemDictionaryShared::_shared_xxx arrays has the same length |
603 | // as the shared classpath table in the shared archive (see |
604 | // FileMap::_shared_path_table in filemap.hpp for details). |
605 | // |
606 | // If a shared InstanceKlass k is loaded from the class path, let |
607 | // |
608 | // index = k->shared_classpath_index(): |
609 | // |
610 | // FileMap::_shared_path_table[index] identifies the JAR file that contains k. |
611 | // |
612 | // k's protection domain is: |
613 | // |
614 | // ProtectionDomain pd = _shared_protection_domains[index]; |
615 | // |
616 | // and k's Package is initialized using |
617 | // |
618 | // manifest = _shared_jar_manifests[index]; |
619 | // url = _shared_jar_urls[index]; |
620 | // define_shared_package(class_name, class_loader, manifest, url, CHECK_(pd)); |
621 | // |
622 | // Note that if an element of these 3 _shared_xxx arrays is NULL, it will be initialized by |
623 | // the corresponding SystemDictionaryShared::get_shared_xxx() function. |
624 | Handle manifest = get_shared_jar_manifest(index, CHECK_(pd)); |
625 | Handle url = get_shared_jar_url(index, CHECK_(pd)); |
626 | define_shared_package(class_name, class_loader, manifest, url, CHECK_(pd)); |
627 | pd = get_shared_protection_domain(class_loader, index, url, CHECK_(pd)); |
628 | } |
629 | } |
630 | return pd; |
631 | } |
632 | |
633 | bool SystemDictionaryShared::is_sharing_possible(ClassLoaderData* loader_data) { |
634 | oop class_loader = loader_data->class_loader(); |
635 | return (class_loader == NULL || |
636 | SystemDictionary::is_system_class_loader(class_loader) || |
637 | SystemDictionary::is_platform_class_loader(class_loader)); |
638 | } |
639 | |
640 | // Currently AppCDS only archives classes from the run-time image, the |
641 | // -Xbootclasspath/a path, the class path, and the module path. |
642 | // |
643 | // Check if a shared class can be loaded by the specific classloader. Following |
644 | // are the "visible" archived classes for different classloaders. |
645 | // |
646 | // NULL classloader: |
647 | // - see SystemDictionary::is_shared_class_visible() |
648 | // Platform classloader: |
649 | // - Module class from runtime image. ModuleEntry must be defined in the |
650 | // classloader. |
651 | // App classloader: |
652 | // - Module Class from runtime image and module path. ModuleEntry must be defined in the |
653 | // classloader. |
654 | // - Class from -cp. The class must have no PackageEntry defined in any of the |
655 | // boot/platform/app classloader, or must be in the unnamed module defined in the |
656 | // AppClassLoader. |
657 | bool SystemDictionaryShared::is_shared_class_visible_for_classloader( |
658 | InstanceKlass* ik, |
659 | Handle class_loader, |
660 | const char* pkg_string, |
661 | Symbol* pkg_name, |
662 | PackageEntry* pkg_entry, |
663 | ModuleEntry* mod_entry, |
664 | TRAPS) { |
665 | assert(class_loader.not_null(), "Class loader should not be NULL" ); |
666 | assert(Universe::is_module_initialized(), "Module system is not initialized" ); |
667 | ResourceMark rm(THREAD); |
668 | |
669 | int path_index = ik->shared_classpath_index(); |
670 | SharedClassPathEntry* ent = |
671 | (SharedClassPathEntry*)FileMapInfo::shared_path(path_index); |
672 | |
673 | if (SystemDictionary::is_platform_class_loader(class_loader())) { |
674 | assert(ent != NULL, "shared class for PlatformClassLoader should have valid SharedClassPathEntry" ); |
675 | // The PlatformClassLoader can only load archived class originated from the |
676 | // run-time image. The class' PackageEntry/ModuleEntry must be |
677 | // defined by the PlatformClassLoader. |
678 | if (mod_entry != NULL) { |
679 | // PackageEntry/ModuleEntry is found in the classloader. Check if the |
680 | // ModuleEntry's location agrees with the archived class' origination. |
681 | if (ent->is_modules_image() && mod_entry->location()->starts_with("jrt:" )) { |
682 | return true; // Module class from the runtime image |
683 | } |
684 | } |
685 | } else if (SystemDictionary::is_system_class_loader(class_loader())) { |
686 | assert(ent != NULL, "shared class for system loader should have valid SharedClassPathEntry" ); |
687 | if (pkg_string == NULL) { |
688 | // The archived class is in the unnamed package. Currently, the boot image |
689 | // does not contain any class in the unnamed package. |
690 | assert(!ent->is_modules_image(), "Class in the unnamed package must be from the classpath" ); |
691 | if (path_index >= ClassLoaderExt::app_class_paths_start_index()) { |
692 | assert(path_index < ClassLoaderExt::app_module_paths_start_index(), "invalid path_index" ); |
693 | return true; |
694 | } |
695 | } else { |
696 | // Check if this is from a PackageEntry/ModuleEntry defined in the AppClassloader. |
697 | if (pkg_entry == NULL) { |
698 | // It's not guaranteed that the class is from the classpath if the |
699 | // PackageEntry cannot be found from the AppClassloader. Need to check |
700 | // the boot and platform classloader as well. |
701 | if (get_package_entry(pkg_name, ClassLoaderData::class_loader_data_or_null(SystemDictionary::java_platform_loader())) == NULL && |
702 | get_package_entry(pkg_name, ClassLoaderData::the_null_class_loader_data()) == NULL) { |
703 | // The PackageEntry is not defined in any of the boot/platform/app classloaders. |
704 | // The archived class must from -cp path and not from the runtime image. |
705 | if (!ent->is_modules_image() && path_index >= ClassLoaderExt::app_class_paths_start_index() && |
706 | path_index < ClassLoaderExt::app_module_paths_start_index()) { |
707 | return true; |
708 | } |
709 | } |
710 | } else if (mod_entry != NULL) { |
711 | // The package/module is defined in the AppClassLoader. We support |
712 | // archiving application module class from the runtime image or from |
713 | // a named module from a module path. |
714 | // Packages from the -cp path are in the unnamed_module. |
715 | if (ent->is_modules_image() && mod_entry->location()->starts_with("jrt:" )) { |
716 | // shared module class from runtime image |
717 | return true; |
718 | } else if (pkg_entry->in_unnamed_module() && path_index >= ClassLoaderExt::app_class_paths_start_index() && |
719 | path_index < ClassLoaderExt::app_module_paths_start_index()) { |
720 | // shared class from -cp |
721 | DEBUG_ONLY( \ |
722 | ClassLoaderData* loader_data = class_loader_data(class_loader); \ |
723 | assert(mod_entry == loader_data->unnamed_module(), "the unnamed module is not defined in the classloader" );) |
724 | return true; |
725 | } else { |
726 | if(!pkg_entry->in_unnamed_module() && |
727 | (path_index >= ClassLoaderExt::app_module_paths_start_index())&& |
728 | (path_index < FileMapInfo::get_number_of_shared_paths()) && |
729 | (strcmp(ent->name(), ClassLoader::skip_uri_protocol(mod_entry->location()->as_C_string())) == 0)) { |
730 | // shared module class from module path |
731 | return true; |
732 | } else { |
733 | assert(path_index < FileMapInfo::get_number_of_shared_paths(), "invalid path_index" ); |
734 | } |
735 | } |
736 | } |
737 | } |
738 | } else { |
739 | // TEMP: if a shared class can be found by a custom loader, consider it visible now. |
740 | // FIXME: is this actually correct? |
741 | return true; |
742 | } |
743 | return false; |
744 | } |
745 | |
746 | bool SystemDictionaryShared::has_platform_or_app_classes() { |
747 | if (FileMapInfo::current_info()->header()->has_platform_or_app_classes()) { |
748 | return true; |
749 | } |
750 | if (DynamicArchive::is_mapped() && |
751 | FileMapInfo::dynamic_info()->header()->has_platform_or_app_classes()) { |
752 | return true; |
753 | } |
754 | return false; |
755 | } |
756 | |
757 | // The following stack shows how this code is reached: |
758 | // |
759 | // [0] SystemDictionaryShared::find_or_load_shared_class() |
760 | // [1] JVM_FindLoadedClass |
761 | // [2] java.lang.ClassLoader.findLoadedClass0() |
762 | // [3] java.lang.ClassLoader.findLoadedClass() |
763 | // [4] jdk.internal.loader.BuiltinClassLoader.loadClassOrNull() |
764 | // [5] jdk.internal.loader.BuiltinClassLoader.loadClass() |
765 | // [6] jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(), or |
766 | // jdk.internal.loader.ClassLoaders$PlatformClassLoader.loadClass() |
767 | // |
768 | // AppCDS supports fast class loading for these 2 built-in class loaders: |
769 | // jdk.internal.loader.ClassLoaders$PlatformClassLoader |
770 | // jdk.internal.loader.ClassLoaders$AppClassLoader |
771 | // with the following assumptions (based on the JDK core library source code): |
772 | // |
773 | // [a] these two loaders use the BuiltinClassLoader.loadClassOrNull() to |
774 | // load the named class. |
775 | // [b] BuiltinClassLoader.loadClassOrNull() first calls findLoadedClass(name). |
776 | // [c] At this point, if we can find the named class inside the |
777 | // shared_dictionary, we can perform further checks (see |
778 | // is_shared_class_visible_for_classloader() to ensure that this class |
779 | // was loaded by the same class loader during dump time. |
780 | // |
781 | // Given these assumptions, we intercept the findLoadedClass() call to invoke |
782 | // SystemDictionaryShared::find_or_load_shared_class() to load the shared class from |
783 | // the archive for the 2 built-in class loaders. This way, |
784 | // we can improve start-up because we avoid decoding the classfile, |
785 | // and avoid delegating to the parent loader. |
786 | // |
787 | // NOTE: there's a lot of assumption about the Java code. If any of that change, this |
788 | // needs to be redesigned. |
789 | |
790 | InstanceKlass* SystemDictionaryShared::find_or_load_shared_class( |
791 | Symbol* name, Handle class_loader, TRAPS) { |
792 | InstanceKlass* k = NULL; |
793 | if (UseSharedSpaces) { |
794 | if (!has_platform_or_app_classes()) { |
795 | return NULL; |
796 | } |
797 | |
798 | if (SystemDictionary::is_system_class_loader(class_loader()) || |
799 | SystemDictionary::is_platform_class_loader(class_loader())) { |
800 | // Fix for 4474172; see evaluation for more details |
801 | class_loader = Handle( |
802 | THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader())); |
803 | ClassLoaderData *loader_data = register_loader(class_loader); |
804 | Dictionary* dictionary = loader_data->dictionary(); |
805 | |
806 | unsigned int d_hash = dictionary->compute_hash(name); |
807 | |
808 | bool DoObjectLock = true; |
809 | if (is_parallelCapable(class_loader)) { |
810 | DoObjectLock = false; |
811 | } |
812 | |
813 | // Make sure we are synchronized on the class loader before we proceed |
814 | // |
815 | // Note: currently, find_or_load_shared_class is called only from |
816 | // JVM_FindLoadedClass and used for PlatformClassLoader and AppClassLoader, |
817 | // which are parallel-capable loaders, so this lock is NOT taken. |
818 | Handle lockObject = compute_loader_lock_object(class_loader, THREAD); |
819 | check_loader_lock_contention(lockObject, THREAD); |
820 | ObjectLocker ol(lockObject, THREAD, DoObjectLock); |
821 | |
822 | { |
823 | MutexLocker mu(SystemDictionary_lock, THREAD); |
824 | InstanceKlass* check = find_class(d_hash, name, dictionary); |
825 | if (check != NULL) { |
826 | return check; |
827 | } |
828 | } |
829 | |
830 | k = load_shared_class_for_builtin_loader(name, class_loader, THREAD); |
831 | if (k != NULL) { |
832 | define_instance_class(k, CHECK_NULL); |
833 | } |
834 | } |
835 | } |
836 | return k; |
837 | } |
838 | |
839 | InstanceKlass* SystemDictionaryShared::load_shared_class_for_builtin_loader( |
840 | Symbol* class_name, Handle class_loader, TRAPS) { |
841 | assert(UseSharedSpaces, "must be" ); |
842 | InstanceKlass* ik = find_builtin_class(class_name); |
843 | |
844 | if (ik != NULL) { |
845 | if ((ik->is_shared_app_class() && |
846 | SystemDictionary::is_system_class_loader(class_loader())) || |
847 | (ik->is_shared_platform_class() && |
848 | SystemDictionary::is_platform_class_loader(class_loader()))) { |
849 | Handle protection_domain = |
850 | SystemDictionaryShared::init_security_info(class_loader, ik, CHECK_NULL); |
851 | return load_shared_class(ik, class_loader, protection_domain, NULL, THREAD); |
852 | } |
853 | } |
854 | return NULL; |
855 | } |
856 | |
857 | void SystemDictionaryShared::oops_do(OopClosure* f) { |
858 | f->do_oop((oop*)&_shared_protection_domains); |
859 | f->do_oop((oop*)&_shared_jar_urls); |
860 | f->do_oop((oop*)&_shared_jar_manifests); |
861 | } |
862 | |
863 | void SystemDictionaryShared::allocate_shared_protection_domain_array(int size, TRAPS) { |
864 | if (_shared_protection_domains == NULL) { |
865 | _shared_protection_domains = oopFactory::new_objArray( |
866 | SystemDictionary::ProtectionDomain_klass(), size, CHECK); |
867 | } |
868 | } |
869 | |
870 | void SystemDictionaryShared::allocate_shared_jar_url_array(int size, TRAPS) { |
871 | if (_shared_jar_urls == NULL) { |
872 | _shared_jar_urls = oopFactory::new_objArray( |
873 | SystemDictionary::URL_klass(), size, CHECK); |
874 | } |
875 | } |
876 | |
877 | void SystemDictionaryShared::allocate_shared_jar_manifest_array(int size, TRAPS) { |
878 | if (_shared_jar_manifests == NULL) { |
879 | _shared_jar_manifests = oopFactory::new_objArray( |
880 | SystemDictionary::Jar_Manifest_klass(), size, CHECK); |
881 | } |
882 | } |
883 | |
884 | void SystemDictionaryShared::allocate_shared_data_arrays(int size, TRAPS) { |
885 | allocate_shared_protection_domain_array(size, CHECK); |
886 | allocate_shared_jar_url_array(size, CHECK); |
887 | allocate_shared_jar_manifest_array(size, CHECK); |
888 | } |
889 | |
890 | // This function is called for loading only UNREGISTERED classes |
891 | InstanceKlass* SystemDictionaryShared::lookup_from_stream(Symbol* class_name, |
892 | Handle class_loader, |
893 | Handle protection_domain, |
894 | const ClassFileStream* cfs, |
895 | TRAPS) { |
896 | if (!UseSharedSpaces) { |
897 | return NULL; |
898 | } |
899 | if (class_name == NULL) { // don't do this for anonymous classes |
900 | return NULL; |
901 | } |
902 | if (class_loader.is_null() || |
903 | SystemDictionary::is_system_class_loader(class_loader()) || |
904 | SystemDictionary::is_platform_class_loader(class_loader())) { |
905 | // Do nothing for the BUILTIN loaders. |
906 | return NULL; |
907 | } |
908 | |
909 | const RunTimeSharedClassInfo* record = find_record(&_unregistered_dictionary, class_name); |
910 | if (record == NULL) { |
911 | if (DynamicArchive::is_mapped()) { |
912 | record = find_record(&_dynamic_unregistered_dictionary, class_name); |
913 | } |
914 | if (record == NULL) { |
915 | return NULL; |
916 | } |
917 | } |
918 | |
919 | int clsfile_size = cfs->length(); |
920 | int clsfile_crc32 = ClassLoader::crc32(0, (const char*)cfs->buffer(), cfs->length()); |
921 | |
922 | if (!record->matches(clsfile_size, clsfile_crc32)) { |
923 | return NULL; |
924 | } |
925 | |
926 | return acquire_class_for_current_thread(record->_klass, class_loader, |
927 | protection_domain, cfs, |
928 | THREAD); |
929 | } |
930 | |
931 | InstanceKlass* SystemDictionaryShared::acquire_class_for_current_thread( |
932 | InstanceKlass *ik, |
933 | Handle class_loader, |
934 | Handle protection_domain, |
935 | const ClassFileStream *cfs, |
936 | TRAPS) { |
937 | ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(class_loader()); |
938 | |
939 | { |
940 | MutexLocker mu(SharedDictionary_lock, THREAD); |
941 | if (ik->class_loader_data() != NULL) { |
942 | // ik is already loaded (by this loader or by a different loader) |
943 | // or ik is being loaded by a different thread (by this loader or by a different loader) |
944 | return NULL; |
945 | } |
946 | |
947 | // No other thread has acquired this yet, so give it to *this thread* |
948 | ik->set_class_loader_data(loader_data); |
949 | } |
950 | |
951 | // No longer holding SharedDictionary_lock |
952 | // No need to lock, as <ik> can be held only by a single thread. |
953 | loader_data->add_class(ik); |
954 | |
955 | // Load and check super/interfaces, restore unsharable info |
956 | InstanceKlass* shared_klass = load_shared_class(ik, class_loader, protection_domain, |
957 | cfs, THREAD); |
958 | if (shared_klass == NULL || HAS_PENDING_EXCEPTION) { |
959 | // TODO: clean up <ik> so it can be used again |
960 | return NULL; |
961 | } |
962 | |
963 | return shared_klass; |
964 | } |
965 | |
966 | static ResourceHashtable< |
967 | Symbol*, bool, |
968 | primitive_hash<Symbol*>, |
969 | primitive_equals<Symbol*>, |
970 | 6661, // prime number |
971 | ResourceObj::C_HEAP> _loaded_unregistered_classes; |
972 | |
973 | bool SystemDictionaryShared::add_unregistered_class(InstanceKlass* k, TRAPS) { |
974 | assert(DumpSharedSpaces, "only when dumping" ); |
975 | |
976 | Symbol* name = k->name(); |
977 | if (_loaded_unregistered_classes.get(name) != NULL) { |
978 | // We don't allow duplicated unregistered classes of the same name. |
979 | return false; |
980 | } else { |
981 | bool isnew = _loaded_unregistered_classes.put(name, true); |
982 | assert(isnew, "sanity" ); |
983 | MutexLocker mu_r(Compile_lock, THREAD); // add_to_hierarchy asserts this. |
984 | SystemDictionary::add_to_hierarchy(k, CHECK_0); |
985 | return true; |
986 | } |
987 | } |
988 | |
989 | // This function is called to resolve the super/interfaces of shared classes for |
990 | // non-built-in loaders. E.g., ChildClass in the below example |
991 | // where "super:" (and optionally "interface:") have been specified. |
992 | // |
993 | // java/lang/Object id: 0 |
994 | // Interface id: 2 super: 0 source: cust.jar |
995 | // ChildClass id: 4 super: 0 interfaces: 2 source: cust.jar |
996 | InstanceKlass* SystemDictionaryShared::dump_time_resolve_super_or_fail( |
997 | Symbol* child_name, Symbol* class_name, Handle class_loader, |
998 | Handle protection_domain, bool is_superclass, TRAPS) { |
999 | |
1000 | assert(DumpSharedSpaces, "only when dumping" ); |
1001 | |
1002 | ClassListParser* parser = ClassListParser::instance(); |
1003 | if (parser == NULL) { |
1004 | // We're still loading the well-known classes, before the ClassListParser is created. |
1005 | return NULL; |
1006 | } |
1007 | if (child_name->equals(parser->current_class_name())) { |
1008 | // When this function is called, all the numbered super and interface types |
1009 | // must have already been loaded. Hence this function is never recursively called. |
1010 | if (is_superclass) { |
1011 | return parser->lookup_super_for_current_class(class_name); |
1012 | } else { |
1013 | return parser->lookup_interface_for_current_class(class_name); |
1014 | } |
1015 | } else { |
1016 | // The VM is not trying to resolve a super type of parser->current_class_name(). |
1017 | // Instead, it's resolving an error class (because parser->current_class_name() has |
1018 | // failed parsing or verification). Don't do anything here. |
1019 | return NULL; |
1020 | } |
1021 | } |
1022 | |
1023 | DumpTimeSharedClassInfo* SystemDictionaryShared::find_or_allocate_info_for(InstanceKlass* k) { |
1024 | MutexLocker ml(DumpTimeTable_lock, Mutex::_no_safepoint_check_flag); |
1025 | if (_dumptime_table == NULL) { |
1026 | _dumptime_table = new (ResourceObj::C_HEAP, mtClass)DumpTimeSharedClassTable(); |
1027 | } |
1028 | return _dumptime_table->find_or_allocate_info_for(k); |
1029 | } |
1030 | |
1031 | void SystemDictionaryShared::set_shared_class_misc_info(InstanceKlass* k, ClassFileStream* cfs) { |
1032 | assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "only when dumping" ); |
1033 | assert(!is_builtin(k), "must be unregistered class" ); |
1034 | DumpTimeSharedClassInfo* info = find_or_allocate_info_for(k); |
1035 | info->_clsfile_size = cfs->length(); |
1036 | info->_clsfile_crc32 = ClassLoader::crc32(0, (const char*)cfs->buffer(), cfs->length()); |
1037 | } |
1038 | |
1039 | void SystemDictionaryShared::init_dumptime_info(InstanceKlass* k) { |
1040 | (void)find_or_allocate_info_for(k); |
1041 | } |
1042 | |
1043 | void SystemDictionaryShared::remove_dumptime_info(InstanceKlass* k) { |
1044 | MutexLocker ml(DumpTimeTable_lock, Mutex::_no_safepoint_check_flag); |
1045 | DumpTimeSharedClassInfo* p = _dumptime_table->get(k); |
1046 | if (p == NULL) { |
1047 | return; |
1048 | } |
1049 | if (p->_verifier_constraints != NULL) { |
1050 | for (int i = 0; i < p->_verifier_constraints->length(); i++) { |
1051 | DumpTimeSharedClassInfo::DTConstraint constraint = p->_verifier_constraints->at(i); |
1052 | if (constraint._name != NULL ) { |
1053 | constraint._name->decrement_refcount(); |
1054 | } |
1055 | if (constraint._from_name != NULL ) { |
1056 | constraint._from_name->decrement_refcount(); |
1057 | } |
1058 | } |
1059 | FREE_C_HEAP_ARRAY(DTConstraint, p->_verifier_constraints); |
1060 | p->_verifier_constraints = NULL; |
1061 | } |
1062 | if (p->_verifier_constraint_flags != NULL) { |
1063 | FREE_C_HEAP_ARRAY(char, p->_verifier_constraint_flags); |
1064 | p->_verifier_constraint_flags = NULL; |
1065 | } |
1066 | _dumptime_table->remove(k); |
1067 | } |
1068 | |
1069 | bool SystemDictionaryShared::is_jfr_event_class(InstanceKlass *k) { |
1070 | while (k) { |
1071 | if (k->name()->equals("jdk/internal/event/Event" )) { |
1072 | return true; |
1073 | } |
1074 | k = k->java_super(); |
1075 | } |
1076 | return false; |
1077 | } |
1078 | |
1079 | void SystemDictionaryShared::warn_excluded(InstanceKlass* k, const char* reason) { |
1080 | ResourceMark rm; |
1081 | log_warning(cds)("Skipping %s: %s" , k->name()->as_C_string(), reason); |
1082 | } |
1083 | |
1084 | bool SystemDictionaryShared::should_be_excluded(InstanceKlass* k) { |
1085 | if (k->class_loader_data()->is_unsafe_anonymous()) { |
1086 | warn_excluded(k, "Unsafe anonymous class" ); |
1087 | return true; // unsafe anonymous classes are not archived, skip |
1088 | } |
1089 | if (k->is_in_error_state()) { |
1090 | warn_excluded(k, "In error state" ); |
1091 | return true; |
1092 | } |
1093 | if (k->shared_classpath_index() < 0 && is_builtin(k)) { |
1094 | // These are classes loaded from unsupported locations (such as those loaded by JVMTI native |
1095 | // agent during dump time). |
1096 | warn_excluded(k, "Unsupported location" ); |
1097 | return true; |
1098 | } |
1099 | if (k->signers() != NULL) { |
1100 | // We cannot include signed classes in the archive because the certificates |
1101 | // used during dump time may be different than those used during |
1102 | // runtime (due to expiration, etc). |
1103 | warn_excluded(k, "Signed JAR" ); |
1104 | return true; |
1105 | } |
1106 | if (is_jfr_event_class(k)) { |
1107 | // We cannot include JFR event classes because they need runtime-specific |
1108 | // instrumentation in order to work with -XX:FlightRecorderOptions=retransform=false. |
1109 | // There are only a small number of these classes, so it's not worthwhile to |
1110 | // support them and make CDS more complicated. |
1111 | warn_excluded(k, "JFR event class" ); |
1112 | return true; |
1113 | } |
1114 | if (k->init_state() < InstanceKlass::linked) { |
1115 | // In static dumping, we will attempt to link all classes. Those that fail to link will |
1116 | // be marked as in error state. |
1117 | assert(DynamicDumpSharedSpaces, "must be" ); |
1118 | |
1119 | // TODO -- rethink how this can be handled. |
1120 | // We should try to link ik, however, we can't do it here because |
1121 | // 1. We are at VM exit |
1122 | // 2. linking a class may cause other classes to be loaded, which means |
1123 | // a custom ClassLoader.loadClass() may be called, at a point where the |
1124 | // class loader doesn't expect it. |
1125 | warn_excluded(k, "Not linked" ); |
1126 | return true; |
1127 | } |
1128 | if (k->major_version() < 50 /*JAVA_6_VERSION*/) { |
1129 | ResourceMark rm; |
1130 | log_warning(cds)("Pre JDK 6 class not supported by CDS: %u.%u %s" , |
1131 | k->major_version(), k->minor_version(), k->name()->as_C_string()); |
1132 | return true; |
1133 | } |
1134 | |
1135 | InstanceKlass* super = k->java_super(); |
1136 | if (super != NULL && should_be_excluded(super)) { |
1137 | ResourceMark rm; |
1138 | log_warning(cds)("Skipping %s: super class %s is excluded" , k->name()->as_C_string(), super->name()->as_C_string()); |
1139 | return true; |
1140 | } |
1141 | |
1142 | Array<InstanceKlass*>* interfaces = k->local_interfaces(); |
1143 | int len = interfaces->length(); |
1144 | for (int i = 0; i < len; i++) { |
1145 | InstanceKlass* intf = interfaces->at(i); |
1146 | if (should_be_excluded(intf)) { |
1147 | log_warning(cds)("Skipping %s: interface %s is excluded" , k->name()->as_C_string(), intf->name()->as_C_string()); |
1148 | return true; |
1149 | } |
1150 | } |
1151 | |
1152 | return false; |
1153 | } |
1154 | |
1155 | // k is a class before relocating by ArchiveCompactor |
1156 | void SystemDictionaryShared::validate_before_archiving(InstanceKlass* k) { |
1157 | ResourceMark rm; |
1158 | const char* name = k->name()->as_C_string(); |
1159 | DumpTimeSharedClassInfo* info = _dumptime_table->get(k); |
1160 | assert(_no_class_loading_should_happen, "class loading must be disabled" ); |
1161 | guarantee(info != NULL, "Class %s must be entered into _dumptime_table" , name); |
1162 | guarantee(!info->is_excluded(), "Should not attempt to archive excluded class %s" , name); |
1163 | if (is_builtin(k)) { |
1164 | guarantee(k->loader_type() != 0, |
1165 | "Class loader type must be set for BUILTIN class %s" , name); |
1166 | } else { |
1167 | guarantee(k->loader_type() == 0, |
1168 | "Class loader type must not be set for UNREGISTERED class %s" , name); |
1169 | } |
1170 | } |
1171 | |
1172 | class ExcludeDumpTimeSharedClasses : StackObj { |
1173 | public: |
1174 | bool do_entry(InstanceKlass* k, DumpTimeSharedClassInfo& info) { |
1175 | if (SystemDictionaryShared::should_be_excluded(k)) { |
1176 | info.set_excluded(); |
1177 | } |
1178 | return true; // keep on iterating |
1179 | } |
1180 | }; |
1181 | |
1182 | void SystemDictionaryShared::check_excluded_classes() { |
1183 | ExcludeDumpTimeSharedClasses excl; |
1184 | _dumptime_table->iterate(&excl); |
1185 | _dumptime_table->update_counts(); |
1186 | } |
1187 | |
1188 | bool SystemDictionaryShared::is_excluded_class(InstanceKlass* k) { |
1189 | assert(_no_class_loading_should_happen, "sanity" ); |
1190 | assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "only when dumping" ); |
1191 | return find_or_allocate_info_for(k)->is_excluded(); |
1192 | } |
1193 | |
1194 | class IterateDumpTimeSharedClassTable : StackObj { |
1195 | MetaspaceClosure *_it; |
1196 | public: |
1197 | IterateDumpTimeSharedClassTable(MetaspaceClosure* it) : _it(it) {} |
1198 | |
1199 | bool do_entry(InstanceKlass* k, DumpTimeSharedClassInfo& info) { |
1200 | if (!info.is_excluded()) { |
1201 | info.metaspace_pointers_do(_it); |
1202 | } |
1203 | return true; // keep on iterating |
1204 | } |
1205 | }; |
1206 | |
1207 | void SystemDictionaryShared::dumptime_classes_do(class MetaspaceClosure* it) { |
1208 | IterateDumpTimeSharedClassTable iter(it); |
1209 | _dumptime_table->iterate(&iter); |
1210 | } |
1211 | |
1212 | bool SystemDictionaryShared::add_verification_constraint(InstanceKlass* k, Symbol* name, |
1213 | Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object) { |
1214 | assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "called at dump time only" ); |
1215 | DumpTimeSharedClassInfo* info = find_or_allocate_info_for(k); |
1216 | info->add_verification_constraint(k, name, from_name, from_field_is_protected, |
1217 | from_is_array, from_is_object); |
1218 | |
1219 | if (DynamicDumpSharedSpaces) { |
1220 | // For dynamic dumping, we can resolve all the constraint classes for all class loaders during |
1221 | // the initial run prior to creating the archive before vm exit. We will also perform verification |
1222 | // check when running with the archive. |
1223 | return false; |
1224 | } else { |
1225 | if (is_builtin(k)) { |
1226 | // For builtin class loaders, we can try to complete the verification check at dump time, |
1227 | // because we can resolve all the constraint classes. We will also perform verification check |
1228 | // when running with the archive. |
1229 | return false; |
1230 | } else { |
1231 | // For non-builtin class loaders, we cannot complete the verification check at dump time, |
1232 | // because at dump time we don't know how to resolve classes for such loaders. |
1233 | return true; |
1234 | } |
1235 | } |
1236 | } |
1237 | |
1238 | void DumpTimeSharedClassInfo::add_verification_constraint(InstanceKlass* k, Symbol* name, |
1239 | Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object) { |
1240 | if (_verifier_constraints == NULL) { |
1241 | _verifier_constraints = new(ResourceObj::C_HEAP, mtClass) GrowableArray<DTConstraint>(4, true, mtClass); |
1242 | } |
1243 | if (_verifier_constraint_flags == NULL) { |
1244 | _verifier_constraint_flags = new(ResourceObj::C_HEAP, mtClass) GrowableArray<char>(4, true, mtClass); |
1245 | } |
1246 | GrowableArray<DTConstraint>* vc_array = _verifier_constraints; |
1247 | for (int i = 0; i < vc_array->length(); i++) { |
1248 | DTConstraint* p = vc_array->adr_at(i); |
1249 | if (name == p->_name && from_name == p->_from_name) { |
1250 | return; |
1251 | } |
1252 | } |
1253 | DTConstraint cons(name, from_name); |
1254 | vc_array->append(cons); |
1255 | |
1256 | GrowableArray<char>* vcflags_array = _verifier_constraint_flags; |
1257 | char c = 0; |
1258 | c |= from_field_is_protected ? SystemDictionaryShared::FROM_FIELD_IS_PROTECTED : 0; |
1259 | c |= from_is_array ? SystemDictionaryShared::FROM_IS_ARRAY : 0; |
1260 | c |= from_is_object ? SystemDictionaryShared::FROM_IS_OBJECT : 0; |
1261 | vcflags_array->append(c); |
1262 | |
1263 | if (log_is_enabled(Trace, cds, verification)) { |
1264 | ResourceMark rm; |
1265 | log_trace(cds, verification)("add_verification_constraint: %s: %s must be subclass of %s [0x%x]" , |
1266 | k->external_name(), from_name->as_klass_external_name(), |
1267 | name->as_klass_external_name(), c); |
1268 | } |
1269 | } |
1270 | |
1271 | void SystemDictionaryShared::check_verification_constraints(InstanceKlass* klass, |
1272 | TRAPS) { |
1273 | assert(!DumpSharedSpaces && UseSharedSpaces, "called at run time with CDS enabled only" ); |
1274 | RunTimeSharedClassInfo* record = RunTimeSharedClassInfo::get_for(klass); |
1275 | |
1276 | int length = record->_num_constraints; |
1277 | if (length > 0) { |
1278 | for (int i = 0; i < length; i++) { |
1279 | Symbol* name = record->get_constraint_name(i); |
1280 | Symbol* from_name = record->get_constraint_from_name(i); |
1281 | char c = record->get_constraint_flag(i); |
1282 | |
1283 | if (log_is_enabled(Trace, cds, verification)) { |
1284 | ResourceMark rm(THREAD); |
1285 | log_trace(cds, verification)("check_verification_constraint: %s: %s must be subclass of %s [0x%x]" , |
1286 | klass->external_name(), from_name->as_klass_external_name(), |
1287 | name->as_klass_external_name(), c); |
1288 | } |
1289 | |
1290 | bool from_field_is_protected = (c & SystemDictionaryShared::FROM_FIELD_IS_PROTECTED) ? true : false; |
1291 | bool from_is_array = (c & SystemDictionaryShared::FROM_IS_ARRAY) ? true : false; |
1292 | bool from_is_object = (c & SystemDictionaryShared::FROM_IS_OBJECT) ? true : false; |
1293 | |
1294 | bool ok = VerificationType::resolve_and_check_assignability(klass, name, |
1295 | from_name, from_field_is_protected, from_is_array, from_is_object, CHECK); |
1296 | if (!ok) { |
1297 | ResourceMark rm(THREAD); |
1298 | stringStream ss; |
1299 | |
1300 | ss.print_cr("Bad type on operand stack" ); |
1301 | ss.print_cr("Exception Details:" ); |
1302 | ss.print_cr(" Location:\n %s" , klass->name()->as_C_string()); |
1303 | ss.print_cr(" Reason:\n Type '%s' is not assignable to '%s'" , |
1304 | from_name->as_quoted_ascii(), name->as_quoted_ascii()); |
1305 | THROW_MSG(vmSymbols::java_lang_VerifyError(), ss.as_string()); |
1306 | } |
1307 | } |
1308 | } |
1309 | } |
1310 | |
1311 | class EstimateSizeForArchive : StackObj { |
1312 | size_t _shared_class_info_size; |
1313 | int _num_builtin_klasses; |
1314 | int _num_unregistered_klasses; |
1315 | |
1316 | public: |
1317 | EstimateSizeForArchive() { |
1318 | _shared_class_info_size = 0; |
1319 | _num_builtin_klasses = 0; |
1320 | _num_unregistered_klasses = 0; |
1321 | } |
1322 | |
1323 | bool do_entry(InstanceKlass* k, DumpTimeSharedClassInfo& info) { |
1324 | if (!info.is_excluded()) { |
1325 | size_t byte_size = RunTimeSharedClassInfo::byte_size(info._klass, info.num_constraints()); |
1326 | _shared_class_info_size += align_up(byte_size, BytesPerWord); |
1327 | } |
1328 | return true; // keep on iterating |
1329 | } |
1330 | |
1331 | size_t total() { |
1332 | return _shared_class_info_size; |
1333 | } |
1334 | }; |
1335 | |
1336 | size_t SystemDictionaryShared::estimate_size_for_archive() { |
1337 | EstimateSizeForArchive est; |
1338 | _dumptime_table->iterate(&est); |
1339 | return est.total() + |
1340 | CompactHashtableWriter::estimate_size(_dumptime_table->count_of(true)) + |
1341 | CompactHashtableWriter::estimate_size(_dumptime_table->count_of(false)); |
1342 | } |
1343 | |
1344 | class CopySharedClassInfoToArchive : StackObj { |
1345 | CompactHashtableWriter* _writer; |
1346 | bool _is_builtin; |
1347 | public: |
1348 | CopySharedClassInfoToArchive(CompactHashtableWriter* writer, |
1349 | bool is_builtin, |
1350 | bool is_static_archive) |
1351 | : _writer(writer), _is_builtin(is_builtin) {} |
1352 | |
1353 | bool do_entry(InstanceKlass* k, DumpTimeSharedClassInfo& info) { |
1354 | if (!info.is_excluded() && info.is_builtin() == _is_builtin) { |
1355 | size_t byte_size = RunTimeSharedClassInfo::byte_size(info._klass, info.num_constraints()); |
1356 | RunTimeSharedClassInfo* record; |
1357 | record = (RunTimeSharedClassInfo*)MetaspaceShared::read_only_space_alloc(byte_size); |
1358 | record->init(info); |
1359 | |
1360 | unsigned int hash; |
1361 | Symbol* name = info._klass->name(); |
1362 | if (DynamicDumpSharedSpaces) { |
1363 | name = DynamicArchive::original_to_target(name); |
1364 | } |
1365 | hash = primitive_hash<Symbol*>(name); |
1366 | u4 delta; |
1367 | if (DynamicDumpSharedSpaces) { |
1368 | delta = MetaspaceShared::object_delta_u4(DynamicArchive::buffer_to_target(record)); |
1369 | } else { |
1370 | delta = MetaspaceShared::object_delta_u4(record); |
1371 | } |
1372 | _writer->add(hash, delta); |
1373 | if (log_is_enabled(Trace, cds, hashtables)) { |
1374 | ResourceMark rm; |
1375 | log_trace(cds,hashtables)("%s dictionary: %s" , (_is_builtin ? "builtin" : "unregistered" ), info._klass->external_name()); |
1376 | } |
1377 | |
1378 | // Save this for quick runtime lookup of InstanceKlass* -> RunTimeSharedClassInfo* |
1379 | RunTimeSharedClassInfo::set_for(info._klass, record); |
1380 | } |
1381 | return true; // keep on iterating |
1382 | } |
1383 | }; |
1384 | |
1385 | void SystemDictionaryShared::write_dictionary(RunTimeSharedDictionary* dictionary, |
1386 | bool is_builtin, |
1387 | bool is_static_archive) { |
1388 | CompactHashtableStats stats; |
1389 | dictionary->reset(); |
1390 | CompactHashtableWriter writer(_dumptime_table->count_of(is_builtin), &stats); |
1391 | CopySharedClassInfoToArchive copy(&writer, is_builtin, is_static_archive); |
1392 | _dumptime_table->iterate(©); |
1393 | writer.dump(dictionary, is_builtin ? "builtin dictionary" : "unregistered dictionary" ); |
1394 | } |
1395 | |
1396 | void SystemDictionaryShared::write_to_archive(bool is_static_archive) { |
1397 | if (is_static_archive) { |
1398 | write_dictionary(&_builtin_dictionary, true); |
1399 | write_dictionary(&_unregistered_dictionary, false); |
1400 | } else { |
1401 | write_dictionary(&_dynamic_builtin_dictionary, true); |
1402 | write_dictionary(&_dynamic_unregistered_dictionary, false); |
1403 | } |
1404 | } |
1405 | |
1406 | void SystemDictionaryShared::(SerializeClosure* soc, |
1407 | bool is_static_archive) { |
1408 | if (is_static_archive) { |
1409 | _builtin_dictionary.serialize_header(soc); |
1410 | _unregistered_dictionary.serialize_header(soc); |
1411 | } else { |
1412 | _dynamic_builtin_dictionary.serialize_header(soc); |
1413 | _dynamic_unregistered_dictionary.serialize_header(soc); |
1414 | } |
1415 | } |
1416 | |
1417 | const RunTimeSharedClassInfo* |
1418 | SystemDictionaryShared::find_record(RunTimeSharedDictionary* dict, Symbol* name) { |
1419 | if (UseSharedSpaces) { |
1420 | unsigned int hash = primitive_hash<Symbol*>(name); |
1421 | return dict->lookup(name, hash, 0); |
1422 | } else { |
1423 | return NULL; |
1424 | } |
1425 | } |
1426 | |
1427 | InstanceKlass* SystemDictionaryShared::find_builtin_class(Symbol* name) { |
1428 | const RunTimeSharedClassInfo* record = find_record(&_builtin_dictionary, name); |
1429 | if (record) { |
1430 | return record->_klass; |
1431 | } |
1432 | |
1433 | if (DynamicArchive::is_mapped()) { |
1434 | record = find_record(&_dynamic_builtin_dictionary, name); |
1435 | if (record) { |
1436 | return record->_klass; |
1437 | } |
1438 | } |
1439 | |
1440 | return NULL; |
1441 | } |
1442 | |
1443 | void SystemDictionaryShared::update_shared_entry(InstanceKlass* k, int id) { |
1444 | assert(DumpSharedSpaces, "supported only when dumping" ); |
1445 | DumpTimeSharedClassInfo* info = find_or_allocate_info_for(k); |
1446 | info->_id = id; |
1447 | } |
1448 | |
1449 | class SharedDictionaryPrinter : StackObj { |
1450 | outputStream* _st; |
1451 | int _index; |
1452 | public: |
1453 | SharedDictionaryPrinter(outputStream* st) : _st(st), _index(0) {} |
1454 | |
1455 | void do_value(const RunTimeSharedClassInfo* record) { |
1456 | ResourceMark rm; |
1457 | _st->print_cr("%4d: %s" , (_index++), record->_klass->external_name()); |
1458 | } |
1459 | }; |
1460 | |
1461 | void SystemDictionaryShared::print_on(outputStream* st) { |
1462 | if (UseSharedSpaces) { |
1463 | st->print_cr("Shared Dictionary" ); |
1464 | SharedDictionaryPrinter p(st); |
1465 | _builtin_dictionary.iterate(&p); |
1466 | _unregistered_dictionary.iterate(&p); |
1467 | if (DynamicArchive::is_mapped()) { |
1468 | _dynamic_builtin_dictionary.iterate(&p); |
1469 | _unregistered_dictionary.iterate(&p); |
1470 | } |
1471 | } |
1472 | } |
1473 | |
1474 | void SystemDictionaryShared::print_table_statistics(outputStream* st) { |
1475 | if (UseSharedSpaces) { |
1476 | _builtin_dictionary.print_table_statistics(st, "Builtin Shared Dictionary" ); |
1477 | _unregistered_dictionary.print_table_statistics(st, "Unregistered Shared Dictionary" ); |
1478 | if (DynamicArchive::is_mapped()) { |
1479 | _dynamic_builtin_dictionary.print_table_statistics(st, "Dynamic Builtin Shared Dictionary" ); |
1480 | _dynamic_unregistered_dictionary.print_table_statistics(st, "Unregistered Shared Dictionary" ); |
1481 | } |
1482 | } |
1483 | } |
1484 | |
1485 | bool SystemDictionaryShared::empty_dumptime_table() { |
1486 | if (_dumptime_table == NULL) { |
1487 | return true; |
1488 | } |
1489 | _dumptime_table->update_counts(); |
1490 | if (_dumptime_table->count_of(true) == 0 && _dumptime_table->count_of(false) == 0){ |
1491 | return true; |
1492 | } |
1493 | return false; |
1494 | } |
1495 | |