361 OopHandle* handle = get(ptr);
362 if (handle != nullptr) {
363 handle->release(Universe::vm_global());
364 remove(ptr);
365 }
366 }
367 };
368
369 void HeapShared::add_scratch_resolved_references(ConstantPool* src, objArrayOop dest) {
370 _scratch_references_table->set_oop(src, dest);
371 }
372
373 objArrayOop HeapShared::scratch_resolved_references(ConstantPool* src) {
374 return (objArrayOop)_scratch_references_table->get_oop(src);
375 }
376
377 void HeapShared::init_scratch_objects(TRAPS) {
378 for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
379 BasicType bt = (BasicType)i;
380 if (!is_reference_type(bt)) {
381 oop m = java_lang_Class::create_basic_type_mirror(type2name(bt), bt, CHECK);
382 _scratch_basic_type_mirrors[i] = OopHandle(Universe::vm_global(), m);
383 }
384 }
385 _scratch_java_mirror_table = new (mtClass)MetaspaceObjToOopHandleTable();
386 _scratch_references_table = new (mtClass)MetaspaceObjToOopHandleTable();
387 }
388
389 // Given java_mirror that represents a (primitive or reference) type T,
390 // return the "scratch" version that represents the same type T.
391 // Note that if java_mirror will be returned if it's already a
392 // scratch mirror.
393 //
394 // See java_lang_Class::create_scratch_mirror() for more info.
395 oop HeapShared::scratch_java_mirror(oop java_mirror) {
396 assert(java_lang_Class::is_instance(java_mirror), "must be");
397
398 for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
399 BasicType bt = (BasicType)i;
400 if (!is_reference_type(bt)) {
401 if (_scratch_basic_type_mirrors[i].resolve() == java_mirror) {
513 nfields ++;
514 }
515 }
516
517 java_lang_Class::set_class_data(m, java_lang_Class::class_data(orig_mirror));
518
519 // Class::reflectData use SoftReference, which cannot be archived. Set it
520 // to null and it will be recreated at runtime.
521 java_lang_Class::set_reflection_data(m, nullptr);
522
523 if (log_is_enabled(Info, cds, init)) {
524 ResourceMark rm;
525 log_debug(cds, init)("copied %3d field(s) in aot-initialized mirror %s%s", nfields, ik->external_name(),
526 ik->is_hidden() ? " (hidden)" : "");
527 }
528 }
529
530 static void copy_java_mirror_hashcode(oop orig_mirror, oop scratch_m) {
531 // We need to retain the identity_hash, because it may have been used by some hashtables
532 // in the shared heap.
533 if (!orig_mirror->fast_no_hash_check()) {
534 intptr_t src_hash = orig_mirror->identity_hash();
535 if (UseCompactObjectHeaders) {
536 narrowKlass nk = CompressedKlassPointers::encode(orig_mirror->klass());
537 scratch_m->set_mark(markWord::prototype().set_narrow_klass(nk).copy_set_hash(src_hash));
538 } else {
539 scratch_m->set_mark(markWord::prototype().copy_set_hash(src_hash));
540 }
541 assert(scratch_m->mark().is_unlocked(), "sanity");
542
543 DEBUG_ONLY(intptr_t archived_hash = scratch_m->identity_hash());
544 assert(src_hash == archived_hash, "Different hash codes: original " INTPTR_FORMAT ", archived " INTPTR_FORMAT, src_hash, archived_hash);
545 }
546 }
547
548 static objArrayOop get_archived_resolved_references(InstanceKlass* src_ik) {
549 InstanceKlass* buffered_ik = ArchiveBuilder::current()->get_buffered_addr(src_ik);
550 if (buffered_ik->is_shared_boot_class() ||
551 buffered_ik->is_shared_platform_class() ||
552 buffered_ik->is_shared_app_class()) {
553 objArrayOop rr = src_ik->constants()->resolved_references_or_null();
554 if (rr != nullptr && !ArchiveHeapWriter::is_too_large_to_archive(rr)) {
555 return HeapShared::scratch_resolved_references(src_ik->constants());
556 }
557 }
558 return nullptr;
559 }
560
561 void HeapShared::archive_java_mirrors() {
562 for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
563 BasicType bt = (BasicType)i;
564 if (!is_reference_type(bt)) {
|
361 OopHandle* handle = get(ptr);
362 if (handle != nullptr) {
363 handle->release(Universe::vm_global());
364 remove(ptr);
365 }
366 }
367 };
368
369 void HeapShared::add_scratch_resolved_references(ConstantPool* src, objArrayOop dest) {
370 _scratch_references_table->set_oop(src, dest);
371 }
372
373 objArrayOop HeapShared::scratch_resolved_references(ConstantPool* src) {
374 return (objArrayOop)_scratch_references_table->get_oop(src);
375 }
376
377 void HeapShared::init_scratch_objects(TRAPS) {
378 for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
379 BasicType bt = (BasicType)i;
380 if (!is_reference_type(bt)) {
381 oop m = java_lang_Class::create_basic_type_mirror(type2name(bt), bt, true, CHECK);
382 _scratch_basic_type_mirrors[i] = OopHandle(Universe::vm_global(), m);
383 }
384 }
385 _scratch_java_mirror_table = new (mtClass)MetaspaceObjToOopHandleTable();
386 _scratch_references_table = new (mtClass)MetaspaceObjToOopHandleTable();
387 }
388
389 // Given java_mirror that represents a (primitive or reference) type T,
390 // return the "scratch" version that represents the same type T.
391 // Note that if java_mirror will be returned if it's already a
392 // scratch mirror.
393 //
394 // See java_lang_Class::create_scratch_mirror() for more info.
395 oop HeapShared::scratch_java_mirror(oop java_mirror) {
396 assert(java_lang_Class::is_instance(java_mirror), "must be");
397
398 for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
399 BasicType bt = (BasicType)i;
400 if (!is_reference_type(bt)) {
401 if (_scratch_basic_type_mirrors[i].resolve() == java_mirror) {
513 nfields ++;
514 }
515 }
516
517 java_lang_Class::set_class_data(m, java_lang_Class::class_data(orig_mirror));
518
519 // Class::reflectData use SoftReference, which cannot be archived. Set it
520 // to null and it will be recreated at runtime.
521 java_lang_Class::set_reflection_data(m, nullptr);
522
523 if (log_is_enabled(Info, cds, init)) {
524 ResourceMark rm;
525 log_debug(cds, init)("copied %3d field(s) in aot-initialized mirror %s%s", nfields, ik->external_name(),
526 ik->is_hidden() ? " (hidden)" : "");
527 }
528 }
529
530 static void copy_java_mirror_hashcode(oop orig_mirror, oop scratch_m) {
531 // We need to retain the identity_hash, because it may have been used by some hashtables
532 // in the shared heap.
533 assert(!UseCompactObjectHeaders || scratch_m->mark().is_not_hashed_expanded(), "scratch mirror must have not-hashed-expanded state");
534 if (!orig_mirror->fast_no_hash_check()) {
535 intptr_t orig_mark = orig_mirror->mark().value();
536 intptr_t src_hash = orig_mirror->identity_hash();
537 if (UseCompactObjectHeaders) {
538 // We leave the cases not_hashed/not_hashed_expanded as they are.
539 assert(orig_mirror->mark().is_hashed_not_expanded() || orig_mirror->mark().is_hashed_expanded(), "must be hashed");
540 Klass* orig_klass = orig_mirror->klass();
541 narrowKlass nk = CompressedKlassPointers::encode(orig_klass);
542 markWord mark = markWord::prototype().set_narrow_klass(nk);
543 mark = mark.copy_hashctrl_from(orig_mirror->mark());
544 if (mark.is_hashed_not_expanded()) {
545 scratch_m->initialize_hash_if_necessary(orig_mirror, orig_klass, mark);
546 } else {
547 assert(mark.is_hashed_expanded(), "must be hashed & moved");
548 int offset = orig_klass->hash_offset_in_bytes(orig_mirror);
549 assert(offset >= 8, "hash offset must not be in header");
550 scratch_m->int_field_put(offset, (jint) src_hash);
551 scratch_m->set_mark(mark);
552 }
553 assert(scratch_m->mark().is_hashed_expanded(), "must be hashed & moved");
554 assert(scratch_m->mark().is_not_hashed_expanded() || scratch_m->mark().is_hashed_expanded(), "must be not hashed and expanded");
555 } else {
556 scratch_m->set_mark(markWord::prototype().copy_set_hash(src_hash));
557 DEBUG_ONLY(intptr_t archived_hash = scratch_m->identity_hash());
558 assert(src_hash == archived_hash, "Different hash codes: original " INTPTR_FORMAT ", archived " INTPTR_FORMAT, src_hash, archived_hash);
559 }
560 assert(scratch_m->mark().is_unlocked(), "sanity");
561 }
562 }
563
564 static objArrayOop get_archived_resolved_references(InstanceKlass* src_ik) {
565 InstanceKlass* buffered_ik = ArchiveBuilder::current()->get_buffered_addr(src_ik);
566 if (buffered_ik->is_shared_boot_class() ||
567 buffered_ik->is_shared_platform_class() ||
568 buffered_ik->is_shared_app_class()) {
569 objArrayOop rr = src_ik->constants()->resolved_references_or_null();
570 if (rr != nullptr && !ArchiveHeapWriter::is_too_large_to_archive(rr)) {
571 return HeapShared::scratch_resolved_references(src_ik->constants());
572 }
573 }
574 return nullptr;
575 }
576
577 void HeapShared::archive_java_mirrors() {
578 for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
579 BasicType bt = (BasicType)i;
580 if (!is_reference_type(bt)) {
|