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