diff --git a/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp index 974527f30e907..3138c76c593e2 100644 --- a/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp @@ -347,7 +347,7 @@ void G1BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorator 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; - ModRefBarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp2); + CardTableBarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp2); if (on_oop && on_reference) { // LR is live. It must be saved around calls. __ enter(/*strip_ret_addr*/true); // barrier may call runtime diff --git a/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.hpp index 72040cd7ad26a..777a86e804b4c 100644 --- a/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.hpp @@ -26,7 +26,7 @@ #define CPU_AARCH64_GC_G1_G1BARRIERSETASSEMBLER_AARCH64_HPP #include "asm/macroAssembler.hpp" -#include "gc/shared/modRefBarrierSetAssembler.hpp" +#include "gc/shared/cardTableBarrierSetAssembler.hpp" #include "utilities/macros.hpp" class LIR_Assembler; @@ -34,7 +34,7 @@ class StubAssembler; class G1PreBarrierStub; class G1PreBarrierStubC2; -class G1BarrierSetAssembler: public ModRefBarrierSetAssembler { +class G1BarrierSetAssembler: public CardTableBarrierSetAssembler { protected: void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count, RegSet saved_regs); diff --git a/src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.cpp index ea36183c9de95..c039e55cd4d06 100644 --- a/src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.cpp @@ -32,6 +32,31 @@ #define __ masm-> +void CardTableBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, + Register src, Register dst, Register count, RegSet saved_regs) { + + if (is_oop) { + gen_write_ref_array_pre_barrier(masm, decorators, dst, count, saved_regs); + } +} + +void CardTableBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, + Register start, Register count, Register tmp, + RegSet saved_regs) { + if (is_oop) { + gen_write_ref_array_post_barrier(masm, decorators, start, count, tmp, saved_regs); + } +} + +void CardTableBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, + Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) { + if (is_reference_type(type)) { + oop_store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3); + } else { + BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3); + } +} + void CardTableBarrierSetAssembler::store_check(MacroAssembler* masm, Register obj, Address dst) { BarrierSet* bs = BarrierSet::barrier_set(); diff --git a/src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.hpp index d0d5e4c3d4c29..91a65710f4586 100644 --- a/src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.hpp @@ -26,17 +26,27 @@ #define CPU_AARCH64_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_AARCH64_HPP #include "asm/macroAssembler.hpp" -#include "gc/shared/modRefBarrierSetAssembler.hpp" +#include "gc/shared/barrierSetAssembler.hpp" -class CardTableBarrierSetAssembler: public ModRefBarrierSetAssembler { +class CardTableBarrierSetAssembler: public BarrierSetAssembler { protected: - void store_check(MacroAssembler* masm, Register obj, Address dst); + virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, + Register addr, Register count, RegSet saved_regs) {} virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register start, Register count, Register tmp, RegSet saved_regs); virtual void oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Address dst, Register val, Register tmp1, Register tmp2, Register tmp3); + virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, + Register src, Register dst, Register count, RegSet saved_regs); + + virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, + Register start, Register count, Register tmp, RegSet saved_regs); + virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, + Address dst, Register val, Register tmp1, Register tmp2, Register tmp3); + + void store_check(MacroAssembler* masm, Register obj, Address dst); }; #endif // CPU_AARCH64_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_AARCH64_HPP diff --git a/src/hotspot/cpu/aarch64/gc/shared/modRefBarrierSetAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/shared/modRefBarrierSetAssembler_aarch64.cpp deleted file mode 100644 index 6890159189310..0000000000000 --- a/src/hotspot/cpu/aarch64/gc/shared/modRefBarrierSetAssembler_aarch64.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "asm/macroAssembler.inline.hpp" -#include "gc/shared/modRefBarrierSetAssembler.hpp" - -#define __ masm-> - -void ModRefBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, - Register src, Register dst, Register count, RegSet saved_regs) { - - if (is_oop) { - gen_write_ref_array_pre_barrier(masm, decorators, dst, count, saved_regs); - } -} - -void ModRefBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, - Register start, Register count, Register tmp, - RegSet saved_regs) { - if (is_oop) { - gen_write_ref_array_post_barrier(masm, decorators, start, count, tmp, saved_regs); - } -} - -void ModRefBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) { - if (is_reference_type(type)) { - oop_store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3); - } else { - BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3); - } -} diff --git a/src/hotspot/cpu/aarch64/gc/shared/modRefBarrierSetAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/gc/shared/modRefBarrierSetAssembler_aarch64.hpp deleted file mode 100644 index 22f98441f4ea6..0000000000000 --- a/src/hotspot/cpu/aarch64/gc/shared/modRefBarrierSetAssembler_aarch64.hpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef CPU_AARCH64_GC_SHARED_MODREFBARRIERSETASSEMBLER_AARCH64_HPP -#define CPU_AARCH64_GC_SHARED_MODREFBARRIERSETASSEMBLER_AARCH64_HPP - -#include "asm/macroAssembler.hpp" -#include "gc/shared/barrierSetAssembler.hpp" - -// The ModRefBarrierSetAssembler filters away accesses on BasicTypes other -// than T_OBJECT/T_ARRAY (oops). The oop accesses call one of the protected -// accesses, which are overridden in the concrete BarrierSetAssembler. - -class ModRefBarrierSetAssembler: public BarrierSetAssembler { -protected: - virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, - Register addr, Register count, RegSet saved_regs) {} - virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, - Register start, Register count, Register tmp, RegSet saved_regs) {} - - virtual void oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) = 0; - -public: - virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, - Register src, Register dst, Register count, RegSet saved_regs); - virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, - Register start, Register count, Register tmp, RegSet saved_regs); - virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Address dst, Register val, Register tmp1, Register tmp2, Register tmp3); -}; - -#endif // CPU_AARCH64_GC_SHARED_MODREFBARRIERSETASSEMBLER_AARCH64_HPP diff --git a/src/hotspot/cpu/arm/gc/g1/g1BarrierSetAssembler_arm.cpp b/src/hotspot/cpu/arm/gc/g1/g1BarrierSetAssembler_arm.cpp index 74a9f273a4328..e8ac1f56bdab6 100644 --- a/src/hotspot/cpu/arm/gc/g1/g1BarrierSetAssembler_arm.cpp +++ b/src/hotspot/cpu/arm/gc/g1/g1BarrierSetAssembler_arm.cpp @@ -320,7 +320,7 @@ void G1BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorator bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0; bool on_reference = on_weak || on_phantom; - ModRefBarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp2, tmp3); + CardTableBarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp2, tmp3); if (on_oop && on_reference) { // Generate the G1 pre-barrier code to log the value of // the referent field in an SATB buffer. diff --git a/src/hotspot/cpu/arm/gc/g1/g1BarrierSetAssembler_arm.hpp b/src/hotspot/cpu/arm/gc/g1/g1BarrierSetAssembler_arm.hpp index 9e0eff4601b7c..e3c8cf46600d9 100644 --- a/src/hotspot/cpu/arm/gc/g1/g1BarrierSetAssembler_arm.hpp +++ b/src/hotspot/cpu/arm/gc/g1/g1BarrierSetAssembler_arm.hpp @@ -26,7 +26,7 @@ #define CPU_ARM_GC_G1_G1BARRIERSETASSEMBLER_ARM_HPP #include "asm/macroAssembler.hpp" -#include "gc/shared/modRefBarrierSetAssembler.hpp" +#include "gc/shared/cardTableBarrierSetAssembler.hpp" #include "utilities/macros.hpp" class LIR_Assembler; @@ -34,7 +34,7 @@ class StubAssembler; class G1PreBarrierStub; class G1PreBarrierStubC2; -class G1BarrierSetAssembler: public ModRefBarrierSetAssembler { +class G1BarrierSetAssembler: public CardTableBarrierSetAssembler { protected: void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count, int callee_saved_regs); diff --git a/src/hotspot/cpu/arm/gc/shared/cardTableBarrierSetAssembler_arm.cpp b/src/hotspot/cpu/arm/gc/shared/cardTableBarrierSetAssembler_arm.cpp index 91d3b8e9e5cee..2427d46cafa5f 100644 --- a/src/hotspot/cpu/arm/gc/shared/cardTableBarrierSetAssembler_arm.cpp +++ b/src/hotspot/cpu/arm/gc/shared/cardTableBarrierSetAssembler_arm.cpp @@ -40,6 +40,30 @@ #define BIND(label) bind(label); BLOCK_COMMENT(#label ":") +void CardTableBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, + Register addr, Register count, int callee_saved_regs) { + + if (is_oop) { + gen_write_ref_array_pre_barrier(masm, decorators, addr, count, callee_saved_regs); + } +} + +void CardTableBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, + Register addr, Register count, Register tmp) { + if (is_oop) { + gen_write_ref_array_post_barrier(masm, decorators, addr, count, tmp); + } +} + +void CardTableBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, + Address obj, Register new_val, Register tmp1, Register tmp2, Register tmp3, bool is_null) { + if (type == T_OBJECT || type == T_ARRAY) { + oop_store_at(masm, decorators, type, obj, new_val, tmp1, tmp2, tmp3, is_null); + } else { + BarrierSetAssembler::store_at(masm, decorators, type, obj, new_val, tmp1, tmp2, tmp3, is_null); + } +} + void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count, Register tmp) { BLOCK_COMMENT("CardTablePostBarrier"); diff --git a/src/hotspot/cpu/arm/gc/shared/cardTableBarrierSetAssembler_arm.hpp b/src/hotspot/cpu/arm/gc/shared/cardTableBarrierSetAssembler_arm.hpp index e08a68445a892..ce767754294bd 100644 --- a/src/hotspot/cpu/arm/gc/shared/cardTableBarrierSetAssembler_arm.hpp +++ b/src/hotspot/cpu/arm/gc/shared/cardTableBarrierSetAssembler_arm.hpp @@ -26,9 +26,9 @@ #define CPU_ARM_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_ARM_HPP #include "asm/macroAssembler.hpp" -#include "gc/shared/modRefBarrierSetAssembler.hpp" +#include "gc/shared/barrierSetAssembler.hpp" -class CardTableBarrierSetAssembler: public ModRefBarrierSetAssembler { +class CardTableBarrierSetAssembler: public BarrierSetAssembler { private: void store_check(MacroAssembler* masm, Register obj, Address dst); void store_check_part1(MacroAssembler* masm, Register card_table_base); @@ -37,10 +37,23 @@ class CardTableBarrierSetAssembler: public ModRefBarrierSetAssembler { void set_card(MacroAssembler* masm, Register card_table_base, Address card_table_addr, Register tmp); protected: + virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, + Register addr, Register count, int callee_saved_regs) {} + virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count, Register tmp); + virtual void oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Address obj, Register new_val, Register tmp1, Register tmp2, Register tmp3, bool is_null); + +public: + virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, + Register addr, Register count, int callee_saved_regs); + virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, + Register addr, Register count, Register tmp); + virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, + Address obj, Register val, Register tmp1, Register tmp2, Register tmp3, bool is_null); + }; #endif // CPU_ARM_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_ARM_HPP diff --git a/src/hotspot/cpu/arm/gc/shared/modRefBarrierSetAssembler_arm.cpp b/src/hotspot/cpu/arm/gc/shared/modRefBarrierSetAssembler_arm.cpp deleted file mode 100644 index cb4058d48edb9..0000000000000 --- a/src/hotspot/cpu/arm/gc/shared/modRefBarrierSetAssembler_arm.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "asm/macroAssembler.inline.hpp" -#include "gc/shared/modRefBarrierSetAssembler.hpp" - -#define __ masm-> - -void ModRefBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, - Register addr, Register count, int callee_saved_regs) { - - if (is_oop) { - gen_write_ref_array_pre_barrier(masm, decorators, addr, count, callee_saved_regs); - } -} - -void ModRefBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, - Register addr, Register count, Register tmp) { - if (is_oop) { - gen_write_ref_array_post_barrier(masm, decorators, addr, count, tmp); - } -} - -void ModRefBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Address obj, Register new_val, Register tmp1, Register tmp2, Register tmp3, bool is_null) { - if (type == T_OBJECT || type == T_ARRAY) { - oop_store_at(masm, decorators, type, obj, new_val, tmp1, tmp2, tmp3, is_null); - } else { - BarrierSetAssembler::store_at(masm, decorators, type, obj, new_val, tmp1, tmp2, tmp3, is_null); - } -} diff --git a/src/hotspot/cpu/arm/gc/shared/modRefBarrierSetAssembler_arm.hpp b/src/hotspot/cpu/arm/gc/shared/modRefBarrierSetAssembler_arm.hpp deleted file mode 100644 index e41d8dc47271d..0000000000000 --- a/src/hotspot/cpu/arm/gc/shared/modRefBarrierSetAssembler_arm.hpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef CPU_ARM_GC_SHARED_MODREFBARRIERSETASSEMBLER_ARM_HPP -#define CPU_ARM_GC_SHARED_MODREFBARRIERSETASSEMBLER_ARM_HPP - -#include "asm/macroAssembler.hpp" -#include "gc/shared/barrierSetAssembler.hpp" - -// The ModRefBarrierSetAssembler filters away accesses on BasicTypes other -// than T_OBJECT/T_ARRAY (oops). The oop accesses call one of the protected -// accesses, which are overridden in the concrete BarrierSetAssembler. - -class ModRefBarrierSetAssembler: public BarrierSetAssembler { -protected: - virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, - Register addr, Register count, int callee_saved_regs) {} - virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, - Register addr, Register count, Register tmp) {} - - virtual void oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Address obj, Register val, Register tmp1, Register tmp2, Register tmp3, bool is_null) = 0; - -public: - virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, - Register addr, Register count, int callee_saved_regs); - virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, - Register addr, Register count, Register tmp); - virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Address obj, Register val, Register tmp1, Register tmp2, Register tmp3, bool is_null); -}; - -#endif // CPU_ARM_GC_SHARED_MODREFBARRIERSETASSEMBLER_ARM_HPP diff --git a/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.cpp b/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.cpp index 65bfd683abde0..5c3e1302ed38b 100644 --- a/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.cpp @@ -321,10 +321,10 @@ void G1BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorator Label done; if (on_oop && on_reference && L_handle_null == nullptr) { L_handle_null = &done; } // Load the value of the referent field. - ModRefBarrierSetAssembler::load_at(masm, decorators, type, - base, ind_or_offs, dst, - tmp1, tmp2, - preservation_level, L_handle_null); + CardTableBarrierSetAssembler::load_at(masm, decorators, type, + base, ind_or_offs, dst, + tmp1, tmp2, + preservation_level, L_handle_null); if (on_oop && on_reference) { // Generate the G1 pre-barrier code to log the value of // the referent field in an SATB buffer. Note with diff --git a/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.hpp b/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.hpp index e059cc661af81..a72dfb80ee4f5 100644 --- a/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.hpp +++ b/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.hpp @@ -27,7 +27,7 @@ #define CPU_PPC_GC_G1_G1BARRIERSETASSEMBLER_PPC_HPP #include "asm/macroAssembler.hpp" -#include "gc/shared/modRefBarrierSetAssembler.hpp" +#include "gc/shared/cardTableBarrierSetAssembler.hpp" #include "utilities/macros.hpp" #ifdef COMPILER2 @@ -39,7 +39,7 @@ class StubAssembler; class G1PreBarrierStub; class G1PreBarrierStubC2; -class G1BarrierSetAssembler: public ModRefBarrierSetAssembler { +class G1BarrierSetAssembler: public CardTableBarrierSetAssembler { protected: virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, Register from, Register to, Register count, diff --git a/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.cpp b/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.cpp index e1272ce508d72..7404f7e2e5cbf 100644 --- a/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.cpp @@ -29,6 +29,7 @@ #include "gc/shared/cardTableBarrierSet.hpp" #include "gc/shared/cardTableBarrierSetAssembler.hpp" #include "interpreter/interp_masm.hpp" +#include "runtime/jniHandles.hpp" #define __ masm-> @@ -40,6 +41,66 @@ #define BIND(label) bind(label); BLOCK_COMMENT(#label ":") +void CardTableBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, + Register src, Register dst, Register count, Register preserve1, Register preserve2) { + if (type == T_OBJECT) { + gen_write_ref_array_pre_barrier(masm, decorators, + src, dst, count, + preserve1, preserve2); + + bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0; + if (!checkcast) { + assert_different_registers(dst, count, R9_ARG7, R10_ARG8); + // Save some arguments for epilogue, e.g. disjoint_long_copy_core destroys them. + __ mr(R9_ARG7, dst); + __ mr(R10_ARG8, count); + } + } +} + +void CardTableBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, + Register dst, Register count, Register preserve) { + if (type == T_OBJECT) { + bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0; + if (!checkcast) { + gen_write_ref_array_post_barrier(masm, decorators, R9_ARG7, R10_ARG8, preserve); + } else { + gen_write_ref_array_post_barrier(masm, decorators, dst, count, preserve); + } + } +} + +void CardTableBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, + Register base, RegisterOrConstant ind_or_offs, Register val, + Register tmp1, Register tmp2, Register tmp3, + MacroAssembler::PreservationLevel preservation_level) { + if (is_reference_type(type)) { + oop_store_at(masm, decorators, type, + base, ind_or_offs, val, + tmp1, tmp2, tmp3, + preservation_level); + } else { + BarrierSetAssembler::store_at(masm, decorators, type, + base, ind_or_offs, val, + tmp1, tmp2, tmp3, + preservation_level); + } +} + +void CardTableBarrierSetAssembler::resolve_jobject(MacroAssembler* masm, Register value, + Register tmp1, Register tmp2, + MacroAssembler::PreservationLevel preservation_level) { + Label done; + __ cmpdi(CR0, value, 0); + __ beq(CR0, done); // Use null as-is. + + __ clrrdi(tmp1, value, JNIHandles::tag_size); + __ ld(value, 0, tmp1); // Resolve (untagged) jobject. + + __ verify_oop(value, FILE_AND_LINE); + __ bind(done); +} + void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count, Register preserve) { CardTableBarrierSet* ctbs = barrier_set_cast(BarrierSet::barrier_set()); diff --git a/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.hpp b/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.hpp index 7d8e59e2c985c..261d6ef85d9cc 100644 --- a/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.hpp +++ b/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.hpp @@ -27,21 +27,42 @@ #define CPU_PPC_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_PPC_HPP #include "asm/macroAssembler.hpp" -#include "gc/shared/modRefBarrierSetAssembler.hpp" +#include "gc/shared/barrierSetAssembler.hpp" -class CardTableBarrierSetAssembler: public ModRefBarrierSetAssembler { +class CardTableBarrierSetAssembler: public BarrierSetAssembler { protected: - virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, - Register addr, Register count, Register preserve); - void card_table_write(MacroAssembler* masm, CardTable::CardValue* byte_map_base, Register tmp, Register obj); void card_write_barrier_post(MacroAssembler* masm, Register store_addr, Register tmp); + virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, + Register from, Register to, Register count, + Register preserve1, Register preserve2) {} + virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, + Register addr, Register count, Register preserve); + virtual void oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Register base, RegisterOrConstant ind_or_offs, Register val, Register tmp1, Register tmp2, Register tmp3, MacroAssembler::PreservationLevel preservation_level); + +public: + virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, + Register src, Register dst, Register count, + Register preserve1, Register preserve2); + virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, + Register dst, Register count, + Register preserve); + + virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, + Register base, RegisterOrConstant ind_or_offs, Register val, + Register tmp1, Register tmp2, Register tmp3, + MacroAssembler::PreservationLevel preservation_level); + + virtual void resolve_jobject(MacroAssembler* masm, Register value, + Register tmp1, Register tmp2, + MacroAssembler::PreservationLevel preservation_level); + }; #endif // CPU_PPC_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_PPC_HPP diff --git a/src/hotspot/cpu/ppc/gc/shared/modRefBarrierSetAssembler_ppc.cpp b/src/hotspot/cpu/ppc/gc/shared/modRefBarrierSetAssembler_ppc.cpp deleted file mode 100644 index 4cdf56f6ad60c..0000000000000 --- a/src/hotspot/cpu/ppc/gc/shared/modRefBarrierSetAssembler_ppc.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2018, 2025 SAP SE. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "asm/macroAssembler.inline.hpp" -#include "gc/shared/modRefBarrierSetAssembler.hpp" -#include "runtime/jniHandles.hpp" -#include "utilities/macros.hpp" - -#define __ masm-> - -void ModRefBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Register src, Register dst, Register count, Register preserve1, Register preserve2) { - if (type == T_OBJECT) { - gen_write_ref_array_pre_barrier(masm, decorators, - src, dst, count, - preserve1, preserve2); - - bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0; - if (!checkcast) { - assert_different_registers(dst, count, R9_ARG7, R10_ARG8); - // Save some arguments for epilogue, e.g. disjoint_long_copy_core destroys them. - __ mr(R9_ARG7, dst); - __ mr(R10_ARG8, count); - } - } -} - -void ModRefBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Register dst, Register count, Register preserve) { - if (type == T_OBJECT) { - bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0; - if (!checkcast) { - gen_write_ref_array_post_barrier(masm, decorators, R9_ARG7, R10_ARG8, preserve); - } else { - gen_write_ref_array_post_barrier(masm, decorators, dst, count, preserve); - } - } -} - -void ModRefBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Register base, RegisterOrConstant ind_or_offs, Register val, - Register tmp1, Register tmp2, Register tmp3, - MacroAssembler::PreservationLevel preservation_level) { - if (is_reference_type(type)) { - oop_store_at(masm, decorators, type, - base, ind_or_offs, val, - tmp1, tmp2, tmp3, - preservation_level); - } else { - BarrierSetAssembler::store_at(masm, decorators, type, - base, ind_or_offs, val, - tmp1, tmp2, tmp3, - preservation_level); - } -} - -void ModRefBarrierSetAssembler::resolve_jobject(MacroAssembler* masm, Register value, - Register tmp1, Register tmp2, - MacroAssembler::PreservationLevel preservation_level) { - Label done; - __ cmpdi(CR0, value, 0); - __ beq(CR0, done); // Use null as-is. - - __ clrrdi(tmp1, value, JNIHandles::tag_size); - __ ld(value, 0, tmp1); // Resolve (untagged) jobject. - - __ verify_oop(value, FILE_AND_LINE); - __ bind(done); -} diff --git a/src/hotspot/cpu/ppc/gc/shared/modRefBarrierSetAssembler_ppc.hpp b/src/hotspot/cpu/ppc/gc/shared/modRefBarrierSetAssembler_ppc.hpp deleted file mode 100644 index 5d105f6c0484f..0000000000000 --- a/src/hotspot/cpu/ppc/gc/shared/modRefBarrierSetAssembler_ppc.hpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2018, 2021 SAP SE. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef CPU_PPC_GC_SHARED_MODREFBARRIERSETASSEMBLER_PPC_HPP -#define CPU_PPC_GC_SHARED_MODREFBARRIERSETASSEMBLER_PPC_HPP - -#include "asm/macroAssembler.hpp" -#include "gc/shared/barrierSetAssembler.hpp" - -// The ModRefBarrierSetAssembler filters away accesses on BasicTypes other -// than T_OBJECT/T_ARRAY (oops). The oop accesses call one of the protected -// accesses, which are overridden in the concrete BarrierSetAssembler. - -class ModRefBarrierSetAssembler: public BarrierSetAssembler { -protected: - virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, - Register from, Register to, Register count, - Register preserve1, Register preserve2) {} - virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, - Register addr, Register count, Register preserve) {} - - virtual void oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Register base, RegisterOrConstant ind_or_offs, Register val, - Register tmp1, Register tmp2, Register tmp3, - MacroAssembler::PreservationLevel preservation_level) = 0; -public: - virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Register src, Register dst, Register count, - Register preserve1, Register preserve2); - virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Register dst, Register count, - Register preserve); - - virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Register base, RegisterOrConstant ind_or_offs, Register val, - Register tmp1, Register tmp2, Register tmp3, - MacroAssembler::PreservationLevel preservation_level); - - virtual void resolve_jobject(MacroAssembler* masm, Register value, - Register tmp1, Register tmp2, - MacroAssembler::PreservationLevel preservation_level); -}; - -#endif // CPU_PPC_GC_SHARED_MODREFBARRIERSETASSEMBLER_PPC_HPP diff --git a/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp index 64e9cbe1f4787..966afde4cb0cb 100644 --- a/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp @@ -345,7 +345,7 @@ void G1BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorator 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; - ModRefBarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp2); + CardTableBarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp2); if (on_oop && on_reference) { // RA is live. It must be saved around calls. __ enter(); // barrier may call runtime diff --git a/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.hpp b/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.hpp index 654ba93424240..d2d2f4d49bc8b 100644 --- a/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.hpp @@ -27,7 +27,7 @@ #define CPU_RISCV_GC_G1_G1BARRIERSETASSEMBLER_RISCV_HPP #include "asm/macroAssembler.hpp" -#include "gc/shared/modRefBarrierSetAssembler.hpp" +#include "gc/shared/cardTableBarrierSetAssembler.hpp" #include "utilities/macros.hpp" #ifdef COMPILER1 @@ -37,7 +37,7 @@ class StubAssembler; class G1PreBarrierStub; class G1PreBarrierStubC2; -class G1BarrierSetAssembler: public ModRefBarrierSetAssembler { +class G1BarrierSetAssembler: public CardTableBarrierSetAssembler { protected: void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count, RegSet saved_regs); diff --git a/src/hotspot/cpu/riscv/gc/shared/cardTableBarrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/shared/cardTableBarrierSetAssembler_riscv.cpp index df7ff65442ef9..408620dc56fbf 100644 --- a/src/hotspot/cpu/riscv/gc/shared/cardTableBarrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/shared/cardTableBarrierSetAssembler_riscv.cpp @@ -33,6 +33,29 @@ #define __ masm-> +void CardTableBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, + Register src, Register dst, Register count, RegSet saved_regs) { + if (is_oop) { + gen_write_ref_array_pre_barrier(masm, decorators, dst, count, saved_regs); + } +} + +void CardTableBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, + Register start, Register count, Register tmp, + RegSet saved_regs) { + if (is_oop) { + gen_write_ref_array_post_barrier(masm, decorators, start, count, tmp, saved_regs); + } +} + +void CardTableBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, + Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) { + if (is_reference_type(type)) { + oop_store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3); + } else { + BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3); + } +} void CardTableBarrierSetAssembler::store_check(MacroAssembler* masm, Register obj, Register tmp) { assert_different_registers(obj, tmp); diff --git a/src/hotspot/cpu/riscv/gc/shared/cardTableBarrierSetAssembler_riscv.hpp b/src/hotspot/cpu/riscv/gc/shared/cardTableBarrierSetAssembler_riscv.hpp index b8ce585ea7055..98737c3623f52 100644 --- a/src/hotspot/cpu/riscv/gc/shared/cardTableBarrierSetAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/gc/shared/cardTableBarrierSetAssembler_riscv.hpp @@ -27,16 +27,30 @@ #define CPU_RISCV_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_RISCV_HPP #include "asm/macroAssembler.hpp" -#include "gc/shared/modRefBarrierSetAssembler.hpp" +#include "gc/shared/barrierSetAssembler.hpp" -class CardTableBarrierSetAssembler: public ModRefBarrierSetAssembler { +class CardTableBarrierSetAssembler: public BarrierSetAssembler { protected: void store_check(MacroAssembler* masm, Register obj, Register tmp); + virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, + Register addr, Register count, RegSet saved_regs) {} + virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register start, Register count, Register tmp, RegSet saved_regs); + virtual void oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Address dst, Register val, Register tmp1, Register tmp2, Register tmp3); + +public: + virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, + Register src, Register dst, Register count, RegSet saved_regs); + + virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, + Register start, Register count, Register tmp, RegSet saved_regs); + + virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, + Address dst, Register val, Register tmp1, Register tmp2, Register tmp3); }; #endif // #ifndef CPU_RISCV_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_RISCV_HPP diff --git a/src/hotspot/cpu/riscv/gc/shared/modRefBarrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/shared/modRefBarrierSetAssembler_riscv.cpp deleted file mode 100644 index 6b0871007f488..0000000000000 --- a/src/hotspot/cpu/riscv/gc/shared/modRefBarrierSetAssembler_riscv.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "asm/macroAssembler.inline.hpp" -#include "gc/shared/modRefBarrierSetAssembler.hpp" - -#define __ masm-> - -void ModRefBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, - Register src, Register dst, Register count, RegSet saved_regs) { - if (is_oop) { - gen_write_ref_array_pre_barrier(masm, decorators, dst, count, saved_regs); - } -} - -void ModRefBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, - Register start, Register count, Register tmp, - RegSet saved_regs) { - if (is_oop) { - gen_write_ref_array_post_barrier(masm, decorators, start, count, tmp, saved_regs); - } -} - -void ModRefBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) { - if (is_reference_type(type)) { - oop_store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3); - } else { - BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3); - } -} diff --git a/src/hotspot/cpu/riscv/gc/shared/modRefBarrierSetAssembler_riscv.hpp b/src/hotspot/cpu/riscv/gc/shared/modRefBarrierSetAssembler_riscv.hpp deleted file mode 100644 index 45e64777ed768..0000000000000 --- a/src/hotspot/cpu/riscv/gc/shared/modRefBarrierSetAssembler_riscv.hpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef CPU_RISCV_GC_SHARED_MODREFBARRIERSETASSEMBLER_RISCV_HPP -#define CPU_RISCV_GC_SHARED_MODREFBARRIERSETASSEMBLER_RISCV_HPP - -#include "asm/macroAssembler.hpp" -#include "gc/shared/barrierSetAssembler.hpp" - -// The ModRefBarrierSetAssembler filters away accesses on BasicTypes other -// than T_OBJECT/T_ARRAY (oops). The oop accesses call one of the protected -// accesses, which are overridden in the concrete BarrierSetAssembler. - -class ModRefBarrierSetAssembler: public BarrierSetAssembler { -protected: - virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, - Register addr, Register count, RegSet saved_regs) {} - virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, - Register start, Register count, Register tmp, RegSet saved_regs) {} - - virtual void oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) = 0; - -public: - virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, - Register src, Register dst, Register count, RegSet saved_regs); - virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, - Register start, Register count, Register tmp, RegSet saved_regs); - virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Address dst, Register val, Register tmp1, Register tmp2, Register tmp3); -}; - -#endif // CPU_RISCV_GC_SHARED_MODREFBARRIERSETASSEMBLER_RISCV_HPP diff --git a/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp b/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp index e4fe690663a8a..272136fc28c79 100644 --- a/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp @@ -279,7 +279,7 @@ void G1BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorator bool on_reference = on_weak || on_phantom; Label done; if (on_oop && on_reference && L_handle_null == nullptr) { L_handle_null = &done; } - ModRefBarrierSetAssembler::load_at(masm, decorators, type, src, dst, tmp1, tmp2, L_handle_null); + CardTableBarrierSetAssembler::load_at(masm, decorators, type, src, dst, tmp1, tmp2, L_handle_null); if (on_oop && on_reference) { // Generate the G1 pre-barrier code to log the value of // the referent field in an SATB buffer. diff --git a/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.hpp b/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.hpp index fdec751c43b4d..00e0a1162076d 100644 --- a/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.hpp +++ b/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.hpp @@ -27,7 +27,7 @@ #define CPU_S390_GC_G1_G1BARRIERSETASSEMBLER_S390_HPP #include "asm/macroAssembler.hpp" -#include "gc/shared/modRefBarrierSetAssembler.hpp" +#include "gc/shared/cardTableBarrierSetAssembler.hpp" #include "utilities/macros.hpp" class LIR_Assembler; @@ -35,7 +35,7 @@ class StubAssembler; class G1PreBarrierStub; class G1PreBarrierStubC2; -class G1BarrierSetAssembler: public ModRefBarrierSetAssembler { +class G1BarrierSetAssembler: public CardTableBarrierSetAssembler { protected: virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count); virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count, diff --git a/src/hotspot/cpu/s390/gc/shared/cardTableBarrierSetAssembler_s390.cpp b/src/hotspot/cpu/s390/gc/shared/cardTableBarrierSetAssembler_s390.cpp index f8f1fe839d232..a0da6ebe68231 100644 --- a/src/hotspot/cpu/s390/gc/shared/cardTableBarrierSetAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/gc/shared/cardTableBarrierSetAssembler_s390.cpp @@ -29,6 +29,7 @@ #include "gc/shared/cardTableBarrierSet.hpp" #include "gc/shared/cardTableBarrierSetAssembler.hpp" #include "interpreter/interp_masm.hpp" +#include "runtime/jniHandles.hpp" #define __ masm-> @@ -42,6 +43,44 @@ #define TIMES_OOP (UseCompressedOops ? Address::times_4 : Address::times_8) +void CardTableBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, + Register src, Register dst, Register count) { + if (is_reference_type(type)) { + gen_write_ref_array_pre_barrier(masm, decorators, dst, count); + } +} + +void CardTableBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, + Register dst, Register count, bool do_return) { + if (is_reference_type(type)) { + gen_write_ref_array_post_barrier(masm, decorators, dst, count, do_return); + } else { + if (do_return) { __ z_br(Z_R14); } + } +} + +void CardTableBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, + const Address& dst, Register val, Register tmp1, Register tmp2, Register tmp3) { + if (is_reference_type(type)) { + oop_store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3); + } else { + BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3); + } +} + +void CardTableBarrierSetAssembler::resolve_jobject(MacroAssembler* masm, Register value, Register tmp1, Register tmp2) { + NearLabel done; + + __ z_ltgr(value, value); + __ z_bre(done); // use null as-is. + + __ z_nill(value, ~JNIHandles::tag_mask); + __ z_lg(value, 0, value); // Resolve (untagged) jobject. + + __ verify_oop(value, FILE_AND_LINE); + __ bind(done); +} + void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count, bool do_return) { CardTableBarrierSet* ctbs = barrier_set_cast(BarrierSet::barrier_set()); diff --git a/src/hotspot/cpu/s390/gc/shared/cardTableBarrierSetAssembler_s390.hpp b/src/hotspot/cpu/s390/gc/shared/cardTableBarrierSetAssembler_s390.hpp index 43ec1e08dca12..eb64a09a51fd6 100644 --- a/src/hotspot/cpu/s390/gc/shared/cardTableBarrierSetAssembler_s390.hpp +++ b/src/hotspot/cpu/s390/gc/shared/cardTableBarrierSetAssembler_s390.hpp @@ -27,17 +27,30 @@ #define CPU_S390_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_S390_HPP #include "asm/macroAssembler.hpp" -#include "gc/shared/modRefBarrierSetAssembler.hpp" +#include "gc/shared/barrierSetAssembler.hpp" -class CardTableBarrierSetAssembler: public ModRefBarrierSetAssembler { +class CardTableBarrierSetAssembler: public BarrierSetAssembler { protected: void store_check(MacroAssembler* masm, Register store_addr, Register tmp); + virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count) {} + virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count, bool do_return); virtual void oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, const Address& dst, Register val, Register tmp1, Register tmp2, Register tmp3); +public: + virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, + Register src, Register dst, Register count); + + virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, + Register dst, Register count, bool do_return = false); + + virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, + const Address& dst, Register val, Register tmp1, Register tmp2, Register tmp3); + + virtual void resolve_jobject(MacroAssembler* masm, Register value, Register tmp1, Register tmp2); }; #endif // CPU_S390_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_S390_HPP diff --git a/src/hotspot/cpu/s390/gc/shared/modRefBarrierSetAssembler_s390.cpp b/src/hotspot/cpu/s390/gc/shared/modRefBarrierSetAssembler_s390.cpp deleted file mode 100644 index 4d37ae2e4ce5f..0000000000000 --- a/src/hotspot/cpu/s390/gc/shared/modRefBarrierSetAssembler_s390.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2018, 2024 SAP SE. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "asm/macroAssembler.inline.hpp" -#include "gc/shared/modRefBarrierSetAssembler.hpp" -#include "runtime/jniHandles.hpp" - -#define __ masm-> - -void ModRefBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count, - bool do_return) { - if (do_return) { __ z_br(Z_R14); } -} - -void ModRefBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Register src, Register dst, Register count) { - if (is_reference_type(type)) { - gen_write_ref_array_pre_barrier(masm, decorators, dst, count); - } -} - -void ModRefBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Register dst, Register count, bool do_return) { - if (is_reference_type(type)) { - gen_write_ref_array_post_barrier(masm, decorators, dst, count, do_return); - } else { - if (do_return) { __ z_br(Z_R14); } - } -} - -void ModRefBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - const Address& dst, Register val, Register tmp1, Register tmp2, Register tmp3) { - if (is_reference_type(type)) { - oop_store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3); - } else { - BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3); - } -} - -void ModRefBarrierSetAssembler::resolve_jobject(MacroAssembler* masm, Register value, Register tmp1, Register tmp2) { - NearLabel done; - - __ z_ltgr(value, value); - __ z_bre(done); // use null as-is. - - __ z_nill(value, ~JNIHandles::tag_mask); - __ z_lg(value, 0, value); // Resolve (untagged) jobject. - - __ verify_oop(value, FILE_AND_LINE); - __ bind(done); -} diff --git a/src/hotspot/cpu/s390/gc/shared/modRefBarrierSetAssembler_s390.hpp b/src/hotspot/cpu/s390/gc/shared/modRefBarrierSetAssembler_s390.hpp deleted file mode 100644 index 7f53d033780c1..0000000000000 --- a/src/hotspot/cpu/s390/gc/shared/modRefBarrierSetAssembler_s390.hpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2018, 2024 SAP SE. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef CPU_S390_GC_SHARED_MODREFBARRIERSETASSEMBLER_S390_HPP -#define CPU_S390_GC_SHARED_MODREFBARRIERSETASSEMBLER_S390_HPP - -#include "asm/macroAssembler.hpp" -#include "gc/shared/barrierSetAssembler.hpp" - -// The ModRefBarrierSetAssembler filters away accesses on BasicTypes other -// than T_OBJECT/T_ARRAY (oops). The oop accesses call one of the protected -// accesses, which are overridden in the concrete BarrierSetAssembler. - -class ModRefBarrierSetAssembler: public BarrierSetAssembler { -protected: - virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count) {} - virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count, - bool do_return); - virtual void oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - const Address& dst, Register val, Register tmp1, Register tmp2, Register tmp3) = 0; -public: - virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Register src, Register dst, Register count); - virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Register dst, Register count, bool do_return = false); - - virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - const Address& dst, Register val, Register tmp1, Register tmp2, Register tmp3); - - virtual void resolve_jobject(MacroAssembler* masm, Register value, Register tmp1, Register tmp2); -}; - -#endif // CPU_S390_GC_SHARED_MODREFBARRIERSETASSEMBLER_S390_HPP diff --git a/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp index a846289d91b1f..586135fcebc28 100644 --- a/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp @@ -144,7 +144,7 @@ void G1BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorator 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; - ModRefBarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1); + CardTableBarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1); if (on_oop && on_reference) { // Generate the G1 pre-barrier code to log the value of // the referent field in an SATB buffer. diff --git a/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.hpp b/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.hpp index 4b2de41de6963..0db96495beeab 100644 --- a/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.hpp +++ b/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.hpp @@ -26,7 +26,7 @@ #define CPU_X86_GC_G1_G1BARRIERSETASSEMBLER_X86_HPP #include "asm/macroAssembler.hpp" -#include "gc/shared/modRefBarrierSetAssembler.hpp" +#include "gc/shared/cardTableBarrierSetAssembler.hpp" class LIR_Assembler; class StubAssembler; @@ -34,7 +34,7 @@ class G1PreBarrierStub; class G1BarrierStubC2; class G1PreBarrierStubC2; -class G1BarrierSetAssembler: public ModRefBarrierSetAssembler { +class G1BarrierSetAssembler: public CardTableBarrierSetAssembler { protected: virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count); virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count, Register tmp); diff --git a/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.cpp index ba89b09e4dcdc..2b91662ddb557 100644 --- a/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.cpp @@ -41,6 +41,58 @@ #define TIMES_OOP (UseCompressedOops ? Address::times_4 : Address::times_8) +void CardTableBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, + Register src, Register dst, Register count) { + bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0; + bool disjoint = (decorators & ARRAYCOPY_DISJOINT) != 0; + bool obj_int = (type == T_OBJECT) && UseCompressedOops; + + if (is_reference_type(type)) { + if (!checkcast) { + if (!obj_int) { + // Save count for barrier + __ movptr(r11, count); + } else if (disjoint) { + // Save dst in r11 in the disjoint case + __ movq(r11, dst); + } + } + gen_write_ref_array_pre_barrier(masm, decorators, dst, count); + } +} + +void CardTableBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, + Register src, Register dst, Register count) { + bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0; + bool disjoint = (decorators & ARRAYCOPY_DISJOINT) != 0; + bool obj_int = (type == T_OBJECT) && UseCompressedOops; + Register tmp = rax; + + if (is_reference_type(type)) { + if (!checkcast) { + if (!obj_int) { + // Save count for barrier + count = r11; + } else if (disjoint) { + // Use the saved dst in the disjoint case + dst = r11; + } + } else { + tmp = rscratch1; + } + gen_write_ref_array_post_barrier(masm, decorators, dst, count, tmp); + } +} + +void CardTableBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, + Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) { + if (is_reference_type(type)) { + oop_store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3); + } else { + BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3); + } +} + void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count, Register tmp) { BarrierSet *bs = BarrierSet::barrier_set(); diff --git a/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.hpp b/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.hpp index 4760b222977a8..6f71ec64218ac 100644 --- a/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.hpp +++ b/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.hpp @@ -26,16 +26,30 @@ #define CPU_X86_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_X86_HPP #include "asm/macroAssembler.hpp" -#include "gc/shared/modRefBarrierSetAssembler.hpp" +#include "gc/shared/barrierSetAssembler.hpp" -class CardTableBarrierSetAssembler: public ModRefBarrierSetAssembler { +class CardTableBarrierSetAssembler: public BarrierSetAssembler { protected: + virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, + Register addr, Register count) {} + void store_check(MacroAssembler* masm, Register obj, Address dst); virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count, Register tmp); virtual void oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Address dst, Register val, Register tmp1, Register tmp2, Register tmp3); + +public: + virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, + Register src, Register dst, Register count); + + virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, + Register src, Register dst, Register count); + + virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, + Address dst, Register val, Register tmp1, Register tmp2, Register tmp3); + }; #endif // CPU_X86_GC_SHARED_CARDTABLEBARRIERSETASSEMBLER_X86_HPP diff --git a/src/hotspot/cpu/x86/gc/shared/modRefBarrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/shared/modRefBarrierSetAssembler_x86.cpp deleted file mode 100644 index 42109b069f2e0..0000000000000 --- a/src/hotspot/cpu/x86/gc/shared/modRefBarrierSetAssembler_x86.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "asm/macroAssembler.inline.hpp" -#include "gc/shared/modRefBarrierSetAssembler.hpp" - -#define __ masm-> - -void ModRefBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Register src, Register dst, Register count) { - bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0; - bool disjoint = (decorators & ARRAYCOPY_DISJOINT) != 0; - bool obj_int = (type == T_OBJECT) && UseCompressedOops; - - if (is_reference_type(type)) { - if (!checkcast) { - if (!obj_int) { - // Save count for barrier - __ movptr(r11, count); - } else if (disjoint) { - // Save dst in r11 in the disjoint case - __ movq(r11, dst); - } - } - gen_write_ref_array_pre_barrier(masm, decorators, dst, count); - } -} - -void ModRefBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Register src, Register dst, Register count) { - bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0; - bool disjoint = (decorators & ARRAYCOPY_DISJOINT) != 0; - bool obj_int = (type == T_OBJECT) && UseCompressedOops; - Register tmp = rax; - - if (is_reference_type(type)) { - if (!checkcast) { - if (!obj_int) { - // Save count for barrier - count = r11; - } else if (disjoint) { - // Use the saved dst in the disjoint case - dst = r11; - } - } else { - tmp = rscratch1; - } - gen_write_ref_array_post_barrier(masm, decorators, dst, count, tmp); - } -} - -void ModRefBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) { - if (is_reference_type(type)) { - oop_store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3); - } else { - BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3); - } -} diff --git a/src/hotspot/cpu/x86/gc/shared/modRefBarrierSetAssembler_x86.hpp b/src/hotspot/cpu/x86/gc/shared/modRefBarrierSetAssembler_x86.hpp deleted file mode 100644 index c8b5043256ad2..0000000000000 --- a/src/hotspot/cpu/x86/gc/shared/modRefBarrierSetAssembler_x86.hpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef CPU_X86_GC_SHARED_MODREFBARRIERSETASSEMBLER_X86_HPP -#define CPU_X86_GC_SHARED_MODREFBARRIERSETASSEMBLER_X86_HPP - -#include "asm/macroAssembler.hpp" -#include "gc/shared/barrierSetAssembler.hpp" - -// The ModRefBarrierSetAssembler filters away accesses on BasicTypes other -// than T_OBJECT/T_ARRAY (oops). The oop accesses call one of the protected -// accesses, which are overridden in the concrete BarrierSetAssembler. - -class ModRefBarrierSetAssembler: public BarrierSetAssembler { -protected: - virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, - Register addr, Register count) {} - virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, - Register addr, Register count, Register tmp) {} - virtual void oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) = 0; -public: - virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Register src, Register dst, Register count); - virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Register src, Register dst, Register count); - - virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Address dst, Register val, Register tmp1, Register tmp2, Register tmp3); -}; - -#endif // CPU_X86_GC_SHARED_MODREFBARRIERSETASSEMBLER_X86_HPP diff --git a/src/hotspot/cpu/zero/gc/shared/modRefBarrierSetAssembler_zero.hpp b/src/hotspot/cpu/zero/gc/shared/modRefBarrierSetAssembler_zero.hpp deleted file mode 100644 index 78c8fc1653af5..0000000000000 --- a/src/hotspot/cpu/zero/gc/shared/modRefBarrierSetAssembler_zero.hpp +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef CPU_ZERO_GC_SHARED_MODREFBARRIERSETASSEMBLER_ZERO_HPP -#define CPU_ZERO_GC_SHARED_MODREFBARRIERSETASSEMBLER_ZERO_HPP - -class ModRefBarrierSetAssembler; - -#endif // CPU_ZERO_GC_SHARED_MODREFBARRIERSETASSEMBLER_ZERO_HPP diff --git a/src/hotspot/share/gc/g1/c1/g1BarrierSetC1.hpp b/src/hotspot/share/gc/g1/c1/g1BarrierSetC1.hpp index 89f5676a2d2a3..76dcd7fa4ff3c 100644 --- a/src/hotspot/share/gc/g1/c1/g1BarrierSetC1.hpp +++ b/src/hotspot/share/gc/g1/c1/g1BarrierSetC1.hpp @@ -27,7 +27,7 @@ #include "c1/c1_CodeStubs.hpp" #include "c1/c1_Compilation.hpp" -#include "gc/shared/c1/modRefBarrierSetC1.hpp" +#include "gc/shared/c1/cardTableBarrierSetC1.hpp" class G1PreBarrierStub: public CodeStub { friend class G1BarrierSetC1; @@ -93,7 +93,7 @@ class G1PreBarrierStub: public CodeStub { class CodeBlob; -class G1BarrierSetC1 : public ModRefBarrierSetC1 { +class G1BarrierSetC1 : public CardTableBarrierSetC1 { protected: CodeBlob* _pre_barrier_c1_runtime_code_blob; diff --git a/src/hotspot/share/gc/g1/g1BarrierSet.hpp b/src/hotspot/share/gc/g1/g1BarrierSet.hpp index 58a70ed6a6076..bf595973a3210 100644 --- a/src/hotspot/share/gc/g1/g1BarrierSet.hpp +++ b/src/hotspot/share/gc/g1/g1BarrierSet.hpp @@ -117,8 +117,8 @@ class G1BarrierSet: public CardTableBarrierSet { // Callbacks for runtime accesses. template - class AccessBarrier: public ModRefBarrierSet::AccessBarrier { - typedef ModRefBarrierSet::AccessBarrier ModRef; + class AccessBarrier: public CardTableBarrierSet::AccessBarrier { + typedef CardTableBarrierSet::AccessBarrier CardTableBS; typedef BarrierSet::AccessBarrier Raw; public: diff --git a/src/hotspot/share/gc/g1/g1BarrierSet.inline.hpp b/src/hotspot/share/gc/g1/g1BarrierSet.inline.hpp index ffba561f11f3d..ee2c1450d9b1f 100644 --- a/src/hotspot/share/gc/g1/g1BarrierSet.inline.hpp +++ b/src/hotspot/share/gc/g1/g1BarrierSet.inline.hpp @@ -94,7 +94,7 @@ template template inline oop G1BarrierSet::AccessBarrier:: oop_load_not_in_heap(T* addr) { - oop value = ModRef::oop_load_not_in_heap(addr); + oop value = CardTableBS::oop_load_not_in_heap(addr); enqueue_preloaded_if_weak(decorators, value); return value; } @@ -103,7 +103,7 @@ template template inline oop G1BarrierSet::AccessBarrier:: oop_load_in_heap(T* addr) { - oop value = ModRef::oop_load_in_heap(addr); + oop value = CardTableBS::oop_load_in_heap(addr); enqueue_preloaded_if_weak(decorators, value); return value; } @@ -111,7 +111,7 @@ oop_load_in_heap(T* addr) { template inline oop G1BarrierSet::AccessBarrier:: oop_load_in_heap_at(oop base, ptrdiff_t offset) { - oop value = ModRef::oop_load_in_heap_at(base, offset); + oop value = CardTableBS::oop_load_in_heap_at(base, offset); enqueue_preloaded_if_weak(AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength(base, offset), value); return value; } diff --git a/src/hotspot/share/gc/serial/serialFullGC.cpp b/src/hotspot/share/gc/serial/serialFullGC.cpp index 76a335d209f7b..546084e38dd1b 100644 --- a/src/hotspot/share/gc/serial/serialFullGC.cpp +++ b/src/hotspot/share/gc/serial/serialFullGC.cpp @@ -48,7 +48,6 @@ #include "gc/shared/gcTimer.hpp" #include "gc/shared/gcTrace.hpp" #include "gc/shared/gcTraceTime.inline.hpp" -#include "gc/shared/modRefBarrierSet.hpp" #include "gc/shared/oopStorageSet.inline.hpp" #include "gc/shared/preservedMarks.inline.hpp" #include "gc/shared/referencePolicy.hpp" diff --git a/src/hotspot/share/gc/shared/barrierSetConfig.hpp b/src/hotspot/share/gc/shared/barrierSetConfig.hpp index 8bb7cf7c7ef65..5a160f52c5ab0 100644 --- a/src/hotspot/share/gc/shared/barrierSetConfig.hpp +++ b/src/hotspot/share/gc/shared/barrierSetConfig.hpp @@ -27,20 +27,12 @@ #include "utilities/macros.hpp" -// Do something for each concrete barrier set part of the build. -#define FOR_EACH_CONCRETE_BARRIER_SET_DO(f) \ +// Do something for each barrier set part of the build. +#define FOR_EACH_BARRIER_SET_DO(f) \ f(CardTableBarrierSet) \ EPSILONGC_ONLY(f(EpsilonBarrierSet)) \ G1GC_ONLY(f(G1BarrierSet)) \ SHENANDOAHGC_ONLY(f(ShenandoahBarrierSet)) \ ZGC_ONLY(f(ZBarrierSet)) -#define FOR_EACH_ABSTRACT_BARRIER_SET_DO(f) \ - f(ModRef) - -// Do something for each known barrier set. -#define FOR_EACH_BARRIER_SET_DO(f) \ - FOR_EACH_ABSTRACT_BARRIER_SET_DO(f) \ - FOR_EACH_CONCRETE_BARRIER_SET_DO(f) - #endif // SHARE_GC_SHARED_BARRIERSETCONFIG_HPP diff --git a/src/hotspot/share/gc/shared/barrierSetConfig.inline.hpp b/src/hotspot/share/gc/shared/barrierSetConfig.inline.hpp index f637c227ee1d9..32a8719e21f58 100644 --- a/src/hotspot/share/gc/shared/barrierSetConfig.inline.hpp +++ b/src/hotspot/share/gc/shared/barrierSetConfig.inline.hpp @@ -28,7 +28,6 @@ #include "gc/shared/barrierSetConfig.hpp" #include "gc/shared/cardTableBarrierSet.inline.hpp" -#include "gc/shared/modRefBarrierSet.inline.hpp" #if INCLUDE_EPSILONGC #include "gc/epsilon/epsilonBarrierSet.hpp" diff --git a/src/hotspot/share/gc/shared/c1/cardTableBarrierSetC1.cpp b/src/hotspot/share/gc/shared/c1/cardTableBarrierSetC1.cpp index 278b1b158aa98..ebc1c1c7fb790 100644 --- a/src/hotspot/share/gc/shared/c1/cardTableBarrierSetC1.cpp +++ b/src/hotspot/share/gc/shared/c1/cardTableBarrierSetC1.cpp @@ -34,6 +34,68 @@ #define __ gen->lir()-> #endif +void CardTableBarrierSetC1::store_at_resolved(LIRAccess& access, LIR_Opr value) { + DecoratorSet decorators = access.decorators(); + bool is_array = (decorators & IS_ARRAY) != 0; + bool on_anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0; + + if (access.is_oop()) { + pre_barrier(access, access.resolved_addr(), + LIR_OprFact::illegalOpr /* pre_val */, access.patch_emit_info()); + } + + BarrierSetC1::store_at_resolved(access, value); + + if (access.is_oop()) { + bool precise = is_array || on_anonymous; + LIR_Opr post_addr = precise ? access.resolved_addr() : access.base().opr(); + post_barrier(access, post_addr, value); + } +} + +LIR_Opr CardTableBarrierSetC1::atomic_cmpxchg_at_resolved(LIRAccess& access, LIRItem& cmp_value, LIRItem& new_value) { + if (access.is_oop()) { + pre_barrier(access, access.resolved_addr(), + LIR_OprFact::illegalOpr /* pre_val */, nullptr); + } + + LIR_Opr result = BarrierSetC1::atomic_cmpxchg_at_resolved(access, cmp_value, new_value); + + if (access.is_oop()) { + post_barrier(access, access.resolved_addr(), new_value.result()); + } + + return result; +} + +LIR_Opr CardTableBarrierSetC1::atomic_xchg_at_resolved(LIRAccess& access, LIRItem& value) { + if (access.is_oop()) { + pre_barrier(access, access.resolved_addr(), + LIR_OprFact::illegalOpr /* pre_val */, nullptr); + } + + LIR_Opr result = BarrierSetC1::atomic_xchg_at_resolved(access, value); + + if (access.is_oop()) { + post_barrier(access, access.resolved_addr(), value.result()); + } + + return result; +} + +// This overrides the default to resolve the address into a register, +// assuming it will be used by a write barrier anyway. +LIR_Opr CardTableBarrierSetC1::resolve_address(LIRAccess& access, bool resolve_in_register) { + DecoratorSet decorators = access.decorators(); + bool needs_patching = (decorators & C1_NEEDS_PATCHING) != 0; + bool is_write = (decorators & ACCESS_WRITE) != 0; + bool is_array = (decorators & IS_ARRAY) != 0; + bool on_anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0; + bool precise = is_array || on_anonymous; + resolve_in_register |= !needs_patching && is_write && access.is_oop() && precise; + return BarrierSetC1::resolve_address(access, resolve_in_register); +} + void CardTableBarrierSetC1::post_barrier(LIRAccess& access, LIR_Opr addr, LIR_Opr new_val) { DecoratorSet decorators = access.decorators(); LIRGenerator* gen = access.gen(); diff --git a/src/hotspot/share/gc/shared/c1/cardTableBarrierSetC1.hpp b/src/hotspot/share/gc/shared/c1/cardTableBarrierSetC1.hpp index 2b1629575b34e..10e8311e7648f 100644 --- a/src/hotspot/share/gc/shared/c1/cardTableBarrierSetC1.hpp +++ b/src/hotspot/share/gc/shared/c1/cardTableBarrierSetC1.hpp @@ -25,11 +25,22 @@ #ifndef SHARE_GC_SHARED_C1_CARDTABLEBARRIERSETC1_HPP #define SHARE_GC_SHARED_C1_CARDTABLEBARRIERSETC1_HPP -#include "gc/shared/c1/modRefBarrierSetC1.hpp" +#include "gc/shared/c1/barrierSetC1.hpp" -class CardTableBarrierSetC1 : public ModRefBarrierSetC1 { +class CardTableBarrierSetC1 : public BarrierSetC1 { protected: + virtual void pre_barrier(LIRAccess& access, LIR_Opr addr_opr, + LIR_Opr pre_val, CodeEmitInfo* info) {} + virtual void post_barrier(LIRAccess& access, LIR_Opr addr, LIR_Opr new_val); + + virtual LIR_Opr resolve_address(LIRAccess& access, bool resolve_in_register); + + virtual void store_at_resolved(LIRAccess& access, LIR_Opr value); + + virtual LIR_Opr atomic_cmpxchg_at_resolved(LIRAccess& access, LIRItem& cmp_value, LIRItem& new_value); + + virtual LIR_Opr atomic_xchg_at_resolved(LIRAccess& access, LIRItem& value); }; #endif // SHARE_GC_SHARED_C1_CARDTABLEBARRIERSETC1_HPP diff --git a/src/hotspot/share/gc/shared/c1/modRefBarrierSetC1.cpp b/src/hotspot/share/gc/shared/c1/modRefBarrierSetC1.cpp deleted file mode 100644 index d7d463d252e4e..0000000000000 --- a/src/hotspot/share/gc/shared/c1/modRefBarrierSetC1.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "gc/shared/c1/modRefBarrierSetC1.hpp" -#include "utilities/macros.hpp" - -#ifdef ASSERT -#define __ gen->lir(__FILE__, __LINE__)-> -#else -#define __ gen->lir()-> -#endif - -void ModRefBarrierSetC1::store_at_resolved(LIRAccess& access, LIR_Opr value) { - DecoratorSet decorators = access.decorators(); - bool is_array = (decorators & IS_ARRAY) != 0; - bool on_anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0; - - if (access.is_oop()) { - pre_barrier(access, access.resolved_addr(), - LIR_OprFact::illegalOpr /* pre_val */, access.patch_emit_info()); - } - - BarrierSetC1::store_at_resolved(access, value); - - if (access.is_oop()) { - bool precise = is_array || on_anonymous; - LIR_Opr post_addr = precise ? access.resolved_addr() : access.base().opr(); - post_barrier(access, post_addr, value); - } -} - -LIR_Opr ModRefBarrierSetC1::atomic_cmpxchg_at_resolved(LIRAccess& access, LIRItem& cmp_value, LIRItem& new_value) { - if (access.is_oop()) { - pre_barrier(access, access.resolved_addr(), - LIR_OprFact::illegalOpr /* pre_val */, nullptr); - } - - LIR_Opr result = BarrierSetC1::atomic_cmpxchg_at_resolved(access, cmp_value, new_value); - - if (access.is_oop()) { - post_barrier(access, access.resolved_addr(), new_value.result()); - } - - return result; -} - -LIR_Opr ModRefBarrierSetC1::atomic_xchg_at_resolved(LIRAccess& access, LIRItem& value) { - if (access.is_oop()) { - pre_barrier(access, access.resolved_addr(), - LIR_OprFact::illegalOpr /* pre_val */, nullptr); - } - - LIR_Opr result = BarrierSetC1::atomic_xchg_at_resolved(access, value); - - if (access.is_oop()) { - post_barrier(access, access.resolved_addr(), value.result()); - } - - return result; -} - -// This overrides the default to resolve the address into a register, -// assuming it will be used by a write barrier anyway. -LIR_Opr ModRefBarrierSetC1::resolve_address(LIRAccess& access, bool resolve_in_register) { - DecoratorSet decorators = access.decorators(); - bool needs_patching = (decorators & C1_NEEDS_PATCHING) != 0; - bool is_write = (decorators & ACCESS_WRITE) != 0; - bool is_array = (decorators & IS_ARRAY) != 0; - bool on_anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0; - bool precise = is_array || on_anonymous; - resolve_in_register |= !needs_patching && is_write && access.is_oop() && precise; - return BarrierSetC1::resolve_address(access, resolve_in_register); -} diff --git a/src/hotspot/share/gc/shared/c1/modRefBarrierSetC1.hpp b/src/hotspot/share/gc/shared/c1/modRefBarrierSetC1.hpp deleted file mode 100644 index 2bd547c41b129..0000000000000 --- a/src/hotspot/share/gc/shared/c1/modRefBarrierSetC1.hpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_GC_SHARED_C1_MODREFBARRIERSETC1_HPP -#define SHARE_GC_SHARED_C1_MODREFBARRIERSETC1_HPP - -#include "gc/shared/c1/barrierSetC1.hpp" - -// The ModRefBarrierSetC1 filters away accesses on BasicTypes other -// than T_OBJECT/T_ARRAY (oops). The oop accesses call one of the protected -// accesses, which are overridden in the concrete BarrierSetAssembler. - -class ModRefBarrierSetC1 : public BarrierSetC1 { -protected: - virtual void pre_barrier(LIRAccess& access, LIR_Opr addr_opr, - LIR_Opr pre_val, CodeEmitInfo* info) {} - virtual void post_barrier(LIRAccess& access, LIR_Opr addr, - LIR_Opr new_val) {} - - virtual LIR_Opr resolve_address(LIRAccess& access, bool resolve_in_register); - - virtual void store_at_resolved(LIRAccess& access, LIR_Opr value); - - virtual LIR_Opr atomic_cmpxchg_at_resolved(LIRAccess& access, LIRItem& cmp_value, LIRItem& new_value); - - virtual LIR_Opr atomic_xchg_at_resolved(LIRAccess& access, LIRItem& value); -}; - -#endif // SHARE_GC_SHARED_C1_MODREFBARRIERSETC1_HPP diff --git a/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.cpp b/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.cpp index 536cd6da1ef8c..fada2672e9f1e 100644 --- a/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.cpp +++ b/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.cpp @@ -35,6 +35,85 @@ #define __ ideal. +Node* CardTableBarrierSetC2::store_at_resolved(C2Access& access, C2AccessValue& val) const { + DecoratorSet decorators = access.decorators(); + + Node* adr = access.addr().node(); + + bool is_array = (decorators & IS_ARRAY) != 0; + bool anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0; + bool in_heap = (decorators & IN_HEAP) != 0; + bool use_precise = is_array || anonymous; + bool tightly_coupled_alloc = (decorators & C2_TIGHTLY_COUPLED_ALLOC) != 0; + + if (!access.is_oop() || tightly_coupled_alloc || (!in_heap && !anonymous)) { + return BarrierSetC2::store_at_resolved(access, val); + } + + assert(access.is_parse_access(), "entry not supported at optimization time"); + C2ParseAccess& parse_access = static_cast(access); + + Node* store = BarrierSetC2::store_at_resolved(access, val); + post_barrier(parse_access.kit(), access.base(), adr, val.node(), use_precise); + + return store; +} + +Node* CardTableBarrierSetC2::atomic_cmpxchg_val_at_resolved(C2AtomicParseAccess& access, Node* expected_val, + Node* new_val, const Type* value_type) const { + if (!access.is_oop()) { + return BarrierSetC2::atomic_cmpxchg_val_at_resolved(access, expected_val, new_val, value_type); + } + + Node* result = BarrierSetC2::atomic_cmpxchg_val_at_resolved(access, expected_val, new_val, value_type); + + post_barrier(access.kit(), access.base(), access.addr().node(), new_val, true); + + return result; +} + +Node* CardTableBarrierSetC2::atomic_cmpxchg_bool_at_resolved(C2AtomicParseAccess& access, Node* expected_val, + Node* new_val, const Type* value_type) const { + GraphKit* kit = access.kit(); + + if (!access.is_oop()) { + return BarrierSetC2::atomic_cmpxchg_bool_at_resolved(access, expected_val, new_val, value_type); + } + + Node* load_store = BarrierSetC2::atomic_cmpxchg_bool_at_resolved(access, expected_val, new_val, value_type); + + // Emit the post barrier only when the actual store happened. This makes sense + // to check only for LS_cmp_* that can fail to set the value. + // LS_cmp_exchange does not produce any branches by default, so there is no + // boolean result to piggyback on. TODO: When we merge CompareAndSwap with + // CompareAndExchange and move branches here, it would make sense to conditionalize + // post_barriers for LS_cmp_exchange as well. + // + // CAS success path is marked more likely since we anticipate this is a performance + // critical path, while CAS failure path can use the penalty for going through unlikely + // path as backoff. Which is still better than doing a store barrier there. + IdealKit ideal(kit); + ideal.if_then(load_store, BoolTest::ne, ideal.ConI(0), PROB_STATIC_FREQUENT); { + kit->sync_kit(ideal); + post_barrier(kit, access.base(), access.addr().node(), new_val, true); + ideal.sync_kit(kit); + } ideal.end_if(); + kit->final_sync(ideal); + + return load_store; +} + +Node* CardTableBarrierSetC2::atomic_xchg_at_resolved(C2AtomicParseAccess& access, Node* new_val, const Type* value_type) const { + Node* result = BarrierSetC2::atomic_xchg_at_resolved(access, new_val, value_type); + if (!access.is_oop()) { + return result; + } + + post_barrier(access.kit(), access.base(), access.addr().node(), new_val, true); + + return result; +} + Node* CardTableBarrierSetC2::byte_map_base_node(GraphKit* kit) const { // Get base of card map CardTable::CardValue* card_table_base = ci_card_table_address(); diff --git a/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.hpp b/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.hpp index 1263030a8b5a3..84876808f0de6 100644 --- a/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.hpp +++ b/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.hpp @@ -25,9 +25,9 @@ #ifndef SHARE_GC_SHARED_C2_CARDTABLEBARRIERSETC2_HPP #define SHARE_GC_SHARED_C2_CARDTABLEBARRIERSETC2_HPP -#include "gc/shared/c2/modRefBarrierSetC2.hpp" +#include "gc/shared/c2/barrierSetC2.hpp" -class CardTableBarrierSetC2: public ModRefBarrierSetC2 { +class CardTableBarrierSetC2: public BarrierSetC2 { protected: virtual void post_barrier(GraphKit* kit, Node* obj, @@ -35,6 +35,14 @@ class CardTableBarrierSetC2: public ModRefBarrierSetC2 { Node* val, bool use_precise) const; + virtual Node* store_at_resolved(C2Access& access, C2AccessValue& val) const; + + virtual Node* atomic_cmpxchg_val_at_resolved(C2AtomicParseAccess& access, Node* expected_val, + Node* new_val, const Type* value_type) const; + virtual Node* atomic_cmpxchg_bool_at_resolved(C2AtomicParseAccess& access, Node* expected_val, + Node* new_val, const Type* value_type) const; + virtual Node* atomic_xchg_at_resolved(C2AtomicParseAccess& access, Node* new_val, const Type* value_type) const; + Node* byte_map_base_node(GraphKit* kit) const; public: diff --git a/src/hotspot/share/gc/shared/c2/modRefBarrierSetC2.cpp b/src/hotspot/share/gc/shared/c2/modRefBarrierSetC2.cpp deleted file mode 100644 index ddc9caedd7165..0000000000000 --- a/src/hotspot/share/gc/shared/c2/modRefBarrierSetC2.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "gc/shared/c2/modRefBarrierSetC2.hpp" -#include "opto/arraycopynode.hpp" -#include "opto/graphKit.hpp" -#include "opto/idealKit.hpp" - -Node* ModRefBarrierSetC2::store_at_resolved(C2Access& access, C2AccessValue& val) const { - DecoratorSet decorators = access.decorators(); - - Node* adr = access.addr().node(); - - bool is_array = (decorators & IS_ARRAY) != 0; - bool anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0; - bool in_heap = (decorators & IN_HEAP) != 0; - bool use_precise = is_array || anonymous; - bool tightly_coupled_alloc = (decorators & C2_TIGHTLY_COUPLED_ALLOC) != 0; - - if (!access.is_oop() || tightly_coupled_alloc || (!in_heap && !anonymous)) { - return BarrierSetC2::store_at_resolved(access, val); - } - - assert(access.is_parse_access(), "entry not supported at optimization time"); - C2ParseAccess& parse_access = static_cast(access); - - Node* store = BarrierSetC2::store_at_resolved(access, val); - post_barrier(parse_access.kit(), access.base(), adr, val.node(), use_precise); - - return store; -} - -Node* ModRefBarrierSetC2::atomic_cmpxchg_val_at_resolved(C2AtomicParseAccess& access, Node* expected_val, - Node* new_val, const Type* value_type) const { - if (!access.is_oop()) { - return BarrierSetC2::atomic_cmpxchg_val_at_resolved(access, expected_val, new_val, value_type); - } - - Node* result = BarrierSetC2::atomic_cmpxchg_val_at_resolved(access, expected_val, new_val, value_type); - - post_barrier(access.kit(), access.base(), access.addr().node(), new_val, true); - - return result; -} - -Node* ModRefBarrierSetC2::atomic_cmpxchg_bool_at_resolved(C2AtomicParseAccess& access, Node* expected_val, - Node* new_val, const Type* value_type) const { - GraphKit* kit = access.kit(); - - if (!access.is_oop()) { - return BarrierSetC2::atomic_cmpxchg_bool_at_resolved(access, expected_val, new_val, value_type); - } - - Node* load_store = BarrierSetC2::atomic_cmpxchg_bool_at_resolved(access, expected_val, new_val, value_type); - - // Emit the post barrier only when the actual store happened. This makes sense - // to check only for LS_cmp_* that can fail to set the value. - // LS_cmp_exchange does not produce any branches by default, so there is no - // boolean result to piggyback on. TODO: When we merge CompareAndSwap with - // CompareAndExchange and move branches here, it would make sense to conditionalize - // post_barriers for LS_cmp_exchange as well. - // - // CAS success path is marked more likely since we anticipate this is a performance - // critical path, while CAS failure path can use the penalty for going through unlikely - // path as backoff. Which is still better than doing a store barrier there. - IdealKit ideal(kit); - ideal.if_then(load_store, BoolTest::ne, ideal.ConI(0), PROB_STATIC_FREQUENT); { - kit->sync_kit(ideal); - post_barrier(kit, access.base(), access.addr().node(), new_val, true); - ideal.sync_kit(kit); - } ideal.end_if(); - kit->final_sync(ideal); - - return load_store; -} - -Node* ModRefBarrierSetC2::atomic_xchg_at_resolved(C2AtomicParseAccess& access, Node* new_val, const Type* value_type) const { - Node* result = BarrierSetC2::atomic_xchg_at_resolved(access, new_val, value_type); - if (!access.is_oop()) { - return result; - } - - post_barrier(access.kit(), access.base(), access.addr().node(), new_val, true); - - return result; -} diff --git a/src/hotspot/share/gc/shared/c2/modRefBarrierSetC2.hpp b/src/hotspot/share/gc/shared/c2/modRefBarrierSetC2.hpp deleted file mode 100644 index 42fe3f7d0b6a4..0000000000000 --- a/src/hotspot/share/gc/shared/c2/modRefBarrierSetC2.hpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_GC_SHARED_C2_MODREFBARRIERSETC2_HPP -#define SHARE_GC_SHARED_C2_MODREFBARRIERSETC2_HPP - -#include "gc/shared/c2/barrierSetC2.hpp" - -class TypeOopPtr; - -class ModRefBarrierSetC2: public BarrierSetC2 { -protected: - virtual void post_barrier(GraphKit* kit, - Node* obj, - Node* adr, - Node* val, - bool use_precise) const {} - - virtual Node* store_at_resolved(C2Access& access, C2AccessValue& val) const; - - virtual Node* atomic_cmpxchg_val_at_resolved(C2AtomicParseAccess& access, Node* expected_val, - Node* new_val, const Type* value_type) const; - virtual Node* atomic_cmpxchg_bool_at_resolved(C2AtomicParseAccess& access, Node* expected_val, - Node* new_val, const Type* value_type) const; - virtual Node* atomic_xchg_at_resolved(C2AtomicParseAccess& access, Node* new_val, const Type* value_type) const; -}; - -#endif // SHARE_GC_SHARED_C2_MODREFBARRIERSETC2_HPP diff --git a/src/hotspot/share/gc/shared/cardTableBarrierSet.cpp b/src/hotspot/share/gc/shared/cardTableBarrierSet.cpp index de514f64be2b0..539e40820a814 100644 --- a/src/hotspot/share/gc/shared/cardTableBarrierSet.cpp +++ b/src/hotspot/share/gc/shared/cardTableBarrierSet.cpp @@ -53,18 +53,22 @@ CardTableBarrierSet::CardTableBarrierSet(BarrierSetAssembler* barrier_set_assemb BarrierSetC2* barrier_set_c2, CardTable* card_table, const BarrierSet::FakeRtti& fake_rtti) : - ModRefBarrierSet(barrier_set_assembler, - barrier_set_c1, - barrier_set_c2, - fake_rtti.add_tag(BarrierSet::CardTableBarrierSet)), + BarrierSet(barrier_set_assembler, + barrier_set_c1, + barrier_set_c2, + nullptr /* barrier_set_nmethod */, + nullptr /* barrier_set_stack_chunk */, + fake_rtti.add_tag(BarrierSet::CardTableBarrierSet)), _card_table(card_table) {} CardTableBarrierSet::CardTableBarrierSet(CardTable* card_table) : - ModRefBarrierSet(make_barrier_set_assembler(), - make_barrier_set_c1(), - make_barrier_set_c2(), - BarrierSet::FakeRtti(BarrierSet::CardTableBarrierSet)), + BarrierSet(make_barrier_set_assembler(), + make_barrier_set_c1(), + make_barrier_set_c2(), + nullptr /* barrier_set_nmethod */, + nullptr /* barrier_set_stack_chunk */, + BarrierSet::FakeRtti(BarrierSet::CardTableBarrierSet)), _card_table(card_table) {} diff --git a/src/hotspot/share/gc/shared/cardTableBarrierSet.hpp b/src/hotspot/share/gc/shared/cardTableBarrierSet.hpp index a5646c303f38a..dea3609867330 100644 --- a/src/hotspot/share/gc/shared/cardTableBarrierSet.hpp +++ b/src/hotspot/share/gc/shared/cardTableBarrierSet.hpp @@ -25,8 +25,9 @@ #ifndef SHARE_GC_SHARED_CARDTABLEBARRIERSET_HPP #define SHARE_GC_SHARED_CARDTABLEBARRIERSET_HPP +#include "gc/shared/barrierSet.hpp" #include "gc/shared/cardTable.hpp" -#include "gc/shared/modRefBarrierSet.hpp" +#include "memory/memRegion.hpp" #include "utilities/align.hpp" // This kind of "BarrierSet" allows a "CollectedHeap" to detect and @@ -41,7 +42,7 @@ // Closures used to scan dirty cards should take these // considerations into account. -class CardTableBarrierSet: public ModRefBarrierSet { +class CardTableBarrierSet: public BarrierSet { // Some classes get to look at some private stuff. friend class VMStructs; @@ -59,23 +60,68 @@ class CardTableBarrierSet: public ModRefBarrierSet { CardTableBarrierSet(CardTable* card_table); virtual ~CardTableBarrierSet(); - CardTable* card_table() const { return _card_table; } + template + inline void write_ref_field_pre(T* addr) {} // Record a reference update. Note that these versions are precise! // The scanning code has to handle the fact that the write barrier may be // either precise or imprecise. We make non-virtual inline variants of // these functions here for performance. template - void write_ref_field_post(T* field); + inline void write_ref_field_post(T *addr); + // Causes all refs in "mr" to be assumed to be modified (by this JavaThread). virtual void write_region(MemRegion mr); + // Operations on arrays, or general regions (e.g., for "clone") may be + // optimized by some barriers. + + // Below length is the # array elements being written + virtual void write_ref_array_pre(oop* dst, size_t length, + bool dest_uninitialized) {} + virtual void write_ref_array_pre(narrowOop* dst, size_t length, + bool dest_uninitialized) {} + // Below count is the # array elements being written, starting + // at the address "start", which may not necessarily be HeapWord-aligned + inline void write_ref_array(HeapWord* start, size_t count); + + CardTable* card_table() const { return _card_table; } + virtual void on_slowpath_allocation_exit(JavaThread* thread, oop new_obj); virtual void print_on(outputStream* st) const; template - class AccessBarrier: public ModRefBarrierSet::AccessBarrier {}; + class AccessBarrier: public BarrierSet::AccessBarrier { + typedef BarrierSet::AccessBarrier Raw; + + public: + template + static void oop_store_in_heap(T* addr, oop value); + template + static oop oop_atomic_cmpxchg_in_heap(T* addr, oop compare_value, oop new_value); + template + static oop oop_atomic_xchg_in_heap(T* addr, oop new_value); + + template + static bool oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw, + arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw, + size_t length); + + static void clone_in_heap(oop src, oop dst, size_t size); + + static void oop_store_in_heap_at(oop base, ptrdiff_t offset, oop value) { + oop_store_in_heap(AccessInternal::oop_field_addr(base, offset), value); + } + + static oop oop_atomic_xchg_in_heap_at(oop base, ptrdiff_t offset, oop new_value) { + return oop_atomic_xchg_in_heap(AccessInternal::oop_field_addr(base, offset), new_value); + } + + static oop oop_atomic_cmpxchg_in_heap_at(oop base, ptrdiff_t offset, oop compare_value, oop new_value) { + return oop_atomic_cmpxchg_in_heap(AccessInternal::oop_field_addr(base, offset), compare_value, new_value); + } + }; }; template<> diff --git a/src/hotspot/share/gc/shared/cardTableBarrierSet.inline.hpp b/src/hotspot/share/gc/shared/cardTableBarrierSet.inline.hpp index 3d87cb2e69dfb..7fc3fee1e7c0d 100644 --- a/src/hotspot/share/gc/shared/cardTableBarrierSet.inline.hpp +++ b/src/hotspot/share/gc/shared/cardTableBarrierSet.inline.hpp @@ -27,8 +27,11 @@ #include "gc/shared/cardTableBarrierSet.hpp" +#include "gc/shared/barrierSet.hpp" #include "gc/shared/cardTable.hpp" -#include "runtime/atomicAccess.hpp" +#include "oops/compressedOops.inline.hpp" +#include "oops/objArrayOop.hpp" +#include "oops/oop.hpp" template inline void CardTableBarrierSet::write_ref_field_post(T* field) { @@ -36,4 +39,112 @@ inline void CardTableBarrierSet::write_ref_field_post(T* field) { *byte = CardTable::dirty_card_val(); } +class Klass; + +// count is number of array elements being written +void CardTableBarrierSet::write_ref_array(HeapWord* start, size_t count) { + HeapWord* end = (HeapWord*)((char*)start + (count*heapOopSize)); + // In the case of compressed oops, start and end may potentially be misaligned; + // so we need to conservatively align the first downward (this is not + // strictly necessary for current uses, but a case of good hygiene and, + // if you will, aesthetics) and the second upward (this is essential for + // current uses) to a HeapWord boundary, so we mark all cards overlapping + // this write. If this evolves in the future to calling a + // logging barrier of narrow oop granularity, like the pre-barrier for G1 + // (mentioned here merely by way of example), we will need to change this + // interface, so it is "exactly precise" (if i may be allowed the adverbial + // redundancy for emphasis) and does not include narrow oop slots not + // included in the original write interval. + HeapWord* aligned_start = align_down(start, HeapWordSize); + HeapWord* aligned_end = align_up (end, HeapWordSize); + // If compressed oops were not being used, these should already be aligned + assert(UseCompressedOops || (aligned_start == start && aligned_end == end), + "Expected heap word alignment of start and end"); + write_region(MemRegion(aligned_start, aligned_end)); +} + +template +template +inline void CardTableBarrierSet::AccessBarrier:: +oop_store_in_heap(T* addr, oop value) { + BarrierSetT *bs = barrier_set_cast(barrier_set()); + bs->template write_ref_field_pre(addr); + Raw::oop_store(addr, value); + bs->template write_ref_field_post(addr); +} + +template +template +inline oop CardTableBarrierSet::AccessBarrier:: +oop_atomic_cmpxchg_in_heap(T* addr, oop compare_value, oop new_value) { + BarrierSetT *bs = barrier_set_cast(barrier_set()); + bs->template write_ref_field_pre(addr); + oop result = Raw::oop_atomic_cmpxchg(addr, compare_value, new_value); + if (result == compare_value) { + bs->template write_ref_field_post(addr); + } + return result; +} + +template +template +inline oop CardTableBarrierSet::AccessBarrier:: +oop_atomic_xchg_in_heap(T* addr, oop new_value) { + BarrierSetT *bs = barrier_set_cast(barrier_set()); + bs->template write_ref_field_pre(addr); + oop result = Raw::oop_atomic_xchg(addr, new_value); + bs->template write_ref_field_post(addr); + return result; +} + +template +template +inline bool CardTableBarrierSet::AccessBarrier:: +oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw, + arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw, + size_t length) { + BarrierSetT *bs = barrier_set_cast(barrier_set()); + + src_raw = arrayOopDesc::obj_offset_to_raw(src_obj, src_offset_in_bytes, src_raw); + dst_raw = arrayOopDesc::obj_offset_to_raw(dst_obj, dst_offset_in_bytes, dst_raw); + + if (!HasDecorator::value) { + // Optimized covariant case + bs->write_ref_array_pre(dst_raw, length, + HasDecorator::value); + Raw::oop_arraycopy(nullptr, 0, src_raw, nullptr, 0, dst_raw, length); + bs->write_ref_array((HeapWord*)dst_raw, length); + } else { + assert(dst_obj != nullptr, "better have an actual oop"); + Klass* bound = objArrayOop(dst_obj)->element_klass(); + T* from = const_cast(src_raw); + T* end = from + length; + for (T* p = dst_raw; from < end; from++, p++) { + T element = *from; + if (oopDesc::is_instanceof_or_null(CompressedOops::decode(element), bound)) { + bs->template write_ref_field_pre(p); + *p = element; + } else { + // We must do a barrier to cover the partial copy. + const size_t pd = pointer_delta(p, dst_raw, (size_t)heapOopSize); + // pointer delta is scaled to number of elements (length field in + // objArrayOop) which we assume is 32 bit. + assert(pd == (size_t)(int)pd, "length field overflow"); + bs->write_ref_array((HeapWord*)dst_raw, pd); + return false; + } + } + bs->write_ref_array((HeapWord*)dst_raw, length); + } + return true; +} + +template +inline void CardTableBarrierSet::AccessBarrier:: +clone_in_heap(oop src, oop dst, size_t size) { + Raw::clone(src, dst, size); + BarrierSetT *bs = barrier_set_cast(barrier_set()); + bs->write_region(MemRegion((HeapWord*)(void*)dst, size)); +} + #endif // SHARE_GC_SHARED_CARDTABLEBARRIERSET_INLINE_HPP diff --git a/src/hotspot/share/gc/shared/modRefBarrierSet.hpp b/src/hotspot/share/gc/shared/modRefBarrierSet.hpp deleted file mode 100644 index c078d151233d1..0000000000000 --- a/src/hotspot/share/gc/shared/modRefBarrierSet.hpp +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_GC_SHARED_MODREFBARRIERSET_HPP -#define SHARE_GC_SHARED_MODREFBARRIERSET_HPP - -#include "gc/shared/barrierSet.hpp" -#include "memory/memRegion.hpp" - -class Klass; - -class ModRefBarrierSet: public BarrierSet { -protected: - ModRefBarrierSet(BarrierSetAssembler* barrier_set_assembler, - BarrierSetC1* barrier_set_c1, - BarrierSetC2* barrier_set_c2, - const BarrierSet::FakeRtti& fake_rtti) - : BarrierSet(barrier_set_assembler, - barrier_set_c1, - barrier_set_c2, - nullptr /* barrier_set_nmethod */, - nullptr /* barrier_set_stack_chunk */, - fake_rtti.add_tag(BarrierSet::ModRef)) { } - ~ModRefBarrierSet() { } - -public: - template - inline void write_ref_field_pre(T* addr) {} - - template - inline void write_ref_field_post(T *addr) {} - - // Causes all refs in "mr" to be assumed to be modified (by this JavaThread). - virtual void write_region(MemRegion mr) = 0; - - // Operations on arrays, or general regions (e.g., for "clone") may be - // optimized by some barriers. - - // Below length is the # array elements being written - virtual void write_ref_array_pre(oop* dst, size_t length, - bool dest_uninitialized) {} - virtual void write_ref_array_pre(narrowOop* dst, size_t length, - bool dest_uninitialized) {} - // Below count is the # array elements being written, starting - // at the address "start", which may not necessarily be HeapWord-aligned - inline void write_ref_array(HeapWord* start, size_t count); - - // The ModRef abstraction introduces pre and post barriers - template - class AccessBarrier: public BarrierSet::AccessBarrier { - typedef BarrierSet::AccessBarrier Raw; - - public: - template - static void oop_store_in_heap(T* addr, oop value); - template - static oop oop_atomic_cmpxchg_in_heap(T* addr, oop compare_value, oop new_value); - template - static oop oop_atomic_xchg_in_heap(T* addr, oop new_value); - - template - static bool oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw, - arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw, - size_t length); - - static void clone_in_heap(oop src, oop dst, size_t size); - - static void oop_store_in_heap_at(oop base, ptrdiff_t offset, oop value) { - oop_store_in_heap(AccessInternal::oop_field_addr(base, offset), value); - } - - static oop oop_atomic_xchg_in_heap_at(oop base, ptrdiff_t offset, oop new_value) { - return oop_atomic_xchg_in_heap(AccessInternal::oop_field_addr(base, offset), new_value); - } - - static oop oop_atomic_cmpxchg_in_heap_at(oop base, ptrdiff_t offset, oop compare_value, oop new_value) { - return oop_atomic_cmpxchg_in_heap(AccessInternal::oop_field_addr(base, offset), compare_value, new_value); - } - }; -}; - -template<> -struct BarrierSet::GetName { - static const BarrierSet::Name value = BarrierSet::ModRef; -}; - -#endif // SHARE_GC_SHARED_MODREFBARRIERSET_HPP diff --git a/src/hotspot/share/gc/shared/modRefBarrierSet.inline.hpp b/src/hotspot/share/gc/shared/modRefBarrierSet.inline.hpp deleted file mode 100644 index f5ad4f2c7564e..0000000000000 --- a/src/hotspot/share/gc/shared/modRefBarrierSet.inline.hpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_GC_SHARED_MODREFBARRIERSET_INLINE_HPP -#define SHARE_GC_SHARED_MODREFBARRIERSET_INLINE_HPP - -#include "gc/shared/modRefBarrierSet.hpp" - -#include "gc/shared/barrierSet.hpp" -#include "oops/compressedOops.inline.hpp" -#include "oops/objArrayOop.hpp" -#include "oops/oop.hpp" -#include "runtime/thread.hpp" - -class Klass; - -// count is number of array elements being written -void ModRefBarrierSet::write_ref_array(HeapWord* start, size_t count) { - HeapWord* end = (HeapWord*)((char*)start + (count*heapOopSize)); - // In the case of compressed oops, start and end may potentially be misaligned; - // so we need to conservatively align the first downward (this is not - // strictly necessary for current uses, but a case of good hygiene and, - // if you will, aesthetics) and the second upward (this is essential for - // current uses) to a HeapWord boundary, so we mark all cards overlapping - // this write. If this evolves in the future to calling a - // logging barrier of narrow oop granularity, like the pre-barrier for G1 - // (mentioned here merely by way of example), we will need to change this - // interface, so it is "exactly precise" (if i may be allowed the adverbial - // redundancy for emphasis) and does not include narrow oop slots not - // included in the original write interval. - HeapWord* aligned_start = align_down(start, HeapWordSize); - HeapWord* aligned_end = align_up (end, HeapWordSize); - // If compressed oops were not being used, these should already be aligned - assert(UseCompressedOops || (aligned_start == start && aligned_end == end), - "Expected heap word alignment of start and end"); - write_region(MemRegion(aligned_start, aligned_end)); -} - -template -template -inline void ModRefBarrierSet::AccessBarrier:: -oop_store_in_heap(T* addr, oop value) { - BarrierSetT *bs = barrier_set_cast(barrier_set()); - bs->template write_ref_field_pre(addr); - Raw::oop_store(addr, value); - bs->template write_ref_field_post(addr); -} - -template -template -inline oop ModRefBarrierSet::AccessBarrier:: -oop_atomic_cmpxchg_in_heap(T* addr, oop compare_value, oop new_value) { - BarrierSetT *bs = barrier_set_cast(barrier_set()); - bs->template write_ref_field_pre(addr); - oop result = Raw::oop_atomic_cmpxchg(addr, compare_value, new_value); - if (result == compare_value) { - bs->template write_ref_field_post(addr); - } - return result; -} - -template -template -inline oop ModRefBarrierSet::AccessBarrier:: -oop_atomic_xchg_in_heap(T* addr, oop new_value) { - BarrierSetT *bs = barrier_set_cast(barrier_set()); - bs->template write_ref_field_pre(addr); - oop result = Raw::oop_atomic_xchg(addr, new_value); - bs->template write_ref_field_post(addr); - return result; -} - -template -template -inline bool ModRefBarrierSet::AccessBarrier:: -oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw, - arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw, - size_t length) { - BarrierSetT *bs = barrier_set_cast(barrier_set()); - - src_raw = arrayOopDesc::obj_offset_to_raw(src_obj, src_offset_in_bytes, src_raw); - dst_raw = arrayOopDesc::obj_offset_to_raw(dst_obj, dst_offset_in_bytes, dst_raw); - - if (!HasDecorator::value) { - // Optimized covariant case - bs->write_ref_array_pre(dst_raw, length, - HasDecorator::value); - Raw::oop_arraycopy(nullptr, 0, src_raw, nullptr, 0, dst_raw, length); - bs->write_ref_array((HeapWord*)dst_raw, length); - } else { - assert(dst_obj != nullptr, "better have an actual oop"); - Klass* bound = objArrayOop(dst_obj)->element_klass(); - T* from = const_cast(src_raw); - T* end = from + length; - for (T* p = dst_raw; from < end; from++, p++) { - T element = *from; - if (oopDesc::is_instanceof_or_null(CompressedOops::decode(element), bound)) { - bs->template write_ref_field_pre(p); - *p = element; - } else { - // We must do a barrier to cover the partial copy. - const size_t pd = pointer_delta(p, dst_raw, (size_t)heapOopSize); - // pointer delta is scaled to number of elements (length field in - // objArrayOop) which we assume is 32 bit. - assert(pd == (size_t)(int)pd, "length field overflow"); - bs->write_ref_array((HeapWord*)dst_raw, pd); - return false; - } - } - bs->write_ref_array((HeapWord*)dst_raw, length); - } - return true; -} - -template -inline void ModRefBarrierSet::AccessBarrier:: -clone_in_heap(oop src, oop dst, size_t size) { - Raw::clone(src, dst, size); - BarrierSetT *bs = barrier_set_cast(barrier_set()); - bs->write_region(MemRegion((HeapWord*)(void*)dst, size)); -} - -#endif // SHARE_GC_SHARED_MODREFBARRIERSET_INLINE_HPP diff --git a/src/hotspot/share/gc/shared/modRefBarrierSetAssembler.hpp b/src/hotspot/share/gc/shared/modRefBarrierSetAssembler.hpp deleted file mode 100644 index 43f1a5d2dc30d..0000000000000 --- a/src/hotspot/share/gc/shared/modRefBarrierSetAssembler.hpp +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_GC_SHARED_MODREFBARRIERSETASSEMBLER_HPP -#define SHARE_GC_SHARED_MODREFBARRIERSETASSEMBLER_HPP - -#include "utilities/macros.hpp" - -#include CPU_HEADER(gc/shared/modRefBarrierSetAssembler) - -#endif // SHARE_GC_SHARED_MODREFBARRIERSETASSEMBLER_HPP diff --git a/src/hotspot/share/gc/shared/vmStructs_gc.hpp b/src/hotspot/share/gc/shared/vmStructs_gc.hpp index 9d84a56fbd748..3a644079875c9 100644 --- a/src/hotspot/share/gc/shared/vmStructs_gc.hpp +++ b/src/hotspot/share/gc/shared/vmStructs_gc.hpp @@ -132,8 +132,7 @@ declare_toplevel_type(CollectedHeap) \ declare_toplevel_type(ContiguousSpace) \ declare_toplevel_type(BarrierSet) \ - declare_type(ModRefBarrierSet, BarrierSet) \ - declare_type(CardTableBarrierSet, ModRefBarrierSet) \ + declare_type(CardTableBarrierSet, BarrierSet) \ declare_toplevel_type(CardTable) \ declare_toplevel_type(BarrierSet::Name) \ \ @@ -183,7 +182,6 @@ \ declare_constant(AgeTable::table_size) \ \ - declare_constant(BarrierSet::ModRef) \ declare_constant(BarrierSet::CardTableBarrierSet) \ \ declare_constant(BOTConstants::LogBase) \ diff --git a/src/hotspot/share/oops/access.inline.hpp b/src/hotspot/share/oops/access.inline.hpp index b3f15f1168d8d..da3d54c49022d 100644 --- a/src/hotspot/share/oops/access.inline.hpp +++ b/src/hotspot/share/oops/access.inline.hpp @@ -219,7 +219,7 @@ namespace AccessInternal { AccessBarrier, barrier_type, ds>::oop_access_barrier; \ } \ break; - FOR_EACH_CONCRETE_BARRIER_SET_DO(BARRIER_SET_RESOLVE_BARRIER_CLOSURE) + FOR_EACH_BARRIER_SET_DO(BARRIER_SET_RESOLVE_BARRIER_CLOSURE) #undef BARRIER_SET_RESOLVE_BARRIER_CLOSURE default: @@ -242,7 +242,7 @@ namespace AccessInternal { AccessBarrier, barrier_type, ds>::access_barrier; \ } \ break; - FOR_EACH_CONCRETE_BARRIER_SET_DO(BARRIER_SET_RESOLVE_BARRIER_CLOSURE) + FOR_EACH_BARRIER_SET_DO(BARRIER_SET_RESOLVE_BARRIER_CLOSURE) #undef BARRIER_SET_RESOLVE_BARRIER_CLOSURE default: diff --git a/src/hotspot/share/runtime/continuationFreezeThaw.cpp b/src/hotspot/share/runtime/continuationFreezeThaw.cpp index 3e509e71551da..345ae965bb7ac 100644 --- a/src/hotspot/share/runtime/continuationFreezeThaw.cpp +++ b/src/hotspot/share/runtime/continuationFreezeThaw.cpp @@ -3053,7 +3053,7 @@ class ConfigResolve { resolve::type>(); \ } \ break; - FOR_EACH_CONCRETE_BARRIER_SET_DO(BARRIER_SET_RESOLVE_BARRIER_CLOSURE) + FOR_EACH_BARRIER_SET_DO(BARRIER_SET_RESOLVE_BARRIER_CLOSURE) #undef BARRIER_SET_RESOLVE_BARRIER_CLOSURE default: