Skip to content

Commit 26bda6d

Browse files
xmas92fiskstefankcoleenp
authored andcommitted
8315884: New Object to ObjectMonitor mapping
Co-authored-by: Erik Österlund <eosterlund@openjdk.org> Co-authored-by: Stefan Karlsson <stefank@openjdk.org> Co-authored-by: Coleen Phillimore <coleenp@openjdk.org> Reviewed-by: rkennke, coleenp, dcubed
1 parent 84d82a1 commit 26bda6d

File tree

68 files changed

+3284
-911
lines changed

Some content is hidden

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

68 files changed

+3284
-911
lines changed

src/hotspot/cpu/aarch64/aarch64.ad

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15793,7 +15793,7 @@ instruct cmpFastLockLightweight(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp
1579315793
format %{ "fastlock $object,$box\t! kills $tmp,$tmp2,$tmp3" %}
1579415794

1579515795
ins_encode %{
15796-
__ fast_lock_lightweight($object$$Register, $tmp$$Register, $tmp2$$Register, $tmp3$$Register);
15796+
__ fast_lock_lightweight($object$$Register, $box$$Register, $tmp$$Register, $tmp2$$Register, $tmp3$$Register);
1579715797
%}
1579815798

1579915799
ins_pipe(pipe_serial);
@@ -15809,7 +15809,7 @@ instruct cmpFastUnlockLightweight(rFlagsReg cr, iRegP object, iRegP box, iRegPNo
1580915809
format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2, $tmp3" %}
1581015810

1581115811
ins_encode %{
15812-
__ fast_unlock_lightweight($object$$Register, $tmp$$Register, $tmp2$$Register, $tmp3$$Register);
15812+
__ fast_unlock_lightweight($object$$Register, $box$$Register, $tmp$$Register, $tmp2$$Register, $tmp3$$Register);
1581315813
%}
1581415814

1581515815
ins_pipe(pipe_serial);

src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr
8181
}
8282

8383
if (LockingMode == LM_LIGHTWEIGHT) {
84-
lightweight_lock(obj, hdr, temp, rscratch2, slow_case);
84+
lightweight_lock(disp_hdr, obj, hdr, temp, rscratch2, slow_case);
8585
} else if (LockingMode == LM_LEGACY) {
8686
Label done;
8787
// Load object header

src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp

Lines changed: 84 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -224,10 +224,10 @@ void C2_MacroAssembler::fast_unlock(Register objectReg, Register boxReg, Registe
224224
bind(no_count);
225225
}
226226

227-
void C2_MacroAssembler::fast_lock_lightweight(Register obj, Register t1,
227+
void C2_MacroAssembler::fast_lock_lightweight(Register obj, Register box, Register t1,
228228
Register t2, Register t3) {
229229
assert(LockingMode == LM_LIGHTWEIGHT, "must be");
230-
assert_different_registers(obj, t1, t2, t3);
230+
assert_different_registers(obj, box, t1, t2, t3);
231231

232232
// Handle inflated monitor.
233233
Label inflated;
@@ -236,6 +236,11 @@ void C2_MacroAssembler::fast_lock_lightweight(Register obj, Register t1,
236236
// Finish fast lock unsuccessfully. MUST branch to with flag == NE
237237
Label slow_path;
238238

239+
if (UseObjectMonitorTable) {
240+
// Clear cache in case fast locking succeeds.
241+
str(zr, Address(box, BasicLock::object_monitor_cache_offset_in_bytes()));
242+
}
243+
239244
if (DiagnoseSyncOnValueBasedClasses != 0) {
240245
load_klass(t1, obj);
241246
ldrw(t1, Address(t1, Klass::access_flags_offset()));
@@ -244,14 +249,14 @@ void C2_MacroAssembler::fast_lock_lightweight(Register obj, Register t1,
244249
}
245250

246251
const Register t1_mark = t1;
252+
const Register t3_t = t3;
247253

248254
{ // Lightweight locking
249255

250256
// Push lock to the lock stack and finish successfully. MUST branch to with flag == EQ
251257
Label push;
252258

253259
const Register t2_top = t2;
254-
const Register t3_t = t3;
255260

256261
// Check if lock-stack is full.
257262
ldrw(t2_top, Address(rthread, JavaThread::lock_stack_top_offset()));
@@ -289,26 +294,71 @@ void C2_MacroAssembler::fast_lock_lightweight(Register obj, Register t1,
289294
{ // Handle inflated monitor.
290295
bind(inflated);
291296

292-
// mark contains the tagged ObjectMonitor*.
293-
const Register t1_tagged_monitor = t1_mark;
294-
const uintptr_t monitor_tag = markWord::monitor_value;
297+
const Register t1_monitor = t1;
298+
299+
if (!UseObjectMonitorTable) {
300+
assert(t1_monitor == t1_mark, "should be the same here");
301+
} else {
302+
Label monitor_found;
303+
304+
// Load cache address
305+
lea(t3_t, Address(rthread, JavaThread::om_cache_oops_offset()));
306+
307+
const int num_unrolled = 2;
308+
for (int i = 0; i < num_unrolled; i++) {
309+
ldr(t1, Address(t3_t));
310+
cmp(obj, t1);
311+
br(Assembler::EQ, monitor_found);
312+
increment(t3_t, in_bytes(OMCache::oop_to_oop_difference()));
313+
}
314+
315+
Label loop;
316+
317+
// Search for obj in cache.
318+
bind(loop);
319+
320+
// Check for match.
321+
ldr(t1, Address(t3_t));
322+
cmp(obj, t1);
323+
br(Assembler::EQ, monitor_found);
324+
325+
// Search until null encountered, guaranteed _null_sentinel at end.
326+
increment(t3_t, in_bytes(OMCache::oop_to_oop_difference()));
327+
cbnz(t1, loop);
328+
// Cache Miss, NE set from cmp above, cbnz does not set flags
329+
b(slow_path);
330+
331+
bind(monitor_found);
332+
ldr(t1_monitor, Address(t3_t, OMCache::oop_to_monitor_difference()));
333+
}
334+
295335
const Register t2_owner_addr = t2;
296336
const Register t3_owner = t3;
337+
const ByteSize monitor_tag = in_ByteSize(UseObjectMonitorTable ? 0 : checked_cast<int>(markWord::monitor_value));
338+
const Address owner_address(t1_monitor, ObjectMonitor::owner_offset() - monitor_tag);
339+
const Address recursions_address(t1_monitor, ObjectMonitor::recursions_offset() - monitor_tag);
340+
341+
Label monitor_locked;
297342

298343
// Compute owner address.
299-
lea(t2_owner_addr, Address(t1_tagged_monitor, (in_bytes(ObjectMonitor::owner_offset()) - monitor_tag)));
344+
lea(t2_owner_addr, owner_address);
300345

301346
// CAS owner (null => current thread).
302347
cmpxchg(t2_owner_addr, zr, rthread, Assembler::xword, /*acquire*/ true,
303348
/*release*/ false, /*weak*/ false, t3_owner);
304-
br(Assembler::EQ, locked);
349+
br(Assembler::EQ, monitor_locked);
305350

306351
// Check if recursive.
307352
cmp(t3_owner, rthread);
308353
br(Assembler::NE, slow_path);
309354

310355
// Recursive.
311-
increment(Address(t1_tagged_monitor, in_bytes(ObjectMonitor::recursions_offset()) - monitor_tag), 1);
356+
increment(recursions_address, 1);
357+
358+
bind(monitor_locked);
359+
if (UseObjectMonitorTable) {
360+
str(t1_monitor, Address(box, BasicLock::object_monitor_cache_offset_in_bytes()));
361+
}
312362
}
313363

314364
bind(locked);
@@ -331,13 +381,13 @@ void C2_MacroAssembler::fast_lock_lightweight(Register obj, Register t1,
331381
// C2 uses the value of Flags (NE vs EQ) to determine the continuation.
332382
}
333383

334-
void C2_MacroAssembler::fast_unlock_lightweight(Register obj, Register t1, Register t2,
335-
Register t3) {
384+
void C2_MacroAssembler::fast_unlock_lightweight(Register obj, Register box, Register t1,
385+
Register t2, Register t3) {
336386
assert(LockingMode == LM_LIGHTWEIGHT, "must be");
337-
assert_different_registers(obj, t1, t2, t3);
387+
assert_different_registers(obj, box, t1, t2, t3);
338388

339389
// Handle inflated monitor.
340-
Label inflated, inflated_load_monitor;
390+
Label inflated, inflated_load_mark;
341391
// Finish fast unlock successfully. MUST branch to with flag == EQ
342392
Label unlocked;
343393
// Finish fast unlock unsuccessfully. MUST branch to with flag == NE
@@ -349,13 +399,15 @@ void C2_MacroAssembler::fast_unlock_lightweight(Register obj, Register t1, Regis
349399

350400
{ // Lightweight unlock
351401

402+
Label push_and_slow_path;
403+
352404
// Check if obj is top of lock-stack.
353405
ldrw(t2_top, Address(rthread, JavaThread::lock_stack_top_offset()));
354406
subw(t2_top, t2_top, oopSize);
355407
ldr(t3_t, Address(rthread, t2_top));
356408
cmp(obj, t3_t);
357409
// Top of lock stack was not obj. Must be monitor.
358-
br(Assembler::NE, inflated_load_monitor);
410+
br(Assembler::NE, inflated_load_mark);
359411

360412
// Pop lock-stack.
361413
DEBUG_ONLY(str(zr, Address(rthread, t2_top));)
@@ -372,7 +424,10 @@ void C2_MacroAssembler::fast_unlock_lightweight(Register obj, Register t1, Regis
372424
ldr(t1_mark, Address(obj, oopDesc::mark_offset_in_bytes()));
373425

374426
// Check header for monitor (0b10).
375-
tbnz(t1_mark, exact_log2(markWord::monitor_value), inflated);
427+
// Because we got here by popping (meaning we pushed in locked)
428+
// there will be no monitor in the box. So we need to push back the obj
429+
// so that the runtime can fix any potential anonymous owner.
430+
tbnz(t1_mark, exact_log2(markWord::monitor_value), UseObjectMonitorTable ? push_and_slow_path : inflated);
376431

377432
// Try to unlock. Transition lock bits 0b00 => 0b01
378433
assert(oopDesc::mark_offset_in_bytes() == 0, "required to avoid lea");
@@ -381,6 +436,7 @@ void C2_MacroAssembler::fast_unlock_lightweight(Register obj, Register t1, Regis
381436
/*acquire*/ false, /*release*/ true, /*weak*/ false, noreg);
382437
br(Assembler::EQ, unlocked);
383438

439+
bind(push_and_slow_path);
384440
// Compare and exchange failed.
385441
// Restore lock-stack and handle the unlock in runtime.
386442
DEBUG_ONLY(str(obj, Address(rthread, t2_top));)
@@ -391,7 +447,7 @@ void C2_MacroAssembler::fast_unlock_lightweight(Register obj, Register t1, Regis
391447

392448

393449
{ // Handle inflated monitor.
394-
bind(inflated_load_monitor);
450+
bind(inflated_load_mark);
395451
ldr(t1_mark, Address(obj, oopDesc::mark_offset_in_bytes()));
396452
#ifdef ASSERT
397453
tbnz(t1_mark, exact_log2(markWord::monitor_value), inflated);
@@ -412,12 +468,19 @@ void C2_MacroAssembler::fast_unlock_lightweight(Register obj, Register t1, Regis
412468
bind(check_done);
413469
#endif
414470

415-
// mark contains the tagged ObjectMonitor*.
416-
const Register t1_monitor = t1_mark;
417-
const uintptr_t monitor_tag = markWord::monitor_value;
471+
const Register t1_monitor = t1;
472+
473+
if (!UseObjectMonitorTable) {
474+
assert(t1_monitor == t1_mark, "should be the same here");
418475

419-
// Untag the monitor.
420-
sub(t1_monitor, t1_mark, monitor_tag);
476+
// Untag the monitor.
477+
add(t1_monitor, t1_mark, -(int)markWord::monitor_value);
478+
} else {
479+
ldr(t1_monitor, Address(box, BasicLock::object_monitor_cache_offset_in_bytes()));
480+
// null check with Flags == NE, no valid pointer below alignof(ObjectMonitor*)
481+
cmp(t1_monitor, checked_cast<uint8_t>(alignof(ObjectMonitor*)));
482+
br(Assembler::LO, slow_path);
483+
}
421484

422485
const Register t2_recursions = t2;
423486
Label not_recursive;

src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@
3939
void fast_lock(Register object, Register box, Register tmp, Register tmp2, Register tmp3);
4040
void fast_unlock(Register object, Register box, Register tmp, Register tmp2);
4141
// Code used by cmpFastLockLightweight and cmpFastUnlockLightweight mach instructions in .ad file.
42-
void fast_lock_lightweight(Register object, Register t1, Register t2, Register t3);
43-
void fast_unlock_lightweight(Register object, Register t1, Register t2, Register t3);
42+
void fast_lock_lightweight(Register object, Register box, Register t1, Register t2, Register t3);
43+
void fast_unlock_lightweight(Register object, Register box, Register t1, Register t2, Register t3);
4444

4545
void string_compare(Register str1, Register str2,
4646
Register cnt1, Register cnt2, Register result,

src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,7 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg)
696696
}
697697

698698
if (LockingMode == LM_LIGHTWEIGHT) {
699-
lightweight_lock(obj_reg, tmp, tmp2, tmp3, slow_case);
699+
lightweight_lock(lock_reg, obj_reg, tmp, tmp2, tmp3, slow_case);
700700
b(count);
701701
} else if (LockingMode == LM_LEGACY) {
702702
// Load (object->mark() | 1) into swap_reg
@@ -752,15 +752,9 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg)
752752
bind(slow_case);
753753

754754
// Call the runtime routine for slow case
755-
if (LockingMode == LM_LIGHTWEIGHT) {
756-
call_VM(noreg,
757-
CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter_obj),
758-
obj_reg);
759-
} else {
760-
call_VM(noreg,
761-
CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
762-
lock_reg);
763-
}
755+
call_VM(noreg,
756+
CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
757+
lock_reg);
764758
b(done);
765759

766760
bind(count);

src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6750,9 +6750,9 @@ void MacroAssembler::double_move(VMRegPair src, VMRegPair dst, Register tmp) {
67506750
// - obj: the object to be locked
67516751
// - t1, t2, t3: temporary registers, will be destroyed
67526752
// - slow: branched to if locking fails, absolute offset may larger than 32KB (imm14 encoding).
6753-
void MacroAssembler::lightweight_lock(Register obj, Register t1, Register t2, Register t3, Label& slow) {
6753+
void MacroAssembler::lightweight_lock(Register basic_lock, Register obj, Register t1, Register t2, Register t3, Label& slow) {
67546754
assert(LockingMode == LM_LIGHTWEIGHT, "only used with new lightweight locking");
6755-
assert_different_registers(obj, t1, t2, t3, rscratch1);
6755+
assert_different_registers(basic_lock, obj, t1, t2, t3, rscratch1);
67566756

67576757
Label push;
67586758
const Register top = t1;
@@ -6763,6 +6763,11 @@ void MacroAssembler::lightweight_lock(Register obj, Register t1, Register t2, Re
67636763
// instruction emitted as it is part of C1's null check semantics.
67646764
ldr(mark, Address(obj, oopDesc::mark_offset_in_bytes()));
67656765

6766+
if (UseObjectMonitorTable) {
6767+
// Clear cache in case fast locking succeeds.
6768+
str(zr, Address(basic_lock, BasicObjectLock::lock_offset() + in_ByteSize((BasicLock::object_monitor_cache_offset_in_bytes()))));
6769+
}
6770+
67666771
// Check if the lock-stack is full.
67676772
ldrw(top, Address(rthread, JavaThread::lock_stack_top_offset()));
67686773
cmpw(top, (unsigned)LockStack::end_offset());

src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1639,7 +1639,7 @@ class MacroAssembler: public Assembler {
16391639
// Code for java.lang.Thread::onSpinWait() intrinsic.
16401640
void spin_wait();
16411641

1642-
void lightweight_lock(Register obj, Register t1, Register t2, Register t3, Label& slow);
1642+
void lightweight_lock(Register basic_lock, Register obj, Register t1, Register t2, Register t3, Label& slow);
16431643
void lightweight_unlock(Register obj, Register t1, Register t2, Register t3, Label& slow);
16441644

16451645
private:

src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1811,7 +1811,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
18111811
__ br(Assembler::NE, slow_path_lock);
18121812
} else {
18131813
assert(LockingMode == LM_LIGHTWEIGHT, "must be");
1814-
__ lightweight_lock(obj_reg, swap_reg, tmp, lock_tmp, slow_path_lock);
1814+
__ lightweight_lock(lock_reg, obj_reg, swap_reg, tmp, lock_tmp, slow_path_lock);
18151815
}
18161816
__ bind(count);
18171817
__ increment(Address(rthread, JavaThread::held_monitor_count_offset()));

src/hotspot/cpu/arm/interp_masm_arm.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -985,15 +985,7 @@ void InterpreterMacroAssembler::lock_object(Register Rlock) {
985985
bind(slow_case);
986986

987987
// Call the runtime routine for slow case
988-
if (LockingMode == LM_LIGHTWEIGHT) {
989-
// Pass oop, not lock, in fast lock case. call_VM wants R1 though.
990-
push(R1);
991-
mov(R1, Robj);
992-
call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter_obj), R1);
993-
pop(R1);
994-
} else {
995-
call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter), Rlock);
996-
}
988+
call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter), Rlock);
997989
bind(done);
998990
}
999991
}

src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,11 +1043,7 @@ void InterpreterMacroAssembler::lock_object(Register monitor, Register object) {
10431043
// None of the above fast optimizations worked so we have to get into the
10441044
// slow case of monitor enter.
10451045
bind(slow_case);
1046-
if (LockingMode == LM_LIGHTWEIGHT) {
1047-
call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter_obj), object);
1048-
} else {
1049-
call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter), monitor);
1050-
}
1046+
call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter), monitor);
10511047
b(done);
10521048
// }
10531049
align(32, 12);

0 commit comments

Comments
 (0)