< prev index next >

src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp

Print this page




  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #include <sys/types.h>
  27 
  28 #include "precompiled.hpp"
  29 #include "jvm.h"
  30 #include "asm/assembler.hpp"
  31 #include "asm/assembler.inline.hpp"
  32 #include "gc/shared/cardTable.hpp"
  33 #include "gc/shared/cardTableModRefBS.hpp"
  34 #include "interpreter/interpreter.hpp"
  35 #include "compiler/disassembler.hpp"
  36 #include "memory/resourceArea.hpp"
  37 #include "nativeInst_aarch64.hpp"

  38 #include "oops/klass.inline.hpp"
  39 #include "oops/oop.inline.hpp"
  40 #include "opto/compile.hpp"
  41 #include "opto/intrinsicnode.hpp"
  42 #include "opto/node.hpp"
  43 #include "runtime/biasedLocking.hpp"
  44 #include "runtime/icache.hpp"
  45 #include "runtime/interfaceSupport.inline.hpp"
  46 #include "runtime/jniHandles.inline.hpp"
  47 #include "runtime/sharedRuntime.hpp"
  48 #include "runtime/thread.hpp"
  49 
  50 #if INCLUDE_ALL_GCS
  51 #include "gc/g1/g1BarrierSet.hpp"
  52 #include "gc/g1/g1CardTable.hpp"
  53 #include "gc/g1/g1CollectedHeap.inline.hpp"
  54 #include "gc/g1/heapRegion.hpp"
  55 #endif
  56 
  57 #ifdef PRODUCT
  58 #define BLOCK_COMMENT(str) /* nothing */
  59 #define STOP(error) stop(error)
  60 #else
  61 #define BLOCK_COMMENT(str) block_comment(str)
  62 #define STOP(error) block_comment(error); stop(error)
  63 #endif
  64 
  65 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
  66 
  67 // Patch any kind of instruction; there may be several instructions.
  68 // Return the total length (in bytes) of the instructions.
  69 int MacroAssembler::pd_patch_instruction_size(address branch, address target) {


 156   } else if (Instruction_aarch64::extract(insn, 31, 22) == 0b1011100101 &&
 157              Instruction_aarch64::extract(insn, 4, 0) == 0b11111) {
 158     // nothing to do
 159     assert(target == 0, "did not expect to relocate target for polling page load");
 160   } else {
 161     ShouldNotReachHere();
 162   }
 163   return instructions * NativeInstruction::instruction_size;
 164 }
 165 
 166 int MacroAssembler::patch_oop(address insn_addr, address o) {
 167   int instructions;
 168   unsigned insn = *(unsigned*)insn_addr;
 169   assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
 170 
 171   // OOPs are either narrow (32 bits) or wide (48 bits).  We encode
 172   // narrow OOPs by setting the upper 16 bits in the first
 173   // instruction.
 174   if (Instruction_aarch64::extract(insn, 31, 21) == 0b11010010101) {
 175     // Move narrow OOP
 176     narrowOop n = oopDesc::encode_heap_oop((oop)o);
 177     Instruction_aarch64::patch(insn_addr, 20, 5, n >> 16);
 178     Instruction_aarch64::patch(insn_addr+4, 20, 5, n & 0xffff);
 179     instructions = 2;
 180   } else {
 181     // Move wide OOP
 182     assert(nativeInstruction_at(insn_addr+8)->is_movk(), "wrong insns in patch");
 183     uintptr_t dest = (uintptr_t)o;
 184     Instruction_aarch64::patch(insn_addr, 20, 5, dest & 0xffff);
 185     Instruction_aarch64::patch(insn_addr+4, 20, 5, (dest >>= 16) & 0xffff);
 186     Instruction_aarch64::patch(insn_addr+8, 20, 5, (dest >>= 16) & 0xffff);
 187     instructions = 3;
 188   }
 189   return instructions * NativeInstruction::instruction_size;
 190 }
 191 
 192 int MacroAssembler::patch_narrow_klass(address insn_addr, narrowKlass n) {
 193   // Metatdata pointers are either narrow (32 bits) or wide (48 bits).
 194   // We encode narrow ones by setting the upper 16 bits in the first
 195   // instruction.
 196   NativeInstruction *insn = nativeInstruction_at(insn_addr);


3695 }
3696 
3697 void MacroAssembler::store_klass(Register dst, Register src) {
3698   // FIXME: Should this be a store release?  concurrent gcs assumes
3699   // klass length is valid if klass field is not null.
3700   if (UseCompressedClassPointers) {
3701     encode_klass_not_null(src);
3702     strw(src, Address(dst, oopDesc::klass_offset_in_bytes()));
3703   } else {
3704     str(src, Address(dst, oopDesc::klass_offset_in_bytes()));
3705   }
3706 }
3707 
3708 void MacroAssembler::store_klass_gap(Register dst, Register src) {
3709   if (UseCompressedClassPointers) {
3710     // Store to klass gap in destination
3711     strw(src, Address(dst, oopDesc::klass_gap_offset_in_bytes()));
3712   }
3713 }
3714 
3715 // Algorithm must match oop.inline.hpp encode_heap_oop.
3716 void MacroAssembler::encode_heap_oop(Register d, Register s) {
3717 #ifdef ASSERT
3718   verify_heapbase("MacroAssembler::encode_heap_oop: heap base corrupted?");
3719 #endif
3720   verify_oop(s, "broken oop in encode_heap_oop");
3721   if (Universe::narrow_oop_base() == NULL) {
3722     if (Universe::narrow_oop_shift() != 0) {
3723       assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
3724       lsr(d, s, LogMinObjAlignmentInBytes);
3725     } else {
3726       mov(d, s);
3727     }
3728   } else {
3729     subs(d, s, rheapbase);
3730     csel(d, d, zr, Assembler::HS);
3731     lsr(d, d, LogMinObjAlignmentInBytes);
3732 
3733     /*  Old algorithm: is this any worse?
3734     Label nonnull;
3735     cbnz(r, nonnull);




  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #include <sys/types.h>
  27 
  28 #include "precompiled.hpp"
  29 #include "jvm.h"
  30 #include "asm/assembler.hpp"
  31 #include "asm/assembler.inline.hpp"
  32 #include "gc/shared/cardTable.hpp"
  33 #include "gc/shared/cardTableModRefBS.hpp"
  34 #include "interpreter/interpreter.hpp"
  35 #include "compiler/disassembler.hpp"
  36 #include "memory/resourceArea.hpp"
  37 #include "nativeInst_aarch64.hpp"
  38 #include "oops/compressedOops.inline.hpp"
  39 #include "oops/klass.inline.hpp"
  40 #include "oops/oop.hpp"
  41 #include "opto/compile.hpp"
  42 #include "opto/intrinsicnode.hpp"
  43 #include "opto/node.hpp"
  44 #include "runtime/biasedLocking.hpp"
  45 #include "runtime/icache.hpp"
  46 #include "runtime/interfaceSupport.inline.hpp"
  47 #include "runtime/jniHandles.inline.hpp"
  48 #include "runtime/sharedRuntime.hpp"
  49 #include "runtime/thread.hpp"

  50 #if INCLUDE_ALL_GCS
  51 #include "gc/g1/g1BarrierSet.hpp"
  52 #include "gc/g1/g1CardTable.hpp"
  53 #include "gc/g1/g1CollectedHeap.inline.hpp"
  54 #include "gc/g1/heapRegion.hpp"
  55 #endif
  56 
  57 #ifdef PRODUCT
  58 #define BLOCK_COMMENT(str) /* nothing */
  59 #define STOP(error) stop(error)
  60 #else
  61 #define BLOCK_COMMENT(str) block_comment(str)
  62 #define STOP(error) block_comment(error); stop(error)
  63 #endif
  64 
  65 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
  66 
  67 // Patch any kind of instruction; there may be several instructions.
  68 // Return the total length (in bytes) of the instructions.
  69 int MacroAssembler::pd_patch_instruction_size(address branch, address target) {


 156   } else if (Instruction_aarch64::extract(insn, 31, 22) == 0b1011100101 &&
 157              Instruction_aarch64::extract(insn, 4, 0) == 0b11111) {
 158     // nothing to do
 159     assert(target == 0, "did not expect to relocate target for polling page load");
 160   } else {
 161     ShouldNotReachHere();
 162   }
 163   return instructions * NativeInstruction::instruction_size;
 164 }
 165 
 166 int MacroAssembler::patch_oop(address insn_addr, address o) {
 167   int instructions;
 168   unsigned insn = *(unsigned*)insn_addr;
 169   assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
 170 
 171   // OOPs are either narrow (32 bits) or wide (48 bits).  We encode
 172   // narrow OOPs by setting the upper 16 bits in the first
 173   // instruction.
 174   if (Instruction_aarch64::extract(insn, 31, 21) == 0b11010010101) {
 175     // Move narrow OOP
 176     narrowOop n = CompressedOops::encode((oop)o);
 177     Instruction_aarch64::patch(insn_addr, 20, 5, n >> 16);
 178     Instruction_aarch64::patch(insn_addr+4, 20, 5, n & 0xffff);
 179     instructions = 2;
 180   } else {
 181     // Move wide OOP
 182     assert(nativeInstruction_at(insn_addr+8)->is_movk(), "wrong insns in patch");
 183     uintptr_t dest = (uintptr_t)o;
 184     Instruction_aarch64::patch(insn_addr, 20, 5, dest & 0xffff);
 185     Instruction_aarch64::patch(insn_addr+4, 20, 5, (dest >>= 16) & 0xffff);
 186     Instruction_aarch64::patch(insn_addr+8, 20, 5, (dest >>= 16) & 0xffff);
 187     instructions = 3;
 188   }
 189   return instructions * NativeInstruction::instruction_size;
 190 }
 191 
 192 int MacroAssembler::patch_narrow_klass(address insn_addr, narrowKlass n) {
 193   // Metatdata pointers are either narrow (32 bits) or wide (48 bits).
 194   // We encode narrow ones by setting the upper 16 bits in the first
 195   // instruction.
 196   NativeInstruction *insn = nativeInstruction_at(insn_addr);


3695 }
3696 
3697 void MacroAssembler::store_klass(Register dst, Register src) {
3698   // FIXME: Should this be a store release?  concurrent gcs assumes
3699   // klass length is valid if klass field is not null.
3700   if (UseCompressedClassPointers) {
3701     encode_klass_not_null(src);
3702     strw(src, Address(dst, oopDesc::klass_offset_in_bytes()));
3703   } else {
3704     str(src, Address(dst, oopDesc::klass_offset_in_bytes()));
3705   }
3706 }
3707 
3708 void MacroAssembler::store_klass_gap(Register dst, Register src) {
3709   if (UseCompressedClassPointers) {
3710     // Store to klass gap in destination
3711     strw(src, Address(dst, oopDesc::klass_gap_offset_in_bytes()));
3712   }
3713 }
3714 
3715 // Algorithm must match CompressedOops::encode.
3716 void MacroAssembler::encode_heap_oop(Register d, Register s) {
3717 #ifdef ASSERT
3718   verify_heapbase("MacroAssembler::encode_heap_oop: heap base corrupted?");
3719 #endif
3720   verify_oop(s, "broken oop in encode_heap_oop");
3721   if (Universe::narrow_oop_base() == NULL) {
3722     if (Universe::narrow_oop_shift() != 0) {
3723       assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
3724       lsr(d, s, LogMinObjAlignmentInBytes);
3725     } else {
3726       mov(d, s);
3727     }
3728   } else {
3729     subs(d, s, rheapbase);
3730     csel(d, d, zr, Assembler::HS);
3731     lsr(d, d, LogMinObjAlignmentInBytes);
3732 
3733     /*  Old algorithm: is this any worse?
3734     Label nonnull;
3735     cbnz(r, nonnull);


< prev index next >