784 assert(success, "sanity");
785 }
786
787 if (log_is_enabled(Debug, aot, init)) {
788 ResourceMark rm;
789 log_debug(aot, init)("copied %3d field(s) in aot-initialized mirror %s%s%s", nfields, ik->external_name(),
790 ik->is_hidden() ? " (hidden)" : "",
791 ik->is_enum_subclass() ? " (enum)" : "");
792 }
793 }
794
795 void HeapShared::copy_java_mirror(oop orig_mirror, oop scratch_m) {
796 // We need to retain the identity_hash, because it may have been used by some hashtables
797 // in the shared heap.
798 if (!orig_mirror->fast_no_hash_check()) {
799 intptr_t src_hash = orig_mirror->identity_hash();
800 if (UseCompactObjectHeaders) {
801 narrowKlass nk = CompressedKlassPointers::encode(orig_mirror->klass());
802 scratch_m->set_mark(markWord::prototype().set_narrow_klass(nk).copy_set_hash(src_hash));
803 } else {
804 scratch_m->set_mark(markWord::prototype().copy_set_hash(src_hash));
805 }
806 assert(scratch_m->mark().is_unlocked(), "sanity");
807
808 DEBUG_ONLY(intptr_t archived_hash = scratch_m->identity_hash());
809 assert(src_hash == archived_hash, "Different hash codes: original " INTPTR_FORMAT ", archived " INTPTR_FORMAT, src_hash, archived_hash);
810 }
811
812 if (CDSConfig::is_dumping_aot_linked_classes()) {
813 java_lang_Class::set_module(scratch_m, java_lang_Class::module(orig_mirror));
814 java_lang_Class::set_protection_domain(scratch_m, java_lang_Class::protection_domain(orig_mirror));
815 }
816 }
817
818 static objArrayOop get_archived_resolved_references(InstanceKlass* src_ik) {
819 if (SystemDictionaryShared::is_builtin_loader(src_ik->class_loader_data())) {
820 objArrayOop rr = src_ik->constants()->resolved_references_or_null();
821 if (rr != nullptr && !HeapShared::is_too_large_to_archive(rr)) {
822 return HeapShared::scratch_resolved_references(src_ik->constants());
823 }
1485 return record;
1486 }
1487
1488 void HeapShared::resolve_or_init(const char* klass_name, bool do_init, TRAPS) {
1489 TempNewSymbol klass_name_sym = SymbolTable::new_symbol(klass_name);
1490 InstanceKlass* k = SystemDictionaryShared::find_builtin_class(klass_name_sym);
1491 if (k == nullptr) {
1492 return;
1493 }
1494 assert(k->defined_by_boot_loader(), "sanity");
1495 resolve_or_init(k, false, CHECK);
1496 if (do_init) {
1497 resolve_or_init(k, true, CHECK);
1498 }
1499 }
1500
1501 void HeapShared::resolve_or_init(Klass* k, bool do_init, TRAPS) {
1502 if (!do_init) {
1503 if (k->class_loader_data() == nullptr) {
1504 Klass* resolved_k = SystemDictionary::resolve_or_null(k->name(), CHECK);
1505 assert(resolved_k == k, "classes used by archived heap must not be replaced by JVMTI ClassFileLoadHook");
1506 }
1507 } else {
1508 assert(k->class_loader_data() != nullptr, "must have been resolved by HeapShared::resolve_classes");
1509 if (k->is_instance_klass()) {
1510 InstanceKlass* ik = InstanceKlass::cast(k);
1511 ik->initialize(CHECK);
1512 } else if (k->is_objArray_klass()) {
1513 ObjArrayKlass* oak = ObjArrayKlass::cast(k);
1514 oak->initialize(CHECK);
1515 }
1516 }
1517 }
1518
1519 void HeapShared::init_archived_fields_for(Klass* k, const ArchivedKlassSubGraphInfoRecord* record) {
1520 verify_the_heap(k, "before");
1521
1522 Array<int>* entry_field_records = record->entry_field_records();
1523 if (entry_field_records != nullptr) {
1524 int efr_len = entry_field_records->length();
1525 assert(efr_len % 2 == 0, "sanity");
2237 }
2238 }
2239
2240 void HeapShared::archive_object_subgraphs(ArchivableStaticFieldInfo fields[],
2241 bool is_full_module_graph) {
2242 _num_total_subgraph_recordings = 0;
2243 _num_total_walked_objs = 0;
2244 _num_total_archived_objs = 0;
2245 _num_total_recorded_klasses = 0;
2246 _num_total_verifications = 0;
2247
2248 // For each class X that has one or more archived fields:
2249 // [1] Dump the subgraph of each archived field
2250 // [2] Create a list of all the class of the objects that can be reached
2251 // by any of these static fields.
2252 // At runtime, these classes are initialized before X's archived fields
2253 // are restored by HeapShared::initialize_from_archived_subgraph().
2254 for (int i = 0; fields[i].valid(); ) {
2255 ArchivableStaticFieldInfo* info = &fields[i];
2256 const char* klass_name = info->klass_name;
2257 start_recording_subgraph(info->klass, klass_name, is_full_module_graph);
2258
2259 // If you have specified consecutive fields of the same klass in
2260 // fields[], these will be archived in the same
2261 // {start_recording_subgraph ... done_recording_subgraph} pass to
2262 // save time.
2263 for (; fields[i].valid(); i++) {
2264 ArchivableStaticFieldInfo* f = &fields[i];
2265 if (f->klass_name != klass_name) {
2266 break;
2267 }
2268
2269 archive_reachable_objects_from_static_field(f->klass, f->klass_name,
2270 f->offset, f->field_name);
2271 }
2272 done_recording_subgraph(info->klass, klass_name);
2273 }
2274
2275 log_info(aot, heap)("Archived subgraph records = %zu",
2276 _num_total_subgraph_recordings);
|
784 assert(success, "sanity");
785 }
786
787 if (log_is_enabled(Debug, aot, init)) {
788 ResourceMark rm;
789 log_debug(aot, init)("copied %3d field(s) in aot-initialized mirror %s%s%s", nfields, ik->external_name(),
790 ik->is_hidden() ? " (hidden)" : "",
791 ik->is_enum_subclass() ? " (enum)" : "");
792 }
793 }
794
795 void HeapShared::copy_java_mirror(oop orig_mirror, oop scratch_m) {
796 // We need to retain the identity_hash, because it may have been used by some hashtables
797 // in the shared heap.
798 if (!orig_mirror->fast_no_hash_check()) {
799 intptr_t src_hash = orig_mirror->identity_hash();
800 if (UseCompactObjectHeaders) {
801 narrowKlass nk = CompressedKlassPointers::encode(orig_mirror->klass());
802 scratch_m->set_mark(markWord::prototype().set_narrow_klass(nk).copy_set_hash(src_hash));
803 } else {
804 // For valhalla, the prototype header is the same as markWord::prototype();
805 scratch_m->set_mark(markWord::prototype().copy_set_hash(src_hash));
806 }
807 assert(scratch_m->mark().is_unlocked(), "sanity");
808
809 DEBUG_ONLY(intptr_t archived_hash = scratch_m->identity_hash());
810 assert(src_hash == archived_hash, "Different hash codes: original " INTPTR_FORMAT ", archived " INTPTR_FORMAT, src_hash, archived_hash);
811 }
812
813 if (CDSConfig::is_dumping_aot_linked_classes()) {
814 java_lang_Class::set_module(scratch_m, java_lang_Class::module(orig_mirror));
815 java_lang_Class::set_protection_domain(scratch_m, java_lang_Class::protection_domain(orig_mirror));
816 }
817 }
818
819 static objArrayOop get_archived_resolved_references(InstanceKlass* src_ik) {
820 if (SystemDictionaryShared::is_builtin_loader(src_ik->class_loader_data())) {
821 objArrayOop rr = src_ik->constants()->resolved_references_or_null();
822 if (rr != nullptr && !HeapShared::is_too_large_to_archive(rr)) {
823 return HeapShared::scratch_resolved_references(src_ik->constants());
824 }
1486 return record;
1487 }
1488
1489 void HeapShared::resolve_or_init(const char* klass_name, bool do_init, TRAPS) {
1490 TempNewSymbol klass_name_sym = SymbolTable::new_symbol(klass_name);
1491 InstanceKlass* k = SystemDictionaryShared::find_builtin_class(klass_name_sym);
1492 if (k == nullptr) {
1493 return;
1494 }
1495 assert(k->defined_by_boot_loader(), "sanity");
1496 resolve_or_init(k, false, CHECK);
1497 if (do_init) {
1498 resolve_or_init(k, true, CHECK);
1499 }
1500 }
1501
1502 void HeapShared::resolve_or_init(Klass* k, bool do_init, TRAPS) {
1503 if (!do_init) {
1504 if (k->class_loader_data() == nullptr) {
1505 Klass* resolved_k = SystemDictionary::resolve_or_null(k->name(), CHECK);
1506 if (resolved_k->is_array_klass()) {
1507 assert(resolved_k == k || resolved_k == k->super(), "classes used by archived heap must not be replaced by JVMTI ClassFileLoadHook");
1508 } else {
1509 assert(resolved_k == k, "classes used by archived heap must not be replaced by JVMTI ClassFileLoadHook");
1510 }
1511 }
1512 } else {
1513 assert(k->class_loader_data() != nullptr, "must have been resolved by HeapShared::resolve_classes");
1514 if (k->is_instance_klass()) {
1515 InstanceKlass* ik = InstanceKlass::cast(k);
1516 ik->initialize(CHECK);
1517 } else if (k->is_objArray_klass()) {
1518 ObjArrayKlass* oak = ObjArrayKlass::cast(k);
1519 oak->initialize(CHECK);
1520 }
1521 }
1522 }
1523
1524 void HeapShared::init_archived_fields_for(Klass* k, const ArchivedKlassSubGraphInfoRecord* record) {
1525 verify_the_heap(k, "before");
1526
1527 Array<int>* entry_field_records = record->entry_field_records();
1528 if (entry_field_records != nullptr) {
1529 int efr_len = entry_field_records->length();
1530 assert(efr_len % 2 == 0, "sanity");
2242 }
2243 }
2244
2245 void HeapShared::archive_object_subgraphs(ArchivableStaticFieldInfo fields[],
2246 bool is_full_module_graph) {
2247 _num_total_subgraph_recordings = 0;
2248 _num_total_walked_objs = 0;
2249 _num_total_archived_objs = 0;
2250 _num_total_recorded_klasses = 0;
2251 _num_total_verifications = 0;
2252
2253 // For each class X that has one or more archived fields:
2254 // [1] Dump the subgraph of each archived field
2255 // [2] Create a list of all the class of the objects that can be reached
2256 // by any of these static fields.
2257 // At runtime, these classes are initialized before X's archived fields
2258 // are restored by HeapShared::initialize_from_archived_subgraph().
2259 for (int i = 0; fields[i].valid(); ) {
2260 ArchivableStaticFieldInfo* info = &fields[i];
2261 const char* klass_name = info->klass_name;
2262
2263 if (CDSConfig::is_valhalla_preview() && strcmp(klass_name, "jdk/internal/module/ArchivedModuleGraph") == 0) {
2264 // FIXME -- ArchivedModuleGraph doesn't work when java.base is patched with valhalla classes.
2265 i++;
2266 continue;
2267 }
2268
2269 start_recording_subgraph(info->klass, klass_name, is_full_module_graph);
2270
2271 // If you have specified consecutive fields of the same klass in
2272 // fields[], these will be archived in the same
2273 // {start_recording_subgraph ... done_recording_subgraph} pass to
2274 // save time.
2275 for (; fields[i].valid(); i++) {
2276 ArchivableStaticFieldInfo* f = &fields[i];
2277 if (f->klass_name != klass_name) {
2278 break;
2279 }
2280
2281 archive_reachable_objects_from_static_field(f->klass, f->klass_name,
2282 f->offset, f->field_name);
2283 }
2284 done_recording_subgraph(info->klass, klass_name);
2285 }
2286
2287 log_info(aot, heap)("Archived subgraph records = %zu",
2288 _num_total_subgraph_recordings);
|