1 //
2 // Copyright (c) 2024, 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 //
56 g1_asm->g1_write_barrier_pre_c2(masm, obj, pre_val, rthread, tmp1, tmp2, stub);
57 }
58
59 static void write_barrier_post(MacroAssembler* masm,
60 const MachNode* node,
61 Register store_addr,
62 Register new_val,
63 Register tmp1,
64 Register tmp2) {
65 if (!G1BarrierStubC2::needs_post_barrier(node)) {
66 return;
67 }
68 Assembler::InlineSkippedInstructionsCounter skip_counter(masm);
69 G1BarrierSetAssembler* g1_asm = static_cast<G1BarrierSetAssembler*>(BarrierSet::barrier_set()->barrier_set_assembler());
70 bool new_val_may_be_null = G1BarrierStubC2::post_new_val_may_be_null(node);
71 g1_asm->g1_write_barrier_post_c2(masm, store_addr, new_val, rthread, tmp1, tmp2, new_val_may_be_null);
72 }
73
74 %}
75
76 // BEGIN This section of the file is automatically generated. Do not edit --------------
77
78 // This section is generated from g1_aarch64.m4
79
80
81 // This pattern is generated automatically from g1_aarch64.m4.
82 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
83 instruct g1StoreP(indirect mem, iRegP src, iRegPNoSp tmp1, iRegPNoSp tmp2, iRegPNoSp tmp3, rFlagsReg cr)
84 %{
85 predicate(UseG1GC && !needs_releasing_store(n) && n->as_Store()->barrier_data() != 0);
86 match(Set mem (StoreP mem src));
87 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
88 ins_cost(INSN_COST);
89 format %{ "str $src, $mem\t# ptr" %}
90 ins_encode %{
91 write_barrier_pre(masm, this,
92 $mem$$Register /* obj */,
93 $tmp1$$Register /* pre_val */,
94 $tmp2$$Register /* tmp1 */,
95 $tmp3$$Register /* tmp2 */,
|
1 //
2 // Copyright (c) 2024, 2026, 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 //
56 g1_asm->g1_write_barrier_pre_c2(masm, obj, pre_val, rthread, tmp1, tmp2, stub);
57 }
58
59 static void write_barrier_post(MacroAssembler* masm,
60 const MachNode* node,
61 Register store_addr,
62 Register new_val,
63 Register tmp1,
64 Register tmp2) {
65 if (!G1BarrierStubC2::needs_post_barrier(node)) {
66 return;
67 }
68 Assembler::InlineSkippedInstructionsCounter skip_counter(masm);
69 G1BarrierSetAssembler* g1_asm = static_cast<G1BarrierSetAssembler*>(BarrierSet::barrier_set()->barrier_set_assembler());
70 bool new_val_may_be_null = G1BarrierStubC2::post_new_val_may_be_null(node);
71 g1_asm->g1_write_barrier_post_c2(masm, store_addr, new_val, rthread, tmp1, tmp2, new_val_may_be_null);
72 }
73
74 %}
75
76 // TODO 8350865 (same applies to g1StoreLSpecialTwoOops)
77 // - Do no set/overwrite barrier data here, also handle G1C2BarrierPostNotNull
78 // - Move this into the .m4?
79 instruct g1StoreLSpecialOneOopOff0(indirect mem, iRegLNoSp src, immI0 off, iRegPNoSp tmp1, iRegPNoSp tmp2, iRegPNoSp tmp3, rFlagsReg cr)
80 %{
81 predicate(UseG1GC);
82 match(Set mem (StoreLSpecial mem (Binary src off)));
83 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
84 ins_cost(INSN_COST);
85 format %{ "str $src, $mem\t# g1StoreLSpecialOneOopOff0" %}
86 ins_encode %{
87 ((MachNode*)this)->set_barrier_data(G1C2BarrierPre | G1C2BarrierPost);
88 write_barrier_pre(masm, this,
89 $mem$$Register /* obj */,
90 $tmp1$$Register /* pre_val */,
91 $tmp2$$Register /* tmp1 */,
92 $tmp3$$Register /* tmp2 */,
93 RegSet::of($mem$$Register, $src$$Register) /* preserve */);
94
95 __ str($src$$Register, $mem$$Register);
96
97 // Extract the narrow oop field value
98 __ ubfm($tmp1$$Register, $src$$Register, 0, 31);
99 __ decode_heap_oop($tmp1$$Register, $tmp1$$Register);
100 write_barrier_post(masm, this,
101 $mem$$Register /* store_addr */,
102 $tmp1$$Register /* new_val */,
103 $tmp2$$Register /* tmp1 */,
104 $tmp3$$Register /* tmp2 */);
105 %}
106 ins_pipe(istore_reg_mem);
107 %}
108
109 instruct g1StoreLSpecialOneOopOff4(indirect mem, iRegLNoSp src, immI_4 off, iRegPNoSp tmp1, iRegPNoSp tmp2, iRegPNoSp tmp3, iRegPNoSp tmp4, rFlagsReg cr)
110 %{
111 predicate(UseG1GC);
112 match(Set mem (StoreLSpecial mem (Binary src off)));
113 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
114 ins_cost(INSN_COST);
115 format %{ "str $src, $mem\t# g1StoreLSpecialOneOopOff4" %}
116 ins_encode %{
117 ((MachNode*)this)->set_barrier_data(G1C2BarrierPre | G1C2BarrierPost);
118
119 // Adjust address to point to narrow oop
120 __ add($tmp4$$Register, $mem$$Register, 4);
121 write_barrier_pre(masm, this,
122 $tmp4$$Register /* obj */,
123 $tmp1$$Register /* pre_val */,
124 $tmp2$$Register /* tmp1 */,
125 $tmp3$$Register /* tmp2 */,
126 RegSet::of($mem$$Register, $src$$Register, $tmp4$$Register) /* preserve */);
127
128 __ str($src$$Register, $mem$$Register);
129
130 // Shift long value to extract the narrow oop field value
131 __ lsr($tmp1$$Register, $src$$Register, 32);
132 __ decode_heap_oop($tmp1$$Register, $tmp1$$Register);
133 write_barrier_post(masm, this,
134 $tmp4$$Register /* store_addr */,
135 $tmp1$$Register /* new_val */,
136 $tmp2$$Register /* tmp1 */,
137 $tmp3$$Register /* tmp2 */);
138 %}
139 ins_pipe(istore_reg_mem);
140 %}
141
142 instruct g1StoreLSpecialTwoOops(indirect mem, iRegLNoSp src, iRegPNoSp tmp1, iRegPNoSp tmp2, iRegPNoSp tmp3, iRegPNoSp tmp4, rFlagsReg cr)
143 %{
144 predicate(UseG1GC);
145 match(Set mem (StoreLSpecial mem src));
146 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
147 ins_cost(INSN_COST);
148 format %{ "str $src, $mem\t# g1StoreLSpecialTwoOops" %}
149 ins_encode %{
150 ((MachNode*)this)->set_barrier_data(G1C2BarrierPre | G1C2BarrierPost);
151
152 write_barrier_pre(masm, this,
153 $mem$$Register /* obj */,
154 $tmp1$$Register /* pre_val */,
155 $tmp2$$Register /* tmp1 */,
156 $tmp3$$Register /* tmp2 */,
157 RegSet::of($mem$$Register, $src$$Register) /* preserve */);
158 // Adjust address to point to the second narrow oop in the long value
159 __ add($tmp4$$Register, $mem$$Register, 4);
160 write_barrier_pre(masm, this,
161 $tmp4$$Register /* obj */,
162 $tmp1$$Register /* pre_val */,
163 $tmp2$$Register /* tmp1 */,
164 $tmp3$$Register /* tmp2 */,
165 RegSet::of($mem$$Register, $src$$Register, $tmp4$$Register) /* preserve */);
166
167 __ str($src$$Register, $mem$$Register);
168
169 // Zero-extend first narrow oop to long
170 __ ubfm($tmp1$$Register, $src$$Register, 0, 31);
171 __ decode_heap_oop($tmp1$$Register, $tmp1$$Register);
172 write_barrier_post(masm, this,
173 $mem$$Register /* store_addr */,
174 $tmp1$$Register /* new_val */,
175 $tmp2$$Register /* tmp1 */,
176 $tmp3$$Register /* tmp2 */);
177
178 // Shift long value to extract the second narrow oop field value
179 __ lsr($tmp1$$Register, $src$$Register, 32);
180 __ decode_heap_oop($tmp1$$Register, $tmp1$$Register);
181 write_barrier_post(masm, this,
182 $tmp4$$Register /* store_addr */,
183 $tmp1$$Register /* new_val */,
184 $tmp2$$Register /* tmp1 */,
185 $tmp3$$Register /* tmp2 */);
186 %}
187 ins_pipe(istore_reg_mem);
188 %}
189
190
191 // BEGIN This section of the file is automatically generated. Do not edit --------------
192
193 // This section is generated from g1_aarch64.m4
194
195
196 // This pattern is generated automatically from g1_aarch64.m4.
197 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
198 instruct g1StoreP(indirect mem, iRegP src, iRegPNoSp tmp1, iRegPNoSp tmp2, iRegPNoSp tmp3, rFlagsReg cr)
199 %{
200 predicate(UseG1GC && !needs_releasing_store(n) && n->as_Store()->barrier_data() != 0);
201 match(Set mem (StoreP mem src));
202 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
203 ins_cost(INSN_COST);
204 format %{ "str $src, $mem\t# ptr" %}
205 ins_encode %{
206 write_barrier_pre(masm, this,
207 $mem$$Register /* obj */,
208 $tmp1$$Register /* pre_val */,
209 $tmp2$$Register /* tmp1 */,
210 $tmp3$$Register /* tmp2 */,
|