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 package compiler.gcbarriers;
25
26 import compiler.lib.ir_framework.*;
27 import java.lang.invoke.VarHandle;
28 import java.lang.invoke.MethodHandles;
29 import java.util.concurrent.ThreadLocalRandom;
30
31 /**
32 * @test
33 * @summary Test that the ZGC barrier elision optimization does not elide
34 * necessary barriers. The tests use volatile memory accesses and
35 * blackholes to prevent C2 from simply optimizing them away.
36 * @library /test/lib /
37 * @requires vm.gc.Z
38 * @run driver compiler.gcbarriers.TestZGCBarrierElision test-correctness
39 */
40
41 /**
42 * @test
43 * @summary Test that the ZGC barrier elision optimization elides unnecessary
44 * barriers following simple allocation and domination rules.
45 * @library /test/lib /
46 * @requires vm.gc.Z & (vm.simpleArch == "x64" | vm.simpleArch == "aarch64")
47 * @run driver compiler.gcbarriers.TestZGCBarrierElision test-effectiveness
48 */
49
50 class Inner {}
51
52 class Outer {
53 volatile Inner field1;
54 volatile Inner field2;
55 Outer() {}
56 }
57
58 class Common {
59
60 static Inner inner = new Inner();
61 static Outer outer = new Outer();
62 static Outer outer2 = new Outer();
170 }
171 o.field1 = i;
172 }
173
174 @Test
175 @IR(counts = { IRNode.Z_STORE_P_WITH_BARRIER_FLAG, Common.REMAINING, "2" }, phase = CompilePhase.FINAL_CODE)
176 static void testStoreThenCallThenStore(Outer o, Inner i) {
177 o.field1 = i;
178 Common.nonInlinedMethod();
179 o.field1 = i;
180 }
181
182 @Run(test = {"testConditionalStoreThenStore",
183 "testStoreThenCallThenStore"})
184 void runControlFlowTests() {
185 testConditionalStoreThenStore(Common.outer, Common.inner, ThreadLocalRandom.current().nextInt(0, 100));
186 testStoreThenCallThenStore(Common.outer, Common.inner);
187 }
188
189 @Test
190 @IR(counts = { IRNode.Z_GET_AND_SET_P_WITH_BARRIER_FLAG, Common.REMAINING, "1" }, phase = CompilePhase.FINAL_CODE)
191 static void testAllocateThenAtomic(Inner i) {
192 Outer o = new Outer();
193 Common.blackhole(o);
194 Common.field1VarHandle.getAndSet(o, i);
195 }
196
197 @Test
198 @IR(counts = { IRNode.Z_LOAD_P_WITH_BARRIER_FLAG, Common.REMAINING, "1" }, phase = CompilePhase.FINAL_CODE)
199 @IR(counts = { IRNode.Z_GET_AND_SET_P_WITH_BARRIER_FLAG, Common.REMAINING, "1" }, phase = CompilePhase.FINAL_CODE)
200 static void testLoadThenAtomic(Outer o, Inner i) {
201 Common.blackhole(o.field1);
202 Common.field1VarHandle.getAndSet(o, i);
203 }
204
205 @Test
206 @IR(counts = { IRNode.Z_GET_AND_SET_P_WITH_BARRIER_FLAG, Common.REMAINING, "2" }, phase = CompilePhase.FINAL_CODE)
207 static void testAtomicThenAtomicAnotherField(Outer o, Inner i) {
208 Common.field1VarHandle.getAndSet(o, i);
209 Common.field2VarHandle.getAndSet(o, i);
210 }
211
212 @Test
213 @IR(counts = { IRNode.Z_GET_AND_SET_P_WITH_BARRIER_FLAG, Common.REMAINING, "1" }, phase = CompilePhase.FINAL_CODE)
214 static void testAllocateArrayThenAtomicAtKnownIndex(Outer o) {
215 Outer[] a = new Outer[42];
216 Common.blackhole(a);
217 Common.outerArrayVarHandle.getAndSet(a, 2, o);
218 }
219
220 @Test
221 @IR(counts = { IRNode.Z_GET_AND_SET_P_WITH_BARRIER_FLAG, Common.REMAINING, "1" }, phase = CompilePhase.FINAL_CODE)
222 static void testAllocateArrayThenAtomicAtUnknownIndex(Outer o, int index) {
223 Outer[] a = new Outer[42];
224 Common.blackhole(a);
225 Common.outerArrayVarHandle.getAndSet(a, index, o);
226 }
227
228 @Test
229 @IR(counts = { IRNode.Z_GET_AND_SET_P_WITH_BARRIER_FLAG, Common.REMAINING, "2" }, phase = CompilePhase.FINAL_CODE)
230 static void testArrayAtomicThenAtomicAtUnknownIndices(Outer[] a, Outer o, int index1, int index2) {
231 Common.outerArrayVarHandle.getAndSet(a, index1, o);
232 Common.outerArrayVarHandle.getAndSet(a, index2, o);
233 }
234
235 @Run(test = {"testAllocateThenAtomic",
236 "testLoadThenAtomic",
237 "testAtomicThenAtomicAnotherField",
238 "testAllocateArrayThenAtomicAtKnownIndex",
239 "testAllocateArrayThenAtomicAtUnknownIndex",
240 "testArrayAtomicThenAtomicAtUnknownIndices"})
241 void runAtomicOperationTests() {
242 testAllocateThenAtomic(Common.inner);
243 testLoadThenAtomic(Common.outer, Common.inner);
244 testAtomicThenAtomicAnotherField(Common.outer, Common.inner);
245 testAllocateArrayThenAtomicAtKnownIndex(Common.outer);
246 testAllocateArrayThenAtomicAtUnknownIndex(Common.outer, 10);
247 testArrayAtomicThenAtomicAtUnknownIndices(Common.outerArray, Common.outer, 10, 20);
248 }
249 }
370
371 @Test
372 @IR(counts = { IRNode.Z_STORE_P_WITH_BARRIER_FLAG, Common.REMAINING, "1" }, phase = CompilePhase.FINAL_CODE)
373 @IR(counts = { IRNode.Z_STORE_P_WITH_BARRIER_FLAG, Common.ELIDED, "1" }, phase = CompilePhase.FINAL_CODE)
374 static void testStoreThenStoreInLoop(Outer o, Inner i) {
375 o.field1 = i;
376 for (int j = 0; j < 100; j++) {
377 o.field1 = i;
378 }
379 }
380
381 @Run(test = {"testStoreThenConditionalStore",
382 "testStoreThenStoreInLoop"})
383 void runControlFlowTests() {
384 testStoreThenConditionalStore(Common.outer, Common.inner, ThreadLocalRandom.current().nextInt(0, 100));
385 testStoreThenStoreInLoop(Common.outer, Common.inner);
386 }
387
388 @Test
389 @IR(counts = { IRNode.Z_STORE_P_WITH_BARRIER_FLAG, Common.REMAINING, "1" }, phase = CompilePhase.FINAL_CODE)
390 @IR(counts = { IRNode.Z_GET_AND_SET_P_WITH_BARRIER_FLAG, Common.ELIDED, "1" }, phase = CompilePhase.FINAL_CODE)
391 static void testStoreThenAtomic(Outer o, Inner i) {
392 o.field1 = i;
393 Common.field1VarHandle.getAndSet(o, i);
394 }
395
396 @Test
397 @IR(counts = { IRNode.Z_GET_AND_SET_P_WITH_BARRIER_FLAG, Common.REMAINING, "1" }, phase = CompilePhase.FINAL_CODE)
398 @IR(counts = { IRNode.Z_LOAD_P_WITH_BARRIER_FLAG, Common.ELIDED, "1" }, phase = CompilePhase.FINAL_CODE)
399 static void testAtomicThenLoad(Outer o, Inner i) {
400 Common.field1VarHandle.getAndSet(o, i);
401 Common.blackhole(o.field1);
402 }
403
404 @Test
405 @IR(counts = { IRNode.Z_GET_AND_SET_P_WITH_BARRIER_FLAG, Common.REMAINING, "1" }, phase = CompilePhase.FINAL_CODE)
406 @IR(counts = { IRNode.Z_STORE_P_WITH_BARRIER_FLAG, Common.ELIDED, "1" }, phase = CompilePhase.FINAL_CODE)
407 static void testAtomicThenStore(Outer o, Inner i) {
408 Common.field1VarHandle.getAndSet(o, i);
409 o.field1 = i;
410 }
411
412 @Test
413 @IR(counts = { IRNode.Z_GET_AND_SET_P_WITH_BARRIER_FLAG, Common.REMAINING, "1" }, phase = CompilePhase.FINAL_CODE)
414 @IR(counts = { IRNode.Z_GET_AND_SET_P_WITH_BARRIER_FLAG, Common.ELIDED, "1" }, phase = CompilePhase.FINAL_CODE)
415 static void testAtomicThenAtomic(Outer o, Inner i) {
416 Common.field1VarHandle.getAndSet(o, i);
417 Common.field1VarHandle.getAndSet(o, i);
418 }
419
420 @Test
421 @IR(counts = { IRNode.Z_GET_AND_SET_P_WITH_BARRIER_FLAG, Common.REMAINING, "1" }, phase = CompilePhase.FINAL_CODE)
422 @IR(counts = { IRNode.Z_GET_AND_SET_P_WITH_BARRIER_FLAG, Common.ELIDED, "1" }, phase = CompilePhase.FINAL_CODE)
423 static void testArrayAtomicThenAtomic(Outer[] a, Outer o) {
424 Common.outerArrayVarHandle.getAndSet(a, 0, o);
425 Common.outerArrayVarHandle.getAndSet(a, 0, o);
426 }
427
428 @Run(test = {"testStoreThenAtomic",
429 "testAtomicThenLoad",
430 "testAtomicThenStore",
431 "testAtomicThenAtomic",
432 "testArrayAtomicThenAtomic"})
433 void runAtomicOperationTests() {
434 testStoreThenAtomic(Common.outer, Common.inner);
435 testAtomicThenLoad(Common.outer, Common.inner);
436 testAtomicThenStore(Common.outer, Common.inner);
437 testAtomicThenAtomic(Common.outer, Common.inner);
438 testArrayAtomicThenAtomic(Common.outerArray, Common.outer);
439 }
440 }
|
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 package compiler.gcbarriers;
25
26 import compiler.lib.ir_framework.*;
27 import java.lang.invoke.VarHandle;
28 import java.lang.invoke.MethodHandles;
29 import java.util.concurrent.ThreadLocalRandom;
30
31 /**
32 * @test id=Z
33 * @summary Test that the ZGC barrier elision optimization does not elide
34 * necessary barriers. The tests use volatile memory accesses and
35 * blackholes to prevent C2 from simply optimizing them away.
36 * @library /test/lib /
37 * @requires vm.gc.Z
38 * @run driver compiler.gcbarriers.TestZGCBarrierElision test-correctness
39 */
40
41 /**
42 * @test id=ZGen
43 * @summary Test that the ZGC barrier elision optimization elides unnecessary
44 * barriers following simple allocation and domination rules.
45 * @library /test/lib /
46 * @requires vm.gc.Z & (vm.simpleArch == "x64" | vm.simpleArch == "aarch64")
47 * @run driver compiler.gcbarriers.TestZGCBarrierElision test-effectiveness
48 */
49
50 class Inner {}
51
52 class Outer {
53 volatile Inner field1;
54 volatile Inner field2;
55 Outer() {}
56 }
57
58 class Common {
59
60 static Inner inner = new Inner();
61 static Outer outer = new Outer();
62 static Outer outer2 = new Outer();
170 }
171 o.field1 = i;
172 }
173
174 @Test
175 @IR(counts = { IRNode.Z_STORE_P_WITH_BARRIER_FLAG, Common.REMAINING, "2" }, phase = CompilePhase.FINAL_CODE)
176 static void testStoreThenCallThenStore(Outer o, Inner i) {
177 o.field1 = i;
178 Common.nonInlinedMethod();
179 o.field1 = i;
180 }
181
182 @Run(test = {"testConditionalStoreThenStore",
183 "testStoreThenCallThenStore"})
184 void runControlFlowTests() {
185 testConditionalStoreThenStore(Common.outer, Common.inner, ThreadLocalRandom.current().nextInt(0, 100));
186 testStoreThenCallThenStore(Common.outer, Common.inner);
187 }
188
189 @Test
190 @IR(counts = { IRNode.Z_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, Common.REMAINING, "1" }, phase = CompilePhase.FINAL_CODE)
191 static void testAllocateThenAtomic(Inner i) {
192 Outer o = new Outer();
193 Common.blackhole(o);
194 Common.field1VarHandle.getAndSet(o, i);
195 }
196
197 @Test
198 @IR(counts = { IRNode.Z_LOAD_P_WITH_BARRIER_FLAG, Common.REMAINING, "1" }, phase = CompilePhase.FINAL_CODE)
199 @IR(counts = { IRNode.Z_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, Common.REMAINING, "1" }, phase = CompilePhase.FINAL_CODE)
200 static void testLoadThenAtomic(Outer o, Inner i) {
201 Common.blackhole(o.field1);
202 Common.field1VarHandle.getAndSet(o, i);
203 }
204
205 @Test
206 @IR(counts = { IRNode.Z_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, Common.REMAINING, "2" }, phase = CompilePhase.FINAL_CODE)
207 static void testAtomicThenAtomicAnotherField(Outer o, Inner i) {
208 Common.field1VarHandle.getAndSet(o, i);
209 Common.field2VarHandle.getAndSet(o, i);
210 }
211
212 @Test
213 @IR(counts = { IRNode.Z_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, Common.REMAINING, "1" }, phase = CompilePhase.FINAL_CODE)
214 static void testAllocateArrayThenAtomicAtKnownIndex(Outer o) {
215 Outer[] a = new Outer[42];
216 Common.blackhole(a);
217 Common.outerArrayVarHandle.getAndSet(a, 2, o);
218 }
219
220 @Test
221 @IR(counts = { IRNode.Z_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, Common.REMAINING, "1" }, phase = CompilePhase.FINAL_CODE)
222 static void testAllocateArrayThenAtomicAtUnknownIndex(Outer o, int index) {
223 Outer[] a = new Outer[42];
224 Common.blackhole(a);
225 Common.outerArrayVarHandle.getAndSet(a, index, o);
226 }
227
228 @Test
229 @IR(counts = { IRNode.Z_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, Common.REMAINING, "2" }, phase = CompilePhase.FINAL_CODE)
230 static void testArrayAtomicThenAtomicAtUnknownIndices(Outer[] a, Outer o, int index1, int index2) {
231 Common.outerArrayVarHandle.getAndSet(a, index1, o);
232 Common.outerArrayVarHandle.getAndSet(a, index2, o);
233 }
234
235 @Run(test = {"testAllocateThenAtomic",
236 "testLoadThenAtomic",
237 "testAtomicThenAtomicAnotherField",
238 "testAllocateArrayThenAtomicAtKnownIndex",
239 "testAllocateArrayThenAtomicAtUnknownIndex",
240 "testArrayAtomicThenAtomicAtUnknownIndices"})
241 void runAtomicOperationTests() {
242 testAllocateThenAtomic(Common.inner);
243 testLoadThenAtomic(Common.outer, Common.inner);
244 testAtomicThenAtomicAnotherField(Common.outer, Common.inner);
245 testAllocateArrayThenAtomicAtKnownIndex(Common.outer);
246 testAllocateArrayThenAtomicAtUnknownIndex(Common.outer, 10);
247 testArrayAtomicThenAtomicAtUnknownIndices(Common.outerArray, Common.outer, 10, 20);
248 }
249 }
370
371 @Test
372 @IR(counts = { IRNode.Z_STORE_P_WITH_BARRIER_FLAG, Common.REMAINING, "1" }, phase = CompilePhase.FINAL_CODE)
373 @IR(counts = { IRNode.Z_STORE_P_WITH_BARRIER_FLAG, Common.ELIDED, "1" }, phase = CompilePhase.FINAL_CODE)
374 static void testStoreThenStoreInLoop(Outer o, Inner i) {
375 o.field1 = i;
376 for (int j = 0; j < 100; j++) {
377 o.field1 = i;
378 }
379 }
380
381 @Run(test = {"testStoreThenConditionalStore",
382 "testStoreThenStoreInLoop"})
383 void runControlFlowTests() {
384 testStoreThenConditionalStore(Common.outer, Common.inner, ThreadLocalRandom.current().nextInt(0, 100));
385 testStoreThenStoreInLoop(Common.outer, Common.inner);
386 }
387
388 @Test
389 @IR(counts = { IRNode.Z_STORE_P_WITH_BARRIER_FLAG, Common.REMAINING, "1" }, phase = CompilePhase.FINAL_CODE)
390 @IR(counts = { IRNode.Z_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, Common.ELIDED, "1" }, phase = CompilePhase.FINAL_CODE)
391 static void testStoreThenAtomic(Outer o, Inner i) {
392 o.field1 = i;
393 Common.field1VarHandle.getAndSet(o, i);
394 }
395
396 @Test
397 @IR(counts = { IRNode.Z_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, Common.REMAINING, "1" }, phase = CompilePhase.FINAL_CODE)
398 @IR(counts = { IRNode.Z_LOAD_P_WITH_BARRIER_FLAG, Common.ELIDED, "1" }, phase = CompilePhase.FINAL_CODE)
399 static void testAtomicThenLoad(Outer o, Inner i) {
400 Common.field1VarHandle.getAndSet(o, i);
401 Common.blackhole(o.field1);
402 }
403
404 @Test
405 @IR(counts = { IRNode.Z_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, Common.REMAINING, "1" }, phase = CompilePhase.FINAL_CODE)
406 @IR(counts = { IRNode.Z_STORE_P_WITH_BARRIER_FLAG, Common.ELIDED, "1" }, phase = CompilePhase.FINAL_CODE)
407 static void testAtomicThenStore(Outer o, Inner i) {
408 Common.field1VarHandle.getAndSet(o, i);
409 o.field1 = i;
410 }
411
412 @Test
413 @IR(counts = { IRNode.Z_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, Common.REMAINING, "1" }, phase = CompilePhase.FINAL_CODE)
414 //@IR(counts = { IRNode.Z_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, Common.ELIDED, "1" }, phase = CompilePhase.FINAL_CODE)
415 static void testAtomicThenAtomic(Outer o, Inner i) {
416 Common.field1VarHandle.getAndSet(o, i);
417 Common.field1VarHandle.getAndSet(o, i);
418 }
419
420 @Test
421 @IR(counts = { IRNode.Z_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, Common.REMAINING, "1" }, phase = CompilePhase.FINAL_CODE)
422 @IR(counts = { IRNode.Z_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, Common.ELIDED, "1" }, phase = CompilePhase.FINAL_CODE)
423 static void testArrayAtomicThenAtomic(Outer[] a, Outer o) {
424 Common.outerArrayVarHandle.getAndSet(a, 0, o);
425 Common.outerArrayVarHandle.getAndSet(a, 0, o);
426 }
427
428 @Run(test = {"testStoreThenAtomic",
429 "testAtomicThenLoad",
430 "testAtomicThenStore",
431 "testAtomicThenAtomic",
432 "testArrayAtomicThenAtomic"})
433 void runAtomicOperationTests() {
434 testStoreThenAtomic(Common.outer, Common.inner);
435 testAtomicThenLoad(Common.outer, Common.inner);
436 testAtomicThenStore(Common.outer, Common.inner);
437 testAtomicThenAtomic(Common.outer, Common.inner);
438 testArrayAtomicThenAtomic(Common.outerArray, Common.outer);
439 }
440 }
|