src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.cpp
changeset 58946 83810b7d12e7
parent 58694 199ee1bf9b3b
child 58985 5606867a5e6e
--- 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 {