< prev index next >

src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp

Print this page
@@ -24,10 +24,11 @@
   */
  
  #include "asm/assembler.hpp"
  #include "asm/assembler.inline.hpp"
  #include "ci/ciEnv.hpp"
+ #include "ci/ciUtilities.hpp"
  #include "code/compiledIC.hpp"
  #include "compiler/compileTask.hpp"
  #include "compiler/disassembler.hpp"
  #include "compiler/oopMap.hpp"
  #include "gc/shared/barrierSet.hpp"

@@ -346,10 +347,20 @@
      dest = (dest & 0xffffffffULL) | (uintptr_t(insn_addr) & 0xffff00000000ULL);
      target = address(dest);
      return 2;
    }
    virtual int immediate(address insn_addr, address &target) {
+     // Metadata pointers are either narrow (32 bits) or wide (48 bits).
+     // We encode narrow ones by setting the upper 16 bits in the first
+     // instruction.
+     if (Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010101) {
+       assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
+       narrowKlass nk = CompressedKlassPointers::encode((Klass*)target);
+       Instruction_aarch64::patch(insn_addr, 20, 5, nk >> 16);
+       Instruction_aarch64::patch(insn_addr+4, 20, 5, nk & 0xffff);
+       return 2;
+     }
      assert(Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010100, "must be");
      uint64_t dest = (uint64_t)target;
      // Move wide constant
      assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
      assert(nativeInstruction_at(insn_addr+8)->is_movk(), "wrong insns in patch");

@@ -476,10 +487,20 @@
        return 2;
      }
    }
    virtual int immediate(address insn_addr, address &target) {
      uint32_t *insns = (uint32_t *)insn_addr;
+     // Metadata pointers are either narrow (32 bits) or wide (48 bits).
+     // We encode narrow ones by setting the upper 16 bits in the first
+     // instruction.
+     if (Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010101) {
+       assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
+       narrowKlass nk = (narrowKlass)((uint32_t(Instruction_aarch64::extract(_insn, 20, 5)) << 16)
+                                    +  uint32_t(Instruction_aarch64::extract(insns[1], 20, 5)));
+       target = (address)CompressedKlassPointers::decode(nk);
+       return 2;
+     }
      assert(Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010100, "must be");
      // Move wide constant: movz, movk, movk.  See movptr().
      assert(nativeInstruction_at(insns+1)->is_movk(), "wrong insns in patch");
      assert(nativeInstruction_at(insns+2)->is_movk(), "wrong insns in patch");
      target = address(uint64_t(Instruction_aarch64::extract(_insn, 20, 5))

@@ -3339,11 +3360,11 @@
  }
  
  void MacroAssembler::reinit_heapbase()
  {
    if (UseCompressedOops) {
-     if (Universe::is_fully_initialized()) {
+     if (Universe::is_fully_initialized() && !AOTCodeCache::is_on_for_dump()) {
        mov(rheapbase, CompressedOops::base());
      } else {
        lea(rheapbase, ExternalAddress(CompressedOops::base_addr()));
        ldr(rheapbase, Address(rheapbase));
      }

@@ -5109,11 +5130,12 @@
        ldrw(tmp, Address(obj, oopDesc::klass_offset_in_bytes()));
      }
      if (CompressedKlassPointers::base() == nullptr) {
        cmp(klass, tmp, LSL, CompressedKlassPointers::shift());
        return;
-     } else if (((uint64_t)CompressedKlassPointers::base() & 0xffffffff) == 0
+     } else if (!AOTCodeCache::is_on_for_dump() &&
+                ((uint64_t)CompressedKlassPointers::base() & 0xffffffff) == 0
                 && CompressedKlassPointers::shift() == 0) {
        // Only the bottom 32 bits matter
        cmpw(klass, tmp);
        return;
      }

@@ -5368,11 +5390,11 @@
      pop(regs, sp);
    }
  }
  
  void MacroAssembler::encode_klass_not_null(Register dst, Register src) {
-   if (AOTCodeCache::is_on_for_dump()) {
+   if (CompressedKlassPointers::base() != nullptr && AOTCodeCache::is_on_for_dump()) {
      encode_klass_not_null_for_aot(dst, src);
      return;
    }
  
    switch (klass_decode_mode()) {

@@ -5434,11 +5456,11 @@
  }
  
  void  MacroAssembler::decode_klass_not_null(Register dst, Register src) {
    assert (UseCompressedClassPointers, "should only be used for compressed headers");
  
-   if (AOTCodeCache::is_on_for_dump()) {
+   if (CompressedKlassPointers::base() != nullptr && AOTCodeCache::is_on_for_dump()) {
      decode_klass_not_null_for_aot(dst, src);
      return;
    }
  
    switch (klass_decode_mode()) {

@@ -5768,11 +5790,34 @@
    CardTable::CardValue* byte_map_base =
      ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base();
  
    // Strictly speaking the byte_map_base isn't an address at all, and it might
    // even be negative. It is thus materialised as a constant.
-   mov(reg, (uint64_t)byte_map_base);
+ #if INCLUDE_CDS
+   if (AOTCodeCache::is_on_for_dump()) {
+     // AOT code needs relocation info for card table base
+     lea(reg, ExternalAddress(reinterpret_cast<address>(byte_map_base)));
+   } else {
+ #endif
+     mov(reg, (uint64_t)byte_map_base);
+ #if INCLUDE_CDS
+   }
+ #endif
+ }
+ 
+ void MacroAssembler::load_aotrc_address(Register reg, address a) {
+ #if INCLUDE_CDS
+   assert(AOTRuntimeConstants::contains(a), "address out of range for data area");
+   if (AOTCodeCache::is_on_for_dump()) {
+     // all aotrc field addresses should be registered in the AOTCodeCache address table
+     lea(reg, ExternalAddress(a));
+   } else {
+     mov(reg, (uint64_t)a);
+   }
+ #else
+   ShouldNotReachHere();
+ #endif
  }
  
  void MacroAssembler::build_frame(int framesize) {
    assert(framesize >= 2 * wordSize, "framesize must include space for FP/LR");
    assert(framesize % (2*wordSize) == 0, "must preserve 2*wordSize alignment");
< prev index next >