diff --git a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp index 5b9552e215a..ad7bac4e067 100644 --- a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp @@ -407,7 +407,8 @@ void ShenandoahBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet tmp3 /* obj */, tmp2 /* pre_val */, rthread /* thread */, - tmp1 /* tmp */, + tmp1 /* tmp */, + rscratch1 /* tmp2 */, storing_non_null /* tosca_live */, false /* expand_call */); } diff --git a/src/hotspot/cpu/ppc/gc/shenandoah/shenandoahBarrierSetAssembler_ppc.cpp b/src/hotspot/cpu/ppc/gc/shenandoah/shenandoahBarrierSetAssembler_ppc.cpp index 1f1bc7622ed..fb43fbab211 100644 --- a/src/hotspot/cpu/ppc/gc/shenandoah/shenandoahBarrierSetAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/shenandoah/shenandoahBarrierSetAssembler_ppc.cpp @@ -50,14 +50,14 @@ #define __ masm-> -void ShenandoahBarrierSetAssembler::satb_write_barrier(MacroAssembler *masm, - Register base, RegisterOrConstant ind_or_offs, - Register tmp1, Register tmp2, Register tmp3, - MacroAssembler::PreservationLevel preservation_level) { +void ShenandoahBarrierSetAssembler::satb_barrier(MacroAssembler *masm, + Register base, RegisterOrConstant ind_or_offs, + Register tmp1, Register tmp2, Register tmp3, + MacroAssembler::PreservationLevel preservation_level) { if (ShenandoahSATBBarrier) { - __ block_comment("satb_write_barrier (shenandoahgc) {"); - satb_write_barrier_impl(masm, 0, base, ind_or_offs, tmp1, tmp2, tmp3, preservation_level); - __ block_comment("} satb_write_barrier (shenandoahgc)"); + __ block_comment("satb_barrier (shenandoahgc) {"); + satb_barrier_impl(masm, 0, base, ind_or_offs, tmp1, tmp2, tmp3, preservation_level); + __ block_comment("} satb_barrier (shenandoahgc)"); } } @@ -198,11 +198,12 @@ void ShenandoahBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, Dec // In "load mode", this register acts as a temporary register and must // thus not be 'noreg'. In "preloaded mode", its content will be sustained. // tmp1/tmp2: Temporary registers, one of which must be non-volatile in "preloaded mode". -void ShenandoahBarrierSetAssembler::satb_write_barrier_impl(MacroAssembler *masm, DecoratorSet decorators, - Register base, RegisterOrConstant ind_or_offs, - Register pre_val, - Register tmp1, Register tmp2, - MacroAssembler::PreservationLevel preservation_level) { +void ShenandoahBarrierSetAssembler::satb_barrier_impl(MacroAssembler *masm, DecoratorSet decorators, + Register base, RegisterOrConstant ind_or_offs, + Register pre_val, + Register tmp1, Register tmp2, + MacroAssembler::PreservationLevel preservation_level) { + assert(ShenandoahSATBBarrier, "Should be checked by caller"); assert_different_registers(tmp1, tmp2, pre_val, noreg); Label skip_barrier; @@ -574,13 +575,13 @@ void ShenandoahBarrierSetAssembler::load_at( if (ShenandoahBarrierSet::need_keep_alive_barrier(decorators, type)) { if (ShenandoahSATBBarrier) { __ block_comment("keep_alive_barrier (shenandoahgc) {"); - satb_write_barrier_impl(masm, 0, noreg, noreg, dst, tmp1, tmp2, preservation_level); + satb_barrier_impl(masm, 0, noreg, noreg, dst, tmp1, tmp2, preservation_level); __ block_comment("} keep_alive_barrier (shenandoahgc)"); } } } -void ShenandoahBarrierSetAssembler::store_check(MacroAssembler* masm, Register base, RegisterOrConstant ind_or_offs, Register tmp) { +void ShenandoahBarrierSetAssembler::card_barrier(MacroAssembler* masm, Register base, RegisterOrConstant ind_or_offs, Register tmp) { assert(ShenandoahCardBarrier, "Should have been checked by caller"); assert_different_registers(base, tmp, R0); @@ -603,21 +604,32 @@ void ShenandoahBarrierSetAssembler::store_at(MacroAssembler *masm, DecoratorSet Register base, RegisterOrConstant ind_or_offs, Register val, Register tmp1, Register tmp2, Register tmp3, MacroAssembler::PreservationLevel preservation_level) { - if (is_reference_type(type)) { - if (ShenandoahSATBBarrier) { - satb_write_barrier(masm, base, ind_or_offs, tmp1, tmp2, tmp3, preservation_level); - } + // 1: non-reference types require no barriers + if (!is_reference_type(type)) { + BarrierSetAssembler::store_at(masm, decorators, type, + base, ind_or_offs, + val, + tmp1, tmp2, tmp3, + preservation_level); } + bool storing_non_null = (val != noreg); + + // 2: pre-barrier: SATB needs the previous value + if (ShenandoahBarrierSet::need_satb_barrier(decorators, type)) { + satb_barrier(masm, base, ind_or_offs, tmp1, tmp2, tmp3, preservation_level); + } + + // Store! BarrierSetAssembler::store_at(masm, decorators, type, base, ind_or_offs, val, tmp1, tmp2, tmp3, preservation_level); - // No need for post barrier if storing null - if (ShenandoahCardBarrier && is_reference_type(type) && val != noreg) { - store_check(masm, base, ind_or_offs, tmp1); + // 3: post-barrier: card barrier needs store address + if (ShenandoahBarrierSet::need_card_barrier(decorators, type) && storing_non_null) { + card_barrier(masm, base, ind_or_offs, tmp1); } } diff --git a/src/hotspot/cpu/ppc/gc/shenandoah/shenandoahBarrierSetAssembler_ppc.hpp b/src/hotspot/cpu/ppc/gc/shenandoah/shenandoahBarrierSetAssembler_ppc.hpp index b058dcf1a2e..52615a740af 100644 --- a/src/hotspot/cpu/ppc/gc/shenandoah/shenandoahBarrierSetAssembler_ppc.hpp +++ b/src/hotspot/cpu/ppc/gc/shenandoah/shenandoahBarrierSetAssembler_ppc.hpp @@ -45,15 +45,15 @@ class ShenandoahBarrierSetAssembler: public BarrierSetAssembler { private: /* ==== Actual barrier implementations ==== */ - void satb_write_barrier_impl(MacroAssembler* masm, DecoratorSet decorators, - Register base, RegisterOrConstant ind_or_offs, - Register pre_val, - Register tmp1, Register tmp2, - MacroAssembler::PreservationLevel preservation_level); + void satb_barrier_impl(MacroAssembler* masm, DecoratorSet decorators, + Register base, RegisterOrConstant ind_or_offs, + Register pre_val, + Register tmp1, Register tmp2, + MacroAssembler::PreservationLevel preservation_level); - void store_check(MacroAssembler* masm, - Register base, RegisterOrConstant ind_or_offs, - Register tmp); + void card_barrier(MacroAssembler* masm, + Register base, RegisterOrConstant ind_or_offs, + Register tmp); void load_reference_barrier_impl(MacroAssembler* masm, DecoratorSet decorators, Register base, RegisterOrConstant ind_or_offs, @@ -85,10 +85,10 @@ public: #endif /* ==== Available barriers (facades of the actual implementations) ==== */ - void satb_write_barrier(MacroAssembler* masm, - Register base, RegisterOrConstant ind_or_offs, - Register tmp1, Register tmp2, Register tmp3, - MacroAssembler::PreservationLevel preservation_level); + void satb_barrier(MacroAssembler* masm, + Register base, RegisterOrConstant ind_or_offs, + Register tmp1, Register tmp2, Register tmp3, + MacroAssembler::PreservationLevel preservation_level); void load_reference_barrier(MacroAssembler* masm, DecoratorSet decorators, Register base, RegisterOrConstant ind_or_offs, diff --git a/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp index 56e59be531a..3cbbb783258 100644 --- a/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp @@ -426,7 +426,8 @@ void ShenandoahBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet tmp3 /* obj */, tmp2 /* pre_val */, xthread /* thread */, - tmp1 /* tmp */, + tmp1 /* tmp */, + t0 /* tmp2 */, storing_non_null /* tosca_live */, false /* expand_call */); } diff --git a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp index f1c67b0f27b..97829a10a3b 100644 --- a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp @@ -523,7 +523,7 @@ void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet d assert_different_registers(dst, tmp1, r15_thread); // Generate the SATB pre-barrier code to log the value of // the referent field in an SATB buffer. - satb_barrier(masm, + satb_barrier(masm /* masm */, noreg /* obj */, dst /* pre_val */, tmp1 /* tmp */,