< prev index next >

src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp

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

@@ -346,10 +348,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 +488,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))

@@ -673,10 +695,13 @@
      set_last_Java_frame(last_java_sp, last_java_fp, pc() /* Patched later */, scratch);
    }
  }
  
  static inline bool target_needs_far_branch(address addr) {
+   if (SCCache::is_on_for_write()) {
+     return true;
+   }
    // codecache size <= 128M
    if (!MacroAssembler::far_branches()) {
      return false;
    }
    // codecache size > 240M

@@ -3009,12 +3034,15 @@
    bind(done);
  }
  
  void MacroAssembler::stop(const char* msg) {
    BLOCK_COMMENT(msg);
+   // load msg into r0 so we can access it from the signal handler
+   // ExternalAddress enables saving and restoring via the code cache
+   lea(c_rarg0, ExternalAddress((address) msg));
    dcps1(0xdeae);
-   emit_int64((uintptr_t)msg);
+   SCCache::add_C_string(msg);
  }
  
  void MacroAssembler::unimplemented(const char* what) {
    const char* buf = nullptr;
    {

@@ -3108,11 +3136,11 @@
  }
  
  void MacroAssembler::reinit_heapbase()
  {
    if (UseCompressedOops) {
-     if (Universe::is_fully_initialized()) {
+     if (Universe::is_fully_initialized() && !SCCache::is_on_for_write()) {
        mov(rheapbase, CompressedOops::ptrs_base());
      } else {
        lea(rheapbase, ExternalAddress(CompressedOops::ptrs_base_addr()));
        ldr(rheapbase, Address(rheapbase));
      }

@@ -5411,11 +5439,16 @@
    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 (SCCache::is_on_for_write()) {
+     // SCA needs relocation info for card table base
+     lea(reg, ExternalAddress(reinterpret_cast<address>(byte_map_base)));
+   } else {
+     mov(reg, (uint64_t)byte_map_base);
+   }
  }
  
  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 >