47 #include "classfile/classLoaderData.inline.hpp"
48 #include "classfile/classLoaderDataGraph.hpp"
49 #include "classfile/dictionary.hpp"
50 #include "classfile/javaClasses.inline.hpp"
51 #include "classfile/symbolTable.hpp"
52 #include "classfile/systemDictionary.hpp"
53 #include "classfile/systemDictionaryShared.hpp"
54 #include "classfile/verificationType.hpp"
55 #include "classfile/vmClasses.hpp"
56 #include "classfile/vmSymbols.hpp"
57 #include "jfr/jfrEvents.hpp"
58 #include "logging/log.hpp"
59 #include "logging/logStream.hpp"
60 #include "memory/allocation.hpp"
61 #include "memory/metadataFactory.hpp"
62 #include "memory/metaspaceClosure.hpp"
63 #include "memory/oopFactory.hpp"
64 #include "memory/resourceArea.hpp"
65 #include "memory/universe.hpp"
66 #include "oops/compressedKlass.inline.hpp"
67 #include "oops/instanceKlass.hpp"
68 #include "oops/klass.inline.hpp"
69 #include "oops/objArrayKlass.hpp"
70 #include "oops/objArrayOop.inline.hpp"
71 #include "oops/oop.inline.hpp"
72 #include "oops/oopHandle.inline.hpp"
73 #include "oops/typeArrayOop.inline.hpp"
74 #include "runtime/arguments.hpp"
75 #include "runtime/handles.inline.hpp"
76 #include "runtime/java.hpp"
77 #include "runtime/javaCalls.hpp"
78 #include "runtime/mutexLocker.hpp"
79 #include "utilities/hashTable.hpp"
80 #include "utilities/stringUtils.hpp"
81
82 SystemDictionaryShared::ArchiveInfo SystemDictionaryShared::_info_for_static_archive;
83 SystemDictionaryShared::ArchiveInfo SystemDictionaryShared::_info_for_dynamic_archive;
84 SystemDictionaryShared::ArchiveInfo SystemDictionaryShared::_info_for_dumping;
85
86 DumpTimeSharedClassTable* SystemDictionaryShared::_dumptime_table = nullptr;
281 Array<InstanceKlass*>* interfaces = k->local_interfaces();
282 int len = interfaces->length();
283 for (int i = 0; i < len; i++) {
284 add_candidate(interfaces->at(i));
285 }
286
287 InstanceKlass* nest_host = k->nest_host_or_null();
288 if (nest_host != nullptr && nest_host != k) {
289 add_candidate(nest_host);
290 }
291
292 if (CDSConfig::is_preserving_verification_constraints()) {
293 SystemDictionaryShared::iterate_verification_constraint_names(k, info, [&] (Symbol* constraint_class_name) {
294 Klass* constraint_bottom_class = find_verification_constraint_bottom_class(k, constraint_class_name);
295 if (constraint_bottom_class != nullptr && constraint_bottom_class->is_instance_klass()) {
296 add_candidate(InstanceKlass::cast(constraint_bottom_class));
297 }
298 return true; // Keep iterating.
299 });
300 }
301 }
302
303 public:
304 ExclusionCheckCandidates(InstanceKlass* k) {
305 add_candidate(k);
306 }
307 };
308
309 // A class X is excluded if check_self_exclusion() returns true for X or any of
310 // X's "exclusion dependency" classes, which include:
311 // - ik's super types
312 // - ik's nest host (if any)
313 //
314 // plus, if CDSConfig::is_preserving_verification_constraints()==true:
315 // - ik's verification constraints. These are the classes used in assignability checks
316 // when verifying ik's bytecodes.
317 //
318 // This method ensure that exclusion check is performed on X and all of its exclusion dependencies.
319 void SystemDictionaryShared::check_exclusion_for_self_and_dependencies(InstanceKlass* ik) {
320 assert_lock_strong(DumpTimeTable_lock);
503 if (CDSConfig::is_preserving_verification_constraints()) {
504 bool excluded = false;
505
506 iterate_verification_constraint_names(k, info, [&] (Symbol* constraint_class_name) {
507 if (check_verification_constraint_exclusion(k, constraint_class_name)) {
508 // If one of the verification constraint class has been excluded, the assignability checks
509 // by the verifier may no longer be valid in the production run. For safety, exclude this class.
510 excluded = true;
511 return false; // terminate iteration; k will be excluded
512 } else {
513 return true; // keep iterating
514 }
515 });
516
517 if (excluded) {
518 // At least one verification constraint class has been excluded
519 return true;
520 }
521 }
522
523 return false;
524 }
525
526 bool SystemDictionaryShared::is_dependency_excluded(InstanceKlass* k, InstanceKlass* dependency, const char* type) {
527 if (CDSConfig::is_dumping_dynamic_archive() && AOTMetaspace::in_aot_cache(dependency)) {
528 return false;
529 }
530 DumpTimeClassInfo* dependency_info = get_info_locked(dependency);
531 if (dependency_info->is_excluded()) {
532 ResourceMark rm;
533 aot_log_info(aot)("Skipping %s: %s %s is excluded", k->name()->as_C_string(), type, dependency->name()->as_C_string());
534 return true;
535 }
536 return false;
537 }
538
539 bool SystemDictionaryShared::check_verification_constraint_exclusion(InstanceKlass* k, Symbol* constraint_class_name) {
540 Klass* constraint_bottom_class = find_verification_constraint_bottom_class(k, constraint_class_name);
541 if (constraint_bottom_class == nullptr) {
542 // We don't have a bottom class (constraint_class_name is a type array), or constraint_class_name
|
47 #include "classfile/classLoaderData.inline.hpp"
48 #include "classfile/classLoaderDataGraph.hpp"
49 #include "classfile/dictionary.hpp"
50 #include "classfile/javaClasses.inline.hpp"
51 #include "classfile/symbolTable.hpp"
52 #include "classfile/systemDictionary.hpp"
53 #include "classfile/systemDictionaryShared.hpp"
54 #include "classfile/verificationType.hpp"
55 #include "classfile/vmClasses.hpp"
56 #include "classfile/vmSymbols.hpp"
57 #include "jfr/jfrEvents.hpp"
58 #include "logging/log.hpp"
59 #include "logging/logStream.hpp"
60 #include "memory/allocation.hpp"
61 #include "memory/metadataFactory.hpp"
62 #include "memory/metaspaceClosure.hpp"
63 #include "memory/oopFactory.hpp"
64 #include "memory/resourceArea.hpp"
65 #include "memory/universe.hpp"
66 #include "oops/compressedKlass.inline.hpp"
67 #include "oops/fieldStreams.inline.hpp"
68 #include "oops/instanceKlass.hpp"
69 #include "oops/klass.inline.hpp"
70 #include "oops/objArrayKlass.hpp"
71 #include "oops/objArrayOop.inline.hpp"
72 #include "oops/oop.inline.hpp"
73 #include "oops/oopHandle.inline.hpp"
74 #include "oops/typeArrayOop.inline.hpp"
75 #include "runtime/arguments.hpp"
76 #include "runtime/handles.inline.hpp"
77 #include "runtime/java.hpp"
78 #include "runtime/javaCalls.hpp"
79 #include "runtime/mutexLocker.hpp"
80 #include "utilities/hashTable.hpp"
81 #include "utilities/stringUtils.hpp"
82
83 SystemDictionaryShared::ArchiveInfo SystemDictionaryShared::_info_for_static_archive;
84 SystemDictionaryShared::ArchiveInfo SystemDictionaryShared::_info_for_dynamic_archive;
85 SystemDictionaryShared::ArchiveInfo SystemDictionaryShared::_info_for_dumping;
86
87 DumpTimeSharedClassTable* SystemDictionaryShared::_dumptime_table = nullptr;
282 Array<InstanceKlass*>* interfaces = k->local_interfaces();
283 int len = interfaces->length();
284 for (int i = 0; i < len; i++) {
285 add_candidate(interfaces->at(i));
286 }
287
288 InstanceKlass* nest_host = k->nest_host_or_null();
289 if (nest_host != nullptr && nest_host != k) {
290 add_candidate(nest_host);
291 }
292
293 if (CDSConfig::is_preserving_verification_constraints()) {
294 SystemDictionaryShared::iterate_verification_constraint_names(k, info, [&] (Symbol* constraint_class_name) {
295 Klass* constraint_bottom_class = find_verification_constraint_bottom_class(k, constraint_class_name);
296 if (constraint_bottom_class != nullptr && constraint_bottom_class->is_instance_klass()) {
297 add_candidate(InstanceKlass::cast(constraint_bottom_class));
298 }
299 return true; // Keep iterating.
300 });
301 }
302
303 // Inline fields need to have their layouts preserved between dumptime and runtime.
304 // To ensure this, the types of the fields must be stored in the archive along with
305 // the field holder.
306 if (k->has_inlined_fields() || k->has_null_restricted_static_fields()) {
307 for (AllFieldStream fs(k); !fs.done(); fs.next()) {
308 if (fs.is_flat() || fs.is_null_free_inline_type()) {
309 InlineKlass* field_klass = k->get_inline_type_field_klass(fs.index());
310 add_candidate(InstanceKlass::cast(field_klass));
311 }
312 }
313 }
314 }
315
316 public:
317 ExclusionCheckCandidates(InstanceKlass* k) {
318 add_candidate(k);
319 }
320 };
321
322 // A class X is excluded if check_self_exclusion() returns true for X or any of
323 // X's "exclusion dependency" classes, which include:
324 // - ik's super types
325 // - ik's nest host (if any)
326 //
327 // plus, if CDSConfig::is_preserving_verification_constraints()==true:
328 // - ik's verification constraints. These are the classes used in assignability checks
329 // when verifying ik's bytecodes.
330 //
331 // This method ensure that exclusion check is performed on X and all of its exclusion dependencies.
332 void SystemDictionaryShared::check_exclusion_for_self_and_dependencies(InstanceKlass* ik) {
333 assert_lock_strong(DumpTimeTable_lock);
516 if (CDSConfig::is_preserving_verification_constraints()) {
517 bool excluded = false;
518
519 iterate_verification_constraint_names(k, info, [&] (Symbol* constraint_class_name) {
520 if (check_verification_constraint_exclusion(k, constraint_class_name)) {
521 // If one of the verification constraint class has been excluded, the assignability checks
522 // by the verifier may no longer be valid in the production run. For safety, exclude this class.
523 excluded = true;
524 return false; // terminate iteration; k will be excluded
525 } else {
526 return true; // keep iterating
527 }
528 });
529
530 if (excluded) {
531 // At least one verification constraint class has been excluded
532 return true;
533 }
534 }
535
536 // If any of the null restricted or flat field types are excluded, the current
537 // klass must be excluded as well, otherwise there is no guarantee that the
538 // field layouts will be consistent at runtime.
539 if (k->has_inlined_fields() || k->has_null_restricted_static_fields()) {
540 for (AllFieldStream fs(k); !fs.done(); fs.next()) {
541 if (fs.is_flat() || fs.is_null_free_inline_type()) {
542 InlineKlass* field_klass = k->get_inline_type_field_klass(fs.index());
543 if (is_dependency_excluded(k, InstanceKlass::cast(field_klass), "inline field type")) {
544 return true;
545 }
546 }
547 }
548 }
549
550 return false;
551 }
552
553 bool SystemDictionaryShared::is_dependency_excluded(InstanceKlass* k, InstanceKlass* dependency, const char* type) {
554 if (CDSConfig::is_dumping_dynamic_archive() && AOTMetaspace::in_aot_cache(dependency)) {
555 return false;
556 }
557 DumpTimeClassInfo* dependency_info = get_info_locked(dependency);
558 if (dependency_info->is_excluded()) {
559 ResourceMark rm;
560 aot_log_info(aot)("Skipping %s: %s %s is excluded", k->name()->as_C_string(), type, dependency->name()->as_C_string());
561 return true;
562 }
563 return false;
564 }
565
566 bool SystemDictionaryShared::check_verification_constraint_exclusion(InstanceKlass* k, Symbol* constraint_class_name) {
567 Klass* constraint_bottom_class = find_verification_constraint_bottom_class(k, constraint_class_name);
568 if (constraint_bottom_class == nullptr) {
569 // We don't have a bottom class (constraint_class_name is a type array), or constraint_class_name
|