< prev index next >

src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp

Print this page

  29 #include "opto/intrinsicnode.hpp"
  30 #include "opto/matcher.hpp"
  31 #include "opto/output.hpp"
  32 #include "opto/subnode.hpp"
  33 #include "runtime/stubRoutines.hpp"
  34 #include "utilities/globalDefinitions.hpp"
  35 #include "utilities/powerOfTwo.hpp"
  36 
  37 #ifdef PRODUCT
  38 #define BLOCK_COMMENT(str) /* nothing */
  39 #define STOP(error) stop(error)
  40 #else
  41 #define BLOCK_COMMENT(str) block_comment(str)
  42 #define STOP(error) block_comment(error); stop(error)
  43 #endif
  44 
  45 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
  46 
  47 typedef void (MacroAssembler::* chr_insn)(Register Rt, const Address &adr);
  48 





















  49 // jdk.internal.util.ArraysSupport.vectorizedHashCode
  50 address C2_MacroAssembler::arrays_hashcode(Register ary, Register cnt, Register result,
  51                                            FloatRegister vdata0, FloatRegister vdata1,
  52                                            FloatRegister vdata2, FloatRegister vdata3,
  53                                            FloatRegister vmul0, FloatRegister vmul1,
  54                                            FloatRegister vmul2, FloatRegister vmul3,
  55                                            FloatRegister vpow, FloatRegister vpowm,
  56                                            BasicType eltype) {
  57   ARRAYS_HASHCODE_REGISTERS;
  58 
  59   Register tmp1 = rscratch1, tmp2 = rscratch2;
  60 
  61   Label TAIL, STUB_SWITCH, STUB_SWITCH_OUT, LOOP, BR_BASE, LARGE, DONE;
  62 
  63   // Vectorization factor. Number of array elements loaded to one SIMD&FP registers by the stubs. We
  64   // use 8H load arrangements for chars and shorts and 8B for booleans and bytes. It's possible to
  65   // use 4H for chars and shorts instead, but using 8H gives better performance.
  66   const size_t vf = eltype == T_BOOLEAN || eltype == T_BYTE ? 8
  67                     : eltype == T_CHAR || eltype == T_SHORT ? 8
  68                     : eltype == T_INT                       ? 4

 164   ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes()));
 165 
 166   if (DiagnoseSyncOnValueBasedClasses != 0) {
 167     load_klass(tmp, oop);
 168     ldrb(tmp, Address(tmp, Klass::misc_flags_offset()));
 169     tst(tmp, KlassFlags::_misc_is_value_based_class);
 170     br(Assembler::NE, cont);
 171   }
 172 
 173   // Check for existing monitor
 174   tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor);
 175 
 176   if (LockingMode == LM_MONITOR) {
 177     tst(oop, oop); // Set NE to indicate 'failure' -> take slow-path. We know that oop != 0.
 178     b(cont);
 179   } else {
 180     assert(LockingMode == LM_LEGACY, "must be");
 181     // Set tmp to be (markWord of object | UNLOCK_VALUE).
 182     orr(tmp, disp_hdr, markWord::unlocked_value);
 183 





 184     // Initialize the box. (Must happen before we update the object mark!)
 185     str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes()));
 186 
 187     // Compare object markWord with an unlocked value (tmp) and if
 188     // equal exchange the stack address of our box with object markWord.
 189     // On failure disp_hdr contains the possibly locked markWord.
 190     cmpxchg(oop, tmp, box, Assembler::xword, /*acquire*/ true,
 191             /*release*/ true, /*weak*/ false, disp_hdr);
 192     br(Assembler::EQ, cont);
 193 
 194     assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
 195 
 196     // If the compare-and-exchange succeeded, then we found an unlocked
 197     // object, will have now locked it will continue at label cont
 198 
 199     // Check if the owner is self by comparing the value in the
 200     // markWord of object (disp_hdr) with the stack pointer.
 201     mov(rscratch1, sp);
 202     sub(disp_hdr, disp_hdr, rscratch1);
 203     mov(tmp, (address) (~(os::vm_page_size()-1) | markWord::lock_mask_in_place));

  29 #include "opto/intrinsicnode.hpp"
  30 #include "opto/matcher.hpp"
  31 #include "opto/output.hpp"
  32 #include "opto/subnode.hpp"
  33 #include "runtime/stubRoutines.hpp"
  34 #include "utilities/globalDefinitions.hpp"
  35 #include "utilities/powerOfTwo.hpp"
  36 
  37 #ifdef PRODUCT
  38 #define BLOCK_COMMENT(str) /* nothing */
  39 #define STOP(error) stop(error)
  40 #else
  41 #define BLOCK_COMMENT(str) block_comment(str)
  42 #define STOP(error) block_comment(error); stop(error)
  43 #endif
  44 
  45 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
  46 
  47 typedef void (MacroAssembler::* chr_insn)(Register Rt, const Address &adr);
  48 
  49 void C2_MacroAssembler::entry_barrier() {
  50   BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
  51   // Dummy labels for just measuring the code size
  52   Label dummy_slow_path;
  53   Label dummy_continuation;
  54   Label dummy_guard;
  55   Label* slow_path = &dummy_slow_path;
  56   Label* continuation = &dummy_continuation;
  57   Label* guard = &dummy_guard;
  58   if (!Compile::current()->output()->in_scratch_emit_size()) {
  59     // Use real labels from actual stub when not emitting code for the purpose of measuring its size
  60     C2EntryBarrierStub* stub = new (Compile::current()->comp_arena()) C2EntryBarrierStub();
  61     Compile::current()->output()->add_stub(stub);
  62     slow_path = &stub->entry();
  63     continuation = &stub->continuation();
  64     guard = &stub->guard();
  65   }
  66   // In the C2 code, we move the non-hot part of nmethod entry barriers out-of-line to a stub.
  67   bs->nmethod_entry_barrier(this, slow_path, continuation, guard);
  68 }
  69 
  70 // jdk.internal.util.ArraysSupport.vectorizedHashCode
  71 address C2_MacroAssembler::arrays_hashcode(Register ary, Register cnt, Register result,
  72                                            FloatRegister vdata0, FloatRegister vdata1,
  73                                            FloatRegister vdata2, FloatRegister vdata3,
  74                                            FloatRegister vmul0, FloatRegister vmul1,
  75                                            FloatRegister vmul2, FloatRegister vmul3,
  76                                            FloatRegister vpow, FloatRegister vpowm,
  77                                            BasicType eltype) {
  78   ARRAYS_HASHCODE_REGISTERS;
  79 
  80   Register tmp1 = rscratch1, tmp2 = rscratch2;
  81 
  82   Label TAIL, STUB_SWITCH, STUB_SWITCH_OUT, LOOP, BR_BASE, LARGE, DONE;
  83 
  84   // Vectorization factor. Number of array elements loaded to one SIMD&FP registers by the stubs. We
  85   // use 8H load arrangements for chars and shorts and 8B for booleans and bytes. It's possible to
  86   // use 4H for chars and shorts instead, but using 8H gives better performance.
  87   const size_t vf = eltype == T_BOOLEAN || eltype == T_BYTE ? 8
  88                     : eltype == T_CHAR || eltype == T_SHORT ? 8
  89                     : eltype == T_INT                       ? 4

 185   ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes()));
 186 
 187   if (DiagnoseSyncOnValueBasedClasses != 0) {
 188     load_klass(tmp, oop);
 189     ldrb(tmp, Address(tmp, Klass::misc_flags_offset()));
 190     tst(tmp, KlassFlags::_misc_is_value_based_class);
 191     br(Assembler::NE, cont);
 192   }
 193 
 194   // Check for existing monitor
 195   tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor);
 196 
 197   if (LockingMode == LM_MONITOR) {
 198     tst(oop, oop); // Set NE to indicate 'failure' -> take slow-path. We know that oop != 0.
 199     b(cont);
 200   } else {
 201     assert(LockingMode == LM_LEGACY, "must be");
 202     // Set tmp to be (markWord of object | UNLOCK_VALUE).
 203     orr(tmp, disp_hdr, markWord::unlocked_value);
 204 
 205     if (EnableValhalla) {
 206       // Mask inline_type bit such that we go to the slow path if object is an inline type
 207       andr(tmp, tmp, ~((int) markWord::inline_type_bit_in_place));
 208     }
 209 
 210     // Initialize the box. (Must happen before we update the object mark!)
 211     str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes()));
 212 
 213     // Compare object markWord with an unlocked value (tmp) and if
 214     // equal exchange the stack address of our box with object markWord.
 215     // On failure disp_hdr contains the possibly locked markWord.
 216     cmpxchg(oop, tmp, box, Assembler::xword, /*acquire*/ true,
 217             /*release*/ true, /*weak*/ false, disp_hdr);
 218     br(Assembler::EQ, cont);
 219 
 220     assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
 221 
 222     // If the compare-and-exchange succeeded, then we found an unlocked
 223     // object, will have now locked it will continue at label cont
 224 
 225     // Check if the owner is self by comparing the value in the
 226     // markWord of object (disp_hdr) with the stack pointer.
 227     mov(rscratch1, sp);
 228     sub(disp_hdr, disp_hdr, rscratch1);
 229     mov(tmp, (address) (~(os::vm_page_size()-1) | markWord::lock_mask_in_place));
< prev index next >