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