1 /* 2 * Copyright (c) 2017, 2019, 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.valuetypes; 25 26 import jdk.test.lib.Asserts; 27 import java.lang.invoke.*; 28 import java.lang.reflect.Method; 29 import java.util.Arrays; 30 31 /* 32 * @test 33 * @summary Test value type arrays 34 * @library /testlibrary /test/lib /compiler/whitebox / 35 * @requires os.simpleArch == "x64" 36 * @compile TestArrays.java 37 * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform 38 * @run main/othervm/timeout=300 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions 39 * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI 40 * compiler.valhalla.valuetypes.ValueTypeTest 41 * compiler.valhalla.valuetypes.TestArrays 42 */ 43 public class TestArrays extends ValueTypeTest { 44 // Unlike C2, C1 intrinsics never deoptimize System.arraycopy. Instead, we fall back to 45 // a normal method invocation when encountering flattened arrays. 46 private static void assertDeoptimizedByC2(Method m) { 47 int CompLevel_none = 0, // Interpreter 48 CompLevel_simple = 1, // C1 49 CompLevel_limited_profile = 2, // C1, invocation & backedge counters 50 CompLevel_full_profile = 3, // C1, invocation & backedge counters + mdo 51 CompLevel_full_optimization = 4; // C2 or JVMCI 52 53 if (USE_COMPILER && !XCOMP && WHITE_BOX.isMethodCompiled(m, false) && 54 WHITE_BOX.getMethodCompilationLevel(m, false) >= CompLevel_full_optimization) { 55 throw new RuntimeException("Type check should have caused it to deoptimize"); 56 } 57 } 58 59 // Extra VM parameters for some test scenarios. See ValueTypeTest.getVMParameters() 60 @Override 61 public String[] getExtraVMParameters(int scenario) { 62 switch (scenario) { 63 case 3: return new String[] {"-XX:-MonomorphicArrayCheck", "-XX:ValueArrayElemMaxFlatSize=-1"}; 64 case 4: return new String[] {"-XX:-MonomorphicArrayCheck"}; 65 } 66 return null; 67 } 68 69 public static void main(String[] args) throws Throwable { 70 TestArrays test = new TestArrays(); 71 test.run(args, MyValue1.class, MyValue2.class, MyValue2Inline.class); 72 } 73 74 // Helper methods 75 76 protected long hash() { 77 return hash(rI, rL); 78 } 79 80 protected long hash(int x, long y) { 81 return MyValue1.createWithFieldsInline(x, y).hash(); 82 } 83 84 // Test value type array creation and initialization 85 @Test(valid = ValueTypeArrayFlattenOff, failOn = LOAD) 86 @Test(valid = ValueTypeArrayFlattenOn) 87 public MyValue1[] test1(int len) { 88 MyValue1[] va = new MyValue1[len]; 89 for (int i = 0; i < len; ++i) { 90 va[i] = MyValue1.createWithFieldsDontInline(rI, rL); 91 } 92 return va; 93 } 94 95 @DontCompile 96 public void test1_verifier(boolean warmup) { 97 int len = Math.abs(rI % 10); 98 MyValue1[] va = test1(len); 99 for (int i = 0; i < len; ++i) { 100 Asserts.assertEQ(va[i].hash(), hash()); 101 } 102 } 103 104 // Test creation of a value type array and element access 105 @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + STORE + TRAP) 106 public long test2() { 107 MyValue1[] va = new MyValue1[1]; 108 va[0] = MyValue1.createWithFieldsInline(rI, rL); 109 return va[0].hash(); 110 } 111 112 @DontCompile 113 public void test2_verifier(boolean warmup) { 114 long result = test2(); 115 Asserts.assertEQ(result, hash()); 116 } 117 118 // Test receiving a value type array from the interpreter, 119 // updating its elements in a loop and computing a hash. 120 @Test(failOn = ALLOCA) 121 public long test3(MyValue1[] va) { 122 long result = 0; 123 for (int i = 0; i < 10; ++i) { 124 result += va[i].hash(); 125 va[i] = MyValue1.createWithFieldsInline(rI + 1, rL + 1); 126 } 127 return result; 128 } 129 130 @DontCompile 131 public void test3_verifier(boolean warmup) { 132 MyValue1[] va = new MyValue1[10]; 133 long expected = 0; 134 for (int i = 0; i < 10; ++i) { 135 va[i] = MyValue1.createWithFieldsDontInline(rI + i, rL + i); 136 expected += va[i].hash(); 137 } 138 long result = test3(va); 139 Asserts.assertEQ(expected, result); 140 for (int i = 0; i < 10; ++i) { 141 if (va[i].hash() != hash(rI + 1, rL + 1)) { 142 Asserts.assertEQ(va[i].hash(), hash(rI + 1, rL + 1)); 143 } 144 } 145 } 146 147 // Test returning a value type array received from the interpreter 148 @Test(failOn = ALLOC + ALLOCA + LOAD + STORE + LOOP + TRAP) 149 public MyValue1[] test4(MyValue1[] va) { 150 return va; 151 } 152 153 @DontCompile 154 public void test4_verifier(boolean warmup) { 155 MyValue1[] va = new MyValue1[10]; 156 for (int i = 0; i < 10; ++i) { 157 va[i] = MyValue1.createWithFieldsDontInline(rI + i, rL + i); 158 } 159 va = test4(va); 160 for (int i = 0; i < 10; ++i) { 161 Asserts.assertEQ(va[i].hash(), hash(rI + i, rL + i)); 162 } 163 } 164 165 // Merge value type arrays created from two branches 166 @Test 167 public MyValue1[] test5(boolean b) { 168 MyValue1[] va; 169 if (b) { 170 va = new MyValue1[5]; 171 for (int i = 0; i < 5; ++i) { 172 va[i] = MyValue1.createWithFieldsInline(rI, rL); 173 } 174 } else { 175 va = new MyValue1[10]; 176 for (int i = 0; i < 10; ++i) { 177 va[i] = MyValue1.createWithFieldsInline(rI + i, rL + i); 178 } 179 } 180 long sum = va[0].hashInterpreted(); 181 if (b) { 182 va[0] = MyValue1.createWithFieldsDontInline(rI, sum); 183 } else { 184 va[0] = MyValue1.createWithFieldsDontInline(rI + 1, sum + 1); 185 } 186 return va; 187 } 188 189 @DontCompile 190 public void test5_verifier(boolean warmup) { 191 MyValue1[] va = test5(true); 192 Asserts.assertEQ(va.length, 5); 193 Asserts.assertEQ(va[0].hash(), hash(rI, hash())); 194 for (int i = 1; i < 5; ++i) { 195 Asserts.assertEQ(va[i].hash(), hash()); 196 } 197 va = test5(false); 198 Asserts.assertEQ(va.length, 10); 199 Asserts.assertEQ(va[0].hash(), hash(rI + 1, hash(rI, rL) + 1)); 200 for (int i = 1; i < 10; ++i) { 201 Asserts.assertEQ(va[i].hash(), hash(rI + i, rL + i)); 202 } 203 } 204 205 // Test creation of value type array with single element 206 @Test(failOn = ALLOCA + LOOP + LOAD + TRAP) 207 public MyValue1 test6() { 208 MyValue1[] va = new MyValue1[1]; 209 return va[0]; 210 } 211 212 @DontCompile 213 public void test6_verifier(boolean warmup) { 214 MyValue1[] va = new MyValue1[1]; 215 MyValue1 v = test6(); 216 Asserts.assertEQ(v.hashPrimitive(), va[0].hashPrimitive()); 217 } 218 219 // Test default initialization of value type arrays 220 @Test(failOn = LOAD) 221 public MyValue1[] test7(int len) { 222 return new MyValue1[len]; 223 } 224 225 @DontCompile 226 public void test7_verifier(boolean warmup) { 227 int len = Math.abs(rI % 10); 228 MyValue1[] va = new MyValue1[len]; 229 MyValue1[] var = test7(len); 230 for (int i = 0; i < len; ++i) { 231 Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive()); 232 } 233 } 234 235 // Test creation of value type array with zero length 236 @Test(failOn = ALLOC + LOAD + STORE + LOOP + TRAP) 237 public MyValue1[] test8() { 238 return new MyValue1[0]; 239 } 240 241 @DontCompile 242 public void test8_verifier(boolean warmup) { 243 MyValue1[] va = test8(); 244 Asserts.assertEQ(va.length, 0); 245 } 246 247 static MyValue1[] test9_va; 248 249 // Test that value type array loaded from field has correct type 250 @Test(failOn = LOOP) 251 public long test9() { 252 return test9_va[0].hash(); 253 } 254 255 @DontCompile 256 public void test9_verifier(boolean warmup) { 257 test9_va = new MyValue1[1]; 258 test9_va[0] = MyValue1.createWithFieldsInline(rI, rL); 259 long result = test9(); 260 Asserts.assertEQ(result, hash()); 261 } 262 263 // Multi-dimensional arrays 264 @Test 265 public MyValue1[][][] test10(int len1, int len2, int len3) { 266 MyValue1[][][] arr = new MyValue1[len1][len2][len3]; 267 for (int i = 0; i < len1; i++) { 268 for (int j = 0; j < len2; j++) { 269 for (int k = 0; k < len3; k++) { 270 arr[i][j][k] = MyValue1.createWithFieldsDontInline(rI + i , rL + j + k); 271 } 272 } 273 } 274 return arr; 275 } 276 277 @DontCompile 278 public void test10_verifier(boolean warmup) { 279 MyValue1[][][] arr = test10(2, 3, 4); 280 for (int i = 0; i < 2; i++) { 281 for (int j = 0; j < 3; j++) { 282 for (int k = 0; k < 4; k++) { 283 Asserts.assertEQ(arr[i][j][k].hash(), MyValue1.createWithFieldsDontInline(rI + i , rL + j + k).hash()); 284 } 285 } 286 } 287 } 288 289 @Test 290 public void test11(MyValue1[][][] arr, long[] res) { 291 int l = 0; 292 for (int i = 0; i < arr.length; i++) { 293 for (int j = 0; j < arr[i].length; j++) { 294 for (int k = 0; k < arr[i][j].length; k++) { 295 res[l] = arr[i][j][k].hash(); 296 l++; 297 } 298 } 299 } 300 } 301 302 @DontCompile 303 public void test11_verifier(boolean warmup) { 304 MyValue1[][][] arr = new MyValue1[2][3][4]; 305 long[] res = new long[2*3*4]; 306 long[] verif = new long[2*3*4]; 307 int l = 0; 308 for (int i = 0; i < 2; i++) { 309 for (int j = 0; j < 3; j++) { 310 for (int k = 0; k < 4; k++) { 311 arr[i][j][k] = MyValue1.createWithFieldsDontInline(rI + i, rL + j + k); 312 verif[l] = arr[i][j][k].hash(); 313 l++; 314 } 315 } 316 } 317 test11(arr, res); 318 for (int i = 0; i < verif.length; i++) { 319 Asserts.assertEQ(res[i], verif[i]); 320 } 321 } 322 323 // Array load out of bounds (upper bound) at compile time 324 @Test 325 public int test12() { 326 int arraySize = Math.abs(rI) % 10;; 327 MyValue1[] va = new MyValue1[arraySize]; 328 329 for (int i = 0; i < arraySize; i++) { 330 va[i] = MyValue1.createWithFieldsDontInline(rI + 1, rL); 331 } 332 333 try { 334 return va[arraySize + 1].x; 335 } catch (ArrayIndexOutOfBoundsException e) { 336 return rI; 337 } 338 } 339 340 public void test12_verifier(boolean warmup) { 341 Asserts.assertEQ(test12(), rI); 342 } 343 344 // Array load out of bounds (lower bound) at compile time 345 @Test 346 public int test13() { 347 int arraySize = Math.abs(rI) % 10;; 348 MyValue1[] va = new MyValue1[arraySize]; 349 350 for (int i = 0; i < arraySize; i++) { 351 va[i] = MyValue1.createWithFieldsDontInline(rI + i, rL); 352 } 353 354 try { 355 return va[-arraySize].x; 356 } catch (ArrayIndexOutOfBoundsException e) { 357 return rI; 358 } 359 } 360 361 public void test13_verifier(boolean warmup) { 362 Asserts.assertEQ(test13(), rI); 363 } 364 365 // Array load out of bound not known to compiler (both lower and upper bound) 366 @Test 367 public int test14(MyValue1[] va, int index) { 368 return va[index].x; 369 } 370 371 public void test14_verifier(boolean warmup) { 372 int arraySize = Math.abs(rI) % 10; 373 MyValue1[] va = new MyValue1[arraySize]; 374 375 for (int i = 0; i < arraySize; i++) { 376 va[i] = MyValue1.createWithFieldsDontInline(rI, rL); 377 } 378 379 int result; 380 for (int i = -20; i < 20; i++) { 381 try { 382 result = test14(va, i); 383 } catch (ArrayIndexOutOfBoundsException e) { 384 result = rI; 385 } 386 Asserts.assertEQ(result, rI); 387 } 388 } 389 390 // Array store out of bounds (upper bound) at compile time 391 @Test 392 public int test15() { 393 int arraySize = Math.abs(rI) % 10;; 394 MyValue1[] va = new MyValue1[arraySize]; 395 396 try { 397 for (int i = 0; i <= arraySize; i++) { 398 va[i] = MyValue1.createWithFieldsDontInline(rI + 1, rL); 399 } 400 return rI - 1; 401 } catch (ArrayIndexOutOfBoundsException e) { 402 return rI; 403 } 404 } 405 406 public void test15_verifier(boolean warmup) { 407 Asserts.assertEQ(test15(), rI); 408 } 409 410 // Array store out of bounds (lower bound) at compile time 411 @Test 412 public int test16() { 413 int arraySize = Math.abs(rI) % 10;; 414 MyValue1[] va = new MyValue1[arraySize]; 415 416 try { 417 for (int i = -1; i <= arraySize; i++) { 418 va[i] = MyValue1.createWithFieldsDontInline(rI + 1, rL); 419 } 420 return rI - 1; 421 } catch (ArrayIndexOutOfBoundsException e) { 422 return rI; 423 } 424 } 425 426 public void test16_verifier(boolean warmup) { 427 Asserts.assertEQ(test16(), rI); 428 } 429 430 // Array store out of bound not known to compiler (both lower and upper bound) 431 @Test 432 public int test17(MyValue1[] va, int index, MyValue1 vt) { 433 va[index] = vt; 434 return va[index].x; 435 } 436 437 @DontCompile 438 public void test17_verifier(boolean warmup) { 439 int arraySize = Math.abs(rI) % 10; 440 MyValue1[] va = new MyValue1[arraySize]; 441 442 for (int i = 0; i < arraySize; i++) { 443 va[i] = MyValue1.createWithFieldsDontInline(rI, rL); 444 } 445 446 MyValue1 vt = MyValue1.createWithFieldsDontInline(rI + 1, rL); 447 int result; 448 for (int i = -20; i < 20; i++) { 449 try { 450 result = test17(va, i, vt); 451 } catch (ArrayIndexOutOfBoundsException e) { 452 result = rI + 1; 453 } 454 Asserts.assertEQ(result, rI + 1); 455 } 456 457 for (int i = 0; i < arraySize; i++) { 458 Asserts.assertEQ(va[i].x, rI + 1); 459 } 460 } 461 462 // clone() as stub call 463 @Test 464 public MyValue1[] test18(MyValue1[] va) { 465 return va.clone(); 466 } 467 468 @DontCompile 469 public void test18_verifier(boolean warmup) { 470 int len = Math.abs(rI) % 10; 471 MyValue1[] va = new MyValue1[len]; 472 for (int i = 0; i < len; ++i) { 473 va[i] = MyValue1.createWithFieldsInline(rI, rL); 474 } 475 MyValue1[] result = test18(va); 476 for (int i = 0; i < len; ++i) { 477 Asserts.assertEQ(result[i].hash(), va[i].hash()); 478 } 479 } 480 481 // clone() as series of loads/stores 482 static MyValue1[] test19_orig = null; 483 484 @Test 485 public MyValue1[] test19() { 486 MyValue1[] va = new MyValue1[8]; 487 for (int i = 0; i < va.length; ++i) { 488 va[i] = MyValue1.createWithFieldsInline(rI, rL); 489 } 490 test19_orig = va; 491 492 return va.clone(); 493 } 494 495 @DontCompile 496 public void test19_verifier(boolean warmup) { 497 MyValue1[] result = test19(); 498 for (int i = 0; i < test19_orig.length; ++i) { 499 Asserts.assertEQ(result[i].hash(), test19_orig[i].hash()); 500 } 501 } 502 503 // arraycopy() of value type array with oop fields 504 @Test 505 public void test20(MyValue1[] src, MyValue1[] dst) { 506 System.arraycopy(src, 0, dst, 0, src.length); 507 } 508 509 @DontCompile 510 public void test20_verifier(boolean warmup) { 511 int len = Math.abs(rI) % 10; 512 MyValue1[] src = new MyValue1[len]; 513 MyValue1[] dst = new MyValue1[len]; 514 for (int i = 0; i < len; ++i) { 515 src[i] = MyValue1.createWithFieldsInline(rI, rL); 516 } 517 test20(src, dst); 518 for (int i = 0; i < len; ++i) { 519 Asserts.assertEQ(src[i].hash(), dst[i].hash()); 520 } 521 } 522 523 // arraycopy() of value type array with no oop field 524 @Test 525 public void test21(MyValue2[] src, MyValue2[] dst) { 526 System.arraycopy(src, 0, dst, 0, src.length); 527 } 528 529 @DontCompile 530 public void test21_verifier(boolean warmup) { 531 int len = Math.abs(rI) % 10; 532 MyValue2[] src = new MyValue2[len]; 533 MyValue2[] dst = new MyValue2[len]; 534 for (int i = 0; i < len; ++i) { 535 src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0); 536 } 537 test21(src, dst); 538 for (int i = 0; i < len; ++i) { 539 Asserts.assertEQ(src[i].hash(), dst[i].hash()); 540 } 541 } 542 543 // arraycopy() of value type array with oop field and tightly 544 // coupled allocation as dest 545 @Test 546 public MyValue1[] test22(MyValue1[] src) { 547 MyValue1[] dst = new MyValue1[src.length]; 548 System.arraycopy(src, 0, dst, 0, src.length); 549 return dst; 550 } 551 552 @DontCompile 553 public void test22_verifier(boolean warmup) { 554 int len = Math.abs(rI) % 10; 555 MyValue1[] src = new MyValue1[len]; 556 for (int i = 0; i < len; ++i) { 557 src[i] = MyValue1.createWithFieldsInline(rI, rL); 558 } 559 MyValue1[] dst = test22(src); 560 for (int i = 0; i < len; ++i) { 561 Asserts.assertEQ(src[i].hash(), dst[i].hash()); 562 } 563 } 564 565 // arraycopy() of value type array with oop fields and tightly 566 // coupled allocation as dest 567 @Test 568 public MyValue1[] test23(MyValue1[] src) { 569 MyValue1[] dst = new MyValue1[src.length + 10]; 570 System.arraycopy(src, 0, dst, 5, src.length); 571 return dst; 572 } 573 574 @DontCompile 575 public void test23_verifier(boolean warmup) { 576 int len = Math.abs(rI) % 10; 577 MyValue1[] src = new MyValue1[len]; 578 for (int i = 0; i < len; ++i) { 579 src[i] = MyValue1.createWithFieldsInline(rI, rL); 580 } 581 MyValue1[] dst = test23(src); 582 for (int i = 5; i < len; ++i) { 583 Asserts.assertEQ(src[i].hash(), dst[i].hash()); 584 } 585 } 586 587 // arraycopy() of value type array passed as Object 588 @Test 589 public void test24(MyValue1[] src, Object dst) { 590 System.arraycopy(src, 0, dst, 0, src.length); 591 } 592 593 @DontCompile 594 public void test24_verifier(boolean warmup) { 595 int len = Math.abs(rI) % 10; 596 MyValue1[] src = new MyValue1[len]; 597 MyValue1[] dst = new MyValue1[len]; 598 for (int i = 0; i < len; ++i) { 599 src[i] = MyValue1.createWithFieldsInline(rI, rL); 600 } 601 test24(src, dst); 602 for (int i = 0; i < len; ++i) { 603 Asserts.assertEQ(src[i].hash(), dst[i].hash()); 604 } 605 } 606 607 // short arraycopy() with no oop field 608 @Test 609 public void test25(MyValue2[] src, MyValue2[] dst) { 610 System.arraycopy(src, 0, dst, 0, 8); 611 } 612 613 @DontCompile 614 public void test25_verifier(boolean warmup) { 615 MyValue2[] src = new MyValue2[8]; 616 MyValue2[] dst = new MyValue2[8]; 617 for (int i = 0; i < 8; ++i) { 618 src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0); 619 } 620 test25(src, dst); 621 for (int i = 0; i < 8; ++i) { 622 Asserts.assertEQ(src[i].hash(), dst[i].hash()); 623 } 624 } 625 626 // short arraycopy() with oop fields 627 @Test 628 public void test26(MyValue1[] src, MyValue1[] dst) { 629 System.arraycopy(src, 0, dst, 0, 8); 630 } 631 632 @DontCompile 633 public void test26_verifier(boolean warmup) { 634 MyValue1[] src = new MyValue1[8]; 635 MyValue1[] dst = new MyValue1[8]; 636 for (int i = 0; i < 8; ++i) { 637 src[i] = MyValue1.createWithFieldsInline(rI, rL); 638 } 639 test26(src, dst); 640 for (int i = 0; i < 8; ++i) { 641 Asserts.assertEQ(src[i].hash(), dst[i].hash()); 642 } 643 } 644 645 // short arraycopy() with oop fields and offsets 646 @Test 647 public void test27(MyValue1[] src, MyValue1[] dst) { 648 System.arraycopy(src, 1, dst, 2, 6); 649 } 650 651 @DontCompile 652 public void test27_verifier(boolean warmup) { 653 MyValue1[] src = new MyValue1[8]; 654 MyValue1[] dst = new MyValue1[8]; 655 for (int i = 0; i < 8; ++i) { 656 src[i] = MyValue1.createWithFieldsInline(rI, rL); 657 } 658 test27(src, dst); 659 for (int i = 2; i < 8; ++i) { 660 Asserts.assertEQ(src[i-1].hash(), dst[i].hash()); 661 } 662 } 663 664 // non escaping allocations 665 @Test(failOn = ALLOCA + LOOP + LOAD + TRAP) 666 public MyValue2 test28() { 667 MyValue2[] src = new MyValue2[10]; 668 src[0] = MyValue2.createWithFieldsInline(rI, false); 669 MyValue2[] dst = (MyValue2[])src.clone(); 670 return dst[0]; 671 } 672 673 @DontCompile 674 public void test28_verifier(boolean warmup) { 675 MyValue2 v = MyValue2.createWithFieldsInline(rI, false); 676 MyValue2 result = test28(); 677 Asserts.assertEQ(result.hash(), v.hash()); 678 } 679 680 // non escaping allocations 681 @Test(failOn = ALLOCA + LOOP + LOAD + TRAP) 682 public MyValue2 test29(MyValue2[] src) { 683 MyValue2[] dst = new MyValue2[10]; 684 System.arraycopy(src, 0, dst, 0, 10); 685 return dst[0]; 686 } 687 688 @DontCompile 689 public void test29_verifier(boolean warmup) { 690 MyValue2[] src = new MyValue2[10]; 691 for (int i = 0; i < 10; ++i) { 692 src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0); 693 } 694 MyValue2 v = test29(src); 695 Asserts.assertEQ(src[0].hash(), v.hash()); 696 } 697 698 // non escaping allocation with uncommon trap that needs 699 // eliminated value type array element as debug info 700 @Test 701 @Warmup(10000) 702 public MyValue2 test30(MyValue2[] src, boolean flag) { 703 MyValue2[] dst = new MyValue2[10]; 704 System.arraycopy(src, 0, dst, 0, 10); 705 if (flag) { } 706 return dst[0]; 707 } 708 709 @DontCompile 710 public void test30_verifier(boolean warmup) { 711 MyValue2[] src = new MyValue2[10]; 712 for (int i = 0; i < 10; ++i) { 713 src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0); 714 } 715 MyValue2 v = test30(src, false); 716 Asserts.assertEQ(src[0].hash(), v.hash()); 717 } 718 719 // non escaping allocation with memory phi 720 @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + TRAP) 721 public long test31(boolean b, boolean deopt) { 722 MyValue2[] src = new MyValue2[1]; 723 if (b) { 724 src[0] = MyValue2.createWithFieldsInline(rI, true); 725 } else { 726 src[0] = MyValue2.createWithFieldsInline(rI, false); 727 } 728 if (deopt) { 729 // uncommon trap 730 WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test31")); 731 } 732 return src[0].hash(); 733 } 734 735 @DontCompile 736 public void test31_verifier(boolean warmup) { 737 MyValue2 v1 = MyValue2.createWithFieldsInline(rI, true); 738 long result1 = test31(true, !warmup); 739 Asserts.assertEQ(result1, v1.hash()); 740 MyValue2 v2 = MyValue2.createWithFieldsInline(rI, false); 741 long result2 = test31(false, !warmup); 742 Asserts.assertEQ(result2, v2.hash()); 743 } 744 745 // Tests with Object arrays and clone/arraycopy 746 // clone() as stub call 747 @Test 748 public Object[] test32(Object[] va) { 749 return va.clone(); 750 } 751 752 @DontCompile 753 public void test32_verifier(boolean warmup) { 754 int len = Math.abs(rI) % 10; 755 MyValue1[] va = new MyValue1[len]; 756 for (int i = 0; i < len; ++i) { 757 va[i] = MyValue1.createWithFieldsInline(rI, rL); 758 } 759 MyValue1[] result = (MyValue1[])test32(va); 760 for (int i = 0; i < len; ++i) { 761 Asserts.assertEQ(((MyValue1)result[i]).hash(), ((MyValue1)va[i]).hash()); 762 } 763 } 764 765 @Test 766 public Object[] test33(Object[] va) { 767 return va.clone(); 768 } 769 770 @DontCompile 771 public void test33_verifier(boolean warmup) { 772 int len = Math.abs(rI) % 10; 773 Object[] va = new Object[len]; 774 for (int i = 0; i < len; ++i) { 775 va[i] = MyValue1.createWithFieldsInline(rI, rL); 776 } 777 Object[] result = test33(va); 778 for (int i = 0; i < len; ++i) { 779 Asserts.assertEQ(((MyValue1)result[i]).hash(), ((MyValue1)va[i]).hash()); 780 // Check that array has correct storage properties (null-ok) 781 result[i] = null; 782 } 783 } 784 785 // clone() as series of loads/stores 786 static Object[] test34_orig = null; 787 788 @ForceInline 789 public Object[] test34_helper(boolean flag) { 790 Object[] va = null; 791 if (flag) { 792 va = new MyValue1[8]; 793 for (int i = 0; i < va.length; ++i) { 794 va[i] = MyValue1.createWithFieldsDontInline(rI, rL); 795 } 796 } else { 797 va = new Object[8]; 798 } 799 return va; 800 } 801 802 @Test 803 public Object[] test34(boolean flag) { 804 Object[] va = test34_helper(flag); 805 test34_orig = va; 806 return va.clone(); 807 } 808 809 @DontCompile 810 public void test34_verifier(boolean warmup) { 811 test34(false); 812 for (int i = 0; i < 10; i++) { // make sure we do deopt 813 Object[] result = test34(true); 814 verify(test34_orig, result); 815 // Check that array has correct storage properties (null-free) 816 try { 817 result[0] = null; 818 throw new RuntimeException("Should throw NullPointerException"); 819 } catch (NullPointerException e) { 820 // Expected 821 } 822 } 823 if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test34")) { 824 Object[] result = test34(true); 825 verify(test34_orig, result); 826 // Check that array has correct storage properties (null-free) 827 try { 828 result[0] = null; 829 throw new RuntimeException("Should throw NullPointerException"); 830 } catch (NullPointerException e) { 831 // Expected 832 } 833 } 834 } 835 836 static void verify(Object[] src, Object[] dst) { 837 for (int i = 0; i < src.length; ++i) { 838 Asserts.assertEQ(((MyInterface)src[i]).hash(), ((MyInterface)dst[i]).hash()); 839 } 840 } 841 842 static void verify(MyValue1[] src, MyValue1[] dst) { 843 for (int i = 0; i < src.length; ++i) { 844 Asserts.assertEQ(src[i].hash(), dst[i].hash()); 845 } 846 } 847 848 static void verify(MyValue1[] src, Object[] dst) { 849 for (int i = 0; i < src.length; ++i) { 850 Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash()); 851 } 852 } 853 854 static void verify(MyValue2[] src, MyValue2[] dst) { 855 for (int i = 0; i < src.length; ++i) { 856 Asserts.assertEQ(src[i].hash(), dst[i].hash()); 857 } 858 } 859 860 static void verify(MyValue2[] src, Object[] dst) { 861 for (int i = 0; i < src.length; ++i) { 862 Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash()); 863 } 864 } 865 866 static boolean compile_and_run_again_if_deoptimized(boolean warmup, String test) { 867 if (!warmup) { 868 Method m = tests.get(test); 869 if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false)) { 870 if (!ValueTypeArrayFlatten && !XCOMP) { 871 throw new RuntimeException("Unexpected deoptimization"); 872 } 873 enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION); 874 return true; 875 } 876 } 877 return false; 878 } 879 880 // arraycopy() of value type array of unknown size 881 @Test 882 public void test35(Object src, Object dst, int len) { 883 System.arraycopy(src, 0, dst, 0, len); 884 } 885 886 @DontCompile 887 public void test35_verifier(boolean warmup) { 888 int len = Math.abs(rI) % 10; 889 MyValue1[] src = new MyValue1[len]; 890 MyValue1[] dst = new MyValue1[len]; 891 for (int i = 0; i < len; ++i) { 892 src[i] = MyValue1.createWithFieldsInline(rI, rL); 893 } 894 test35(src, dst, src.length); 895 verify(src, dst); 896 if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test35")) { 897 test35(src, dst, src.length); 898 verify(src, dst); 899 } 900 } 901 902 @Test 903 public void test36(Object src, MyValue2[] dst) { 904 System.arraycopy(src, 0, dst, 0, dst.length); 905 } 906 907 @DontCompile 908 public void test36_verifier(boolean warmup) { 909 int len = Math.abs(rI) % 10; 910 MyValue2[] src = new MyValue2[len]; 911 MyValue2[] dst = new MyValue2[len]; 912 for (int i = 0; i < len; ++i) { 913 src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0); 914 } 915 test36(src, dst); 916 verify(src, dst); 917 if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test36")) { 918 test36(src, dst); 919 verify(src, dst); 920 } 921 } 922 923 @Test 924 public void test37(MyValue2[] src, Object dst) { 925 System.arraycopy(src, 0, dst, 0, src.length); 926 } 927 928 @DontCompile 929 public void test37_verifier(boolean warmup) { 930 int len = Math.abs(rI) % 10; 931 MyValue2[] src = new MyValue2[len]; 932 MyValue2[] dst = new MyValue2[len]; 933 for (int i = 0; i < len; ++i) { 934 src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0); 935 } 936 test37(src, dst); 937 verify(src, dst); 938 if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test37")) { 939 test37(src, dst); 940 verify(src, dst); 941 } 942 } 943 944 @Test 945 @Warmup(1) // Avoid early compilation 946 public void test38(Object src, MyValue2[] dst) { 947 System.arraycopy(src, 0, dst, 0, dst.length); 948 } 949 950 @DontCompile 951 public void test38_verifier(boolean warmup) { 952 int len = Math.abs(rI) % 10; 953 Object[] src = new Object[len]; 954 MyValue2[] dst = new MyValue2[len]; 955 for (int i = 0; i < len; ++i) { 956 src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0); 957 } 958 test38(src, dst); 959 verify(dst, src); 960 if (!warmup) { 961 Method m = tests.get("TestArrays::test38"); 962 assertDeoptimizedByC2(m); 963 enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION); 964 test38(src, dst); 965 verify(dst, src); 966 if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) { 967 throw new RuntimeException("unexpected deoptimization"); 968 } 969 } 970 } 971 972 @Test 973 public void test39(MyValue2[] src, Object dst) { 974 System.arraycopy(src, 0, dst, 0, src.length); 975 } 976 977 @DontCompile 978 public void test39_verifier(boolean warmup) { 979 int len = Math.abs(rI) % 10; 980 MyValue2[] src = new MyValue2[len]; 981 Object[] dst = new Object[len]; 982 for (int i = 0; i < len; ++i) { 983 src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0); 984 } 985 test39(src, dst); 986 verify(src, dst); 987 if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test39")) { 988 test39(src, dst); 989 verify(src, dst); 990 } 991 } 992 993 @Test 994 @Warmup(1) // Avoid early compilation 995 public void test40(Object[] src, Object dst) { 996 System.arraycopy(src, 0, dst, 0, src.length); 997 } 998 999 @DontCompile 1000 public void test40_verifier(boolean warmup) { 1001 int len = Math.abs(rI) % 10; 1002 Object[] src = new Object[len]; 1003 MyValue2[] dst = new MyValue2[len]; 1004 for (int i = 0; i < len; ++i) { 1005 src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0); 1006 } 1007 test40(src, dst); 1008 verify(dst, src); 1009 if (!warmup) { 1010 Method m = tests.get("TestArrays::test40"); 1011 assertDeoptimizedByC2(m); 1012 enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION); 1013 test40(src, dst); 1014 verify(dst, src); 1015 if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) { 1016 throw new RuntimeException("unexpected deoptimization"); 1017 } 1018 } 1019 } 1020 1021 @Test 1022 public void test41(Object src, Object[] dst) { 1023 System.arraycopy(src, 0, dst, 0, dst.length); 1024 } 1025 1026 @DontCompile 1027 public void test41_verifier(boolean warmup) { 1028 int len = Math.abs(rI) % 10; 1029 MyValue2[] src = new MyValue2[len]; 1030 Object[] dst = new Object[len]; 1031 for (int i = 0; i < len; ++i) { 1032 src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0); 1033 } 1034 test41(src, dst); 1035 verify(src, dst); 1036 if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test41")) { 1037 test41(src, dst); 1038 verify(src, dst); 1039 } 1040 } 1041 1042 @Test 1043 public void test42(Object[] src, Object[] dst) { 1044 System.arraycopy(src, 0, dst, 0, src.length); 1045 } 1046 1047 @DontCompile 1048 public void test42_verifier(boolean warmup) { 1049 int len = Math.abs(rI) % 10; 1050 Object[] src = new Object[len]; 1051 Object[] dst = new Object[len]; 1052 for (int i = 0; i < len; ++i) { 1053 src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0); 1054 } 1055 test42(src, dst); 1056 verify(src, dst); 1057 if (!warmup) { 1058 Method m = tests.get("TestArrays::test42"); 1059 if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) { 1060 throw new RuntimeException("unexpected deoptimization"); 1061 } 1062 } 1063 } 1064 1065 // short arraycopy()'s 1066 @Test 1067 public void test43(Object src, Object dst) { 1068 System.arraycopy(src, 0, dst, 0, 8); 1069 } 1070 1071 @DontCompile 1072 public void test43_verifier(boolean warmup) { 1073 MyValue1[] src = new MyValue1[8]; 1074 MyValue1[] dst = new MyValue1[8]; 1075 for (int i = 0; i < 8; ++i) { 1076 src[i] = MyValue1.createWithFieldsInline(rI, rL); 1077 } 1078 test43(src, dst); 1079 verify(src, dst); 1080 if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test43")) { 1081 test43(src, dst); 1082 verify(src, dst); 1083 } 1084 } 1085 1086 @Test 1087 public void test44(Object src, MyValue2[] dst) { 1088 System.arraycopy(src, 0, dst, 0, 8); 1089 } 1090 1091 @DontCompile 1092 public void test44_verifier(boolean warmup) { 1093 MyValue2[] src = new MyValue2[8]; 1094 MyValue2[] dst = new MyValue2[8]; 1095 for (int i = 0; i < 8; ++i) { 1096 src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0); 1097 } 1098 test44(src, dst); 1099 verify(src, dst); 1100 if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test44")) { 1101 test44(src, dst); 1102 verify(src, dst); 1103 } 1104 } 1105 1106 @Test 1107 public void test45(MyValue2[] src, Object dst) { 1108 System.arraycopy(src, 0, dst, 0, 8); 1109 } 1110 1111 @DontCompile 1112 public void test45_verifier(boolean warmup) { 1113 MyValue2[] src = new MyValue2[8]; 1114 MyValue2[] dst = new MyValue2[8]; 1115 for (int i = 0; i < 8; ++i) { 1116 src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0); 1117 } 1118 test45(src, dst); 1119 verify(src, dst); 1120 if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test45")) { 1121 test45(src, dst); 1122 verify(src, dst); 1123 } 1124 } 1125 1126 @Test 1127 @Warmup(1) // Avoid early compilation 1128 public void test46(Object[] src, MyValue2[] dst) { 1129 System.arraycopy(src, 0, dst, 0, 8); 1130 } 1131 1132 @DontCompile 1133 public void test46_verifier(boolean warmup) { 1134 Object[] src = new Object[8]; 1135 MyValue2[] dst = new MyValue2[8]; 1136 for (int i = 0; i < 8; ++i) { 1137 src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0); 1138 } 1139 test46(src, dst); 1140 verify(dst, src); 1141 if (!warmup) { 1142 Method m = tests.get("TestArrays::test46"); 1143 assertDeoptimizedByC2(m); 1144 enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION); 1145 test46(src, dst); 1146 verify(dst, src); 1147 if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) { 1148 throw new RuntimeException("unexpected deoptimization"); 1149 } 1150 } 1151 } 1152 1153 @Test 1154 public void test47(MyValue2[] src, Object[] dst) { 1155 System.arraycopy(src, 0, dst, 0, 8); 1156 } 1157 1158 @DontCompile 1159 public void test47_verifier(boolean warmup) { 1160 MyValue2[] src = new MyValue2[8]; 1161 Object[] dst = new Object[8]; 1162 for (int i = 0; i < 8; ++i) { 1163 src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0); 1164 } 1165 test47(src, dst); 1166 verify(src, dst); 1167 if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test47")) { 1168 test47(src, dst); 1169 verify(src, dst); 1170 } 1171 } 1172 1173 @Test 1174 @Warmup(1) // Avoid early compilation 1175 public void test48(Object[] src, Object dst) { 1176 System.arraycopy(src, 0, dst, 0, 8); 1177 } 1178 1179 @DontCompile 1180 public void test48_verifier(boolean warmup) { 1181 Object[] src = new Object[8]; 1182 MyValue2[] dst = new MyValue2[8]; 1183 for (int i = 0; i < 8; ++i) { 1184 src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0); 1185 } 1186 test48(src, dst); 1187 verify(dst, src); 1188 if (!warmup) { 1189 Method m = tests.get("TestArrays::test48"); 1190 assertDeoptimizedByC2(m); 1191 enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION); 1192 test48(src, dst); 1193 verify(dst, src); 1194 if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) { 1195 throw new RuntimeException("unexpected deoptimization"); 1196 } 1197 } 1198 } 1199 1200 @Test 1201 public void test49(Object src, Object[] dst) { 1202 System.arraycopy(src, 0, dst, 0, 8); 1203 } 1204 1205 @DontCompile 1206 public void test49_verifier(boolean warmup) { 1207 MyValue2[] src = new MyValue2[8]; 1208 Object[] dst = new Object[8]; 1209 for (int i = 0; i < 8; ++i) { 1210 src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0); 1211 } 1212 test49(src, dst); 1213 verify(src, dst); 1214 if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test49")) { 1215 test49(src, dst); 1216 verify(src, dst); 1217 } 1218 } 1219 1220 @Test 1221 public void test50(Object[] src, Object[] dst) { 1222 System.arraycopy(src, 0, dst, 0, 8); 1223 } 1224 1225 @DontCompile 1226 public void test50_verifier(boolean warmup) { 1227 Object[] src = new Object[8]; 1228 Object[] dst = new Object[8]; 1229 for (int i = 0; i < 8; ++i) { 1230 src[i] = MyValue2.createWithFieldsInline(rI, (i % 2) == 0); 1231 } 1232 test50(src, dst); 1233 verify(src, dst); 1234 if (!warmup) { 1235 Method m = tests.get("TestArrays::test50"); 1236 if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP) { 1237 throw new RuntimeException("unexpected deoptimization"); 1238 } 1239 } 1240 } 1241 1242 @Test 1243 public MyValue1[] test51(MyValue1[] va) { 1244 return Arrays.copyOf(va, va.length, MyValue1[].class); 1245 } 1246 1247 @DontCompile 1248 public void test51_verifier(boolean warmup) { 1249 int len = Math.abs(rI) % 10; 1250 MyValue1[] va = new MyValue1[len]; 1251 for (int i = 0; i < len; ++i) { 1252 va[i] = MyValue1.createWithFieldsInline(rI, rL); 1253 } 1254 MyValue1[] result = test51(va); 1255 verify(va, result); 1256 } 1257 1258 static final MyValue1[] test52_va = new MyValue1[8]; 1259 1260 @Test 1261 public MyValue1[] test52() { 1262 return Arrays.copyOf(test52_va, 8, MyValue1[].class); 1263 } 1264 1265 @DontCompile 1266 public void test52_verifier(boolean warmup) { 1267 for (int i = 0; i < 8; ++i) { 1268 test52_va[i] = MyValue1.createWithFieldsInline(rI, rL); 1269 } 1270 MyValue1[] result = test52(); 1271 verify(test52_va, result); 1272 } 1273 1274 @Test 1275 public MyValue1[] test53(Object[] va) { 1276 return Arrays.copyOf(va, va.length, MyValue1[].class); 1277 } 1278 1279 @DontCompile 1280 public void test53_verifier(boolean warmup) { 1281 int len = Math.abs(rI) % 10; 1282 MyValue1[] va = new MyValue1[len]; 1283 for (int i = 0; i < len; ++i) { 1284 va[i] = MyValue1.createWithFieldsInline(rI, rL); 1285 } 1286 MyValue1[] result = test53(va); 1287 verify(result, va); 1288 } 1289 1290 @Test 1291 public Object[] test54(MyValue1[] va) { 1292 return Arrays.copyOf(va, va.length, Object[].class); 1293 } 1294 1295 @DontCompile 1296 public void test54_verifier(boolean warmup) { 1297 int len = Math.abs(rI) % 10; 1298 MyValue1[] va = new MyValue1[len]; 1299 for (int i = 0; i < len; ++i) { 1300 va[i] = MyValue1.createWithFieldsInline(rI, rL); 1301 } 1302 Object[] result = test54(va); 1303 verify(va, result); 1304 } 1305 1306 @Test 1307 public Object[] test55(Object[] va) { 1308 return Arrays.copyOf(va, va.length, Object[].class); 1309 } 1310 1311 @DontCompile 1312 public void test55_verifier(boolean warmup) { 1313 int len = Math.abs(rI) % 10; 1314 MyValue1[] va = new MyValue1[len]; 1315 for (int i = 0; i < len; ++i) { 1316 va[i] = MyValue1.createWithFieldsInline(rI, rL); 1317 } 1318 Object[] result = test55(va); 1319 verify(va, result); 1320 } 1321 1322 @Test 1323 public MyValue1[] test56(Object[] va) { 1324 return Arrays.copyOf(va, va.length, MyValue1[].class); 1325 } 1326 1327 @DontCompile 1328 public void test56_verifier(boolean warmup) { 1329 int len = Math.abs(rI) % 10; 1330 Object[] va = new Object[len]; 1331 for (int i = 0; i < len; ++i) { 1332 va[i] = MyValue1.createWithFieldsInline(rI, rL); 1333 } 1334 MyValue1[] result = test56(va); 1335 verify(result, va); 1336 } 1337 1338 @Test 1339 public Object[] test57(Object[] va, Class klass) { 1340 return Arrays.copyOf(va, va.length, klass); 1341 } 1342 1343 @DontCompile 1344 public void test57_verifier(boolean warmup) { 1345 int len = Math.abs(rI) % 10; 1346 Object[] va = new MyValue1[len]; 1347 for (int i = 0; i < len; ++i) { 1348 va[i] = MyValue1.createWithFieldsInline(rI, rL); 1349 } 1350 Object[] result = test57(va, MyValue1[].class); 1351 verify(va, result); 1352 } 1353 1354 @Test 1355 public Object[] test58(MyValue1[] va, Class klass) { 1356 return Arrays.copyOf(va, va.length, klass); 1357 } 1358 1359 @DontCompile 1360 public void test58_verifier(boolean warmup) { 1361 int len = Math.abs(rI) % 10; 1362 MyValue1[] va = new MyValue1[len]; 1363 for (int i = 0; i < len; ++i) { 1364 va[i] = MyValue1.createWithFieldsInline(rI, rL); 1365 } 1366 for (int i = 0; i < 10; i++) { 1367 Object[] result = test58(va, MyValue1[].class); 1368 verify(va, result); 1369 } 1370 if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test58")) { 1371 Object[] result = test58(va, MyValue1[].class); 1372 verify(va, result); 1373 } 1374 } 1375 1376 @Test 1377 public Object[] test59(MyValue1[] va) { 1378 return Arrays.copyOf(va, va.length+1, MyValue1[].class); 1379 } 1380 1381 @DontCompile 1382 public void test59_verifier(boolean warmup) { 1383 int len = Math.abs(rI) % 10; 1384 MyValue1[] va = new MyValue1[len]; 1385 MyValue1[] verif = new MyValue1[len+1]; 1386 for (int i = 0; i < len; ++i) { 1387 va[i] = MyValue1.createWithFieldsInline(rI, rL); 1388 verif[i] = va[i]; 1389 } 1390 Object[] result = test59(va); 1391 verify(verif, result); 1392 } 1393 1394 @Test 1395 public Object[] test60(Object[] va, Class klass) { 1396 return Arrays.copyOf(va, va.length+1, klass); 1397 } 1398 1399 @DontCompile 1400 public void test60_verifier(boolean warmup) { 1401 int len = Math.abs(rI) % 10; 1402 MyValue1[] va = new MyValue1[len]; 1403 MyValue1[] verif = new MyValue1[len+1]; 1404 for (int i = 0; i < len; ++i) { 1405 va[i] = MyValue1.createWithFieldsInline(rI, rL); 1406 verif[i] = (MyValue1)va[i]; 1407 } 1408 Object[] result = test60(va, MyValue1[].class); 1409 verify(verif, result); 1410 } 1411 1412 @Test 1413 public Object[] test61(Object[] va, Class klass) { 1414 return Arrays.copyOf(va, va.length+1, klass); 1415 } 1416 1417 @DontCompile 1418 public void test61_verifier(boolean warmup) { 1419 int len = Math.abs(rI) % 10; 1420 Object[] va = new Integer[len]; 1421 for (int i = 0; i < len; ++i) { 1422 va[i] = new Integer(rI); 1423 } 1424 Object[] result = test61(va, Integer[].class); 1425 for (int i = 0; i < va.length; ++i) { 1426 Asserts.assertEQ(va[i], result[i]); 1427 } 1428 } 1429 1430 @ForceInline 1431 public Object[] test62_helper(int i, MyValue1[] va, Integer[] oa) { 1432 Object[] arr = null; 1433 if (i == 10) { 1434 arr = oa; 1435 } else { 1436 arr = va; 1437 } 1438 return arr; 1439 } 1440 1441 @Test 1442 public Object[] test62(MyValue1[] va, Integer[] oa) { 1443 int i = 0; 1444 for (; i < 10; i++); 1445 1446 Object[] arr = test62_helper(i, va, oa); 1447 1448 return Arrays.copyOf(arr, arr.length+1, arr.getClass()); 1449 } 1450 1451 @DontCompile 1452 public void test62_verifier(boolean warmup) { 1453 int len = Math.abs(rI) % 10; 1454 MyValue1[] va = new MyValue1[len]; 1455 Integer[] oa = new Integer[len]; 1456 for (int i = 0; i < len; ++i) { 1457 oa[i] = new Integer(rI); 1458 } 1459 test62_helper(42, va, oa); 1460 Object[] result = test62(va, oa); 1461 for (int i = 0; i < va.length; ++i) { 1462 Asserts.assertEQ(oa[i], result[i]); 1463 } 1464 } 1465 1466 @ForceInline 1467 public Object[] test63_helper(int i, MyValue1[] va, Integer[] oa) { 1468 Object[] arr = null; 1469 if (i == 10) { 1470 arr = va; 1471 } else { 1472 arr = oa; 1473 } 1474 return arr; 1475 } 1476 1477 @Test 1478 public Object[] test63(MyValue1[] va, Integer[] oa) { 1479 int i = 0; 1480 for (; i < 10; i++); 1481 1482 Object[] arr = test63_helper(i, va, oa); 1483 1484 return Arrays.copyOf(arr, arr.length+1, arr.getClass()); 1485 } 1486 1487 @DontCompile 1488 public void test63_verifier(boolean warmup) { 1489 int len = Math.abs(rI) % 10; 1490 MyValue1[] va = new MyValue1[len]; 1491 MyValue1[] verif = new MyValue1[len+1]; 1492 for (int i = 0; i < len; ++i) { 1493 va[i] = MyValue1.createWithFieldsInline(rI, rL); 1494 verif[i] = va[i]; 1495 } 1496 Integer[] oa = new Integer[len]; 1497 test63_helper(42, va, oa); 1498 Object[] result = test63(va, oa); 1499 verify(verif, result); 1500 } 1501 1502 // Test default initialization of value type arrays: small array 1503 @Test 1504 public MyValue1[] test64() { 1505 return new MyValue1[8]; 1506 } 1507 1508 @DontCompile 1509 public void test64_verifier(boolean warmup) { 1510 MyValue1[] va = new MyValue1[8]; 1511 MyValue1[] var = test64(); 1512 for (int i = 0; i < 8; ++i) { 1513 Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive()); 1514 } 1515 } 1516 1517 // Test default initialization of value type arrays: large array 1518 @Test 1519 public MyValue1[] test65() { 1520 return new MyValue1[32]; 1521 } 1522 1523 @DontCompile 1524 public void test65_verifier(boolean warmup) { 1525 MyValue1[] va = new MyValue1[32]; 1526 MyValue1[] var = test65(); 1527 for (int i = 0; i < 32; ++i) { 1528 Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive()); 1529 } 1530 } 1531 1532 // Check init store elimination 1533 @Test 1534 public MyValue1[] test66(MyValue1 vt) { 1535 MyValue1[] va = new MyValue1[1]; 1536 va[0] = vt; 1537 return va; 1538 } 1539 1540 @DontCompile 1541 public void test66_verifier(boolean warmup) { 1542 MyValue1 vt = MyValue1.createWithFieldsDontInline(rI, rL); 1543 MyValue1[] va = test66(vt); 1544 Asserts.assertEQ(va[0].hashPrimitive(), vt.hashPrimitive()); 1545 } 1546 1547 // Zeroing elimination and arraycopy 1548 @Test 1549 public MyValue1[] test67(MyValue1[] src) { 1550 MyValue1[] dst = new MyValue1[16]; 1551 System.arraycopy(src, 0, dst, 0, 13); 1552 return dst; 1553 } 1554 1555 @DontCompile 1556 public void test67_verifier(boolean warmup) { 1557 MyValue1[] va = new MyValue1[16]; 1558 MyValue1[] var = test67(va); 1559 for (int i = 0; i < 16; ++i) { 1560 Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive()); 1561 } 1562 } 1563 1564 // A store with a default value can be eliminated 1565 @Test 1566 public MyValue1[] test68() { 1567 MyValue1[] va = new MyValue1[2]; 1568 va[0] = va[1]; 1569 return va; 1570 } 1571 1572 @DontCompile 1573 public void test68_verifier(boolean warmup) { 1574 MyValue1[] va = new MyValue1[2]; 1575 MyValue1[] var = test68(); 1576 for (int i = 0; i < 2; ++i) { 1577 Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive()); 1578 } 1579 } 1580 1581 // Requires individual stores to init array 1582 @Test 1583 public MyValue1[] test69(MyValue1 vt) { 1584 MyValue1[] va = new MyValue1[4]; 1585 va[0] = vt; 1586 va[3] = vt; 1587 return va; 1588 } 1589 1590 @DontCompile 1591 public void test69_verifier(boolean warmup) { 1592 MyValue1 vt = MyValue1.createWithFieldsDontInline(rI, rL); 1593 MyValue1[] va = new MyValue1[4]; 1594 va[0] = vt; 1595 va[3] = vt; 1596 MyValue1[] var = test69(vt); 1597 for (int i = 0; i < va.length; ++i) { 1598 Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive()); 1599 } 1600 } 1601 1602 // A store with a default value can be eliminated: same as test68 1603 // but store is farther away from allocation 1604 @Test 1605 public MyValue1[] test70(MyValue1[] other) { 1606 other[1] = other[0]; 1607 MyValue1[] va = new MyValue1[2]; 1608 other[0] = va[1]; 1609 va[0] = va[1]; 1610 return va; 1611 } 1612 1613 @DontCompile 1614 public void test70_verifier(boolean warmup) { 1615 MyValue1[] va = new MyValue1[2]; 1616 MyValue1[] var = test70(va); 1617 for (int i = 0; i < 2; ++i) { 1618 Asserts.assertEQ(va[i].hashPrimitive(), var[i].hashPrimitive()); 1619 } 1620 } 1621 1622 // EA needs to consider oop fields in flattened arrays 1623 @Test 1624 public void test71() { 1625 int len = 10; 1626 MyValue2[] src = new MyValue2[len]; 1627 MyValue2[] dst = new MyValue2[len]; 1628 for (int i = 0; i < len; ++i) { 1629 src[i] = MyValue2.createWithFieldsDontInline(rI, (i % 2) == 0); 1630 } 1631 System.arraycopy(src, 0, dst, 0, src.length); 1632 for (int i = 0; i < len; ++i) { 1633 Asserts.assertEQ(src[i].hash(), dst[i].hash()); 1634 } 1635 } 1636 1637 @DontCompile 1638 public void test71_verifier(boolean warmup) { 1639 test71(); 1640 } 1641 1642 // Test EA with leaf call to 'store_unknown_value' 1643 @Test 1644 public void test72(Object[] o, boolean b, Object element) { 1645 Object[] arr1 = new Object[10]; 1646 Object[] arr2 = new Object[10]; 1647 if (b) { 1648 arr1 = o; 1649 } 1650 arr1[0] = element; 1651 arr2[0] = element; 1652 } 1653 1654 @DontCompile 1655 public void test72_verifier(boolean warmup) { 1656 Object[] arr = new Object[1]; 1657 Object elem = new Object(); 1658 test72(arr, true, elem); 1659 test72(arr, false, elem); 1660 } 1661 1662 @Test 1663 public void test73(Object[] oa, MyValue1 v, Object o) { 1664 // TestLWorld.test38 use a C1 Phi node for the array. This test 1665 // adds the case where the stored value is a C1 Phi node. 1666 Object o2 = (o == null) ? v : o; 1667 oa[0] = v; // The stored value is known to be flattenable 1668 oa[1] = o; // The stored value may be flattenable 1669 oa[2] = o2; // The stored value may be flattenable (a C1 Phi node) 1670 oa[0] = oa; // The stored value is known to be not flattenable (an Object[]) 1671 } 1672 1673 @DontCompile 1674 public void test73_verifier(boolean warmup) { 1675 MyValue1 v0 = MyValue1.createWithFieldsDontInline(rI, rL); 1676 MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI+1, rL+1); 1677 MyValue1[] arr = new MyValue1[3]; 1678 try { 1679 test73(arr, v0, v1); 1680 throw new RuntimeException("ArrayStoreException expected"); 1681 } catch (ArrayStoreException t) { 1682 // expected 1683 } 1684 Asserts.assertEQ(arr[0].hash(), v0.hash()); 1685 Asserts.assertEQ(arr[1].hash(), v1.hash()); 1686 Asserts.assertEQ(arr[2].hash(), v1.hash()); 1687 } 1688 1689 public static void test74Callee(MyValue1[] va) { } 1690 1691 // Tests invoking unloaded method with value array in signature 1692 @Test 1693 @Warmup(0) 1694 public void test74(MethodHandle m, MyValue1[] va) throws Throwable { 1695 m.invoke(va); 1696 } 1697 1698 @DontCompile 1699 public void test74_verifier(boolean warmup) throws Throwable { 1700 MethodHandle m = MethodHandles.lookup().findStatic(TestArrays.class, "test74Callee", MethodType.methodType(void.class, MyValue1[].class)); 1701 MyValue1[] va = new MyValue1[0]; 1702 test74(m, va); 1703 } 1704 1705 // Some more array clone tests 1706 @ForceInline 1707 public Object[] test75_helper(int i, MyValue1[] va, Integer[] oa) { 1708 Object[] arr = null; 1709 if (i == 10) { 1710 arr = oa; 1711 } else { 1712 arr = va; 1713 } 1714 return arr; 1715 } 1716 1717 @Test 1718 public Object[] test75(MyValue1[] va, Integer[] oa) { 1719 int i = 0; 1720 for (; i < 10; i++); 1721 1722 Object[] arr = test75_helper(i, va, oa); 1723 return arr.clone(); 1724 } 1725 1726 @DontCompile 1727 public void test75_verifier(boolean warmup) { 1728 int len = Math.abs(rI) % 10; 1729 MyValue1[] va = new MyValue1[len]; 1730 Integer[] oa = new Integer[len]; 1731 for (int i = 0; i < len; ++i) { 1732 oa[i] = new Integer(rI); 1733 } 1734 test75_helper(42, va, oa); 1735 Object[] result = test75(va, oa); 1736 1737 for (int i = 0; i < va.length; ++i) { 1738 Asserts.assertEQ(oa[i], result[i]); 1739 // Check that array has correct storage properties (null-ok) 1740 result[i] = null; 1741 } 1742 } 1743 1744 @ForceInline 1745 public Object[] test76_helper(int i, MyValue1[] va, Integer[] oa) { 1746 Object[] arr = null; 1747 if (i == 10) { 1748 arr = va; 1749 } else { 1750 arr = oa; 1751 } 1752 return arr; 1753 } 1754 1755 @Test 1756 public Object[] test76(MyValue1[] va, Integer[] oa) { 1757 int i = 0; 1758 for (; i < 10; i++); 1759 1760 Object[] arr = test76_helper(i, va, oa); 1761 return arr.clone(); 1762 } 1763 1764 @DontCompile 1765 public void test76_verifier(boolean warmup) { 1766 int len = Math.abs(rI) % 10; 1767 MyValue1[] va = new MyValue1[len]; 1768 MyValue1[] verif = new MyValue1[len]; 1769 for (int i = 0; i < len; ++i) { 1770 va[i] = MyValue1.createWithFieldsInline(rI, rL); 1771 verif[i] = va[i]; 1772 } 1773 Integer[] oa = new Integer[len]; 1774 test76_helper(42, va, oa); 1775 Object[] result = test76(va, oa); 1776 verify(verif, result); 1777 // Check that array has correct storage properties (null-free) 1778 if (len > 0) { 1779 try { 1780 result[0] = null; 1781 throw new RuntimeException("Should throw NullPointerException"); 1782 } catch (NullPointerException e) { 1783 // Expected 1784 } 1785 } 1786 } 1787 1788 @Test 1789 public void test77() { 1790 MyValue1 v0 = MyValue1.createWithFieldsDontInline(rI, rL); 1791 MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI+1, rL+1); 1792 MyValue1[] arr = new MyValue1[1]; 1793 1794 Object[] oa = arr; 1795 Object o1 = v1; 1796 Object o = (o1 == null) ? v0 : o1; 1797 1798 oa[0] = o; // For C1, due to IfOp optimization, the declared_type of o becomes NULL. 1799 1800 Asserts.assertEQ(arr[0].hash(), v1.hash()); 1801 } 1802 1803 1804 @DontCompile 1805 public void test77_verifier(boolean warmup) { 1806 test77(); 1807 } 1808 1809 @Test 1810 public long test78(MyValue1 v, int n) { 1811 long x = 0; 1812 for (int i = 0; i<n; i++) { 1813 } 1814 1815 MyValue1[] a = new MyValue1[n]; 1816 a[0] = v; 1817 for (int i = 0; i<n; i++) { 1818 x += a[i].hash(); // C1 PhiSimplifier changes "a" from a Phi node to a NewObjectArray node 1819 } 1820 1821 return x; 1822 } 1823 1824 @DontCompile 1825 public void test78_verifier(boolean warmup) { 1826 MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); 1827 Asserts.assertEQ(test78(v, 1), v.hash()); 1828 } 1829 }