1 /*
2 * Copyright (c) 2021, 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 8260034 8260225 8260283 8261037 8261874 8262128 8262831 8306986 8355299 8378780
27 * @summary A selection of generated tests that triggered bugs not covered by other tests.
28 * @enablePreview
29 * @library /testlibrary /test/lib /
30 * @modules java.base/jdk.internal.value
31 * java.base/jdk.internal.vm.annotation
32 * @build jdk.test.whitebox.WhiteBox
33 * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
34 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
35 * -Xbatch
36 * compiler.valhalla.inlinetypes.TestGenerated
37 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
38 * -Xbatch -XX:ForceNonTearable=*
39 * compiler.valhalla.inlinetypes.TestGenerated
40 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
41 * -Xbatch -XX:-UseArrayFlattening
42 * compiler.valhalla.inlinetypes.TestGenerated
43 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI
44 * -Xbatch -XX:+UseNullableAtomicValueFlattening -XX:+UseNullFreeAtomicValueFlattening -XX:+UseNullFreeNonAtomicValueFlattening
45 * compiler.valhalla.inlinetypes.TestGenerated
46 */
47
48 package compiler.valhalla.inlinetypes;
49
50 import jdk.internal.value.ValueClass;
51 import jdk.internal.vm.annotation.LooselyConsistentValue;
52 import jdk.internal.vm.annotation.NullRestricted;
53
54 import jdk.test.whitebox.WhiteBox;
55
56 @LooselyConsistentValue
57 value class EmptyPrimitive {
58
59 }
60
61 value class EmptyValue {
62
63 }
64
65 @LooselyConsistentValue
66 value class MyValue1Generated {
67 int x = 42;
68 int[] array = new int[1];
69 }
70
71 @LooselyConsistentValue
72 value class MyValue2Generated {
73 int[] a = new int[1];
74 int[] b = new int[6];
75 int[] c = new int[5];
76 }
77
78 @LooselyConsistentValue
79 value class MyValue3Generated {
80 int[] intArray = new int[1];
81 float[] floatArray = new float[1];
82 }
83
84 @LooselyConsistentValue
85 value class MyValue4Generated {
86 short b = 2;
87 int c = 8;
88 }
89
90 class MyValue4Wrapper {
91 public MyValue4Generated val;
92
93 public MyValue4Wrapper(MyValue4Generated val) {
94 this.val = val;
95 }
96 }
97
98 @LooselyConsistentValue
99 value class MyValue5Generated {
100 int b = 2;
101 }
102
103 value class MyValue6Generated {
104 int x = 42;
105 }
106
107 public class TestGenerated {
108 private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
109 private static final boolean SLOW_CONFIGURATION = (WHITE_BOX.getIntxVMFlag("TieredStopAtLevel").intValue() < 4);
110
111 EmptyPrimitive f1 = new EmptyPrimitive();
112 EmptyPrimitive f2 = new EmptyPrimitive();
113
114 public TestGenerated() {
115 f4 = new MyValue1Generated();
116 e = new MyValue4Generated();
117 test13_t = new MyValue5Generated();
118 super();
119 }
120
121 void test1(EmptyPrimitive[] array) {
122 for (int i = 0; i < 10; ++i) {
123 f1 = array[0];
124 f2 = array[0];
125 }
126 }
127
128 MyValue1Generated test2(MyValue1Generated[] array) {
129 MyValue1Generated res = new MyValue1Generated();
130 for (int i = 0; i < array.length; ++i) {
131 res = array[i];
132 }
133 for (int i = 0; i < 1000; ++i) {
134
135 }
136 return res;
137 }
138
139 void test3(MyValue1Generated[] array) {
140 for (int i = 0; i < array.length; ++i) {
141 array[i] = new MyValue1Generated();
142 }
143 for (int i = 0; i < 1000; ++i) {
144
145 }
146 }
147
148 void test4(MyValue1Generated[] array) {
149 array[0].array[0] = 0;
150 }
151
152 int test5(MyValue1Generated[] array) {
153 return array[0].array[0];
154 }
155
156 long f3;
157 @NullRestricted
158 MyValue1Generated f4;
159
160 void test6() {
161 f3 = 123L;
162 int res = f4.x;
163 if (res != 42) {
164 throw new RuntimeException("test6 failed");
165 }
166 }
167
168 MyValue2Generated f5;
169
170 void test7(boolean b) {
171 MyValue2Generated[] array1 = (MyValue2Generated[])ValueClass.newNullRestrictedNonAtomicArray(MyValue2Generated.class, 6, new MyValue2Generated());
172 array1[0] = new MyValue2Generated();
173 array1[1] = new MyValue2Generated();
174 array1[2] = new MyValue2Generated();
175 array1[3] = new MyValue2Generated();
176 array1[4] = new MyValue2Generated();
177 array1[5] = new MyValue2Generated();
178
179 MyValue2Generated h = new MyValue2Generated();
180 MyValue2Generated n = new MyValue2Generated();
181 int[] array2 = new int[1];
182
183 for (int i = 0; i < 10; ++i) {
184 for (int j = 0; j < 10; ++j) {
185 array1[0] = array1[0];
186 if (i == 1) {
187 h = h;
188 array2[0] *= 42;
189 }
190 }
191 }
192 if (b) {
193 f5 = n;
194 }
195 }
196
197 boolean test8(MyValue1Generated[] array) {
198 return array[0].array == array[0].array;
199 }
200
201 void test9(boolean b) {
202 MyValue1Generated[] array = (MyValue1Generated[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1Generated.class, 1, new MyValue1Generated());
203 if (b) {
204 for (int i = 0; i < 10; ++i) {
205 if (array != array) {
206 array = null;
207 }
208 }
209 }
210 }
211
212 int[] f6 = new int[1];
213
214 void test10(MyValue3Generated[] array) {
215 float[] floatArray = array[0].floatArray;
216 if (f6 == f6) {
217 f6 = array[0].intArray;
218 }
219 }
220
221 void test11(MyValue3Generated[] array) {
222 float[] floatArray = array[0].floatArray;
223 if (array[0].intArray[0] != 42) {
224 throw new RuntimeException("test11 failed");
225 }
226 }
227
228 MyValue4Generated[] d = (MyValue4Generated[])ValueClass.newNullRestrictedNonAtomicArray(MyValue4Generated.class, 1, new MyValue4Generated());
229 @NullRestricted
230 MyValue4Generated e;
231 byte f;
232
233 byte test12() {
234 MyValue4Generated i = new MyValue4Generated();
235 for (int j = 0; j < 6; ++j) {
236 MyValue4Generated[] k = (MyValue4Generated[])ValueClass.newNullRestrictedNonAtomicArray(MyValue4Generated.class, 0, new MyValue4Generated());
237 if (i.b < 101) {
238 i = e;
239 }
240 for (int l = 0; l < 9; ++l) {
241 MyValue4Generated m = new MyValue4Generated();
242 i = m;
243 }
244 }
245 if (d[0].c > 1) {
246 for (int n = 0; n < 7; ++n) {
247 }
248 }
249 return f;
250 }
251
252 int test13_iField;
253 MyValue5Generated test13_c;
254 @NullRestricted
255 MyValue5Generated test13_t;
256
257 void test13(MyValue5Generated[] array) {
258 for (int i = 0; i < 10; ++i) {
259 for (int j = 0; j < 10; ++j) {
260 test13_iField = 6;
261 }
262 for (int j = 0; j < 2; ++j) {
263 test13_iField += array[0].b;
264 }
265 MyValue5Generated[] array2 = (MyValue5Generated[])ValueClass.newNullRestrictedNonAtomicArray(MyValue5Generated.class, 1, new MyValue5Generated());
266 test13_c = array[0];
267 array2[0] = test13_t;
268 }
269 }
270
271 void test14(boolean b, MyValue4Generated val) {
272 for (int i = 0; i < 10; ++i) {
273 if (b) {
274 val = new MyValue4Generated();
275 }
276 MyValue4Generated[] array = (MyValue4Generated[])ValueClass.newNullRestrictedNonAtomicArray(MyValue4Generated.class, 1, new MyValue4Generated());
277 array[0] = val;
278
279 for (int j = 0; j < 5; ++j) {
280 for (int k = 0; k < 5; ++k) {
281 }
282 }
283 }
284 }
285
286 void test15() {
287 MyValue4Generated val = new MyValue4Generated();
288 for (int i = 0; i < 10; ++i) {
289 for (int j = 0; j < 10; ++j) {
290 MyValue4Generated[] array = (MyValue4Generated[])ValueClass.newNullRestrictedNonAtomicArray(MyValue4Generated.class, 1, new MyValue4Generated());
291 for (int k = 0; k < 10; ++k) {
292 array[0] = val;
293 val = array[0];
294 }
295 }
296 }
297 }
298
299 void test16() {
300 MyValue4Generated val = new MyValue4Generated();
301 for (int i = 0; i < 10; ++i) {
302 for (int j = 0; j < 10; ++j) {
303 val = (new MyValue4Wrapper(val)).val;
304 for (int k = 0; k < 10; ++k) {
305 }
306 }
307 }
308 }
309
310 static MyValue6Generated test17Field = new MyValue6Generated();
311
312 void test17() {
313 for (int i = 0; i < 10; ++i) {
314 MyValue6Generated val = new MyValue6Generated();
315 for (int j = 0; j < 10; ++j) {
316 test17Field = val;
317 }
318 }
319 }
320
321 EmptyValue test18Field;
322
323 EmptyValue test18() {
324 EmptyValue val = new EmptyValue();
325 test18Field = val;
326 return test18Field;
327 }
328
329 MyValue1Generated test19Field = new MyValue1Generated();
330
331 public void test19() {
332 for (int i = 0; i < 10; ++i) {
333 MyValue1Generated val = new MyValue1Generated();
334 for (int j = 0; j < 10; ++j) {
335 test19Field = val;
336 }
337 }
338 }
339
340 public static void main(String[] args) {
341 TestGenerated t = new TestGenerated();
342 EmptyPrimitive[] array1 = (EmptyPrimitive[])ValueClass.newNullRestrictedNonAtomicArray(EmptyPrimitive.class, 1, new EmptyPrimitive());
343 MyValue1Generated[] array2 = (MyValue1Generated[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1Generated.class, 10, new MyValue1Generated());
344 MyValue1Generated[] array3 = (MyValue1Generated[])ValueClass.newNullRestrictedNonAtomicArray(MyValue1Generated.class, 1, new MyValue1Generated());
345 array3[0] = new MyValue1Generated();
346 MyValue3Generated[] array4 = (MyValue3Generated[])ValueClass.newNullRestrictedNonAtomicArray(MyValue3Generated.class, 1, new MyValue3Generated());
347 array4[0] = new MyValue3Generated();
348 MyValue5Generated[] array5 = (MyValue5Generated[])ValueClass.newNullRestrictedNonAtomicArray(MyValue5Generated.class, 1, new MyValue5Generated());
349 array5[0] = new MyValue5Generated();
350 array4[0].intArray[0] = 42;
351
352 int iterations = SLOW_CONFIGURATION ? 1_000 : 50_000;
353 for (int i = 0; i < iterations; ++i) {
354 t.test1(array1);
355 t.test2(array2);
356 t.test3(array2);
357 t.test4(array3);
358 t.test5(array3);
359 t.test6();
360 t.test7(false);
361 t.test8(array3);
362 t.test9(true);
363 t.test10(array4);
364 t.test11(array4);
365 t.test12();
366 t.test13(array5);
367 t.test14(false, new MyValue4Generated());
368 t.test15();
369 t.test16();
370 t.test17();
371 t.test18();
372 t.test19();
373 }
374 }
375 }