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