8255691: Shenandoah: Invoke native-LRB only on non-strong refs
Reviewed-by: zgu
This commit is contained in:
parent
d2812f780e
commit
1019581ce2
@ -262,7 +262,7 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier_not_null(MacroAssembl
|
|||||||
__ leave();
|
__ leave();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShenandoahBarrierSetAssembler::load_reference_barrier_native(MacroAssembler* masm, Register dst, Address load_addr) {
|
void ShenandoahBarrierSetAssembler::load_reference_barrier_weak(MacroAssembler* masm, Register dst, Address load_addr) {
|
||||||
if (!ShenandoahLoadRefBarrier) {
|
if (!ShenandoahLoadRefBarrier) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -272,7 +272,7 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier_native(MacroAssembler
|
|||||||
Label is_null;
|
Label is_null;
|
||||||
Label done;
|
Label done;
|
||||||
|
|
||||||
__ block_comment("load_reference_barrier_native { ");
|
__ block_comment("load_reference_barrier_weak { ");
|
||||||
|
|
||||||
__ cbz(dst, is_null);
|
__ cbz(dst, is_null);
|
||||||
|
|
||||||
@ -286,7 +286,7 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier_native(MacroAssembler
|
|||||||
|
|
||||||
__ mov(rscratch2, dst);
|
__ mov(rscratch2, dst);
|
||||||
__ push_call_clobbered_registers();
|
__ push_call_clobbered_registers();
|
||||||
__ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native));
|
__ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak));
|
||||||
__ lea(r1, load_addr);
|
__ lea(r1, load_addr);
|
||||||
__ mov(r0, rscratch2);
|
__ mov(r0, rscratch2);
|
||||||
__ blr(lr);
|
__ blr(lr);
|
||||||
@ -297,7 +297,7 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier_native(MacroAssembler
|
|||||||
__ bind(done);
|
__ bind(done);
|
||||||
__ leave();
|
__ leave();
|
||||||
__ bind(is_null);
|
__ bind(is_null);
|
||||||
__ block_comment("} load_reference_barrier_native");
|
__ block_comment("} load_reference_barrier_weak");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShenandoahBarrierSetAssembler::storeval_barrier(MacroAssembler* masm, Register dst, Register tmp) {
|
void ShenandoahBarrierSetAssembler::storeval_barrier(MacroAssembler* masm, Register dst, Register tmp) {
|
||||||
@ -352,8 +352,8 @@ void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet d
|
|||||||
|
|
||||||
BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
|
BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
|
||||||
|
|
||||||
if (ShenandoahBarrierSet::use_load_reference_barrier_native(decorators, type)) {
|
if (ShenandoahBarrierSet::use_load_reference_barrier_weak(decorators, type)) {
|
||||||
load_reference_barrier_native(masm, dst, src);
|
load_reference_barrier_weak(masm, dst, src);
|
||||||
} else {
|
} else {
|
||||||
load_reference_barrier(masm, dst, src);
|
load_reference_barrier(masm, dst, src);
|
||||||
}
|
}
|
||||||
@ -669,8 +669,8 @@ void ShenandoahBarrierSetAssembler::gen_load_reference_barrier_stub(LIR_Assemble
|
|||||||
__ bind(slow_path);
|
__ bind(slow_path);
|
||||||
ce->store_parameter(res, 0);
|
ce->store_parameter(res, 0);
|
||||||
ce->store_parameter(addr, 1);
|
ce->store_parameter(addr, 1);
|
||||||
if (stub->is_native()) {
|
if (stub->is_weak()) {
|
||||||
__ far_call(RuntimeAddress(bs->load_reference_barrier_native_rt_code_blob()->code_begin()));
|
__ far_call(RuntimeAddress(bs->load_reference_barrier_weak_rt_code_blob()->code_begin()));
|
||||||
} else {
|
} else {
|
||||||
__ far_call(RuntimeAddress(bs->load_reference_barrier_rt_code_blob()->code_begin()));
|
__ far_call(RuntimeAddress(bs->load_reference_barrier_rt_code_blob()->code_begin()));
|
||||||
}
|
}
|
||||||
@ -728,15 +728,15 @@ void ShenandoahBarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAss
|
|||||||
__ epilogue();
|
__ epilogue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShenandoahBarrierSetAssembler::generate_c1_load_reference_barrier_runtime_stub(StubAssembler* sasm, bool is_native) {
|
void ShenandoahBarrierSetAssembler::generate_c1_load_reference_barrier_runtime_stub(StubAssembler* sasm, bool is_weak) {
|
||||||
__ prologue("shenandoah_load_reference_barrier", false);
|
__ prologue("shenandoah_load_reference_barrier", false);
|
||||||
// arg0 : object to be resolved
|
// arg0 : object to be resolved
|
||||||
|
|
||||||
__ push_call_clobbered_registers();
|
__ push_call_clobbered_registers();
|
||||||
__ load_parameter(0, r0);
|
__ load_parameter(0, r0);
|
||||||
__ load_parameter(1, r1);
|
__ load_parameter(1, r1);
|
||||||
if (is_native) {
|
if (is_weak) {
|
||||||
__ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native));
|
__ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak));
|
||||||
} else if (UseCompressedOops) {
|
} else if (UseCompressedOops) {
|
||||||
__ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow));
|
__ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow));
|
||||||
} else {
|
} else {
|
||||||
|
@ -59,7 +59,7 @@ private:
|
|||||||
void resolve_forward_pointer_not_null(MacroAssembler* masm, Register dst, Register tmp = noreg);
|
void resolve_forward_pointer_not_null(MacroAssembler* masm, Register dst, Register tmp = noreg);
|
||||||
void load_reference_barrier(MacroAssembler* masm, Register dst, Address load_addr);
|
void load_reference_barrier(MacroAssembler* masm, Register dst, Address load_addr);
|
||||||
void load_reference_barrier_not_null(MacroAssembler* masm, Register dst, Address load_addr);
|
void load_reference_barrier_not_null(MacroAssembler* masm, Register dst, Address load_addr);
|
||||||
void load_reference_barrier_native(MacroAssembler* masm, Register dst, Address load_addr);
|
void load_reference_barrier_weak(MacroAssembler* masm, Register dst, Address load_addr);
|
||||||
|
|
||||||
address generate_shenandoah_lrb(StubCodeGenerator* cgen);
|
address generate_shenandoah_lrb(StubCodeGenerator* cgen);
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ public:
|
|||||||
void gen_pre_barrier_stub(LIR_Assembler* ce, ShenandoahPreBarrierStub* stub);
|
void gen_pre_barrier_stub(LIR_Assembler* ce, ShenandoahPreBarrierStub* stub);
|
||||||
void gen_load_reference_barrier_stub(LIR_Assembler* ce, ShenandoahLoadReferenceBarrierStub* stub);
|
void gen_load_reference_barrier_stub(LIR_Assembler* ce, ShenandoahLoadReferenceBarrierStub* stub);
|
||||||
void generate_c1_pre_barrier_runtime_stub(StubAssembler* sasm);
|
void generate_c1_pre_barrier_runtime_stub(StubAssembler* sasm);
|
||||||
void generate_c1_load_reference_barrier_runtime_stub(StubAssembler* sasm, bool is_native);
|
void generate_c1_load_reference_barrier_runtime_stub(StubAssembler* sasm, bool is_weak);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
|
virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
|
||||||
|
@ -336,7 +336,7 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier_not_null(MacroAssembl
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShenandoahBarrierSetAssembler::load_reference_barrier_native(MacroAssembler* masm, Register dst, Address src) {
|
void ShenandoahBarrierSetAssembler::load_reference_barrier_weak(MacroAssembler* masm, Register dst, Address src) {
|
||||||
if (!ShenandoahLoadRefBarrier) {
|
if (!ShenandoahLoadRefBarrier) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -344,7 +344,7 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier_native(MacroAssembler
|
|||||||
Label done;
|
Label done;
|
||||||
Label not_null;
|
Label not_null;
|
||||||
Label slow_path;
|
Label slow_path;
|
||||||
__ block_comment("load_reference_barrier_native { ");
|
__ block_comment("load_reference_barrier_weak { ");
|
||||||
|
|
||||||
// null check
|
// null check
|
||||||
__ testptr(dst, dst);
|
__ testptr(dst, dst);
|
||||||
@ -396,7 +396,7 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier_native(MacroAssembler
|
|||||||
__ lea(rsi, src);
|
__ lea(rsi, src);
|
||||||
|
|
||||||
save_xmm_registers(masm);
|
save_xmm_registers(masm);
|
||||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native), dst, rsi);
|
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak), dst, rsi);
|
||||||
restore_xmm_registers(masm);
|
restore_xmm_registers(masm);
|
||||||
|
|
||||||
#ifdef _LP64
|
#ifdef _LP64
|
||||||
@ -420,7 +420,7 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier_native(MacroAssembler
|
|||||||
}
|
}
|
||||||
|
|
||||||
__ bind(done);
|
__ bind(done);
|
||||||
__ block_comment("load_reference_barrier_native { ");
|
__ block_comment("} load_reference_barrier_weak");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShenandoahBarrierSetAssembler::storeval_barrier(MacroAssembler* masm, Register dst, Register tmp) {
|
void ShenandoahBarrierSetAssembler::storeval_barrier(MacroAssembler* masm, Register dst, Register tmp) {
|
||||||
@ -517,8 +517,8 @@ void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet d
|
|||||||
|
|
||||||
BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
|
BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
|
||||||
|
|
||||||
if (ShenandoahBarrierSet::use_load_reference_barrier_native(decorators, type)) {
|
if (ShenandoahBarrierSet::use_load_reference_barrier_weak(decorators, type)) {
|
||||||
load_reference_barrier_native(masm, dst, src);
|
load_reference_barrier_weak(masm, dst, src);
|
||||||
} else {
|
} else {
|
||||||
load_reference_barrier(masm, dst, src);
|
load_reference_barrier(masm, dst, src);
|
||||||
}
|
}
|
||||||
@ -870,8 +870,8 @@ void ShenandoahBarrierSetAssembler::gen_load_reference_barrier_stub(LIR_Assemble
|
|||||||
__ bind(slow_path);
|
__ bind(slow_path);
|
||||||
ce->store_parameter(res, 0);
|
ce->store_parameter(res, 0);
|
||||||
ce->store_parameter(addr, 1);
|
ce->store_parameter(addr, 1);
|
||||||
if (stub->is_native()) {
|
if (stub->is_weak()) {
|
||||||
__ call(RuntimeAddress(bs->load_reference_barrier_native_rt_code_blob()->code_begin()));
|
__ call(RuntimeAddress(bs->load_reference_barrier_weak_rt_code_blob()->code_begin()));
|
||||||
} else {
|
} else {
|
||||||
__ call(RuntimeAddress(bs->load_reference_barrier_rt_code_blob()->code_begin()));
|
__ call(RuntimeAddress(bs->load_reference_barrier_rt_code_blob()->code_begin()));
|
||||||
}
|
}
|
||||||
@ -938,7 +938,7 @@ void ShenandoahBarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAss
|
|||||||
__ epilogue();
|
__ epilogue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShenandoahBarrierSetAssembler::generate_c1_load_reference_barrier_runtime_stub(StubAssembler* sasm, bool is_native) {
|
void ShenandoahBarrierSetAssembler::generate_c1_load_reference_barrier_runtime_stub(StubAssembler* sasm, bool is_weak) {
|
||||||
__ prologue("shenandoah_load_reference_barrier", false);
|
__ prologue("shenandoah_load_reference_barrier", false);
|
||||||
// arg0 : object to be resolved
|
// arg0 : object to be resolved
|
||||||
|
|
||||||
@ -947,8 +947,8 @@ void ShenandoahBarrierSetAssembler::generate_c1_load_reference_barrier_runtime_s
|
|||||||
#ifdef _LP64
|
#ifdef _LP64
|
||||||
__ load_parameter(0, c_rarg0);
|
__ load_parameter(0, c_rarg0);
|
||||||
__ load_parameter(1, c_rarg1);
|
__ load_parameter(1, c_rarg1);
|
||||||
if (is_native) {
|
if (is_weak) {
|
||||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native), c_rarg0, c_rarg1);
|
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak), c_rarg0, c_rarg1);
|
||||||
} else if (UseCompressedOops) {
|
} else if (UseCompressedOops) {
|
||||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow), c_rarg0, c_rarg1);
|
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow), c_rarg0, c_rarg1);
|
||||||
} else {
|
} else {
|
||||||
@ -957,8 +957,8 @@ void ShenandoahBarrierSetAssembler::generate_c1_load_reference_barrier_runtime_s
|
|||||||
#else
|
#else
|
||||||
__ load_parameter(0, rax);
|
__ load_parameter(0, rax);
|
||||||
__ load_parameter(1, rbx);
|
__ load_parameter(1, rbx);
|
||||||
if (is_native) {
|
if (is_weak) {
|
||||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native), rax, rbx);
|
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak), rax, rbx);
|
||||||
} else {
|
} else {
|
||||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier), rax, rbx);
|
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier), rax, rbx);
|
||||||
}
|
}
|
||||||
|
@ -70,11 +70,11 @@ public:
|
|||||||
void gen_pre_barrier_stub(LIR_Assembler* ce, ShenandoahPreBarrierStub* stub);
|
void gen_pre_barrier_stub(LIR_Assembler* ce, ShenandoahPreBarrierStub* stub);
|
||||||
void gen_load_reference_barrier_stub(LIR_Assembler* ce, ShenandoahLoadReferenceBarrierStub* stub);
|
void gen_load_reference_barrier_stub(LIR_Assembler* ce, ShenandoahLoadReferenceBarrierStub* stub);
|
||||||
void generate_c1_pre_barrier_runtime_stub(StubAssembler* sasm);
|
void generate_c1_pre_barrier_runtime_stub(StubAssembler* sasm);
|
||||||
void generate_c1_load_reference_barrier_runtime_stub(StubAssembler* sasm, bool is_native);
|
void generate_c1_load_reference_barrier_runtime_stub(StubAssembler* sasm, bool is_weak);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void load_reference_barrier(MacroAssembler* masm, Register dst, Address src);
|
void load_reference_barrier(MacroAssembler* masm, Register dst, Address src);
|
||||||
void load_reference_barrier_native(MacroAssembler* masm, Register dst, Address src);
|
void load_reference_barrier_weak(MacroAssembler* masm, Register dst, Address src);
|
||||||
|
|
||||||
void cmpxchg_oop(MacroAssembler* masm,
|
void cmpxchg_oop(MacroAssembler* masm,
|
||||||
Register res, Address addr, Register oldval, Register newval,
|
Register res, Address addr, Register oldval, Register newval,
|
||||||
|
@ -211,8 +211,8 @@ void ShenandoahBarrierSetC1::load_at_resolved(LIRAccess& access, LIR_Opr result)
|
|||||||
if (ShenandoahBarrierSet::need_load_reference_barrier(decorators, type)) {
|
if (ShenandoahBarrierSet::need_load_reference_barrier(decorators, type)) {
|
||||||
LIR_Opr tmp = gen->new_register(T_OBJECT);
|
LIR_Opr tmp = gen->new_register(T_OBJECT);
|
||||||
BarrierSetC1::load_at_resolved(access, tmp);
|
BarrierSetC1::load_at_resolved(access, tmp);
|
||||||
bool is_native = ShenandoahBarrierSet::use_load_reference_barrier_native(decorators, type);
|
bool is_weak = ShenandoahBarrierSet::use_load_reference_barrier_weak(decorators, type);
|
||||||
tmp = load_reference_barrier(gen, tmp, access.resolved_addr(), is_native);
|
tmp = load_reference_barrier(gen, tmp, access.resolved_addr(), is_weak);
|
||||||
__ move(tmp, result);
|
__ move(tmp, result);
|
||||||
} else {
|
} else {
|
||||||
BarrierSetC1::load_at_resolved(access, result);
|
BarrierSetC1::load_at_resolved(access, result);
|
||||||
@ -251,14 +251,14 @@ class C1ShenandoahPreBarrierCodeGenClosure : public StubAssemblerCodeGenClosure
|
|||||||
|
|
||||||
class C1ShenandoahLoadReferenceBarrierCodeGenClosure : public StubAssemblerCodeGenClosure {
|
class C1ShenandoahLoadReferenceBarrierCodeGenClosure : public StubAssemblerCodeGenClosure {
|
||||||
private:
|
private:
|
||||||
const bool _is_native;
|
const bool _is_weak;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
C1ShenandoahLoadReferenceBarrierCodeGenClosure(bool is_native) : _is_native(is_native) {}
|
C1ShenandoahLoadReferenceBarrierCodeGenClosure(bool is_weak) : _is_weak(is_weak) {}
|
||||||
|
|
||||||
virtual OopMapSet* generate_code(StubAssembler* sasm) {
|
virtual OopMapSet* generate_code(StubAssembler* sasm) {
|
||||||
ShenandoahBarrierSetAssembler* bs = (ShenandoahBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler();
|
ShenandoahBarrierSetAssembler* bs = (ShenandoahBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler();
|
||||||
bs->generate_c1_load_reference_barrier_runtime_stub(sasm, _is_native);
|
bs->generate_c1_load_reference_barrier_runtime_stub(sasm, _is_weak);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -274,9 +274,9 @@ void ShenandoahBarrierSetC1::generate_c1_runtime_stubs(BufferBlob* buffer_blob)
|
|||||||
"shenandoah_load_reference_barrier_slow",
|
"shenandoah_load_reference_barrier_slow",
|
||||||
false, &lrb_code_gen_cl);
|
false, &lrb_code_gen_cl);
|
||||||
|
|
||||||
C1ShenandoahLoadReferenceBarrierCodeGenClosure lrb_native_code_gen_cl(true);
|
C1ShenandoahLoadReferenceBarrierCodeGenClosure lrb_weak_code_gen_cl(true);
|
||||||
_load_reference_barrier_native_rt_code_blob = Runtime1::generate_blob(buffer_blob, -1,
|
_load_reference_barrier_weak_rt_code_blob = Runtime1::generate_blob(buffer_blob, -1,
|
||||||
"shenandoah_load_reference_barrier_native_slow",
|
"shenandoah_load_reference_barrier_weak_slow",
|
||||||
false, &lrb_native_code_gen_cl);
|
false, &lrb_weak_code_gen_cl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,10 +94,10 @@ private:
|
|||||||
LIR_Opr _result;
|
LIR_Opr _result;
|
||||||
LIR_Opr _tmp1;
|
LIR_Opr _tmp1;
|
||||||
LIR_Opr _tmp2;
|
LIR_Opr _tmp2;
|
||||||
bool _is_native;
|
bool _is_weak;
|
||||||
public:
|
public:
|
||||||
ShenandoahLoadReferenceBarrierStub(LIR_Opr obj, LIR_Opr addr, LIR_Opr result, LIR_Opr tmp1, LIR_Opr tmp2, bool is_native) :
|
ShenandoahLoadReferenceBarrierStub(LIR_Opr obj, LIR_Opr addr, LIR_Opr result, LIR_Opr tmp1, LIR_Opr tmp2, bool is_weak) :
|
||||||
_obj(obj), _addr(addr), _result(result), _tmp1(tmp1), _tmp2(tmp2), _is_native(is_native)
|
_obj(obj), _addr(addr), _result(result), _tmp1(tmp1), _tmp2(tmp2), _is_weak(is_weak)
|
||||||
{
|
{
|
||||||
assert(_obj->is_register(), "should be register");
|
assert(_obj->is_register(), "should be register");
|
||||||
assert(_addr->is_register(), "should be register");
|
assert(_addr->is_register(), "should be register");
|
||||||
@ -111,7 +111,7 @@ public:
|
|||||||
LIR_Opr result() const { return _result; }
|
LIR_Opr result() const { return _result; }
|
||||||
LIR_Opr tmp1() const { return _tmp1; }
|
LIR_Opr tmp1() const { return _tmp1; }
|
||||||
LIR_Opr tmp2() const { return _tmp2; }
|
LIR_Opr tmp2() const { return _tmp2; }
|
||||||
bool is_native() const { return _is_native; }
|
bool is_weak() const { return _is_weak; }
|
||||||
|
|
||||||
virtual void emit_code(LIR_Assembler* e);
|
virtual void emit_code(LIR_Assembler* e);
|
||||||
virtual void visit(LIR_OpVisitState* visitor) {
|
virtual void visit(LIR_OpVisitState* visitor) {
|
||||||
@ -191,7 +191,7 @@ class ShenandoahBarrierSetC1 : public BarrierSetC1 {
|
|||||||
private:
|
private:
|
||||||
CodeBlob* _pre_barrier_c1_runtime_code_blob;
|
CodeBlob* _pre_barrier_c1_runtime_code_blob;
|
||||||
CodeBlob* _load_reference_barrier_rt_code_blob;
|
CodeBlob* _load_reference_barrier_rt_code_blob;
|
||||||
CodeBlob* _load_reference_barrier_native_rt_code_blob;
|
CodeBlob* _load_reference_barrier_weak_rt_code_blob;
|
||||||
|
|
||||||
void pre_barrier(LIRGenerator* gen, CodeEmitInfo* info, DecoratorSet decorators, LIR_Opr addr_opr, LIR_Opr pre_val);
|
void pre_barrier(LIRGenerator* gen, CodeEmitInfo* info, DecoratorSet decorators, LIR_Opr addr_opr, LIR_Opr pre_val);
|
||||||
|
|
||||||
@ -215,9 +215,9 @@ public:
|
|||||||
return _load_reference_barrier_rt_code_blob;
|
return _load_reference_barrier_rt_code_blob;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeBlob* load_reference_barrier_native_rt_code_blob() {
|
CodeBlob* load_reference_barrier_weak_rt_code_blob() {
|
||||||
assert(_load_reference_barrier_native_rt_code_blob != NULL, "");
|
assert(_load_reference_barrier_weak_rt_code_blob != NULL, "");
|
||||||
return _load_reference_barrier_native_rt_code_blob;
|
return _load_reference_barrier_weak_rt_code_blob;
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -305,7 +305,7 @@ bool ShenandoahBarrierSetC2::is_shenandoah_lrb_call(Node* call) {
|
|||||||
address entry_point = call->as_CallLeaf()->entry_point();
|
address entry_point = call->as_CallLeaf()->entry_point();
|
||||||
return (entry_point == CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier)) ||
|
return (entry_point == CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier)) ||
|
||||||
(entry_point == CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow)) ||
|
(entry_point == CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow)) ||
|
||||||
(entry_point == CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native));
|
(entry_point == CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShenandoahBarrierSetC2::is_shenandoah_marking_if(PhaseTransform *phase, Node* n) {
|
bool ShenandoahBarrierSetC2::is_shenandoah_marking_if(PhaseTransform *phase, Node* n) {
|
||||||
@ -547,7 +547,7 @@ Node* ShenandoahBarrierSetC2::load_at_resolved(C2Access& access, const Type* val
|
|||||||
if (ShenandoahBarrierSet::need_load_reference_barrier(decorators, type)) {
|
if (ShenandoahBarrierSet::need_load_reference_barrier(decorators, type)) {
|
||||||
load = new ShenandoahLoadReferenceBarrierNode(NULL,
|
load = new ShenandoahLoadReferenceBarrierNode(NULL,
|
||||||
load,
|
load,
|
||||||
ShenandoahBarrierSet::use_load_reference_barrier_native(decorators, type));
|
ShenandoahBarrierSet::use_load_reference_barrier_weak(decorators, type));
|
||||||
if (access.is_parse_access()) {
|
if (access.is_parse_access()) {
|
||||||
load = static_cast<C2ParseAccess &>(access).kit()->gvn().transform(load);
|
load = static_cast<C2ParseAccess &>(access).kit()->gvn().transform(load);
|
||||||
} else {
|
} else {
|
||||||
@ -1063,12 +1063,12 @@ Node* ShenandoahBarrierSetC2::ideal_node(PhaseGVN* phase, Node* n, bool can_resh
|
|||||||
// If one input is NULL, then step over the barriers (except LRB native) on the other input
|
// If one input is NULL, then step over the barriers (except LRB native) on the other input
|
||||||
if (in1->bottom_type() == TypePtr::NULL_PTR &&
|
if (in1->bottom_type() == TypePtr::NULL_PTR &&
|
||||||
!((in2->Opcode() == Op_ShenandoahLoadReferenceBarrier) &&
|
!((in2->Opcode() == Op_ShenandoahLoadReferenceBarrier) &&
|
||||||
((ShenandoahLoadReferenceBarrierNode*)in2)->is_native())) {
|
((ShenandoahLoadReferenceBarrierNode*)in2)->is_weak())) {
|
||||||
in2 = step_over_gc_barrier(in2);
|
in2 = step_over_gc_barrier(in2);
|
||||||
}
|
}
|
||||||
if (in2->bottom_type() == TypePtr::NULL_PTR &&
|
if (in2->bottom_type() == TypePtr::NULL_PTR &&
|
||||||
!((in1->Opcode() == Op_ShenandoahLoadReferenceBarrier) &&
|
!((in1->Opcode() == Op_ShenandoahLoadReferenceBarrier) &&
|
||||||
((ShenandoahLoadReferenceBarrierNode*)in1)->is_native())) {
|
((ShenandoahLoadReferenceBarrierNode*)in1)->is_weak())) {
|
||||||
in1 = step_over_gc_barrier(in1);
|
in1 = step_over_gc_barrier(in1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -956,7 +956,7 @@ void ShenandoahBarrierC2Support::test_in_cset(Node*& ctrl, Node*& not_cset_ctrl,
|
|||||||
phase->register_new_node(cset_bool, old_ctrl);
|
phase->register_new_node(cset_bool, old_ctrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShenandoahBarrierC2Support::call_lrb_stub(Node*& ctrl, Node*& val, Node* load_addr, Node*& result_mem, Node* raw_mem, bool is_native, PhaseIdealLoop* phase) {
|
void ShenandoahBarrierC2Support::call_lrb_stub(Node*& ctrl, Node*& val, Node* load_addr, Node*& result_mem, Node* raw_mem, bool is_weak, PhaseIdealLoop* phase) {
|
||||||
IdealLoopTree*loop = phase->get_loop(ctrl);
|
IdealLoopTree*loop = phase->get_loop(ctrl);
|
||||||
const TypePtr* obj_type = phase->igvn().type(val)->is_oopptr();
|
const TypePtr* obj_type = phase->igvn().type(val)->is_oopptr();
|
||||||
|
|
||||||
@ -971,9 +971,9 @@ void ShenandoahBarrierC2Support::call_lrb_stub(Node*& ctrl, Node*& val, Node* lo
|
|||||||
CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow) :
|
CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow) :
|
||||||
CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier);
|
CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier);
|
||||||
|
|
||||||
address calladdr = is_native ? CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native)
|
address calladdr = is_weak ? CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak)
|
||||||
: target;
|
: target;
|
||||||
const char* name = is_native ? "load_reference_barrier_native" : "load_reference_barrier";
|
const char* name = is_weak ? "load_reference_barrier_native" : "load_reference_barrier";
|
||||||
Node* call = new CallLeafNode(ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type(), calladdr, name, TypeRawPtr::BOTTOM);
|
Node* call = new CallLeafNode(ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type(), calladdr, name, TypeRawPtr::BOTTOM);
|
||||||
|
|
||||||
call->init_req(TypeFunc::Control, ctrl);
|
call->init_req(TypeFunc::Control, ctrl);
|
||||||
@ -1338,7 +1338,7 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
|
|||||||
// even for non-cset objects to prevent ressurrection of such objects.
|
// even for non-cset objects to prevent ressurrection of such objects.
|
||||||
// Wires !in_cset(obj) to slot 2 of region and phis
|
// Wires !in_cset(obj) to slot 2 of region and phis
|
||||||
Node* not_cset_ctrl = NULL;
|
Node* not_cset_ctrl = NULL;
|
||||||
if (!lrb->is_native()) {
|
if (!lrb->is_weak()) {
|
||||||
test_in_cset(ctrl, not_cset_ctrl, val, raw_mem, phase);
|
test_in_cset(ctrl, not_cset_ctrl, val, raw_mem, phase);
|
||||||
}
|
}
|
||||||
if (not_cset_ctrl != NULL) {
|
if (not_cset_ctrl != NULL) {
|
||||||
@ -1389,7 +1389,7 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
call_lrb_stub(ctrl, val, addr, result_mem, raw_mem, lrb->is_native(), phase);
|
call_lrb_stub(ctrl, val, addr, result_mem, raw_mem, lrb->is_weak(), phase);
|
||||||
region->init_req(_evac_path, ctrl);
|
region->init_req(_evac_path, ctrl);
|
||||||
val_phi->init_req(_evac_path, val);
|
val_phi->init_req(_evac_path, val);
|
||||||
raw_mem_phi->init_req(_evac_path, result_mem);
|
raw_mem_phi->init_req(_evac_path, result_mem);
|
||||||
@ -2879,13 +2879,13 @@ void MemoryGraphFixer::fix_memory_uses(Node* mem, Node* replacement, Node* rep_p
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ShenandoahLoadReferenceBarrierNode::ShenandoahLoadReferenceBarrierNode(Node* ctrl, Node* obj, bool native)
|
ShenandoahLoadReferenceBarrierNode::ShenandoahLoadReferenceBarrierNode(Node* ctrl, Node* obj, bool weak)
|
||||||
: Node(ctrl, obj), _native(native) {
|
: Node(ctrl, obj), _weak(weak) {
|
||||||
ShenandoahBarrierSetC2::bsc2()->state()->add_load_reference_barrier(this);
|
ShenandoahBarrierSetC2::bsc2()->state()->add_load_reference_barrier(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShenandoahLoadReferenceBarrierNode::is_native() const {
|
bool ShenandoahLoadReferenceBarrierNode::is_weak() const {
|
||||||
return _native;
|
return _weak;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint ShenandoahLoadReferenceBarrierNode::size_of() const {
|
uint ShenandoahLoadReferenceBarrierNode::size_of() const {
|
||||||
@ -2893,12 +2893,12 @@ uint ShenandoahLoadReferenceBarrierNode::size_of() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint ShenandoahLoadReferenceBarrierNode::hash() const {
|
uint ShenandoahLoadReferenceBarrierNode::hash() const {
|
||||||
return Node::hash() + (_native ? 1 : 0);
|
return Node::hash() + (_weak ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShenandoahLoadReferenceBarrierNode::cmp( const Node &n ) const {
|
bool ShenandoahLoadReferenceBarrierNode::cmp( const Node &n ) const {
|
||||||
return Node::cmp(n) && n.Opcode() == Op_ShenandoahLoadReferenceBarrier &&
|
return Node::cmp(n) && n.Opcode() == Op_ShenandoahLoadReferenceBarrier &&
|
||||||
_native == ((const ShenandoahLoadReferenceBarrierNode&)n)._native;
|
_weak == ((const ShenandoahLoadReferenceBarrierNode&)n)._weak;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Type* ShenandoahLoadReferenceBarrierNode::bottom_type() const {
|
const Type* ShenandoahLoadReferenceBarrierNode::bottom_type() const {
|
||||||
|
@ -60,7 +60,7 @@ private:
|
|||||||
static void test_null(Node*& ctrl, Node* val, Node*& null_ctrl, PhaseIdealLoop* phase);
|
static void test_null(Node*& ctrl, Node* val, Node*& null_ctrl, PhaseIdealLoop* phase);
|
||||||
static void test_gc_state(Node*& ctrl, Node* raw_mem, Node*& heap_stable_ctrl,
|
static void test_gc_state(Node*& ctrl, Node* raw_mem, Node*& heap_stable_ctrl,
|
||||||
PhaseIdealLoop* phase, int flags);
|
PhaseIdealLoop* phase, int flags);
|
||||||
static void call_lrb_stub(Node*& ctrl, Node*& val, Node* load_addr, Node*& result_mem, Node* raw_mem, bool is_native, PhaseIdealLoop* phase);
|
static void call_lrb_stub(Node*& ctrl, Node*& val, Node* load_addr, Node*& result_mem, Node* raw_mem, bool is_weak, PhaseIdealLoop* phase);
|
||||||
static void test_in_cset(Node*& ctrl, Node*& not_cset_ctrl, Node* val, Node* raw_mem, PhaseIdealLoop* phase);
|
static void test_in_cset(Node*& ctrl, Node*& not_cset_ctrl, Node* val, Node* raw_mem, PhaseIdealLoop* phase);
|
||||||
static void move_gc_state_test_out_of_loop(IfNode* iff, PhaseIdealLoop* phase);
|
static void move_gc_state_test_out_of_loop(IfNode* iff, PhaseIdealLoop* phase);
|
||||||
static void merge_back_to_back_tests(Node* n, PhaseIdealLoop* phase);
|
static void merge_back_to_back_tests(Node* n, PhaseIdealLoop* phase);
|
||||||
@ -229,12 +229,12 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _native;
|
bool _weak;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ShenandoahLoadReferenceBarrierNode(Node* ctrl, Node* val, bool native);
|
ShenandoahLoadReferenceBarrierNode(Node* ctrl, Node* val, bool native);
|
||||||
|
|
||||||
bool is_native() const;
|
bool is_weak() const;
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
virtual const Type* bottom_type() const;
|
virtual const Type* bottom_type() const;
|
||||||
virtual const Type* Value(PhaseGVN* phase) const;
|
virtual const Type* Value(PhaseGVN* phase) const;
|
||||||
|
@ -87,7 +87,7 @@ bool ShenandoahBarrierSet::need_load_reference_barrier(DecoratorSet decorators,
|
|||||||
return is_reference_type(type);
|
return is_reference_type(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShenandoahBarrierSet::use_load_reference_barrier_native(DecoratorSet decorators, BasicType type) {
|
bool ShenandoahBarrierSet::use_load_reference_barrier_weak(DecoratorSet decorators, BasicType type) {
|
||||||
assert(need_load_reference_barrier(decorators, type), "Should be subset of LRB");
|
assert(need_load_reference_barrier(decorators, type), "Should be subset of LRB");
|
||||||
assert(is_reference_type(type), "Why we here?");
|
assert(is_reference_type(type), "Why we here?");
|
||||||
// Native load reference barrier is only needed for concurrent root processing
|
// Native load reference barrier is only needed for concurrent root processing
|
||||||
@ -95,7 +95,7 @@ bool ShenandoahBarrierSet::use_load_reference_barrier_native(DecoratorSet decora
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (decorators & IN_NATIVE) != 0;
|
return ((decorators & IN_NATIVE) != 0) && ((decorators & ON_STRONG_OOP_REF) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShenandoahBarrierSet::need_keep_alive_barrier(DecoratorSet decorators,BasicType type) {
|
bool ShenandoahBarrierSet::need_keep_alive_barrier(DecoratorSet decorators,BasicType type) {
|
||||||
|
@ -53,7 +53,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool need_load_reference_barrier(DecoratorSet decorators, BasicType type);
|
static bool need_load_reference_barrier(DecoratorSet decorators, BasicType type);
|
||||||
static bool use_load_reference_barrier_native(DecoratorSet decorators, BasicType type);
|
static bool use_load_reference_barrier_weak(DecoratorSet decorators, BasicType type);
|
||||||
static bool need_keep_alive_barrier(DecoratorSet decorators, BasicType type);
|
static bool need_keep_alive_barrier(DecoratorSet decorators, BasicType type);
|
||||||
|
|
||||||
void print_on(outputStream* st) const;
|
void print_on(outputStream* st) const;
|
||||||
@ -92,8 +92,8 @@ public:
|
|||||||
template <class T>
|
template <class T>
|
||||||
inline oop load_reference_barrier_mutator(oop obj, T* load_addr);
|
inline oop load_reference_barrier_mutator(oop obj, T* load_addr);
|
||||||
|
|
||||||
template <class T>
|
template <DecoratorSet decorators, class T>
|
||||||
inline oop load_reference_barrier_native(oop obj, T* load_addr);
|
inline oop load_reference_barrier(oop obj, T* load_addr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <class T>
|
template <class T>
|
||||||
|
@ -99,18 +99,19 @@ inline oop ShenandoahBarrierSet::load_reference_barrier(oop obj) {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <DecoratorSet decorators, class T>
|
||||||
inline oop ShenandoahBarrierSet::load_reference_barrier_native(oop obj, T* load_addr) {
|
inline oop ShenandoahBarrierSet::load_reference_barrier(oop obj, T* load_addr) {
|
||||||
if (CompressedOops::is_null(obj)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ShenandoahMarkingContext* const marking_context = _heap->marking_context();
|
// Prevent resurrection of unreachable non-strorg references.
|
||||||
if (_heap->is_concurrent_weak_root_in_progress() && !marking_context->is_marked(obj)) {
|
if (!HasDecorator<decorators, ON_STRONG_OOP_REF>::value && obj != NULL &&
|
||||||
|
_heap->is_concurrent_weak_root_in_progress() &&
|
||||||
|
!_heap->marking_context()->is_marked(obj)) {
|
||||||
Thread* thr = Thread::current();
|
Thread* thr = Thread::current();
|
||||||
if (thr->is_Java_thread()) {
|
if (thr->is_Java_thread()) {
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
|
// This path is sometimes (rarely) taken by GC threads.
|
||||||
|
// See e.g.: https://bugs.openjdk.java.net/browse/JDK-8237874
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -186,7 +187,7 @@ inline oop ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_loa
|
|||||||
oop value = Raw::oop_load_not_in_heap(addr);
|
oop value = Raw::oop_load_not_in_heap(addr);
|
||||||
if (value != NULL) {
|
if (value != NULL) {
|
||||||
ShenandoahBarrierSet *const bs = ShenandoahBarrierSet::barrier_set();
|
ShenandoahBarrierSet *const bs = ShenandoahBarrierSet::barrier_set();
|
||||||
value = bs->load_reference_barrier_native(value, addr);
|
value = bs->load_reference_barrier<decorators, T>(value, addr);
|
||||||
bs->keep_alive_if_weak<decorators>(value);
|
bs->keep_alive_if_weak<decorators>(value);
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
|
@ -66,6 +66,6 @@ JRT_LEAF(void, ShenandoahRuntime::shenandoah_clone_barrier(oopDesc* src))
|
|||||||
ShenandoahBarrierSet::barrier_set()->clone_barrier(s);
|
ShenandoahBarrierSet::barrier_set()->clone_barrier(s);
|
||||||
JRT_END
|
JRT_END
|
||||||
|
|
||||||
JRT_LEAF(oopDesc*, ShenandoahRuntime::load_reference_barrier_native(oopDesc * src, oop* load_addr))
|
JRT_LEAF(oopDesc*, ShenandoahRuntime::load_reference_barrier_weak(oopDesc * src, oop* load_addr))
|
||||||
return (oopDesc*) ShenandoahBarrierSet::barrier_set()->load_reference_barrier_native(oop(src), load_addr);
|
return (oopDesc*) ShenandoahBarrierSet::barrier_set()->load_reference_barrier<ON_UNKNOWN_OOP_REF, oop>(oop(src), load_addr);
|
||||||
JRT_END
|
JRT_END
|
||||||
|
@ -41,7 +41,7 @@ public:
|
|||||||
static oopDesc* load_reference_barrier(oopDesc* src, oop* load_addr);
|
static oopDesc* load_reference_barrier(oopDesc* src, oop* load_addr);
|
||||||
static oopDesc* load_reference_barrier_narrow(oopDesc* src, narrowOop* load_addr);
|
static oopDesc* load_reference_barrier_narrow(oopDesc* src, narrowOop* load_addr);
|
||||||
|
|
||||||
static oopDesc* load_reference_barrier_native(oopDesc* src, oop* load_addr);
|
static oopDesc* load_reference_barrier_weak(oopDesc* src, oop* load_addr);
|
||||||
|
|
||||||
static void shenandoah_clone_barrier(oopDesc* src);
|
static void shenandoah_clone_barrier(oopDesc* src);
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user