1 /*
2 * Copyright (c) 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 */
23
24 /*
25 * @test
26 * @bug 8372700
27 * @summary Check stable flat array field folding
28 * @library /test/lib /
29 * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64")
30 * @enablePreview
31 * @modules java.base/jdk.internal.value
32 * java.base/jdk.internal.vm.annotation
33 * @run driver ${test.main.class}
34 */
35
36 package compiler.c2.irTests.stable;
37
38 import compiler.lib.ir_framework.*;
39 import compiler.valhalla.inlinetypes.*;
40 import jdk.internal.value.ValueClass;
41 import jdk.internal.vm.annotation.Stable;
42 import jdk.test.lib.Asserts;
43
44 public class StableFlatArrayTest {
45 public static void main(String[] args) {
46 TestFramework tf = new TestFramework();
47 tf.addTestClassesToBootClassPath();
48 tf.addFlags(
49 "--enable-preview",
50 "--add-exports", "java.base/jdk.internal.value=ALL-UNNAMED"
51 )
52 .start();
53 }
54
55 static final Integer[] NULL_RESTRICTED_NON_ATOMIC_ARRAY = (Integer[]) ValueClass.newNullRestrictedNonAtomicArray(Integer.class, 1, 42);
56 static final Integer[] NULL_RESTRICTED_ATOMIC_ARRAY = (Integer[]) ValueClass.newNullRestrictedAtomicArray(Integer.class, 1, 43);
57 static final Integer[] NULLABLE_ATOMIC_ARRAY = (Integer[]) ValueClass.newNullableAtomicArray(Integer.class, 1);
58 static {
59 NULLABLE_ATOMIC_ARRAY[0] = 44;
60 }
61
62 static final int NULL_RESTRICTED_NON_ATOMIC_CASE = 1;
63 static final int NULL_RESTRICTED_ATOMIC_CASE = 2;
64 static final int NULLABLE_ATOMIC_CASE = 3;
65
66 static class Carrier {
67 @Stable
68 Integer[] field;
69
70 @ForceInline
71 public Carrier(int initLevel) {
72 switch (initLevel) {
73 case NULL_RESTRICTED_NON_ATOMIC_CASE:
74 field = NULL_RESTRICTED_NON_ATOMIC_ARRAY;
75 break;
76 case NULL_RESTRICTED_ATOMIC_CASE:
77 field = NULL_RESTRICTED_ATOMIC_ARRAY;
78 break;
79 case NULLABLE_ATOMIC_CASE:
80 field = NULLABLE_ATOMIC_ARRAY;
81 break;
82 default:
83 throw new IllegalStateException("Unknown level");
84 }
85 }
86 }
87
88 static final Carrier NULL_RESTRICTED_NON_ATOMIC_CARRIER = new Carrier(NULL_RESTRICTED_NON_ATOMIC_CASE);
89 static final Carrier NULL_RESTRICTED_ATOMIC_CARRIER = new Carrier(NULL_RESTRICTED_ATOMIC_CASE);
90 static final Carrier NULLABLE_ATOMIC_CARRIER = new Carrier(NULLABLE_ATOMIC_CASE);
91
92 @Test
93 @IR(failOn = {IRNode.LOAD, IRNode.MEMBAR})
94 static int testNullRestrictedNonAtomic() {
95 Integer[] is = NULL_RESTRICTED_NON_ATOMIC_CARRIER.field;
96 if (is != null) {
97 Integer i = is[0];
98 if (i != null) {
99 return i;
100 }
101 }
102 return 0;
103 }
104
105 @Run(test = "testNullRestrictedNonAtomic")
106 public void testNullRestrictedNonAtomic_verifier() {
107 int result = testNullRestrictedNonAtomic();
108 Asserts.assertEquals(result, 42);
109 }
110
111 @Test
112 @IR(failOn = {IRNode.LOAD, IRNode.MEMBAR})
113 static int testNullRestrictedAtomic() {
114 Integer[] is = NULL_RESTRICTED_ATOMIC_CARRIER.field;
115 if (is != null) {
116 Integer i = is[0];
117 if (i != null) {
118 return i;
119 }
120 }
121 return 0;
122 }
123
124 @Run(test = "testNullRestrictedAtomic")
125 public void testNullRestrictedAtomic_verifier() {
126 int result = testNullRestrictedAtomic();
127 Asserts.assertEquals(result, 43);
128 }
129
130 @Test
131 @IR(failOn = {IRNode.LOAD, IRNode.MEMBAR})
132 static int testNullableAtomic() {
133 Integer[] is = NULLABLE_ATOMIC_CARRIER.field;
134 if (is != null) {
135 Integer i = is[0];
136 if (i != null) {
137 return i;
138 }
139 }
140 return 0;
141 }
142
143 @Run(test = "testNullableAtomic")
144 public void testNullableAtomic_verifier() {
145 int result = testNullableAtomic();
146 Asserts.assertEquals(result, 44);
147 }
148 }