src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp
changeset 55718 9fbc32392798
parent 55679 aa96c53c592b
child 55735 08893cf52ee9
--- a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp	Wed Jul 17 04:33:37 2019 -0700
+++ b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp	Sat Jul 13 12:14:24 2019 -0400
@@ -24,7 +24,7 @@
 #include "precompiled.hpp"
 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
 #include "gc/shenandoah/shenandoahForwarding.hpp"
-#include "gc/shenandoah/shenandoahHeap.hpp"
+#include "gc/shenandoah/shenandoahHeap.inline.hpp"
 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
 #include "gc/shenandoah/shenandoahHeuristics.hpp"
 #include "gc/shenandoah/shenandoahRuntime.hpp"
@@ -282,6 +282,40 @@
   __ leave();
 }
 
+void ShenandoahBarrierSetAssembler::load_reference_barrier_native(MacroAssembler* masm, Register dst, Register tmp) {
+  if (!ShenandoahLoadRefBarrier) {
+    return;
+  }
+
+  assert(dst != rscratch2, "need rscratch2");
+
+  Label is_null;
+  Label done;
+
+  __ cbz(dst, is_null);
+
+  __ enter();
+
+  Address gc_state(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
+  __ ldrb(rscratch2, gc_state);
+
+  // Check for heap in evacuation phase
+  __ tbz(rscratch2, ShenandoahHeap::EVACUATION_BITPOS, done);
+
+  __ mov(rscratch2, dst);
+  __ push_call_clobbered_registers();
+  __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native));
+  __ mov(r0, rscratch2);
+  __ blrt(lr, 1, 0, MacroAssembler::ret_type_integral);
+  __ mov(rscratch2, r0);
+  __ pop_call_clobbered_registers();
+  __ mov(dst, rscratch2);
+
+  __ bind(done);
+  __ leave();
+  __ bind(is_null);
+}
+
 void ShenandoahBarrierSetAssembler::storeval_barrier(MacroAssembler* masm, Register dst, Register tmp) {
   if (ShenandoahStoreValEnqueueBarrier) {
     // Save possibly live regs.
@@ -309,15 +343,25 @@
 void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
                                             Register dst, Address src, Register tmp1, Register tmp_thread) {
   bool on_oop = type == T_OBJECT || type == T_ARRAY;
+  bool not_in_heap = (decorators & IN_NATIVE) != 0;
   bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0;
   bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0;
   bool on_reference = on_weak || on_phantom;
+  bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0;
 
   BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
   if (on_oop) {
-    load_reference_barrier(masm, dst, tmp1);
-
-    if (ShenandoahKeepAliveBarrier && on_reference) {
+     if (not_in_heap) {
+       if (ShenandoahHeap::heap()->is_traversal_mode()) {
+         load_reference_barrier(masm, dst, tmp1);
+         keep_alive = true;
+       } else {
+         load_reference_barrier_native(masm, dst, tmp1);
+       }
+     } else {
+       load_reference_barrier(masm, dst, tmp1);
+     }
+    if (ShenandoahKeepAliveBarrier && on_reference && keep_alive) {
       __ enter();
       satb_write_barrier_pre(masm /* masm */,
                              noreg /* obj */,