1 /* 2 * Copyright (c) 2017, 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 package compiler.valhalla.inlinetypes; 25 26 import compiler.lib.ir_framework.*; 27 import jdk.test.lib.Asserts; 28 29 import jdk.internal.value.ValueClass; 30 import jdk.internal.vm.annotation.ImplicitlyConstructible; 31 import jdk.internal.vm.annotation.LooselyConsistentValue; 32 import jdk.internal.vm.annotation.NullRestricted; 33 34 import java.lang.invoke.MethodHandle; 35 import java.lang.invoke.MethodHandles; 36 import java.lang.invoke.MethodType; 37 import java.lang.reflect.Method; 38 import java.util.Arrays; 39 40 import static compiler.valhalla.inlinetypes.InlineTypeIRNode.*; 41 import static compiler.valhalla.inlinetypes.InlineTypes.*; 42 43 /* 44 * @test 45 * @key randomness 46 * @summary Test value class arrays. 47 * @library /test/lib / 48 * @enablePreview 49 * @modules java.base/jdk.internal.value 50 * java.base/jdk.internal.vm.annotation 51 * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") 52 * @enablePreview 53 * @run main/othervm/timeout=300 compiler.valhalla.inlinetypes.TestArrays 54 */ 55 56 @ForceCompileClassInitializer 57 public class TestArrays { 58 59 public static void main(String[] args) { 60 Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS; 61 scenarios[2].addFlags("--enable-preview", "-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast", "-XX:+StressArrayCopyMacroNode"); 62 scenarios[3].addFlags("--enable-preview", "-XX:-MonomorphicArrayCheck", "-XX:+UseArrayFlattening", "-XX:-UncommonNullCast"); 63 scenarios[4].addFlags("--enable-preview", "-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast"); 64 scenarios[5].addFlags("--enable-preview", "-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast", "-XX:+StressArrayCopyMacroNode"); 65 66 InlineTypes.getFramework() 67 .addScenarios(scenarios) 68 .addHelperClasses(MyValue1.class, MyValue2.class, MyValue2Inline.class) 69 .start(); 70 } 71 72 static { 73 // Make sure RuntimeException is loaded to prevent uncommon traps in IR verified tests 74 RuntimeException tmp = new RuntimeException("42"); 75 } 76 77 // Helper methods and classes 78 79 protected long hash() { 80 return hash(rI, rL); 81 } 82 83 protected long hash(int x, long y) { 84 return MyValue1.createWithFieldsInline(x, y).hash(); 85 } 86 87 static void verify(Object[] src, Object[] dst) { 88 if (src instanceof MyInterface[] && dst instanceof MyInterface[]) { 89 for (int i = 0; i < src.length; ++i) { 90 Asserts.assertEQ(((MyInterface)src[i]).hash(), ((MyInterface)dst[i]).hash()); 91 } 92 } else { 93 for (int i = 0; i < src.length; ++i) { 94 Asserts.assertEQ(src[i], dst[i]); 95 } 96 } 97 } 98 99 static void verify(MyValue1[] src, MyValue1[] dst) { 100 for (int i = 0; i < src.length; ++i) { 101 Asserts.assertEQ(src[i].hash(), dst[i].hash()); 102 } 103 } 104 105 static void verify(MyValue1[] src, Object[] dst) { 106 for (int i = 0; i < src.length; ++i) { 107 Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash()); 108 } 109 } 110 111 static void verify(MyValue2[] src, MyValue2[] dst) { 112 for (int i = 0; i < src.length; ++i) { 113 Asserts.assertEQ(src[i].hash(), dst[i].hash()); 114 } 115 } 116 117 static void verify(MyValue2[] src, Object[] dst) { 118 for (int i = 0; i < src.length; ++i) { 119 Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash()); 120 } 121 } 122 123 static boolean compile_and_run_again_if_deoptimized(RunInfo info) { 124 if (!info.isWarmUp()) { 125 Method m = info.getTest(); 126 if (TestFramework.isCompiled(m)) { 127 TestFramework.compile(m, CompLevel.C2); 128 } 129 } 130 return false; 131 } 132 133 @ImplicitlyConstructible 134 @LooselyConsistentValue 135 static value class NotFlattenable { 136 private final Object o1 = null; 137 private final Object o2 = null; 138 private final Object o3 = null; 139 private final Object o4 = null; 140 private final Object o5 = null; 141 private final Object o6 = null; 142 } 143 144 // Test value class array creation and initialization 145 @Test 146 @IR(applyIf = {"UseArrayFlattening", "true"}, 147 counts = {ALLOCA, "= 1"}) 148 @IR(applyIf = {"UseArrayFlattening", "false"}, 149 counts = {ALLOCA, "= 1"}, 150 failOn = LOAD) 151 public MyValue1[] test1(int len) { 152 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len); 153 for (int i = 0; i < len; ++i) { 154 va[i] = MyValue1.createWithFieldsDontInline(rI, rL); 155 } 156 return va; 157 } 158 159 @Run(test = "test1") 160 public void test1_verifier() { 161 int len = Math.abs(rI % 10); 162 MyValue1[] va = test1(len); 163 for (int i = 0; i < len; ++i) { 164 Asserts.assertEQ(va[i].hash(), hash()); 165 } 166 } 167 168 // Test creation of a value class array and element access 169 @Test 170 @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE, TRAP}) 171 public long test2() { 172 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 173 va[0] = MyValue1.createWithFieldsInline(rI, rL); 174 return va[0].hash(); 175 } 176 177 @Run(test = "test2") 178 public void test2_verifier() { 179 long result = test2(); 180 Asserts.assertEQ(result, hash()); 181 } 182 183 // Test receiving a value class array from the interpreter, 184 // updating its elements in a loop and computing a hash. 185 @Test 186 @IR(failOn = ALLOCA) 187 public long test3(MyValue1[] va) { 188 long result = 0; 189 for (int i = 0; i < 10; ++i) { 190 result += va[i].hash(); 191 va[i] = MyValue1.createWithFieldsInline(rI + 1, rL + 1); 192 } 193 return result; 194 } 195 196 @Run(test = "test3") 197 public void test3_verifier() { 198 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 10); 199 long expected = 0; 200 for (int i = 0; i < 10; ++i) { 201 va[i] = MyValue1.createWithFieldsDontInline(rI + i, rL + i); 202 expected += va[i].hash(); 203 } 204 long result = test3(va); 205 Asserts.assertEQ(expected, result); 206 for (int i = 0; i < 10; ++i) { 207 if (va[i].hash() != hash(rI + 1, rL + 1)) { 208 Asserts.assertEQ(va[i].hash(), hash(rI + 1, rL + 1)); 209 } 210 } 211 } 212 213 // Test returning a value class array received from the interpreter 214 @Test 215 @IR(failOn = {ALLOC, ALLOCA, LOAD, STORE, LOOP, TRAP}) 216 public MyValue1[] test4(MyValue1[] va) { 217 return va; 218 } 219 220 @Run(test = "test4") 221 public void test4_verifier() { 222 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 10); 223 for (int i = 0; i < 10; ++i) { 224 va[i] = MyValue1.createWithFieldsDontInline(rI + i, rL + i); 225 } 226 va = test4(va); 227 for (int i = 0; i < 10; ++i) { 228 Asserts.assertEQ(va[i].hash(), hash(rI + i, rL + i)); 229 } 230 } 231 232 // Merge value class arrays created from two branches 233 @Test 234 public MyValue1[] test5(boolean b) { 235 MyValue1[] va; 236 if (b) { 237 va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 5); 238 for (int i = 0; i < 5; ++i) { 239 va[i] = MyValue1.createWithFieldsInline(rI, rL); 240 } 241 } else { 242 va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 10); 243 for (int i = 0; i < 10; ++i) { 244 va[i] = MyValue1.createWithFieldsInline(rI + i, rL + i); 245 } 246 } 247 long sum = va[0].hashInterpreted(); 248 if (b) { 249 va[0] = MyValue1.createWithFieldsDontInline(rI, sum); 250 } else { 251 va[0] = MyValue1.createWithFieldsDontInline(rI + 1, sum + 1); 252 } 253 return va; 254 } 255 256 @Run(test = "test5") 257 public void test5_verifier() { 258 MyValue1[] va = test5(true); 259 Asserts.assertEQ(va.length, 5); 260 Asserts.assertEQ(va[0].hash(), hash(rI, hash())); 261 for (int i = 1; i < 5; ++i) { 262 Asserts.assertEQ(va[i].hash(), hash()); 263 } 264 va = test5(false); 265 Asserts.assertEQ(va.length, 10); 266 Asserts.assertEQ(va[0].hash(), hash(rI + 1, hash(rI, rL) + 1)); 267 for (int i = 1; i < 10; ++i) { 268 Asserts.assertEQ(va[i].hash(), hash(rI + i, rL + i)); 269 } 270 } 271 272 // Test creation of value class array with single element 273 @Test 274 @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE, TRAP}) 275 public MyValue1 test6() { 276 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 277 return va[0]; 278 } 279 280 @Run(test = "test6") 281 public void test6_verifier() { 282 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 283 MyValue1 v = test6(); 284 Asserts.assertEQ(v.hashPrimitive(), va[0].hashPrimitive()); 285 } 286 287 // Test default initialization of value class arrays 288 @Test 289 @IR(failOn = LOAD) 290 public MyValue1[] test7(int len) { 291 return (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len); 292 } 293 294 @Run(test = "test7") 295 public void test7_verifier() { 296 int len = Math.abs(rI % 10); 297 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len); 298 MyValue1[] var = test7(len); 299 for (int i = 0; i < len; ++i) { 300 Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive()); 301 } 302 } 303 304 // Test creation of value class array with zero length 305 @Test 306 @IR(failOn = {ALLOC, LOAD, STORE, LOOP, TRAP}) 307 public MyValue1[] test8() { 308 return (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 0); 309 } 310 311 @Run(test = "test8") 312 public void test8_verifier() { 313 MyValue1[] va = test8(); 314 Asserts.assertEQ(va.length, 0); 315 } 316 317 static MyValue1[] test9_va; 318 319 // Test that value class array loaded from field has correct type 320 @Test 321 @IR(failOn = LOOP) 322 public long test9() { 323 return test9_va[0].hash(); 324 } 325 326 @Run(test = "test9") 327 public void test9_verifier() { 328 test9_va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 329 test9_va[0] = MyValue1.createWithFieldsInline(rI, rL); 330 long result = test9(); 331 Asserts.assertEQ(result, hash()); 332 } 333 334 // Multi-dimensional arrays 335 @Test 336 public MyValue1[][][] test10(int len1, int len2, int len3) { 337 MyValue1[][][] arr = new MyValue1[len1][len2][len3]; 338 for (int i = 0; i < len1; i++) { 339 for (int j = 0; j < len2; j++) { 340 for (int k = 0; k < len3; k++) { 341 arr[i][j][k] = MyValue1.createWithFieldsDontInline(rI + i , rL + j + k); 342 } 343 } 344 } 345 return arr; 346 } 347 348 @Run(test = "test10") 349 public void test10_verifier() { 350 MyValue1[][][] arr = test10(2, 3, 4); 351 for (int i = 0; i < 2; i++) { 352 for (int j = 0; j < 3; j++) { 353 for (int k = 0; k < 4; k++) { 354 Asserts.assertEQ(arr[i][j][k].hash(), MyValue1.createWithFieldsDontInline(rI + i , rL + j + k).hash()); 355 } 356 } 357 } 358 } 359 360 @Test 361 public void test11(MyValue1[][][] arr, long[] res) { 362 int l = 0; 363 for (int i = 0; i < arr.length; i++) { 364 for (int j = 0; j < arr[i].length; j++) { 365 for (int k = 0; k < arr[i][j].length; k++) { 366 res[l] = arr[i][j][k].hash(); 367 l++; 368 } 369 } 370 } 371 } 372 373 @Run(test = "test11") 374 public void test11_verifier() { 375 MyValue1[][][] arr = new MyValue1[2][3][4]; 376 long[] res = new long[2*3*4]; 377 long[] verif = new long[2*3*4]; 378 int l = 0; 379 for (int i = 0; i < 2; i++) { 380 for (int j = 0; j < 3; j++) { 381 for (int k = 0; k < 4; k++) { 382 arr[i][j][k] = MyValue1.createWithFieldsDontInline(rI + i, rL + j + k); 383 verif[l] = arr[i][j][k].hash(); 384 l++; 385 } 386 } 387 } 388 test11(arr, res); 389 for (int i = 0; i < verif.length; i++) { 390 Asserts.assertEQ(res[i], verif[i]); 391 } 392 } 393 394 // Array load out of bounds (upper bound) at compile time 395 @Test 396 public int test12() { 397 int arraySize = Math.abs(rI) % 10; 398 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, arraySize); 399 400 for (int i = 0; i < arraySize; i++) { 401 va[i] = MyValue1.createWithFieldsDontInline(rI + 1, rL); 402 } 403 404 try { 405 return va[arraySize + 1].x; 406 } catch (ArrayIndexOutOfBoundsException e) { 407 return rI; 408 } 409 } 410 411 @Run(test = "test12") 412 public void test12_verifier() { 413 Asserts.assertEQ(test12(), rI); 414 } 415 416 // Array load out of bounds (lower bound) at compile time 417 @Test 418 public int test13() { 419 int arraySize = Math.abs(rI) % 10; 420 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, arraySize); 421 422 for (int i = 0; i < arraySize; i++) { 423 va[i] = MyValue1.createWithFieldsDontInline(rI + i, rL); 424 } 425 426 try { 427 return va[-arraySize].x; 428 } catch (ArrayIndexOutOfBoundsException e) { 429 return rI; 430 } 431 } 432 433 @Run(test = "test13") 434 public void test13_verifier() { 435 Asserts.assertEQ(test13(), rI); 436 } 437 438 // Array load out of bound not known to compiler (both lower and upper bound) 439 @Test 440 public int test14(MyValue1[] va, int index) { 441 return va[index].x; 442 } 443 444 @Run(test = "test14") 445 public void test14_verifier() { 446 int arraySize = Math.abs(rI) % 10; 447 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, arraySize); 448 449 for (int i = 0; i < arraySize; i++) { 450 va[i] = MyValue1.createWithFieldsDontInline(rI, rL); 451 } 452 453 int result; 454 for (int i = -20; i < 20; i++) { 455 try { 456 result = test14(va, i); 457 } catch (ArrayIndexOutOfBoundsException e) { 458 result = rI; 459 } 460 Asserts.assertEQ(result, rI); 461 } 462 } 463 464 // Array store out of bounds (upper bound) at compile time 465 @Test 466 public int test15() { 467 int arraySize = Math.abs(rI) % 10; 468 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, arraySize); 469 470 try { 471 for (int i = 0; i <= arraySize; i++) { 472 va[i] = MyValue1.createWithFieldsDontInline(rI + 1, rL); 473 } 474 return rI - 1; 475 } catch (ArrayIndexOutOfBoundsException e) { 476 return rI; 477 } 478 } 479 480 @Run(test = "test15") 481 public void test15_verifier() { 482 Asserts.assertEQ(test15(), rI); 483 } 484 485 // Array store out of bounds (lower bound) at compile time 486 @Test 487 public int test16() { 488 int arraySize = Math.abs(rI) % 10; 489 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, arraySize); 490 491 try { 492 for (int i = -1; i <= arraySize; i++) { 493 va[i] = MyValue1.createWithFieldsDontInline(rI + 1, rL); 494 } 495 return rI - 1; 496 } catch (ArrayIndexOutOfBoundsException e) { 497 return rI; 498 } 499 } 500 501 @Run(test = "test16") 502 public void test16_verifier() { 503 Asserts.assertEQ(test16(), rI); 504 } 505 506 // Array store out of bound not known to compiler (both lower and upper bound) 507 @Test 508 public int test17(MyValue1[] va, int index, MyValue1 vt) { 509 va[index] = vt; 510 return va[index].x; 511 } 512 513 @Run(test = "test17") 514 public void test17_verifier() { 515 int arraySize = Math.abs(rI) % 10; 516 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, arraySize); 517 518 for (int i = 0; i < arraySize; i++) { 519 va[i] = MyValue1.createWithFieldsDontInline(rI, rL); 520 } 521 522 MyValue1 vt = MyValue1.createWithFieldsDontInline(rI + 1, rL); 523 int result; 524 for (int i = -20; i < 20; i++) { 525 try { 526 result = test17(va, i, vt); 527 } catch (ArrayIndexOutOfBoundsException e) { 528 result = rI + 1; 529 } 530 Asserts.assertEQ(result, rI + 1); 531 } 532 533 for (int i = 0; i < arraySize; i++) { 534 Asserts.assertEQ(va[i].x, rI + 1); 535 } 536 } 537 538 // clone() as stub call 539 @Test 540 public MyValue1[] test18(MyValue1[] va) { 541 return va.clone(); 542 } 543 544 @Run(test = "test18") 545 public void test18_verifier() { 546 int len = Math.abs(rI) % 10; 547 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len); 548 for (int i = 0; i < len; ++i) { 549 va[i] = MyValue1.createWithFieldsInline(rI, rL); 550 } 551 MyValue1[] result = test18(va); 552 for (int i = 0; i < len; ++i) { 553 Asserts.assertEQ(result[i].hash(), va[i].hash()); 554 } 555 } 556 557 // clone() as series of loads/stores 558 static MyValue1[] test19_orig = null; 559 560 @Test 561 public MyValue1[] test19() { 562 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 8); 563 for (int i = 0; i < va.length; ++i) { 564 va[i] = MyValue1.createWithFieldsInline(rI, rL); 565 } 566 test19_orig = va; 567 568 return va.clone(); 569 } 570 571 @Run(test = "test19") 572 public void test19_verifier() { 573 MyValue1[] result = test19(); 574 for (int i = 0; i < test19_orig.length; ++i) { 575 Asserts.assertEQ(result[i].hash(), test19_orig[i].hash()); 576 } 577 } 578 579 // arraycopy() of value class array with oop fields 580 @Test 581 public void test20(MyValue1[] src, MyValue1[] dst) { 582 System.arraycopy(src, 0, dst, 0, src.length); 583 } 584 585 @Run(test = "test20") 586 public void test20_verifier() { 587 int len = Math.abs(rI) % 10; 588 MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len); 589 MyValue1[] dst = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len); 590 for (int i = 0; i < len; ++i) { 591 src[i] = MyValue1.createWithFieldsInline(rI, rL); 592 } 593 test20(src, dst); 594 for (int i = 0; i < len; ++i) { 595 Asserts.assertEQ(src[i].hash(), dst[i].hash()); 596 } 597 } 598 599 // arraycopy() of value class array with no oop field 600 @Test 601 public void test21(MyValue2[] src, MyValue2[] dst) { 602 System.arraycopy(src, 0, dst, 0, src.length); 603 } 604 605 @Run(test = "test21") 606 public void test21_verifier() { 607 int len = Math.abs(rI) % 10; 608 MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, len); 609 MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, len); 610 for (int i = 0; i < len; ++i) { 611 src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); 612 } 613 test21(src, dst); 614 for (int i = 0; i < len; ++i) { 615 Asserts.assertEQ(src[i].hash(), dst[i].hash()); 616 } 617 } 618 619 // arraycopy() of value class array with oop field and tightly 620 // coupled allocation as dest 621 @Test 622 public MyValue1[] test22(MyValue1[] src) { 623 MyValue1[] dst = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, src.length); 624 System.arraycopy(src, 0, dst, 0, src.length); 625 return dst; 626 } 627 628 @Run(test = "test22") 629 public void test22_verifier() { 630 int len = Math.abs(rI) % 10; 631 MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len); 632 for (int i = 0; i < len; ++i) { 633 src[i] = MyValue1.createWithFieldsInline(rI, rL); 634 } 635 MyValue1[] dst = test22(src); 636 for (int i = 0; i < len; ++i) { 637 Asserts.assertEQ(src[i].hash(), dst[i].hash()); 638 } 639 } 640 641 // arraycopy() of value class array with oop fields and tightly 642 // coupled allocation as dest 643 @Test 644 public MyValue1[] test23(MyValue1[] src) { 645 MyValue1[] dst = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, src.length + 10); 646 System.arraycopy(src, 0, dst, 5, src.length); 647 return dst; 648 } 649 650 @Run(test = "test23") 651 public void test23_verifier() { 652 int len = Math.abs(rI) % 10; 653 MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len); 654 for (int i = 0; i < len; ++i) { 655 src[i] = MyValue1.createWithFieldsInline(rI, rL); 656 } 657 MyValue1[] dst = test23(src); 658 for (int i = 5; i < len; ++i) { 659 Asserts.assertEQ(src[i].hash(), dst[i].hash()); 660 } 661 } 662 663 // arraycopy() of value class array passed as Object 664 @Test 665 public void test24(MyValue1[] src, Object dst) { 666 System.arraycopy(src, 0, dst, 0, src.length); 667 } 668 669 @Run(test = "test24") 670 public void test24_verifier() { 671 int len = Math.abs(rI) % 10; 672 MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len); 673 MyValue1[] dst1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len); 674 Object[] dst2 = new Object[len]; 675 for (int i = 0; i < len; ++i) { 676 src[i] = MyValue1.createWithFieldsInline(rI, rL); 677 } 678 test24(src, dst1); 679 for (int i = 0; i < len; ++i) { 680 Asserts.assertEQ(src[i].hash(), dst1[i].hash()); 681 } 682 test24(src, dst2); 683 for (int i = 0; i < len; ++i) { 684 Asserts.assertEQ(src[i].hash(), ((MyValue1)dst2[i]).hash()); 685 } 686 } 687 688 // short arraycopy() with no oop field 689 @Test 690 public void test25(MyValue2[] src, MyValue2[] dst) { 691 System.arraycopy(src, 0, dst, 0, 8); 692 } 693 694 @Run(test = "test25") 695 public void test25_verifier() { 696 MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 8); 697 MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 8); 698 for (int i = 0; i < 8; ++i) { 699 src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); 700 } 701 test25(src, dst); 702 for (int i = 0; i < 8; ++i) { 703 Asserts.assertEQ(src[i].hash(), dst[i].hash()); 704 } 705 } 706 707 // short arraycopy() with oop fields 708 @Test 709 public void test26(MyValue1[] src, MyValue1[] dst) { 710 System.arraycopy(src, 0, dst, 0, 8); 711 } 712 713 @Run(test = "test26") 714 public void test26_verifier() { 715 MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 8); 716 MyValue1[] dst = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 8); 717 for (int i = 0; i < 8; ++i) { 718 src[i] = MyValue1.createWithFieldsInline(rI, rL); 719 } 720 test26(src, dst); 721 for (int i = 0; i < 8; ++i) { 722 Asserts.assertEQ(src[i].hash(), dst[i].hash()); 723 } 724 } 725 726 // short arraycopy() with oop fields and offsets 727 @Test 728 public void test27(MyValue1[] src, MyValue1[] dst) { 729 System.arraycopy(src, 1, dst, 2, 6); 730 } 731 732 @Run(test = "test27") 733 public void test27_verifier() { 734 MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 8); 735 MyValue1[] dst = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 8); 736 for (int i = 0; i < 8; ++i) { 737 src[i] = MyValue1.createWithFieldsInline(rI, rL); 738 } 739 test27(src, dst); 740 for (int i = 2; i < 8; ++i) { 741 Asserts.assertEQ(src[i-1].hash(), dst[i].hash()); 742 } 743 } 744 745 // non escaping allocations 746 // TODO 8252027: Make sure this is optimized with ZGC 747 @Test 748 @IR(applyIf = {"UseZGC", "false"}, 749 failOn = {ALLOCA, LOOP, LOAD, TRAP}) 750 public MyValue2 test28() { 751 MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 10); 752 src[0] = MyValue2.createWithFieldsInline(rI, rD); 753 MyValue2[] dst = (MyValue2[])src.clone(); 754 return dst[0]; 755 } 756 757 @Run(test = "test28") 758 public void test28_verifier() { 759 MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); 760 MyValue2 result = test28(); 761 Asserts.assertEQ(result.hash(), v.hash()); 762 } 763 764 // non escaping allocations 765 // TODO 8227588: shouldn't this have the same IR matching rules as test6? 766 // @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + STORE + TRAP) 767 @Test 768 @IR(applyIf = {"UseArrayFlattening", "true"}, 769 failOn = {ALLOCA, LOOP, LOAD, TRAP}) 770 @IR(applyIf = {"UseArrayFlattening", "false"}, 771 failOn = {ALLOCA, LOOP, TRAP}) 772 public MyValue2 test29(MyValue2[] src) { 773 MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 10); 774 System.arraycopy(src, 0, dst, 0, 10); 775 return dst[0]; 776 } 777 778 @Run(test = "test29") 779 public void test29_verifier() { 780 MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 10); 781 for (int i = 0; i < 10; ++i) { 782 src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); 783 } 784 MyValue2 v = test29(src); 785 Asserts.assertEQ(src[0].hash(), v.hash()); 786 } 787 788 // non escaping allocation with uncommon trap that needs 789 // eliminated value class array element as debug info 790 @Test 791 public MyValue2 test30(MyValue2[] src, boolean flag) { 792 MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 10); 793 System.arraycopy(src, 0, dst, 0, 10); 794 if (flag) { } 795 return dst[0]; 796 } 797 798 @Run(test = "test30") 799 @Warmup(10000) 800 public void test30_verifier(RunInfo info) { 801 MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 10); 802 for (int i = 0; i < 10; ++i) { 803 src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); 804 } 805 MyValue2 v = test30(src, !info.isWarmUp()); 806 Asserts.assertEQ(src[0].hash(), v.hash()); 807 } 808 809 810 // non escaping allocation with memory phi 811 @Test 812 @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE, TRAP}) 813 public long test31(boolean b, boolean deopt, Method m) { 814 MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 1); 815 if (b) { 816 src[0] = MyValue2.createWithFieldsInline(rI, rD); 817 } else { 818 src[0] = MyValue2.createWithFieldsInline(rI+1, rD+1); 819 } 820 if (deopt) { 821 // uncommon trap 822 TestFramework.deoptimize(m); 823 } 824 return src[0].hash(); 825 } 826 827 @Run(test = "test31") 828 public void test31_verifier(RunInfo info) { 829 MyValue2 v1 = MyValue2.createWithFieldsInline(rI, rD); 830 long result1 = test31(true, !info.isWarmUp(), info.getTest()); 831 Asserts.assertEQ(result1, v1.hash()); 832 MyValue2 v2 = MyValue2.createWithFieldsInline(rI + 1, rD + 1); 833 long result2 = test31(false, !info.isWarmUp(), info.getTest()); 834 Asserts.assertEQ(result2, v2.hash()); 835 } 836 837 // Tests with Object arrays and clone/arraycopy 838 // clone() as stub call 839 @Test 840 public Object[] test32(Object[] va) { 841 return va.clone(); 842 } 843 844 @Run(test = "test32") 845 public void test32_verifier() { 846 int len = Math.abs(rI) % 10; 847 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len); 848 for (int i = 0; i < len; ++i) { 849 va[i] = MyValue1.createWithFieldsInline(rI, rL); 850 } 851 MyValue1[] result = (MyValue1[])test32(va); 852 for (int i = 0; i < len; ++i) { 853 Asserts.assertEQ(((MyValue1)result[i]).hash(), ((MyValue1)va[i]).hash()); 854 } 855 } 856 857 @Test 858 public Object[] test33(Object[] va) { 859 return va.clone(); 860 } 861 862 @Run(test = "test33") 863 public void test33_verifier() { 864 int len = Math.abs(rI) % 10; 865 Object[] va = new Object[len]; 866 for (int i = 0; i < len; ++i) { 867 va[i] = MyValue1.createWithFieldsInline(rI, rL); 868 } 869 Object[] result = test33(va); 870 for (int i = 0; i < len; ++i) { 871 Asserts.assertEQ(((MyValue1)result[i]).hash(), ((MyValue1)va[i]).hash()); 872 // Check that array has correct properties (null-ok) 873 result[i] = null; 874 } 875 } 876 877 // clone() as series of loads/stores 878 static Object[] test34_orig = null; 879 880 @ForceInline 881 public Object[] test34_helper(boolean flag) { 882 Object[] va = null; 883 if (flag) { 884 va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 8); 885 for (int i = 0; i < va.length; ++i) { 886 va[i] = MyValue1.createWithFieldsDontInline(rI, rL); 887 } 888 } else { 889 va = new Object[8]; 890 } 891 return va; 892 } 893 894 @Test 895 public Object[] test34(boolean flag) { 896 Object[] va = test34_helper(flag); 897 test34_orig = va; 898 return va.clone(); 899 } 900 901 @Run(test = "test34") 902 public void test34_verifier(RunInfo info) { 903 test34(false); 904 for (int i = 0; i < 10; i++) { // make sure we do deopt 905 Object[] result = test34(true); 906 verify(test34_orig, result); 907 // Check that array has correct properties (null-free) 908 try { 909 result[0] = null; 910 throw new RuntimeException("Should throw NullPointerException"); 911 } catch (NullPointerException e) { 912 // Expected 913 } 914 } 915 if (compile_and_run_again_if_deoptimized(info)) { 916 Object[] result = test34(true); 917 verify(test34_orig, result); 918 // Check that array has correct properties (null-free) 919 try { 920 result[0] = null; 921 throw new RuntimeException("Should throw NullPointerException"); 922 } catch (NullPointerException e) { 923 // Expected 924 } 925 } 926 } 927 928 // arraycopy() of value class array of unknown size 929 @Test 930 public void test35(Object src, Object dst, int len) { 931 System.arraycopy(src, 0, dst, 0, len); 932 } 933 934 @Run(test = "test35") 935 public void test35_verifier(RunInfo info) { 936 int len = Math.abs(rI) % 10; 937 MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len); 938 MyValue1[] dst1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len); 939 Object[] dst2 = new Object[len]; 940 for (int i = 0; i < len; ++i) { 941 src[i] = MyValue1.createWithFieldsInline(rI, rL); 942 } 943 test35(src, dst1, src.length); 944 verify(src, dst1); 945 test35(src, dst2, src.length); 946 verify(src, dst2); 947 if (compile_and_run_again_if_deoptimized(info)) { 948 test35(src, dst1, src.length); 949 verify(src, dst1); 950 } 951 } 952 953 @Test 954 public void test36(Object src, MyValue2[] dst) { 955 System.arraycopy(src, 0, dst, 0, dst.length); 956 } 957 958 @Run(test = "test36") 959 public void test36_verifier(RunInfo info) { 960 int len = Math.abs(rI) % 10; 961 MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, len); 962 MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, len); 963 for (int i = 0; i < len; ++i) { 964 src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); 965 } 966 test36(src, dst); 967 verify(src, dst); 968 if (compile_and_run_again_if_deoptimized(info)) { 969 test36(src, dst); 970 verify(src, dst); 971 } 972 } 973 974 @Test 975 public void test37(MyValue2[] src, Object dst) { 976 System.arraycopy(src, 0, dst, 0, src.length); 977 } 978 979 @Run(test = "test37") 980 public void test37_verifier(RunInfo info) { 981 int len = Math.abs(rI) % 10; 982 MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, len); 983 MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, len); 984 for (int i = 0; i < len; ++i) { 985 src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); 986 } 987 test37(src, dst); 988 verify(src, dst); 989 if (compile_and_run_again_if_deoptimized(info)) { 990 test37(src, dst); 991 verify(src, dst); 992 } 993 } 994 995 @Test 996 public void test38(Object src, MyValue2[] dst) { 997 System.arraycopy(src, 0, dst, 0, dst.length); 998 } 999 1000 @Run(test = "test38") 1001 @Warmup(1) // Avoid early compilation 1002 public void test38_verifier(RunInfo info) { 1003 int len = Math.abs(rI) % 10; 1004 Object[] src = new Object[len]; 1005 MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, len); 1006 for (int i = 0; i < len; ++i) { 1007 src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); 1008 } 1009 test38(src, dst); 1010 verify(dst, src); 1011 if (!info.isWarmUp()) { 1012 Method m = info.getTest(); 1013 TestFramework.assertDeoptimizedByC2(m); 1014 TestFramework.compile(m, CompLevel.C2); 1015 test38(src, dst); 1016 verify(dst, src); 1017 TestFramework.assertCompiledByC2(m); 1018 } 1019 } 1020 1021 @Test 1022 public void test39(MyValue2[] src, Object dst) { 1023 System.arraycopy(src, 0, dst, 0, src.length); 1024 } 1025 1026 @Run(test = "test39") 1027 public void test39_verifier(RunInfo info) { 1028 int len = Math.abs(rI) % 10; 1029 MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, len); 1030 Object[] dst = new Object[len]; 1031 for (int i = 0; i < len; ++i) { 1032 src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); 1033 } 1034 test39(src, dst); 1035 verify(src, dst); 1036 if (compile_and_run_again_if_deoptimized(info)) { 1037 test39(src, dst); 1038 verify(src, dst); 1039 } 1040 } 1041 1042 @Test 1043 public void test40(Object[] src, Object dst) { 1044 System.arraycopy(src, 0, dst, 0, src.length); 1045 } 1046 1047 @Run(test = "test40") 1048 @Warmup(1) // Avoid early compilation 1049 public void test40_verifier(RunInfo info) { 1050 int len = Math.abs(rI) % 10; 1051 Object[] src = new Object[len]; 1052 MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, len); 1053 for (int i = 0; i < len; ++i) { 1054 src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); 1055 } 1056 test40(src, dst); 1057 verify(dst, src); 1058 if (!info.isWarmUp()) { 1059 Method m = info.getTest(); 1060 TestFramework.assertDeoptimizedByC2(m); 1061 TestFramework.compile(m, CompLevel.C2); 1062 test40(src, dst); 1063 verify(dst, src); 1064 TestFramework.assertCompiledByC2(m); 1065 } 1066 } 1067 1068 @Test 1069 public void test41(Object src, Object[] dst) { 1070 System.arraycopy(src, 0, dst, 0, dst.length); 1071 } 1072 1073 @Run(test = "test41") 1074 public void test41_verifier(RunInfo info) { 1075 int len = Math.abs(rI) % 10; 1076 MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, len); 1077 Object[] dst = new Object[len]; 1078 for (int i = 0; i < len; ++i) { 1079 src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); 1080 } 1081 test41(src, dst); 1082 verify(src, dst); 1083 if (compile_and_run_again_if_deoptimized(info)) { 1084 test41(src, dst); 1085 verify(src, dst); 1086 } 1087 } 1088 1089 @Test 1090 public void test42(Object[] src, Object[] dst) { 1091 System.arraycopy(src, 0, dst, 0, src.length); 1092 } 1093 1094 @Run(test = "test42") 1095 public void test42_verifier(RunInfo info) { 1096 int len = Math.abs(rI) % 10; 1097 Object[] src = new Object[len]; 1098 Object[] dst = new Object[len]; 1099 for (int i = 0; i < len; ++i) { 1100 src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); 1101 } 1102 test42(src, dst); 1103 verify(src, dst); 1104 if (!info.isWarmUp()) { 1105 TestFramework.assertCompiledByC2(info.getTest()); 1106 } 1107 } 1108 1109 // short arraycopy()'s 1110 @Test 1111 public void test43(Object src, Object dst) { 1112 System.arraycopy(src, 0, dst, 0, 8); 1113 } 1114 1115 @Run(test = "test43") 1116 public void test43_verifier(RunInfo info) { 1117 MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 8); 1118 MyValue1[] dst = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 8); 1119 for (int i = 0; i < 8; ++i) { 1120 src[i] = MyValue1.createWithFieldsInline(rI, rL); 1121 } 1122 test43(src, dst); 1123 verify(src, dst); 1124 if (compile_and_run_again_if_deoptimized(info)) { 1125 test43(src, dst); 1126 verify(src, dst); 1127 } 1128 } 1129 1130 @Test 1131 public void test44(Object src, MyValue2[] dst) { 1132 System.arraycopy(src, 0, dst, 0, 8); 1133 } 1134 1135 @Run(test = "test44") 1136 public void test44_verifier(RunInfo info) { 1137 MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 8); 1138 MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 8); 1139 for (int i = 0; i < 8; ++i) { 1140 src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); 1141 } 1142 test44(src, dst); 1143 verify(src, dst); 1144 if (compile_and_run_again_if_deoptimized(info)) { 1145 test44(src, dst); 1146 verify(src, dst); 1147 } 1148 } 1149 1150 @Test 1151 public void test45(MyValue2[] src, Object dst) { 1152 System.arraycopy(src, 0, dst, 0, 8); 1153 } 1154 1155 @Run(test = "test45") 1156 public void test45_verifier(RunInfo info) { 1157 MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 8); 1158 MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 8); 1159 for (int i = 0; i < 8; ++i) { 1160 src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); 1161 } 1162 test45(src, dst); 1163 verify(src, dst); 1164 if (compile_and_run_again_if_deoptimized(info)) { 1165 test45(src, dst); 1166 verify(src, dst); 1167 } 1168 } 1169 1170 @Test 1171 public void test46(Object[] src, MyValue2[] dst) { 1172 System.arraycopy(src, 0, dst, 0, 8); 1173 } 1174 1175 @Run(test = "test46") 1176 @Warmup(1) // Avoid early compilation 1177 public void test46_verifier(RunInfo info) { 1178 Object[] src = new Object[8]; 1179 MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 8); 1180 for (int i = 0; i < 8; ++i) { 1181 src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); 1182 } 1183 test46(src, dst); 1184 verify(dst, src); 1185 if (!info.isWarmUp()) { 1186 Method m = info.getTest(); 1187 TestFramework.assertDeoptimizedByC2(m); 1188 TestFramework.compile(m, CompLevel.C2); 1189 test46(src, dst); 1190 verify(dst, src); 1191 TestFramework.assertCompiledByC2(m); 1192 } 1193 } 1194 1195 @Test 1196 public void test47(MyValue2[] src, Object[] dst) { 1197 System.arraycopy(src, 0, dst, 0, 8); 1198 } 1199 1200 @Run(test = "test47") 1201 public void test47_verifier(RunInfo info) { 1202 MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 8); 1203 Object[] dst = new Object[8]; 1204 for (int i = 0; i < 8; ++i) { 1205 src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); 1206 } 1207 test47(src, dst); 1208 verify(src, dst); 1209 if (compile_and_run_again_if_deoptimized(info)) { 1210 test47(src, dst); 1211 verify(src, dst); 1212 } 1213 } 1214 1215 @Test 1216 public void test48(Object[] src, Object dst) { 1217 System.arraycopy(src, 0, dst, 0, 8); 1218 } 1219 1220 @Run(test = "test48") 1221 @Warmup(1) // Avoid early compilation 1222 public void test48_verifier(RunInfo info) { 1223 Object[] src = new Object[8]; 1224 MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 8); 1225 for (int i = 0; i < 8; ++i) { 1226 src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); 1227 } 1228 test48(src, dst); 1229 verify(dst, src); 1230 if (!info.isWarmUp()) { 1231 Method m = info.getTest(); 1232 TestFramework.assertDeoptimizedByC2(m); 1233 TestFramework.compile(m, CompLevel.C2); 1234 test48(src, dst); 1235 verify(dst, src); 1236 TestFramework.assertCompiledByC2(m); 1237 } 1238 } 1239 1240 @Test 1241 public void test49(Object src, Object[] dst) { 1242 System.arraycopy(src, 0, dst, 0, 8); 1243 } 1244 1245 @Run(test = "test49") 1246 public void test49_verifier(RunInfo info) { 1247 MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 8); 1248 Object[] dst = new Object[8]; 1249 for (int i = 0; i < 8; ++i) { 1250 src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); 1251 } 1252 test49(src, dst); 1253 verify(src, dst); 1254 if (compile_and_run_again_if_deoptimized(info)) { 1255 test49(src, dst); 1256 verify(src, dst); 1257 } 1258 } 1259 1260 @Test 1261 public void test50(Object[] src, Object[] dst) { 1262 System.arraycopy(src, 0, dst, 0, 8); 1263 } 1264 1265 @Run(test = "test50") 1266 public void test50_verifier(RunInfo info) { 1267 Object[] src = new Object[8]; 1268 Object[] dst = new Object[8]; 1269 for (int i = 0; i < 8; ++i) { 1270 src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); 1271 } 1272 test50(src, dst); 1273 verify(src, dst); 1274 if (!info.isWarmUp()) { 1275 Method m = info.getTest(); 1276 TestFramework.assertCompiledByC2(m); 1277 } 1278 } 1279 1280 @Test 1281 public MyValue1[] test51(MyValue1[] va) { 1282 Object[] res = Arrays.copyOf(va, va.length, MyValue1[].class); 1283 return (MyValue1[]) res; 1284 } 1285 1286 @Run(test = "test51") 1287 public void test51_verifier() { 1288 int len = Math.abs(rI) % 10; 1289 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len); 1290 for (int i = 0; i < len; ++i) { 1291 va[i] = MyValue1.createWithFieldsInline(rI, rL); 1292 } 1293 MyValue1[] result = test51(va); 1294 verify(va, result); 1295 } 1296 1297 static final MyValue1[] test52_va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 8); 1298 1299 @Test 1300 public MyValue1[] test52() { 1301 Object[] res = Arrays.copyOf(test52_va, 8, MyValue1[].class); 1302 return (MyValue1[]) res; 1303 } 1304 1305 @Run(test = "test52") 1306 public void test52_verifier() { 1307 for (int i = 0; i < 8; ++i) { 1308 test52_va[i] = MyValue1.createWithFieldsInline(rI, rL); 1309 } 1310 MyValue1[] result = test52(); 1311 verify(test52_va, result); 1312 } 1313 1314 @Test 1315 public MyValue1[] test53(Object[] va) { 1316 Object[] res = Arrays.copyOf(va, va.length, MyValue1[].class); 1317 return (MyValue1[]) res; 1318 } 1319 1320 @Run(test = "test53") 1321 public void test53_verifier() { 1322 int len = Math.abs(rI) % 10; 1323 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len); 1324 for (int i = 0; i < len; ++i) { 1325 va[i] = MyValue1.createWithFieldsInline(rI, rL); 1326 } 1327 MyValue1[] result = test53(va); 1328 verify(result, va); 1329 } 1330 1331 @Test 1332 public Object[] test54(MyValue1[] va) { 1333 return Arrays.copyOf(va, va.length, Object[].class); 1334 } 1335 1336 @Run(test = "test54") 1337 public void test54_verifier() { 1338 int len = Math.abs(rI) % 10; 1339 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len); 1340 for (int i = 0; i < len; ++i) { 1341 va[i] = MyValue1.createWithFieldsInline(rI, rL); 1342 } 1343 Object[] result = test54(va); 1344 verify(va, result); 1345 } 1346 1347 @Test 1348 public Object[] test55(Object[] va) { 1349 return Arrays.copyOf(va, va.length, Object[].class); 1350 } 1351 1352 @Run(test = "test55") 1353 public void test55_verifier() { 1354 int len = Math.abs(rI) % 10; 1355 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len); 1356 for (int i = 0; i < len; ++i) { 1357 va[i] = MyValue1.createWithFieldsInline(rI, rL); 1358 } 1359 Object[] result = test55(va); 1360 verify(va, result); 1361 } 1362 1363 @Test 1364 public MyValue1[] test56(Object[] va) { 1365 Object[] res = Arrays.copyOf(va, va.length, MyValue1[].class); 1366 return (MyValue1[]) res; 1367 } 1368 1369 @Run(test = "test56") 1370 public void test56_verifier() { 1371 int len = Math.abs(rI) % 10; 1372 Object[] va = new Object[len]; 1373 for (int i = 0; i < len; ++i) { 1374 va[i] = MyValue1.createWithFieldsInline(rI, rL); 1375 } 1376 MyValue1[] result = test56(va); 1377 verify(result, va); 1378 } 1379 1380 @Test 1381 public Object[] test57(Object[] va, Class klass) { 1382 return Arrays.copyOf(va, va.length, klass); 1383 } 1384 1385 @Run(test = "test57") 1386 public void test57_verifier() { 1387 int len = Math.abs(rI) % 10; 1388 Object[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len); 1389 for (int i = 0; i < len; ++i) { 1390 va[i] = MyValue1.createWithFieldsInline(rI, rL); 1391 } 1392 Object[] result = test57(va, MyValue1[].class); 1393 verify(va, result); 1394 } 1395 1396 @Test 1397 public Object[] test58(MyValue1[] va, Class klass) { 1398 return Arrays.copyOf(va, va.length, klass); 1399 } 1400 1401 @Run(test = "test58") 1402 public void test58_verifier(RunInfo info) { 1403 int len = Math.abs(rI) % 10; 1404 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len); 1405 for (int i = 0; i < len; ++i) { 1406 va[i] = MyValue1.createWithFieldsInline(rI, rL); 1407 } 1408 for (int i = 0; i < 10; i++) { 1409 Object[] result = test58(va, MyValue1[].class); 1410 verify(va, result); 1411 } 1412 if (compile_and_run_again_if_deoptimized(info)) { 1413 Object[] result = test58(va, MyValue1[].class); 1414 verify(va, result); 1415 } 1416 } 1417 1418 @Test 1419 public Object[] test59(MyValue1[] va) { 1420 return Arrays.copyOf(va, va.length+1, va.getClass()); 1421 } 1422 1423 @Run(test = "test59") 1424 public void test59_verifier() { 1425 int len = Math.abs(rI) % 10; 1426 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len); 1427 MyValue1[] verif = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len + 1); 1428 for (int i = 0; i < len; ++i) { 1429 va[i] = MyValue1.createWithFieldsInline(rI, rL); 1430 verif[i] = va[i]; 1431 } 1432 Object[] result = test59(va); 1433 // Result is a null-restricted array 1434 Asserts.assertEQ(result[len], MyValue1.createDefaultInline()); 1435 result[len] = MyValue1.createDefaultInline(); 1436 verify(verif, result); 1437 } 1438 1439 @Test 1440 public Object[] test60(Object[] va, Class klass) { 1441 return Arrays.copyOf(va, va.length+1, klass); 1442 } 1443 1444 @Run(test = "test60") 1445 public void test60_verifier() { 1446 int len = Math.abs(rI) % 10; 1447 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len); 1448 MyValue1[] verif = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len + 1); 1449 for (int i = 0; i < len; ++i) { 1450 va[i] = MyValue1.createWithFieldsInline(rI, rL); 1451 verif[i] = (MyValue1)va[i]; 1452 } 1453 Object[] result = test60(va, va.getClass()); 1454 // Result is a null-restricted array 1455 Asserts.assertEQ(result[len], MyValue1.createDefaultInline()); 1456 result[len] = MyValue1.createDefaultInline(); 1457 verify(verif, result); 1458 } 1459 1460 @Test 1461 public Object[] test61(Object[] va, Class klass) { 1462 return Arrays.copyOf(va, va.length+1, klass); 1463 } 1464 1465 @Run(test = "test61") 1466 public void test61_verifier() { 1467 int len = Math.abs(rI) % 10; 1468 Object[] va = new NonValueClass[len]; 1469 for (int i = 0; i < len; ++i) { 1470 va[i] = new NonValueClass(rI); 1471 } 1472 Object[] result = test61(va, NonValueClass[].class); 1473 for (int i = 0; i < va.length; ++i) { 1474 Asserts.assertEQ(va[i], result[i]); 1475 } 1476 } 1477 1478 @ForceInline 1479 public Object[] test62_helper(int i, MyValue1[] va, NonValueClass[] oa) { 1480 Object[] arr = null; 1481 if (i == 10) { 1482 arr = oa; 1483 } else { 1484 arr = va; 1485 } 1486 return arr; 1487 } 1488 1489 @Test 1490 public Object[] test62(MyValue1[] va, NonValueClass[] oa) { 1491 int i = 0; 1492 for (; i < 10; i++); 1493 1494 Object[] arr = test62_helper(i, va, oa); 1495 1496 return Arrays.copyOf(arr, arr.length+1, arr.getClass()); 1497 } 1498 1499 @Run(test = "test62") 1500 public void test62_verifier() { 1501 int len = Math.abs(rI) % 10; 1502 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len); 1503 NonValueClass[] oa = new NonValueClass[len]; 1504 for (int i = 0; i < len; ++i) { 1505 oa[i] = new NonValueClass(rI); 1506 } 1507 test62_helper(42, va, oa); 1508 Object[] result = test62(va, oa); 1509 for (int i = 0; i < va.length; ++i) { 1510 Asserts.assertEQ(oa[i], result[i]); 1511 } 1512 } 1513 1514 @ForceInline 1515 public Object[] test63_helper(int i, MyValue1[] va, NonValueClass[] oa) { 1516 Object[] arr = null; 1517 if (i == 10) { 1518 arr = va; 1519 } else { 1520 arr = oa; 1521 } 1522 return arr; 1523 } 1524 1525 @Test 1526 public Object[] test63(MyValue1[] va, NonValueClass[] oa) { 1527 int i = 0; 1528 for (; i < 10; i++); 1529 1530 Object[] arr = test63_helper(i, va, oa); 1531 1532 return Arrays.copyOf(arr, arr.length+1, arr.getClass()); 1533 } 1534 1535 @Run(test = "test63") 1536 public void test63_verifier() { 1537 int len = Math.abs(rI) % 10; 1538 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len); 1539 MyValue1[] verif = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len + 1); 1540 for (int i = 0; i < len; ++i) { 1541 va[i] = MyValue1.createWithFieldsInline(rI, rL); 1542 verif[i] = va[i]; 1543 } 1544 NonValueClass[] oa = new NonValueClass[len]; 1545 test63_helper(42, va, oa); 1546 Object[] result = test63(va, oa); 1547 // Result is a null-restricted array 1548 Asserts.assertEQ(result[len], MyValue1.createDefaultInline()); 1549 result[len] = MyValue1.createDefaultInline(); 1550 verify(verif, result); 1551 } 1552 1553 // Test default initialization of value class arrays: small array 1554 @Test 1555 public MyValue1[] test64() { 1556 return (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 8); 1557 } 1558 1559 @Run(test = "test64") 1560 public void test64_verifier() { 1561 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 8); 1562 MyValue1[] var = test64(); 1563 for (int i = 0; i < 8; ++i) { 1564 Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive()); 1565 } 1566 } 1567 1568 // Test default initialization of value class arrays: large array 1569 @Test 1570 public MyValue1[] test65() { 1571 return (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 32); 1572 } 1573 1574 @Run(test = "test65") 1575 public void test65_verifier() { 1576 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 32); 1577 MyValue1[] var = test65(); 1578 for (int i = 0; i < 32; ++i) { 1579 Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive()); 1580 } 1581 } 1582 1583 // Check init store elimination 1584 @Test 1585 @IR(counts = {ALLOCA, "= 1"}) 1586 public MyValue1[] test66(MyValue1 vt) { 1587 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 1588 va[0] = vt; 1589 return va; 1590 } 1591 1592 @Run(test = "test66") 1593 public void test66_verifier() { 1594 MyValue1 vt = MyValue1.createWithFieldsDontInline(rI, rL); 1595 MyValue1[] va = test66(vt); 1596 Asserts.assertEQ(va[0].hashPrimitive(), vt.hashPrimitive()); 1597 } 1598 1599 // Zeroing elimination and arraycopy 1600 @Test 1601 public MyValue1[] test67(MyValue1[] src) { 1602 MyValue1[] dst = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 16); 1603 System.arraycopy(src, 0, dst, 0, 13); 1604 return dst; 1605 } 1606 1607 @Run(test = "test67") 1608 public void test67_verifier() { 1609 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 16); 1610 MyValue1[] var = test67(va); 1611 for (int i = 0; i < 16; ++i) { 1612 Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive()); 1613 } 1614 } 1615 1616 // A store with a default value can be eliminated 1617 @Test 1618 public MyValue1[] test68() { 1619 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2); 1620 va[0] = va[1]; 1621 return va; 1622 } 1623 1624 @Run(test = "test68") 1625 public void test68_verifier() { 1626 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2); 1627 MyValue1[] var = test68(); 1628 for (int i = 0; i < 2; ++i) { 1629 Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive()); 1630 } 1631 } 1632 1633 // Requires individual stores to init array 1634 @Test 1635 public MyValue1[] test69(MyValue1 vt) { 1636 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 4); 1637 va[0] = vt; 1638 va[3] = vt; 1639 return va; 1640 } 1641 1642 @Run(test = "test69") 1643 public void test69_verifier() { 1644 MyValue1 vt = MyValue1.createWithFieldsDontInline(rI, rL); 1645 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 4); 1646 va[0] = vt; 1647 va[3] = vt; 1648 MyValue1[] var = test69(vt); 1649 for (int i = 0; i < va.length; ++i) { 1650 Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive()); 1651 } 1652 } 1653 1654 // A store with a default value can be eliminated: same as test68 1655 // but store is further away from allocation 1656 @Test 1657 public MyValue1[] test70(MyValue1[] other) { 1658 other[1] = other[0]; 1659 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2); 1660 other[0] = va[1]; 1661 va[0] = va[1]; 1662 return va; 1663 } 1664 1665 @Run(test = "test70") 1666 public void test70_verifier() { 1667 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2); 1668 MyValue1[] var = test70(va); 1669 for (int i = 0; i < 2; ++i) { 1670 Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive()); 1671 } 1672 } 1673 1674 // EA needs to consider oop fields in flattened arrays 1675 @Test 1676 public void test71() { 1677 int len = 10; 1678 MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, len); 1679 MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, len); 1680 for (int i = 0; i < len; ++i) { 1681 src[i] = MyValue2.createWithFieldsDontInline(rI+i, rD+i); 1682 } 1683 System.arraycopy(src, 0, dst, 0, src.length); 1684 for (int i = 0; i < len; ++i) { 1685 Asserts.assertEQ(src[i].hash(), dst[i].hash()); 1686 } 1687 } 1688 1689 @Run(test = "test71") 1690 public void test71_verifier() { 1691 test71(); 1692 } 1693 1694 // Test EA with leaf call to 'store_unknown_inline' 1695 @Test 1696 public void test72(Object[] o, boolean b, Object element) { 1697 Object[] arr1 = new Object[10]; 1698 Object[] arr2 = new Object[10]; 1699 if (b) { 1700 arr1 = o; 1701 } 1702 arr1[0] = element; 1703 arr2[0] = element; 1704 } 1705 1706 @Run(test = "test72") 1707 public void test72_verifier() { 1708 Object[] arr = new Object[1]; 1709 Object elem = new Object(); 1710 test72(arr, true, elem); 1711 test72(arr, false, elem); 1712 } 1713 1714 @Test 1715 public void test73(Object[] oa, MyValue1 v, Object o) { 1716 // TestLWorld.test38 use a C1 Phi node for the array. This test 1717 // adds the case where the stored value is a C1 Phi node. 1718 Object o2 = (o == null) ? v : o; 1719 oa[0] = v; // The stored value is known to be flattenable 1720 oa[1] = o; // The stored value may be flattenable 1721 oa[2] = o2; // The stored value may be flattenable (a C1 Phi node) 1722 oa[0] = oa; // The stored value is known to be not flattenable (an Object[]) 1723 } 1724 1725 @Run(test = "test73") 1726 public void test73_verifier() { 1727 MyValue1 v0 = MyValue1.createWithFieldsDontInline(rI, rL); 1728 MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI+1, rL+1); 1729 MyValue1[] arr = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 3); 1730 try { 1731 test73(arr, v0, v1); 1732 throw new RuntimeException("ArrayStoreException expected"); 1733 } catch (ArrayStoreException e) { 1734 // expected 1735 } 1736 Asserts.assertEQ(arr[0].hash(), v0.hash()); 1737 Asserts.assertEQ(arr[1].hash(), v1.hash()); 1738 Asserts.assertEQ(arr[2].hash(), v1.hash()); 1739 } 1740 1741 public static void test74Callee(MyValue1[] va) { } 1742 1743 // Tests invoking unloaded method with value class array in signature 1744 @Test 1745 public void test74(MethodHandle m, MyValue1[] va) throws Throwable { 1746 m.invoke(va); 1747 } 1748 1749 @Run(test = "test74") 1750 @Warmup(0) 1751 public void test74_verifier() throws Throwable { 1752 MethodHandle m = MethodHandles.lookup().findStatic(TestArrays.class, "test74Callee", MethodType.methodType(void.class, MyValue1[].class)); 1753 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 0); 1754 test74(m, va); 1755 } 1756 1757 // Some more array clone tests 1758 @ForceInline 1759 public Object[] test75_helper(int i, MyValue1[] va, NonValueClass[] oa) { 1760 Object[] arr = null; 1761 if (i == 10) { 1762 arr = oa; 1763 } else { 1764 arr = va; 1765 } 1766 return arr; 1767 } 1768 1769 @Test 1770 public Object[] test75(MyValue1[] va, NonValueClass[] oa) { 1771 int i = 0; 1772 for (; i < 10; i++); 1773 1774 Object[] arr = test75_helper(i, va, oa); 1775 return arr.clone(); 1776 } 1777 1778 @Run(test = "test75") 1779 public void test75_verifier() { 1780 int len = Math.abs(rI) % 10; 1781 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len); 1782 NonValueClass[] oa = new NonValueClass[len]; 1783 for (int i = 0; i < len; ++i) { 1784 oa[i] = new NonValueClass(rI); 1785 } 1786 test75_helper(42, va, oa); 1787 Object[] result = test75(va, oa); 1788 1789 for (int i = 0; i < va.length; ++i) { 1790 Asserts.assertEQ(oa[i], result[i]); 1791 // Check that array has correct properties (null-ok) 1792 result[i] = null; 1793 } 1794 } 1795 1796 @ForceInline 1797 public Object[] test76_helper(int i, MyValue1[] va, NonValueClass[] oa) { 1798 Object[] arr = null; 1799 if (i == 10) { 1800 arr = va; 1801 } else { 1802 arr = oa; 1803 } 1804 return arr; 1805 } 1806 1807 @Test 1808 public Object[] test76(MyValue1[] va, NonValueClass[] oa) { 1809 int i = 0; 1810 for (; i < 10; i++); 1811 1812 Object[] arr = test76_helper(i, va, oa); 1813 return arr.clone(); 1814 } 1815 1816 @Run(test = "test76") 1817 public void test76_verifier() { 1818 int len = Math.abs(rI) % 10; 1819 MyValue1[] va = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len); 1820 MyValue1[] verif = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, len); 1821 for (int i = 0; i < len; ++i) { 1822 va[i] = MyValue1.createWithFieldsInline(rI, rL); 1823 verif[i] = va[i]; 1824 } 1825 NonValueClass[] oa = new NonValueClass[len]; 1826 test76_helper(42, va, oa); 1827 Object[] result = test76(va, oa); 1828 verify(verif, result); 1829 // Check that array has correct properties (null-free) 1830 if (len > 0) { 1831 try { 1832 result[0] = null; 1833 throw new RuntimeException("Should throw NullPointerException"); 1834 } catch (NullPointerException e) { 1835 // Expected 1836 } 1837 } 1838 } 1839 1840 @Test 1841 public void test77() { 1842 MyValue1 v0 = MyValue1.createWithFieldsDontInline(rI, rL); 1843 MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI+1, rL+1); 1844 MyValue1[] arr = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 1845 1846 Object[] oa = arr; 1847 Object o1 = v1; 1848 Object o = (o1 == null) ? v0 : o1; 1849 1850 oa[0] = o; // For C1, due to IfOp optimization, the declared_type of o becomes NULL. 1851 1852 Asserts.assertEQ(arr[0].hash(), v1.hash()); 1853 } 1854 1855 1856 @Run(test = "test77") 1857 public void test77_verifier() { 1858 test77(); 1859 } 1860 1861 @Test 1862 public long test78(MyValue1 v, int n) { 1863 long x = 0; 1864 for (int i = 0; i < n; i++) { 1865 } 1866 1867 MyValue1[] a = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, n); 1868 a[0] = v; 1869 for (int i = 0; i<n; i++) { 1870 x += a[i].hash(); // C1 PhiSimplifier changes "a" from a Phi node to a NewObjectArray node 1871 } 1872 1873 return x; 1874 } 1875 1876 @Run(test = "test78") 1877 public void test78_verifier() { 1878 MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); 1879 Asserts.assertEQ(test78(v, 1), v.hash()); 1880 } 1881 1882 // Verify that casting an array element to a non-flattenable type marks the array as not-flat 1883 @Test 1884 @IR(applyIf = {"UseArrayFlattening", "true"}, 1885 counts = {LOAD_UNKNOWN_INLINE, "= 1"}) 1886 @IR(applyIf = {"UseArrayFlattening", "false"}, 1887 failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE}) 1888 public Object test79(Object[] array, int i) { 1889 NonValueClass i1 = (NonValueClass)array[0]; 1890 Object o = array[1]; 1891 return array[i]; 1892 } 1893 1894 @Run(test = "test79") 1895 public void test79_verifier() { 1896 NonValueClass obj = new NonValueClass(rI); 1897 NonValueClass[] array = new NonValueClass[2]; 1898 array[1] = obj; 1899 Object result = test79(array, 1); 1900 Asserts.assertEquals(result, obj); 1901 } 1902 1903 // Same as test79 but with not-flattenable value class 1904 @Test 1905 @IR(applyIf = {"UseArrayFlattening", "true"}, 1906 counts = {LOAD_UNKNOWN_INLINE, "= 1"}) 1907 @IR(applyIf = {"UseArrayFlattening", "false"}, 1908 failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE}) 1909 public Object test80(Object[] array, int i) { 1910 NotFlattenable vt = (NotFlattenable)array[0]; 1911 Object o = array[1]; 1912 return array[i]; 1913 } 1914 1915 @Run(test = "test80") 1916 public void test80_verifier() { 1917 NotFlattenable vt = new NotFlattenable(); 1918 NotFlattenable[] array = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 2); 1919 array[1] = vt; 1920 Object result = test80(array, 1); 1921 Asserts.assertEquals(result, vt); 1922 } 1923 1924 // Verify that writing an object of a non-inline, non-null type to an array marks the array as not-null-free and not-flat 1925 @Test 1926 @IR(failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}) 1927 public Object test81(Object[] array, NonValueClass v, Object o, int i) { 1928 if (v == null) { 1929 return null; 1930 } 1931 array[0] = v; 1932 array[1] = array[0]; 1933 array[2] = o; 1934 return array[i]; 1935 } 1936 1937 @Run(test = "test81") 1938 public void test81_verifier() { 1939 NonValueClass obj = new NonValueClass(rI); 1940 NonValueClass[] array1 = new NonValueClass[3]; 1941 Object[] array2 = new Object[3]; 1942 Object result = test81(array1, obj, obj, 0); 1943 Asserts.assertEquals(array1[0], obj); 1944 Asserts.assertEquals(array1[1], obj); 1945 Asserts.assertEquals(array1[2], obj); 1946 Asserts.assertEquals(result, obj); 1947 result = test81(array2, obj, obj, 1); 1948 Asserts.assertEquals(array2[0], obj); 1949 Asserts.assertEquals(array2[1], obj); 1950 Asserts.assertEquals(array2[2], obj); 1951 Asserts.assertEquals(result, obj); 1952 } 1953 1954 // Verify that writing an object of a non-flattenable value class to an array marks the array as not-flat 1955 @Test 1956 @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, 1957 failOn = {ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE}) 1958 @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, 1959 failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE}) 1960 public Object test82(Object[] array, NotFlattenable vt, Object o, int i) { 1961 array[0] = vt; 1962 array[1] = array[0]; 1963 array[2] = o; 1964 return array[i]; 1965 } 1966 1967 @Run(test = "test82") 1968 public void test82_verifier() { 1969 NotFlattenable vt = new NotFlattenable(); 1970 NotFlattenable[] array1 = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 3); 1971 Object[] array2 = new Object[3]; 1972 Object result = test82(array1, vt, vt, 0); 1973 Asserts.assertEquals(array1[0], vt); 1974 Asserts.assertEquals(array1[1], vt); 1975 Asserts.assertEquals(array1[2], vt); 1976 Asserts.assertEquals(result, vt); 1977 result = test82(array2, vt, vt, 1); 1978 Asserts.assertEquals(array2[0], vt); 1979 Asserts.assertEquals(array2[1], vt); 1980 Asserts.assertEquals(array2[2], vt); 1981 Asserts.assertEquals(result, vt); 1982 } 1983 1984 // Verify that casting an array element to a non-value class type type marks the array as not-null-free and not-flat 1985 @Test 1986 @IR(applyIf = {"UseArrayFlattening", "true"}, 1987 counts = {LOAD_UNKNOWN_INLINE, "= 1"}, 1988 failOn = {ALLOCA_G, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}) 1989 @IR(applyIf = {"UseArrayFlattening", "false"}, 1990 failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}) 1991 public void test83(Object[] array, Object o) { 1992 NonValueClass i = (NonValueClass)array[0]; 1993 array[1] = o; 1994 } 1995 1996 @Run(test = "test83") 1997 public void test83_verifier() { 1998 NonValueClass obj = new NonValueClass(rI); 1999 NonValueClass[] array1 = new NonValueClass[2]; 2000 Object[] array2 = new Object[2]; 2001 test83(array1, obj); 2002 Asserts.assertEquals(array1[1], obj); 2003 test83(array2, null); 2004 Asserts.assertEquals(array2[1], null); 2005 } 2006 2007 // Verify that writing constant null into an array marks the array as not-null-free and not-flat 2008 @Test 2009 @IR(failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE}, 2010 counts = {INLINE_ARRAY_NULL_GUARD, "= 1"}) 2011 public Object test84(Object[] array, int i) { 2012 array[0] = null; 2013 array[1] = null; 2014 return array[i]; 2015 } 2016 2017 @Run(test = "test84") 2018 public void test84_verifier(RunInfo info) { 2019 NotFlattenable[] array1 = new NotFlattenable[2]; 2020 Object[] array2 = new Object[2]; 2021 Object result = test84(array1, 0); 2022 Asserts.assertEquals(array1[0], null); 2023 Asserts.assertEquals(result, null); 2024 result = test84(array2, 1); 2025 Asserts.assertEquals(array2[0], null); 2026 Asserts.assertEquals(result, null); 2027 if (!info.isWarmUp()) { 2028 NotFlattenable[] array3 = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 2); 2029 try { 2030 test84(array3, 1); 2031 throw new RuntimeException("Should throw NullPointerException"); 2032 } catch (NullPointerException e) { 2033 // Expected 2034 } 2035 } 2036 } 2037 2038 // Same as test84 but with branches 2039 @Test 2040 @IR(failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE}, 2041 counts = {INLINE_ARRAY_NULL_GUARD, "= 2"}) 2042 public void test85(Object[] array, Object o, boolean b) { 2043 if (b) { 2044 array[0] = null; 2045 } else { 2046 array[1] = null; 2047 } 2048 array[1] = o; 2049 } 2050 2051 @Run(test = "test85") 2052 public void test85_verifier(RunInfo info) { 2053 NonValueClass obj = new NonValueClass(rI); 2054 NonValueClass[] array1 = new NonValueClass[2]; 2055 Object[] array2 = new Object[2]; 2056 test85(array1, obj, true); 2057 Asserts.assertEquals(array1[1], obj); 2058 test85(array1, null, false); 2059 Asserts.assertEquals(array1[1], null); 2060 test85(array2, obj, true); 2061 Asserts.assertEquals(array2[1], obj); 2062 test85(array2, null, false); 2063 Asserts.assertEquals(array2[1], null); 2064 if (!info.isWarmUp()) { 2065 NotFlattenable[] array3 = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 2); 2066 try { 2067 test85(array3, null, true); 2068 throw new RuntimeException("Should throw NullPointerException"); 2069 } catch (NullPointerException e) { 2070 // Expected 2071 } 2072 } 2073 } 2074 2075 // Same as test85 but with not-flattenable value class array 2076 @Test 2077 @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, 2078 failOn = {ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE}, 2079 counts = {INLINE_ARRAY_NULL_GUARD, "= 2", ALLOC_G, "= 1"}) 2080 @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, 2081 failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE}, 2082 counts = {INLINE_ARRAY_NULL_GUARD, "= 2"}) 2083 public void test86(NotFlattenable[] array, NotFlattenable o, boolean b) { 2084 if (b) { 2085 array[0] = null; 2086 } else { 2087 array[1] = null; 2088 } 2089 array[1] = o; 2090 } 2091 2092 @Run(test = "test86") 2093 public void test86_verifier(RunInfo info) { 2094 NotFlattenable vt = new NotFlattenable(); 2095 NotFlattenable[] array1 = new NotFlattenable[2]; 2096 test86(array1, vt, true); 2097 Asserts.assertEquals(array1[1], vt); 2098 test86(array1, null, false); 2099 Asserts.assertEquals(array1[1], null); 2100 if (!info.isWarmUp()) { 2101 NotFlattenable[] array2 = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 2); 2102 try { 2103 test86(array2, null, true); 2104 throw new RuntimeException("Should throw NullPointerException"); 2105 } catch (NullPointerException e) { 2106 // Expected 2107 } 2108 } 2109 } 2110 2111 // Same as test85 but with value class array 2112 @Test 2113 @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, 2114 failOn = {ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE}, 2115 counts = {INLINE_ARRAY_NULL_GUARD, "= 2", ALLOC_G, "= 1"}) 2116 @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, 2117 failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE}, 2118 counts = {INLINE_ARRAY_NULL_GUARD, "= 2"}) 2119 public void test87(MyValue1[] array, MyValue1 o, boolean b) { 2120 if (b) { 2121 array[0] = null; 2122 } else { 2123 array[1] = null; 2124 } 2125 array[1] = o; 2126 } 2127 2128 @Run(test = "test87") 2129 public void test87_verifier(RunInfo info) { 2130 MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); 2131 MyValue1[] array1 = new MyValue1[2]; 2132 test87(array1, vt, true); 2133 Asserts.assertEquals(array1[1], vt); 2134 test87(array1, null, false); 2135 Asserts.assertEquals(array1[1], null); 2136 if (!info.isWarmUp()) { 2137 MyValue1[] array2 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2); 2138 try { 2139 test87(array2, null, true); 2140 throw new RuntimeException("Should throw NullPointerException"); 2141 } catch (NullPointerException e) { 2142 // Expected 2143 } 2144 } 2145 } 2146 2147 // Additional correctness tests to make sure we have the required null checks 2148 @Test 2149 public void test88(Object[] array, NonValueClass v) { 2150 array[0] = v; 2151 } 2152 2153 @Run(test = "test88") 2154 public void test88_verifier(RunInfo info) { 2155 NonValueClass[] array1 = new NonValueClass[1]; 2156 Object[] array2 = new Object[1]; 2157 test88(array1, null); 2158 Asserts.assertEquals(array1[0], null); 2159 test88(array2, null); 2160 Asserts.assertEquals(array2[0], null); 2161 if (!info.isWarmUp()) { 2162 MyValue1[] array3 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 2163 try { 2164 test88(array3, null); 2165 throw new RuntimeException("Should throw NullPointerException"); 2166 } catch (NullPointerException e) { 2167 // Expected 2168 } 2169 } 2170 } 2171 2172 @Test 2173 public void test89(MyValue1[] array, NonValueClass v) { 2174 Object o = v; 2175 array[0] = (MyValue1)o; 2176 } 2177 2178 @Run(test = "test89") 2179 public void test89_verifier(RunInfo info) { 2180 MyValue1[] array1 = new MyValue1[1]; 2181 test89(array1, null); 2182 Asserts.assertEquals(array1[0], null); 2183 if (!info.isWarmUp()) { 2184 MyValue1[] array2 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 2185 try { 2186 test89(array2, null); 2187 throw new RuntimeException("Should throw NullPointerException"); 2188 } catch (NullPointerException e) { 2189 // Expected 2190 } 2191 } 2192 } 2193 2194 @Test 2195 public boolean test90() { 2196 boolean b = true; 2197 2198 MyValue1[] qArray = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 0); 2199 MyValue1[] lArray = new MyValue1[0]; 2200 2201 b = b && (qArray instanceof MyValue1[]); 2202 b = b && (lArray instanceof MyValue1[]); 2203 2204 MyValue1[][] qArray2 = { (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 0) }; 2205 MyValue1[][] lArray2 = new MyValue1[0][0]; 2206 2207 b = b && (qArray2 instanceof MyValue1[][]); 2208 b = b && (lArray2 instanceof MyValue1[][]); 2209 2210 return b; 2211 } 2212 2213 @Run(test = "test90") 2214 public void test90_verifier() { 2215 Asserts.assertEQ(test90(), true); 2216 } 2217 2218 @ImplicitlyConstructible 2219 @LooselyConsistentValue 2220 static value class Test91Value { 2221 public int f0; 2222 public int f1; 2223 public int f2; 2224 public int f3; 2225 public int f4; 2226 public int f5; 2227 2228 public Test91Value(int i) { 2229 this.f0 = i; 2230 this.f1 = i; 2231 this.f2 = i; 2232 this.f3 = i; 2233 this.f4 = i; 2234 this.f5 = i; 2235 } 2236 2237 public void verify() { 2238 if ((f0 != f1) || (f1 != f2) || (f2 != f3) || (f3 != f4) || (f4 != f5)) { 2239 throw new RuntimeException("test91 failed"); 2240 } 2241 } 2242 } 2243 2244 // Test anti-dependencies between loads and stores from flattened array 2245 @Test 2246 public int test91(Test91Value[] array, int lo, int val) { 2247 int i = 3; 2248 while (lo < i) { 2249 Test91Value tmp = array[lo]; 2250 array[lo++] = array[i]; 2251 array[i--] = tmp; 2252 } 2253 return val; 2254 } 2255 2256 @Run(test = "test91") 2257 @Warmup(0) 2258 public void test91_verifier() { 2259 Test91Value[] array = (Test91Value[])ValueClass.newNullRestrictedArray(Test91Value.class, 5); 2260 for (int i = 0; i < 5; ++i) { 2261 array[i] = new Test91Value(i); 2262 array[i].verify(); 2263 } 2264 Asserts.assertEQ(test91(array, 0, 5), 5); 2265 for (int i = 0; i < 5; ++i) { 2266 array[i].verify(); 2267 } 2268 } 2269 2270 @Test 2271 public void test92(Object[] src, Object[] dst) { 2272 System.arraycopy(src, 0, dst, 0, src.length); 2273 } 2274 2275 @Run(test = "test92") 2276 public void test92_verifier() { 2277 MyValue1[] a = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 2278 MyValue1[] b = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 2279 try { 2280 test92(a, null); 2281 throw new RuntimeException("Should throw NullPointerException"); 2282 } catch (NullPointerException expected) {} 2283 2284 try { 2285 test92(null, b); 2286 throw new RuntimeException("Should throw NullPointerException"); 2287 } catch (NullPointerException expected) {} 2288 2289 a[0] = MyValue1.createWithFieldsInline(rI, rL); 2290 test92(a, b); 2291 verify(a, b); 2292 } 2293 2294 // Same as test30 but accessing all elements of the non-escaping array 2295 @Test 2296 public long test93(MyValue2[] src, boolean flag) { 2297 MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 10); 2298 System.arraycopy(src, 0, dst, 0, 10); 2299 if (flag) { } 2300 return dst[0].hash() + dst[1].hash() + dst[2].hash() + dst[3].hash() + dst[4].hash() + 2301 dst[5].hash() + dst[6].hash() + dst[7].hash() + dst[8].hash() + dst[9].hash(); 2302 } 2303 2304 @Run(test = "test93") 2305 @Warmup(10000) 2306 public void test93_verifier(RunInfo info) { 2307 MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 10); 2308 for (int i = 0; i < 10; ++i) { 2309 src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); 2310 } 2311 long res = test93(src, !info.isWarmUp()); 2312 long expected = 0; 2313 for (int i = 0; i < 10; ++i) { 2314 expected += src[i].hash(); 2315 } 2316 Asserts.assertEQ(res, expected); 2317 } 2318 2319 // Same as test93 but with variable source array offset 2320 @Test 2321 public long test94(MyValue2[] src, int i, boolean flag) { 2322 MyValue2[] dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 10); 2323 System.arraycopy(src, i, dst, 0, 1); 2324 if (flag) { } 2325 return dst[0].hash() + dst[1].hash() + dst[2].hash() + dst[3].hash() + dst[4].hash() + 2326 dst[5].hash() + dst[6].hash() + dst[7].hash() + dst[8].hash() + dst[9].hash(); 2327 } 2328 2329 @Run(test = "test94") 2330 @Warmup(10000) 2331 public void test94_verifier(RunInfo info) { 2332 MyValue2[] src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 10); 2333 for (int i = 0; i < 10; ++i) { 2334 src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); 2335 } 2336 for (int i = 0; i < 10; ++i) { 2337 long res = test94(src, i, !info.isWarmUp()); 2338 long expected = src[i].hash() + 9*MyValue2.createDefaultInline().hash(); 2339 Asserts.assertEQ(res, expected); 2340 } 2341 } 2342 2343 static final MyValue1[] nullFreeArray = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 2344 2345 // Test propagation of not null-free/flat information 2346 @Test 2347 @IR(failOn = IRNode.SUBTYPE_CHECK) 2348 public MyValue1[] test95(Object[] array) { 2349 array[0] = null; 2350 // Always throws a ClassCastException because we just successfully 2351 // stored null and therefore the array can't be a null-free value class array. 2352 return nullFreeArray.getClass().cast(array); 2353 } 2354 2355 @Run(test = "test95") 2356 public void test95_verifier() { 2357 MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 2358 NonValueClass[] array2 = new NonValueClass[1]; 2359 try { 2360 test95(array1); 2361 throw new RuntimeException("Should throw NullPointerException"); 2362 } catch (NullPointerException e) { 2363 // Expected 2364 } 2365 try { 2366 test95(array2); 2367 throw new RuntimeException("Should throw ClassCastException"); 2368 } catch (ClassCastException e) { 2369 // Expected 2370 } 2371 } 2372 2373 // Same as test95 but with cmp user of cast result 2374 @Test 2375 @IR(failOn = IRNode.SUBTYPE_CHECK) 2376 public boolean test96(Object[] array) { 2377 array[0] = null; 2378 // Always throws a ClassCastException because we just successfully 2379 // stored null and therefore the array can't be a null-free value class array. 2380 MyValue1[] casted = nullFreeArray.getClass().cast(array); 2381 return casted != null; 2382 } 2383 2384 @Run(test = "test96") 2385 public void test96_verifier() { 2386 MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 2387 NonValueClass[] array2 = new NonValueClass[1]; 2388 try { 2389 test96(array1); 2390 throw new RuntimeException("Should throw NullPointerException"); 2391 } catch (NullPointerException e) { 2392 // Expected 2393 } 2394 try { 2395 test96(array2); 2396 throw new RuntimeException("Should throw ClassCastException"); 2397 } catch (ClassCastException e) { 2398 // Expected 2399 } 2400 } 2401 2402 // Same as test95 but with instanceof instead of cast 2403 @Test 2404 @IR(applyIf = {"MonomorphicArrayCheck", "true"}, failOn = IRNode.SUBTYPE_CHECK) 2405 public boolean test97(Object[] array) { 2406 // When calling this with array = MyValue1[], we will already throw an ArrayStoreException here. 2407 array[0] = new NonValueClass(42); 2408 // Always returns false because we just successfully stored a non-value object and therefore the array can't 2409 // be a value class array. 2410 return array instanceof MyValue1[]; 2411 } 2412 2413 @Run(test = "test97") 2414 public void test97_verifier(RunInfo runInfo) { 2415 MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 2416 NonValueClass[] array2 = new NonValueClass[1]; 2417 // When emitting the array store check "NonValueClass <: Object[]" for "array[0] = new NonValueClass(42)" in 2418 // test97(), we speculatively assume that Object[] is exact and emit such a check with an uncommon trap before 2419 // the array store check at the same bci. We propagate that information with an additional CheckCastPP node 2420 // feeding into the array store sub type check. 2421 // At runtime, we will hit the ArrayStoreException in the first execution when array is a MyValue1[]. 2422 // With the default IR framework warm-up, we will profile the ArrayStoreException in the interpreter and 2423 // pass it in the MDO to the C2 compiler which treats these exceptions as traps being hit (see 2424 // InterpreterRuntime::create_klass_exception). As a result, C2 is not able to speculatively cast the array of 2425 // type Object[] to an exact type before the first sub type check because we've seen too many traps being taken 2426 // at that bci due to the ArrayStoreException that was hit at the very same bci (see Compile::too_many_traps() 2427 // which checks that zero traps have been taken so far). Thus, neither the first sub type check for the array 2428 // check cast nor the second sub type check for the instanceof can be removed. 2429 // By not executing test97() with MyValue1[] during warm-up, which would trigger the ArrayStoreException, 2430 // we will not observe an ArrayStoreException before C2 compilation. Note that C2 also requires 2431 // MonomorphicArrayCheck in order to emit the speculative exactness check. 2432 // The same is required for test98-100(). 2433 if (!runInfo.isWarmUp()) { 2434 try { 2435 test97(array1); 2436 throw new RuntimeException("Should throw ArrayStoreException"); 2437 } catch (ArrayStoreException e) { 2438 // Expected 2439 } 2440 } 2441 boolean res = test97(array2); 2442 Asserts.assertFalse(res); 2443 } 2444 2445 // Same as test95 but with non-flattenable store 2446 @Test 2447 @IR(applyIfAnd = {"UseArrayFlattening", "true", "MonomorphicArrayCheck", "true"}, 2448 failOn = IRNode.SUBTYPE_CHECK) 2449 public MyValue1[] test98(Object[] array) { 2450 // When calling this with array = MyValue1[], we will already throw an ArrayStoreException here. 2451 array[0] = new NotFlattenable(); 2452 // Always throws a ClassCastException because we just successfully stored a 2453 // non-flattenable value and therefore the array can't be a flat array. 2454 return (MyValue1[])array; 2455 } 2456 2457 @Run(test = "test98") 2458 public void test98_verifier(RunInfo runInfo) { 2459 MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 2460 NotFlattenable[] array2 = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 1); 2461 if (!runInfo.isWarmUp()) { // See test97() for the reason why we need this. 2462 try { 2463 test98(array1); 2464 throw new RuntimeException("Should throw ArrayStoreException"); 2465 } catch (ArrayStoreException e) { 2466 // Expected 2467 } 2468 } 2469 try { 2470 test98(array2); 2471 throw new RuntimeException("Should throw ClassCastException"); 2472 } catch (ClassCastException e) { 2473 // Expected 2474 } 2475 } 2476 2477 // Same as test98 but with cmp user of cast result 2478 @Test 2479 @IR(applyIfAnd = {"UseArrayFlattening", "true", "MonomorphicArrayCheck", "true"}, 2480 failOn = IRNode.SUBTYPE_CHECK) 2481 public boolean test99(Object[] array) { 2482 // When calling this with array = MyValue1[], we will already throw an ArrayStoreException here. 2483 array[0] = new NotFlattenable(); 2484 // Always throws a ClassCastException because we just successfully stored a 2485 // non-flattenable value and therefore the array can't be a flat array. 2486 MyValue1[] casted = (MyValue1[])array; 2487 return casted != null; 2488 } 2489 2490 @Run(test = "test99") 2491 public void test99_verifier(RunInfo runInfo) { 2492 MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 2493 NotFlattenable[] array2 = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 1); 2494 if (!runInfo.isWarmUp()) { // See test97() for the reason why we need this. 2495 try { 2496 test99(array1); 2497 throw new RuntimeException("Should throw ArrayStoreException"); 2498 } catch (ArrayStoreException e) { 2499 // Expected 2500 } 2501 } 2502 try { 2503 test99(array2); 2504 throw new RuntimeException("Should throw ClassCastException"); 2505 } catch (ClassCastException e) { 2506 // Expected 2507 } 2508 } 2509 2510 // Same as test98 but with instanceof instead of cast 2511 @Test 2512 @IR(applyIfAnd = {"UseArrayFlattening", "true", "MonomorphicArrayCheck", "true"}, 2513 failOn = IRNode.SUBTYPE_CHECK) 2514 public boolean test100(Object[] array) { 2515 // When calling this with array = MyValue1[], we will already throw an ArrayStoreException here. 2516 array[0] = new NotFlattenable(); 2517 // Always throws a ClassCastException because we just successfully stored a 2518 // non-flattenable value and therefore the array can't be a flat array. 2519 return array instanceof MyValue1[]; 2520 } 2521 2522 @Run(test = "test100") 2523 public void test100_verifier(RunInfo runInfo) { 2524 MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 2525 NotFlattenable[] array2 = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 1); 2526 if (!runInfo.isWarmUp()) { // See test97() for the reason why we need this. 2527 try { 2528 test100(array1); 2529 throw new RuntimeException("Should throw ArrayStoreException"); 2530 } catch (ArrayStoreException e) { 2531 // Expected 2532 } 2533 } 2534 boolean res = test100(array2); 2535 Asserts.assertFalse(res); 2536 } 2537 2538 // Test that SUBTYPE_CHECK matching works as expected 2539 @Test 2540 @IR(counts = { IRNode.SUBTYPE_CHECK, "1" }) 2541 public boolean test101(Object[] array) { 2542 return array instanceof MyValue1[]; 2543 } 2544 2545 @Run(test = "test101") 2546 public void test101_verifier() { 2547 MyValue1[] array1 = new MyValue1[1]; 2548 NotFlattenable[] array2 = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 1); 2549 MyValue1[] array3 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 2550 Asserts.assertTrue(test101(array1)); 2551 Asserts.assertFalse(test101(array2)); 2552 Asserts.assertTrue(test101(array3)); 2553 } 2554 2555 // Test that SUBTYPE_CHECK matching works as expected with null-free arrays 2556 @Test 2557 @IR(counts = { IRNode.SUBTYPE_CHECK, "1" }) 2558 public Object test101NullFree(Object[] array) { 2559 return nullFreeArray.getClass().cast(array); 2560 } 2561 2562 @Run(test = "test101NullFree") 2563 public void test101NullFree_verifier() { 2564 MyValue1[] array1 = new MyValue1[1]; 2565 NotFlattenable[] array2 = (NotFlattenable[])ValueClass.newNullRestrictedArray(NotFlattenable.class, 1); 2566 MyValue1[] array3 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 2567 try { 2568 test101NullFree(array1); 2569 throw new RuntimeException("Should throw ClassCastException"); 2570 } catch (ClassCastException e) { 2571 // Expected 2572 } 2573 try { 2574 test101NullFree(array2); 2575 throw new RuntimeException("Should throw ClassCastException"); 2576 } catch (ClassCastException e) { 2577 // Expected 2578 } 2579 test101NullFree(array3); 2580 } 2581 2582 static final MyValue2[] val_src = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 8); 2583 static final MyValue2[] val_dst = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 8); 2584 static final Object[] obj_src = new Object[8]; 2585 static final Object[] obj_null_src = new Object[8]; 2586 static final Object[] obj_dst = new Object[8]; 2587 2588 @ForceInline 2589 static Object get_val_src() { return val_src; } 2590 @ForceInline 2591 static Object get_val_dst() { return val_dst; } 2592 @ForceInline 2593 static Class get_val_class() { return val_src.getClass(); } 2594 @ForceInline 2595 static Class get_non_val_class() { return NonValueClass[].class; } 2596 @ForceInline 2597 static Object get_obj_src() { return obj_src; } 2598 @ForceInline 2599 static Object get_obj_null_src() { return obj_null_src; } 2600 @ForceInline 2601 static Object get_obj_dst() { return obj_dst; } 2602 @ForceInline 2603 static Class get_obj_class() { return Object[].class; } 2604 2605 static { 2606 for (int i = 0; i < 8; ++i) { 2607 val_src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); 2608 obj_src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); 2609 obj_null_src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); 2610 } 2611 obj_null_src[0] = null; 2612 } 2613 2614 // Arraycopy with constant source and destination arrays 2615 @Test 2616 @IR(applyIf = {"UseArrayFlattening", "true"}, 2617 counts = {INTRINSIC_SLOW_PATH, "= 1"}) 2618 @IR(applyIf = {"UseArrayFlattening", "false"}, 2619 failOn = INTRINSIC_SLOW_PATH) 2620 public void test102() { 2621 System.arraycopy(val_src, 0, obj_dst, 0, 8); 2622 } 2623 2624 @Run(test = "test102") 2625 public void test102_verifier() { 2626 test102(); 2627 verify(val_src, obj_dst); 2628 } 2629 2630 // Same as test102 but with MyValue2[] dst 2631 @Test 2632 @IR(failOn = INTRINSIC_SLOW_PATH) 2633 public void test103() { 2634 System.arraycopy(val_src, 0, val_dst, 0, 8); 2635 } 2636 2637 @Run(test = "test103") 2638 public void test103_verifier() { 2639 test103(); 2640 verify(val_src, val_dst); 2641 } 2642 2643 // Same as test102 but with Object[] src 2644 @Test 2645 @IR(failOn = INTRINSIC_SLOW_PATH) 2646 public void test104() { 2647 System.arraycopy(obj_src, 0, obj_dst, 0, 8); 2648 } 2649 2650 @Run(test = "test104") 2651 public void test104_verifier() { 2652 test104(); 2653 verify(obj_src, obj_dst); 2654 } 2655 2656 // Same as test103 but with Object[] src 2657 @Test 2658 @IR(counts = {INTRINSIC_SLOW_PATH, "= 1"}) 2659 public void test105() { 2660 System.arraycopy(obj_src, 0, val_dst, 0, 8); 2661 } 2662 2663 @Run(test = "test105") 2664 public void test105_verifier() { 2665 test105(); 2666 verify(obj_src, val_dst); 2667 } 2668 2669 // Same as test103 but with Object[] src containing null 2670 @Test 2671 @IR(counts = {INTRINSIC_SLOW_PATH, "= 1"}) 2672 public void test105_null() { 2673 System.arraycopy(obj_null_src, 0, val_dst, 0, 8); 2674 } 2675 2676 @Run(test = "test105_null") 2677 public void test105_null_verifier() { 2678 try { 2679 test105_null(); 2680 throw new RuntimeException("NullPointerException expected"); 2681 } catch (NullPointerException e) { 2682 // expected 2683 } 2684 } 2685 2686 // Below tests are equal to test102-test105 but hide the src/dst types until 2687 // after the arraycopy intrinsic is emitted (with incremental inlining). 2688 @Test 2689 @IR(applyIf = {"UseArrayFlattening", "true"}, 2690 counts = {INTRINSIC_SLOW_PATH, "= 1"}) 2691 @IR(applyIf = {"UseArrayFlattening", "false"}, 2692 failOn = INTRINSIC_SLOW_PATH) 2693 public void test106() { 2694 System.arraycopy(get_val_src(), 0, get_obj_dst(), 0, 8); 2695 } 2696 2697 @Run(test = "test106") 2698 public void test106_verifier() { 2699 test106(); 2700 verify(val_src, obj_dst); 2701 } 2702 2703 // TODO 8251971: Should be optimized but we are bailing out because 2704 // at parse time it looks as if src could be flat and dst could be not flat. 2705 @Test 2706 @IR(applyIf = {"UseArrayFlattening", "false"}, 2707 failOn = INTRINSIC_SLOW_PATH) 2708 public void test107() { 2709 System.arraycopy(get_val_src(), 0, get_val_dst(), 0, 8); 2710 } 2711 2712 @Run(test = "test107") 2713 public void test107_verifier() { 2714 test107(); 2715 verify(val_src, val_dst); 2716 } 2717 2718 @Test 2719 @IR(failOn = INTRINSIC_SLOW_PATH) 2720 public void test108() { 2721 System.arraycopy(get_obj_src(), 0, get_obj_dst(), 0, 8); 2722 } 2723 2724 @Run(test = "test108") 2725 public void test108_verifier() { 2726 test108(); 2727 verify(obj_src, obj_dst); 2728 } 2729 2730 @Test 2731 @IR(counts = {INTRINSIC_SLOW_PATH, "= 1"}) 2732 public void test109() { 2733 System.arraycopy(get_obj_src(), 0, get_val_dst(), 0, 8); 2734 } 2735 2736 @Run(test = "test109") 2737 public void test109_verifier() { 2738 test109(); 2739 verify(obj_src, val_dst); 2740 } 2741 2742 @Test 2743 @IR(counts = {INTRINSIC_SLOW_PATH, "= 1"}) 2744 public void test109_null() { 2745 System.arraycopy(get_obj_null_src(), 0, get_val_dst(), 0, 8); 2746 } 2747 2748 @Run(test = "test109_null") 2749 public void test109_null_verifier() { 2750 try { 2751 test109_null(); 2752 throw new RuntimeException("NullPointerException expected"); 2753 } catch (NullPointerException e) { 2754 // expected 2755 } 2756 } 2757 2758 // Arrays.copyOf with constant source and destination arrays 2759 @Test 2760 @IR(applyIf = {"UseArrayFlattening", "true"}, 2761 counts = {INTRINSIC_SLOW_PATH, "= 1"}) 2762 @IR(applyIf = {"UseArrayFlattening", "false"}, 2763 failOn = {INTRINSIC_SLOW_PATH, CLASS_CHECK_TRAP}) 2764 public Object[] test110() { 2765 return Arrays.copyOf(val_src, 8, Object[].class); 2766 } 2767 2768 @Run(test = "test110") 2769 public void test110_verifier() { 2770 Object[] res = test110(); 2771 verify(val_src, res); 2772 } 2773 2774 // Same as test110 but with MyValue2[] dst 2775 @Test 2776 @IR(failOn = {INTRINSIC_SLOW_PATH, CLASS_CHECK_TRAP}) 2777 public Object[] test111() { 2778 return Arrays.copyOf(val_src, 8, val_src.getClass()); 2779 } 2780 2781 @Run(test = "test111") 2782 public void test111_verifier() { 2783 Object[] res = test111(); 2784 verify(val_src, res); 2785 } 2786 2787 // Same as test110 but with Object[] src 2788 @Test 2789 @IR(failOn = {INTRINSIC_SLOW_PATH, CLASS_CHECK_TRAP}) 2790 public Object[] test112() { 2791 return Arrays.copyOf(obj_src, 8, Object[].class); 2792 } 2793 2794 @Run(test = "test112") 2795 public void test112_verifier() { 2796 Object[] res = test112(); 2797 verify(obj_src, res); 2798 } 2799 2800 // Same as test111 but with Object[] src 2801 @Test 2802 @IR(counts = {CLASS_CHECK_TRAP, " = 1"}) 2803 public Object[] test113() { 2804 return Arrays.copyOf(obj_src, 8, MyValue2[].class); 2805 } 2806 2807 @Run(test = "test113") 2808 public void test113_verifier() { 2809 Object[] res = test113(); 2810 verify(obj_src, res); 2811 } 2812 2813 // Same as test111 but with Object[] src containing null 2814 @Test 2815 @IR(counts = {CLASS_CHECK_TRAP, " = 1"}) 2816 public Object[] test113_null() { 2817 return Arrays.copyOf(obj_null_src, 8, val_src.getClass()); 2818 } 2819 2820 @Run(test = "test113_null") 2821 public void test113_null_verifier() { 2822 Object[] res = test113_null(); 2823 verify(obj_null_src, res); 2824 } 2825 2826 // Below tests are equal to test110-test113 but hide the src/dst types until 2827 // after the arraycopy intrinsic is emitted (with incremental inlining). 2828 2829 @Test 2830 @IR(applyIf = {"UseArrayFlattening", "true"}, 2831 counts = {INTRINSIC_SLOW_PATH, "= 1"}) 2832 @IR(applyIf = {"UseArrayFlattening", "false"}, 2833 failOn = {INTRINSIC_SLOW_PATH, CLASS_CHECK_TRAP}) 2834 public Object[] test114() { 2835 return Arrays.copyOf((Object[])get_val_src(), 8, get_obj_class()); 2836 } 2837 2838 @Run(test = "test114") 2839 public void test114_verifier() { 2840 Object[] res = test114(); 2841 verify(val_src, res); 2842 } 2843 2844 // TODO 8251971: Should be optimized but we are bailing out because 2845 // at parse time it looks as if src could be flat and dst could be not flat 2846 @Test 2847 @IR(applyIf = {"UseArrayFlattening", "false"}, 2848 failOn = {INTRINSIC_SLOW_PATH, CLASS_CHECK_TRAP}) 2849 public Object[] test115() { 2850 return Arrays.copyOf((Object[])get_val_src(), 8, get_val_class()); 2851 } 2852 2853 @Run(test = "test115") 2854 public void test115_verifier() { 2855 Object[] res = test115(); 2856 verify(val_src, res); 2857 } 2858 2859 @Test 2860 @IR(failOn = {INTRINSIC_SLOW_PATH, CLASS_CHECK_TRAP}) 2861 public Object[] test116() { 2862 return Arrays.copyOf((Object[])get_obj_src(), 8, get_obj_class()); 2863 } 2864 2865 @Run(test = "test116") 2866 public void test116_verifier() { 2867 Object[] res = test116(); 2868 verify(obj_src, res); 2869 } 2870 2871 @Test 2872 @IR(counts = {CLASS_CHECK_TRAP, " = 1"}) 2873 public Object[] test117() { 2874 return Arrays.copyOf((Object[])get_obj_src(), 8, get_val_class()); 2875 } 2876 2877 @Run(test = "test117") 2878 public void test117_verifier() { 2879 Object[] res = test117(); 2880 verify(obj_src, res); 2881 } 2882 2883 @Test 2884 @IR(counts = {CLASS_CHECK_TRAP, " = 1"}) 2885 public Object[] test117_null() { 2886 return Arrays.copyOf((Object[])get_obj_null_src(), 8, get_val_class()); 2887 } 2888 2889 @Run(test = "test117_null") 2890 public void test117_null_verifier() { 2891 Object[] res = test117_null(); 2892 verify((Object[])get_obj_null_src(), res); 2893 } 2894 2895 // Some more Arrays.copyOf tests with only constant class 2896 2897 @Test 2898 @IR(counts = {CLASS_CHECK_TRAP, "= 1"}) 2899 // TODO JDK-8329224 2900 // failOn = INTRINSIC_SLOW_PATH) 2901 public Object[] test118(Object[] src) { 2902 return Arrays.copyOf(src, 8, val_src.getClass()); 2903 } 2904 2905 @Run(test = "test118") 2906 public void test118_verifier() { 2907 Object[] res = test118(obj_src); 2908 verify(obj_src, res); 2909 res = test118(val_src); 2910 verify(val_src, res); 2911 res = test118(obj_null_src); 2912 verify(obj_null_src, res); 2913 } 2914 2915 @Test 2916 public Object[] test119(Object[] src) { 2917 return Arrays.copyOf(src, 8, Object[].class); 2918 } 2919 2920 @Run(test = "test119") 2921 public void test119_verifier() { 2922 Object[] res = test119(obj_src); 2923 verify(obj_src, res); 2924 res = test119(val_src); 2925 verify(val_src, res); 2926 } 2927 2928 @Test 2929 @IR(counts = {CLASS_CHECK_TRAP, "= 1"}) 2930 // TODO JDK-8329224 2931 // failOn = INTRINSIC_SLOW_PATH) 2932 public Object[] test120(Object[] src) { 2933 return Arrays.copyOf(src, 8, NonValueClass[].class); 2934 } 2935 2936 @Run(test = "test120") 2937 public void test120_verifier() { 2938 NonValueClass[] arr = new NonValueClass[8]; 2939 for (int i = 0; i < 8; ++i) { 2940 arr[i] = new NonValueClass(rI + i); 2941 } 2942 Object[] res = test120(arr); 2943 verify(arr, res); 2944 try { 2945 test120(val_src); 2946 throw new RuntimeException("ArrayStoreException expected"); 2947 } catch (ArrayStoreException e) { 2948 // expected 2949 } 2950 } 2951 2952 @Test 2953 public Object[] test121(Object[] src) { 2954 return Arrays.copyOf(src, 8, val_src.getClass()); 2955 } 2956 2957 @Run(test = "test121") 2958 @Warmup(10000) // Make sure we hit too_many_traps for the src <: dst check 2959 public void test121_verifier() { 2960 Object[] res = test121(obj_src); 2961 verify(obj_src, res); 2962 res = test121(val_src); 2963 verify(val_src, res); 2964 res = test121(obj_null_src); 2965 verify(obj_null_src, res); 2966 } 2967 @Test 2968 public Object[] test122(Object[] src) { 2969 return Arrays.copyOf(src, 8, get_val_class()); 2970 } 2971 2972 @Run(test = "test122") 2973 @Warmup(10000) // Make sure we hit too_many_traps for the src <: dst check 2974 public void test122_verifier() { 2975 Object[] res = test122(obj_src); 2976 verify(obj_src, res); 2977 res = test122(val_src); 2978 verify(val_src, res); 2979 res = test122(obj_null_src); 2980 verify(obj_null_src, res); 2981 } 2982 2983 @Test 2984 public Object[] test123(Object[] src) { 2985 return Arrays.copyOf(src, 8, NonValueClass[].class); 2986 } 2987 2988 @Run(test = "test123") 2989 @Warmup(10000) // Make sure we hit too_many_traps for the src <: dst check 2990 public void test123_verifier() { 2991 NonValueClass[] arr = new NonValueClass[8]; 2992 for (int i = 0; i < 8; ++i) { 2993 arr[i] = new NonValueClass(rI + i); 2994 } 2995 Object[] res = test123(arr); 2996 verify(arr, res); 2997 try { 2998 test123(val_src); 2999 throw new RuntimeException("ArrayStoreException expected"); 3000 } catch (ArrayStoreException e) { 3001 // expected 3002 } 3003 } 3004 3005 @Test 3006 public Object[] test124(Object[] src) { 3007 return Arrays.copyOf(src, 8, get_non_val_class()); 3008 } 3009 3010 @Run(test = "test124") 3011 @Warmup(10000) // Make sure we hit too_many_traps for the src <: dst check 3012 public void test124_verifier() { 3013 NonValueClass[] arr = new NonValueClass[8]; 3014 for (int i = 0; i < 8; ++i) { 3015 arr[i] = new NonValueClass(rI + i); 3016 } 3017 Object[] res = test124(arr); 3018 verify(arr, res); 3019 try { 3020 test124(val_src); 3021 throw new RuntimeException("ArrayStoreException expected"); 3022 } catch (ArrayStoreException e) { 3023 // expected 3024 } 3025 } 3026 3027 @Test 3028 public Object[] test125(Object[] src, Class klass) { 3029 return Arrays.copyOf(src, 8, klass); 3030 } 3031 3032 @Run(test = "test125") 3033 @Warmup(10000) // Make sure we hit too_many_traps for the src <: dst check 3034 public void test125_verifier() { 3035 NonValueClass[] arr = new NonValueClass[8]; 3036 for (int i = 0; i < 8; ++i) { 3037 arr[i] = new NonValueClass(rI + i); 3038 } 3039 Object[] res = test125(arr, NonValueClass[].class); 3040 verify((Object[])arr, res); 3041 res = test125(val_src, val_src.getClass()); 3042 verify(val_src, res); 3043 res = test125(obj_src, val_src.getClass()); 3044 verify(obj_src, res); 3045 res = test125(obj_null_src, val_src.getClass()); 3046 verify(obj_null_src, res); 3047 try { 3048 test125(arr, val_src.getClass()); 3049 throw new RuntimeException("ArrayStoreException expected"); 3050 } catch (ArrayStoreException e) { 3051 // expected 3052 } 3053 try { 3054 test125(val_src, MyValue1[].class); 3055 throw new RuntimeException("ArrayStoreException expected"); 3056 } catch (ArrayStoreException e) { 3057 // expected 3058 } 3059 } 3060 3061 // Verify that clone from (flat) value class array not containing oops is always optimized. 3062 @Test 3063 @IR(applyIf = {"UseArrayFlattening", "true"}, 3064 counts = {JLONG_ARRAYCOPY, "= 1"}, 3065 failOn = {CHECKCAST_ARRAYCOPY, CLONE_INTRINSIC_SLOW_PATH}) 3066 @IR(applyIf = {"UseArrayFlattening", "false"}, 3067 failOn = CLONE_INTRINSIC_SLOW_PATH) 3068 public Object[] test126() { 3069 return val_src.clone(); 3070 } 3071 3072 @Run(test = "test126") 3073 public void test126_verifier() { 3074 Object[] res = test126(); 3075 verify(val_src, res); 3076 } 3077 3078 // Verify correctness of generic_copy stub 3079 @Test 3080 public void test127(Object src, Object dst, int len) { 3081 System.arraycopy(src, 0, dst, 0, len); 3082 } 3083 3084 @Run(test = "test127") 3085 public void test127_verifier() { 3086 test127(val_src, obj_dst, 8); 3087 verify(val_src, obj_dst); 3088 test127(val_src, val_dst, 8); 3089 verify(val_src, val_dst); 3090 test127(obj_src, val_dst, 8); 3091 verify(obj_src, val_dst); 3092 try { 3093 test127(obj_null_src, val_dst, 8); 3094 throw new RuntimeException("NullPointerException expected"); 3095 } catch (NullPointerException e) { 3096 // expected 3097 } 3098 } 3099 3100 // Verify that copyOf with known source and unknown destination class is optimized 3101 @Test 3102 @IR(applyIf = {"UseArrayFlattening", "true"}, 3103 counts = {JLONG_ARRAYCOPY, "= 1"}, 3104 failOn = CHECKCAST_ARRAYCOPY) 3105 public Object[] test128(Class klass) { 3106 return Arrays.copyOf(val_src, 8, klass); 3107 } 3108 3109 @Run(test = "test128") 3110 public void test128_verifier() { 3111 Object[] res = test128(MyValue2[].class); 3112 verify(val_src, res); 3113 res = test128(Object[].class); 3114 verify(val_src, res); 3115 try { 3116 test128(MyValue1[].class); 3117 throw new RuntimeException("ArrayStoreException expected"); 3118 } catch (ArrayStoreException e) { 3119 // expected 3120 } 3121 } 3122 3123 // Arraycopy with non-array src/dst 3124 @Test 3125 public void test129(Object src, Object dst, int len) { 3126 System.arraycopy(src, 0, dst, 0, len); 3127 } 3128 3129 @Run(test = "test129") 3130 public void test129_verifier() { 3131 try { 3132 test129(new Object(), new Object[0], 0); 3133 throw new RuntimeException("ArrayStoreException expected"); 3134 } catch (ArrayStoreException e) { 3135 // expected 3136 } 3137 try { 3138 test129(new Object[0], new Object(), 0); 3139 throw new RuntimeException("ArrayStoreException expected"); 3140 } catch (ArrayStoreException e) { 3141 // expected 3142 } 3143 } 3144 3145 @NullRestricted 3146 static final MyValueEmpty empty = new MyValueEmpty(); 3147 3148 // Empty value class array access 3149 @Test 3150 @IR(failOn = {ALLOC, ALLOCA, LOAD}) 3151 public MyValueEmpty test130(MyValueEmpty[] array) { 3152 array[0] = new MyValueEmpty(); 3153 return array[1]; 3154 } 3155 3156 @Run(test = "test130") 3157 public void test130_verifier() { 3158 MyValueEmpty[] array = (MyValueEmpty[])ValueClass.newNullRestrictedArray(MyValueEmpty.class, 2); 3159 MyValueEmpty res = test130(array); 3160 Asserts.assertEquals(array[0], empty); 3161 Asserts.assertEquals(res, empty); 3162 } 3163 3164 @ImplicitlyConstructible 3165 @LooselyConsistentValue 3166 static value class EmptyContainer { 3167 @NullRestricted 3168 MyValueEmpty empty = new MyValueEmpty(); 3169 } 3170 3171 // Empty value class container array access 3172 @Test 3173 @IR(failOn = {ALLOC, ALLOCA, LOAD}) 3174 public MyValueEmpty test131(EmptyContainer[] array) { 3175 array[0] = new EmptyContainer(); 3176 return array[1].empty; 3177 } 3178 3179 @Run(test = "test131") 3180 public void test131_verifier() { 3181 EmptyContainer[] array = (EmptyContainer[])ValueClass.newNullRestrictedArray(EmptyContainer.class, 2); 3182 MyValueEmpty res = test131(array); 3183 Asserts.assertEquals(array[0], new EmptyContainer()); 3184 Asserts.assertEquals(res, new MyValueEmpty()); 3185 } 3186 3187 // Empty value class array access with unknown array type 3188 @Test 3189 public Object test132(Object[] array) { 3190 array[0] = new MyValueEmpty(); 3191 return array[1]; 3192 } 3193 3194 @Run(test = "test132") 3195 public void test132_verifier() { 3196 Object[] array = (MyValueEmpty[])ValueClass.newNullRestrictedArray(MyValueEmpty.class, 2); 3197 Object res = test132(array); 3198 Asserts.assertEquals(array[0], empty); 3199 Asserts.assertEquals(res, empty); 3200 array = new Object[2]; 3201 res = test132(array); 3202 Asserts.assertEquals(array[0], empty); 3203 Asserts.assertEquals(res, null); 3204 } 3205 3206 // Empty value class container array access with unknown array type 3207 @Test 3208 public Object test133(Object[] array) { 3209 array[0] = new EmptyContainer(); 3210 return array[1]; 3211 } 3212 3213 @Run(test = "test133") 3214 public void test133_verifier() { 3215 EmptyContainer empty = new EmptyContainer(); 3216 Object[] array = (EmptyContainer[])ValueClass.newNullRestrictedArray(EmptyContainer.class, 2); 3217 Object res = test133(array); 3218 Asserts.assertEquals(array[0], empty); 3219 Asserts.assertEquals(res, empty); 3220 array = new Object[2]; 3221 res = test133(array); 3222 Asserts.assertEquals(array[0], empty); 3223 Asserts.assertEquals(res, null); 3224 } 3225 3226 // Non-escaping empty value class array access 3227 @Test 3228 @IR(failOn = {ALLOC, ALLOCA, LOAD, STORE}) 3229 public static MyValueEmpty test134() { 3230 MyValueEmpty[] array = new MyValueEmpty[1]; 3231 array[0] = empty; 3232 return array[0]; 3233 } 3234 3235 @Run(test = "test134") 3236 public void test134_verifier() { 3237 MyValueEmpty res = test134(); 3238 Asserts.assertEquals(res, empty); 3239 } 3240 3241 // Test accessing a locked (value class) array 3242 @Test 3243 public Object test135(Object[] array, Object val) { 3244 array[0] = val; 3245 return array[1]; 3246 } 3247 3248 @Run(test = "test135") 3249 public void test135_verifier() { 3250 MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2); 3251 array1[1] = MyValue1.createWithFieldsInline(rI, rL); 3252 synchronized (array1) { 3253 Object res = test135(array1, array1[1]); 3254 Asserts.assertEquals(((MyValue1)res).hash(), array1[1].hash()); 3255 Asserts.assertEquals(array1[0].hash(), array1[1].hash()); 3256 } 3257 NonValueClass[] array2 = new NonValueClass[2]; 3258 array2[1] = new NonValueClass(rI); 3259 synchronized (array2) { 3260 Object res = test135(array2, array2[1]); 3261 Asserts.assertEquals(res, array2[1]); 3262 Asserts.assertEquals(array2[0], array2[1]); 3263 } 3264 } 3265 3266 // Same as test135 but with locking in compiled method 3267 @Test 3268 public Object test136(Object[] array, Object val) { 3269 Object res = null; 3270 synchronized (array) { 3271 array[0] = val; 3272 res = array[1]; 3273 } 3274 return res; 3275 } 3276 3277 @Run(test = "test136") 3278 public void test136_verifier() { 3279 MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2); 3280 array1[1] = MyValue1.createWithFieldsInline(rI, rL); 3281 Object res = test136(array1, array1[1]); 3282 Asserts.assertEquals(((MyValue1)res).hash(), array1[1].hash()); 3283 Asserts.assertEquals(array1[0].hash(), array1[1].hash()); 3284 NonValueClass[] array2 = new NonValueClass[2]; 3285 array2[1] = new NonValueClass(rI); 3286 res = test136(array2, array2[1]); 3287 Asserts.assertEquals(res, array2[1]); 3288 Asserts.assertEquals(array2[0], array2[1]); 3289 } 3290 3291 Object oFld1, oFld2; 3292 3293 // Test loop unwswitching with locked (value class) array accesses 3294 @Test 3295 public void test137(Object[] array1, Object[] array2) { 3296 for (int i = 0; i < array1.length; i++) { 3297 oFld1 = array1[i]; 3298 oFld2 = array2[i]; 3299 } 3300 } 3301 3302 @Run(test = "test137") 3303 public void test137_verifier() { 3304 MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 100); 3305 Arrays.fill(array1, MyValue1.createWithFieldsInline(rI, rL)); 3306 NonValueClass[] array2 = new NonValueClass[100]; 3307 Arrays.fill(array2, new NonValueClass(rI)); 3308 synchronized (array1) { 3309 test137(array1, array1); 3310 Asserts.assertEquals(oFld1, array1[0]); 3311 Asserts.assertEquals(oFld2, array1[0]); 3312 test137(array1, array2); 3313 Asserts.assertEquals(oFld1, array1[0]); 3314 Asserts.assertEquals(oFld2, array2[0]); 3315 test137(array2, array1); 3316 Asserts.assertEquals(oFld1, array2[0]); 3317 Asserts.assertEquals(oFld2, array1[0]); 3318 } 3319 synchronized (array2) { 3320 test137(array2, array2); 3321 Asserts.assertEquals(oFld1, array2[0]); 3322 Asserts.assertEquals(oFld2, array2[0]); 3323 test137(array1, array2); 3324 Asserts.assertEquals(oFld1, array1[0]); 3325 Asserts.assertEquals(oFld2, array2[0]); 3326 test137(array2, array1); 3327 Asserts.assertEquals(oFld1, array2[0]); 3328 Asserts.assertEquals(oFld2, array1[0]); 3329 } 3330 } 3331 3332 // Same as test137 but with locking in loop 3333 @Test 3334 public void test138(Object[] array1, Object[] array2) { 3335 for (int i = 0; i < array1.length; i++) { 3336 synchronized (array1) { 3337 oFld1 = array1[i]; 3338 } 3339 synchronized (array2) { 3340 oFld2 = array2[i]; 3341 } 3342 } 3343 } 3344 3345 @Run(test = "test138") 3346 public void test138_verifier() { 3347 MyValue1[] array1 = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 100); 3348 Arrays.fill(array1, MyValue1.createWithFieldsInline(rI, rL)); 3349 NonValueClass[] array2 = new NonValueClass[100]; 3350 Arrays.fill(array2, new NonValueClass(rI)); 3351 test138(array1, array1); 3352 Asserts.assertEquals(oFld1, array1[0]); 3353 Asserts.assertEquals(oFld2, array1[0]); 3354 test138(array1, array2); 3355 Asserts.assertEquals(oFld1, array1[0]); 3356 Asserts.assertEquals(oFld2, array2[0]); 3357 test138(array2, array1); 3358 Asserts.assertEquals(oFld1, array2[0]); 3359 Asserts.assertEquals(oFld2, array1[0]); 3360 test138(array2, array2); 3361 Asserts.assertEquals(oFld1, array2[0]); 3362 Asserts.assertEquals(oFld2, array2[0]); 3363 Asserts.assertEquals(oFld2, array2[0]); 3364 } 3365 3366 // Test load from array that is only known to be not a value class array after parsing 3367 @Test 3368 @IR(failOn = {ALLOC_G, ALLOCA_G, LOOP, LOAD, STORE, TRAP, LOAD_UNKNOWN_INLINE, 3369 STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}) 3370 public Object test139() { 3371 Object[] array = null; 3372 Object[] oarray = new NonValueClass[1]; 3373 Object[] varray = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 3374 for (int i = 0; i < 10; i++) { 3375 array = varray; 3376 varray = oarray; 3377 } 3378 return array[0]; 3379 } 3380 3381 @Run(test = "test139") 3382 public void test139_verifier() { 3383 Object res = test139(); 3384 Asserts.assertEquals(res, null); 3385 } 3386 3387 // Test store to array that is only known to be not a value class array after parsing 3388 @Test 3389 @IR(failOn = {ALLOCA, ALLOC_G, LOOP, LOAD, TRAP, 3390 LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}) 3391 public Object[] test140(Object val) { 3392 Object[] array = null; 3393 Object[] oarray = new NonValueClass[1]; 3394 Object[] varray = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 3395 for (int i = 0; i < 10; i++) { 3396 array = varray; 3397 varray = oarray; 3398 } 3399 array[0] = val; 3400 return array; 3401 } 3402 3403 @Run(test = "test140") 3404 public void test140_verifier() { 3405 NonValueClass obj = new NonValueClass(rI); 3406 Object[] res = test140(obj); 3407 Asserts.assertEquals(res[0], obj); 3408 res = test140(null); 3409 Asserts.assertEquals(res[0], null); 3410 } 3411 3412 // Test load from array that is only known to be not a value class array after parsing 3413 // TODO 8255938 3414 @Test 3415 // @IR(failOn = {ALLOC_G, ALLOCA_G, LOOP, LOAD, STORE, TRAP, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}) 3416 public Object test141() { 3417 Object[] array = null; 3418 Object[] oarray = new NonValueClass[1]; 3419 Object[] varray = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 3420 for (int i = 0; i < 10; i++) { 3421 array = oarray; 3422 oarray = varray; 3423 } 3424 return array[0]; 3425 } 3426 3427 @Run(test = "test141") 3428 public void test141_verifier() { 3429 Object res = test141(); 3430 Asserts.assertEquals(res, MyValue1.createDefaultInline()); 3431 } 3432 3433 // Test store to array that is only known to be not a value class array after parsing 3434 // TODO 8255938 3435 @Test 3436 // @IR(failOn = {ALLOCA, ALLOC_G, LOOP, LOAD, STORE, TRAP, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}) 3437 public Object[] test142(Object val) { 3438 Object[] array = null; 3439 Object[] oarray = new NonValueClass[1]; 3440 Object[] varray = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 3441 for (int i = 0; i < 10; i++) { 3442 array = oarray; 3443 oarray = varray; 3444 } 3445 array[0] = val; 3446 return array; 3447 } 3448 3449 @Run(test = "test142") 3450 public void test142_verifier(RunInfo info) { 3451 Object[] res = test142(MyValue1.createDefaultInline()); 3452 Asserts.assertEquals(res[0], MyValue1.createDefaultInline()); 3453 if (!info.isWarmUp()) { 3454 try { 3455 test142(null); 3456 throw new RuntimeException("Should throw NullPointerException"); 3457 } catch (NullPointerException e) { 3458 // Expected 3459 } 3460 } 3461 } 3462 3463 static interface MyInterface143 { 3464 public int hash(); 3465 } 3466 3467 static class MyObject143 implements MyInterface143 { 3468 public int hash() { return 42; } 3469 } 3470 3471 volatile MyInterface143[] array143 = new MyObject143[1]; 3472 int len143 = 0; 3473 3474 volatile int vf = 0; 3475 3476 // Test that triggers an anti dependency failure when array mark word is loaded from immutable memory 3477 @Test 3478 public void test143() { 3479 MyInterface143[] arr = array143; 3480 int tmp = arr.length; 3481 for (int i = 0; i < len143; i++) { 3482 if (arr[i].hash() > 0) { 3483 return; 3484 } 3485 } 3486 } 3487 3488 @Run(test = "test143") 3489 @Warmup(0) 3490 public void test143_verifier() { 3491 test143(); 3492 } 3493 3494 // Same as test143 but with two flat array checks that are unswitched 3495 @Test 3496 public void test144() { 3497 MyInterface143[] arr1 = array143; 3498 MyInterface143[] arr2 = array143; 3499 int tmp1 = arr1.length; 3500 int tmp2 = arr2.length; 3501 for (int i = 0; i < len143; i++) { 3502 if (arr1[i].hash() > 0 && arr2[i].hash() > 0) { 3503 return; 3504 } 3505 } 3506 } 3507 3508 @Run(test = "test144") 3509 @Warmup(0) 3510 public void test144_verifier() { 3511 test144(); 3512 } 3513 3514 // Test that array load slow path correctly initializes non-flattened field of empty value class 3515 @Test 3516 public Object test145(Object[] array) { 3517 return array[0]; 3518 } 3519 3520 @Run(test = "test145") 3521 public void test145_verifier() { 3522 Object[] array = (EmptyContainer[])ValueClass.newNullRestrictedArray(EmptyContainer.class, 1); 3523 EmptyContainer empty = (EmptyContainer)test145(array); 3524 Asserts.assertEquals(empty, new EmptyContainer()); 3525 } 3526 3527 // Test that non-flattened array does not block scalarization 3528 @Test 3529 @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE}) 3530 public void test146(boolean b) { 3531 MyValue2 vt = MyValue2.createWithFieldsInline(rI, rD); 3532 MyValue2[] array = { vt }; 3533 if (b) { 3534 for (int i = 0; i < 10; ++i) { 3535 if (array != array) { 3536 array = null; 3537 } 3538 } 3539 } 3540 } 3541 3542 @Run(test = "test146") 3543 @Warmup(50000) 3544 public void test146_verifier() { 3545 test146(true); 3546 } 3547 3548 // Test that non-flattened array does not block scalarization 3549 @Test 3550 @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE}) 3551 public int test147(boolean deopt) { 3552 // Both vt and array should be scalarized 3553 MyValue2 vt = MyValue2.createWithFieldsInline(rI, rD); 3554 MyValue2[] array = (MyValue2[])ValueClass.newNullRestrictedArray(MyValue2.class, 1); 3555 3556 // Delay scalarization to after loop opts 3557 boolean store = false; 3558 for (int i = 0; i < 5; ++i) { 3559 if (i == 1) { 3560 store = true; 3561 } 3562 } 3563 if (store) { 3564 array[0] = vt; 3565 } 3566 3567 if (deopt) { 3568 // Uncommon trap referencing array 3569 return array[0].x + 42; 3570 } 3571 return array[0].x; 3572 } 3573 3574 @Run(test = "test147") 3575 @Warmup(50000) 3576 public void test147_verifier(RunInfo info) { 3577 int res = test147(!info.isWarmUp()); 3578 Asserts.assertEquals(res, MyValue2.createWithFieldsInline(rI, rD).x + (info.isWarmUp() ? 0 : 42)); 3579 } 3580 3581 // Test that correct basic types are used when folding field 3582 // loads from a scalar replaced array through an arraycopy. 3583 @Test 3584 public void test148(MyValue1 vt) { 3585 MyValue1[] src = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 3586 MyValue1[] dst = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 1); 3587 src[0] = vt; 3588 System.arraycopy(src, 0, dst, 0, 1); 3589 if (src[0].hash() != dst[0].hash()) { 3590 throw new RuntimeException("Unexpected hash"); 3591 } 3592 } 3593 3594 @Run(test = "test148") 3595 public void test148_verifier() { 3596 test148(MyValue1.createWithFieldsInline(rI, rL)); 3597 } 3598 3599 // Abstract class without any value class implementers 3600 static abstract class MyAbstract149 { 3601 public abstract int get(); 3602 } 3603 3604 static class TestClass149 extends MyAbstract149 { 3605 final int x; 3606 3607 public int get() { return x; }; 3608 3609 public TestClass149(int x) { 3610 this.x = x; 3611 } 3612 } 3613 3614 // Test OSR compilation with array known to be not null-free/flat 3615 @Test 3616 public int test149(MyAbstract149[] array) { 3617 int res = 0; 3618 // Trigger OSR compilation 3619 for (int i = 0; i < 10_000; ++i) { 3620 res += array[i % 10].get(); 3621 } 3622 return res; 3623 } 3624 3625 @Run(test = "test149") 3626 public void test149_verifier() { 3627 TestClass149[] array = new TestClass149[10]; 3628 for (int i = 0; i < 10; ++i) { 3629 array[i] = new TestClass149(i); 3630 } 3631 Asserts.assertEquals(test149(array), 45000); 3632 } 3633 3634 @ImplicitlyConstructible 3635 @LooselyConsistentValue 3636 static value class Test150Value { 3637 Object s = "test"; 3638 } 3639 3640 // Test that optimizing a checkcast of a load from a flat array works as expected 3641 @Test 3642 static String test150() { 3643 Test150Value[] array = (Test150Value[])ValueClass.newNullRestrictedArray(Test150Value.class, 1); 3644 array[0] = new Test150Value(); 3645 return (String)array[0].s; 3646 } 3647 }