diff --git a/src/hotspot/share/c1/c1_Compiler.cpp b/src/hotspot/share/c1/c1_Compiler.cpp index e1c4e90d063..a3d7eef5c22 100644 --- a/src/hotspot/share/c1/c1_Compiler.cpp +++ b/src/hotspot/share/c1/c1_Compiler.cpp @@ -146,6 +146,7 @@ bool Compiler::is_intrinsic_supported(vmIntrinsics::ID id) { // the referent field can be registered by the G1 pre-barrier code. // Also to prevent commoning reads from this field across safepoint // since GC can change its value. + case vmIntrinsics::_Reference_clear0: case vmIntrinsics::_loadFence: case vmIntrinsics::_storeFence: case vmIntrinsics::_storeStoreFence: diff --git a/src/hotspot/share/c1/c1_LIRGenerator.cpp b/src/hotspot/share/c1/c1_LIRGenerator.cpp index cd084135658..9b636b9da8d 100644 --- a/src/hotspot/share/c1/c1_LIRGenerator.cpp +++ b/src/hotspot/share/c1/c1_LIRGenerator.cpp @@ -3039,6 +3039,10 @@ void LIRGenerator::do_Intrinsic(Intrinsic* x) { do_blackhole(x); break; + case vmIntrinsics::_Reference_clear0: + do_Reference_clear(x); + break; + default: ShouldNotReachHere(); break; } } @@ -3447,6 +3451,47 @@ void LIRGenerator::do_blackhole(Intrinsic *x) { } } +void LIRGenerator::do_Reference_clear(Intrinsic* x) { + // This matches the implementation in JVM_ReferenceClear, see the comments there. + + assert(x->number_of_arguments() == 1, "wrong type"); + + LIRItem reference(x->argument_at(0), this); + reference.load_item(); + + // need to perform the null check on the reference object + CodeEmitInfo* info = nullptr; + if (x->needs_null_check()) { + info = state_for(x); + } + + DecoratorSet decorators = IN_HEAP | AS_NO_KEEPALIVE | ON_UNKNOWN_OOP_REF; + LIR_Opr referent_offset = LIR_OprFact::intConst(java_lang_ref_Reference::referent_offset()); + + LIR_Opr referent = new_register(T_OBJECT); + access_load_at(decorators, + T_OBJECT, + reference, + referent_offset, + referent, + nullptr, + info); + + LabelObj* L_null = new LabelObj(); + __ cmp(lir_cond_equal, referent, LIR_OprFact::oopConst(nullptr)); + __ branch(lir_cond_equal, L_null->label()); + + access_store_at(decorators, + T_OBJECT, + reference, + referent_offset, + LIR_OprFact::oopConst(nullptr), + nullptr, + info); + + __ branch_destination(L_null->label()); +} + LIR_Opr LIRGenerator::call_runtime(Value arg1, address entry, ValueType* result_type, CodeEmitInfo* info) { LIRItemList args(1); LIRItem value(arg1, this); diff --git a/src/hotspot/share/c1/c1_LIRGenerator.hpp b/src/hotspot/share/c1/c1_LIRGenerator.hpp index 518cd5fa5e7..f9b5c5fadd1 100644 --- a/src/hotspot/share/c1/c1_LIRGenerator.hpp +++ b/src/hotspot/share/c1/c1_LIRGenerator.hpp @@ -276,6 +276,7 @@ class LIRGenerator: public InstructionVisitor, public BlockClosure { void do_update_CRC32C(Intrinsic* x); void do_vectorizedMismatch(Intrinsic* x); void do_blackhole(Intrinsic* x); + void do_Reference_clear(Intrinsic* x); public: LIR_Opr call_runtime(BasicTypeArray* signature, LIRItemList* args, address entry, ValueType* result_type, CodeEmitInfo* info);