8379706: Cleanup and clarify BarrierSetAssembler::try_resolve_weak_handle_in_c2

Reviewed-by: mdoerr, fyang, amitkumar
This commit is contained in:
Axel Boldt-Christmas 2026-05-04 05:51:18 +00:00
parent 5ccf99b8e9
commit 05882095a8
32 changed files with 150 additions and 114 deletions

View File

@ -265,7 +265,7 @@ void C2_MacroAssembler::fast_lock(Register obj, Register box, Register t1,
// Check if object matches.
ldr(t3, Address(t1_monitor, ObjectMonitor::object_offset()));
BarrierSetAssembler* bs_asm = BarrierSet::barrier_set()->barrier_set_assembler();
bs_asm->try_resolve_weak_handle_in_c2(this, t3, t2, slow_path);
bs_asm->try_peek_weak_handle_in_nmethod(this, t3, t3, t2, slow_path);
cmp(t3, obj);
br(Assembler::NE, slow_path);

View File

@ -393,6 +393,11 @@ void BarrierSetAssembler::check_oop(MacroAssembler* masm, Register obj, Register
__ cbz(obj, error); // if klass is null it is broken
}
void BarrierSetAssembler::try_peek_weak_handle_in_nmethod(MacroAssembler* masm, Register weak_handle, Register obj, Register tmp, Label& slow_path) {
// Load the oop from the weak handle without barriers.
__ ldr(obj, Address(weak_handle));
}
#ifdef COMPILER2
OptoReg::Name BarrierSetAssembler::encode_float_vector_register_size(const Node* node, OptoReg::Name opto_reg) {
@ -440,12 +445,6 @@ OptoReg::Name BarrierSetAssembler::refine_register(const Node* node, OptoReg::Na
return opto_reg;
}
void BarrierSetAssembler::try_resolve_weak_handle_in_c2(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path) {
// Load the oop from the weak handle.
__ ldr(obj, Address(obj));
}
#undef __
#define __ _masm->

View File

@ -130,12 +130,15 @@ public:
static void clear_patching_epoch();
static void increment_patching_epoch();
// See AS_NO_KEEPALIVE for peek semantics
// weak_handle and obj may alias
virtual void try_peek_weak_handle_in_nmethod(MacroAssembler* masm, Register weak_handle, Register obj, Register tmp, Label& slow_path);
#ifdef COMPILER2
OptoReg::Name encode_float_vector_register_size(const Node* node,
OptoReg::Name opto_reg);
OptoReg::Name refine_register(const Node* node,
OptoReg::Name opto_reg);
virtual void try_resolve_weak_handle_in_c2(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path);
#endif // COMPILER2
};

View File

@ -451,15 +451,15 @@ void ShenandoahBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler
__ bind(done);
}
#ifdef COMPILER2
void ShenandoahBarrierSetAssembler::try_resolve_weak_handle_in_c2(MacroAssembler* masm, Register obj,
Register tmp, Label& slow_path) {
assert_different_registers(obj, tmp);
void ShenandoahBarrierSetAssembler::try_peek_weak_handle_in_nmethod(MacroAssembler* masm, Register weak_handle, Register obj,
Register tmp, Label& slow_path) {
assert_different_registers(weak_handle, tmp, noreg);
assert_different_registers(obj, tmp, noreg);
Label done;
// Resolve weak handle using the standard implementation.
BarrierSetAssembler::try_resolve_weak_handle_in_c2(masm, obj, tmp, slow_path);
// Peek weak handle using the standard implementation.
BarrierSetAssembler::try_peek_weak_handle_in_nmethod(masm, weak_handle, obj, tmp, slow_path);
// Check if the reference is null, and if it is, take the fast path.
__ cbz(obj, done);
@ -473,7 +473,6 @@ void ShenandoahBarrierSetAssembler::try_resolve_weak_handle_in_c2(MacroAssembler
__ tbnz(tmp, ShenandoahHeap::WEAK_ROOTS_BITPOS, slow_path);
__ bind(done);
}
#endif
// Special Shenandoah CAS implementation that handles false negatives due
// to concurrent evacuation. The service is more complex than a

View File

@ -80,9 +80,8 @@ public:
Address dst, Register val, Register tmp1, Register tmp2, Register tmp3);
virtual void try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
Register obj, Register tmp, Label& slowpath);
#ifdef COMPILER2
virtual void try_resolve_weak_handle_in_c2(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path);
#endif
virtual void try_peek_weak_handle_in_nmethod(MacroAssembler* masm, Register weak_handle, Register obj,
Register tmp, Label& slow_path);
void cmpxchg_oop(MacroAssembler* masm, Register addr, Register expected, Register new_val,
bool acquire, bool release, bool is_cae, Register result);
};

View File

@ -1328,12 +1328,20 @@ void ZStoreBarrierStubC2Aarch64::emit_code(MacroAssembler& masm) {
register_stub(this);
}
#undef __
#endif // COMPILER2
#undef __
#define __ masm->
void ZBarrierSetAssembler::try_resolve_weak_handle_in_c2(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path) {
// Resolve weak handle using the standard implementation.
BarrierSetAssembler::try_resolve_weak_handle_in_c2(masm, obj, tmp, slow_path);
void ZBarrierSetAssembler::try_peek_weak_handle_in_nmethod(MacroAssembler* masm, Register weak_handle, Register obj,
Register tmp, Label& slow_path) {
assert_different_registers(weak_handle, tmp, noreg);
assert_different_registers(obj, tmp, noreg);
// Peek weak handle using the standard implementation.
BarrierSetAssembler::try_peek_weak_handle_in_nmethod(masm, weak_handle, obj, tmp, slow_path);
// Check if the oop is bad, in which case we need to take the slow path.
__ relocate(barrier_Relocation::spec(), ZBarrierRelocationFormatMarkBadBeforeMov);
@ -1345,13 +1353,6 @@ void ZBarrierSetAssembler::try_resolve_weak_handle_in_c2(MacroAssembler* masm, R
__ lsr(obj, obj, ZPointerLoadShift);
}
#undef __
#endif // COMPILER2
#undef __
#define __ masm->
void ZBarrierSetAssembler::check_oop(MacroAssembler* masm, Register obj, Register tmp1, Register tmp2, Label& error) {
// C1 calls verfy_oop in the middle of barriers, before they have been uncolored
// and after being colored. Therefore, we must deal with colored oops as well.

View File

@ -191,9 +191,10 @@ public:
ZLoadBarrierStubC2* stub) const;
void generate_c2_store_barrier_stub(MacroAssembler* masm,
ZStoreBarrierStubC2* stub) const;
void try_resolve_weak_handle_in_c2(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path);
#endif // COMPILER2
void try_peek_weak_handle_in_nmethod(MacroAssembler* masm, Register weak_handle, Register obj, Register tmp, Label& slow_path);
void check_oop(MacroAssembler* masm, Register obj, Register tmp1, Register tmp2, Label& error);
};

View File

@ -179,9 +179,10 @@ void BarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, Re
__ ld(dst, 0, dst); // Resolve (untagged) jobject.
}
void BarrierSetAssembler::try_resolve_weak_handle(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path) {
// Load the oop from the weak handle.
__ ld(obj, 0, obj);
void BarrierSetAssembler::try_peek_weak_handle_in_nmethod(MacroAssembler* masm, Register weak_handle, Register obj,
Register tmp, Label& slow_path) {
// Load the oop from the weak handle without barriers.
__ ld(obj, 0, weak_handle);
}
void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm, Register tmp) {

View File

@ -70,11 +70,10 @@ public:
virtual void try_resolve_jobject_in_native(MacroAssembler* masm, Register dst, Register jni_env,
Register obj, Register tmp, Label& slowpath);
// Can be used in nmethods including native wrappers.
// Attention: obj will only be valid until next safepoint (no SATB barrier).
// TODO: maybe rename to try_peek_weak_handle on all platforms (try: operation may fail, peek: obj is not kept alive)
// (other platforms currently use it for C2 only: try_resolve_weak_handle_in_c2)
virtual void try_resolve_weak_handle(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path);
// See AS_NO_KEEPALIVE for peek semantics
// weak_handle and obj may alias
virtual void try_peek_weak_handle_in_nmethod(MacroAssembler* masm, Register weak_handle, Register obj,
Register tmp, Label& slow_path);
virtual void barrier_stubs_init() {}

View File

@ -663,16 +663,18 @@ void ShenandoahBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler
__ block_comment("} try_resolve_jobject_in_native (shenandoahgc)");
}
void ShenandoahBarrierSetAssembler::try_resolve_weak_handle(MacroAssembler *masm, Register obj,
Register tmp, Label &slow_path) {
__ block_comment("try_resolve_weak_handle (shenandoahgc) {");
void ShenandoahBarrierSetAssembler::try_peek_weak_handle_in_nmethod(MacroAssembler *masm, Register weak_handle,
Register obj, Register tmp, Label &slow_path) {
__ block_comment("try_peek_weak_handle_in_nmethod (shenandoahgc) {");
assert_different_registers(weak_handle, tmp, noreg);
assert_different_registers(obj, tmp, noreg);
assert_different_registers(obj, tmp);
Label done;
// Resolve weak handle using the standard implementation.
BarrierSetAssembler::try_resolve_weak_handle(masm, obj, tmp, slow_path);
// Peek weak handle using the standard implementation.
BarrierSetAssembler::try_peek_weak_handle_in_nmethod(masm, weak_handle, obj, tmp, slow_path);
// Check if the reference is null, and if it is, take the fast path.
__ cmpdi(CR0, obj, 0);
@ -685,7 +687,7 @@ void ShenandoahBarrierSetAssembler::try_resolve_weak_handle(MacroAssembler *masm
__ bne(CR0, slow_path);
__ bind(done);
__ block_comment("} try_resolve_weak_handle (shenandoahgc)");
__ block_comment("} try_peek_weak_handle_in_nmethod (shenandoahgc)");
}
// Special shenandoah CAS implementation that handles false negatives due

View File

@ -123,7 +123,8 @@ public:
virtual void try_resolve_jobject_in_native(MacroAssembler* masm, Register dst, Register jni_env,
Register obj, Register tmp, Label& slowpath);
virtual void try_resolve_weak_handle(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path);
virtual void try_peek_weak_handle_in_nmethod(MacroAssembler* masm, Register weak_handle, Register obj,
Register tmp, Label& slow_path);
};
#endif // CPU_PPC_GC_SHENANDOAH_SHENANDOAHBARRIERSETASSEMBLER_PPC_HPP

View File

@ -627,9 +627,13 @@ void ZBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, R
__ block_comment("} try_resolve_jobject_in_native (zgc)");
}
void ZBarrierSetAssembler::try_resolve_weak_handle(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path) {
// Resolve weak handle using the standard implementation.
BarrierSetAssembler::try_resolve_weak_handle(masm, obj, tmp, slow_path);
void ZBarrierSetAssembler::try_peek_weak_handle_in_nmethod(MacroAssembler* masm, Register weak_handle, Register obj,
Register tmp, Label& slow_path) {
assert_different_registers(weak_handle, tmp, noreg);
assert_different_registers(obj, tmp, noreg);
// Peek weak handle using the standard implementation.
BarrierSetAssembler::try_peek_weak_handle_in_nmethod(masm, weak_handle, obj, tmp, slow_path);
// Check if the oop is bad, in which case we need to take the slow path.
__ relocate(barrier_Relocation::spec(), ZBarrierRelocationFormatMarkBadMask);

View File

@ -72,7 +72,8 @@ public:
virtual void try_resolve_jobject_in_native(MacroAssembler* masm, Register dst, Register jni_env,
Register obj, Register tmp, Label& slowpath);
virtual void try_resolve_weak_handle(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path);
virtual void try_peek_weak_handle_in_nmethod(MacroAssembler* masm, Register weak_handle, Register obj,
Register tmp, Label& slow_path);
virtual void check_oop(MacroAssembler *masm, Register obj, const char* msg);

View File

@ -2788,7 +2788,7 @@ void MacroAssembler::compiler_fast_lock_object(ConditionRegister flag, Register
// Check if object matches.
ld(tmp3, in_bytes(ObjectMonitor::object_offset()), monitor);
BarrierSetAssembler* bs_asm = BarrierSet::barrier_set()->barrier_set_assembler();
bs_asm->try_resolve_weak_handle(this, tmp3, tmp2, slow_path);
bs_asm->try_peek_weak_handle_in_nmethod(this, tmp3, tmp3, tmp2, slow_path);
cmpd(CR0, tmp3, obj);
bne(CR0, slow_path);

View File

@ -167,7 +167,7 @@ void C2_MacroAssembler::fast_lock(Register obj, Register box,
// Check if object matches.
ld(tmp3, Address(tmp1_monitor, ObjectMonitor::object_offset()));
BarrierSetAssembler* bs_asm = BarrierSet::barrier_set()->barrier_set_assembler();
bs_asm->try_resolve_weak_handle_in_c2(this, tmp3, tmp2, slow_path);
bs_asm->try_peek_weak_handle_in_nmethod(this, tmp3, tmp3, tmp2, slow_path);
bne(tmp3, obj, slow_path);
bind(monitor_found);

View File

@ -354,6 +354,12 @@ void BarrierSetAssembler::check_oop(MacroAssembler* masm, Register obj, Register
__ beqz(obj, error); // if klass is null it is broken
}
void BarrierSetAssembler::try_peek_weak_handle_in_nmethod(MacroAssembler* masm, Register weak_handle, Register obj,
Register tmp, Label& slow_path) {
// Load the oop from the weak handle without barriers.
__ ld(obj, Address(weak_handle));
}
#ifdef COMPILER2
OptoReg::Name BarrierSetAssembler::refine_register(const Node* node, OptoReg::Name opto_reg) {
@ -368,12 +374,6 @@ OptoReg::Name BarrierSetAssembler::refine_register(const Node* node, OptoReg::Na
return opto_reg;
}
void BarrierSetAssembler::try_resolve_weak_handle_in_c2(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path) {
// Load the oop from the weak handle.
__ ld(obj, Address(obj));
}
#undef __
#define __ _masm->

View File

@ -107,11 +107,14 @@ public:
static void clear_patching_epoch();
static void increment_patching_epoch();
// See AS_NO_KEEPALIVE for peek semantics
// weak_handle and obj may alias
virtual void try_peek_weak_handle_in_nmethod(MacroAssembler* masm, Register weak_handle, Register obj,
Register tmp, Label& slow_path);
#ifdef COMPILER2
OptoReg::Name refine_register(const Node* node,
OptoReg::Name opto_reg);
virtual void try_resolve_weak_handle_in_c2(MacroAssembler* masm, Register obj,
Register tmp, Label& slow_path);
#endif // COMPILER2
};

View File

@ -462,15 +462,16 @@ void ShenandoahBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler
__ bind(done);
}
#ifdef COMPILER2
void ShenandoahBarrierSetAssembler::try_resolve_weak_handle_in_c2(MacroAssembler *masm, Register obj,
Register tmp, Label& slow_path) {
assert_different_registers(obj, tmp);
void ShenandoahBarrierSetAssembler::try_peek_weak_handle_in_nmethod(MacroAssembler *masm, Register weak_handle,
Register obj, Register tmp, Label& slow_path) {
assert_different_registers(weak_handle, tmp, noreg);
assert_different_registers(obj, tmp, noreg);
Label done;
// Resolve weak handle using the standard implementation.
BarrierSetAssembler::try_resolve_weak_handle_in_c2(masm, obj, tmp, slow_path);
// Peek weak handle using the standard implementation.
BarrierSetAssembler::try_peek_weak_handle_in_nmethod(masm, weak_handle, obj, tmp, slow_path);
// Check if the reference is null, and if it is, take the fast path.
__ beqz(obj, done);
@ -484,7 +485,6 @@ void ShenandoahBarrierSetAssembler::try_resolve_weak_handle_in_c2(MacroAssembler
__ bnez(tmp, slow_path);
__ bind(done);
}
#endif
// Special Shenandoah CAS implementation that handles false negatives due
// to concurrent evacuation. The service is more complex than a

View File

@ -85,9 +85,8 @@ public:
virtual void try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
Register obj, Register tmp, Label& slowpath);
#ifdef COMPILER2
virtual void try_resolve_weak_handle_in_c2(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path);
#endif
virtual void try_peek_weak_handle_in_nmethod(MacroAssembler* masm, Register weak_handle, Register obj,
Register tmp, Label& slow_path);
void cmpxchg_oop(MacroAssembler* masm, Register addr, Register expected, Register new_val,
Assembler::Aqrl acquire, Assembler::Aqrl release, bool is_cae, Register result);
};

View File

@ -602,12 +602,16 @@ void ZBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm,
BLOCK_COMMENT("} ZBarrierSetAssembler::try_resolve_jobject_in_native");
}
#ifdef COMPILER2
void ZBarrierSetAssembler::try_resolve_weak_handle_in_c2(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path) {
BLOCK_COMMENT("ZBarrierSetAssembler::try_resolve_weak_handle_in_c2 {");
void ZBarrierSetAssembler::try_peek_weak_handle_in_nmethod(MacroAssembler* masm, Register weak_handle, Register obj,
Register tmp, Label& slow_path) {
BLOCK_COMMENT("ZBarrierSetAssembler::try_peek_weak_handle_in_nmethod {");
// Resolve weak handle using the standard implementation.
BarrierSetAssembler::try_resolve_weak_handle_in_c2(masm, obj, tmp, slow_path);
assert_different_registers(weak_handle, tmp, noreg);
assert_different_registers(obj, tmp, noreg);
// Peek weak handle using the standard implementation.
BarrierSetAssembler::try_peek_weak_handle_in_nmethod(masm, weak_handle, obj, tmp, slow_path);
// Check if the oop is bad, in which case we need to take the slow path.
__ relocate(barrier_Relocation::spec(), [&] {
@ -619,9 +623,8 @@ void ZBarrierSetAssembler::try_resolve_weak_handle_in_c2(MacroAssembler* masm, R
// Oop is okay, so we uncolor it.
__ srli(obj, obj, ZPointerLoadShift);
BLOCK_COMMENT("} ZBarrierSetAssembler::try_resolve_weak_handle_in_c2");
BLOCK_COMMENT("} ZBarrierSetAssembler::try_peek_weak_handle_in_nmethod");
}
#endif
static uint16_t patch_barrier_relocation_value(int format) {
switch (format) {

View File

@ -170,12 +170,14 @@ public:
ZLoadBarrierStubC2* stub) const;
void generate_c2_store_barrier_stub(MacroAssembler* masm,
ZStoreBarrierStubC2* stub) const;
void try_resolve_weak_handle_in_c2(MacroAssembler* masm,
Register obj,
Register tmp,
Label& slow_path);
#endif // COMPILER2
void try_peek_weak_handle_in_nmethod(MacroAssembler* masm,
Register weak_handle,
Register obj,
Register tmp,
Label& slow_path);
void check_oop(MacroAssembler* masm, Register obj, Register tmp1, Register tmp2, Label& error);
};

View File

@ -169,9 +169,10 @@ void BarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, Re
__ z_lg(obj, 0, obj); // Resolve (untagged) jobject.
}
void BarrierSetAssembler::try_resolve_weak_handle(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path) {
// Load the oop from the weak handle.
__ z_lg(obj, Address(obj));
void BarrierSetAssembler::try_peek_weak_handle_in_nmethod(MacroAssembler* masm, Register weak_handle, Register obj,
Register tmp, Label& slow_path) {
// Load the oop from the weak handle without barriers.
__ z_lg(obj, Address(weak_handle));
}
void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm) {

View File

@ -58,10 +58,10 @@ public:
virtual void try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
Register obj, Register tmp, Label& slowpath);
// Can be used in nmethods including native wrappers.
// Attention: obj will only be valid until next safepoint (no SATB barrier).
// (other platforms currently use it for C2 only: try_resolve_weak_handle_in_c2)
virtual void try_resolve_weak_handle(MacroAssembler* masm, Register obj, Register tmp, Label& slow_path);
// See AS_NO_KEEPALIVE for peek semantics
// weak_handle and obj may alias
virtual void try_peek_weak_handle_in_nmethod(MacroAssembler* masm, Register weak_handle, Register obj,
Register tmp, Label& slow_path);
virtual void nmethod_entry_barrier(MacroAssembler* masm);

View File

@ -6395,7 +6395,7 @@ void MacroAssembler::compiler_fast_lock_object(Register obj, Register box, Regis
// Check if object matches.
z_lg(tmp2, Address(tmp1_monitor, ObjectMonitor::object_offset()));
BarrierSetAssembler* bs_asm = BarrierSet::barrier_set()->barrier_set_assembler();
bs_asm->try_resolve_weak_handle(this, tmp2, Z_R0_scratch, slow_path);
bs_asm->try_peek_weak_handle_in_nmethod(this, tmp2, tmp2, Z_R0_scratch, slow_path);
z_cgr(obj, tmp2);
z_brne(slow_path);

View File

@ -336,7 +336,7 @@ void C2_MacroAssembler::fast_lock(Register obj, Register box, Register rax_reg,
// Check if object matches.
movptr(rax_reg, Address(monitor, ObjectMonitor::object_offset()));
BarrierSetAssembler* bs_asm = BarrierSet::barrier_set()->barrier_set_assembler();
bs_asm->try_resolve_weak_handle_in_c2(this, rax_reg, slow_path);
bs_asm->try_peek_weak_handle_in_nmethod(this, rax_reg, rax_reg, slow_path);
cmpptr(rax_reg, obj);
jcc(Assembler::notEqual, slow_path);

View File

@ -362,6 +362,11 @@ void BarrierSetAssembler::check_oop(MacroAssembler* masm, Register obj, Register
__ jcc(Assembler::zero, error); // if klass is null it is broken
}
void BarrierSetAssembler::try_peek_weak_handle_in_nmethod(MacroAssembler* masm, Register weak_handle, Register obj, Label& slowpath) {
// Load the oop from the weak handle without barriers.
__ movptr(obj, Address(weak_handle));
}
#ifdef COMPILER2
OptoReg::Name BarrierSetAssembler::refine_register(const Node* node, OptoReg::Name opto_reg) {
@ -395,11 +400,6 @@ OptoReg::Name BarrierSetAssembler::refine_register(const Node* node, OptoReg::Na
extern void vec_spill_helper(C2_MacroAssembler *masm, bool is_load,
int stack_offset, int reg, uint ireg, outputStream* st);
void BarrierSetAssembler::try_resolve_weak_handle_in_c2(MacroAssembler* masm, Register obj, Label& slowpath) {
// Load the oop from the weak handle.
__ movptr(obj, Address(obj));
}
#undef __
#define __ _masm->

View File

@ -106,11 +106,13 @@ public:
virtual void check_oop(MacroAssembler* masm, Register obj, Register tmp1, Register tmp2, Label& error);
// See AS_NO_KEEPALIVE for peek semantics
// weak_handle and obj may alias
virtual void try_peek_weak_handle_in_nmethod(MacroAssembler* masm, Register weak_handle, Register obj, Label& slowpath);
#ifdef COMPILER2
OptoReg::Name refine_register(const Node* node,
OptoReg::Name opto_reg);
virtual void try_resolve_weak_handle_in_c2(MacroAssembler* masm, Register obj, Label& slowpath);
#endif // COMPILER2
};

View File

@ -630,12 +630,11 @@ void ShenandoahBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler
__ bind(done);
}
#ifdef COMPILER2
void ShenandoahBarrierSetAssembler::try_resolve_weak_handle_in_c2(MacroAssembler* masm, Register obj, Label& slowpath) {
void ShenandoahBarrierSetAssembler::try_peek_weak_handle_in_nmethod(MacroAssembler* masm, Register weak_handle, Register obj, Label& slowpath) {
Label done;
// Resolve weak handle using the standard implementation.
BarrierSetAssembler::try_resolve_weak_handle_in_c2(masm, obj, slowpath);
// Peek weak handle using the standard implementation.
BarrierSetAssembler::try_peek_weak_handle_in_nmethod(masm, weak_handle, obj, slowpath);
// Check if the reference is null, and if it is, take the fast path.
__ testptr(obj, obj);
@ -649,7 +648,6 @@ void ShenandoahBarrierSetAssembler::try_resolve_weak_handle_in_c2(MacroAssembler
__ jcc(Assembler::notZero, slowpath);
__ bind(done);
}
#endif // COMPILER2
// Special Shenandoah CAS implementation that handles false negatives
// due to concurrent evacuation.

View File

@ -78,9 +78,7 @@ public:
Address dst, Register val, Register tmp1, Register tmp2, Register tmp3);
virtual void try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
Register obj, Register tmp, Label& slowpath);
#ifdef COMPILER2
virtual void try_resolve_weak_handle_in_c2(MacroAssembler* masm, Register obj, Label& slowpath);
#endif // COMPILER2
virtual void try_peek_weak_handle_in_nmethod(MacroAssembler* masm, Register weak_handle, Register obj, Label& slowpath);
};
#endif // CPU_X86_GC_SHENANDOAH_SHENANDOAHBARRIERSETASSEMBLER_X86_HPP

View File

@ -1329,9 +1329,14 @@ void ZBarrierSetAssembler::generate_c2_store_barrier_stub(MacroAssembler* masm,
__ jmp(slow_continuation);
}
void ZBarrierSetAssembler::try_resolve_weak_handle_in_c2(MacroAssembler* masm, Register obj, Label& slow_path) {
// Resolve weak handle using the standard implementation.
BarrierSetAssembler::try_resolve_weak_handle_in_c2(masm, obj, slow_path);
#undef __
#endif // COMPILER2
#define __ masm->
void ZBarrierSetAssembler::try_peek_weak_handle_in_nmethod(MacroAssembler* masm, Register weak_handle, Register obj, Label& slow_path) {
// Peek weak handle using the standard implementation.
BarrierSetAssembler::try_peek_weak_handle_in_nmethod(masm, weak_handle, obj, slow_path);
// Check if the oop is bad, in which case we need to take the slow path.
__ testptr(obj, Address(r15_thread, ZThreadLocalData::mark_bad_mask_offset()));
@ -1343,7 +1348,6 @@ void ZBarrierSetAssembler::try_resolve_weak_handle_in_c2(MacroAssembler* masm, R
}
#undef __
#endif // COMPILER2
static int patch_barrier_relocation_offset(int format) {
switch (format) {

View File

@ -167,10 +167,10 @@ public:
ZLoadBarrierStubC2* stub) const;
void generate_c2_store_barrier_stub(MacroAssembler* masm,
ZStoreBarrierStubC2* stub) const;
virtual void try_resolve_weak_handle_in_c2(MacroAssembler* masm, Register obj, Label& slow_path);
#endif // COMPILER2
virtual void try_peek_weak_handle_in_nmethod(MacroAssembler* masm, Register weak_handle, Register obj, Label& slow_path);
void store_barrier_fast(MacroAssembler* masm,
Address ref_addr,
Register rnew_persistent,

View File

@ -138,10 +138,26 @@ const DecoratorSet MO_DECORATOR_MASK = MO_UNORDERED | MO_RELAXED |
// - Accesses on HeapWord* translate to a runtime check choosing one of the above
// - Accesses on other types translate to raw memory accesses without runtime checks
// * AS_NO_KEEPALIVE: The barrier is used only on oop references and will not keep any involved objects
// alive, regardless of the type of reference being accessed. It will however perform the memory access
// in a consistent way w.r.t. e.g. concurrent compaction, so that the right field is being accessed,
// or maintain, e.g. intergenerational or interregional pointers if applicable. This should be used with
// extreme caution in isolated scopes.
// alive, regardless of the type of reference being accessed. This should be used with extreme caution
// in isolated scopes.
// AS_NO_KEEPALIVE stores are currently used primarily by the VM implementation of java.lang.ref.Reference
// and reference processing. AS_NO_KEEPALIVE loads have broader use, e.g. VM / serviceability introspection,
// printing, liveness checks, and weak (hash) table lookups.
// AS_NO_KEEPALIVE does not establish liveness for the current GC cycle. The oop returned by such
// a load, and any oop reached only by traversing from it, must not be stored as a new oop edge into
// GC-visible state (GC roots and the object graph). For SATB marking, violating this rule breaks
// the snapshot invariant. This includes, but is not limited to:
// - object graph storage (e.g. static and non-static Object fields, Object array elements)
// - local root storage (e.g. Handles, OopMap/GC-tracked frame / register slots)
// - other root storage (e.g. OopHandles, WeakHandles, nmethod and class metadata)
// Before such an oop is stored into GC-visible state, liveness must first be explicitly re-established,
// for example by:
// - re-resolving without AS_NO_KEEPALIVE
// - using CollectedHeap::keep_alive(oop)
// Related special case: for CLD-owned OopHandles (notably java mirrors), loading the oop does not
// keep the owning CLD / Klass alive. In those cases, a plain resolve() is insufficient; use the corresponding
// owner keep-alive helper (e.g. Klass::keep_alive()) or CollectedHeap::keep_alive(oop), or have some
// other guarantee of liveness before storing the oop into GC-visible state.
// * AS_NORMAL: The accesses will be resolved to an accessor on the BarrierSet class, giving the
// responsibility of performing the access and what barriers to be performed to the GC. This is the default.
// Note that primitive accesses will only be resolved on the barrier set if the appropriate build-time