Skip to content

Commit

Permalink
Merge branch 'upstream-master'
Browse files Browse the repository at this point in the history
  • Loading branch information
Datadog Syncup Service committed Sep 30, 2024
2 parents e5ce7ca + f1bf469 commit 361f506
Show file tree
Hide file tree
Showing 58 changed files with 3,172 additions and 594 deletions.
72 changes: 54 additions & 18 deletions src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,12 @@ void C2_MacroAssembler::fast_unlock(Register objectReg, Register boxReg, Registe
Register oop = objectReg;
Register box = boxReg;
Register disp_hdr = tmpReg;
Register owner_addr = tmpReg;
Register tmp = tmp2Reg;
Label cont;
Label object_has_monitor;
Label count, no_count;
Label unlocked;

assert(LockingMode != LM_LIGHTWEIGHT, "lightweight locking should use fast_unlock_lightweight");
assert_different_registers(oop, box, tmp, disp_hdr);
Expand Down Expand Up @@ -204,14 +206,40 @@ void C2_MacroAssembler::fast_unlock(Register objectReg, Register boxReg, Registe
b(cont);

bind(notRecursive);

// Compute owner address.
lea(owner_addr, Address(tmp, ObjectMonitor::owner_offset()));

// Set owner to null.
// Release to satisfy the JMM
stlr(zr, owner_addr);
// We need a full fence after clearing owner to avoid stranding.
// StoreLoad achieves this.
membar(StoreLoad);

// Check if the entry lists are empty.
ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset()));
ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset()));
orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0.
cmp(rscratch1, zr); // Sets flags for result
cbnz(rscratch1, cont);
// need a release store here
lea(tmp, Address(tmp, ObjectMonitor::owner_offset()));
stlr(zr, tmp); // set unowned
ldr(tmpReg, Address(tmp, ObjectMonitor::cxq_offset()));
orr(rscratch1, rscratch1, tmpReg);
cmp(rscratch1, zr);
br(Assembler::EQ, cont); // If so we are done.

// Check if there is a successor.
ldr(rscratch1, Address(tmp, ObjectMonitor::succ_offset()));
cmp(rscratch1, zr);
br(Assembler::NE, unlocked); // If so we are done.

// Save the monitor pointer in the current thread, so we can try to
// reacquire the lock in SharedRuntime::monitor_exit_helper().
str(tmp, Address(rthread, JavaThread::unlocked_inflated_monitor_offset()));

cmp(zr, rthread); // Set Flag to NE => slow path
b(cont);

bind(unlocked);
cmp(zr, zr); // Set Flag to EQ => fast path

// Intentional fall-through

bind(cont);
// flag == EQ indicates success
Expand Down Expand Up @@ -498,33 +526,41 @@ void C2_MacroAssembler::fast_unlock_lightweight(Register obj, Register box, Regi

bind(not_recursive);

Label release;
const Register t2_owner_addr = t2;

// Compute owner address.
lea(t2_owner_addr, Address(t1_monitor, ObjectMonitor::owner_offset()));

// Set owner to null.
// Release to satisfy the JMM
stlr(zr, t2_owner_addr);
// We need a full fence after clearing owner to avoid stranding.
// StoreLoad achieves this.
membar(StoreLoad);

// Check if the entry lists are empty.
ldr(rscratch1, Address(t1_monitor, ObjectMonitor::EntryList_offset()));
ldr(t3_t, Address(t1_monitor, ObjectMonitor::cxq_offset()));
orr(rscratch1, rscratch1, t3_t);
cmp(rscratch1, zr);
br(Assembler::EQ, release);
br(Assembler::EQ, unlocked); // If so we are done.

// The owner may be anonymous and we removed the last obj entry in
// the lock-stack. This loses the information about the owner.
// Write the thread to the owner field so the runtime knows the owner.
str(rthread, Address(t2_owner_addr));
b(slow_path);
// Check if there is a successor.
ldr(rscratch1, Address(t1_monitor, ObjectMonitor::succ_offset()));
cmp(rscratch1, zr);
br(Assembler::NE, unlocked); // If so we are done.

bind(release);
// Set owner to null.
// Release to satisfy the JMM
stlr(zr, t2_owner_addr);
// Save the monitor pointer in the current thread, so we can try to
// reacquire the lock in SharedRuntime::monitor_exit_helper().
str(t1_monitor, Address(rthread, JavaThread::unlocked_inflated_monitor_offset()));

cmp(zr, rthread); // Set Flag to NE => slow path
b(slow_path);
}

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

#ifdef ASSERT
// Check that unlocked label is reached with Flags == EQ.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, Dec

__ push(saved_regs, sp);
if (UseCompressedOops) {
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_narrow_oop_entry), src, dst, count);
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_narrow_oop), src, dst, count);
} else {
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_oop_entry), src, dst, count);
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_oop), src, dst, count);
}
__ pop(saved_regs, sp);
__ bind(done);
Expand Down Expand Up @@ -164,9 +164,9 @@ void ShenandoahBarrierSetAssembler::satb_write_barrier_pre(MacroAssembler* masm,

if (expand_call) {
assert(pre_val != c_rarg1, "smashed arg");
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre_entry), pre_val, thread);
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre), pre_val, thread);
} else {
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre_entry), pre_val, thread);
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre), pre_val, thread);
}

__ pop(saved, sp);
Expand Down Expand Up @@ -698,7 +698,7 @@ void ShenandoahBarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAss
__ bind(runtime);
__ push_call_clobbered_registers();
__ load_parameter(0, pre_val);
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre_entry), pre_val, thread);
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre), pre_val, thread);
__ pop_call_clobbered_registers();
__ bind(done);

Expand Down
10 changes: 5 additions & 5 deletions src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3417,15 +3417,15 @@ class StubGenerator: public StubCodeGenerator {
Register rscratch3 = r10;
Register rscratch4 = r11;

__ andw(rscratch3, r2, r4);
__ bicw(rscratch4, r3, r4);
reg_cache.extract_u32(rscratch1, k);
__ movw(rscratch2, t);
__ orrw(rscratch3, rscratch3, rscratch4);
__ addw(rscratch4, r1, rscratch2);
__ addw(rscratch4, rscratch4, rscratch1);
__ addw(rscratch3, rscratch3, rscratch4);
__ rorw(rscratch2, rscratch3, 32 - s);
__ bicw(rscratch2, r3, r4);
__ andw(rscratch3, r2, r4);
__ addw(rscratch2, rscratch2, rscratch4);
__ addw(rscratch2, rscratch2, rscratch3);
__ rorw(rscratch2, rscratch2, 32 - s);
__ addw(r1, rscratch2, r2);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,9 @@ void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler *masm, Dec
// Invoke runtime.
address jrt_address = nullptr;
if (UseCompressedOops) {
jrt_address = CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_narrow_oop_entry);
jrt_address = CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_narrow_oop);
} else {
jrt_address = CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_oop_entry);
jrt_address = CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_oop);
}
assert(jrt_address != nullptr, "jrt routine cannot be found");

Expand Down Expand Up @@ -302,7 +302,7 @@ void ShenandoahBarrierSetAssembler::satb_write_barrier_impl(MacroAssembler *masm
}

// Invoke runtime.
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre_entry), pre_val, R16_thread);
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre), pre_val, R16_thread);

// Restore to-be-preserved registers.
if (!preserve_gp_registers && preloaded_mode && pre_val->is_volatile()) {
Expand Down Expand Up @@ -906,7 +906,7 @@ void ShenandoahBarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAss
__ push_frame_reg_args(nbytes_save, R11_tmp1);

// Invoke runtime.
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre_entry), R0_pre_val, R16_thread);
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre), R0_pre_val, R16_thread);

// Restore to-be-preserved registers.
__ pop_frame();
Expand Down
61 changes: 47 additions & 14 deletions src/hotspot/cpu/ppc/macroAssembler_ppc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2715,13 +2715,34 @@ void MacroAssembler::compiler_fast_unlock_object(ConditionRegister flag, Registe
b(success);

bind(notRecursive);

// Set owner to null.
// Release to satisfy the JMM
release();
li(temp, 0);
std(temp, in_bytes(ObjectMonitor::owner_offset()), current_header);
// We need a full fence after clearing owner to avoid stranding.
// StoreLoad achieves this.
membar(StoreLoad);

// Check if the entry lists are empty.
ld(temp, in_bytes(ObjectMonitor::EntryList_offset()), current_header);
ld(displaced_header, in_bytes(ObjectMonitor::cxq_offset()), current_header);
orr(temp, temp, displaced_header); // Will be 0 if both are 0.
cmpdi(flag, temp, 0);
bne(flag, failure);
release();
std(temp, in_bytes(ObjectMonitor::owner_offset()), current_header);
beq(flag, success); // If so we are done.

// Check if there is a successor.
ld(temp, in_bytes(ObjectMonitor::succ_offset()), current_header);
cmpdi(flag, temp, 0);
bne(flag, success); // If so we are done.

// Save the monitor pointer in the current thread, so we can try
// to reacquire the lock in SharedRuntime::monitor_exit_helper().
std(current_header, in_bytes(JavaThread::unlocked_inflated_monitor_offset()), R16_thread);

crxor(flag, Assembler::equal, flag, Assembler::equal); // Set flag = NE => slow path
b(failure);

// flag == EQ indicates success, decrement held monitor count
// flag == NE indicates failure
Expand Down Expand Up @@ -3028,27 +3049,39 @@ void MacroAssembler::compiler_fast_unlock_lightweight_object(ConditionRegister f

bind(not_recursive);

Label release_;
Label set_eq_unlocked;
const Register t2 = tmp2;

// Set owner to null.
// Release to satisfy the JMM
release();
li(t, 0);
std(t, in_bytes(ObjectMonitor::owner_offset()), monitor);
// We need a full fence after clearing owner to avoid stranding.
// StoreLoad achieves this.
membar(StoreLoad);

// Check if the entry lists are empty.
ld(t, in_bytes(ObjectMonitor::EntryList_offset()), monitor);
ld(t2, in_bytes(ObjectMonitor::cxq_offset()), monitor);
orr(t, t, t2);
cmpdi(CCR0, t, 0);
beq(CCR0, release_);
beq(CCR0, unlocked); // If so we are done.

// The owner may be anonymous and we removed the last obj entry in
// the lock-stack. This loses the information about the owner.
// Write the thread to the owner field so the runtime knows the owner.
std(R16_thread, in_bytes(ObjectMonitor::owner_offset()), monitor);
// Check if there is a successor.
ld(t, in_bytes(ObjectMonitor::succ_offset()), monitor);
cmpdi(CCR0, t, 0);
bne(CCR0, set_eq_unlocked); // If so we are done.

// Save the monitor pointer in the current thread, so we can try
// to reacquire the lock in SharedRuntime::monitor_exit_helper().
std(monitor, in_bytes(JavaThread::unlocked_inflated_monitor_offset()), R16_thread);

crxor(CCR0, Assembler::equal, CCR0, Assembler::equal); // Set flag = NE => slow path
b(slow_path);

bind(release_);
// Set owner to null.
release();
// t contains 0
std(t, in_bytes(ObjectMonitor::owner_offset()), monitor);
bind(set_eq_unlocked);
crorc(CCR0, Assembler::equal, CCR0, Assembler::equal); // Set flag = EQ => fast path
}

bind(unlocked);
Expand Down
62 changes: 44 additions & 18 deletions src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ void C2_MacroAssembler::fast_unlock(Register objectReg, Register boxReg,
Register oop = objectReg;
Register box = boxReg;
Register disp_hdr = tmp1Reg;
Register owner_addr = tmp1Reg;
Register tmp = tmp2Reg;
Label object_has_monitor;
// Finish fast lock successfully. MUST branch to with flag == 0
Expand Down Expand Up @@ -222,15 +223,33 @@ void C2_MacroAssembler::fast_unlock(Register objectReg, Register boxReg,
j(unlocked);

bind(notRecursive);
ld(t0, Address(tmp, ObjectMonitor::EntryList_offset()));
ld(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset()));
orr(t0, t0, disp_hdr); // Will be 0 if both are 0.
bnez(t0, slow_path);
// Compute owner address.
la(owner_addr, Address(tmp, ObjectMonitor::owner_offset()));

// need a release store here
la(tmp, Address(tmp, ObjectMonitor::owner_offset()));
// Set owner to null.
// Release to satisfy the JMM
membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore);
sd(zr, Address(tmp)); // set unowned
sd(zr, Address(owner_addr));
// We need a full fence after clearing owner to avoid stranding.
// StoreLoad achieves this.
membar(StoreLoad);

// Check if the entry lists are empty.
ld(t0, Address(tmp, ObjectMonitor::EntryList_offset()));
ld(tmp1Reg, Address(tmp, ObjectMonitor::cxq_offset()));
orr(t0, t0, tmp1Reg);
beqz(t0, unlocked); // If so we are done.

// Check if there is a successor.
ld(t0, Address(tmp, ObjectMonitor::succ_offset()));
bnez(t0, unlocked); // If so we are done.

// Save the monitor pointer in the current thread, so we can try to
// reacquire the lock in SharedRuntime::monitor_exit_helper().
sd(tmp, Address(xthread, JavaThread::unlocked_inflated_monitor_offset()));

mv(flag, 1);
j(slow_path);

bind(unlocked);
mv(flag, zr);
Expand Down Expand Up @@ -534,28 +553,35 @@ void C2_MacroAssembler::fast_unlock_lightweight(Register obj, Register box,

bind(not_recursive);

Label release;
const Register tmp2_owner_addr = tmp2;

// Compute owner address.
la(tmp2_owner_addr, Address(tmp1_monitor, ObjectMonitor::owner_offset()));

// Set owner to null.
// Release to satisfy the JMM
membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore);
sd(zr, Address(tmp2_owner_addr));
// We need a full fence after clearing owner to avoid stranding.
// StoreLoad achieves this.
membar(StoreLoad);

// Check if the entry lists are empty.
ld(t0, Address(tmp1_monitor, ObjectMonitor::EntryList_offset()));
ld(tmp3_t, Address(tmp1_monitor, ObjectMonitor::cxq_offset()));
orr(t0, t0, tmp3_t);
beqz(t0, release);
beqz(t0, unlocked); // If so we are done.

// The owner may be anonymous and we removed the last obj entry in
// the lock-stack. This loses the information about the owner.
// Write the thread to the owner field so the runtime knows the owner.
sd(xthread, Address(tmp2_owner_addr));
j(slow_path);
// Check if there is a successor.
ld(tmp3_t, Address(tmp1_monitor, ObjectMonitor::succ_offset()));
bnez(tmp3_t, unlocked); // If so we are done.

bind(release);
// Set owner to null.
membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore);
sd(zr, Address(tmp2_owner_addr));
// Save the monitor pointer in the current thread, so we can try
// to reacquire the lock in SharedRuntime::monitor_exit_helper().
sd(tmp1_monitor, Address(xthread, JavaThread::unlocked_inflated_monitor_offset()));

mv(flag, 1);
j(slow_path);
}

bind(unlocked);
Expand Down
Loading

0 comments on commit 361f506

Please sign in to comment.