607 assert(success, "sanity");
608 }
609
610 if (log_is_enabled(Debug, aot, init)) {
611 ResourceMark rm;
612 log_debug(aot, init)("copied %3d field(s) in aot-initialized mirror %s%s%s", nfields, ik->external_name(),
613 ik->is_hidden() ? " (hidden)" : "",
614 ik->is_enum_subclass() ? " (enum)" : "");
615 }
616 }
617
618 void HeapShared::copy_java_mirror(oop orig_mirror, oop scratch_m) {
619 // We need to retain the identity_hash, because it may have been used by some hashtables
620 // in the shared heap.
621 if (!orig_mirror->fast_no_hash_check()) {
622 intptr_t src_hash = orig_mirror->identity_hash();
623 if (UseCompactObjectHeaders) {
624 narrowKlass nk = CompressedKlassPointers::encode(orig_mirror->klass());
625 scratch_m->set_mark(markWord::prototype().set_narrow_klass(nk).copy_set_hash(src_hash));
626 } else {
627 scratch_m->set_mark(markWord::prototype().copy_set_hash(src_hash));
628 }
629 assert(scratch_m->mark().is_unlocked(), "sanity");
630
631 DEBUG_ONLY(intptr_t archived_hash = scratch_m->identity_hash());
632 assert(src_hash == archived_hash, "Different hash codes: original " INTPTR_FORMAT ", archived " INTPTR_FORMAT, src_hash, archived_hash);
633 }
634
635 if (CDSConfig::is_dumping_aot_linked_classes()) {
636 java_lang_Class::set_module(scratch_m, java_lang_Class::module(orig_mirror));
637 java_lang_Class::set_protection_domain(scratch_m, java_lang_Class::protection_domain(orig_mirror));
638 }
639 }
640
641 static objArrayOop get_archived_resolved_references(InstanceKlass* src_ik) {
642 if (SystemDictionaryShared::is_builtin_loader(src_ik->class_loader_data())) {
643 objArrayOop rr = src_ik->constants()->resolved_references_or_null();
644 if (rr != nullptr && !ArchiveHeapWriter::is_too_large_to_archive(rr)) {
645 return HeapShared::scratch_resolved_references(src_ik->constants());
646 }
1322 return record;
1323 }
1324
1325 void HeapShared::resolve_or_init(const char* klass_name, bool do_init, TRAPS) {
1326 TempNewSymbol klass_name_sym = SymbolTable::new_symbol(klass_name);
1327 InstanceKlass* k = SystemDictionaryShared::find_builtin_class(klass_name_sym);
1328 if (k == nullptr) {
1329 return;
1330 }
1331 assert(k->defined_by_boot_loader(), "sanity");
1332 resolve_or_init(k, false, CHECK);
1333 if (do_init) {
1334 resolve_or_init(k, true, CHECK);
1335 }
1336 }
1337
1338 void HeapShared::resolve_or_init(Klass* k, bool do_init, TRAPS) {
1339 if (!do_init) {
1340 if (k->class_loader_data() == nullptr) {
1341 Klass* resolved_k = SystemDictionary::resolve_or_null(k->name(), CHECK);
1342 assert(resolved_k == k, "classes used by archived heap must not be replaced by JVMTI ClassFileLoadHook");
1343 }
1344 } else {
1345 assert(k->class_loader_data() != nullptr, "must have been resolved by HeapShared::resolve_classes");
1346 if (k->is_instance_klass()) {
1347 InstanceKlass* ik = InstanceKlass::cast(k);
1348 ik->initialize(CHECK);
1349 } else if (k->is_objArray_klass()) {
1350 ObjArrayKlass* oak = ObjArrayKlass::cast(k);
1351 oak->initialize(CHECK);
1352 }
1353 }
1354 }
1355
1356 void HeapShared::init_archived_fields_for(Klass* k, const ArchivedKlassSubGraphInfoRecord* record) {
1357 verify_the_heap(k, "before");
1358
1359 // Load the subgraph entry fields from the record and store them back to
1360 // the corresponding fields within the mirror.
1361 oop m = k->java_mirror();
1362 Array<int>* entry_field_records = record->entry_field_records();
2066 }
2067 }
2068
2069 void HeapShared::archive_object_subgraphs(ArchivableStaticFieldInfo fields[],
2070 bool is_full_module_graph) {
2071 _num_total_subgraph_recordings = 0;
2072 _num_total_walked_objs = 0;
2073 _num_total_archived_objs = 0;
2074 _num_total_recorded_klasses = 0;
2075 _num_total_verifications = 0;
2076
2077 // For each class X that has one or more archived fields:
2078 // [1] Dump the subgraph of each archived field
2079 // [2] Create a list of all the class of the objects that can be reached
2080 // by any of these static fields.
2081 // At runtime, these classes are initialized before X's archived fields
2082 // are restored by HeapShared::initialize_from_archived_subgraph().
2083 for (int i = 0; fields[i].valid(); ) {
2084 ArchivableStaticFieldInfo* info = &fields[i];
2085 const char* klass_name = info->klass_name;
2086 start_recording_subgraph(info->klass, klass_name, is_full_module_graph);
2087
2088 // If you have specified consecutive fields of the same klass in
2089 // fields[], these will be archived in the same
2090 // {start_recording_subgraph ... done_recording_subgraph} pass to
2091 // save time.
2092 for (; fields[i].valid(); i++) {
2093 ArchivableStaticFieldInfo* f = &fields[i];
2094 if (f->klass_name != klass_name) {
2095 break;
2096 }
2097
2098 archive_reachable_objects_from_static_field(f->klass, f->klass_name,
2099 f->offset, f->field_name);
2100 }
2101 done_recording_subgraph(info->klass, klass_name);
2102 }
2103
2104 log_info(aot, heap)("Archived subgraph records = %d",
2105 _num_total_subgraph_recordings);
|
607 assert(success, "sanity");
608 }
609
610 if (log_is_enabled(Debug, aot, init)) {
611 ResourceMark rm;
612 log_debug(aot, init)("copied %3d field(s) in aot-initialized mirror %s%s%s", nfields, ik->external_name(),
613 ik->is_hidden() ? " (hidden)" : "",
614 ik->is_enum_subclass() ? " (enum)" : "");
615 }
616 }
617
618 void HeapShared::copy_java_mirror(oop orig_mirror, oop scratch_m) {
619 // We need to retain the identity_hash, because it may have been used by some hashtables
620 // in the shared heap.
621 if (!orig_mirror->fast_no_hash_check()) {
622 intptr_t src_hash = orig_mirror->identity_hash();
623 if (UseCompactObjectHeaders) {
624 narrowKlass nk = CompressedKlassPointers::encode(orig_mirror->klass());
625 scratch_m->set_mark(markWord::prototype().set_narrow_klass(nk).copy_set_hash(src_hash));
626 } else {
627 // For valhalla, the prototype header is the same as markWord::prototype();
628 scratch_m->set_mark(markWord::prototype().copy_set_hash(src_hash));
629 }
630 assert(scratch_m->mark().is_unlocked(), "sanity");
631
632 DEBUG_ONLY(intptr_t archived_hash = scratch_m->identity_hash());
633 assert(src_hash == archived_hash, "Different hash codes: original " INTPTR_FORMAT ", archived " INTPTR_FORMAT, src_hash, archived_hash);
634 }
635
636 if (CDSConfig::is_dumping_aot_linked_classes()) {
637 java_lang_Class::set_module(scratch_m, java_lang_Class::module(orig_mirror));
638 java_lang_Class::set_protection_domain(scratch_m, java_lang_Class::protection_domain(orig_mirror));
639 }
640 }
641
642 static objArrayOop get_archived_resolved_references(InstanceKlass* src_ik) {
643 if (SystemDictionaryShared::is_builtin_loader(src_ik->class_loader_data())) {
644 objArrayOop rr = src_ik->constants()->resolved_references_or_null();
645 if (rr != nullptr && !ArchiveHeapWriter::is_too_large_to_archive(rr)) {
646 return HeapShared::scratch_resolved_references(src_ik->constants());
647 }
1323 return record;
1324 }
1325
1326 void HeapShared::resolve_or_init(const char* klass_name, bool do_init, TRAPS) {
1327 TempNewSymbol klass_name_sym = SymbolTable::new_symbol(klass_name);
1328 InstanceKlass* k = SystemDictionaryShared::find_builtin_class(klass_name_sym);
1329 if (k == nullptr) {
1330 return;
1331 }
1332 assert(k->defined_by_boot_loader(), "sanity");
1333 resolve_or_init(k, false, CHECK);
1334 if (do_init) {
1335 resolve_or_init(k, true, CHECK);
1336 }
1337 }
1338
1339 void HeapShared::resolve_or_init(Klass* k, bool do_init, TRAPS) {
1340 if (!do_init) {
1341 if (k->class_loader_data() == nullptr) {
1342 Klass* resolved_k = SystemDictionary::resolve_or_null(k->name(), CHECK);
1343 if (resolved_k->is_array_klass()) {
1344 assert(resolved_k == k || resolved_k == k->super(), "classes used by archived heap must not be replaced by JVMTI ClassFileLoadHook");
1345 } else {
1346 assert(resolved_k == k, "classes used by archived heap must not be replaced by JVMTI ClassFileLoadHook");
1347 }
1348 }
1349 } else {
1350 assert(k->class_loader_data() != nullptr, "must have been resolved by HeapShared::resolve_classes");
1351 if (k->is_instance_klass()) {
1352 InstanceKlass* ik = InstanceKlass::cast(k);
1353 ik->initialize(CHECK);
1354 } else if (k->is_objArray_klass()) {
1355 ObjArrayKlass* oak = ObjArrayKlass::cast(k);
1356 oak->initialize(CHECK);
1357 }
1358 }
1359 }
1360
1361 void HeapShared::init_archived_fields_for(Klass* k, const ArchivedKlassSubGraphInfoRecord* record) {
1362 verify_the_heap(k, "before");
1363
1364 // Load the subgraph entry fields from the record and store them back to
1365 // the corresponding fields within the mirror.
1366 oop m = k->java_mirror();
1367 Array<int>* entry_field_records = record->entry_field_records();
2071 }
2072 }
2073
2074 void HeapShared::archive_object_subgraphs(ArchivableStaticFieldInfo fields[],
2075 bool is_full_module_graph) {
2076 _num_total_subgraph_recordings = 0;
2077 _num_total_walked_objs = 0;
2078 _num_total_archived_objs = 0;
2079 _num_total_recorded_klasses = 0;
2080 _num_total_verifications = 0;
2081
2082 // For each class X that has one or more archived fields:
2083 // [1] Dump the subgraph of each archived field
2084 // [2] Create a list of all the class of the objects that can be reached
2085 // by any of these static fields.
2086 // At runtime, these classes are initialized before X's archived fields
2087 // are restored by HeapShared::initialize_from_archived_subgraph().
2088 for (int i = 0; fields[i].valid(); ) {
2089 ArchivableStaticFieldInfo* info = &fields[i];
2090 const char* klass_name = info->klass_name;
2091
2092 if (CDSConfig::is_valhalla_preview() && strcmp(klass_name, "jdk/internal/module/ArchivedModuleGraph") == 0) {
2093 // FIXME -- ArchivedModuleGraph doesn't work when java.base is patched with valhalla classes.
2094 i++;
2095 continue;
2096 }
2097
2098 start_recording_subgraph(info->klass, klass_name, is_full_module_graph);
2099
2100 // If you have specified consecutive fields of the same klass in
2101 // fields[], these will be archived in the same
2102 // {start_recording_subgraph ... done_recording_subgraph} pass to
2103 // save time.
2104 for (; fields[i].valid(); i++) {
2105 ArchivableStaticFieldInfo* f = &fields[i];
2106 if (f->klass_name != klass_name) {
2107 break;
2108 }
2109
2110 archive_reachable_objects_from_static_field(f->klass, f->klass_name,
2111 f->offset, f->field_name);
2112 }
2113 done_recording_subgraph(info->klass, klass_name);
2114 }
2115
2116 log_info(aot, heap)("Archived subgraph records = %d",
2117 _num_total_subgraph_recordings);
|