< 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));
      }

@@ -5707,11 +5728,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 >