diff -r a3b046720c3b -r 83810b7d12e7 src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.cpp --- a/src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.cpp Wed Nov 06 21:49:30 2019 +0900 +++ b/src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.cpp Wed Nov 06 09:50:53 2019 -0500 @@ -25,6 +25,7 @@ #include "c1/c1_IR.hpp" #include "gc/shared/satbMarkQueue.hpp" #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp" +#include "gc/shenandoah/shenandoahConcurrentRoots.hpp" #include "gc/shenandoah/shenandoahHeap.hpp" #include "gc/shenandoah/shenandoahHeapRegion.hpp" #include "gc/shenandoah/shenandoahRuntime.hpp" @@ -203,46 +204,49 @@ } void ShenandoahBarrierSetC1::load_at_resolved(LIRAccess& access, LIR_Opr result) { + // 1: non-reference load, no additional barrier is needed if (!access.is_oop()) { BarrierSetC1::load_at_resolved(access, result); return; } LIRGenerator* gen = access.gen(); - DecoratorSet decorators = access.decorators(); - bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode(); - if ((decorators & IN_NATIVE) != 0 && !is_traversal_mode) { - assert(access.is_oop(), "IN_NATIVE access only for oop values"); - BarrierSetC1::load_at_resolved(access, result); - LIR_OprList* args = new LIR_OprList(); - LIR_Opr addr = access.resolved_addr(); - addr = ensure_in_register(gen, addr); - args->append(result); - args->append(addr); - BasicTypeList signature; - signature.append(T_OBJECT); - signature.append(T_ADDRESS); - LIR_Opr call_result = gen->call_runtime(&signature, args, - CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native), - objectType, NULL); - __ move(call_result, result); - } else { - if (ShenandoahLoadRefBarrier) { + // 2: load a reference from src location and apply LRB if ShenandoahLoadRefBarrier is set + if (ShenandoahLoadRefBarrier) { + // Native barrier is for concurrent root processing + bool in_native = (decorators & IN_NATIVE) != 0; + if (in_native && ShenandoahConcurrentRoots::can_do_concurrent_roots()) { + BarrierSetC1::load_at_resolved(access, result); + LIR_OprList* args = new LIR_OprList(); + LIR_Opr addr = access.resolved_addr(); + addr = ensure_in_register(gen, addr); + args->append(result); + args->append(addr); + BasicTypeList signature; + signature.append(T_OBJECT); + signature.append(T_ADDRESS); + LIR_Opr call_result = gen->call_runtime(&signature, args, + CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native), + objectType, NULL); + __ move(call_result, result); + } else { LIR_Opr tmp = gen->new_register(T_OBJECT); BarrierSetC1::load_at_resolved(access, tmp); - tmp = load_reference_barrier(access.gen(), tmp, access.resolved_addr()); + tmp = load_reference_barrier(gen, tmp, access.resolved_addr()); __ move(tmp, result); - } else { - BarrierSetC1::load_at_resolved(access, result); } + } else { + BarrierSetC1::load_at_resolved(access, result); } + // 3: apply keep-alive barrier if ShenandoahKeepAliveBarrier is set if (ShenandoahKeepAliveBarrier) { bool is_weak = (decorators & ON_WEAK_OOP_REF) != 0; bool is_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0; bool is_anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0; + bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode(); bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0 || is_traversal_mode; if ((is_weak || is_phantom || is_anonymous) && keep_alive) { @@ -252,13 +256,13 @@ Lcont_anonymous = new LabelObj(); generate_referent_check(access, Lcont_anonymous); } - pre_barrier(access.gen(), access.access_emit_info(), access.decorators(), LIR_OprFact::illegalOpr /* addr_opr */, + pre_barrier(gen, access.access_emit_info(), decorators, LIR_OprFact::illegalOpr /* addr_opr */, result /* pre_val */); if (is_anonymous) { __ branch_destination(Lcont_anonymous->label()); } } - } + } } class C1ShenandoahPreBarrierCodeGenClosure : public StubAssemblerCodeGenClosure {