< prev index next >

src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp

Print this page
rev 56771 : 8233339: Shenandoah: Centralize load barrier decisions into ShenandoahBarrierSet

@@ -443,25 +443,33 @@
     load_reference_barrier_not_null(masm, dst, src);
     __ bind(done);
   }
 }
 
+//
+// Arguments:
+//
+// Inputs:
+//   src:        oop location, might be clobbered
+//   tmp1:       scratch register, might not be valid.
+//   tmp_thread: unused
+//
+// Output:
+//   dst:        oop loaded from src location
+//
+// Kill:
+//   tmp1 (if it is valid)
+//
 void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
              Register dst, Address src, Register tmp1, Register tmp_thread) {
-  bool on_oop = is_reference_type(type);
-  bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0;
-  bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0;
-  bool not_in_heap = (decorators & IN_NATIVE) != 0;
-  bool on_reference = on_weak || on_phantom;
-  bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode();
-  bool keep_alive = ((decorators & AS_NO_KEEPALIVE) == 0) || is_traversal_mode;
-
   Register result_dst = dst;
   bool use_tmp1_for_dst = false;
+  bool need_load_reference_barrier = ShenandoahBarrierSet::need_load_reference_barrier(decorators, type);
 
-  if (on_oop) {
-    // We want to preserve src
+  // Only preserve src address if we need load reference barrier
+  if (need_load_reference_barrier) {
+    // Use tmp1 or rdi as temporary output register to avoid clobbering src
     if (dst == src.base() || dst == src.index()) {
       // Use tmp1 for dst if possible, as it is not used in BarrierAssembler::load_at()
       if (tmp1->is_valid() && tmp1 != src.base() && tmp1 != src.index()) {
         dst = tmp1;
         use_tmp1_for_dst = true;

@@ -473,28 +481,30 @@
     assert_different_registers(dst, src.base(), src.index());
   }
 
   BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
 
-  if (on_oop) {
-    if (not_in_heap && !is_traversal_mode) {
+  if (!need_load_reference_barrier) return;
+
+  if (ShenandoahBarrierSet::use_native_load_reference_barrier(decorators, type)) {
       load_reference_barrier_native(masm, dst, src);
     } else {
       load_reference_barrier(masm, dst, src);
     }
 
+  // Move loaded oop to final destination
     if (dst != result_dst) {
       __ movptr(result_dst, dst);
 
       if (!use_tmp1_for_dst) {
         __ pop(dst);
       }
 
       dst = result_dst;
     }
 
-    if (ShenandoahKeepAliveBarrier && on_reference && keep_alive) {
+  if (ShenandoahBarrierSet::need_keep_alive_barrier(decorators, type)) {
       const Register thread = NOT_LP64(tmp_thread) LP64_ONLY(r15_thread);
       assert_different_registers(dst, tmp1, tmp_thread);
       NOT_LP64(__ get_thread(thread));
       // Generate the SATB pre-barrier code to log the value of
       // the referent field in an SATB buffer.

@@ -504,11 +514,10 @@
                                    thread /* thread */,
                                    tmp1 /* tmp */,
                                    true /* tosca_live */,
                                    true /* expand_call */);
     }
-  }
 }
 
 void ShenandoahBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
               Address dst, Register val, Register tmp1, Register tmp2) {
 
< prev index next >