Skip to content

Commit 8282832

Browse files
zifeihanpull[bot]
authored andcommitted
8320280: RISC-V: Avoid passing t0 as temp register to MacroAssembler::lightweight_lock/unlock
Reviewed-by: fyang, rehn
1 parent fc3dea8 commit 8282832

10 files changed

+52
-43
lines changed

src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ int LIR_Assembler::emit_unwind_handler() {
363363
if (LockingMode == LM_MONITOR) {
364364
__ j(*stub->entry());
365365
} else {
366-
__ unlock_object(x15, x14, x10, *stub->entry());
366+
__ unlock_object(x15, x14, x10, x16, *stub->entry());
367367
}
368368
__ bind(*stub->continuation());
369369
}
@@ -1512,6 +1512,7 @@ void LIR_Assembler::emit_lock(LIR_OpLock* op) {
15121512
Register obj = op->obj_opr()->as_register(); // may not be an oop
15131513
Register hdr = op->hdr_opr()->as_register();
15141514
Register lock = op->lock_opr()->as_register();
1515+
Register temp = op->scratch_opr()->as_register();
15151516
if (LockingMode == LM_MONITOR) {
15161517
if (op->info() != nullptr) {
15171518
add_debug_info_for_null_check_here(op->info());
@@ -1521,13 +1522,13 @@ void LIR_Assembler::emit_lock(LIR_OpLock* op) {
15211522
} else if (op->code() == lir_lock) {
15221523
assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
15231524
// add debug info for NullPointerException only if one is possible
1524-
int null_check_offset = __ lock_object(hdr, obj, lock, *op->stub()->entry());
1525+
int null_check_offset = __ lock_object(hdr, obj, lock, temp, *op->stub()->entry());
15251526
if (op->info() != nullptr) {
15261527
add_debug_info_for_null_check(null_check_offset, op->info());
15271528
}
15281529
} else if (op->code() == lir_unlock) {
15291530
assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
1530-
__ unlock_object(hdr, obj, lock, *op->stub()->entry());
1531+
__ unlock_object(hdr, obj, lock, temp, *op->stub()->entry());
15311532
} else {
15321533
Unimplemented();
15331534
}

src/hotspot/cpu/riscv/c1_LIRGenerator_riscv.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ void LIRGenerator::do_MonitorEnter(MonitorEnter* x) {
274274

275275
// "lock" stores the address of the monitor stack slot, so this is not an oop
276276
LIR_Opr lock = new_register(T_INT);
277+
LIR_Opr scratch = new_register(T_INT);
277278

278279
CodeEmitInfo* info_for_exception = nullptr;
279280
if (x->needs_null_check()) {
@@ -282,7 +283,7 @@ void LIRGenerator::do_MonitorEnter(MonitorEnter* x) {
282283
// this CodeEmitInfo must not have the xhandlers because here the
283284
// object is already locked (xhandlers expect object to be unlocked)
284285
CodeEmitInfo* info = state_for(x, x->state(), true);
285-
monitor_enter(obj.result(), lock, syncTempOpr(), LIR_OprFact::illegalOpr,
286+
monitor_enter(obj.result(), lock, syncTempOpr(), scratch,
286287
x->monitor_no(), info_for_exception, info);
287288
}
288289

@@ -294,8 +295,9 @@ void LIRGenerator::do_MonitorExit(MonitorExit* x) {
294295

295296
LIR_Opr lock = new_register(T_INT);
296297
LIR_Opr obj_temp = new_register(T_INT);
298+
LIR_Opr scratch = new_register(T_INT);
297299
set_no_result(x);
298-
monitor_exit(obj_temp, lock, syncTempOpr(), LIR_OprFact::illegalOpr, x->monitor_no());
300+
monitor_exit(obj_temp, lock, syncTempOpr(), scratch, x->monitor_no());
299301
}
300302

301303
// neg

src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.cpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ void C1_MacroAssembler::float_cmp(bool is_float, int unordered_result,
4949
}
5050
}
5151

52-
int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) {
52+
int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Register temp, Label& slow_case) {
5353
const int aligned_mask = BytesPerWord - 1;
5454
const int hdr_offset = oopDesc::mark_offset_in_bytes();
55-
assert_different_registers(hdr, obj, disp_hdr);
55+
assert_different_registers(hdr, obj, disp_hdr, temp, t0, t1);
5656
int null_check_offset = -1;
5757

5858
verify_oop(obj);
@@ -65,15 +65,15 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr
6565
if (DiagnoseSyncOnValueBasedClasses != 0) {
6666
load_klass(hdr, obj);
6767
lwu(hdr, Address(hdr, Klass::access_flags_offset()));
68-
test_bit(t0, hdr, exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS));
69-
bnez(t0, slow_case, true /* is_far */);
68+
test_bit(temp, hdr, exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS));
69+
bnez(temp, slow_case, true /* is_far */);
7070
}
7171

7272
// Load object header
7373
ld(hdr, Address(obj, hdr_offset));
7474

7575
if (LockingMode == LM_LIGHTWEIGHT) {
76-
lightweight_lock(obj, hdr, t0, t1, slow_case);
76+
lightweight_lock(obj, hdr, temp, t1, slow_case);
7777
} else if (LockingMode == LM_LEGACY) {
7878
Label done;
7979
// and mark it as unlocked
@@ -83,8 +83,8 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr
8383
// test if object header is still the same (i.e. unlocked), and if so, store the
8484
// displaced header address in the object header - if it is not the same, get the
8585
// object header instead
86-
la(t1, Address(obj, hdr_offset));
87-
cmpxchgptr(hdr, disp_hdr, t1, t0, done, /*fallthough*/nullptr);
86+
la(temp, Address(obj, hdr_offset));
87+
cmpxchgptr(hdr, disp_hdr, temp, t1, done, /*fallthough*/nullptr);
8888
// if the object header was the same, we're done
8989
// if the object header was not the same, it is now in the hdr register
9090
// => test if it is a stack pointer into the same stack (recursive locking), i.e.:
@@ -100,8 +100,8 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr
100100
// assuming both the stack pointer and page_size have their least
101101
// significant 2 bits cleared and page_size is a power of 2
102102
sub(hdr, hdr, sp);
103-
mv(t0, aligned_mask - (int)os::vm_page_size());
104-
andr(hdr, hdr, t0);
103+
mv(temp, aligned_mask - (int)os::vm_page_size());
104+
andr(hdr, hdr, temp);
105105
// for recursive locking, the result is zero => save it in the displaced header
106106
// location (null in the displaced hdr location indicates recursive locking)
107107
sd(hdr, Address(disp_hdr, 0));
@@ -115,10 +115,10 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr
115115
return null_check_offset;
116116
}
117117

118-
void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) {
118+
void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Register temp, Label& slow_case) {
119119
const int aligned_mask = BytesPerWord - 1;
120120
const int hdr_offset = oopDesc::mark_offset_in_bytes();
121-
assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different");
121+
assert_different_registers(hdr, obj, disp_hdr, temp, t0, t1);
122122
Label done;
123123

124124
if (LockingMode != LM_LIGHTWEIGHT) {
@@ -135,18 +135,18 @@ void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_
135135

136136
if (LockingMode == LM_LIGHTWEIGHT) {
137137
ld(hdr, Address(obj, oopDesc::mark_offset_in_bytes()));
138-
test_bit(t0, hdr, exact_log2(markWord::monitor_value));
139-
bnez(t0, slow_case, /* is_far */ true);
140-
lightweight_unlock(obj, hdr, t0, t1, slow_case);
138+
test_bit(temp, hdr, exact_log2(markWord::monitor_value));
139+
bnez(temp, slow_case, /* is_far */ true);
140+
lightweight_unlock(obj, hdr, temp, t1, slow_case);
141141
} else if (LockingMode == LM_LEGACY) {
142142
// test if object header is pointing to the displaced header, and if so, restore
143143
// the displaced header in the object - if the object header is not pointing to
144144
// the displaced header, get the object header instead
145145
// if the object header was not pointing to the displaced header,
146146
// we do unlocking via runtime call
147147
if (hdr_offset) {
148-
la(t0, Address(obj, hdr_offset));
149-
cmpxchgptr(disp_hdr, hdr, t0, t1, done, &slow_case);
148+
la(temp, Address(obj, hdr_offset));
149+
cmpxchgptr(disp_hdr, hdr, temp, t1, done, &slow_case);
150150
} else {
151151
cmpxchgptr(disp_hdr, hdr, obj, t1, done, &slow_case);
152152
}

src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,16 @@ using MacroAssembler::null_check;
5959
// hdr : must be x10, contents destroyed
6060
// obj : must point to the object to lock, contents preserved
6161
// disp_hdr: must point to the displaced header location, contents preserved
62+
// temp : temporary register, must not be scratch register t0 or t1
6263
// returns code offset at which to add null check debug information
63-
int lock_object (Register swap, Register obj, Register disp_hdr, Label& slow_case);
64+
int lock_object(Register swap, Register obj, Register disp_hdr, Register temp, Label& slow_case);
6465

6566
// unlocking
6667
// hdr : contents destroyed
6768
// obj : must point to the object to lock, contents preserved
6869
// disp_hdr: must be x10 & must point to the displaced header location, contents destroyed
69-
void unlock_object(Register swap, Register obj, Register lock, Label& slow_case);
70+
// temp : temporary register, must not be scratch register t0 or t1
71+
void unlock_object(Register swap, Register obj, Register lock, Register temp, Label& slow_case);
7072

7173
void initialize_object(
7274
Register obj, // result: pointer to object after successful allocation

src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@
4343

4444
#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
4545

46-
void C2_MacroAssembler::fast_lock(Register objectReg, Register boxReg, Register tmp1Reg,
47-
Register tmp2Reg) {
46+
void C2_MacroAssembler::fast_lock(Register objectReg, Register boxReg,
47+
Register tmp1Reg, Register tmp2Reg, Register tmp3Reg) {
4848
// Use cr register to indicate the fast_lock result: zero for success; non-zero for failure.
4949
Register flag = t1;
5050
Register oop = objectReg;
@@ -55,7 +55,7 @@ void C2_MacroAssembler::fast_lock(Register objectReg, Register boxReg, Register
5555
Label object_has_monitor;
5656
Label count, no_count;
5757

58-
assert_different_registers(oop, box, tmp, disp_hdr, t0);
58+
assert_different_registers(oop, box, tmp, disp_hdr, flag, tmp3Reg, t0);
5959

6060
// Load markWord from object into displaced_header.
6161
ld(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes()));
@@ -109,7 +109,7 @@ void C2_MacroAssembler::fast_lock(Register objectReg, Register boxReg, Register
109109
} else {
110110
assert(LockingMode == LM_LIGHTWEIGHT, "");
111111
Label slow;
112-
lightweight_lock(oop, disp_hdr, tmp, t0, slow);
112+
lightweight_lock(oop, disp_hdr, tmp, tmp3Reg, slow);
113113

114114
// Indicate success on completion.
115115
mv(flag, zr);
@@ -157,8 +157,8 @@ void C2_MacroAssembler::fast_lock(Register objectReg, Register boxReg, Register
157157
bind(no_count);
158158
}
159159

160-
void C2_MacroAssembler::fast_unlock(Register objectReg, Register boxReg, Register tmp1Reg,
161-
Register tmp2Reg) {
160+
void C2_MacroAssembler::fast_unlock(Register objectReg, Register boxReg,
161+
Register tmp1Reg, Register tmp2Reg) {
162162
// Use cr register to indicate the fast_unlock result: zero for success; non-zero for failure.
163163
Register flag = t1;
164164
Register oop = objectReg;
@@ -169,7 +169,7 @@ void C2_MacroAssembler::fast_unlock(Register objectReg, Register boxReg, Registe
169169
Label object_has_monitor;
170170
Label count, no_count;
171171

172-
assert_different_registers(oop, box, tmp, disp_hdr, flag);
172+
assert_different_registers(oop, box, tmp, disp_hdr, flag, t0);
173173

174174
if (LockingMode == LM_LEGACY) {
175175
// Find the lock address and load the displaced header from the stack.

src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
public:
4646
// Code used by cmpFastLock and cmpFastUnlock mach instructions in .ad file.
4747
// See full description in macroAssembler_riscv.cpp.
48-
void fast_lock(Register object, Register box, Register tmp1, Register tmp2);
48+
void fast_lock(Register object, Register box, Register tmp1, Register tmp2, Register tmp3);
4949
void fast_unlock(Register object, Register box, Register tmp1, Register tmp2);
5050

5151
void string_compare(Register str1, Register str2,

src/hotspot/cpu/riscv/interp_masm_riscv.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,7 @@ void InterpreterMacroAssembler::remove_activation(
727727
//
728728
// Kills:
729729
// x10
730-
// c_rarg0, c_rarg1, c_rarg2, c_rarg3, .. (param regs)
730+
// c_rarg0, c_rarg1, c_rarg2, c_rarg3, c_rarg4, c_rarg5, .. (param regs)
731731
// t0, t1 (temp regs)
732732
void InterpreterMacroAssembler::lock_object(Register lock_reg)
733733
{
@@ -742,6 +742,8 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg)
742742
const Register swap_reg = x10;
743743
const Register tmp = c_rarg2;
744744
const Register obj_reg = c_rarg3; // Will contain the oop
745+
const Register tmp2 = c_rarg4;
746+
const Register tmp3 = c_rarg5;
745747

746748
const int obj_offset = in_bytes(BasicObjectLock::obj_offset());
747749
const int lock_offset = in_bytes(BasicObjectLock::lock_offset());
@@ -762,7 +764,7 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg)
762764

763765
if (LockingMode == LM_LIGHTWEIGHT) {
764766
ld(tmp, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
765-
lightweight_lock(obj_reg, tmp, t0, t1, slow_case);
767+
lightweight_lock(obj_reg, tmp, tmp2, tmp3, slow_case);
766768
j(count);
767769
} else if (LockingMode == LM_LEGACY) {
768770
// Load (object->mark() | 1) into swap_reg
@@ -826,7 +828,7 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg)
826828
//
827829
// Kills:
828830
// x10
829-
// c_rarg0, c_rarg1, c_rarg2, c_rarg3, ... (param regs)
831+
// c_rarg0, c_rarg1, c_rarg2, c_rarg3, c_rarg4, ... (param regs)
830832
// t0, t1 (temp regs)
831833
void InterpreterMacroAssembler::unlock_object(Register lock_reg)
832834
{
@@ -840,6 +842,7 @@ void InterpreterMacroAssembler::unlock_object(Register lock_reg)
840842
const Register swap_reg = x10;
841843
const Register header_reg = c_rarg2; // Will contain the old oopMark
842844
const Register obj_reg = c_rarg3; // Will contain the oop
845+
const Register tmp_reg = c_rarg4; // Temporary used by lightweight_unlock
843846

844847
save_bcp(); // Save in case of exception
845848

@@ -875,7 +878,7 @@ void InterpreterMacroAssembler::unlock_object(Register lock_reg)
875878
ld(header_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
876879
test_bit(t0, header_reg, exact_log2(markWord::monitor_value));
877880
bnez(t0, slow_case);
878-
lightweight_unlock(obj_reg, header_reg, swap_reg, t0, slow_case);
881+
lightweight_unlock(obj_reg, header_reg, swap_reg, tmp_reg, slow_case);
879882
j(count);
880883

881884
bind(slow_case);

src/hotspot/cpu/riscv/macroAssembler_riscv.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4701,7 +4701,7 @@ void MacroAssembler::test_bit(Register Rd, Register Rs, uint32_t bit_pos) {
47014701
// - tmp1, tmp2: temporary registers, will be destroyed
47024702
void MacroAssembler::lightweight_lock(Register obj, Register hdr, Register tmp1, Register tmp2, Label& slow) {
47034703
assert(LockingMode == LM_LIGHTWEIGHT, "only used with new lightweight locking");
4704-
assert_different_registers(obj, hdr, tmp1, tmp2);
4704+
assert_different_registers(obj, hdr, tmp1, tmp2, t0);
47054705

47064706
// Check if we would have space on lock-stack for the object.
47074707
lwu(tmp1, Address(xthread, JavaThread::lock_stack_top_offset()));
@@ -4735,7 +4735,7 @@ void MacroAssembler::lightweight_lock(Register obj, Register hdr, Register tmp1,
47354735
// - tmp1, tmp2: temporary registers
47364736
void MacroAssembler::lightweight_unlock(Register obj, Register hdr, Register tmp1, Register tmp2, Label& slow) {
47374737
assert(LockingMode == LM_LIGHTWEIGHT, "only used with new lightweight locking");
4738-
assert_different_registers(obj, hdr, tmp1, tmp2);
4738+
assert_different_registers(obj, hdr, tmp1, tmp2, t0);
47394739

47404740
#ifdef ASSERT
47414741
{

src/hotspot/cpu/riscv/riscv.ad

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10401,16 +10401,16 @@ instruct tlsLoadP(javaThread_RegP dst)
1040110401

1040210402
// inlined locking and unlocking
1040310403
// using t1 as the 'flag' register to bridge the BoolNode producers and consumers
10404-
instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp1, iRegPNoSp tmp2)
10404+
instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp1, iRegPNoSp tmp2, iRegPNoSp tmp3)
1040510405
%{
1040610406
match(Set cr (FastLock object box));
10407-
effect(TEMP tmp1, TEMP tmp2);
10407+
effect(TEMP tmp1, TEMP tmp2, TEMP tmp3);
1040810408

1040910409
ins_cost(LOAD_COST * 2 + STORE_COST * 3 + ALU_COST * 6 + BRANCH_COST * 3);
10410-
format %{ "fastlock $object,$box\t! kills $tmp1,$tmp2, #@cmpFastLock" %}
10410+
format %{ "fastlock $object,$box\t! kills $tmp1,$tmp2,$tmp3, #@cmpFastLock" %}
1041110411

1041210412
ins_encode %{
10413-
__ fast_lock($object$$Register, $box$$Register, $tmp1$$Register, $tmp2$$Register);
10413+
__ fast_lock($object$$Register, $box$$Register, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register);
1041410414
%}
1041510415

1041610416
ins_pipe(pipe_serial);

src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1648,6 +1648,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
16481648
const Register obj_reg = x9; // Will contain the oop
16491649
const Register lock_reg = x30; // Address of compiler lock object (BasicLock)
16501650
const Register old_hdr = x30; // value of old header at unlock time
1651+
const Register lock_tmp = x31; // Temporary used by lightweight_lock/unlock
16511652
const Register tmp = ra;
16521653

16531654
Label slow_path_lock;
@@ -1699,7 +1700,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
16991700
} else {
17001701
assert(LockingMode == LM_LIGHTWEIGHT, "");
17011702
__ ld(swap_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
1702-
__ lightweight_lock(obj_reg, swap_reg, tmp, t0, slow_path_lock);
1703+
__ lightweight_lock(obj_reg, swap_reg, tmp, lock_tmp, slow_path_lock);
17031704
}
17041705

17051706
__ bind(count);
@@ -1827,7 +1828,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
18271828
__ ld(old_hdr, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
18281829
__ test_bit(t0, old_hdr, exact_log2(markWord::monitor_value));
18291830
__ bnez(t0, slow_path_unlock);
1830-
__ lightweight_unlock(obj_reg, old_hdr, swap_reg, t0, slow_path_unlock);
1831+
__ lightweight_unlock(obj_reg, old_hdr, swap_reg, lock_tmp, slow_path_unlock);
18311832
__ decrement(Address(xthread, JavaThread::held_monitor_count_offset()));
18321833
}
18331834

0 commit comments

Comments
 (0)