46 #include "classfile/javaClasses.inline.hpp"
47 #include "classfile/modules.hpp"
48 #include "classfile/stringTable.hpp"
49 #include "classfile/symbolTable.hpp"
50 #include "classfile/systemDictionary.hpp"
51 #include "classfile/systemDictionaryShared.hpp"
52 #include "classfile/vmClasses.hpp"
53 #include "classfile/vmSymbols.hpp"
54 #include "gc/shared/collectedHeap.hpp"
55 #include "gc/shared/gcLocker.hpp"
56 #include "gc/shared/gcVMOperations.hpp"
57 #include "logging/log.hpp"
58 #include "logging/logStream.hpp"
59 #include "memory/iterator.inline.hpp"
60 #include "memory/resourceArea.hpp"
61 #include "memory/universe.hpp"
62 #include "oops/compressedOops.inline.hpp"
63 #include "oops/fieldStreams.inline.hpp"
64 #include "oops/objArrayOop.inline.hpp"
65 #include "oops/oop.inline.hpp"
66 #include "oops/oopHandle.inline.hpp"
67 #include "oops/typeArrayOop.inline.hpp"
68 #include "prims/jvmtiExport.hpp"
69 #include "runtime/arguments.hpp"
70 #include "runtime/fieldDescriptor.inline.hpp"
71 #include "runtime/globals_extension.hpp"
72 #include "runtime/init.hpp"
73 #include "runtime/javaCalls.hpp"
74 #include "runtime/mutexLocker.hpp"
75 #include "runtime/safepointVerifiers.hpp"
76 #include "utilities/bitMap.inline.hpp"
77 #include "utilities/copy.hpp"
78 #if INCLUDE_G1GC
79 #include "gc/g1/g1CollectedHeap.hpp"
80 #endif
81
82 #if INCLUDE_CDS_JAVA_HEAP
83
84 struct ArchivableStaticFieldInfo {
85 const char* klass_name;
435 AOTStreamedHeapLoader::finish_initialization(static_mapinfo);
436 } else {
437 // Finish up archived heap initialization. These must be
438 // done after ReadClosure.
439 AOTMappedHeapLoader::finish_initialization(static_mapinfo);
440 }
441 }
442 }
443
444 void HeapShared::make_archived_object_cache_gc_safe() {
445 ArchivedObjectCache* new_cache = new (mtClass)ArchivedObjectCache(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE);
446
447 // It's safe to change the behavior of the hash function now, because iterate_all()
448 // doesn't call the hash function.
449 // See archived_object_cache_hash() for more details.
450 assert(_use_identity_hash_for_archived_object_cache == false, "happens only once");
451 _use_identity_hash_for_archived_object_cache = true;
452
453 // Copy all CachedOopInfo into a new table using a different hashing algorithm
454 archived_object_cache()->iterate_all([&] (OopHandle oh, CachedOopInfo info) {
455 new_cache->put_when_absent(oh, info);
456 });
457
458 destroy_archived_object_cache();
459 _archived_object_cache = new_cache;
460 }
461
462 HeapShared::CachedOopInfo* HeapShared::get_cached_oop_info(oop obj) {
463 OopHandle oh(Universe::vm_global(), obj);
464 CachedOopInfo* result = _archived_object_cache->get(oh);
465 oh.release(Universe::vm_global());
466 return result;
467 }
468
469 bool HeapShared::has_been_archived(oop obj) {
470 assert(CDSConfig::is_dumping_heap(), "dump-time only");
471 return get_cached_oop_info(obj) != nullptr;
472 }
473
474 int HeapShared::append_root(oop obj) {
475 assert(SafepointSynchronize::is_at_safepoint(), "sanity");
476 assert(CDSConfig::is_dumping_heap(), "dump-time only");
675 MutexLocker ml(ScratchObjects_lock, Mutex::_no_safepoint_check_flag);
676 OopHandle handle(Universe::vm_global(), o);
677 put_when_absent(ptr, handle);
678 }
679 void remove_oop(MetaspaceObj* ptr) {
680 MutexLocker ml(ScratchObjects_lock, Mutex::_no_safepoint_check_flag);
681 OopHandle* handle = get(ptr);
682 if (handle != nullptr) {
683 handle->release(Universe::vm_global());
684 remove(ptr);
685 }
686 }
687 };
688
689 void HeapShared::add_scratch_resolved_references(ConstantPool* src, objArrayOop dest) {
690 if (SystemDictionaryShared::is_builtin_loader(src->pool_holder()->class_loader_data())) {
691 _scratch_objects_table->set_oop(src, dest);
692 }
693 }
694
695 objArrayOop HeapShared::scratch_resolved_references(ConstantPool* src) {
696 return (objArrayOop)_scratch_objects_table->get_oop(src);
697 }
698
699 void HeapShared::remove_scratch_resolved_references(ConstantPool* src) {
700 if (CDSConfig::is_dumping_heap()) {
701 _scratch_objects_table->remove_oop(src);
702 }
703 }
704
705 void HeapShared::init_dumping() {
706 _scratch_objects_table = new (mtClass)MetaspaceObjToOopHandleTable();
707 _pending_roots = new GrowableArrayCHeap<oop, mtClassShared>(500);
708 _pending_roots->append(nullptr); // root index 0 represents a null oop
709 DEBUG_ONLY(_dumptime_classes_with_cached_oops = new (mtClassShared)ArchivableKlassTable());
710 }
711
712 void HeapShared::init_scratch_objects_for_basic_type_mirrors(TRAPS) {
713 for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
714 BasicType bt = (BasicType)i;
715 if (!is_reference_type(bt)) {
716 oop m = java_lang_Class::create_basic_type_mirror(type2name(bt), bt, CHECK);
873 assert(success, "sanity");
874 }
875
876 if (log_is_enabled(Debug, aot, init)) {
877 ResourceMark rm;
878 log_debug(aot, init)("copied %3d field(s) in aot-initialized mirror %s%s%s", nfields, ik->external_name(),
879 ik->is_hidden() ? " (hidden)" : "",
880 ik->is_enum_subclass() ? " (enum)" : "");
881 }
882 }
883
884 void HeapShared::copy_java_mirror(oop orig_mirror, oop scratch_m) {
885 // We need to retain the identity_hash, because it may have been used by some hashtables
886 // in the shared heap.
887 if (!orig_mirror->fast_no_hash_check()) {
888 intptr_t src_hash = orig_mirror->identity_hash();
889 if (UseCompactObjectHeaders) {
890 narrowKlass nk = CompressedKlassPointers::encode(orig_mirror->klass());
891 scratch_m->set_mark(markWord::prototype().set_narrow_klass(nk).copy_set_hash(src_hash));
892 } else {
893 scratch_m->set_mark(markWord::prototype().copy_set_hash(src_hash));
894 }
895 assert(scratch_m->mark().is_unlocked(), "sanity");
896
897 DEBUG_ONLY(intptr_t archived_hash = scratch_m->identity_hash());
898 assert(src_hash == archived_hash, "Different hash codes: original " INTPTR_FORMAT ", archived " INTPTR_FORMAT, src_hash, archived_hash);
899 }
900
901 if (CDSConfig::is_dumping_aot_linked_classes()) {
902 java_lang_Class::set_module(scratch_m, java_lang_Class::module(orig_mirror));
903 java_lang_Class::set_protection_domain(scratch_m, java_lang_Class::protection_domain(orig_mirror));
904 }
905 }
906
907 static objArrayOop get_archived_resolved_references(InstanceKlass* src_ik) {
908 if (SystemDictionaryShared::is_builtin_loader(src_ik->class_loader_data())) {
909 objArrayOop rr = src_ik->constants()->resolved_references_or_null();
910 if (rr != nullptr && !HeapShared::is_too_large_to_archive(rr)) {
911 return HeapShared::scratch_resolved_references(src_ik->constants());
912 }
913 }
914 return nullptr;
915 }
916
917 int HeapShared::archive_exception_instance(oop exception) {
918 bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, exception);
919 assert(success, "sanity");
920 return append_root(exception);
1097 // the original Klass*
1098 if (orig_k == vmClasses::String_klass() ||
1099 orig_k == vmClasses::Object_klass()) {
1100 // Initialized early during VM initialization. No need to be added
1101 // to the sub-graph object class list.
1102 return;
1103 }
1104 check_allowed_klass(InstanceKlass::cast(orig_k));
1105 } else if (orig_k->is_objArray_klass()) {
1106 Klass* abk = ObjArrayKlass::cast(orig_k)->bottom_klass();
1107 if (abk->is_instance_klass()) {
1108 assert(InstanceKlass::cast(abk)->defined_by_boot_loader(),
1109 "must be boot class");
1110 check_allowed_klass(InstanceKlass::cast(ObjArrayKlass::cast(orig_k)->bottom_klass()));
1111 }
1112 if (orig_k == Universe::objectArrayKlass()) {
1113 // Initialized early during Universe::genesis. No need to be added
1114 // to the list.
1115 return;
1116 }
1117 } else {
1118 assert(orig_k->is_typeArray_klass(), "must be");
1119 // Primitive type arrays are created early during Universe::genesis.
1120 return;
1121 }
1122
1123 if (log_is_enabled(Debug, aot, heap)) {
1124 if (!_subgraph_object_klasses->contains(orig_k)) {
1125 ResourceMark rm;
1126 log_debug(aot, heap)("Adding klass %s", orig_k->external_name());
1127 }
1128 }
1129
1130 _subgraph_object_klasses->append_if_missing(orig_k);
1131 }
1132
1133 void KlassSubGraphInfo::check_allowed_klass(InstanceKlass* ik) {
1134 #ifndef PRODUCT
1135 if (AOTClassInitializer::has_test_class()) {
1136 // The tests can cache arbitrary types of objects.
1472 _test_class = k;
1473 _test_class_record = record;
1474 }
1475 #endif
1476
1477 // Initialize from archived data. Currently this is done only
1478 // during VM initialization time. No lock is needed.
1479 if (record == nullptr) {
1480 if (log_is_enabled(Info, aot, heap)) {
1481 ResourceMark rm(THREAD);
1482 log_info(aot, heap)("subgraph %s is not recorded",
1483 k->external_name());
1484 }
1485 return nullptr;
1486 } else {
1487 if (log_is_enabled(Info, aot, heap)) {
1488 ResourceMark rm;
1489 log_info(aot, heap)("%s subgraph %s ", do_init ? "init" : "resolve", k->external_name());
1490 }
1491
1492 resolve_or_init(k, do_init, CHECK_NULL);
1493
1494 // Load/link/initialize the klasses of the objects in the subgraph.
1495 // nullptr class loader is used.
1496 Array<Klass*>* klasses = record->subgraph_object_klasses();
1497 if (klasses != nullptr) {
1498 for (int i = 0; i < klasses->length(); i++) {
1499 Klass* klass = klasses->at(i);
1500 if (!klass->in_aot_cache()) {
1501 return nullptr;
1502 }
1503 resolve_or_init(klass, do_init, CHECK_NULL);
1504 }
1505 }
1506 }
1507
1508 return record;
1509 }
1510
1511 void HeapShared::resolve_or_init(const char* klass_name, bool do_init, TRAPS) {
1512 TempNewSymbol klass_name_sym = SymbolTable::new_symbol(klass_name);
1513 InstanceKlass* k = SystemDictionaryShared::find_builtin_class(klass_name_sym);
1514 if (k == nullptr) {
1515 return;
1516 }
1517 assert(k->defined_by_boot_loader(), "sanity");
1518 resolve_or_init(k, false, CHECK);
1519 if (do_init) {
1520 resolve_or_init(k, true, CHECK);
1521 }
1522 }
1523
1524 void HeapShared::resolve_or_init(Klass* k, bool do_init, TRAPS) {
1525 if (!do_init) {
1526 if (k->class_loader_data() == nullptr) {
1527 Klass* resolved_k = SystemDictionary::resolve_or_null(k->name(), CHECK);
1528 assert(resolved_k == k, "classes used by archived heap must not be replaced by JVMTI ClassFileLoadHook");
1529 }
1530 } else {
1531 assert(k->class_loader_data() != nullptr, "must have been resolved by HeapShared::resolve_classes");
1532 if (k->is_instance_klass()) {
1533 InstanceKlass* ik = InstanceKlass::cast(k);
1534 ik->initialize(CHECK);
1535 } else if (k->is_objArray_klass()) {
1536 ObjArrayKlass* oak = ObjArrayKlass::cast(k);
1537 oak->initialize(CHECK);
1538 }
1539 }
1540 }
1541
1542 void HeapShared::init_archived_fields_for(Klass* k, const ArchivedKlassSubGraphInfoRecord* record) {
1543 verify_the_heap(k, "before");
1544
1545 Array<int>* entry_field_records = record->entry_field_records();
1546 if (entry_field_records != nullptr) {
1547 int efr_len = entry_field_records->length();
1548 assert(efr_len % 2 == 0, "sanity");
1968 }
1969 }
1970 #endif
1971
1972 void HeapShared::check_special_subgraph_classes() {
1973 if (CDSConfig::is_dumping_aot_linked_classes()) {
1974 // We can have aot-initialized classes (such as Enums) that can reference objects
1975 // of arbitrary types. Currently, we trust the JEP 483 implementation to only
1976 // aot-initialize classes that are "safe".
1977 //
1978 // TODO: we need an automatic tool that checks the safety of aot-initialized
1979 // classes (when we extend the set of aot-initialized classes beyond JEP 483)
1980 return;
1981 } else {
1982 // In this case, the special subgraph should contain a few specific types
1983 GrowableArray<Klass*>* klasses = _dump_time_special_subgraph->subgraph_object_klasses();
1984 int num = klasses->length();
1985 for (int i = 0; i < num; i++) {
1986 Klass* subgraph_k = klasses->at(i);
1987 Symbol* name = subgraph_k->name();
1988 if (subgraph_k->is_instance_klass() &&
1989 name != vmSymbols::java_lang_Class() &&
1990 name != vmSymbols::java_lang_String() &&
1991 name != vmSymbols::java_lang_ArithmeticException() &&
1992 name != vmSymbols::java_lang_ArrayIndexOutOfBoundsException() &&
1993 name != vmSymbols::java_lang_ArrayStoreException() &&
1994 name != vmSymbols::java_lang_ClassCastException() &&
1995 name != vmSymbols::java_lang_InternalError() &&
1996 name != vmSymbols::java_lang_NullPointerException() &&
1997 name != vmSymbols::jdk_internal_vm_PreemptedException()) {
1998 ResourceMark rm;
1999 fatal("special subgraph cannot have objects of type %s", subgraph_k->external_name());
2000 }
2001 }
2002 }
2003 }
2004
2005 HeapShared::SeenObjectsTable* HeapShared::_seen_objects_table = nullptr;
2006 HeapShared::PendingOop HeapShared::_object_being_archived;
2007 size_t HeapShared::_num_new_walked_objs;
2008 size_t HeapShared::_num_new_archived_objs;
|
46 #include "classfile/javaClasses.inline.hpp"
47 #include "classfile/modules.hpp"
48 #include "classfile/stringTable.hpp"
49 #include "classfile/symbolTable.hpp"
50 #include "classfile/systemDictionary.hpp"
51 #include "classfile/systemDictionaryShared.hpp"
52 #include "classfile/vmClasses.hpp"
53 #include "classfile/vmSymbols.hpp"
54 #include "gc/shared/collectedHeap.hpp"
55 #include "gc/shared/gcLocker.hpp"
56 #include "gc/shared/gcVMOperations.hpp"
57 #include "logging/log.hpp"
58 #include "logging/logStream.hpp"
59 #include "memory/iterator.inline.hpp"
60 #include "memory/resourceArea.hpp"
61 #include "memory/universe.hpp"
62 #include "oops/compressedOops.inline.hpp"
63 #include "oops/fieldStreams.inline.hpp"
64 #include "oops/objArrayOop.inline.hpp"
65 #include "oops/oop.inline.hpp"
66 #include "oops/oopCast.inline.hpp"
67 #include "oops/oopHandle.inline.hpp"
68 #include "oops/typeArrayOop.inline.hpp"
69 #include "prims/jvmtiExport.hpp"
70 #include "runtime/arguments.hpp"
71 #include "runtime/fieldDescriptor.inline.hpp"
72 #include "runtime/globals_extension.hpp"
73 #include "runtime/init.hpp"
74 #include "runtime/javaCalls.hpp"
75 #include "runtime/mutexLocker.hpp"
76 #include "runtime/safepointVerifiers.hpp"
77 #include "utilities/bitMap.inline.hpp"
78 #include "utilities/copy.hpp"
79 #if INCLUDE_G1GC
80 #include "gc/g1/g1CollectedHeap.hpp"
81 #endif
82
83 #if INCLUDE_CDS_JAVA_HEAP
84
85 struct ArchivableStaticFieldInfo {
86 const char* klass_name;
436 AOTStreamedHeapLoader::finish_initialization(static_mapinfo);
437 } else {
438 // Finish up archived heap initialization. These must be
439 // done after ReadClosure.
440 AOTMappedHeapLoader::finish_initialization(static_mapinfo);
441 }
442 }
443 }
444
445 void HeapShared::make_archived_object_cache_gc_safe() {
446 ArchivedObjectCache* new_cache = new (mtClass)ArchivedObjectCache(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE);
447
448 // It's safe to change the behavior of the hash function now, because iterate_all()
449 // doesn't call the hash function.
450 // See archived_object_cache_hash() for more details.
451 assert(_use_identity_hash_for_archived_object_cache == false, "happens only once");
452 _use_identity_hash_for_archived_object_cache = true;
453
454 // Copy all CachedOopInfo into a new table using a different hashing algorithm
455 archived_object_cache()->iterate_all([&] (OopHandle oh, CachedOopInfo info) {
456 if (Arguments::is_valhalla_enabled() && oh.resolve()->klass()->is_inline_klass()) {
457 // After make_archived_object_cache_gc_safe() returns,
458 // _archived_object_cache->get() is called only from the (future) AOT code
459 // compiler to access heap oops referenced by AOT-compiled method.
460 //
461 // As planned in JDK 27 (JDK-8335368), AOT-compiled methods will only reference
462 // oops that are Strings, mirrors, or exceptions, all of which are not value
463 // objects.
464 //
465 // We exclude value objects from new_cache, as we don't know how to track them
466 // after the GC moves them. This should be fixed when AOT-compiled methods
467 // need to reference value objects.
468 //
469 // Also TODO: the AOT heap should de-duplicate value objects with identical
470 // values. See JDK-8383381
471 } else {
472 new_cache->put_when_absent(oh, info);
473 }
474 });
475
476 destroy_archived_object_cache();
477 _archived_object_cache = new_cache;
478 }
479
480 HeapShared::CachedOopInfo* HeapShared::get_cached_oop_info(oop obj) {
481 OopHandle oh(Universe::vm_global(), obj);
482 CachedOopInfo* result = _archived_object_cache->get(oh);
483 oh.release(Universe::vm_global());
484 return result;
485 }
486
487 bool HeapShared::has_been_archived(oop obj) {
488 assert(CDSConfig::is_dumping_heap(), "dump-time only");
489 return get_cached_oop_info(obj) != nullptr;
490 }
491
492 int HeapShared::append_root(oop obj) {
493 assert(SafepointSynchronize::is_at_safepoint(), "sanity");
494 assert(CDSConfig::is_dumping_heap(), "dump-time only");
693 MutexLocker ml(ScratchObjects_lock, Mutex::_no_safepoint_check_flag);
694 OopHandle handle(Universe::vm_global(), o);
695 put_when_absent(ptr, handle);
696 }
697 void remove_oop(MetaspaceObj* ptr) {
698 MutexLocker ml(ScratchObjects_lock, Mutex::_no_safepoint_check_flag);
699 OopHandle* handle = get(ptr);
700 if (handle != nullptr) {
701 handle->release(Universe::vm_global());
702 remove(ptr);
703 }
704 }
705 };
706
707 void HeapShared::add_scratch_resolved_references(ConstantPool* src, objArrayOop dest) {
708 if (SystemDictionaryShared::is_builtin_loader(src->pool_holder()->class_loader_data())) {
709 _scratch_objects_table->set_oop(src, dest);
710 }
711 }
712
713 refArrayOop HeapShared::scratch_resolved_references(ConstantPool* src) {
714 oop rr = _scratch_objects_table->get_oop(src);
715 return rr == nullptr ? nullptr : oop_cast<refArrayOop>(rr);
716 }
717
718 void HeapShared::remove_scratch_resolved_references(ConstantPool* src) {
719 if (CDSConfig::is_dumping_heap()) {
720 _scratch_objects_table->remove_oop(src);
721 }
722 }
723
724 void HeapShared::init_dumping() {
725 _scratch_objects_table = new (mtClass)MetaspaceObjToOopHandleTable();
726 _pending_roots = new GrowableArrayCHeap<oop, mtClassShared>(500);
727 _pending_roots->append(nullptr); // root index 0 represents a null oop
728 DEBUG_ONLY(_dumptime_classes_with_cached_oops = new (mtClassShared)ArchivableKlassTable());
729 }
730
731 void HeapShared::init_scratch_objects_for_basic_type_mirrors(TRAPS) {
732 for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
733 BasicType bt = (BasicType)i;
734 if (!is_reference_type(bt)) {
735 oop m = java_lang_Class::create_basic_type_mirror(type2name(bt), bt, CHECK);
892 assert(success, "sanity");
893 }
894
895 if (log_is_enabled(Debug, aot, init)) {
896 ResourceMark rm;
897 log_debug(aot, init)("copied %3d field(s) in aot-initialized mirror %s%s%s", nfields, ik->external_name(),
898 ik->is_hidden() ? " (hidden)" : "",
899 ik->is_enum_subclass() ? " (enum)" : "");
900 }
901 }
902
903 void HeapShared::copy_java_mirror(oop orig_mirror, oop scratch_m) {
904 // We need to retain the identity_hash, because it may have been used by some hashtables
905 // in the shared heap.
906 if (!orig_mirror->fast_no_hash_check()) {
907 intptr_t src_hash = orig_mirror->identity_hash();
908 if (UseCompactObjectHeaders) {
909 narrowKlass nk = CompressedKlassPointers::encode(orig_mirror->klass());
910 scratch_m->set_mark(markWord::prototype().set_narrow_klass(nk).copy_set_hash(src_hash));
911 } else {
912 // For valhalla, the prototype header is the same as markWord::prototype();
913 scratch_m->set_mark(markWord::prototype().copy_set_hash(src_hash));
914 }
915 assert(scratch_m->mark().is_unlocked(), "sanity");
916
917 DEBUG_ONLY(intptr_t archived_hash = scratch_m->identity_hash());
918 assert(src_hash == archived_hash, "Different hash codes: original " INTPTR_FORMAT ", archived " INTPTR_FORMAT, src_hash, archived_hash);
919 }
920
921 Klass* k = java_lang_Class::as_Klass(orig_mirror);
922 if (k != nullptr && k->is_instance_klass()) {
923 InstanceKlass* ik = InstanceKlass::cast(k);
924
925 if (ik->is_inline_klass() && ik->is_initialized()) {
926 // Only concrete value classes need the null_reset field
927 InlineKlass* ilk = InlineKlass::cast(k);
928 if (ilk->supports_nullable_layouts()) {
929 scratch_m->obj_field_put(ilk->null_reset_value_offset(), ilk->null_reset_value());
930 }
931 }
932
933 if (ik->has_acmp_maps_offset()) {
934 int maps_offset = ik->acmp_maps_offset();
935 oop maps = orig_mirror->obj_field(maps_offset);
936 scratch_m->obj_field_put(maps_offset, maps);
937 }
938 }
939
940 if (CDSConfig::is_dumping_aot_linked_classes()) {
941 java_lang_Class::set_module(scratch_m, java_lang_Class::module(orig_mirror));
942 java_lang_Class::set_protection_domain(scratch_m, java_lang_Class::protection_domain(orig_mirror));
943 }
944 }
945
946 static objArrayOop get_archived_resolved_references(InstanceKlass* src_ik) {
947 if (SystemDictionaryShared::is_builtin_loader(src_ik->class_loader_data())) {
948 objArrayOop rr = src_ik->constants()->resolved_references_or_null();
949 if (rr != nullptr && !HeapShared::is_too_large_to_archive(rr)) {
950 return HeapShared::scratch_resolved_references(src_ik->constants());
951 }
952 }
953 return nullptr;
954 }
955
956 int HeapShared::archive_exception_instance(oop exception) {
957 bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, exception);
958 assert(success, "sanity");
959 return append_root(exception);
1136 // the original Klass*
1137 if (orig_k == vmClasses::String_klass() ||
1138 orig_k == vmClasses::Object_klass()) {
1139 // Initialized early during VM initialization. No need to be added
1140 // to the sub-graph object class list.
1141 return;
1142 }
1143 check_allowed_klass(InstanceKlass::cast(orig_k));
1144 } else if (orig_k->is_objArray_klass()) {
1145 Klass* abk = ObjArrayKlass::cast(orig_k)->bottom_klass();
1146 if (abk->is_instance_klass()) {
1147 assert(InstanceKlass::cast(abk)->defined_by_boot_loader(),
1148 "must be boot class");
1149 check_allowed_klass(InstanceKlass::cast(ObjArrayKlass::cast(orig_k)->bottom_klass()));
1150 }
1151 if (orig_k == Universe::objectArrayKlass()) {
1152 // Initialized early during Universe::genesis. No need to be added
1153 // to the list.
1154 return;
1155 }
1156 if (orig_k->is_flatArray_klass()) {
1157 _subgraph_object_klasses->append_if_missing(FlatArrayKlass::cast(orig_k)->element_klass());
1158 }
1159 } else {
1160 assert(orig_k->is_typeArray_klass(), "must be");
1161 // Primitive type arrays are created early during Universe::genesis.
1162 return;
1163 }
1164
1165 if (log_is_enabled(Debug, aot, heap)) {
1166 if (!_subgraph_object_klasses->contains(orig_k)) {
1167 ResourceMark rm;
1168 log_debug(aot, heap)("Adding klass %s", orig_k->external_name());
1169 }
1170 }
1171
1172 _subgraph_object_klasses->append_if_missing(orig_k);
1173 }
1174
1175 void KlassSubGraphInfo::check_allowed_klass(InstanceKlass* ik) {
1176 #ifndef PRODUCT
1177 if (AOTClassInitializer::has_test_class()) {
1178 // The tests can cache arbitrary types of objects.
1514 _test_class = k;
1515 _test_class_record = record;
1516 }
1517 #endif
1518
1519 // Initialize from archived data. Currently this is done only
1520 // during VM initialization time. No lock is needed.
1521 if (record == nullptr) {
1522 if (log_is_enabled(Info, aot, heap)) {
1523 ResourceMark rm(THREAD);
1524 log_info(aot, heap)("subgraph %s is not recorded",
1525 k->external_name());
1526 }
1527 return nullptr;
1528 } else {
1529 if (log_is_enabled(Info, aot, heap)) {
1530 ResourceMark rm;
1531 log_info(aot, heap)("%s subgraph %s ", do_init ? "init" : "resolve", k->external_name());
1532 }
1533
1534 Array<Klass*>* klasses = record->subgraph_object_klasses();
1535
1536 if (do_init && klasses != nullptr) {
1537 // All the classes of the oops in this subgraph are in the klasses array.
1538 // Link them first in case any of the oops are used in the <clinit> methods
1539 // invoked in the rest of this function.
1540 for (int i = 0; i < klasses->length(); i++) {
1541 Klass* klass = klasses->at(i);
1542 if (klass->in_aot_cache() && klass->is_instance_klass()) {
1543 InstanceKlass::cast(klass)->link_class(CHECK_NULL);
1544 }
1545 }
1546 }
1547
1548 resolve_or_init(k, do_init, CHECK_NULL);
1549
1550 // Load/link/initialize the klasses of the objects in the subgraph.
1551 // nullptr class loader is used.
1552 if (klasses != nullptr) {
1553 for (int i = 0; i < klasses->length(); i++) {
1554 Klass* klass = klasses->at(i);
1555 if (!klass->in_aot_cache()) {
1556 return nullptr;
1557 }
1558 resolve_or_init(klass, do_init, CHECK_NULL);
1559 }
1560 }
1561 }
1562
1563 return record;
1564 }
1565
1566 void HeapShared::resolve_or_init(const char* klass_name, bool do_init, TRAPS) {
1567 TempNewSymbol klass_name_sym = SymbolTable::new_symbol(klass_name);
1568 InstanceKlass* k = SystemDictionaryShared::find_builtin_class(klass_name_sym);
1569 if (k == nullptr) {
1570 return;
1571 }
1572 assert(k->defined_by_boot_loader(), "sanity");
1573 resolve_or_init(k, false, CHECK);
1574 if (do_init) {
1575 resolve_or_init(k, true, CHECK);
1576 }
1577 }
1578
1579 void HeapShared::resolve_or_init(Klass* k, bool do_init, TRAPS) {
1580 if (!do_init) {
1581 if (k->class_loader_data() == nullptr) {
1582 Klass* resolved_k = SystemDictionary::resolve_or_null(k->name(), CHECK);
1583 if (resolved_k->is_array_klass()) {
1584 assert(resolved_k == k || resolved_k == k->super(), "classes used by archived heap must not be replaced by JVMTI ClassFileLoadHook");
1585 } else {
1586 assert(resolved_k == k, "classes used by archived heap must not be replaced by JVMTI ClassFileLoadHook");
1587 }
1588 }
1589 } else {
1590 assert(k->class_loader_data() != nullptr, "must have been resolved by HeapShared::resolve_classes");
1591 if (k->is_instance_klass()) {
1592 InstanceKlass* ik = InstanceKlass::cast(k);
1593 ik->initialize(CHECK);
1594 } else if (k->is_objArray_klass()) {
1595 ObjArrayKlass* oak = ObjArrayKlass::cast(k);
1596 oak->initialize(CHECK);
1597 }
1598 }
1599 }
1600
1601 void HeapShared::init_archived_fields_for(Klass* k, const ArchivedKlassSubGraphInfoRecord* record) {
1602 verify_the_heap(k, "before");
1603
1604 Array<int>* entry_field_records = record->entry_field_records();
1605 if (entry_field_records != nullptr) {
1606 int efr_len = entry_field_records->length();
1607 assert(efr_len % 2 == 0, "sanity");
2027 }
2028 }
2029 #endif
2030
2031 void HeapShared::check_special_subgraph_classes() {
2032 if (CDSConfig::is_dumping_aot_linked_classes()) {
2033 // We can have aot-initialized classes (such as Enums) that can reference objects
2034 // of arbitrary types. Currently, we trust the JEP 483 implementation to only
2035 // aot-initialize classes that are "safe".
2036 //
2037 // TODO: we need an automatic tool that checks the safety of aot-initialized
2038 // classes (when we extend the set of aot-initialized classes beyond JEP 483)
2039 return;
2040 } else {
2041 // In this case, the special subgraph should contain a few specific types
2042 GrowableArray<Klass*>* klasses = _dump_time_special_subgraph->subgraph_object_klasses();
2043 int num = klasses->length();
2044 for (int i = 0; i < num; i++) {
2045 Klass* subgraph_k = klasses->at(i);
2046 Symbol* name = subgraph_k->name();
2047
2048 if (subgraph_k->is_identity_class() &&
2049 name != vmSymbols::java_lang_Class() &&
2050 name != vmSymbols::java_lang_String() &&
2051 name != vmSymbols::java_lang_ArithmeticException() &&
2052 name != vmSymbols::java_lang_ArrayIndexOutOfBoundsException() &&
2053 name != vmSymbols::java_lang_ArrayStoreException() &&
2054 name != vmSymbols::java_lang_ClassCastException() &&
2055 name != vmSymbols::java_lang_InternalError() &&
2056 name != vmSymbols::java_lang_NullPointerException() &&
2057 name != vmSymbols::jdk_internal_vm_PreemptedException()) {
2058 ResourceMark rm;
2059 fatal("special subgraph cannot have objects of type %s", subgraph_k->external_name());
2060 }
2061 }
2062 }
2063 }
2064
2065 HeapShared::SeenObjectsTable* HeapShared::_seen_objects_table = nullptr;
2066 HeapShared::PendingOop HeapShared::_object_being_archived;
2067 size_t HeapShared::_num_new_walked_objs;
2068 size_t HeapShared::_num_new_archived_objs;
|