Skip to content

Commit ccdd279

Browse files
committed
Allow virtual threads to unmount while holding monitors
1 parent 363327e commit ccdd279

File tree

80 files changed

+1092
-658
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+1092
-658
lines changed

src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,8 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr
119119
cbnz(hdr, slow_case);
120120
// done
121121
bind(done);
122+
inc_held_monitor_count();
122123
}
123-
increment(Address(rthread, JavaThread::held_monitor_count_offset()));
124124
return null_check_offset;
125125
}
126126

@@ -159,8 +159,8 @@ void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_
159159
}
160160
// done
161161
bind(done);
162+
dec_held_monitor_count();
162163
}
163-
decrement(Address(rthread, JavaThread::held_monitor_count_offset()));
164164
}
165165

166166

src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ void C2_MacroAssembler::fast_lock(Register objectReg, Register boxReg, Register
5757
Label count, no_count;
5858

5959
assert(LockingMode != LM_LIGHTWEIGHT, "lightweight locking should use fast_lock_lightweight");
60-
assert_different_registers(oop, box, tmp, disp_hdr);
60+
assert_different_registers(oop, box, tmp, disp_hdr, rscratch2);
6161

6262
// Load markWord from object into displaced_header.
6363
ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes()));
@@ -111,11 +111,13 @@ void C2_MacroAssembler::fast_lock(Register objectReg, Register boxReg, Register
111111
bind(object_has_monitor);
112112

113113
// The object's monitor m is unlocked iff m->owner == nullptr,
114-
// otherwise m->owner may contain a thread or a stack address.
114+
// otherwise m->owner may contain a thread id, a stack address for LM_LEGACY,
115+
// or the ANONYMOUS_OWNER constant for LM_LIGHTWEIGHT.
115116
//
116117
// Try to CAS m->owner from null to current thread.
118+
ldr(rscratch2, Address(rthread, JavaThread::lock_id_offset()));
117119
add(tmp, disp_hdr, (in_bytes(ObjectMonitor::owner_offset())-markWord::monitor_value));
118-
cmpxchg(tmp, zr, rthread, Assembler::xword, /*acquire*/ true,
120+
cmpxchg(tmp, zr, rscratch2, Assembler::xword, /*acquire*/ true,
119121
/*release*/ true, /*weak*/ false, tmp3Reg); // Sets flags for result
120122

121123
// Store a non-null value into the box to avoid looking like a re-entrant
@@ -127,7 +129,7 @@ void C2_MacroAssembler::fast_lock(Register objectReg, Register boxReg, Register
127129

128130
br(Assembler::EQ, cont); // CAS success means locking succeeded
129131

130-
cmp(tmp3Reg, rthread);
132+
cmp(tmp3Reg, rscratch2);
131133
br(Assembler::NE, cont); // Check for recursive locking
132134

133135
// Recursive lock case
@@ -140,7 +142,9 @@ void C2_MacroAssembler::fast_lock(Register objectReg, Register boxReg, Register
140142
br(Assembler::NE, no_count);
141143

142144
bind(count);
143-
increment(Address(rthread, JavaThread::held_monitor_count_offset()));
145+
if (LockingMode == LM_LEGACY) {
146+
inc_held_monitor_count();
147+
}
144148

145149
bind(no_count);
146150
}
@@ -247,15 +251,17 @@ void C2_MacroAssembler::fast_unlock(Register objectReg, Register boxReg, Registe
247251
br(Assembler::NE, no_count);
248252

249253
bind(count);
250-
decrement(Address(rthread, JavaThread::held_monitor_count_offset()));
254+
if (LockingMode == LM_LEGACY) {
255+
dec_held_monitor_count();
256+
}
251257

252258
bind(no_count);
253259
}
254260

255261
void C2_MacroAssembler::fast_lock_lightweight(Register obj, Register box, Register t1,
256262
Register t2, Register t3) {
257263
assert(LockingMode == LM_LIGHTWEIGHT, "must be");
258-
assert_different_registers(obj, box, t1, t2, t3);
264+
assert_different_registers(obj, box, t1, t2, t3, rscratch2);
259265

260266
// Handle inflated monitor.
261267
Label inflated;
@@ -371,13 +377,14 @@ void C2_MacroAssembler::fast_lock_lightweight(Register obj, Register box, Regist
371377
// Compute owner address.
372378
lea(t2_owner_addr, owner_address);
373379

374-
// CAS owner (null => current thread).
375-
cmpxchg(t2_owner_addr, zr, rthread, Assembler::xword, /*acquire*/ true,
380+
// CAS owner (null => current thread id).
381+
ldr(rscratch2, Address(rthread, JavaThread::lock_id_offset()));
382+
cmpxchg(t2_owner_addr, zr, rscratch2, Assembler::xword, /*acquire*/ true,
376383
/*release*/ false, /*weak*/ false, t3_owner);
377384
br(Assembler::EQ, monitor_locked);
378385

379386
// Check if recursive.
380-
cmp(t3_owner, rthread);
387+
cmp(t3_owner, rscratch2);
381388
br(Assembler::NE, slow_path);
382389

383390
// Recursive.
@@ -390,7 +397,6 @@ void C2_MacroAssembler::fast_lock_lightweight(Register obj, Register box, Regist
390397
}
391398

392399
bind(locked);
393-
increment(Address(rthread, JavaThread::held_monitor_count_offset()));
394400

395401
#ifdef ASSERT
396402
// Check that locked label is reached with Flags == EQ.
@@ -559,7 +565,6 @@ void C2_MacroAssembler::fast_unlock_lightweight(Register obj, Register box, Regi
559565
}
560566

561567
bind(unlocked);
562-
decrement(Address(rthread, JavaThread::held_monitor_count_offset()));
563568
cmp(zr, zr); // Set Flags to EQ => fast path
564569

565570
#ifdef ASSERT

src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,7 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg)
697697

698698
if (LockingMode == LM_LIGHTWEIGHT) {
699699
lightweight_lock(lock_reg, obj_reg, tmp, tmp2, tmp3, slow_case);
700-
b(count);
700+
b(done);
701701
} else if (LockingMode == LM_LEGACY) {
702702
// Load (object->mark() | 1) into swap_reg
703703
ldr(rscratch1, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
@@ -747,18 +747,18 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg)
747747

748748
// Save the test result, for recursive case, the result is zero
749749
str(swap_reg, Address(lock_reg, mark_offset));
750-
br(Assembler::EQ, count);
750+
br(Assembler::NE, slow_case);
751+
752+
bind(count);
753+
inc_held_monitor_count();
754+
b(done);
751755
}
752756
bind(slow_case);
753757

754758
// Call the runtime routine for slow case
755759
call_VM(noreg,
756760
CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
757761
lock_reg);
758-
b(done);
759-
760-
bind(count);
761-
increment(Address(rthread, JavaThread::held_monitor_count_offset()));
762762

763763
bind(done);
764764
}
@@ -804,11 +804,10 @@ void InterpreterMacroAssembler::unlock_object(Register lock_reg)
804804
// Free entry
805805
str(zr, Address(lock_reg, BasicObjectLock::obj_offset()));
806806

807+
Label slow_case;
807808
if (LockingMode == LM_LIGHTWEIGHT) {
808-
Label slow_case;
809809
lightweight_unlock(obj_reg, header_reg, swap_reg, tmp_reg, slow_case);
810-
b(count);
811-
bind(slow_case);
810+
b(done);
812811
} else if (LockingMode == LM_LEGACY) {
813812
// Load the old header from BasicLock structure
814813
ldr(header_reg, Address(swap_reg,
@@ -818,16 +817,17 @@ void InterpreterMacroAssembler::unlock_object(Register lock_reg)
818817
cbz(header_reg, count);
819818

820819
// Atomic swap back the old header
821-
cmpxchg_obj_header(swap_reg, header_reg, obj_reg, rscratch1, count, /*fallthrough*/nullptr);
820+
cmpxchg_obj_header(swap_reg, header_reg, obj_reg, rscratch1, count, &slow_case);
821+
822+
bind(count);
823+
dec_held_monitor_count();
824+
b(done);
822825
}
826+
827+
bind(slow_case);
823828
// Call the runtime routine for slow case.
824829
str(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset())); // restore obj
825830
call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg);
826-
b(done);
827-
828-
bind(count);
829-
decrement(Address(rthread, JavaThread::held_monitor_count_offset()));
830-
831831
bind(done);
832832
restore_bcp();
833833
}

src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "gc/shared/tlab_globals.hpp"
4040
#include "interpreter/bytecodeHistogram.hpp"
4141
#include "interpreter/interpreter.hpp"
42+
#include "interpreter/interpreterRuntime.hpp"
4243
#include "jvm.h"
4344
#include "memory/resourceArea.hpp"
4445
#include "memory/universe.hpp"
@@ -5327,6 +5328,38 @@ void MacroAssembler::tlab_allocate(Register obj,
53275328
bs->tlab_allocate(this, obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
53285329
}
53295330

5331+
void MacroAssembler::inc_held_monitor_count() {
5332+
Address dst = Address(rthread, JavaThread::held_monitor_count_offset());
5333+
#ifdef ASSERT
5334+
ldr(rscratch2, dst);
5335+
increment(rscratch2);
5336+
str(rscratch2, dst);
5337+
Label ok;
5338+
tbz(rscratch2, 63, ok);
5339+
STOP("assert(held monitor count underflow)");
5340+
should_not_reach_here();
5341+
bind(ok);
5342+
#else
5343+
increment(dst);
5344+
#endif
5345+
}
5346+
5347+
void MacroAssembler::dec_held_monitor_count() {
5348+
Address dst = Address(rthread, JavaThread::held_monitor_count_offset());
5349+
#ifdef ASSERT
5350+
ldr(rscratch2, dst);
5351+
decrement(rscratch2);
5352+
str(rscratch2, dst);
5353+
Label ok;
5354+
tbz(rscratch2, 63, ok);
5355+
STOP("assert(held monitor count underflow)");
5356+
should_not_reach_here();
5357+
bind(ok);
5358+
#else
5359+
decrement(dst);
5360+
#endif
5361+
}
5362+
53305363
void MacroAssembler::verify_tlab() {
53315364
#ifdef ASSERT
53325365
if (UseTLAB && VerifyOops) {

src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -940,6 +940,8 @@ class MacroAssembler: public Assembler {
940940

941941
void push_cont_fastpath(Register java_thread);
942942
void pop_cont_fastpath(Register java_thread);
943+
void inc_held_monitor_count();
944+
void dec_held_monitor_count();
943945

944946
// Round up to a power of two
945947
void round_to(Register reg, int modulus);

src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1816,12 +1816,13 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
18161816
// Save the test result, for recursive case, the result is zero
18171817
__ str(swap_reg, Address(lock_reg, mark_word_offset));
18181818
__ br(Assembler::NE, slow_path_lock);
1819+
1820+
__ bind(count);
1821+
__ inc_held_monitor_count();
18191822
} else {
18201823
assert(LockingMode == LM_LIGHTWEIGHT, "must be");
18211824
__ lightweight_lock(lock_reg, obj_reg, swap_reg, tmp, lock_tmp, slow_path_lock);
18221825
}
1823-
__ bind(count);
1824-
__ increment(Address(rthread, JavaThread::held_monitor_count_offset()));
18251826

18261827
// Slow path will re-enter here
18271828
__ bind(lock_done);
@@ -1926,7 +1927,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
19261927
// Simple recursive lock?
19271928
__ ldr(rscratch1, Address(sp, lock_slot_offset * VMRegImpl::stack_slot_size));
19281929
__ cbnz(rscratch1, not_recursive);
1929-
__ decrement(Address(rthread, JavaThread::held_monitor_count_offset()));
1930+
__ dec_held_monitor_count();
19301931
__ b(done);
19311932
}
19321933

@@ -1949,11 +1950,10 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
19491950
Label count;
19501951
__ cmpxchg_obj_header(r0, old_hdr, obj_reg, rscratch1, count, &slow_path_unlock);
19511952
__ bind(count);
1952-
__ decrement(Address(rthread, JavaThread::held_monitor_count_offset()));
1953+
__ dec_held_monitor_count();
19531954
} else {
19541955
assert(LockingMode == LM_LIGHTWEIGHT, "");
19551956
__ lightweight_unlock(obj_reg, old_hdr, swap_reg, lock_tmp, slow_path_unlock);
1956-
__ decrement(Address(rthread, JavaThread::held_monitor_count_offset()));
19571957
}
19581958

19591959
// slow path re-enters here

src/hotspot/cpu/ppc/macroAssembler_ppc.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2625,10 +2625,12 @@ void MacroAssembler::compiler_fast_lock_object(ConditionRegister flag, Register
26252625

26262626
// Try to CAS m->owner from null to current thread.
26272627
addi(temp, displaced_header, in_bytes(ObjectMonitor::owner_offset()) - markWord::monitor_value);
2628+
Register thread_id = displaced_header;
2629+
ld(thread_id, in_bytes(JavaThread::lock_id_offset()), R16_thread);
26282630
cmpxchgd(/*flag=*/flag,
26292631
/*current_value=*/current_header,
26302632
/*compare_value=*/(intptr_t)0,
2631-
/*exchange_value=*/R16_thread,
2633+
/*exchange_value=*/thread_id,
26322634
/*where=*/temp,
26332635
MacroAssembler::MemBarRel | MacroAssembler::MemBarAcq,
26342636
MacroAssembler::cmpxchgx_hint_acquire_lock());
@@ -2638,7 +2640,7 @@ void MacroAssembler::compiler_fast_lock_object(ConditionRegister flag, Register
26382640
beq(flag, success);
26392641

26402642
// Check for recursive locking.
2641-
cmpd(flag, current_header, R16_thread);
2643+
cmpd(flag, current_header, thread_id);
26422644
bne(flag, failure);
26432645

26442646
// Current thread already owns the lock. Just increment recursions.
@@ -2895,18 +2897,20 @@ void MacroAssembler::compiler_fast_lock_lightweight_object(ConditionRegister fla
28952897
addi(owner_addr, monitor, in_bytes(ObjectMonitor::owner_offset()));
28962898
}
28972899

2898-
// CAS owner (null => current thread).
2900+
// CAS owner (null => current thread id).
2901+
Register thread_id = tmp1;
2902+
ld(thread_id, in_bytes(JavaThread::lock_id_offset()), R16_thread);
28992903
cmpxchgd(/*flag=*/CCR0,
29002904
/*current_value=*/t,
29012905
/*compare_value=*/(intptr_t)0,
2902-
/*exchange_value=*/R16_thread,
2906+
/*exchange_value=*/thread_id,
29032907
/*where=*/owner_addr,
29042908
MacroAssembler::MemBarRel | MacroAssembler::MemBarAcq,
29052909
MacroAssembler::cmpxchgx_hint_acquire_lock());
29062910
beq(CCR0, monitor_locked);
29072911

29082912
// Check if recursive.
2909-
cmpd(CCR0, t, R16_thread);
2913+
cmpd(CCR0, t, thread_id);
29102914
bne(CCR0, slow_path);
29112915

29122916
// Recursive.

src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,8 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr
8383
// displaced header address in the object header - if it is not the same, get the
8484
// object header instead
8585
la(temp, Address(obj, hdr_offset));
86-
cmpxchgptr(hdr, disp_hdr, temp, t1, done, /*fallthough*/nullptr);
8786
// if the object header was the same, we're done
87+
cmpxchgptr(hdr, disp_hdr, temp, t1, done, /*fallthough*/nullptr);
8888
// if the object header was not the same, it is now in the hdr register
8989
// => test if it is a stack pointer into the same stack (recursive locking), i.e.:
9090
//
@@ -106,11 +106,12 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr
106106
sd(hdr, Address(disp_hdr, 0));
107107
// otherwise we don't care about the result and handle locking via runtime call
108108
bnez(hdr, slow_case, /* is_far */ true);
109+
109110
// done
110111
bind(done);
112+
inc_held_monitor_count();
111113
}
112114

113-
increment(Address(xthread, JavaThread::held_monitor_count_offset()));
114115
return null_check_offset;
115116
}
116117

@@ -146,11 +147,11 @@ void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_
146147
} else {
147148
cmpxchgptr(disp_hdr, hdr, obj, t1, done, &slow_case);
148149
}
150+
149151
// done
150152
bind(done);
153+
dec_held_monitor_count();
151154
}
152-
153-
decrement(Address(xthread, JavaThread::held_monitor_count_offset()));
154155
}
155156

156157
// Defines obj, preserves var_size_in_bytes

src/hotspot/cpu/riscv/c2_CodeStubs_riscv.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,3 @@ void C2EntryBarrierStub::emit(C2_MacroAssembler& masm) {
7070
__ relocate(entry_guard_Relocation::spec());
7171
__ emit_int32(0); // nmethod guard value
7272
}
73-
74-
#undef __

0 commit comments

Comments
 (0)