--- 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 {