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 //
82 // Materialize the store address internally (as opposed to defining 'mem' as
83 // an indirect memory operand) to reduce the overhead of LCM when processing
84 // large basic blocks with many stores. Such basic blocks arise, for
85 // instance, from static initializations of large String arrays.
86 // The same holds for g1StoreN and g1EncodePAndStoreN.
87 __ lea($tmp1$$Register, $mem$$Address);
88 write_barrier_pre(masm, this,
89 $tmp1$$Register /* obj */,
90 $tmp2$$Register /* pre_val */,
91 $tmp3$$Register /* tmp */,
92 RegSet::of($tmp1$$Register, $src$$Register) /* preserve */);
93 __ movq(Address($tmp1$$Register, 0), $src$$Register);
94 write_barrier_post(masm, this,
95 $tmp1$$Register /* store_addr */,
96 $src$$Register /* new_val */,
97 $tmp3$$Register /* tmp1 */);
98 %}
99 ins_pipe(ialu_mem_reg);
100 %}
101
102 instruct g1StoreN(memory mem, rRegN src, rRegP tmp1, rRegP tmp2, rRegP tmp3, rFlagsReg cr)
103 %{
104 predicate(UseG1GC && n->as_Store()->barrier_data() != 0);
105 match(Set mem (StoreN mem src));
106 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
107 ins_cost(125); // XXX
108 format %{ "movl $mem, $src\t# ptr" %}
109 ins_encode %{
110 __ lea($tmp1$$Register, $mem$$Address);
111 write_barrier_pre(masm, this,
112 $tmp1$$Register /* obj */,
113 $tmp2$$Register /* pre_val */,
114 $tmp3$$Register /* tmp */,
115 RegSet::of($tmp1$$Register, $src$$Register) /* preserve */);
116 __ movl(Address($tmp1$$Register, 0), $src$$Register);
117 if ((barrier_data() & G1C2BarrierPost) != 0) {
118 __ movl($tmp2$$Register, $src$$Register);
119 if ((barrier_data() & G1C2BarrierPostNotNull) == 0) {
120 __ decode_heap_oop($tmp2$$Register);
121 } else {
|
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 //
82 // Materialize the store address internally (as opposed to defining 'mem' as
83 // an indirect memory operand) to reduce the overhead of LCM when processing
84 // large basic blocks with many stores. Such basic blocks arise, for
85 // instance, from static initializations of large String arrays.
86 // The same holds for g1StoreN and g1EncodePAndStoreN.
87 __ lea($tmp1$$Register, $mem$$Address);
88 write_barrier_pre(masm, this,
89 $tmp1$$Register /* obj */,
90 $tmp2$$Register /* pre_val */,
91 $tmp3$$Register /* tmp */,
92 RegSet::of($tmp1$$Register, $src$$Register) /* preserve */);
93 __ movq(Address($tmp1$$Register, 0), $src$$Register);
94 write_barrier_post(masm, this,
95 $tmp1$$Register /* store_addr */,
96 $src$$Register /* new_val */,
97 $tmp3$$Register /* tmp1 */);
98 %}
99 ins_pipe(ialu_mem_reg);
100 %}
101
102 // TODO 8350865 (same applies to g1StoreLSpecialTwoOops)
103 // - Do no set/overwrite barrier data here, also handle G1C2BarrierPostNotNull
104 instruct g1StoreLSpecialOneOopOff0(memory mem, rRegL src, immI_0 off, rRegP tmp1, rRegP tmp2, rRegP tmp3, rFlagsReg cr)
105 %{
106 predicate(UseG1GC);
107 match(Set mem (StoreLSpecial mem (Binary src off)));
108 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
109 format %{ "movq $mem, $src\t# g1StoreLSpecialOneOopOff0" %}
110 ins_encode %{
111 ((MachNode*)this)->set_barrier_data(G1C2BarrierPre | G1C2BarrierPost);
112
113 __ lea($tmp1$$Register, $mem$$Address);
114 write_barrier_pre(masm, this,
115 $tmp1$$Register /* obj */,
116 $tmp2$$Register /* pre_val */,
117 $tmp3$$Register /* tmp */,
118 RegSet::of($tmp1$$Register, $src$$Register) /* preserve */);
119
120 __ movq(Address($tmp1$$Register, 0), $src$$Register);
121
122 // Extract the narrow oop field value
123 __ movl($tmp2$$Register, $src$$Register);
124 __ decode_heap_oop($tmp2$$Register);
125 write_barrier_post(masm, this,
126 $tmp1$$Register /* store_addr */,
127 $tmp2$$Register /* new_val */,
128 $tmp3$$Register /* tmp1 */);
129 %}
130 ins_pipe(ialu_mem_reg);
131 %}
132
133 instruct g1StoreLSpecialOneOopOff4(memory mem, rRegL src, immI_4 off, rRegP tmp1, rRegP tmp2, rRegP tmp3, rFlagsReg cr)
134 %{
135 predicate(UseG1GC);
136 match(Set mem (StoreLSpecial mem (Binary src off)));
137 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
138 format %{ "movq $mem, $src\t# g1StoreLSpecialOneOopOff4" %}
139 ins_encode %{
140 ((MachNode*)this)->set_barrier_data(G1C2BarrierPre | G1C2BarrierPost);
141
142 // Adjust address to point to narrow oop
143 Address dst = $mem$$Address;
144 __ lea($tmp1$$Register, dst.plus_disp(4));
145 write_barrier_pre(masm, this,
146 $tmp1$$Register /* obj */,
147 $tmp2$$Register /* pre_val */,
148 $tmp3$$Register /* tmp */,
149 RegSet::of($tmp1$$Register, $src$$Register) /* preserve */);
150
151 // The address of the oop is the address of the store plus the offset of the oop
152 __ movq(Address($tmp1$$Register, -4), $src$$Register);
153
154 // Shift long value to extract the narrow oop field value
155 __ movq($tmp2$$Register, $src$$Register);
156 __ shrq($tmp2$$Register, 32);
157 __ decode_heap_oop($tmp2$$Register);
158 write_barrier_post(masm, this,
159 $tmp1$$Register /* store_addr */,
160 $src$$Register /* new_val */,
161 $tmp3$$Register /* tmp1 */);
162 %}
163 ins_pipe(ialu_mem_reg);
164 %}
165
166 instruct g1StoreLSpecialTwoOops(memory mem, rRegL src, rRegP tmp1, rRegP tmp2, rRegP tmp3, rFlagsReg cr)
167 %{
168 predicate(UseG1GC);
169 match(Set mem (StoreLSpecial mem src));
170 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
171 format %{ "movq $mem, $src\t# g1StoreLSpecialTwoOops" %}
172 ins_encode %{
173 ((MachNode*)this)->set_barrier_data(G1C2BarrierPre | G1C2BarrierPost);
174
175 __ lea($tmp1$$Register, $mem$$Address);
176 write_barrier_pre(masm, this,
177 $tmp1$$Register /* obj */,
178 $tmp2$$Register /* pre_val */,
179 $tmp3$$Register /* tmp */,
180 RegSet::of($tmp1$$Register, $src$$Register) /* preserve */);
181 // Adjust address to point to the second narrow oop in the long value
182 __ addq($tmp1$$Register, 4);
183 write_barrier_pre(masm, this,
184 $tmp1$$Register /* obj */,
185 $tmp2$$Register /* pre_val */,
186 $tmp3$$Register /* tmp */,
187 RegSet::of($tmp1$$Register, $src$$Register) /* preserve */);
188
189 // The address of the second oop is the address of the store plus the offset of the second oop
190 __ movq(Address($tmp1$$Register, -4), $src$$Register);
191
192 // Do the post-barrier of the second oop first since we have its address in tmp1
193 __ movq($tmp2$$Register, $src$$Register);
194 __ shrq($tmp2$$Register, 32);
195 __ decode_heap_oop($tmp2$$Register);
196 write_barrier_post(masm, this,
197 $tmp1$$Register /* store_addr */,
198 $tmp2$$Register /* new_val */,
199 $tmp3$$Register /* tmp1 */);
200
201 // Retrieve the address of the first narrow oop
202 __ addq($tmp1$$Register, -4);
203 // Extract the first narrow oop
204 __ movl($tmp2$$Register, $src$$Register);
205 __ decode_heap_oop($tmp2$$Register);
206 write_barrier_post(masm, this,
207 $tmp1$$Register /* store_addr */,
208 $tmp2$$Register /* new_val */,
209 $tmp3$$Register /* tmp1 */);
210 %}
211 ins_pipe(ialu_mem_reg);
212 %}
213
214 instruct g1StoreN(memory mem, rRegN src, rRegP tmp1, rRegP tmp2, rRegP tmp3, rFlagsReg cr)
215 %{
216 predicate(UseG1GC && n->as_Store()->barrier_data() != 0);
217 match(Set mem (StoreN mem src));
218 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
219 ins_cost(125); // XXX
220 format %{ "movl $mem, $src\t# ptr" %}
221 ins_encode %{
222 __ lea($tmp1$$Register, $mem$$Address);
223 write_barrier_pre(masm, this,
224 $tmp1$$Register /* obj */,
225 $tmp2$$Register /* pre_val */,
226 $tmp3$$Register /* tmp */,
227 RegSet::of($tmp1$$Register, $src$$Register) /* preserve */);
228 __ movl(Address($tmp1$$Register, 0), $src$$Register);
229 if ((barrier_data() & G1C2BarrierPost) != 0) {
230 __ movl($tmp2$$Register, $src$$Register);
231 if ((barrier_data() & G1C2BarrierPostNotNull) == 0) {
232 __ decode_heap_oop($tmp2$$Register);
233 } else {
|