387 handle->release(Universe::vm_global());
388 remove(ptr);
389 }
390 }
391 };
392
393 void HeapShared::add_scratch_resolved_references(ConstantPool* src, objArrayOop dest) {
394 if (SystemDictionaryShared::is_builtin_loader(src->pool_holder()->class_loader_data())) {
395 _scratch_references_table->set_oop(src, dest);
396 }
397 }
398
399 objArrayOop HeapShared::scratch_resolved_references(ConstantPool* src) {
400 return (objArrayOop)_scratch_references_table->get_oop(src);
401 }
402
403 void HeapShared::init_scratch_objects(TRAPS) {
404 for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
405 BasicType bt = (BasicType)i;
406 if (!is_reference_type(bt)) {
407 oop m = java_lang_Class::create_basic_type_mirror(type2name(bt), bt, CHECK);
408 _scratch_basic_type_mirrors[i] = OopHandle(Universe::vm_global(), m);
409 }
410 }
411 _scratch_java_mirror_table = new (mtClass)MetaspaceObjToOopHandleTable();
412 _scratch_references_table = new (mtClass)MetaspaceObjToOopHandleTable();
413 }
414
415 // Given java_mirror that represents a (primitive or reference) type T,
416 // return the "scratch" version that represents the same type T.
417 // Note that if java_mirror will be returned if it's already a
418 // scratch mirror.
419 //
420 // See java_lang_Class::create_scratch_mirror() for more info.
421 oop HeapShared::scratch_java_mirror(oop java_mirror) {
422 assert(java_lang_Class::is_instance(java_mirror), "must be");
423
424 for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
425 BasicType bt = (BasicType)i;
426 if (!is_reference_type(bt)) {
427 if (_scratch_basic_type_mirrors[i].resolve() == java_mirror) {
557 }
558
559 oop class_data = java_lang_Class::class_data(orig_mirror);
560 java_lang_Class::set_class_data(m, class_data);
561 if (class_data != nullptr) {
562 bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, class_data);
563 assert(success, "sanity");
564 }
565
566 if (log_is_enabled(Info, cds, init)) {
567 ResourceMark rm;
568 log_debug(cds, init)("copied %3d field(s) in aot-initialized mirror %s%s%s", nfields, ik->external_name(),
569 ik->is_hidden() ? " (hidden)" : "",
570 ik->is_enum_subclass() ? " (enum)" : "");
571 }
572 }
573
574 static void copy_java_mirror_hashcode(oop orig_mirror, oop scratch_m) {
575 // We need to retain the identity_hash, because it may have been used by some hashtables
576 // in the shared heap.
577 if (!orig_mirror->fast_no_hash_check()) {
578 intptr_t src_hash = orig_mirror->identity_hash();
579 if (UseCompactObjectHeaders) {
580 narrowKlass nk = CompressedKlassPointers::encode(orig_mirror->klass());
581 scratch_m->set_mark(markWord::prototype().set_narrow_klass(nk).copy_set_hash(src_hash));
582 } else {
583 scratch_m->set_mark(markWord::prototype().copy_set_hash(src_hash));
584 }
585 assert(scratch_m->mark().is_unlocked(), "sanity");
586
587 DEBUG_ONLY(intptr_t archived_hash = scratch_m->identity_hash());
588 assert(src_hash == archived_hash, "Different hash codes: original " INTPTR_FORMAT ", archived " INTPTR_FORMAT, src_hash, archived_hash);
589 }
590 }
591
592 static objArrayOop get_archived_resolved_references(InstanceKlass* src_ik) {
593 if (SystemDictionaryShared::is_builtin_loader(src_ik->class_loader_data())) {
594 objArrayOop rr = src_ik->constants()->resolved_references_or_null();
595 if (rr != nullptr && !ArchiveHeapWriter::is_too_large_to_archive(rr)) {
596 return HeapShared::scratch_resolved_references(src_ik->constants());
597 }
598 }
599 return nullptr;
600 }
601
602 void HeapShared::archive_strings() {
603 oop shared_strings_array = StringTable::init_shared_strings_array(_dumped_interned_strings);
604 bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, shared_strings_array);
605 // We must succeed because:
606 // - _dumped_interned_strings do not contain any large strings.
607 // - StringTable::init_shared_table() doesn't create any large arrays.
608 assert(success, "shared strings array must not point to arrays or strings that are too large to archive");
|
387 handle->release(Universe::vm_global());
388 remove(ptr);
389 }
390 }
391 };
392
393 void HeapShared::add_scratch_resolved_references(ConstantPool* src, objArrayOop dest) {
394 if (SystemDictionaryShared::is_builtin_loader(src->pool_holder()->class_loader_data())) {
395 _scratch_references_table->set_oop(src, dest);
396 }
397 }
398
399 objArrayOop HeapShared::scratch_resolved_references(ConstantPool* src) {
400 return (objArrayOop)_scratch_references_table->get_oop(src);
401 }
402
403 void HeapShared::init_scratch_objects(TRAPS) {
404 for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
405 BasicType bt = (BasicType)i;
406 if (!is_reference_type(bt)) {
407 oop m = java_lang_Class::create_basic_type_mirror(type2name(bt), bt, true, CHECK);
408 _scratch_basic_type_mirrors[i] = OopHandle(Universe::vm_global(), m);
409 }
410 }
411 _scratch_java_mirror_table = new (mtClass)MetaspaceObjToOopHandleTable();
412 _scratch_references_table = new (mtClass)MetaspaceObjToOopHandleTable();
413 }
414
415 // Given java_mirror that represents a (primitive or reference) type T,
416 // return the "scratch" version that represents the same type T.
417 // Note that if java_mirror will be returned if it's already a
418 // scratch mirror.
419 //
420 // See java_lang_Class::create_scratch_mirror() for more info.
421 oop HeapShared::scratch_java_mirror(oop java_mirror) {
422 assert(java_lang_Class::is_instance(java_mirror), "must be");
423
424 for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
425 BasicType bt = (BasicType)i;
426 if (!is_reference_type(bt)) {
427 if (_scratch_basic_type_mirrors[i].resolve() == java_mirror) {
557 }
558
559 oop class_data = java_lang_Class::class_data(orig_mirror);
560 java_lang_Class::set_class_data(m, class_data);
561 if (class_data != nullptr) {
562 bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, class_data);
563 assert(success, "sanity");
564 }
565
566 if (log_is_enabled(Info, cds, init)) {
567 ResourceMark rm;
568 log_debug(cds, init)("copied %3d field(s) in aot-initialized mirror %s%s%s", nfields, ik->external_name(),
569 ik->is_hidden() ? " (hidden)" : "",
570 ik->is_enum_subclass() ? " (enum)" : "");
571 }
572 }
573
574 static void copy_java_mirror_hashcode(oop orig_mirror, oop scratch_m) {
575 // We need to retain the identity_hash, because it may have been used by some hashtables
576 // in the shared heap.
577 assert(!UseCompactObjectHeaders || scratch_m->mark().is_not_hashed_expanded(), "scratch mirror must have not-hashed-expanded state");
578 if (!orig_mirror->fast_no_hash_check()) {
579 intptr_t orig_mark = orig_mirror->mark().value();
580 intptr_t src_hash = orig_mirror->identity_hash();
581 if (UseCompactObjectHeaders) {
582 // We leave the cases not_hashed/not_hashed_expanded as they are.
583 assert(orig_mirror->mark().is_hashed_not_expanded() || orig_mirror->mark().is_hashed_expanded(), "must be hashed");
584 Klass* orig_klass = orig_mirror->klass();
585 narrowKlass nk = CompressedKlassPointers::encode(orig_klass);
586 markWord mark = markWord::prototype().set_narrow_klass(nk);
587 mark = mark.copy_hashctrl_from(orig_mirror->mark());
588 if (mark.is_hashed_not_expanded()) {
589 scratch_m->initialize_hash_if_necessary(orig_mirror, orig_klass, mark);
590 } else {
591 assert(mark.is_hashed_expanded(), "must be hashed & moved");
592 int offset = orig_klass->hash_offset_in_bytes(orig_mirror);
593 assert(offset >= 8, "hash offset must not be in header");
594 scratch_m->int_field_put(offset, (jint) src_hash);
595 scratch_m->set_mark(mark);
596 }
597 assert(scratch_m->mark().is_hashed_expanded(), "must be hashed & moved");
598 assert(scratch_m->mark().is_not_hashed_expanded() || scratch_m->mark().is_hashed_expanded(), "must be not hashed and expanded");
599 } else {
600 scratch_m->set_mark(markWord::prototype().copy_set_hash(src_hash));
601 DEBUG_ONLY(intptr_t archived_hash = scratch_m->identity_hash());
602 assert(src_hash == archived_hash, "Different hash codes: original " INTPTR_FORMAT ", archived " INTPTR_FORMAT, src_hash, archived_hash);
603 }
604 assert(scratch_m->mark().is_unlocked(), "sanity");
605 }
606 }
607
608 static objArrayOop get_archived_resolved_references(InstanceKlass* src_ik) {
609 if (SystemDictionaryShared::is_builtin_loader(src_ik->class_loader_data())) {
610 objArrayOop rr = src_ik->constants()->resolved_references_or_null();
611 if (rr != nullptr && !ArchiveHeapWriter::is_too_large_to_archive(rr)) {
612 return HeapShared::scratch_resolved_references(src_ik->constants());
613 }
614 }
615 return nullptr;
616 }
617
618 void HeapShared::archive_strings() {
619 oop shared_strings_array = StringTable::init_shared_strings_array(_dumped_interned_strings);
620 bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, shared_strings_array);
621 // We must succeed because:
622 // - _dumped_interned_strings do not contain any large strings.
623 // - StringTable::init_shared_table() doesn't create any large arrays.
624 assert(success, "shared strings array must not point to arrays or strings that are too large to archive");
|