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