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 }