# HG changeset patch # User zgu # Date 1571682370 14400 # Node ID 190ec5fae2af2a012fe171aa233dc530a0124530 # Parent 559c46cd0e8bf24ce56b7d4133532f46417b7e05 8232712: Shenandoah: SIGBUS in load_reference_barrier_native Reviewed-by: shade, rkennke diff -r 559c46cd0e8b -r 190ec5fae2af src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp --- a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp Mon Oct 21 10:32:49 2019 -0700 +++ b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp Mon Oct 21 14:26:10 2019 -0400 @@ -262,7 +262,7 @@ __ leave(); } -void ShenandoahBarrierSetAssembler::load_reference_barrier_native(MacroAssembler* masm, Register dst, Register tmp) { +void ShenandoahBarrierSetAssembler::load_reference_barrier_native(MacroAssembler* masm, Register dst, Address load_addr) { if (!ShenandoahLoadRefBarrier) { return; } @@ -272,6 +272,8 @@ Label is_null; Label done; + __ block_comment("load_reference_barrier_native { "); + __ cbz(dst, is_null); __ enter(); @@ -285,6 +287,7 @@ __ mov(rscratch2, dst); __ push_call_clobbered_registers(); __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native)); + __ lea(r1, load_addr); __ mov(r0, rscratch2); __ blr(lr); __ mov(rscratch2, r0); @@ -294,6 +297,7 @@ __ bind(done); __ leave(); __ bind(is_null); + __ block_comment("} load_reference_barrier_native"); } void ShenandoahBarrierSetAssembler::storeval_barrier(MacroAssembler* masm, Register dst, Register tmp) { @@ -327,20 +331,32 @@ 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; + bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode(); + bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0 || is_traversal_mode; + + Register result_dst = dst; + + if (on_oop) { + // We want to preserve src + if (dst == src.base() || dst == src.index()) { + dst = rscratch1; + } + 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) { - 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 (not_in_heap && !is_traversal_mode) { + load_reference_barrier_native(masm, dst, src); + } else { + load_reference_barrier(masm, dst, tmp1); + } + + if (dst != result_dst) { + __ mov(result_dst, dst); + dst = result_dst; + } + if (ShenandoahKeepAliveBarrier && on_reference && keep_alive) { __ enter(); satb_write_barrier_pre(masm /* masm */, diff -r 559c46cd0e8b -r 190ec5fae2af src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.hpp --- a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.hpp Mon Oct 21 10:32:49 2019 -0700 +++ b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.hpp Mon Oct 21 14:26:10 2019 -0400 @@ -58,7 +58,7 @@ void resolve_forward_pointer_not_null(MacroAssembler* masm, Register dst, Register tmp = noreg); void load_reference_barrier(MacroAssembler* masm, Register dst, Register tmp); void load_reference_barrier_not_null(MacroAssembler* masm, Register dst, Register tmp); - void load_reference_barrier_native(MacroAssembler* masm, Register dst, Register tmp); + void load_reference_barrier_native(MacroAssembler* masm, Register dst, Address load_addr); address generate_shenandoah_lrb(StubCodeGenerator* cgen);