< prev index next >

src/hotspot/cpu/x86/c2_CodeStubs_x86.cpp

Print this page

 79 
 80 void C2FastUnlockLightweightStub::emit(C2_MacroAssembler& masm) {
 81   assert(_t == rax, "must be");
 82 
 83   Label restore_held_monitor_count_and_slow_path;
 84 
 85   { // Restore lock-stack and handle the unlock in runtime.
 86 
 87     __ bind(_push_and_slow_path);
 88 #ifdef ASSERT
 89     // The obj was only cleared in debug.
 90     __ movl(_t, Address(_thread, JavaThread::lock_stack_top_offset()));
 91     __ movptr(Address(_thread, _t), _obj);
 92 #endif
 93     __ addl(Address(_thread, JavaThread::lock_stack_top_offset()), oopSize);
 94   }
 95 
 96   { // Restore held monitor count and slow path.
 97 
 98     __ bind(restore_held_monitor_count_and_slow_path);

 99     // Restore held monitor count.
100     __ increment(Address(_thread, JavaThread::held_monitor_count_offset()));
101     // increment will always result in ZF = 0 (no overflows).
102     __ jmp(slow_path_continuation());
103   }
104 
105   { // Handle monitor medium path.
106 
107     __ bind(_check_successor);
108 
109     Label fix_zf_and_unlocked;
110     const Register monitor = _mark;
111 
112 #ifndef _LP64
113     __ jmpb(restore_held_monitor_count_and_slow_path);
114 #else // _LP64




115     // successor null check.
116     __ cmpptr(Address(monitor, OM_OFFSET_NO_MONITOR_VALUE_TAG(succ)), NULL_WORD);
117     __ jccb(Assembler::equal, restore_held_monitor_count_and_slow_path);
118 
119     // Release lock.
120     __ movptr(Address(monitor, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)), NULL_WORD);
121 
122     // Fence.
123     // Instead of MFENCE we use a dummy locked add of 0 to the top-of-stack.
124     __ lock(); __ addl(Address(rsp, 0), 0);
125 
126     // Recheck successor.
127     __ cmpptr(Address(monitor, OM_OFFSET_NO_MONITOR_VALUE_TAG(succ)), NULL_WORD);
128     // Observed a successor after the release -> fence we have handed off the monitor
129     __ jccb(Assembler::notEqual, fix_zf_and_unlocked);
130 
131     // Try to relock, if it fails the monitor has been handed over
132     // TODO: Caveat, this may fail due to deflation, which does
133     //       not handle the monitor handoff. Currently only works
134     //       due to the responsible thread.
135     __ xorptr(rax, rax);
136     __ lock(); __ cmpxchgptr(_thread, Address(monitor, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
137     __ jccb  (Assembler::equal, restore_held_monitor_count_and_slow_path);
138 #endif
139 
140     __ bind(fix_zf_and_unlocked);
141     __ xorl(rax, rax);
142     __ jmp(unlocked_continuation());
143   }
144 }
145 
146 #undef __

 79 
 80 void C2FastUnlockLightweightStub::emit(C2_MacroAssembler& masm) {
 81   assert(_t == rax, "must be");
 82 
 83   Label restore_held_monitor_count_and_slow_path;
 84 
 85   { // Restore lock-stack and handle the unlock in runtime.
 86 
 87     __ bind(_push_and_slow_path);
 88 #ifdef ASSERT
 89     // The obj was only cleared in debug.
 90     __ movl(_t, Address(_thread, JavaThread::lock_stack_top_offset()));
 91     __ movptr(Address(_thread, _t), _obj);
 92 #endif
 93     __ addl(Address(_thread, JavaThread::lock_stack_top_offset()), oopSize);
 94   }
 95 
 96   { // Restore held monitor count and slow path.
 97 
 98     __ bind(restore_held_monitor_count_and_slow_path);
 99     __ bind(_slow_path);
100     // Restore held monitor count.
101     __ increment(Address(_thread, JavaThread::held_monitor_count_offset()));
102     // increment will always result in ZF = 0 (no overflows).
103     __ jmp(slow_path_continuation());
104   }
105 
106   { // Handle monitor medium path.
107 
108     __ bind(_check_successor);
109 
110     Label fix_zf_and_unlocked;
111     const Register monitor = _mark;
112 
113 #ifndef _LP64
114     __ jmpb(restore_held_monitor_count_and_slow_path);
115 #else // _LP64
116     const ByteSize monitor_tag = in_ByteSize(UseObjectMonitorTable ? 0 : checked_cast<int>(markWord::monitor_value));
117     const Address succ_address{monitor, ObjectMonitor::succ_offset() - monitor_tag};
118     const Address owner_address{monitor, ObjectMonitor::owner_offset() - monitor_tag};
119 
120     // successor null check.
121     __ cmpptr(succ_address, NULL_WORD);
122     __ jccb(Assembler::equal, restore_held_monitor_count_and_slow_path);
123 
124     // Release lock.
125     __ movptr(owner_address, NULL_WORD);
126 
127     // Fence.
128     // Instead of MFENCE we use a dummy locked add of 0 to the top-of-stack.
129     __ lock(); __ addl(Address(rsp, 0), 0);
130 
131     // Recheck successor.
132     __ cmpptr(succ_address, NULL_WORD);
133     // Observed a successor after the release -> fence we have handed off the monitor
134     __ jccb(Assembler::notEqual, fix_zf_and_unlocked);
135 
136     // Try to relock, if it fails the monitor has been handed over
137     // TODO: Caveat, this may fail due to deflation, which does
138     //       not handle the monitor handoff. Currently only works
139     //       due to the responsible thread.
140     __ xorptr(rax, rax);
141     __ lock(); __ cmpxchgptr(_thread, owner_address);
142     __ jccb  (Assembler::equal, restore_held_monitor_count_and_slow_path);
143 #endif
144 
145     __ bind(fix_zf_and_unlocked);
146     __ xorl(rax, rax);
147     __ jmp(unlocked_continuation());
148   }
149 }
150 
151 #undef __
< prev index next >