mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-10 05:29:48 +00:00
8379706: Cleanup and clarify BarrierSetAssembler::try_resolve_weak_handle_in_c2
Reviewed-by: mdoerr, fyang, amitkumar
This commit is contained in:
parent
5ccf99b8e9
commit
05882095a8
@ -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);
|
||||
|
||||
|
||||
@ -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->
|
||||
|
||||
|
||||
@ -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
|
||||
};
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
};
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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);
|
||||
};
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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() {}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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->
|
||||
|
||||
|
||||
@ -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
|
||||
};
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
};
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
};
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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->
|
||||
|
||||
|
||||
@ -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
|
||||
};
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user