< prev index next >

src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp

Print this page

  29 #include "opto/compile.hpp"
  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 
  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::fast_lock(Register objectReg, Register boxReg, Register tmpReg,
  50                                   Register tmp2Reg, Register tmp3Reg) {
  51   Register oop = objectReg;
  52   Register box = boxReg;
  53   Register disp_hdr = tmpReg;
  54   Register tmp = tmp2Reg;
  55   Label cont;
  56   Label object_has_monitor;
  57   Label count, no_count;
  58 
  59   assert(LockingMode != LM_LIGHTWEIGHT, "lightweight locking should use fast_lock_lightweight");
  60   assert_different_registers(oop, box, tmp, disp_hdr);
  61 
  62   // Load markWord from object into displaced_header.
  63   ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes()));
  64 
  65   if (DiagnoseSyncOnValueBasedClasses != 0) {
  66     load_klass(tmp, oop);
  67     ldrb(tmp, Address(tmp, Klass::misc_flags_offset()));
  68     tst(tmp, KlassFlags::_misc_is_value_based_class);
  69     br(Assembler::NE, cont);
  70   }
  71 
  72   // Check for existing monitor
  73   tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor);
  74 
  75   if (LockingMode == LM_MONITOR) {
  76     tst(oop, oop); // Set NE to indicate 'failure' -> take slow-path. We know that oop != 0.
  77     b(cont);
  78   } else {
  79     assert(LockingMode == LM_LEGACY, "must be");
  80     // Set tmp to be (markWord of object | UNLOCK_VALUE).
  81     orr(tmp, disp_hdr, markWord::unlocked_value);
  82 





  83     // Initialize the box. (Must happen before we update the object mark!)
  84     str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes()));
  85 
  86     // Compare object markWord with an unlocked value (tmp) and if
  87     // equal exchange the stack address of our box with object markWord.
  88     // On failure disp_hdr contains the possibly locked markWord.
  89     cmpxchg(oop, tmp, box, Assembler::xword, /*acquire*/ true,
  90             /*release*/ true, /*weak*/ false, disp_hdr);
  91     br(Assembler::EQ, cont);
  92 
  93     assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
  94 
  95     // If the compare-and-exchange succeeded, then we found an unlocked
  96     // object, will have now locked it will continue at label cont
  97 
  98     // Check if the owner is self by comparing the value in the
  99     // markWord of object (disp_hdr) with the stack pointer.
 100     mov(rscratch1, sp);
 101     sub(disp_hdr, disp_hdr, rscratch1);
 102     mov(tmp, (address) (~(os::vm_page_size()-1) | markWord::lock_mask_in_place));

  29 #include "opto/compile.hpp"
  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 
  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   if (BarrierSet::barrier_set()->barrier_set_nmethod() != nullptr) {
  52     // Dummy labels for just measuring the code size
  53     Label dummy_slow_path;
  54     Label dummy_continuation;
  55     Label dummy_guard;
  56     Label* slow_path = &dummy_slow_path;
  57     Label* continuation = &dummy_continuation;
  58     Label* guard = &dummy_guard;
  59     if (!Compile::current()->output()->in_scratch_emit_size()) {
  60       // Use real labels from actual stub when not emitting code for the purpose of measuring its size
  61       C2EntryBarrierStub* stub = new (Compile::current()->comp_arena()) C2EntryBarrierStub();
  62       Compile::current()->output()->add_stub(stub);
  63       slow_path = &stub->entry();
  64       continuation = &stub->continuation();
  65       guard = &stub->guard();
  66     }
  67     // In the C2 code, we move the non-hot part of nmethod entry barriers out-of-line to a stub.
  68     bs->nmethod_entry_barrier(this, slow_path, continuation, guard);
  69   }
  70 }
  71 
  72 void C2_MacroAssembler::fast_lock(Register objectReg, Register boxReg, Register tmpReg,
  73                                   Register tmp2Reg, Register tmp3Reg) {
  74   Register oop = objectReg;
  75   Register box = boxReg;
  76   Register disp_hdr = tmpReg;
  77   Register tmp = tmp2Reg;
  78   Label cont;
  79   Label object_has_monitor;
  80   Label count, no_count;
  81 
  82   assert(LockingMode != LM_LIGHTWEIGHT, "lightweight locking should use fast_lock_lightweight");
  83   assert_different_registers(oop, box, tmp, disp_hdr);
  84 
  85   // Load markWord from object into displaced_header.
  86   ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes()));
  87 
  88   if (DiagnoseSyncOnValueBasedClasses != 0) {
  89     load_klass(tmp, oop);
  90     ldrb(tmp, Address(tmp, Klass::misc_flags_offset()));
  91     tst(tmp, KlassFlags::_misc_is_value_based_class);
  92     br(Assembler::NE, cont);
  93   }
  94 
  95   // Check for existing monitor
  96   tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor);
  97 
  98   if (LockingMode == LM_MONITOR) {
  99     tst(oop, oop); // Set NE to indicate 'failure' -> take slow-path. We know that oop != 0.
 100     b(cont);
 101   } else {
 102     assert(LockingMode == LM_LEGACY, "must be");
 103     // Set tmp to be (markWord of object | UNLOCK_VALUE).
 104     orr(tmp, disp_hdr, markWord::unlocked_value);
 105 
 106     if (EnableValhalla) {
 107       // Mask inline_type bit such that we go to the slow path if object is an inline type
 108       andr(tmp, tmp, ~((int) markWord::inline_type_bit_in_place));
 109     }
 110 
 111     // Initialize the box. (Must happen before we update the object mark!)
 112     str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes()));
 113 
 114     // Compare object markWord with an unlocked value (tmp) and if
 115     // equal exchange the stack address of our box with object markWord.
 116     // On failure disp_hdr contains the possibly locked markWord.
 117     cmpxchg(oop, tmp, box, Assembler::xword, /*acquire*/ true,
 118             /*release*/ true, /*weak*/ false, disp_hdr);
 119     br(Assembler::EQ, cont);
 120 
 121     assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
 122 
 123     // If the compare-and-exchange succeeded, then we found an unlocked
 124     // object, will have now locked it will continue at label cont
 125 
 126     // Check if the owner is self by comparing the value in the
 127     // markWord of object (disp_hdr) with the stack pointer.
 128     mov(rscratch1, sp);
 129     sub(disp_hdr, disp_hdr, rscratch1);
 130     mov(tmp, (address) (~(os::vm_page_size()-1) | markWord::lock_mask_in_place));
< prev index next >