< 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

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





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

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