< prev index next >

src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp

Print this page

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























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

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





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

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

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