Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8326430

Avoid patching native pointers in archived heap

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Unresolved
    • Icon: P4 P4
    • tbd
    • None
    • hotspot

      https://github.com/openjdk/jdk/blob/64f7972a3d0c82ad7047f73f0b57c3d88f62935f/src/hotspot/share/cds/heapShared.cpp#L433-L438

      void HeapShared::mark_native_pointers(oop orig_obj) {
        if (java_lang_Class::is_instance(orig_obj)) {
          ArchiveHeapWriter::mark_native_pointer(orig_obj, java_lang_Class::klass_offset());
          ArchiveHeapWriter::mark_native_pointer(orig_obj, java_lang_Class::array_klass_offset());
        }
      }

      We can avoid marking these pointers (and relocating them at runtime) by storing the Class::{klass, array_klass} as an offset instead of a direct pointer.

      I.e.,

      Klass* java_lang_Class::array_klass_acquire(oop java_class) {
      - Klass* k = ((Klass*)java_class->metadata_field_acquire(_array_klass_offset));
      + intx delta = (intx)(java_class->long_field_acquire(_array_klass_offset)));
      + Klass* k = (Klass*)((intx)SharedBaseAddress + delta);

        assert(k == nullptr || (k->is_klass() && k->is_array_klass()), "should be array klass");
        return k;
      }

      void java_lang_Class::release_set_array_klass(oop java_class, Klass* klass) {
        assert(klass->is_klass() && klass->is_array_klass(), "should be array klass");
      - java_class->release_metadata_field_put(_array_klass_offset, klass);
      + intx delta = ((intx)klass) - ((intx)SharedBaseAddress);
      + java_class->release_long_field_put(_array_klass_offset, (jlong)klass);
      }

      ======= Update 2024/10/11

      We have lots of assembly code that loads off java_lang_Class::klass_offset(), so all of those places would need to updated. This *might* cause performance degradation. So this proposal is more complicated that I thought, and there might be a trade off between start-up (will be faster( vs steady state (might be slower)

      ./cpu/aarch64/methodHandles_aarch64.cpp: __ ldr(klass_reg, Address(klass_reg, java_lang_Class::klass_offset()));
      ./cpu/arm/c1_CodeStubs_arm.cpp: __ ldr(Rtemp, Address(_obj, java_lang_Class::klass_offset()));
      ./cpu/arm/methodHandles_arm.cpp: __ ldr(klass_reg, Address(klass_reg, java_lang_Class::klass_offset()));
      ./cpu/ppc/c1_CodeStubs_ppc.cpp: __ ld(_obj, java_lang_Class::klass_offset(), _obj);
      ./cpu/ppc/methodHandles_ppc.cpp: __ ld(klass_reg, java_lang_Class::klass_offset(), klass_reg);
      ./cpu/riscv/methodHandles_riscv.cpp: __ ld(klass_reg, Address(klass_reg, java_lang_Class::klass_offset()));
      ./cpu/s390/c1_CodeStubs_s390.cpp: __ z_lg(Z_R1_scratch, java_lang_Class::klass_offset(), _obj);
      ./cpu/s390/methodHandles_s390.cpp: __ z_lg(klass_reg, Address(klass_reg, java_lang_Class::klass_offset()));
      ./cpu/x86/c1_CodeStubs_x86.cpp: __ movptr(tmp2, Address(_obj, java_lang_Class::klass_offset()));
      ./cpu/x86/methodHandles_x86.cpp: __ movptr(klass_reg, Address(klass_reg, java_lang_Class::klass_offset()));
      ./share/c1/c1_LIRGenerator.cpp: __ move(new LIR_Address(rcvr.result(), java_lang_Class::klass_offset(), T_ADDRESS), temp, info);
      ./share/c1/c1_LIRGenerator.cpp: __ move(new LIR_Address(receiver.result(), java_lang_Class::klass_offset(), T_ADDRESS), recv_klass, info);
      ./share/cds/heapShared.cpp: ArchiveHeapWriter::mark_native_pointer(orig_obj, java_lang_Class::klass_offset());
      ./share/gc/shenandoah/shenandoahAsserts.cpp: Metadata* klass = obj->metadata_field(java_lang_Class::klass_offset());
      ./share/gc/shenandoah/shenandoahVerifier.cpp: Metadata* klass = obj->metadata_field(java_lang_Class::klass_offset());
      ./share/jvmci/jvmciCompilerToVM.cpp: if (offset == java_lang_Class::klass_offset()) {
      ./share/opto/compile.cpp: if (flat->offset() == java_lang_Class::klass_offset()
      ./share/opto/library_call.cpp: basic_plus_adr(cls, java_lang_Class::klass_offset()),
      ./share/opto/library_call.cpp: int class_klass_offset = java_lang_Class::klass_offset();
      ./share/opto/library_call.hpp: int offset = java_lang_Class::klass_offset();
      ./share/opto/memnode.cpp: && (offset == java_lang_Class::klass_offset() ||
      ./share/opto/memnode.cpp: && offset == java_lang_Class::klass_offset()) {
      ./share/opto/type.cpp: (_offset == java_lang_Class::klass_offset() ||


            matsaave Matias Saavedra Silva
            iklam Ioi Lam
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: