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