< prev index next >

src/hotspot/share/cds/heapShared.cpp

Print this page

  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;
< prev index next >