1 /*
2 * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 #ifndef SHARE_GC_Z_C2_ZBARRIERSETC2_HPP
25 #define SHARE_GC_Z_C2_ZBARRIERSETC2_HPP
26
27 #include "gc/shared/c2/barrierSetC2.hpp"
28 #include "memory/allocation.hpp"
29 #include "opto/node.hpp"
30 #include "utilities/growableArray.hpp"
31
32 const uint8_t ZBarrierStrong = 1;
33 const uint8_t ZBarrierWeak = 2;
34 const uint8_t ZBarrierPhantom = 4;
35 const uint8_t ZBarrierNoKeepalive = 8;
36 const uint8_t ZBarrierNative = 16;
37 const uint8_t ZBarrierElided = 32;
38
39 class Block;
40 class MachNode;
41
42 class MacroAssembler;
43
44 class ZBarrierStubC2 : public BarrierStubC2 {
45 protected:
46 static void register_stub(ZBarrierStubC2* stub);
47 static void inc_trampoline_stubs_count();
48 static int trampoline_stubs_count();
49 static int stubs_start_offset();
50
51 ZBarrierStubC2(const MachNode* node);
52
53 public:
54 virtual void emit_code(MacroAssembler& masm) = 0;
55 };
56
57 class ZLoadBarrierStubC2 : public ZBarrierStubC2 {
58 private:
59 const Address _ref_addr;
60 const Register _ref;
61
62 protected:
63 ZLoadBarrierStubC2(const MachNode* node, Address ref_addr, Register ref);
64
65 public:
66 static ZLoadBarrierStubC2* create(const MachNode* node, Address ref_addr, Register ref);
67
68 Address ref_addr() const;
69 Register ref() const;
70 address slow_path() const;
71
72 virtual void emit_code(MacroAssembler& masm);
73 };
74
75 class ZStoreBarrierStubC2 : public ZBarrierStubC2 {
76 private:
77 const Address _ref_addr;
78 const Register _new_zaddress;
79 const Register _new_zpointer;
80 const bool _is_native;
81 const bool _is_atomic;
82 const bool _is_nokeepalive;
83
84 protected:
85 ZStoreBarrierStubC2(const MachNode* node, Address ref_addr, Register new_zaddress, Register new_zpointer, bool is_native, bool is_atomic, bool is_nokeepalive);
86
87 public:
88 static ZStoreBarrierStubC2* create(const MachNode* node, Address ref_addr, Register new_zaddress, Register new_zpointer, bool is_native, bool is_atomic, bool is_nokeepalive);
89
90 Address ref_addr() const;
91 Register new_zaddress() const;
92 Register new_zpointer() const;
93 bool is_native() const;
94 bool is_atomic() const;
95 bool is_nokeepalive() const;
96
97 virtual void emit_code(MacroAssembler& masm);
98 };
99
100 class ZBarrierSetC2 : public BarrierSetC2 {
101 private:
102 void analyze_dominating_barriers() const;
103
104 protected:
105 virtual Node* store_at_resolved(C2Access& access, C2AccessValue& val) const;
106 virtual Node* load_at_resolved(C2Access& access, const Type* val_type) const;
107 virtual Node* atomic_cmpxchg_val_at_resolved(C2AtomicParseAccess& access,
108 Node* expected_val,
109 Node* new_val,
110 const Type* val_type) const;
111 virtual Node* atomic_cmpxchg_bool_at_resolved(C2AtomicParseAccess& access,
112 Node* expected_val,
113 Node* new_val,
114 const Type* value_type) const;
115 virtual Node* atomic_xchg_at_resolved(C2AtomicParseAccess& access,
116 Node* new_val,
117 const Type* val_type) const;
118
119 public:
120 virtual uint estimated_barrier_size(const Node* node) const;
121 virtual void* create_barrier_state(Arena* comp_arena) const;
122 virtual bool array_copy_requires_gc_barriers(bool tightly_coupled_alloc,
123 BasicType type,
124 bool is_clone,
125 bool is_clone_instance,
126 ArrayCopyPhase phase) const;
127 virtual void clone_at_expansion(PhaseMacroExpand* phase,
128 ArrayCopyNode* ac) const;
129
130 virtual void elide_dominated_barrier(MachNode* mach) const;
131 virtual void late_barrier_analysis() const;
132 virtual int estimate_stub_size() const;
133 virtual void emit_stubs(CodeBuffer& cb) const;
134 virtual void eliminate_gc_barrier(PhaseIterGVN* igvn, Node* node) const;
135 virtual void eliminate_gc_barrier_data(Node* node) const;
136
137 #ifndef PRODUCT
138 virtual void dump_barrier_data(const MachNode* mach, outputStream* st) const;
139 #endif
140 };
141
142 #endif // SHARE_GC_Z_C2_ZBARRIERSETC2_HPP