1 /* 2 * Copyright (c) 2018, 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 java.lang.invoke.*; 27 import java.lang.reflect.Method; 28 29 import jdk.experimental.value.MethodHandleBuilder; 30 import jdk.experimental.bytecode.MacroCodeBuilder; 31 import jdk.experimental.bytecode.MacroCodeBuilder.CondKind; 32 import jdk.experimental.bytecode.TypeTag; 33 import jdk.test.lib.Asserts; 34 35 /* 36 * @test 37 * @summary Test value types in LWorld. 38 * @modules java.base/jdk.experimental.bytecode 39 * java.base/jdk.experimental.value 40 * @library /testlibrary /test/lib /compiler/whitebox / 41 * @requires os.simpleArch == "x64" 42 * @build TestLWorld_mismatched 43 * @compile -XDenableValueTypes -XDallowWithFieldOperator -XDallowFlattenabilityModifiers TestLWorld.java 44 * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform 45 * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions 46 * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:+EnableValhalla 47 * compiler.valhalla.valuetypes.ValueTypeTest 48 * compiler.valhalla.valuetypes.TestLWorld 49 */ 50 public class TestLWorld extends ValueTypeTest { 51 // Extra VM parameters for some test scenarios. See ValueTypeTest.getVMParameters() 52 @Override 53 public String[] getExtraVMParameters(int scenario) { 54 switch (scenario) { 55 case 1: return new String[] {"-XX:-UseOptoBiasInlining"}; 56 case 2: return new String[] {"-XX:-UseBiasedLocking"}; 57 case 3: return new String[] {"-XX:-MonomorphicArrayCheck", "-XX:-UseBiasedLocking", "-XX:+ValueArrayFlatten"}; 58 case 4: return new String[] {"-XX:-MonomorphicArrayCheck"}; 59 } 60 return null; 61 } 62 63 public static void main(String[] args) throws Throwable { 64 TestLWorld test = new TestLWorld(); 65 test.run(args, MyValue1.class, MyValue2.class, MyValue2Inline.class, MyValue3.class, 66 MyValue3Inline.class, Test65Value.class, TestLWorld_mismatched.class); 67 } 68 69 // Helper methods 70 71 private static final MyValue1 testValue1 = MyValue1.createWithFieldsInline(rI, rL); 72 private static final MyValue2 testValue2 = MyValue2.createWithFieldsInline(rI, true); 73 74 protected long hash() { 75 return testValue1.hash(); 76 } 77 78 // Test passing a value type as an Object 79 @DontInline 80 public Object test1_dontinline1(Object o) { 81 return o; 82 } 83 84 @DontInline 85 public MyValue1 test1_dontinline2(Object o) { 86 return (MyValue1)o; 87 } 88 89 @ForceInline 90 public Object test1_inline1(Object o) { 91 return o; 92 } 93 94 @ForceInline 95 public MyValue1 test1_inline2(Object o) { 96 return (MyValue1)o; 97 } 98 99 @Test() 100 public MyValue1 test1() { 101 MyValue1 vt = testValue1; 102 vt = (MyValue1)test1_dontinline1(vt); 103 vt = test1_dontinline2(vt); 104 vt = (MyValue1)test1_inline1(vt); 105 vt = test1_inline2(vt); 106 return vt; 107 } 108 109 @DontCompile 110 public void test1_verifier(boolean warmup) { 111 Asserts.assertEQ(test1().hash(), hash()); 112 } 113 114 // Test storing/loading value types to/from Object and value type fields 115 Object objectField1 = null; 116 Object objectField2 = null; 117 Object objectField3 = null; 118 Object objectField4 = null; 119 Object objectField5 = null; 120 Object objectField6 = null; 121 122 __Flattenable MyValue1 valueField1 = testValue1; 123 __Flattenable MyValue1 valueField2 = testValue1; 124 __NotFlattened MyValue1 valueField3 = testValue1; 125 __Flattenable MyValue1 valueField4; 126 __NotFlattened MyValue1 valueField5; 127 128 static __NotFlattened MyValue1 staticValueField1 = testValue1; 129 static __Flattenable MyValue1 staticValueField2 = testValue1; 130 static __Flattenable MyValue1 staticValueField3; 131 static __NotFlattened MyValue1 staticValueField4; 132 133 @DontInline 134 public Object readValueField5() { 135 return (Object)valueField5; 136 } 137 138 @DontInline 139 public Object readStaticValueField4() { 140 return (Object)staticValueField4; 141 } 142 143 @Test() 144 public long test2(MyValue1 vt1, Object vt2) { 145 objectField1 = vt1; 146 objectField2 = (MyValue1)vt2; 147 objectField3 = testValue1; 148 objectField4 = MyValue1.createWithFieldsDontInline(rI, rL); 149 objectField5 = valueField1; 150 objectField6 = valueField3; 151 valueField1 = (MyValue1)objectField1; 152 valueField2 = (MyValue1)vt2; 153 valueField3 = (MyValue1)vt2; 154 staticValueField1 = (MyValue1)objectField1; 155 staticValueField2 = (MyValue1)vt1; 156 // Don't inline these methods because reading NULL will trigger a deoptimization 157 if (readValueField5() != null || readStaticValueField4() != null) { 158 throw new RuntimeException("Should be null"); 159 } 160 return ((MyValue1)objectField1).hash() + ((MyValue1)objectField2).hash() + 161 ((MyValue1)objectField3).hash() + ((MyValue1)objectField4).hash() + 162 ((MyValue1)objectField5).hash() + ((MyValue1)objectField6).hash() + 163 valueField1.hash() + valueField2.hash() + valueField3.hash() + valueField4.hashPrimitive() + 164 staticValueField1.hash() + staticValueField2.hash() + staticValueField3.hashPrimitive(); 165 } 166 167 @DontCompile 168 public void test2_verifier(boolean warmup) { 169 MyValue1 vt = testValue1; 170 MyValue1 def = MyValue1.createDefaultDontInline(); 171 long result = test2(vt, vt); 172 Asserts.assertEQ(result, 11*vt.hash() + 2*def.hashPrimitive()); 173 } 174 175 // Test merging value types and objects 176 @Test() 177 public Object test3(int state) { 178 Object res = null; 179 if (state == 0) { 180 res = new Integer(rI); 181 } else if (state == 1) { 182 res = MyValue1.createWithFieldsInline(rI, rL); 183 } else if (state == 2) { 184 res = MyValue1.createWithFieldsDontInline(rI, rL); 185 } else if (state == 3) { 186 res = (MyValue1)objectField1; 187 } else if (state == 4) { 188 res = valueField1; 189 } else if (state == 5) { 190 res = null; 191 } else if (state == 6) { 192 res = MyValue2.createWithFieldsInline(rI, true); 193 } else if (state == 7) { 194 res = testValue2; 195 } 196 return res; 197 } 198 199 @DontCompile 200 public void test3_verifier(boolean warmup) { 201 objectField1 = valueField1; 202 Object result = null; 203 result = test3(0); 204 Asserts.assertEQ((Integer)result, rI); 205 result = test3(1); 206 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 207 result = test3(2); 208 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 209 result = test3(3); 210 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 211 result = test3(4); 212 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 213 result = test3(5); 214 Asserts.assertEQ(result, null); 215 result = test3(6); 216 Asserts.assertEQ(((MyValue2)result).hash(), testValue2.hash()); 217 result = test3(7); 218 Asserts.assertEQ(((MyValue2)result).hash(), testValue2.hash()); 219 } 220 221 // Test merging value types and objects in loops 222 @Test() 223 public Object test4(int iters) { 224 Object res = new Integer(rI); 225 for (int i = 0; i < iters; ++i) { 226 if (res instanceof Integer) { 227 res = MyValue1.createWithFieldsInline(rI, rL); 228 } else { 229 res = MyValue1.createWithFieldsInline(((MyValue1)res).x + 1, rL); 230 } 231 } 232 return res; 233 } 234 235 @DontCompile 236 public void test4_verifier(boolean warmup) { 237 Integer result1 = (Integer)test4(0); 238 Asserts.assertEQ(result1, rI); 239 int iters = (Math.abs(rI) % 10) + 1; 240 MyValue1 result2 = (MyValue1)test4(iters); 241 MyValue1 vt = MyValue1.createWithFieldsInline(rI + iters - 1, rL); 242 Asserts.assertEQ(result2.hash(), vt.hash()); 243 } 244 245 // Test value types in object variables that are live at safepoint 246 @Test(failOn = ALLOC + STORE + LOOP) 247 public long test5(MyValue1 arg, boolean deopt) { 248 Object vt1 = MyValue1.createWithFieldsInline(rI, rL); 249 Object vt2 = MyValue1.createWithFieldsDontInline(rI, rL); 250 Object vt3 = arg; 251 Object vt4 = valueField1; 252 if (deopt) { 253 // uncommon trap 254 WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test5")); 255 } 256 return ((MyValue1)vt1).hash() + ((MyValue1)vt2).hash() + 257 ((MyValue1)vt3).hash() + ((MyValue1)vt4).hash(); 258 } 259 260 @DontCompile 261 public void test5_verifier(boolean warmup) { 262 long result = test5(valueField1, !warmup); 263 Asserts.assertEQ(result, 4*hash()); 264 } 265 266 // Test comparing value types with objects 267 @Test(failOn = ALLOC + LOAD + STORE + LOOP) 268 public boolean test6(Object arg) { 269 Object vt = MyValue1.createWithFieldsInline(rI, rL); 270 if (vt == arg || vt == (Object)valueField1 || vt == objectField1 || vt == null || 271 arg == vt || (Object)valueField1 == vt || objectField1 == vt || null == vt) { 272 return true; 273 } 274 return false; 275 } 276 277 @DontCompile 278 public void test6_verifier(boolean warmup) { 279 boolean result = test6(null); 280 Asserts.assertFalse(result); 281 } 282 283 // Test correct handling of null-ness of value types 284 285 __NotFlattened MyValue1 nullField; 286 287 @Test 288 @Warmup(10000) // Warmup to make sure 'callTest7WithNull' is compiled 289 public long test7(MyValue1 vt) { 290 long result = 0; 291 try { 292 result = vt.hash(); 293 throw new RuntimeException("NullPointerException expected"); 294 } catch (NullPointerException e) { 295 // Expected 296 } 297 return result; 298 } 299 300 private static final MethodHandle callTest7WithNull = MethodHandleBuilder.loadCode(MethodHandles.lookup(), 301 "callTest7WithNull", 302 MethodType.methodType(void.class, TestLWorld.class), 303 CODE -> { 304 CODE. 305 aload_0(). 306 aconst_null(). 307 invokevirtual(TestLWorld.class, "test7", "(Lcompiler/valhalla/valuetypes/MyValue1;)J", false). 308 return_(); 309 }, 310 MyValue1.class); 311 312 @DontCompile 313 public void test7_verifier(boolean warmup) throws Throwable { 314 long result = (long)callTest7WithNull.invoke(this); 315 Asserts.assertEquals(result, 0L); 316 } 317 318 @Test 319 public long test8(MyValue1 vt) { 320 long result = 0; 321 try { 322 result = vt.hashInterpreted(); 323 throw new RuntimeException("NullPointerException expected"); 324 } catch (NullPointerException e) { 325 // Expected 326 } 327 return result; 328 } 329 330 @DontCompile 331 public void test8_verifier(boolean warmup) { 332 long result = test8(nullField); 333 Asserts.assertEquals(result, 0L); 334 } 335 336 @Test 337 public long test9() { 338 long result = 0; 339 try { 340 if ((Object)nullField != null) { 341 throw new RuntimeException("nullField should be null"); 342 } 343 result = nullField.hash(); 344 throw new RuntimeException("NullPointerException expected"); 345 } catch (NullPointerException e) { 346 // Expected 347 } 348 return result; 349 } 350 351 @DontCompile 352 public void test9_verifier(boolean warmup) { 353 long result = test9(); 354 Asserts.assertEquals(result, 0L); 355 } 356 357 @Test 358 public void test10() { 359 try { 360 valueField1 = nullField; 361 throw new RuntimeException("NullPointerException expected"); 362 } catch (NullPointerException e) { 363 // Expected 364 } 365 } 366 367 @DontCompile 368 public void test10_verifier(boolean warmup) { 369 test10(); 370 } 371 372 @Test 373 public MyValue1 test11(MyValue1 vt) { 374 try { 375 Object o = vt; 376 vt = (MyValue1)o; 377 throw new RuntimeException("NullPointerException expected"); 378 } catch (NullPointerException e) { 379 // Expected 380 } 381 382 // Should not throw 383 vt = test11_dontinline(vt); 384 vt = test11_inline(vt); 385 return vt; 386 } 387 388 @DontCompile 389 public void test11_verifier(boolean warmup) { 390 MyValue1 vt = test11(nullField); 391 Asserts.assertEquals((Object)vt, null); 392 } 393 394 @DontInline 395 public MyValue1 test11_dontinline(MyValue1 vt) { 396 return vt; 397 } 398 399 @ForceInline 400 public MyValue1 test11_inline(MyValue1 vt) { 401 return vt; 402 } 403 404 @Test 405 public MyValue1 test12(Object obj) { 406 MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); 407 try { 408 vt = (MyValue1)obj; 409 throw new RuntimeException("NullPointerException expected"); 410 } catch (NullPointerException e) { 411 // Expected 412 } 413 return vt; 414 } 415 416 @DontCompile 417 public void test12_verifier(boolean warmup) { 418 MyValue1 vt = test12(null); 419 Asserts.assertEquals(vt.hash(), hash()); 420 } 421 422 private static final MethodHandle getNull = MethodHandleBuilder.loadCode(MethodHandles.lookup(), 423 "getNull", 424 MethodType.methodType(MyValue1.class), 425 CODE -> { 426 CODE. 427 aconst_null(). 428 areturn(); 429 }, 430 MyValue1.class); 431 432 @Test 433 public void test13() throws Throwable { 434 try { 435 valueField1 = (MyValue1)getNull.invoke(); 436 throw new RuntimeException("NullPointerException expected"); 437 } catch (NullPointerException e) { 438 // Expected 439 } 440 nullField = (MyValue1)getNull.invoke(); // Should not throw 441 } 442 443 @DontCompile 444 public void test13_verifier(boolean warmup) throws Throwable { 445 test13(); 446 } 447 448 // null constant 449 private static final MethodHandle setNull = MethodHandleBuilder.loadCode(MethodHandles.lookup(), 450 "setNull", 451 MethodType.methodType(void.class, TestLWorld.class), 452 CODE -> { 453 CODE. 454 aload_0(). 455 aconst_null(). 456 putfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;"). 457 return_(); 458 }, 459 MyValue1.class); 460 461 @Test 462 public void test14() throws Throwable { 463 try { 464 setNull.invoke(this); 465 throw new RuntimeException("NullPointerException expected"); 466 } catch (NullPointerException e) { 467 // Expected 468 } 469 } 470 471 @DontCompile 472 public void test14_verifier(boolean warmup) throws Throwable { 473 test14(); 474 } 475 476 // merge of 2 values, one being null 477 @Test 478 public void test15(boolean flag1) { 479 MyValue1 v; 480 if (flag1) { 481 v = valueField1; 482 } else { 483 v = valueField5; 484 } 485 valueField1 = v; 486 } 487 488 @DontCompile 489 public void test15_verifier(boolean warmup) { 490 test15(true); 491 try { 492 test15(false); 493 throw new RuntimeException("NullPointerException expected"); 494 } catch (NullPointerException e) { 495 // Expected 496 } 497 } 498 499 // null constant 500 private static final MethodHandle mergeNull = MethodHandleBuilder.loadCode(MethodHandles.lookup(), 501 "mergeNull", 502 MethodType.methodType(void.class, TestLWorld.class, boolean.class), 503 CODE -> { 504 CODE. 505 iload_1(). 506 iconst_0(). 507 ifcmp(TypeTag.I, CondKind.EQ, "null"). 508 aload_0(). 509 getfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;"). 510 goto_("continue"). 511 label("null"). 512 aconst_null(). 513 label("continue"). 514 aload_0(). 515 swap(). 516 putfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;"). 517 return_(); 518 }, 519 MyValue1.class); 520 521 @Test 522 public void test16(boolean flag) throws Throwable { 523 mergeNull.invoke(this, flag); 524 } 525 526 @DontCompile 527 public void test16_verifier(boolean warmup) throws Throwable { 528 test16(true); 529 try { 530 test16(false); 531 throw new RuntimeException("NullPointerException expected"); 532 } catch (NullPointerException e) { 533 // Expected 534 } 535 } 536 537 // merge of value and non value 538 @Test 539 public Object test17(boolean flag) { 540 Object res = null; 541 if (flag) { 542 res = valueField1; 543 } else { 544 res = objectField1; 545 } 546 return res; 547 } 548 549 @DontCompile 550 public void test17_verifier(boolean warmup) { 551 test17(true); 552 test17(false); 553 } 554 555 @Test 556 public Object test18(boolean flag) { 557 Object res = null; 558 if (flag) { 559 res = objectField1; 560 } else { 561 res = valueField1; 562 } 563 return res; 564 } 565 566 @DontCompile 567 public void test18_verifier(boolean warmup) { 568 test18(true); 569 test18(false); 570 } 571 572 // null constant 573 private static final MethodHandle mergeNull2 = MethodHandleBuilder.loadCode(MethodHandles.lookup(), 574 "mergeNull2", 575 MethodType.methodType(void.class, TestLWorld.class, boolean.class), 576 CODE -> { 577 CODE. 578 iload_1(). 579 iconst_0(). 580 ifcmp(TypeTag.I, CondKind.EQ, "not_null"). 581 aconst_null(). 582 goto_("continue"). 583 label("not_null"). 584 aload_0(). 585 getfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;"). 586 label("continue"). 587 aload_0(). 588 swap(). 589 putfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;"). 590 return_(); 591 }, 592 MyValue1.class); 593 594 @Test 595 public void test19(boolean flag) throws Throwable { 596 mergeNull2.invoke(this, flag); 597 } 598 599 @DontCompile 600 public void test19_verifier(boolean warmup) throws Throwable { 601 test19(false); 602 try { 603 test19(true); 604 throw new RuntimeException("NullPointerException expected"); 605 } catch (NullPointerException e) { 606 // Expected 607 } 608 } 609 610 // merge of values in a loop, stored in an object local 611 @Test 612 public Object test20() { 613 Object o = valueField1; 614 for (int i = 1; i < 100; i *= 2) { 615 MyValue1 v = (MyValue1)o; 616 o = MyValue1.setX(v, v.x + 1); 617 } 618 return o; 619 } 620 621 @DontCompile 622 public void test20_verifier(boolean warmup) { 623 test20(); 624 } 625 626 // merge of values in an object local 627 public Object test21_helper() { 628 return valueField1; 629 } 630 631 @Test(failOn = ALLOC + LOAD + STORE) 632 public void test21(boolean flag) { 633 Object o = null; 634 if (flag) { 635 o = valueField1; 636 } else { 637 o = test21_helper(); 638 } 639 valueField1 = (MyValue1)o; 640 } 641 642 @DontCompile 643 public void test21_verifier(boolean warmup) { 644 test21(true); 645 test21(false); 646 } 647 648 // null return 649 int test_22_cnt; 650 651 @DontInline 652 public MyValue1 test22_helper() { 653 test_22_cnt++; 654 return valueField5; 655 } 656 657 @Test 658 public void test22() { 659 valueField1 = test22_helper(); 660 } 661 662 @DontCompile 663 public void test22_verifier(boolean warmup) { 664 try { 665 test_22_cnt = 0; 666 test22(); 667 throw new RuntimeException("NullPointerException expected"); 668 } catch (NullPointerException e) { 669 // Expected 670 } 671 if (test_22_cnt != 1) { 672 throw new RuntimeException("call executed twice"); 673 } 674 } 675 676 // null return at virtual call 677 class A { 678 public MyValue1 test23_helper() { 679 return valueField5; 680 } 681 } 682 683 class B extends A { 684 public MyValue1 test23_helper() { 685 return valueField5; 686 } 687 } 688 689 class C extends A { 690 public MyValue1 test23_helper() { 691 return valueField5; 692 } 693 } 694 695 class D extends A { 696 public MyValue1 test23_helper() { 697 return valueField5; 698 } 699 } 700 701 @Test 702 public void test23(A a) { 703 valueField1 = a.test23_helper(); 704 } 705 706 @DontCompile 707 public void test23_verifier(boolean warmup) { 708 A b = new B(); 709 A c = new C(); 710 A d = new D(); 711 try { 712 test23(b); 713 throw new RuntimeException("NullPointerException expected"); 714 } catch (NullPointerException e) { 715 // Expected 716 } 717 try { 718 test23(c); 719 throw new RuntimeException("NullPointerException expected"); 720 } catch (NullPointerException e) { 721 // Expected 722 } 723 try { 724 test23(d); 725 throw new RuntimeException("NullPointerException expected"); 726 } catch (NullPointerException e) { 727 // Expected 728 } 729 } 730 731 732 // Interface tests 733 734 @DontInline 735 public MyInterface test24_dontinline1(MyInterface o) { 736 return o; 737 } 738 739 @DontInline 740 public MyValue1 test24_dontinline2(MyInterface o) { 741 return (MyValue1)o; 742 } 743 744 @ForceInline 745 public MyInterface test24_inline1(MyInterface o) { 746 return o; 747 } 748 749 @ForceInline 750 public MyValue1 test24_inline2(MyInterface o) { 751 return (MyValue1)o; 752 } 753 754 @Test() 755 public MyValue1 test24() { 756 MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); 757 vt = (MyValue1)test24_dontinline1(vt); 758 vt = test24_dontinline2(vt); 759 vt = (MyValue1)test24_inline1(vt); 760 vt = test24_inline2(vt); 761 return vt; 762 } 763 764 @DontCompile 765 public void test24_verifier(boolean warmup) { 766 Asserts.assertEQ(test24().hash(), hash()); 767 } 768 769 // Test storing/loading value types to/from interface and value type fields 770 MyInterface interfaceField1 = null; 771 MyInterface interfaceField2 = null; 772 MyInterface interfaceField3 = null; 773 MyInterface interfaceField4 = null; 774 MyInterface interfaceField5 = null; 775 MyInterface interfaceField6 = null; 776 777 @DontInline 778 public MyInterface readValueField5AsInterface() { 779 return (MyInterface)valueField5; 780 } 781 782 @DontInline 783 public MyInterface readStaticValueField4AsInterface() { 784 return (MyInterface)staticValueField4; 785 } 786 787 @Test() 788 public long test25(MyValue1 vt1, MyInterface vt2) { 789 interfaceField1 = vt1; 790 interfaceField2 = (MyValue1)vt2; 791 interfaceField3 = MyValue1.createWithFieldsInline(rI, rL); 792 interfaceField4 = MyValue1.createWithFieldsDontInline(rI, rL); 793 interfaceField5 = valueField1; 794 interfaceField6 = valueField3; 795 valueField1 = (MyValue1)interfaceField1; 796 valueField2 = (MyValue1)vt2; 797 valueField3 = (MyValue1)vt2; 798 staticValueField1 = (MyValue1)interfaceField1; 799 staticValueField2 = (MyValue1)vt1; 800 // Don't inline these methods because reading NULL will trigger a deoptimization 801 if (readValueField5AsInterface() != null || readStaticValueField4AsInterface() != null) { 802 throw new RuntimeException("Should be null"); 803 } 804 return ((MyValue1)interfaceField1).hash() + ((MyValue1)interfaceField2).hash() + 805 ((MyValue1)interfaceField3).hash() + ((MyValue1)interfaceField4).hash() + 806 ((MyValue1)interfaceField5).hash() + ((MyValue1)interfaceField6).hash() + 807 valueField1.hash() + valueField2.hash() + valueField3.hash() + valueField4.hashPrimitive() + 808 staticValueField1.hash() + staticValueField2.hash() + staticValueField3.hashPrimitive(); 809 } 810 811 @DontCompile 812 public void test25_verifier(boolean warmup) { 813 MyValue1 vt = testValue1; 814 MyValue1 def = MyValue1.createDefaultDontInline(); 815 long result = test25(vt, vt); 816 Asserts.assertEQ(result, 11*vt.hash() + 2*def.hashPrimitive()); 817 } 818 819 class MyObject implements MyInterface { 820 public int x; 821 822 public MyObject(int x) { 823 this.x = x; 824 } 825 826 @ForceInline 827 public long hash() { 828 return x; 829 } 830 } 831 832 // Test merging value types and interfaces 833 @Test() 834 public MyInterface test26(int state) { 835 MyInterface res = null; 836 if (state == 0) { 837 res = new MyObject(rI); 838 } else if (state == 1) { 839 res = MyValue1.createWithFieldsInline(rI, rL); 840 } else if (state == 2) { 841 res = MyValue1.createWithFieldsDontInline(rI, rL); 842 } else if (state == 3) { 843 res = (MyValue1)objectField1; 844 } else if (state == 4) { 845 res = valueField1; 846 } else if (state == 5) { 847 res = null; 848 } 849 return res; 850 } 851 852 @DontCompile 853 public void test26_verifier(boolean warmup) { 854 objectField1 = valueField1; 855 MyInterface result = null; 856 result = test26(0); 857 Asserts.assertEQ(((MyObject)result).x, rI); 858 result = test26(1); 859 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 860 result = test26(2); 861 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 862 result = test26(3); 863 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 864 result = test26(4); 865 Asserts.assertEQ(((MyValue1)result).hash(), hash()); 866 result = test26(5); 867 Asserts.assertEQ(result, null); 868 } 869 870 // Test merging value types and interfaces in loops 871 @Test() 872 public MyInterface test27(int iters) { 873 MyInterface res = new MyObject(rI); 874 for (int i = 0; i < iters; ++i) { 875 if (res instanceof MyObject) { 876 res = MyValue1.createWithFieldsInline(rI, rL); 877 } else { 878 res = MyValue1.createWithFieldsInline(((MyValue1)res).x + 1, rL); 879 } 880 } 881 return res; 882 } 883 884 @DontCompile 885 public void test27_verifier(boolean warmup) { 886 MyObject result1 = (MyObject)test27(0); 887 Asserts.assertEQ(result1.x, rI); 888 int iters = (Math.abs(rI) % 10) + 1; 889 MyValue1 result2 = (MyValue1)test27(iters); 890 MyValue1 vt = MyValue1.createWithFieldsInline(rI + iters - 1, rL); 891 Asserts.assertEQ(result2.hash(), vt.hash()); 892 } 893 894 // Test value types in interface variables that are live at safepoint 895 @Test(failOn = ALLOC + STORE + LOOP) 896 public long test28(MyValue1 arg, boolean deopt) { 897 MyInterface vt1 = MyValue1.createWithFieldsInline(rI, rL); 898 MyInterface vt2 = MyValue1.createWithFieldsDontInline(rI, rL); 899 MyInterface vt3 = arg; 900 MyInterface vt4 = valueField1; 901 if (deopt) { 902 // uncommon trap 903 WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test28")); 904 } 905 return ((MyValue1)vt1).hash() + ((MyValue1)vt2).hash() + 906 ((MyValue1)vt3).hash() + ((MyValue1)vt4).hash(); 907 } 908 909 @DontCompile 910 public void test28_verifier(boolean warmup) { 911 long result = test28(valueField1, !warmup); 912 Asserts.assertEQ(result, 4*hash()); 913 } 914 915 // Test comparing value types with interfaces 916 @Test(failOn = ALLOC + LOAD + STORE + LOOP) 917 public boolean test29(Object arg) { 918 MyInterface vt = MyValue1.createWithFieldsInline(rI, rL); 919 if (vt == arg || vt == (MyInterface)valueField1 || vt == interfaceField1 || vt == null || 920 arg == vt || (MyInterface)valueField1 == vt || interfaceField1 == vt || null == vt) { 921 return true; 922 } 923 return false; 924 } 925 926 @DontCompile 927 public void test29_verifier(boolean warmup) { 928 boolean result = test29(null); 929 Asserts.assertFalse(result); 930 } 931 932 // Test subtype check when casting to value type 933 @Test 934 public MyValue1 test30(MyValue1 vt, Object obj) { 935 try { 936 vt = (MyValue1)obj; 937 throw new RuntimeException("ClassCastException expected"); 938 } catch (ClassCastException e) { 939 // Expected 940 } 941 return vt; 942 } 943 944 @DontCompile 945 public void test30_verifier(boolean warmup) { 946 MyValue1 vt = testValue1; 947 MyValue1 result = test30(vt, new Integer(rI)); 948 Asserts.assertEquals(result.hash(), vt.hash()); 949 } 950 951 @Test 952 public MyValue1 test31(MyValue1 vt) { 953 Object obj = vt; 954 vt = (MyValue1)obj; 955 return vt; 956 } 957 958 @DontCompile 959 public void test31_verifier(boolean warmup) { 960 MyValue1 vt = testValue1; 961 MyValue1 result = test31(vt); 962 Asserts.assertEquals(result.hash(), vt.hash()); 963 } 964 965 @Test 966 public void test32(MyValue1 vt) { 967 Object obj = vt; 968 try { 969 MyValue2 vt2 = (MyValue2)obj; 970 throw new RuntimeException("ClassCastException expected"); 971 } catch (ClassCastException e) { 972 // Expected 973 } 974 } 975 976 @DontCompile 977 public void test32_verifier(boolean warmup) { 978 test32(valueField1); 979 } 980 981 @Test 982 public void test33(MyValue1 vt) { 983 Object obj = vt; 984 try { 985 Integer i = (Integer)obj; 986 throw new RuntimeException("ClassCastException expected"); 987 } catch (ClassCastException e) { 988 // Expected 989 } 990 } 991 992 @DontCompile 993 public void test33_verifier(boolean warmup) { 994 test33(valueField1); 995 } 996 997 998 // Array tests 999 1000 private static final MyValue1[] testValue1Array = new MyValue1[] {testValue1, 1001 testValue1, 1002 testValue1}; 1003 1004 private static final MyValue1[][] testValue1Array2 = new MyValue1[][] {testValue1Array, 1005 testValue1Array, 1006 testValue1Array}; 1007 1008 private static final MyValue2[] testValue2Array = new MyValue2[] {testValue2, 1009 testValue2, 1010 testValue2}; 1011 1012 private static final Integer[] testIntegerArray = new Integer[42]; 1013 1014 // Test load from (flattened) value type array disguised as object array 1015 @Test() 1016 public Object test34(Object[] oa, int index) { 1017 return oa[index]; 1018 } 1019 1020 @DontCompile 1021 public void test34_verifier(boolean warmup) { 1022 MyValue1 result = (MyValue1)test34(testValue1Array, Math.abs(rI) % 3); 1023 Asserts.assertEQ(result.hash(), hash()); 1024 } 1025 1026 // Test load from (flattened) value type array disguised as interface array 1027 @Test() 1028 public Object test35(MyInterface[] ia, int index) { 1029 return ia[index]; 1030 } 1031 1032 @DontCompile 1033 public void test35_verifier(boolean warmup) { 1034 MyValue1 result = (MyValue1)test35(testValue1Array, Math.abs(rI) % 3); 1035 Asserts.assertEQ(result.hash(), hash()); 1036 } 1037 1038 // Test value store to (flattened) value type array disguised as object array 1039 1040 @ForceInline 1041 public void test36_inline(Object[] oa, Object o, int index) { 1042 oa[index] = o; 1043 } 1044 1045 @Test() 1046 public void test36(Object[] oa, MyValue1 vt, int index) { 1047 test36_inline(oa, vt, index); 1048 } 1049 1050 @DontCompile 1051 public void test36_verifier(boolean warmup) { 1052 int index = Math.abs(rI) % 3; 1053 MyValue1 vt = MyValue1.createWithFieldsInline(rI + 1, rL + 1); 1054 test36(testValue1Array, vt, index); 1055 Asserts.assertEQ(testValue1Array[index].hash(), vt.hash()); 1056 testValue1Array[index] = testValue1; 1057 try { 1058 test36(testValue2Array, vt, index); 1059 throw new RuntimeException("No ArrayStoreException thrown"); 1060 } catch (ArrayStoreException e) { 1061 // Expected 1062 } 1063 Asserts.assertEQ(testValue2Array[index].hash(), testValue2.hash()); 1064 } 1065 1066 @ForceInline 1067 public void test37_inline(Object[] oa, Object o, int index) { 1068 oa[index] = o; 1069 } 1070 1071 @Test() 1072 public void test37(Object[] oa, MyValue1 vt, int index) { 1073 test37_inline(oa, vt, index); 1074 } 1075 1076 @DontCompile 1077 public void test37_verifier(boolean warmup) { 1078 int index = Math.abs(rI) % 3; 1079 try { 1080 test37(testIntegerArray, testValue1, index); 1081 throw new RuntimeException("No ArrayStoreException thrown"); 1082 } catch (ArrayStoreException e) { 1083 // Expected 1084 } 1085 } 1086 1087 @ForceInline 1088 public void test38_inline(Object[] oa, Object o, int index) { 1089 oa[index] = o; 1090 } 1091 1092 @Test() 1093 public void test38(Object[] oa, MyValue1 vt, int index) { 1094 test38_inline(oa, vt, index); 1095 } 1096 1097 @DontCompile 1098 public void test38_verifier(boolean warmup) { 1099 int index = Math.abs(rI) % 3; 1100 try { 1101 test38(null, testValue1, index); 1102 throw new RuntimeException("No NPE thrown"); 1103 } catch (NullPointerException e) { 1104 // Expected 1105 } 1106 } 1107 1108 // Test value store to (flattened) value type array disguised as interface array 1109 1110 @ForceInline 1111 public void test39_inline(MyInterface[] ia, MyInterface i, int index) { 1112 ia[index] = i; 1113 } 1114 1115 @Test() 1116 public void test39(MyInterface[] ia, MyValue1 vt, int index) { 1117 test39_inline(ia, vt, index); 1118 } 1119 1120 @DontCompile 1121 public void test39_verifier(boolean warmup) { 1122 int index = Math.abs(rI) % 3; 1123 MyValue1 vt = MyValue1.createWithFieldsInline(rI + 1, rL + 1); 1124 test39(testValue1Array, vt, index); 1125 Asserts.assertEQ(testValue1Array[index].hash(), vt.hash()); 1126 testValue1Array[index] = testValue1; 1127 try { 1128 test39(testValue2Array, vt, index); 1129 throw new RuntimeException("No ArrayStoreException thrown"); 1130 } catch (ArrayStoreException e) { 1131 // Expected 1132 } 1133 Asserts.assertEQ(testValue2Array[index].hash(), testValue2.hash()); 1134 } 1135 1136 @ForceInline 1137 public void test40_inline(MyInterface[] ia, MyInterface i, int index) { 1138 ia[index] = i; 1139 } 1140 1141 @Test() 1142 public void test40(MyInterface[] ia, MyValue1 vt, int index) { 1143 test40_inline(ia, vt, index); 1144 } 1145 1146 @DontCompile 1147 public void test40_verifier(boolean warmup) { 1148 int index = Math.abs(rI) % 3; 1149 try { 1150 test40(null, testValue1, index); 1151 throw new RuntimeException("No NPE thrown"); 1152 } catch (NullPointerException e) { 1153 // Expected 1154 } 1155 } 1156 1157 // Test object store to (flattened) value type array disguised as object array 1158 1159 @ForceInline 1160 public void test41_inline(Object[] oa, Object o, int index) { 1161 oa[index] = o; 1162 } 1163 1164 @Test() 1165 public void test41(Object[] oa, Object o, int index) { 1166 test41_inline(oa, o, index); 1167 } 1168 1169 @DontCompile 1170 public void test41_verifier(boolean warmup) { 1171 int index = Math.abs(rI) % 3; 1172 MyValue1 vt1 = MyValue1.createWithFieldsInline(rI + 1, rL + 1); 1173 test41(testValue1Array, vt1, index); 1174 Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash()); 1175 try { 1176 test41(testValue1Array, testValue2, index); 1177 throw new RuntimeException("No ArrayStoreException thrown"); 1178 } catch (ArrayStoreException e) { 1179 // Expected 1180 } 1181 Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash()); 1182 testValue1Array[index] = testValue1; 1183 } 1184 1185 @ForceInline 1186 public void test42_inline(Object[] oa, Object o, int index) { 1187 oa[index] = o; 1188 } 1189 1190 @Test() 1191 public void test42(Object[] oa, Object o, int index) { 1192 test42_inline(oa, o, index); 1193 } 1194 1195 @DontCompile 1196 public void test42_verifier(boolean warmup) { 1197 int index = Math.abs(rI) % 3; 1198 try { 1199 test42(testValue2Array, testValue1, index); 1200 throw new RuntimeException("No ArrayStoreException thrown"); 1201 } catch (ArrayStoreException e) { 1202 // Expected 1203 } 1204 Asserts.assertEQ(testValue2Array[index].hash(), testValue2.hash()); 1205 } 1206 1207 @ForceInline 1208 public void test43_inline(Object[] oa, Object o, int index) { 1209 oa[index] = o; 1210 } 1211 1212 @Test() 1213 public void test43(Object[] oa, Object o, int index) { 1214 test43_inline(oa, o, index); 1215 } 1216 1217 @DontCompile 1218 public void test43_verifier(boolean warmup) { 1219 int index = Math.abs(rI) % 3; 1220 try { 1221 test43(testIntegerArray, testValue1, index); 1222 throw new RuntimeException("No ArrayStoreException thrown"); 1223 } catch (ArrayStoreException e) { 1224 // Expected 1225 } 1226 } 1227 1228 // Test value store to (flattened) value type array disguised as interface array 1229 1230 @ForceInline 1231 public void test44_inline(MyInterface[] ia, MyInterface i, int index) { 1232 ia[index] = i; 1233 } 1234 1235 @Test() 1236 public void test44(MyInterface[] ia, MyInterface i, int index) { 1237 test44_inline(ia, i, index); 1238 } 1239 1240 @DontCompile 1241 public void test44_verifier(boolean warmup) { 1242 int index = Math.abs(rI) % 3; 1243 MyValue1 vt1 = MyValue1.createWithFieldsInline(rI + 1, rL + 1); 1244 test44(testValue1Array, vt1, index); 1245 Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash()); 1246 try { 1247 test44(testValue1Array, testValue2, index); 1248 throw new RuntimeException("No ArrayStoreException thrown"); 1249 } catch (ArrayStoreException e) { 1250 // Expected 1251 } 1252 Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash()); 1253 testValue1Array[index] = testValue1; 1254 } 1255 1256 @ForceInline 1257 public void test45_inline(MyInterface[] ia, MyInterface i, int index) { 1258 ia[index] = i; 1259 } 1260 1261 @Test() 1262 public void test45(MyInterface[] ia, MyInterface i, int index) { 1263 test45_inline(ia, i, index); 1264 } 1265 1266 @DontCompile 1267 public void test45_verifier(boolean warmup) { 1268 int index = Math.abs(rI) % 3; 1269 try { 1270 test45(testValue2Array, testValue1, index); 1271 throw new RuntimeException("No ArrayStoreException thrown"); 1272 } catch (ArrayStoreException e) { 1273 // Expected 1274 } 1275 } 1276 1277 // Test writing null to a (flattened) value type array disguised as object array 1278 1279 @ForceInline 1280 public void test46_inline(Object[] oa, Object o, int index) { 1281 oa[index] = o; 1282 } 1283 1284 @Test() 1285 public void test46(Object[] oa, Object o, int index) { 1286 test46_inline(oa, o, index); 1287 } 1288 1289 @DontCompile 1290 public void test46_verifier(boolean warmup) { 1291 int index = Math.abs(rI) % 3; 1292 try { 1293 test46(testValue1Array, null, index); 1294 throw new RuntimeException("No NPE thrown"); 1295 } catch (NullPointerException e) { 1296 // Expected 1297 } 1298 Asserts.assertEQ(testValue1Array[index].hash(), hash()); 1299 } 1300 1301 // Test writing constant null to a (flattened) value type array disguised as object array 1302 1303 @ForceInline 1304 public void test47_inline(Object[] oa, Object o, int index) { 1305 oa[index] = o; 1306 } 1307 1308 @Test() 1309 public void test47(Object[] oa, int index) { 1310 test47_inline(oa, null, index); 1311 } 1312 1313 @DontCompile 1314 public void test47_verifier(boolean warmup) { 1315 int index = Math.abs(rI) % 3; 1316 try { 1317 test47(testValue1Array, index); 1318 throw new RuntimeException("No NPE thrown"); 1319 } catch (NullPointerException e) { 1320 // Expected 1321 } 1322 Asserts.assertEQ(testValue1Array[index].hash(), hash()); 1323 } 1324 1325 // Test writing null to a (flattened) value type array 1326 1327 @ForceInline 1328 public void test48_inline(Object[] oa, Object o, int index) { 1329 oa[index] = o; 1330 } 1331 1332 @Test() 1333 public void test48(MyValue1[] va, int index) { 1334 test48_inline(va, nullField, index); 1335 } 1336 1337 @DontCompile 1338 public void test48_verifier(boolean warmup) { 1339 int index = Math.abs(rI) % 3; 1340 try { 1341 test48(testValue1Array, index); 1342 throw new RuntimeException("No NPE thrown"); 1343 } catch (NullPointerException e) { 1344 // Expected 1345 } 1346 Asserts.assertEQ(testValue1Array[index].hash(), hash()); 1347 } 1348 1349 // Test writing constant null to a (flattened) value type array 1350 1351 private static final MethodHandle setArrayElementNull = MethodHandleBuilder.loadCode(MethodHandles.lookup(), 1352 "setArrayElementNull", 1353 MethodType.methodType(void.class, TestLWorld.class, MyValue1[].class, int.class), 1354 CODE -> { 1355 CODE. 1356 aload_1(). 1357 iload_2(). 1358 aconst_null(). 1359 aastore(). 1360 return_(); 1361 }, 1362 MyValue1.class); 1363 1364 @Test() 1365 public void test49(MyValue1[] va, int index) throws Throwable { 1366 setArrayElementNull.invoke(this, va, index); 1367 } 1368 1369 @DontCompile 1370 public void test49_verifier(boolean warmup) throws Throwable { 1371 int index = Math.abs(rI) % 3; 1372 try { 1373 test49(testValue1Array, index); 1374 throw new RuntimeException("No NPE thrown"); 1375 } catch (NullPointerException e) { 1376 // Expected 1377 } 1378 Asserts.assertEQ(testValue1Array[index].hash(), hash()); 1379 } 1380 1381 // Test writing a value type to a null value type array 1382 @Test() 1383 public void test50(MyValue1[] va, MyValue1 vt, int index) { 1384 va[index] = vt; 1385 } 1386 1387 @DontCompile 1388 public void test50_verifier(boolean warmup) { 1389 int index = Math.abs(rI) % 3; 1390 try { 1391 test50(null, testValue1Array[index], index); 1392 throw new RuntimeException("No NPE thrown"); 1393 } catch (NullPointerException e) { 1394 // Expected 1395 } 1396 } 1397 1398 // Test incremental inlining 1399 1400 @ForceInline 1401 public void test51_inline(Object[] oa, Object o, int index) { 1402 oa[index] = o; 1403 } 1404 1405 @Test() 1406 public void test51(MyValue1[] va, Object o, int index) { 1407 test51_inline(va, o, index); 1408 } 1409 1410 @DontCompile 1411 public void test51_verifier(boolean warmup) { 1412 int index = Math.abs(rI) % 3; 1413 MyValue1 vt1 = MyValue1.createWithFieldsInline(rI + 1, rL + 1); 1414 test51(testValue1Array, vt1, index); 1415 Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash()); 1416 try { 1417 test51(testValue1Array, testValue2, index); 1418 throw new RuntimeException("No ArrayStoreException thrown"); 1419 } catch (ArrayStoreException e) { 1420 // Expected 1421 } 1422 Asserts.assertEQ(testValue1Array[index].hash(), vt1.hash()); 1423 testValue1Array[index] = testValue1; 1424 } 1425 1426 // Test merging of value type arrays 1427 1428 @ForceInline 1429 public Object[] test52_inline() { 1430 return new MyValue1[42]; 1431 } 1432 1433 @Test() 1434 public Object[] test52(Object[] oa, Object o, int i1, int i2, int num) { 1435 Object[] result = null; 1436 switch (num) { 1437 case 0: 1438 result = test52_inline(); 1439 break; 1440 case 1: 1441 result = oa; 1442 break; 1443 case 2: 1444 result = testValue1Array; 1445 break; 1446 case 3: 1447 result = testValue2Array; 1448 break; 1449 case 4: 1450 result = testIntegerArray; 1451 break; 1452 case 5: 1453 result = null; 1454 break; 1455 case 6: 1456 result = testValue1Array2; 1457 break; 1458 } 1459 result[i1] = result[i2]; 1460 result[i2] = o; 1461 return result; 1462 } 1463 1464 @DontCompile 1465 public void test52_verifier(boolean warmup) { 1466 int index = Math.abs(rI) % 3; 1467 MyValue1[] va = new MyValue1[42]; 1468 Object[] result = test52(null, testValue1, index, index, 0); 1469 Asserts.assertEQ(((MyValue1)result[index]).hash(), testValue1.hash()); 1470 result = test52(testValue1Array, testValue1, index, index, 1); 1471 Asserts.assertEQ(((MyValue1)result[index]).hash(), testValue1.hash()); 1472 result = test52(null, testValue1, index, index, 2); 1473 Asserts.assertEQ(((MyValue1)result[index]).hash(), testValue1.hash()); 1474 result = test52(null, testValue2, index, index, 3); 1475 Asserts.assertEQ(((MyValue2)result[index]).hash(), testValue2.hash()); 1476 try { 1477 result = test52(null, null, index, index, 3); 1478 throw new RuntimeException("No NPE thrown"); 1479 } catch (NullPointerException e) { 1480 // Expected 1481 } 1482 result = test52(null, null, index, index, 4); 1483 try { 1484 result = test52(null, testValue1, index, index, 4); 1485 throw new RuntimeException("No ArrayStoreException thrown"); 1486 } catch (ArrayStoreException e) { 1487 // Expected 1488 } 1489 try { 1490 result = test52(null, testValue1, index, index, 5); 1491 throw new RuntimeException("No NPE thrown"); 1492 } catch (NullPointerException e) { 1493 // Expected 1494 } 1495 result = test52(null, testValue1Array, index, index, 6); 1496 Asserts.assertEQ(((MyValue1[][])result)[index][index].hash(), testValue1.hash()); 1497 } 1498 1499 // Same as above but merging into Object instead of Object[] 1500 @Test() 1501 public Object test53(Object oa, Object o, int i1, int i2, int num) { 1502 Object result = null; 1503 switch (num) { 1504 case 0: 1505 result = test52_inline(); 1506 break; 1507 case 1: 1508 result = oa; 1509 break; 1510 case 2: 1511 result = testValue1Array; 1512 break; 1513 case 3: 1514 result = testValue2Array; 1515 break; 1516 case 4: 1517 result = testIntegerArray; 1518 break; 1519 case 5: 1520 result = null; 1521 break; 1522 case 6: 1523 result = testValue1; 1524 break; 1525 case 7: 1526 result = testValue2; 1527 break; 1528 case 8: 1529 result = MyValue1.createWithFieldsInline(rI, rL); 1530 break; 1531 case 9: 1532 result = new Integer(42); 1533 break; 1534 case 10: 1535 result = testValue1Array2; 1536 break; 1537 } 1538 if (result instanceof Object[]) { 1539 ((Object[])result)[i1] = ((Object[])result)[i2]; 1540 ((Object[])result)[i2] = o; 1541 } 1542 return result; 1543 } 1544 1545 @DontCompile 1546 public void test53_verifier(boolean warmup) { 1547 int index = Math.abs(rI) % 3; 1548 MyValue1[] va = new MyValue1[42]; 1549 Object result = test53(null, testValue1, index, index, 0); 1550 Asserts.assertEQ(((MyValue1[])result)[index].hash(), testValue1.hash()); 1551 result = test53(testValue1Array, testValue1, index, index, 1); 1552 Asserts.assertEQ(((MyValue1[])result)[index].hash(), testValue1.hash()); 1553 result = test53(null, testValue1, index, index, 2); 1554 Asserts.assertEQ(((MyValue1[])result)[index].hash(), testValue1.hash()); 1555 result = test53(null, testValue2, index, index, 3); 1556 Asserts.assertEQ(((MyValue2[])result)[index].hash(), testValue2.hash()); 1557 try { 1558 result = test53(null, null, index, index, 3); 1559 throw new RuntimeException("No NPE thrown"); 1560 } catch (NullPointerException e) { 1561 // Expected 1562 } 1563 result = test53(null, null, index, index, 4); 1564 try { 1565 result = test53(null, testValue1, index, index, 4); 1566 throw new RuntimeException("No ArrayStoreException thrown"); 1567 } catch (ArrayStoreException e) { 1568 // Expected 1569 } 1570 result = test53(null, testValue1, index, index, 5); 1571 Asserts.assertEQ(result, null); 1572 result = test53(null, testValue1, index, index, 6); 1573 Asserts.assertEQ(((MyValue1)result).hash(), testValue1.hash()); 1574 result = test53(null, testValue1, index, index, 7); 1575 Asserts.assertEQ(((MyValue2)result).hash(), testValue2.hash()); 1576 result = test53(null, testValue1, index, index, 8); 1577 Asserts.assertEQ(((MyValue1)result).hash(), testValue1.hash()); 1578 result = test53(null, testValue1, index, index, 9); 1579 Asserts.assertEQ(((Integer)result), 42); 1580 result = test53(null, testValue1Array, index, index, 10); 1581 Asserts.assertEQ(((MyValue1[][])result)[index][index].hash(), testValue1.hash()); 1582 } 1583 1584 // Test instanceof with value types and arrays 1585 @Test() 1586 public long test54(Object o, int index) { 1587 if (o instanceof MyValue1) { 1588 return ((MyValue1)o).hashInterpreted(); 1589 } else if (o instanceof MyValue1[]) { 1590 return ((MyValue1[])o)[index].hashInterpreted(); 1591 } else if (o instanceof MyValue2) { 1592 return ((MyValue2)o).hash(); 1593 } else if (o instanceof MyValue2[]) { 1594 return ((MyValue2[])o)[index].hash(); 1595 } else if (o instanceof MyValue1[][]) { 1596 return ((MyValue1[][])o)[index][index].hash(); 1597 } else if (o instanceof Long) { 1598 return (long)o; 1599 } 1600 return 0; 1601 } 1602 1603 @DontCompile 1604 public void test54_verifier(boolean warmup) { 1605 int index = Math.abs(rI) % 3; 1606 long result = test54(testValue1, 0); 1607 Asserts.assertEQ(result, testValue1.hash()); 1608 result = test54(testValue1Array, index); 1609 Asserts.assertEQ(result, testValue1.hash()); 1610 result = test54(testValue2, index); 1611 Asserts.assertEQ(result, testValue2.hash()); 1612 result = test54(testValue2Array, index); 1613 Asserts.assertEQ(result, testValue2.hash()); 1614 result = test54(testValue1Array2, index); 1615 Asserts.assertEQ(result, testValue1.hash()); 1616 result = test54(new Long(42), index); 1617 Asserts.assertEQ(result, 42L); 1618 } 1619 1620 // Test for bug in Escape Analysis 1621 @DontInline 1622 public void test55_dontinline(Object o) { 1623 Asserts.assertEQ(o, rI); 1624 } 1625 1626 @Test() 1627 public void test55() { 1628 MyValue1[] vals = new MyValue1[] {testValue1}; 1629 test55_dontinline(vals[0].oa[0]); 1630 test55_dontinline(vals[0].oa[0]); 1631 } 1632 1633 @DontCompile 1634 public void test55_verifier(boolean warmup) { 1635 test55(); 1636 } 1637 1638 // Test for bug in Escape Analysis 1639 private static __NotFlattened final MyValue1 test56VT1 = MyValue1.createWithFieldsInline(rI, rL); 1640 private static __NotFlattened final MyValue1 test56VT2 = MyValue1.createWithFieldsInline(rI + 1, rL + 1); 1641 1642 @Test() 1643 public void test56() { 1644 MyValue1[] vals = new MyValue1[] {test56VT1, test56VT2}; 1645 Asserts.assertEQ(vals[0].hash(), test56VT1.hash()); 1646 Asserts.assertEQ(vals[1].hash(), test56VT2.hash()); 1647 } 1648 1649 @DontCompile 1650 public void test56_verifier(boolean warmup) { 1651 if (!warmup) test56(); // We need -Xcomp behavior 1652 } 1653 1654 // Test for bug in Escape Analysis 1655 @Test() 1656 public long test57(boolean deopt) { 1657 MyValue1[] vals = new MyValue1[] {test56VT1, test56VT2}; 1658 1659 if (deopt) { 1660 // uncommon trap 1661 WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test57")); 1662 Asserts.assertEQ(vals[0].hash(), test56VT1.hash()); 1663 Asserts.assertEQ(vals[1].hash(), test56VT2.hash()); 1664 } 1665 1666 return vals[0].hash(); 1667 } 1668 1669 @DontCompile 1670 public void test57_verifier(boolean warmup) { 1671 test57(!warmup); 1672 } 1673 1674 // Tests writing an array element with a (statically known) incompatible type 1675 private static final MethodHandle setArrayElementIncompatible = MethodHandleBuilder.loadCode(MethodHandles.lookup(), 1676 "setArrayElementIncompatible", 1677 MethodType.methodType(void.class, TestLWorld.class, MyValue1[].class, int.class, MyValue2.class), 1678 CODE -> { 1679 CODE. 1680 aload_1(). 1681 iload_2(). 1682 aload_3(). 1683 aastore(). 1684 return_(); 1685 }, 1686 MyValue1.class, MyValue2.class); 1687 1688 @Test() 1689 public void test58(MyValue1[] va, int index, MyValue2 v) throws Throwable { 1690 setArrayElementIncompatible.invoke(this, va, index, v); 1691 } 1692 1693 @DontCompile 1694 public void test58_verifier(boolean warmup) throws Throwable { 1695 int index = Math.abs(rI) % 3; 1696 try { 1697 test58(testValue1Array, index, testValue2); 1698 throw new RuntimeException("No ArrayStoreException thrown"); 1699 } catch (ArrayStoreException e) { 1700 // Expected 1701 } 1702 Asserts.assertEQ(testValue1Array[index].hash(), hash()); 1703 } 1704 1705 // Tests writing an array element with a (statically known) incompatible type 1706 @ForceInline 1707 public void test59_inline(Object[] oa, Object o, int index) { 1708 oa[index] = o; 1709 } 1710 1711 @Test() 1712 public void test59(MyValue1[] va, int index, MyValue2 v) throws Throwable { 1713 test59_inline(va, v, index); 1714 } 1715 1716 @DontCompile 1717 public void test59_verifier(boolean warmup) throws Throwable { 1718 int index = Math.abs(rI) % 3; 1719 try { 1720 test59(testValue1Array, index, testValue2); 1721 throw new RuntimeException("No ArrayStoreException thrown"); 1722 } catch (ArrayStoreException e) { 1723 // Expected 1724 } 1725 Asserts.assertEQ(testValue1Array[index].hash(), hash()); 1726 } 1727 1728 // instanceof tests with values 1729 @Test 1730 public boolean test60(MyValue1 vt) { 1731 Object obj = vt; 1732 return obj instanceof MyValue1; 1733 } 1734 1735 @DontCompile 1736 public void test60_verifier(boolean warmup) { 1737 MyValue1 vt = testValue1; 1738 boolean result = test60(vt); 1739 Asserts.assertTrue(result); 1740 } 1741 1742 @Test 1743 public boolean test61(MyValue1 vt) { 1744 Object obj = vt; 1745 return obj instanceof MyValue2; 1746 } 1747 1748 @DontCompile 1749 public void test61_verifier(boolean warmup) { 1750 MyValue1 vt = testValue1; 1751 boolean result = test61(vt); 1752 Asserts.assertFalse(result); 1753 } 1754 1755 @Test 1756 public boolean test62(Object obj) { 1757 return obj instanceof MyValue1; 1758 } 1759 1760 @DontCompile 1761 public void test62_verifier(boolean warmup) { 1762 MyValue1 vt = testValue1; 1763 boolean result = test62(vt); 1764 Asserts.assertTrue(result); 1765 } 1766 1767 @Test 1768 public boolean test63(Object obj) { 1769 return obj instanceof MyValue2; 1770 } 1771 1772 @DontCompile 1773 public void test63_verifier(boolean warmup) { 1774 MyValue1 vt = testValue1; 1775 boolean result = test63(vt); 1776 Asserts.assertFalse(result); 1777 } 1778 1779 @Test 1780 public boolean test64(Object obj) { 1781 return obj instanceof MyValue1; 1782 } 1783 1784 @DontCompile 1785 public void test64_verifier(boolean warmup) { 1786 boolean result = test63(new Integer(42)); 1787 Asserts.assertFalse(result); 1788 } 1789 1790 // Value type with some non-flattened fields 1791 value final class Test65Value { 1792 final Object objectField1 = null; 1793 final Object objectField2 = null; 1794 final Object objectField3 = null; 1795 final Object objectField4 = null; 1796 final Object objectField5 = null; 1797 final Object objectField6 = null; 1798 1799 final __Flattenable MyValue1 valueField1; 1800 final __Flattenable MyValue1 valueField2; 1801 final __NotFlattened MyValue1 valueField3; 1802 final __Flattenable MyValue1 valueField4; 1803 final __NotFlattened MyValue1 valueField5; 1804 1805 private Test65Value() { 1806 valueField1 = testValue1; 1807 valueField2 = testValue1; 1808 valueField3 = testValue1; 1809 valueField4 = MyValue1.createDefaultDontInline(); 1810 valueField5 = MyValue1.createDefaultDontInline(); 1811 } 1812 1813 public Test65Value init() { 1814 Test65Value vt = __WithField(this.valueField1, testValue1); 1815 vt = __WithField(vt.valueField2, testValue1); 1816 vt = __WithField(vt.valueField3, testValue1); 1817 return vt; 1818 } 1819 1820 @ForceInline 1821 public long test(Test65Value holder, MyValue1 vt1, Object vt2) { 1822 holder = __WithField(holder.objectField1, vt1); 1823 holder = __WithField(holder.objectField2, (MyValue1)vt2); 1824 holder = __WithField(holder.objectField3, testValue1); 1825 holder = __WithField(holder.objectField4, MyValue1.createWithFieldsDontInline(rI, rL)); 1826 holder = __WithField(holder.objectField5, holder.valueField1); 1827 holder = __WithField(holder.objectField6, holder.valueField3); 1828 holder = __WithField(holder.valueField1, (MyValue1)holder.objectField1); 1829 holder = __WithField(holder.valueField2, (MyValue1)vt2); 1830 holder = __WithField(holder.valueField3, (MyValue1)vt2); 1831 1832 return ((MyValue1)holder.objectField1).hash() + 1833 ((MyValue1)holder.objectField2).hash() + 1834 ((MyValue1)holder.objectField3).hash() + 1835 ((MyValue1)holder.objectField4).hash() + 1836 ((MyValue1)holder.objectField5).hash() + 1837 ((MyValue1)holder.objectField6).hash() + 1838 holder.valueField1.hash() + 1839 holder.valueField2.hash() + 1840 holder.valueField3.hash() + 1841 holder.valueField4.hashPrimitive(); 1842 } 1843 } 1844 1845 // Same as test2 but with field holder being a value type 1846 @Test() 1847 public long test65(Test65Value holder, MyValue1 vt1, Object vt2) { 1848 return holder.test(holder, vt1, vt2); 1849 } 1850 1851 @DontCompile 1852 public void test65_verifier(boolean warmup) { 1853 MyValue1 vt = testValue1; 1854 MyValue1 def = MyValue1.createDefaultDontInline(); 1855 Test65Value holder = Test65Value.default; 1856 Asserts.assertEQ(testValue1.hash(), vt.hash()); 1857 holder = holder.init(); 1858 Asserts.assertEQ(holder.valueField1.hash(), vt.hash()); 1859 long result = test65(holder, vt, vt); 1860 Asserts.assertEQ(result, 9*vt.hash() + def.hashPrimitive()); 1861 } 1862 1863 // Access non-flattened, uninitialized value type field with value type holder 1864 @Test() 1865 public void test66(Test65Value holder) { 1866 if ((Object)holder.valueField5 != null) { 1867 throw new RuntimeException("Should be null"); 1868 } 1869 } 1870 1871 @DontCompile 1872 public void test66_verifier(boolean warmup) { 1873 Test65Value vt = Test65Value.default; 1874 test66(vt); 1875 } 1876 1877 // Merging value types of different types 1878 @Test() 1879 public Object test67(Object o, boolean b) { 1880 MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); 1881 return b ? vt : o; 1882 } 1883 1884 @DontCompile 1885 public void test67_verifier(boolean warmup) { 1886 test67(new Object(), false); 1887 MyValue1 result = (MyValue1)test67(new Object(), true); 1888 Asserts.assertEQ(result.hash(), hash()); 1889 } 1890 1891 @Test() 1892 public Object test68(boolean b) { 1893 MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); 1894 return b ? vt : testValue2; 1895 } 1896 1897 @DontCompile 1898 public void test68_verifier(boolean warmup) { 1899 MyValue1 result1 = (MyValue1)test68(true); 1900 Asserts.assertEQ(result1.hash(), hash()); 1901 MyValue2 result2 = (MyValue2)test68(false); 1902 Asserts.assertEQ(result2.hash(), testValue2.hash()); 1903 } 1904 1905 @Test() 1906 public Object test69(boolean b) { 1907 MyValue1 vt1 = MyValue1.createWithFieldsInline(rI, rL); 1908 MyValue2 vt2 = MyValue2.createWithFieldsInline(rI, true); 1909 return b ? vt1 : vt2; 1910 } 1911 1912 @DontCompile 1913 public void test69_verifier(boolean warmup) { 1914 MyValue1 result1 = (MyValue1)test69(true); 1915 Asserts.assertEQ(result1.hash(), hash()); 1916 MyValue2 result2 = (MyValue2)test69(false); 1917 Asserts.assertEQ(result2.hash(), testValue2.hash()); 1918 } 1919 1920 // Test synchronization on value types 1921 @Test() 1922 public void test70(Object vt) { 1923 synchronized (vt) { 1924 throw new RuntimeException("test70 failed: synchronization on value type should not succeed"); 1925 } 1926 } 1927 1928 @DontCompile 1929 public void test70_verifier(boolean warmup) { 1930 try { 1931 test70(testValue1); 1932 throw new RuntimeException("test70 failed: no exception thrown"); 1933 } catch (IllegalMonitorStateException ex) { 1934 // Expected 1935 } 1936 } 1937 1938 @ForceInline 1939 public void test71_inline(Object vt) { 1940 synchronized (vt) { 1941 throw new RuntimeException("test71 failed: synchronization on value type should not succeed"); 1942 } 1943 } 1944 1945 @Test() 1946 public void test71(MyValue1 vt) { 1947 test71_inline(vt); 1948 } 1949 1950 @DontCompile 1951 public void test71_verifier(boolean warmup) { 1952 try { 1953 test71(testValue1); 1954 throw new RuntimeException("test71 failed: no exception thrown"); 1955 } catch (IllegalMonitorStateException ex) { 1956 // Expected 1957 } 1958 } 1959 1960 @ForceInline 1961 public void test72_inline(Object vt) { 1962 synchronized (vt) { 1963 throw new RuntimeException("test72 failed: synchronization on value type should not succeed"); 1964 } 1965 } 1966 1967 @Test() 1968 public void test72() { 1969 MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); 1970 test72_inline(vt); 1971 } 1972 1973 @DontCompile 1974 public void test72_verifier(boolean warmup) { 1975 try { 1976 test72(); 1977 throw new RuntimeException("test72 failed: no exception thrown"); 1978 } catch (IllegalMonitorStateException ex) { 1979 // Expected 1980 } 1981 } 1982 1983 @Test() 1984 public void test73(Object o, boolean b) { 1985 MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); 1986 Object sync = b ? vt : o; 1987 synchronized (sync) { 1988 if (b) { 1989 throw new RuntimeException("test73 failed: synchronization on value type should not succeed"); 1990 } 1991 } 1992 } 1993 1994 @DontCompile 1995 public void test73_verifier(boolean warmup) { 1996 test73(new Object(), false); 1997 try { 1998 test73(new Object(), true); 1999 throw new RuntimeException("test73 failed: no exception thrown"); 2000 } catch (IllegalMonitorStateException ex) { 2001 // Expected 2002 } 2003 } 2004 2005 @Test() 2006 public void test74(boolean b) { 2007 MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); 2008 Object sync = b ? vt : testValue2; 2009 synchronized (sync) { 2010 throw new RuntimeException("test74 failed: synchronization on value type should not succeed"); 2011 } 2012 } 2013 2014 @DontCompile 2015 public void test74_verifier(boolean warmup) { 2016 try { 2017 test74(false); 2018 throw new RuntimeException("test74 failed: no exception thrown"); 2019 } catch (IllegalMonitorStateException ex) { 2020 // Expected 2021 } 2022 try { 2023 test74(true); 2024 throw new RuntimeException("test74 failed: no exception thrown"); 2025 } catch (IllegalMonitorStateException ex) { 2026 // Expected 2027 } 2028 } 2029 2030 // Test catching the IllegalMonitorStateException in compiled code 2031 @Test() 2032 public void test75(Object vt) { 2033 boolean thrown = false; 2034 try { 2035 synchronized (vt) { 2036 throw new RuntimeException("test75 failed: no exception thrown"); 2037 } 2038 } catch (IllegalMonitorStateException ex) { 2039 thrown = true; 2040 } 2041 if (!thrown) { 2042 throw new RuntimeException("test75 failed: no exception thrown"); 2043 } 2044 } 2045 2046 @DontCompile 2047 public void test75_verifier(boolean warmup) { 2048 test75(testValue1); 2049 } 2050 2051 @Test() 2052 public void test76(Object o) { 2053 try { 2054 synchronized (o) { } 2055 } catch (IllegalMonitorStateException ex) { 2056 // Expected 2057 return; 2058 } 2059 throw new RuntimeException("test76 failed: no exception thrown"); 2060 } 2061 2062 @DontCompile 2063 public void test76_verifier(boolean warmup) { 2064 test76(testValue1); 2065 } 2066 2067 // Test synchronization without any instructions in the synchronized block 2068 @Test() 2069 public void test77(Object o) { 2070 synchronized (o) { } 2071 } 2072 2073 @DontCompile 2074 public void test77_verifier(boolean warmup) { 2075 try { 2076 test77(testValue1); 2077 } catch (IllegalMonitorStateException ex) { 2078 // Expected 2079 return; 2080 } 2081 throw new RuntimeException("test77 failed: no exception thrown"); 2082 } 2083 2084 // type system test with interface and value type 2085 @ForceInline 2086 public MyInterface test78_helper(MyValue1 vt) { 2087 return vt; 2088 } 2089 2090 @Test() 2091 public MyInterface test78(MyValue1 vt) { 2092 return test78_helper(vt); 2093 } 2094 2095 @DontCompile 2096 public void test78_verifier(boolean warmup) { 2097 test78(testValue1); 2098 } 2099 2100 // Array store tests 2101 @Test() 2102 public void test79(Object[] array, MyValue1 vt) { 2103 array[0] = vt; 2104 } 2105 2106 @DontCompile 2107 public void test79_verifier(boolean warmup) { 2108 Object[] array = new Object[1]; 2109 test79(array, testValue1); 2110 Asserts.assertEQ(((MyValue1)array[0]).hash(), testValue1.hash()); 2111 } 2112 2113 @Test() 2114 public void test80(Object[] array, MyValue1 vt) { 2115 array[0] = vt; 2116 } 2117 2118 @DontCompile 2119 public void test80_verifier(boolean warmup) { 2120 MyValue1[] array = new MyValue1[1]; 2121 test80(array, testValue1); 2122 Asserts.assertEQ(array[0].hash(), testValue1.hash()); 2123 } 2124 2125 @Test() 2126 public void test81(Object[] array, Object vt) { 2127 array[0] = vt; 2128 } 2129 2130 @DontCompile 2131 public void test81_verifier(boolean warmup) { 2132 MyValue1[] array = new MyValue1[1]; 2133 test81(array, testValue1); 2134 Asserts.assertEQ(array[0].hash(), testValue1.hash()); 2135 } 2136 2137 @Test() 2138 public void test82(Object[] array, Integer o) { 2139 array[0] = o; 2140 } 2141 2142 @DontCompile 2143 public void test82_verifier(boolean warmup) { 2144 Integer[] array = new Integer[1]; 2145 test82(array, 1); 2146 Asserts.assertEQ(array[0], Integer.valueOf(1)); 2147 } 2148 2149 // Test convertion between a value type and java.lang.Object without an allocation 2150 @ForceInline 2151 public Object test83_sum(Object a, Object b) { 2152 int sum = ((MyValue1)a).x + ((MyValue1)b).x; 2153 return MyValue1.setX(((MyValue1)a), sum); 2154 } 2155 2156 @Test(failOn = ALLOC + STORE) 2157 public int test83(Object[] array) { 2158 MyValue1 result = MyValue1.createDefaultInline(); 2159 for (int i = 0; i < array.length; ++i) { 2160 result = (MyValue1)test83_sum(result, (MyValue1)array[i]); 2161 } 2162 return result.x; 2163 } 2164 2165 @DontCompile 2166 public void test83_verifier(boolean warmup) { 2167 int result = test83(testValue1Array); 2168 Asserts.assertEQ(result, rI * testValue1Array.length); 2169 } 2170 2171 // Same as test84 but with an Interface 2172 @ForceInline 2173 public MyInterface test84_sum(MyInterface a, MyInterface b) { 2174 int sum = ((MyValue1)a).x + ((MyValue1)b).x; 2175 return MyValue1.setX(((MyValue1)a), sum); 2176 } 2177 2178 @Test(failOn = ALLOC + STORE) 2179 public int test84(MyInterface[] array) { 2180 MyValue1 result = MyValue1.createDefaultInline(); 2181 for (int i = 0; i < array.length; ++i) { 2182 result = (MyValue1)test84_sum(result, (MyValue1)array[i]); 2183 } 2184 return result.x; 2185 } 2186 2187 @DontCompile 2188 public void test84_verifier(boolean warmup) { 2189 int result = test84(testValue1Array); 2190 Asserts.assertEQ(result, rI * testValue1Array.length); 2191 } 2192 2193 // Test that allocated value type is not used in non-dominated path 2194 public MyValue1 test85_inline(Object obj) { 2195 MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); 2196 try { 2197 vt = (MyValue1)obj; 2198 throw new RuntimeException("NullPointerException expected"); 2199 } catch (NullPointerException e) { 2200 // Expected 2201 } 2202 return vt; 2203 } 2204 2205 @Test 2206 public MyValue1 test85() { 2207 return test85_inline(null); 2208 } 2209 2210 @DontCompile 2211 public void test85_verifier(boolean warmup) { 2212 MyValue1 vt = test85(); 2213 Asserts.assertEquals(vt.hash(), hash()); 2214 } 2215 2216 // Test calling a method on an uninitialized value type 2217 value final class Test86Value { 2218 final int x = 42; 2219 public int get() { 2220 return x; 2221 } 2222 } 2223 2224 // Make sure Test86Value is loaded but not initialized 2225 public void unused(Test86Value vt) { } 2226 2227 @Test 2228 @Warmup(0) 2229 public int test86() { 2230 Test86Value vt = Test86Value.default; 2231 return vt.get(); 2232 } 2233 2234 @DontCompile 2235 public void test86_verifier(boolean warmup) { 2236 int result = test86(); 2237 Asserts.assertEquals(result, 0); 2238 } 2239 2240 @DontInline 2241 MyValue1 get_nullField() { 2242 return nullField; 2243 } 2244 2245 // A callees that returns a VT performs null check (and deoptimizes caller) before returning. 2246 @Test(match = {"CallStaticJava.*TestLWorld::get_nullField compiler/valhalla/valuetypes/MyValue1:NotNull"}, matchCount = {2}) 2247 public void test87() { 2248 try { 2249 valueField1 = get_nullField(); 2250 throw new RuntimeException("NullPointerException expected"); 2251 } catch (NullPointerException e) { 2252 // Expected 2253 } 2254 2255 nullField = get_nullField(); // should not throw 2256 } 2257 2258 @DontCompile 2259 public void test87_verifier(boolean warmup) { 2260 test87(); 2261 } 2262 2263 // A callee that's not aware of VT may return a null to the caller. An 2264 // explicit null check is needed in compiled code. 2265 @Test(failOn = "CallStaticJava.*TestLWorld_mismatched::test88_callee compiler/valhalla/valuetypes/MyValue1:NotNull") 2266 public void test88() { 2267 TestLWorld_mismatched.test88(); 2268 } 2269 2270 @DontCompile 2271 public void test88_verifier(boolean warmup) { 2272 test88(); 2273 } 2274 2275 // Tests for loading/storing unkown values 2276 @Test 2277 public Object test89(Object[] va) { 2278 return va[0]; 2279 } 2280 2281 @DontCompile 2282 public void test89_verifier(boolean warmup) { 2283 MyValue1 vt = (MyValue1)test89(testValue1Array); 2284 Asserts.assertEquals(testValue1Array[0].hash(), vt.hash()); 2285 } 2286 2287 @Test 2288 public void test90(Object[] va, Object vt) { 2289 va[0] = vt; 2290 } 2291 2292 @DontCompile 2293 public void test90_verifier(boolean warmup) { 2294 MyValue1[] va = new MyValue1[1]; 2295 test90(va, testValue1); 2296 Asserts.assertEquals(va[0].hash(), testValue1.hash()); 2297 } 2298 2299 // Verify that mixing instances and arrays with the clone api 2300 // doesn't break anything 2301 @Test 2302 public Object test91(Object o) { 2303 MyValue1[] va = new MyValue1[1]; 2304 Object[] next = va; 2305 Object[] arr = va; 2306 for (int i = 0; i < 10; i++) { 2307 arr = next; 2308 next = new Integer[1]; 2309 } 2310 return arr[0]; 2311 } 2312 2313 @DontCompile 2314 public void test91_verifier(boolean warmup) { 2315 test91(42); 2316 } 2317 2318 @DontInline 2319 public boolean test92_dontinline(MyValue1 vt) { 2320 return (Object)vt == null; 2321 } 2322 2323 // Test c2c call passing null for a value type 2324 @Test 2325 @Warmup(10000) // Warmup to make sure 'test92_dontinline' is compiled 2326 public boolean test92(Object arg) throws Exception { 2327 Method test92method = getClass().getMethod("test92_dontinline", MyValue1.class); 2328 return (boolean)test92method.invoke(this, arg); 2329 } 2330 2331 @DontCompile 2332 public void test92_verifier(boolean warmup) throws Exception { 2333 boolean res = test92(null); 2334 Asserts.assertTrue(res); 2335 } 2336 2337 // Cast an Integer to a value type 2338 private static final MethodHandle castIntegerToValue = MethodHandleBuilder.loadCode(MethodHandles.lookup(), 2339 "castIntegerToValue", 2340 MethodType.methodType(void.class, TestLWorld.class, Integer.class), 2341 CODE -> { 2342 CODE. 2343 aload_1(). 2344 checkcast(MyValue1.class). 2345 return_(); 2346 }, 2347 MyValue1.class); 2348 2349 // Casting a null Integer to a value type should throw an exception 2350 @Test 2351 public void test93(Integer i) throws Throwable { 2352 castIntegerToValue.invoke(this, i); 2353 } 2354 2355 @DontCompile 2356 public void test93_verifier(boolean warmup) throws Throwable { 2357 try { 2358 test93(null); 2359 // TODO enable this once we've fixed the interpreter to throw a NPE 2360 // throw new RuntimeException("ClassCastException expected"); 2361 } catch (ClassCastException e) { 2362 // Expected 2363 } 2364 } 2365 }