28 #include "opto/c2_MacroAssembler.hpp"
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
36 #ifdef PRODUCT
37 #define BLOCK_COMMENT(str) /* nothing */
38 #define STOP(error) stop(error)
39 #else
40 #define BLOCK_COMMENT(str) block_comment(str)
41 #define STOP(error) block_comment(error); stop(error)
42 #endif
43
44 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
45
46 typedef void (MacroAssembler::* chr_insn)(Register Rt, const Address &adr);
47
48 void C2_MacroAssembler::fast_lock(Register objectReg, Register boxReg, Register tmpReg,
49 Register tmp2Reg, Register tmp3Reg) {
50 Register oop = objectReg;
51 Register box = boxReg;
52 Register disp_hdr = tmpReg;
53 Register tmp = tmp2Reg;
54 Label cont;
55 Label object_has_monitor;
56 Label count, no_count;
57
58 assert_different_registers(oop, box, tmp, disp_hdr);
59
60 // Load markWord from object into displaced_header.
61 ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes()));
62
63 if (DiagnoseSyncOnValueBasedClasses != 0) {
64 load_klass(tmp, oop);
65 ldrw(tmp, Address(tmp, Klass::access_flags_offset()));
66 tstw(tmp, JVM_ACC_IS_VALUE_BASED_CLASS);
67 br(Assembler::NE, cont);
68 }
69
70 // Check for existing monitor
71 tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor);
72
73 if (LockingMode == LM_MONITOR) {
74 tst(oop, oop); // Set NE to indicate 'failure' -> take slow-path. We know that oop != 0.
75 b(cont);
76 } else if (LockingMode == LM_LEGACY) {
77 // Set tmp to be (markWord of object | UNLOCK_VALUE).
78 orr(tmp, disp_hdr, markWord::unlocked_value);
79
80 // Initialize the box. (Must happen before we update the object mark!)
81 str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes()));
82
83 // Compare object markWord with an unlocked value (tmp) and if
84 // equal exchange the stack address of our box with object markWord.
85 // On failure disp_hdr contains the possibly locked markWord.
86 cmpxchg(oop, tmp, box, Assembler::xword, /*acquire*/ true,
87 /*release*/ true, /*weak*/ false, disp_hdr);
88 br(Assembler::EQ, cont);
89
90 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
91
92 // If the compare-and-exchange succeeded, then we found an unlocked
93 // object, will have now locked it will continue at label cont
94
95 // Check if the owner is self by comparing the value in the
96 // markWord of object (disp_hdr) with the stack pointer.
97 mov(rscratch1, sp);
98 sub(disp_hdr, disp_hdr, rscratch1);
99 mov(tmp, (address) (~(os::vm_page_size()-1) | markWord::lock_mask_in_place));
|
28 #include "opto/c2_MacroAssembler.hpp"
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
36 #ifdef PRODUCT
37 #define BLOCK_COMMENT(str) /* nothing */
38 #define STOP(error) stop(error)
39 #else
40 #define BLOCK_COMMENT(str) block_comment(str)
41 #define STOP(error) block_comment(error); stop(error)
42 #endif
43
44 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
45
46 typedef void (MacroAssembler::* chr_insn)(Register Rt, const Address &adr);
47
48 void C2_MacroAssembler::entry_barrier() {
49 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
50 if (BarrierSet::barrier_set()->barrier_set_nmethod() != nullptr) {
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
71 void C2_MacroAssembler::fast_lock(Register objectReg, Register boxReg, Register tmpReg,
72 Register tmp2Reg, Register tmp3Reg) {
73 Register oop = objectReg;
74 Register box = boxReg;
75 Register disp_hdr = tmpReg;
76 Register tmp = tmp2Reg;
77 Label cont;
78 Label object_has_monitor;
79 Label count, no_count;
80
81 assert_different_registers(oop, box, tmp, disp_hdr);
82
83 // Load markWord from object into displaced_header.
84 ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes()));
85
86 if (DiagnoseSyncOnValueBasedClasses != 0) {
87 load_klass(tmp, oop);
88 ldrw(tmp, Address(tmp, Klass::access_flags_offset()));
89 tstw(tmp, JVM_ACC_IS_VALUE_BASED_CLASS);
90 br(Assembler::NE, cont);
91 }
92
93 // Check for existing monitor
94 tbnz(disp_hdr, exact_log2(markWord::monitor_value), object_has_monitor);
95
96 if (LockingMode == LM_MONITOR) {
97 tst(oop, oop); // Set NE to indicate 'failure' -> take slow-path. We know that oop != 0.
98 b(cont);
99 } else if (LockingMode == LM_LEGACY) {
100 // Set tmp to be (markWord of object | UNLOCK_VALUE).
101 orr(tmp, disp_hdr, markWord::unlocked_value);
102
103 if (EnableValhalla) {
104 // Mask inline_type bit such that we go to the slow path if object is an inline type
105 andr(tmp, tmp, ~((int) markWord::inline_type_bit_in_place));
106 }
107
108 // Initialize the box. (Must happen before we update the object mark!)
109 str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes()));
110
111 // Compare object markWord with an unlocked value (tmp) and if
112 // equal exchange the stack address of our box with object markWord.
113 // On failure disp_hdr contains the possibly locked markWord.
114 cmpxchg(oop, tmp, box, Assembler::xword, /*acquire*/ true,
115 /*release*/ true, /*weak*/ false, disp_hdr);
116 br(Assembler::EQ, cont);
117
118 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
119
120 // If the compare-and-exchange succeeded, then we found an unlocked
121 // object, will have now locked it will continue at label cont
122
123 // Check if the owner is self by comparing the value in the
124 // markWord of object (disp_hdr) with the stack pointer.
125 mov(rscratch1, sp);
126 sub(disp_hdr, disp_hdr, rscratch1);
127 mov(tmp, (address) (~(os::vm_page_size()-1) | markWord::lock_mask_in_place));
|