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));
|