1 /* 2 * Copyright (c) 2019, 2025, 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.inlinetypes; 25 26 import compiler.lib.ir_framework.*; 27 import jdk.test.lib.Asserts; 28 29 import jdk.internal.value.ValueClass; 30 import jdk.internal.vm.annotation.LooselyConsistentValue; 31 import jdk.internal.vm.annotation.NullRestricted; 32 import jdk.internal.vm.annotation.Strict; 33 34 import static compiler.valhalla.inlinetypes.InlineTypes.rI; 35 36 /* 37 * @test 38 * @key randomness 39 * @summary Test the handling of fields of unloaded value classes. 40 * @library /test/lib / 41 * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") 42 * @enablePreview 43 * @modules java.base/jdk.internal.value 44 * java.base/jdk.internal.vm.annotation 45 * @compile hack/GetUnresolvedInlineFieldWrongSignature.java 46 * @compile TestUnloadedInlineTypeField.java 47 * @run main/othervm/timeout=300 compiler.valhalla.inlinetypes.TestUnloadedInlineTypeField 48 */ 49 50 public class TestUnloadedInlineTypeField { 51 // Only prevent loading of classes when testing with C1. Load classes 52 // early when executing with C2 to prevent uncommon traps. It's still 53 // beneficial to execute this test with C2 because it also checks handling 54 // of type mismatches. 55 56 public static void main(String[] args) { 57 final Scenario[] scenarios = { 58 new Scenario(0), 59 new Scenario(1, "-XX:-UseFieldFlattening"), 60 new Scenario(2, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:+PatchALot"), 61 new Scenario(3, "-XX:-UseFieldFlattening", 62 "-XX:+IgnoreUnrecognizedVMOptions", "-XX:+PatchALot") 63 }; 64 InlineTypes.getFramework() 65 .addScenarios(scenarios) 66 .addFlags("--enable-preview", 67 // Prevent IR Test Framework from loading classes 68 "-DIgnoreCompilerControls=true", 69 // Some tests trigger frequent re-compilation. Don't mark them as non-compilable. 70 "-XX:PerMethodRecompilationCutoff=-1", "-XX:PerBytecodeRecompilationCutoff=-1") 71 .start(); 72 } 73 74 // Test case 1: 75 // The value class field class has been loaded, but the holder class has not been loaded. 76 // 77 // aload_0 78 // getfield MyValue1Holder.v:LMyValue1; 79 // ^ not loaded ^ already loaded 80 // 81 // MyValue1 has already been loaded, because it's in the preload attribute of 82 // TestUnloadedInlineTypeField, due to TestUnloadedInlineTypeField.test1_precondition(). 83 @LooselyConsistentValue 84 static value class MyValue1 { 85 int foo; 86 87 MyValue1() { 88 foo = rI; 89 } 90 } 91 92 static class MyValue1Holder { 93 @Strict 94 @NullRestricted 95 MyValue1 v; 96 97 public MyValue1Holder() { 98 v = new MyValue1(); 99 } 100 } 101 102 static MyValue1 test1_precondition() { 103 return new MyValue1(); 104 } 105 106 @Test 107 public int test1(Object holder) { 108 if (holder != null) { 109 // Don't use MyValue1Holder in the signature, it might trigger class loading 110 return ((MyValue1Holder)holder).v.foo; 111 } else { 112 return 0; 113 } 114 } 115 116 @Run(test = "test1") 117 public void test1_verifier(RunInfo info) { 118 if (info.isWarmUp() && !info.isC2CompilationEnabled()) { 119 test1(null); 120 } else { 121 MyValue1Holder holder = new MyValue1Holder(); 122 Asserts.assertEQ(test1(holder), rI); 123 } 124 } 125 126 // Test case 2: 127 // Both the value class field class, and the holder class have not been loaded. 128 // 129 // aload_0 130 // getfield MyValue2Holder.v:LMyValue2; 131 // ^ not loaded ^ not loaded 132 // 133 // MyValue2 has not been loaded, because it is not explicitly referenced by 134 // TestUnloadedInlineTypeField. 135 @LooselyConsistentValue 136 static value class MyValue2 { 137 int foo; 138 139 public MyValue2(int n) { 140 foo = n; 141 } 142 } 143 144 static class MyValue2Holder { 145 @Strict 146 @NullRestricted 147 MyValue2 v; 148 149 public MyValue2Holder() { 150 v = new MyValue2(rI); 151 } 152 } 153 154 @Test 155 public int test2(Object holder) { 156 if (holder != null) { 157 // Don't use MyValue2Holder in the signature, it might trigger class loading 158 return ((MyValue2Holder)holder).v.foo; 159 } else { 160 return 0; 161 } 162 } 163 164 @Run(test = "test2") 165 public void test2_verifier(RunInfo info) { 166 if (info.isWarmUp() && !info.isC2CompilationEnabled()) { 167 test2(null); 168 } else { 169 MyValue2Holder holder = new MyValue2Holder(); 170 Asserts.assertEQ(test2(holder), rI); 171 } 172 } 173 174 // Test case 4: 175 // Same as case 1, except we use putfield instead of getfield. 176 @LooselyConsistentValue 177 static value class MyValue4 { 178 int foo; 179 180 MyValue4(int n) { 181 foo = n; 182 } 183 } 184 185 static class MyValue4Holder { 186 @Strict 187 @NullRestricted 188 MyValue4 v; 189 190 public MyValue4Holder() { 191 v = new MyValue4(0); 192 } 193 } 194 195 @Test 196 public void test4(Object holder, MyValue4 v) { 197 if (holder != null) { 198 // Don't use MyValue4Holder in the signature, it might trigger class loading 199 ((MyValue4Holder)holder).v = v; 200 } 201 } 202 203 @Run(test = "test4") 204 public void test4_verifier(RunInfo info) { 205 MyValue4 v = new MyValue4(rI); 206 if (info.isWarmUp() && !info.isC2CompilationEnabled()) { 207 test4(null, v); 208 } else { 209 MyValue4Holder holder = new MyValue4Holder(); 210 test4(holder, v); 211 Asserts.assertEQ(holder.v.foo, rI); 212 } 213 } 214 215 // Test case 5: 216 // Same as case 2, except we use putfield instead of getfield. 217 @LooselyConsistentValue 218 static value class MyValue5 { 219 int foo; 220 221 MyValue5(int n) { 222 foo = n; 223 } 224 } 225 226 static class MyValue5Holder { 227 @Strict 228 @NullRestricted 229 MyValue5 v; 230 231 public MyValue5Holder() { 232 v = new MyValue5(0); 233 } 234 235 public Object make(int n) { 236 return new MyValue5(n); 237 } 238 } 239 240 @Test 241 public void test5(Object holder, Object o) { 242 if (holder != null) { 243 // Don't use MyValue5 and MyValue5Holder in the signature, it might trigger class loading 244 MyValue5 v = (MyValue5)o; 245 ((MyValue5Holder)holder).v = v; 246 } 247 } 248 249 @Run(test = "test5") 250 public void test5_verifier(RunInfo info) { 251 if (info.isWarmUp() && !info.isC2CompilationEnabled()) { 252 test5(null, null); 253 } else { 254 MyValue5Holder holder = new MyValue5Holder(); 255 Object v = holder.make(rI); 256 test5(holder, v); 257 Asserts.assertEQ(holder.v.foo, rI); 258 } 259 } 260 261 262 // Test case 6: (same as test1, except we use getstatic instead of getfield) 263 // The value class field class has been loaded, but the holder class has not been loaded. 264 // 265 // getstatic MyValue6Holder.v:LMyValue1; 266 // ^ not loaded ^ already loaded 267 // 268 // MyValue6 has already been loaded, because it's in the preload attribute of 269 // TestUnloadedInlineTypeField, due to TestUnloadedInlineTypeField.test1_precondition(). 270 @LooselyConsistentValue 271 static value class MyValue6 { 272 int foo; 273 274 MyValue6() { 275 foo = rI; 276 } 277 } 278 279 static class MyValue6Holder { 280 @Strict 281 @NullRestricted 282 static MyValue6 v = new MyValue6(); 283 } 284 285 static MyValue6 test6_precondition() { 286 return new MyValue6(); 287 } 288 289 @Test 290 public int test6(int n) { 291 if (n == 0) { 292 return 0; 293 } else { 294 return MyValue6Holder.v.foo + n; 295 } 296 } 297 298 @Run(test = "test6") 299 public void test6_verifier(RunInfo info) { 300 if (info.isWarmUp() && !info.isC2CompilationEnabled()) { 301 test6(0); 302 } else { 303 Asserts.assertEQ(test6(rI), 2*rI); 304 } 305 } 306 307 308 // Test case 7: (same as test2, except we use getstatic instead of getfield) 309 // Both the value class field class, and the holder class have not been loaded. 310 // 311 // getstatic MyValue7Holder.v:LMyValue7; 312 // ^ not loaded ^ not loaded 313 // 314 // MyValue7 has not been loaded, because it is not explicitly referenced by 315 // TestUnloadedInlineTypeField. 316 @LooselyConsistentValue 317 static value class MyValue7 { 318 int foo; 319 320 MyValue7(int n) { 321 foo = n; 322 } 323 } 324 325 static class MyValue7Holder { 326 @Strict 327 @NullRestricted 328 static MyValue7 v = new MyValue7(rI); 329 } 330 331 @Test 332 public int test7(int n) { 333 if (n == 0) { 334 return 0; 335 } else { 336 return MyValue7Holder.v.foo + n; 337 } 338 } 339 340 @Run(test = "test7") 341 public void test7_verifier(RunInfo info) { 342 if (info.isWarmUp() && !info.isC2CompilationEnabled()) { 343 test7(0); 344 } else { 345 Asserts.assertEQ(test7(rI), 2*rI); 346 } 347 } 348 349 // Test case 8: 350 // Same as case 1, except holder is allocated in test method (-> no holder null check required) 351 @LooselyConsistentValue 352 static value class MyValue8 { 353 int foo; 354 355 MyValue8() { 356 foo = rI; 357 } 358 } 359 360 static class MyValue8Holder { 361 @Strict 362 @NullRestricted 363 MyValue8 v; 364 365 public MyValue8Holder() { 366 v = new MyValue8(); 367 } 368 } 369 370 static MyValue8 test8_precondition() { 371 return new MyValue8(); 372 } 373 374 @Test 375 public int test8(boolean warmup) { 376 if (!warmup) { 377 MyValue8Holder holder = new MyValue8Holder(); 378 return holder.v.foo; 379 } else { 380 return 0; 381 } 382 } 383 384 @Run(test = "test8") 385 public void test8_verifier(RunInfo info) { 386 if (info.isWarmUp() && !info.isC2CompilationEnabled()) { 387 test8(true); 388 } else { 389 Asserts.assertEQ(test8(false), rI); 390 } 391 } 392 393 // Test case 9: 394 // Same as case 2, except holder is allocated in test method (-> no holder null check required) 395 @LooselyConsistentValue 396 static value class MyValue9 { 397 int foo; 398 399 public MyValue9(int n) { 400 foo = n; 401 } 402 } 403 404 static class MyValue9Holder { 405 @Strict 406 @NullRestricted 407 MyValue9 v; 408 409 public MyValue9Holder() { 410 v = new MyValue9(rI); 411 } 412 } 413 414 @Test 415 public int test9(boolean warmup) { 416 if (!warmup) { 417 MyValue9Holder holder = new MyValue9Holder(); 418 return holder.v.foo; 419 } else { 420 return 0; 421 } 422 } 423 424 @Run(test = "test9") 425 public void test9_verifier(RunInfo info) { 426 if (info.isWarmUp() && !info.isC2CompilationEnabled()) { 427 test9(true); 428 } else { 429 Asserts.assertEQ(test9(false), rI); 430 } 431 } 432 433 // Test case 11: 434 // Same as case 4, except holder is allocated in test method (-> no holder null check required) 435 @LooselyConsistentValue 436 static value class MyValue11 { 437 int foo; 438 439 MyValue11(int n) { 440 foo = n; 441 } 442 } 443 444 static class MyValue11Holder { 445 @Strict 446 @NullRestricted 447 MyValue11 v; 448 449 public MyValue11Holder() { 450 v = new MyValue11(0); 451 } 452 } 453 454 @Test 455 public Object test11(boolean warmup, MyValue11 v) { 456 if (!warmup) { 457 MyValue11Holder holder = new MyValue11Holder(); 458 holder.v = v; 459 return holder; 460 } else { 461 return null; 462 } 463 } 464 465 @Run(test = "test11") 466 public void test11_verifier(RunInfo info) { 467 MyValue11 v = new MyValue11(rI); 468 if (info.isWarmUp() && !info.isC2CompilationEnabled()) { 469 test11(true, v); 470 } else { 471 MyValue11Holder holder = (MyValue11Holder)test11(false, v); 472 Asserts.assertEQ(holder.v.foo, rI); 473 } 474 } 475 476 // Test case 12: 477 // Same as case 5, except holder is allocated in test method (-> no holder null check required) 478 @LooselyConsistentValue 479 static value class MyValue12 { 480 int foo; 481 482 MyValue12(int n) { 483 foo = n; 484 } 485 } 486 487 static class MyValue12Holder { 488 @Strict 489 @NullRestricted 490 MyValue12 v; 491 492 public MyValue12Holder() { 493 v = new MyValue12(0); 494 } 495 } 496 497 @Test 498 public Object test12(boolean warmup, Object o) { 499 if (!warmup) { 500 // Don't use MyValue12 in the signature, it might trigger class loading 501 MyValue12Holder holder = new MyValue12Holder(); 502 holder.v = (MyValue12)o; 503 return holder; 504 } else { 505 return null; 506 } 507 } 508 509 @Run(test = "test12") 510 public void test12_verifier(RunInfo info) { 511 if (info.isWarmUp() && !info.isC2CompilationEnabled()) { 512 test12(true, null); 513 } else { 514 MyValue12 v = new MyValue12(rI); 515 MyValue12Holder holder = (MyValue12Holder)test12(false, v); 516 Asserts.assertEQ(holder.v.foo, rI); 517 } 518 } 519 520 // Test case 13: 521 // Same as case 10, except MyValue13 is allocated in test method 522 @LooselyConsistentValue 523 static value class MyValue13 { 524 int foo; 525 526 public MyValue13() { 527 foo = rI; 528 } 529 } 530 531 static class MyValue13Holder { 532 @Strict 533 @NullRestricted 534 MyValue13 v; 535 536 public MyValue13Holder() { 537 v = new MyValue13(); 538 } 539 } 540 541 static MyValue13 test13_precondition() { 542 return new MyValue13(); 543 } 544 545 @Test 546 public void test13(Object holder) { 547 // Don't use MyValue13Holder in the signature, it might trigger class loading 548 GetUnresolvedInlineFieldWrongSignature.test13(holder); 549 } 550 551 @Run(test = "test13") 552 public void test13_verifier(RunInfo info) { 553 if (info.isWarmUp() && !info.isC2CompilationEnabled()) { 554 test13(null); 555 } else { 556 // Make sure klass is resolved 557 for (int i = 0; i < 10; ++i) { 558 test13(new MyValue13Holder()); 559 } 560 } 561 } 562 563 // Test case 15: 564 // Same as case 13, except MyValue15 is unloaded 565 @LooselyConsistentValue 566 static value class MyValue15 { 567 int foo; 568 569 public MyValue15() { 570 foo = rI; 571 } 572 } 573 574 static class MyValue15Holder { 575 @Strict 576 @NullRestricted 577 MyValue15 v; 578 579 public MyValue15Holder() { 580 v = new MyValue15(); 581 } 582 } 583 584 @Test 585 public void test15(Object holder) { 586 // Don't use MyValue15Holder in the signature, it might trigger class loading 587 GetUnresolvedInlineFieldWrongSignature.test15(holder); 588 } 589 590 @Run(test = "test15") 591 public void test15_verifier(RunInfo info) { 592 if (info.isWarmUp() && !info.isC2CompilationEnabled()) { 593 test15(null); 594 } else { 595 // Make sure klass is resolved 596 for (int i = 0; i < 10; ++i) { 597 test15(new MyValue15Holder()); 598 } 599 } 600 } 601 602 // Test case 16: 603 // aconst_init with type which is not a value class 604 static class MyValue16 { 605 int foo; 606 607 public MyValue16() { 608 foo = rI; 609 } 610 } 611 612 static MyValue16 test16_precondition() { 613 return new MyValue16(); 614 } 615 616 @Test 617 public Object test16(boolean warmup) { 618 return GetUnresolvedInlineFieldWrongSignature.test16(warmup); 619 } 620 621 @Run(test = "test16") 622 public void test16_verifier(RunInfo info) { 623 if (info.isWarmUp() && !info.isC2CompilationEnabled()) { 624 test16(true); 625 } else { 626 // Make sure klass is resolved 627 for (int i = 0; i < 10; ++i) { 628 test16(false); 629 } 630 } 631 } 632 633 // Test case 17: 634 // Same as test16 but with unloaded type at aconst_init 635 static class MyValue17 { 636 int foo; 637 638 public MyValue17() { 639 foo = rI; 640 } 641 } 642 643 @Test 644 public Object test17(boolean warmup) { 645 return GetUnresolvedInlineFieldWrongSignature.test17(warmup); 646 } 647 648 @Run(test = "test17") 649 public void test17_verifier(RunInfo info) { 650 if (info.isWarmUp() && !info.isC2CompilationEnabled()) { 651 test17(true); 652 } else { 653 // Make sure klass is resolved 654 for (int i = 0; i < 10; ++i) { 655 test17(false); 656 } 657 } 658 } 659 660 // Test case 18: 661 // Same as test7 but with the holder being loaded 662 @LooselyConsistentValue 663 static value class MyValue18 { 664 int foo; 665 666 MyValue18(int n) { 667 foo = n; 668 } 669 } 670 671 static class MyValue18Holder { 672 @Strict 673 @NullRestricted 674 static MyValue18 v = new MyValue18(rI); 675 } 676 677 @Test 678 public int test18(int n) { 679 if (n == 0) { 680 return 0; 681 } else { 682 return MyValue18Holder.v.foo + n; 683 } 684 } 685 686 @Run(test = "test18") 687 public void test18_verifier(RunInfo info) { 688 // Make sure MyValue18Holder is loaded 689 MyValue18Holder holder = new MyValue18Holder(); 690 if (info.isWarmUp() && !info.isC2CompilationEnabled()) { 691 test18(0); 692 } else { 693 Asserts.assertEQ(test18(rI), 2*rI); 694 } 695 } 696 697 // Test case 19: 698 // Same as test18 but uninitialized (null) static value class field 699 @LooselyConsistentValue 700 static value class MyValue19 { 701 int foo; 702 703 MyValue19(int n) { 704 foo = n; 705 } 706 } 707 708 static class MyValue19Holder { 709 @Strict 710 @NullRestricted 711 static MyValue19 v = new MyValue19(0); 712 } 713 714 @Test 715 public int test19(int n) { 716 if (n == 0) { 717 return 0; 718 } else { 719 return MyValue19Holder.v.foo + n; 720 } 721 } 722 723 @Run(test = "test19") 724 public void test19_verifier(RunInfo info) { 725 // Make sure MyValue19Holder is loaded 726 MyValue19Holder holder = new MyValue19Holder(); 727 if (info.isWarmUp() && !info.isC2CompilationEnabled()) { 728 test19(0); 729 } else { 730 Asserts.assertEQ(test19(rI), rI); 731 } 732 } 733 734 // Test case 20: 735 // Value class with object field of unloaded type. 736 static class MyObject20 { 737 int x = 42; 738 } 739 740 @LooselyConsistentValue 741 static value class MyValue20 { 742 MyObject20 obj; 743 744 MyValue20() { 745 this.obj = null; 746 } 747 } 748 749 @Test 750 public MyValue20 test20() { 751 return new MyValue20(); 752 } 753 754 @Run(test = "test20") 755 public void test20_verifier() { 756 MyValue20 vt = test20(); 757 Asserts.assertEQ(vt.obj, null); 758 } 759 760 @LooselyConsistentValue 761 static value class Test21ClassA { 762 static Test21ClassB b; 763 @Strict 764 @NullRestricted 765 static Test21ClassC c = new Test21ClassC(); 766 } 767 768 @LooselyConsistentValue 769 static value class Test21ClassB { 770 static int x = Test21ClassA.c.x; 771 } 772 773 @LooselyConsistentValue 774 static value class Test21ClassC { 775 int x = 42; 776 } 777 778 // Test access to static value class field with unloaded type 779 @Test 780 public Object test21() { 781 return new Test21ClassA(); 782 } 783 784 @Run(test = "test21") 785 public void test21_verifier() { 786 Object ret = test21(); 787 Asserts.assertEQ(Test21ClassA.b.x, 42); 788 Asserts.assertEQ(Test21ClassA.c.x, 42); 789 } 790 791 static boolean test22FailInit = true; 792 793 @LooselyConsistentValue 794 static value class Test22ClassA { 795 int x = 0; 796 @Strict 797 @NullRestricted 798 static Test22ClassB b = new Test22ClassB(); 799 } 800 801 @LooselyConsistentValue 802 static value class Test22ClassB { 803 int x = 0; 804 static { 805 if (test22FailInit) { 806 throw new RuntimeException("Init failed"); 807 } 808 } 809 } 810 811 // Test that load from static field of uninitialized value class throws an exception 812 @Test 813 public Object test22() { 814 return Test22ClassA.b; 815 } 816 817 @Run(test = "test22") 818 public void test22_verifier() { 819 // Trigger initialization error in Test22ClassB 820 try { 821 Test22ClassB b = new Test22ClassB(); 822 throw new RuntimeException("Should have thrown error during initialization"); 823 } catch (ExceptionInInitializerError | NoClassDefFoundError e) { 824 // Expected 825 } 826 try { 827 test22(); 828 throw new RuntimeException("Should have thrown NoClassDefFoundError"); 829 } catch (NoClassDefFoundError e) { 830 // Expected 831 } 832 } 833 834 static boolean test23FailInit = true; 835 836 @LooselyConsistentValue 837 static value class Test23ClassA { 838 int x = 0; 839 @Strict 840 @NullRestricted 841 static Test23ClassB b = new Test23ClassB(); 842 } 843 844 @LooselyConsistentValue 845 static value class Test23ClassB { 846 static { 847 if (test23FailInit) { 848 throw new RuntimeException("Init failed"); 849 } 850 } 851 } 852 853 // Same as test22 but with empty ClassB 854 @Test 855 public Object test23() { 856 return Test23ClassA.b; 857 } 858 859 @Run(test = "test23") 860 public void test23_verifier() { 861 // Trigger initialization error in Test23ClassB 862 try { 863 Test23ClassB b = new Test23ClassB(); 864 throw new RuntimeException("Should have thrown error during initialization"); 865 } catch (ExceptionInInitializerError | NoClassDefFoundError e) { 866 // Expected 867 } 868 try { 869 test23(); 870 throw new RuntimeException("Should have thrown NoClassDefFoundError"); 871 } catch (NoClassDefFoundError e) { 872 // Expected 873 } 874 } 875 876 static boolean test24FailInit = true; 877 878 @LooselyConsistentValue 879 static value class Test24ClassA { 880 @Strict 881 @NullRestricted 882 Test24ClassB b = new Test24ClassB(); 883 } 884 885 @LooselyConsistentValue 886 static value class Test24ClassB { 887 int x = 0; 888 static { 889 if (test24FailInit) { 890 throw new RuntimeException("Init failed"); 891 } 892 } 893 } 894 895 // Test that access to non-static field of uninitialized value class throws an exception 896 @Test 897 public Object test24() { 898 return (new Test24ClassA()).b.x; 899 } 900 901 @Run(test = "test24") 902 public void test24_verifier() { 903 // Trigger initialization error in Test24ClassB 904 try { 905 Test24ClassB b = new Test24ClassB(); 906 throw new RuntimeException("Should have thrown error during initialization"); 907 } catch (ExceptionInInitializerError | NoClassDefFoundError e) { 908 // Expected 909 } 910 try { 911 test24(); 912 throw new RuntimeException("Should have thrown NoClassDefFoundError"); 913 } catch (NoClassDefFoundError e) { 914 // Expected 915 } 916 } 917 918 static boolean test25FailInit = true; 919 920 @LooselyConsistentValue 921 static value class Test25ClassA { 922 @Strict 923 @NullRestricted 924 Test25ClassB b = new Test25ClassB(); 925 } 926 927 @LooselyConsistentValue 928 static value class Test25ClassB { 929 int x = 24; 930 static { 931 if (test25FailInit) { 932 throw new RuntimeException("Init failed"); 933 } 934 } 935 } 936 937 // Same as test24 but with field access outside of test method 938 @Test 939 public Test25ClassB test25() { 940 return (new Test25ClassA()).b; 941 } 942 943 @Run(test = "test25") 944 public void test25_verifier() { 945 // Trigger initialization error in Test25ClassB 946 try { 947 Test25ClassB b = new Test25ClassB(); 948 throw new RuntimeException("Should have thrown error during initialization"); 949 } catch (ExceptionInInitializerError | NoClassDefFoundError e) { 950 // Expected 951 } 952 try { 953 Test25ClassB res = test25(); 954 Asserts.assertEQ(res.x, 0); 955 throw new RuntimeException("Should have thrown NoClassDefFoundError"); 956 } catch (NoClassDefFoundError e) { 957 // Expected 958 } 959 } 960 961 static boolean test26FailInit = true; 962 963 @LooselyConsistentValue 964 static value class Test26ClassA { 965 @Strict 966 @NullRestricted 967 Test26ClassB b = new Test26ClassB(); 968 } 969 970 @LooselyConsistentValue 971 static value class Test26ClassB { 972 static { 973 if (test26FailInit) { 974 throw new RuntimeException("Init failed"); 975 } 976 } 977 } 978 979 // Same as test25 but with empty ClassB 980 @Test 981 public Object test26() { 982 return (new Test26ClassA()).b; 983 } 984 985 @Run(test = "test26") 986 public void test26_verifier() { 987 // Trigger initialization error in Test26ClassB 988 try { 989 Test26ClassB b = new Test26ClassB(); 990 throw new RuntimeException("Should have thrown error during initialization"); 991 } catch (ExceptionInInitializerError | NoClassDefFoundError e) { 992 // Expected 993 } 994 try { 995 test26(); 996 throw new RuntimeException("Should have thrown NoClassDefFoundError"); 997 } catch (NoClassDefFoundError e) { 998 // Expected 999 } 1000 } 1001 1002 @LooselyConsistentValue 1003 static value class MyValue27 { 1004 int foo = 42; 1005 } 1006 1007 static class MyValue27Holder { 1008 MyValue27 v; 1009 } 1010 1011 // Make sure MyValue27Holder is loaded but MyValue27 is not 1012 Class test27Class = MyValue27Holder.class; 1013 1014 // Test unloaded value class field load from loaded holder 1015 @Test 1016 public static Object test27() { 1017 MyValue27Holder holder = new MyValue27Holder(); 1018 return holder.v; 1019 } 1020 1021 @Run(test = "test27") 1022 public void test27_verifier() { 1023 Asserts.assertEQ(test27(), null); 1024 } 1025 1026 @LooselyConsistentValue 1027 static value class MyValue28 { 1028 @Strict 1029 @NullRestricted 1030 static MyValue28 field1 = new MyValue28(); 1031 } 1032 1033 // Test null store to null restricted field with unloaded holder 1034 @Test 1035 public static void test28() { 1036 MyValue28.field1 = null; 1037 } 1038 1039 @Run(test = "test28") 1040 @Warmup(0) // Make sure that MyValue28 is not loaded 1041 public void test28_verifier() { 1042 try { 1043 test28(); 1044 throw new RuntimeException("No exception thrown"); 1045 } catch (NullPointerException e) { 1046 // Expected 1047 } 1048 } 1049 }