1 /* 2 * Copyright (c) 2019, 2020, 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.test.lib.Asserts; 30 31 /* 32 * @test 33 * @summary Test correct handling of nullable value types. 34 * @library /testlibrary /test/lib /compiler/whitebox / 35 * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") 36 * @compile TestNullableValueTypes.java 37 * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform 38 * @run main/othervm/timeout=300 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions 39 * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI 40 * compiler.valhalla.valuetypes.ValueTypeTest 41 * compiler.valhalla.valuetypes.TestNullableValueTypes 42 */ 43 public class TestNullableValueTypes extends ValueTypeTest { 44 // Extra VM parameters for some test scenarios. See ValueTypeTest.getVMParameters() 45 @Override 46 public String[] getExtraVMParameters(int scenario) { 47 switch (scenario) { 48 case 1: return new String[] {"-XX:-UseOptoBiasInlining"}; 49 case 2: return new String[] {"-XX:-UseBiasedLocking"}; 50 case 3: return new String[] {"-XX:-MonomorphicArrayCheck", "-XX:-UseBiasedLocking", "-XX:ValueArrayElemMaxFlatSize=-1"}; 51 case 4: return new String[] {"-XX:-MonomorphicArrayCheck"}; 52 } 53 return null; 54 } 55 56 public static void main(String[] args) throws Throwable { 57 TestNullableValueTypes test = new TestNullableValueTypes(); 58 test.run(args, MyValue1.class, MyValue2.class, MyValue2Inline.class, Test17Value.class, Test21Value.class); 59 } 60 61 static { 62 try { 63 Class<?> clazz = TestNullableValueTypes.class; 64 MethodHandles.Lookup lookup = MethodHandles.lookup(); 65 66 MethodType test18_mt = MethodType.methodType(void.class, MyValue1.class.asNullableType()); 67 test18_mh1 = lookup.findStatic(clazz, "test18_target1", test18_mt); 68 test18_mh2 = lookup.findStatic(clazz, "test18_target2", test18_mt); 69 70 MethodType test19_mt = MethodType.methodType(void.class, MyValue1.class.asNullableType()); 71 test19_mh1 = lookup.findStatic(clazz, "test19_target1", test19_mt); 72 test19_mh2 = lookup.findStatic(clazz, "test19_target2", test19_mt); 73 } catch (NoSuchMethodException | IllegalAccessException e) { 74 e.printStackTrace(); 75 throw new RuntimeException("Method handle lookup failed"); 76 } 77 } 78 79 private static final MyValue1 testValue1 = MyValue1.createWithFieldsInline(rI, rL); 80 private static final MyValue1[] testValue1Array = new MyValue1[] {testValue1, 81 testValue1, 82 testValue1}; 83 84 MyValue1? nullField; 85 MyValue1 valueField1 = testValue1; 86 87 @Test 88 public long test1(MyValue1? vt) { 89 long result = 0; 90 try { 91 result = vt.hash(); 92 throw new RuntimeException("NullPointerException expected"); 93 } catch (NullPointerException e) { 94 // Expected 95 } 96 return result; 97 } 98 99 @DontCompile 100 public void test1_verifier(boolean warmup) throws Throwable { 101 long result = test1(null); 102 Asserts.assertEquals(result, 0L); 103 } 104 105 @Test 106 public long test2(MyValue1? vt) { 107 long result = 0; 108 try { 109 result = vt.hashInterpreted(); 110 throw new RuntimeException("NullPointerException expected"); 111 } catch (NullPointerException e) { 112 // Expected 113 } 114 return result; 115 } 116 117 @DontCompile 118 public void test2_verifier(boolean warmup) { 119 long result = test2(nullField); 120 Asserts.assertEquals(result, 0L); 121 } 122 123 @Test 124 public long test3() { 125 long result = 0; 126 try { 127 if ((Object)nullField != null) { 128 throw new RuntimeException("nullField should be null"); 129 } 130 result = nullField.hash(); 131 throw new RuntimeException("NullPointerException expected"); 132 } catch (NullPointerException e) { 133 // Expected 134 } 135 return result; 136 } 137 138 @DontCompile 139 public void test3_verifier(boolean warmup) { 140 long result = test3(); 141 Asserts.assertEquals(result, 0L); 142 } 143 144 @Test 145 public void test4() { 146 try { 147 valueField1 = (MyValue1) nullField; 148 throw new RuntimeException("NullPointerException expected"); 149 } catch (NullPointerException e) { 150 // Expected 151 } 152 } 153 154 @DontCompile 155 public void test4_verifier(boolean warmup) { 156 test4(); 157 } 158 159 @Test 160 public MyValue1? test5(MyValue1? vt) { 161 try { 162 Object o = vt; 163 vt = (MyValue1)o; 164 throw new RuntimeException("NullPointerException expected"); 165 } catch (NullPointerException e) { 166 // Expected 167 } 168 169 // Should not throw 170 vt = test5_dontinline(vt); 171 vt = test5_inline(vt); 172 return vt; 173 } 174 175 @DontCompile 176 public void test5_verifier(boolean warmup) { 177 MyValue1? vt = test5(nullField); 178 Asserts.assertEquals((Object)vt, null); 179 } 180 181 @DontInline 182 public MyValue1? test5_dontinline(MyValue1? vt) { 183 return vt; 184 } 185 186 @ForceInline 187 public MyValue1? test5_inline(MyValue1? vt) { 188 return vt; 189 } 190 191 @Test 192 public MyValue1 test6(Object obj) { 193 MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); 194 try { 195 vt = (MyValue1)obj; 196 throw new RuntimeException("NullPointerException expected"); 197 } catch (NullPointerException e) { 198 // Expected 199 } 200 return vt; 201 } 202 203 @DontCompile 204 public void test6_verifier(boolean warmup) { 205 MyValue1 vt = test6(null); 206 Asserts.assertEquals(vt.hash(), testValue1.hash()); 207 } 208 209 @ForceInline 210 public MyValue1? getNullInline() { 211 return null; 212 } 213 214 @DontInline 215 public MyValue1? getNullDontInline() { 216 return null; 217 } 218 219 @Test 220 public void test7() throws Throwable { 221 nullField = getNullInline(); // Should not throw 222 nullField = getNullDontInline(); // Should not throw 223 try { 224 valueField1 = (MyValue1) getNullInline(); 225 throw new RuntimeException("NullPointerException expected"); 226 } catch (NullPointerException e) { 227 // Expected 228 } 229 try { 230 valueField1 = (MyValue1) getNullDontInline(); 231 throw new RuntimeException("NullPointerException expected"); 232 } catch (NullPointerException e) { 233 // Expected 234 } 235 } 236 237 @DontCompile 238 public void test7_verifier(boolean warmup) throws Throwable { 239 test7(); 240 } 241 242 @Test 243 public void test8() throws Throwable { 244 try { 245 valueField1 = (MyValue1) nullField; 246 throw new RuntimeException("NullPointerException expected"); 247 } catch (NullPointerException e) { 248 // Expected 249 } 250 } 251 252 @DontCompile 253 public void test8_verifier(boolean warmup) throws Throwable { 254 test8(); 255 } 256 257 // merge of 2 values, one being null 258 @Test 259 public void test9(boolean flag1) { 260 MyValue1 v; 261 if (flag1) { 262 v = valueField1; 263 } else { 264 v = (MyValue1) nullField; 265 } 266 valueField1 = v; 267 } 268 269 @DontCompile 270 public void test9_verifier(boolean warmup) { 271 test9(true); 272 try { 273 test9(false); 274 throw new RuntimeException("NullPointerException expected"); 275 } catch (NullPointerException e) { 276 // Expected 277 } 278 } 279 280 // null constant 281 @Test 282 public void test10(boolean flag) throws Throwable { 283 MyValue1? val = flag ? valueField1 : null; 284 valueField1 = (MyValue1) val; 285 } 286 287 @DontCompile 288 public void test10_verifier(boolean warmup) throws Throwable { 289 test10(true); 290 try { 291 test10(false); 292 throw new RuntimeException("NullPointerException expected"); 293 } catch (NullPointerException e) { 294 // Expected 295 } 296 } 297 298 // null constant 299 @Test 300 public void test11(boolean flag) throws Throwable { 301 MyValue1? val = flag ? null : valueField1; 302 valueField1 = (MyValue1) val; 303 } 304 305 @DontCompile 306 public void test11_verifier(boolean warmup) throws Throwable { 307 test11(false); 308 try { 309 test11(true); 310 throw new RuntimeException("NullPointerException expected"); 311 } catch (NullPointerException e) { 312 // Expected 313 } 314 } 315 316 // null return 317 int test12_cnt; 318 319 @DontInline 320 public MyValue1? test12_helper() { 321 test12_cnt++; 322 return nullField; 323 } 324 325 @Test 326 public void test12() { 327 valueField1 = (MyValue1) test12_helper(); 328 } 329 330 @DontCompile 331 public void test12_verifier(boolean warmup) { 332 try { 333 test12_cnt = 0; 334 test12(); 335 throw new RuntimeException("NullPointerException expected"); 336 } catch (NullPointerException e) { 337 // Expected 338 } 339 if (test12_cnt != 1) { 340 throw new RuntimeException("call executed twice"); 341 } 342 } 343 344 // null return at virtual call 345 class A { 346 public MyValue1? test13_helper() { 347 return nullField; 348 } 349 } 350 351 class B extends A { 352 public MyValue1 test13_helper() { 353 return (MyValue1) nullField; 354 } 355 } 356 357 class C extends A { 358 public MyValue1? test13_helper() { 359 return nullField; 360 } 361 } 362 363 class D extends C { 364 public MyValue1 test13_helper() { 365 return (MyValue1) nullField; 366 } 367 } 368 369 @Test 370 public void test13(A a) { 371 valueField1 = (MyValue1) a.test13_helper(); 372 } 373 374 @DontCompile 375 public void test13_verifier(boolean warmup) { 376 A a = new A(); 377 A b = new B(); 378 A c = new C(); 379 A d = new D(); 380 try { 381 test13(a); 382 throw new RuntimeException("NullPointerException expected"); 383 } catch (NullPointerException e) { 384 // Expected 385 } 386 try { 387 test13(b); 388 throw new RuntimeException("NullPointerException expected"); 389 } catch (NullPointerException e) { 390 // Expected 391 } 392 try { 393 test13(c); 394 throw new RuntimeException("NullPointerException expected"); 395 } catch (NullPointerException e) { 396 // Expected 397 } 398 try { 399 test13(d); 400 throw new RuntimeException("NullPointerException expected"); 401 } catch (NullPointerException e) { 402 // Expected 403 } 404 } 405 406 // Test writing null to a (flattened) value type array 407 @ForceInline 408 public void test14_inline(Object[] oa, Object o, int index) { 409 oa[index] = o; 410 } 411 412 @Test() 413 public void test14(MyValue1[] va, int index) { 414 test14_inline(va, nullField, index); 415 } 416 417 @DontCompile 418 public void test14_verifier(boolean warmup) { 419 int index = Math.abs(rI) % 3; 420 try { 421 test14(testValue1Array, index); 422 throw new RuntimeException("No NPE thrown"); 423 } catch (NullPointerException e) { 424 // Expected 425 } 426 Asserts.assertEQ(testValue1Array[index].hash(), testValue1.hash()); 427 } 428 429 @DontInline 430 MyValue1? getNullField1() { 431 return nullField; 432 } 433 434 @DontInline 435 MyValue1 getNullField2() { 436 return (MyValue1) nullField; 437 } 438 439 @Test() 440 public void test15() { 441 nullField = getNullField1(); // should not throw 442 try { 443 valueField1 = (MyValue1) getNullField1(); 444 throw new RuntimeException("NullPointerException expected"); 445 } catch (NullPointerException e) { 446 // Expected 447 } 448 try { 449 valueField1 = getNullField2(); 450 throw new RuntimeException("NullPointerException expected"); 451 } catch (NullPointerException e) { 452 // Expected 453 } 454 } 455 456 @DontCompile 457 public void test15_verifier(boolean warmup) { 458 test15(); 459 } 460 461 @DontInline 462 public boolean test16_dontinline(MyValue1? vt) { 463 return (Object)vt == null; 464 } 465 466 // Test c2c call passing null for a value type 467 @Test 468 @Warmup(10000) // Warmup to make sure 'test17_dontinline' is compiled 469 public boolean test16(Object arg) throws Exception { 470 Method test16method = getClass().getMethod("test16_dontinline", MyValue1.class.asNullableType()); 471 return (boolean)test16method.invoke(this, arg); 472 } 473 474 @DontCompile 475 public void test16_verifier(boolean warmup) throws Exception { 476 boolean res = test16(null); 477 Asserts.assertTrue(res); 478 } 479 480 // Test scalarization of default value type with non-flattenable field 481 final inline class Test17Value { 482 public final MyValue1? valueField; 483 484 @ForceInline 485 public Test17Value(MyValue1? valueField) { 486 this.valueField = valueField; 487 } 488 } 489 490 @Test() 491 public Test17Value test17(boolean b) { 492 Test17Value vt1 = Test17Value.default; 493 if ((Object)vt1.valueField != null) { 494 throw new RuntimeException("Should be null"); 495 } 496 Test17Value vt2 = new Test17Value(testValue1); 497 return b ? vt1 : vt2; 498 } 499 500 @DontCompile 501 public void test17_verifier(boolean warmup) { 502 test17(true); 503 test17(false); 504 } 505 506 static final MethodHandle test18_mh1; 507 static final MethodHandle test18_mh2; 508 509 static MyValue1? nullValue; 510 511 @DontInline 512 static void test18_target1(MyValue1? vt) { 513 nullValue = vt; 514 } 515 516 @ForceInline 517 static void test18_target2(MyValue1? vt) { 518 nullValue = vt; 519 } 520 521 // Test passing null for a value type 522 @Test 523 @Warmup(11000) // Make sure lambda forms get compiled 524 public void test18() throws Throwable { 525 test18_mh1.invokeExact(nullValue); 526 test18_mh2.invokeExact(nullValue); 527 } 528 529 @DontCompile 530 public void test18_verifier(boolean warmup) { 531 try { 532 test18(); 533 } catch (Throwable t) { 534 throw new RuntimeException("test18 failed", t); 535 } 536 } 537 538 static MethodHandle test19_mh1; 539 static MethodHandle test19_mh2; 540 541 @DontInline 542 static void test19_target1(MyValue1? vt) { 543 nullValue = vt; 544 } 545 546 @ForceInline 547 static void test19_target2(MyValue1? vt) { 548 nullValue = vt; 549 } 550 551 // Same as test12 but with non-final mh 552 @Test 553 @Warmup(11000) // Make sure lambda forms get compiled 554 public void test19() throws Throwable { 555 test19_mh1.invokeExact(nullValue); 556 test19_mh2.invokeExact(nullValue); 557 } 558 559 @DontCompile 560 public void test19_verifier(boolean warmup) { 561 try { 562 test19(); 563 } catch (Throwable t) { 564 throw new RuntimeException("test19 failed", t); 565 } 566 } 567 568 // Same as test12/13 but with constant null 569 @Test 570 @Warmup(11000) // Make sure lambda forms get compiled 571 public void test20(MethodHandle mh) throws Throwable { 572 mh.invoke(null); 573 } 574 575 @DontCompile 576 public void test20_verifier(boolean warmup) { 577 try { 578 test20(test18_mh1); 579 test20(test18_mh2); 580 test20(test19_mh1); 581 test20(test19_mh2); 582 } catch (Throwable t) { 583 throw new RuntimeException("test20 failed", t); 584 } 585 } 586 587 // Test writing null to a flattenable/non-flattenable value type field in a value type 588 final inline class Test21Value { 589 final MyValue1? valueField1; 590 final MyValue1 valueField2; 591 final MyValue1? alwaysNull = null; 592 593 @ForceInline 594 public Test21Value(MyValue1? valueField1, MyValue1 valueField2) { 595 this.valueField1 = testValue1; 596 this.valueField2 = testValue1; 597 } 598 599 @ForceInline 600 public Test21Value test1() { 601 return new Test21Value(alwaysNull, this.valueField2); // Should not throw NPE 602 } 603 604 @ForceInline 605 public Test21Value test2() { 606 return new Test21Value(this.valueField1, (MyValue1) alwaysNull); // Should throw NPE 607 } 608 } 609 610 @Test 611 public Test21Value test21(Test21Value vt) { 612 vt = vt.test1(); 613 try { 614 vt = vt.test2(); 615 throw new RuntimeException("NullPointerException expected"); 616 } catch (NullPointerException e) { 617 // Expected 618 } 619 return vt; 620 } 621 622 @DontCompile 623 public void test21_verifier(boolean warmup) { 624 test21(Test21Value.default); 625 } 626 627 @DontInline 628 public MyValue1 test22_helper() { 629 return (MyValue1) nullField; 630 } 631 632 @Test 633 public void test22() { 634 valueField1 = test22_helper(); 635 } 636 637 @DontCompile 638 public void test22_verifier(boolean warmup) { 639 try { 640 test22(); 641 throw new RuntimeException("NullPointerException expected"); 642 } catch (NullPointerException e) { 643 // Expected 644 } 645 } 646 647 @Test 648 public void test23(MyValue1[] arr, MyValue1? b) { 649 arr[0] = (MyValue1) b; 650 } 651 652 @DontCompile 653 public void test23_verifier(boolean warmup) { 654 MyValue1[] arr = new MyValue1[2]; 655 MyValue1? b = null; 656 try { 657 test23(arr, b); 658 throw new RuntimeException("NullPointerException expected"); 659 } catch (NullPointerException e) { 660 // Expected 661 } 662 } 663 664 static MyValue1? nullBox; 665 666 @Test 667 public MyValue1 test24() { 668 return (MyValue1) nullBox; 669 } 670 671 @DontCompile 672 public void test24_verifier(boolean warmup) { 673 try { 674 test24(); 675 throw new RuntimeException("NullPointerException expected"); 676 } catch (NullPointerException e) { 677 // Expected 678 } 679 } 680 681 @DontInline 682 public void test25_callee(MyValue1 val) { } 683 684 // Test that when checkcasting from null-ok to null-free and back to null-ok we 685 // keep track of the information that the value can never be null. 686 @Test(failOn = ALLOC + STORE) 687 public int test25(boolean b, MyValue1? vt1, MyValue1 vt2) { 688 vt1 = (MyValue1)vt1; 689 Object obj = b ? vt1 : vt2; // We should not allocate here 690 test25_callee((MyValue1) vt1); 691 return ((MyValue1)obj).x; 692 } 693 694 @DontCompile 695 public void test25_verifier(boolean warmup) { 696 int res = test25(true, testValue1, testValue1); 697 Asserts.assertEquals(res, testValue1.x); 698 res = test25(false, testValue1, testValue1); 699 Asserts.assertEquals(res, testValue1.x); 700 } 701 702 // Test that chains of casts are folded and don't trigger an allocation 703 @Test(failOn = ALLOC + STORE) 704 public MyValue3 test26(MyValue3 vt) { 705 return ((MyValue3)((Object)((MyValue3?)(MyValue3)((MyValue3?)((Object)vt))))); 706 } 707 708 @DontCompile 709 public void test26_verifier(boolean warmup) { 710 MyValue3 vt = MyValue3.create(); 711 MyValue3 result = test26(vt); 712 Asserts.assertEquals(result, vt); 713 } 714 715 @Test(failOn = ALLOC + STORE) 716 public MyValue3? test27(MyValue3? vt) { 717 return ((MyValue3?)((Object)((MyValue3)(MyValue3?)((MyValue3)((Object)vt))))); 718 } 719 720 @DontCompile 721 public void test27_verifier(boolean warmup) { 722 MyValue3 vt = MyValue3.create(); 723 MyValue3 result = (MyValue3) test27(vt); 724 Asserts.assertEquals(result, vt); 725 } 726 727 // Some more casting tests 728 @Test() 729 public MyValue1? test28(MyValue1 vt, MyValue1? vtBox, int i) { 730 MyValue1? result = null; 731 if (i == 0) { 732 result = (MyValue1?)vt; 733 result = null; 734 } else if (i == 1) { 735 result = (MyValue1?)vt; 736 } else if (i == 2) { 737 result = vtBox; 738 } 739 return result; 740 } 741 742 @DontCompile 743 public void test28_verifier(boolean warmup) { 744 MyValue1? result = test28(testValue1, null, 0); 745 Asserts.assertEquals(result, null); 746 result = test28(testValue1, testValue1, 1); 747 Asserts.assertEquals(result, testValue1); 748 result = test28(testValue1, null, 2); 749 Asserts.assertEquals(result, null); 750 result = test28(testValue1, testValue1, 2); 751 Asserts.assertEquals(result, testValue1); 752 } 753 754 @Test() 755 public long test29(MyValue1 vt, MyValue1? vtBox) { 756 long result = 0; 757 for (int i = 0; i < 100; ++i) { 758 MyValue1? box; 759 if (i == 0) { 760 box = (MyValue1?)vt; 761 box = null; 762 } else if (i < 99) { 763 box = (MyValue1?)vt; 764 } else { 765 box = vtBox; 766 } 767 if (box != null) { 768 result += box.hash(); 769 } 770 } 771 return result; 772 } 773 774 @DontCompile 775 public void test29_verifier(boolean warmup) { 776 long result = test29(testValue1, null); 777 Asserts.assertEquals(result, testValue1.hash()*98); 778 result = test29(testValue1, testValue1); 779 Asserts.assertEquals(result, testValue1.hash()*99); 780 } 781 782 // Test null check of value type receiver with incremental inlining 783 public long test30_callee(MyValue1? vt) { 784 long result = 0; 785 try { 786 result = vt.hashInterpreted(); 787 throw new RuntimeException("NullPointerException expected"); 788 } catch (NullPointerException e) { 789 // Expected 790 } 791 return result; 792 } 793 794 @Test 795 public long test30() { 796 return test30_callee(nullField); 797 } 798 799 @DontCompile 800 public void test30_verifier(boolean warmup) { 801 long result = test30(); 802 Asserts.assertEquals(result, 0L); 803 } 804 805 // Test casting null to unloaded value type 806 final inline class Test31Value { 807 private final int i = 0; 808 } 809 810 @Test 811 public void test31(Object o) { 812 try { 813 o = (Test31Value)o; 814 throw new RuntimeException("NullPointerException expected"); 815 } catch (NullPointerException e) { 816 // Expected 817 } 818 } 819 820 @DontCompile 821 public void test31_verifier(boolean warmup) { 822 test31(null); 823 } 824 825 private static final MyValue1? constNullField = null; 826 827 @Test 828 public MyValue1? test32() { 829 return constNullField; 830 } 831 832 @DontCompile 833 public void test32_verifier(boolean warmup) { 834 MyValue1? result = test32(); 835 Asserts.assertEquals(result, null); 836 } 837 838 static inline class Test33Value1 { 839 int x = 0; 840 } 841 842 static inline class Test33Value2 { 843 Test33Value1? vt; 844 845 public Test33Value2() { 846 vt = new Test33Value1(); 847 } 848 } 849 850 public static final Test33Value2 test33Val = new Test33Value2(); 851 852 @Test 853 public Test33Value2 test33() { 854 return test33Val; 855 } 856 857 @DontCompile 858 public void test33_verifier(boolean warmup) { 859 Test33Value2 result = test33(); 860 Asserts.assertEquals(result, test33Val); 861 } 862 863 // Verify that static nullable inline-type fields are not 864 // treated as never-null by C2 when initialized at compile time. 865 private static MyValue1? test34Val; 866 867 @Test 868 public void test34(MyValue1 vt) { 869 if (test34Val == null) { 870 test34Val = vt; 871 } 872 } 873 874 @DontCompile 875 public void test34_verifier(boolean warmup) { 876 test34(testValue1); 877 if (!warmup) { 878 test34Val = null; 879 test34(testValue1); 880 Asserts.assertEquals(test34Val, testValue1); 881 } 882 } 883 884 // Same as test17 but with non-allocated value at withfield 885 @Test() 886 public Test17Value test35(boolean b) { 887 Test17Value vt1 = Test17Value.default; 888 if ((Object)vt1.valueField != null) { 889 throw new RuntimeException("Should be null"); 890 } 891 MyValue1 vt3 = MyValue1.createWithFieldsInline(rI, rL); 892 Test17Value vt2 = new Test17Value(vt3); 893 return b ? vt1 : vt2; 894 } 895 896 @DontCompile 897 public void test35_verifier(boolean warmup) { 898 test35(true); 899 test35(false); 900 } 901 }