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