1 /* 2 * Copyright (c) 2017, 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 jdk.test.lib.Asserts; 27 28 import java.lang.invoke.*; 29 import java.lang.reflect.Method; 30 31 /* 32 * @test 33 * @summary Test value type calling convention optimizations 34 * @library /testlibrary /test/lib /compiler/whitebox / 35 * @requires os.simpleArch == "x64" 36 * @compile TestCallingConvention.java 37 * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform 38 * @run main/othervm/timeout=300 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions 39 * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI 40 * compiler.valhalla.valuetypes.ValueTypeTest 41 * compiler.valhalla.valuetypes.TestCallingConvention 42 */ 43 public class TestCallingConvention extends ValueTypeTest { 44 // Extra VM parameters for some test scenarios. See ValueTypeTest.getVMParameters() 45 @Override 46 public String[] getExtraVMParameters(int scenario) { 47 switch (scenario) { 48 case 0: return new String[] {"-Dsun.reflect.inflationThreshold=10000"}; // Don't generate bytecodes but call through runtime for reflective calls 49 case 1: return new String[] {"-Dsun.reflect.inflationThreshold=10000"}; 50 case 3: return new String[] {"-XX:ValueArrayElemMaxFlatSize=0"}; 51 } 52 return null; 53 } 54 55 static { 56 try { 57 Class<?> clazz = TestCallingConvention.class; 58 ClassLoader loader = clazz.getClassLoader(); 59 MethodHandles.Lookup lookup = MethodHandles.lookup(); 60 61 MethodType mt32 = MethodType.methodType(MyValue2.class, boolean.class); 62 test32_mh = lookup.findVirtual(clazz, "test32_interp", mt32); 63 64 MethodType mt33 = MethodType.methodType(Object.class, boolean.class); 65 test33_mh = lookup.findVirtual(clazz, "test33_interp", mt33); 66 } catch (NoSuchMethodException | IllegalAccessException e) { 67 e.printStackTrace(); 68 throw new RuntimeException("Method handle lookup failed"); 69 } 70 } 71 72 public static void main(String[] args) throws Throwable { 73 TestCallingConvention test = new TestCallingConvention(); 74 test.run(args, MyValue1.class, MyValue2.class, MyValue2Inline.class, MyValue4.class, Test27Value1.class, Test27Value2.class, Test27Value3.class); 75 } 76 77 // Test interpreter to compiled code with various signatures 78 @Test(failOn = ALLOC + STORE + TRAP) 79 public long test1(MyValue2 v) { 80 return v.hash(); 81 } 82 83 @DontCompile 84 public void test1_verifier(boolean warmup) { 85 MyValue2 v = MyValue2.createWithFieldsInline(rI, true); 86 long result = test1(v); 87 Asserts.assertEQ(result, v.hashInterpreted()); 88 } 89 90 @Test(failOn = ALLOC + STORE + TRAP) 91 public long test2(int i1, MyValue2 v, int i2) { 92 return v.hash() + i1 - i2; 93 } 94 95 @DontCompile 96 public void test2_verifier(boolean warmup) { 97 MyValue2 v = MyValue2.createWithFieldsInline(rI, true); 98 long result = test2(rI, v, 2*rI); 99 Asserts.assertEQ(result, v.hashInterpreted() - rI); 100 } 101 102 @Test(failOn = ALLOC + STORE + TRAP) 103 public long test3(long l1, MyValue2 v, long l2) { 104 return v.hash() + l1 - l2; 105 } 106 107 @DontCompile 108 public void test3_verifier(boolean warmup) { 109 MyValue2 v = MyValue2.createWithFieldsInline(rI, true); 110 long result = test3(rL, v, 2*rL); 111 Asserts.assertEQ(result, v.hashInterpreted() - rL); 112 } 113 114 @Test(failOn = ALLOC + STORE + TRAP) 115 public long test4(int i, MyValue2 v, long l) { 116 return v.hash() + i + l; 117 } 118 119 @DontCompile 120 public void test4_verifier(boolean warmup) { 121 MyValue2 v = MyValue2.createWithFieldsInline(rI, true); 122 long result = test4(rI, v, rL); 123 Asserts.assertEQ(result, v.hashInterpreted() + rL + rI); 124 } 125 126 @Test(failOn = ALLOC + STORE + TRAP) 127 public long test5(long l, MyValue2 v, int i) { 128 return v.hash() + i + l; 129 } 130 131 @DontCompile 132 public void test5_verifier(boolean warmup) { 133 MyValue2 v = MyValue2.createWithFieldsInline(rI, true); 134 long result = test5(rL, v, rI); 135 Asserts.assertEQ(result, v.hashInterpreted() + rL + rI); 136 } 137 138 @Test(failOn = ALLOC + STORE + TRAP) 139 public long test6(long l, MyValue1 v1, int i, MyValue2 v2) { 140 return v1.hash() + i + l + v2.hash(); 141 } 142 143 @DontCompile 144 public void test6_verifier(boolean warmup) { 145 MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI, rL); 146 MyValue2 v2 = MyValue2.createWithFieldsInline(rI, true); 147 long result = test6(rL, v1, rI, v2); 148 Asserts.assertEQ(result, v1.hashInterpreted() + rL + rI + v2.hashInterpreted()); 149 } 150 151 // Test compiled code to interpreter with various signatures 152 @DontCompile 153 public long test7_interp(MyValue2 v) { 154 return v.hash(); 155 } 156 157 @Test(failOn = ALLOC + STORE + TRAP) 158 public long test7(MyValue2 v) { 159 return test7_interp(v); 160 } 161 162 @DontCompile 163 public void test7_verifier(boolean warmup) { 164 MyValue2 v = MyValue2.createWithFieldsInline(rI, true); 165 long result = test7(v); 166 Asserts.assertEQ(result, v.hashInterpreted()); 167 } 168 169 @DontCompile 170 public long test8_interp(int i1, MyValue2 v, int i2) { 171 return v.hash() + i1 - i2; 172 } 173 174 @Test(failOn = ALLOC + STORE + TRAP) 175 public long test8(int i1, MyValue2 v, int i2) { 176 return test8_interp(i1, v, i2); 177 } 178 179 @DontCompile 180 public void test8_verifier(boolean warmup) { 181 MyValue2 v = MyValue2.createWithFieldsInline(rI, true); 182 long result = test8(rI, v, 2*rI); 183 Asserts.assertEQ(result, v.hashInterpreted() - rI); 184 } 185 186 @DontCompile 187 public long test9_interp(long l1, MyValue2 v, long l2) { 188 return v.hash() + l1 - l2; 189 } 190 191 @Test(failOn = ALLOC + STORE + TRAP) 192 public long test9(long l1, MyValue2 v, long l2) { 193 return test9_interp(l1, v, l2); 194 } 195 196 @DontCompile 197 public void test9_verifier(boolean warmup) { 198 MyValue2 v = MyValue2.createWithFieldsInline(rI, true); 199 long result = test9(rL, v, 2*rL); 200 Asserts.assertEQ(result, v.hashInterpreted() - rL); 201 } 202 203 @DontCompile 204 public long test10_interp(int i, MyValue2 v, long l) { 205 return v.hash() + i + l; 206 } 207 208 @Test(failOn = ALLOC + STORE + TRAP) 209 public long test10(int i, MyValue2 v, long l) { 210 return test10_interp(i, v, l); 211 } 212 213 @DontCompile 214 public void test10_verifier(boolean warmup) { 215 MyValue2 v = MyValue2.createWithFieldsInline(rI, true); 216 long result = test10(rI, v, rL); 217 Asserts.assertEQ(result, v.hashInterpreted() + rL + rI); 218 } 219 220 @DontCompile 221 public long test11_interp(long l, MyValue2 v, int i) { 222 return v.hash() + i + l; 223 } 224 225 @Test(failOn = ALLOC + STORE + TRAP) 226 public long test11(long l, MyValue2 v, int i) { 227 return test11_interp(l, v, i); 228 } 229 230 @DontCompile 231 public void test11_verifier(boolean warmup) { 232 MyValue2 v = MyValue2.createWithFieldsInline(rI, true); 233 long result = test11(rL, v, rI); 234 Asserts.assertEQ(result, v.hashInterpreted() + rL + rI); 235 } 236 237 @DontCompile 238 public long test12_interp(long l, MyValue1 v1, int i, MyValue2 v2) { 239 return v1.hash() + i + l + v2.hash(); 240 } 241 242 @Test(failOn = ALLOC + STORE + TRAP) 243 public long test12(long l, MyValue1 v1, int i, MyValue2 v2) { 244 return test12_interp(l, v1, i, v2); 245 } 246 247 @DontCompile 248 public void test12_verifier(boolean warmup) { 249 MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI, rL); 250 MyValue2 v2 = MyValue2.createWithFieldsInline(rI, true); 251 long result = test12(rL, v1, rI, v2); 252 Asserts.assertEQ(result, v1.hashInterpreted() + rL + rI + v2.hashInterpreted()); 253 } 254 255 // Test that debug info at a call is correct 256 @DontCompile 257 public long test13_interp(MyValue2 v, MyValue1[] va, boolean deopt) { 258 if (deopt) { 259 // uncommon trap 260 WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test13")); 261 } 262 return v.hash() + va[0].hash() + va[1].hash(); 263 } 264 265 @Test(failOn = ALLOC + STORE + TRAP) 266 public long test13(MyValue2 v, MyValue1[] va, boolean flag, long l) { 267 return test13_interp(v, va, flag) + l; 268 } 269 270 @DontCompile 271 public void test13_verifier(boolean warmup) { 272 MyValue2 v = MyValue2.createWithFieldsInline(rI, true); 273 MyValue1[] va = new MyValue1[2]; 274 va[0] = MyValue1.createWithFieldsDontInline(rI, rL); 275 va[1] = MyValue1.createWithFieldsDontInline(rI, rL); 276 long result = test13(v, va, !warmup, rL); 277 Asserts.assertEQ(result, v.hashInterpreted() + va[0].hash() + va[1].hash() + rL); 278 } 279 280 // Test deoptimization at call return with return value in registers 281 @DontCompile 282 public MyValue2 test14_interp(boolean deopt) { 283 if (deopt) { 284 // uncommon trap 285 WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test14")); 286 } 287 return MyValue2.createWithFieldsInline(rI, true); 288 } 289 290 @Test() 291 public MyValue2 test14(boolean flag) { 292 return test14_interp(flag); 293 } 294 295 @DontCompile 296 public void test14_verifier(boolean warmup) { 297 MyValue2 result = test14(!warmup); 298 MyValue2 v = MyValue2.createWithFieldsInline(rI, true); 299 Asserts.assertEQ(result.hash(), v.hash()); 300 } 301 302 // Return value types in registers from interpreter -> compiled 303 final MyValue3 test15_vt = MyValue3.create(); 304 @DontCompile 305 public MyValue3 test15_interp() { 306 return test15_vt; 307 } 308 309 MyValue3 test15_vt2; 310 @Test(valid = ValueTypeReturnedAsFieldsOn, failOn = ALLOC + LOAD + TRAP) 311 @Test(valid = ValueTypeReturnedAsFieldsOff) 312 public void test15() { 313 test15_vt2 = test15_interp(); 314 } 315 316 @DontCompile 317 public void test15_verifier(boolean warmup) { 318 test15(); 319 test15_vt.verify(test15_vt2); 320 } 321 322 // Return value types in registers from compiled -> interpreter 323 final MyValue3 test16_vt = MyValue3.create(); 324 @Test(valid = ValueTypeReturnedAsFieldsOn, failOn = ALLOC + STORE + TRAP) 325 @Test(valid = ValueTypeReturnedAsFieldsOff) 326 public MyValue3 test16() { 327 return test16_vt; 328 } 329 330 @DontCompile 331 public void test16_verifier(boolean warmup) { 332 MyValue3 vt = test16(); 333 test16_vt.verify(vt); 334 } 335 336 // Return value types in registers from compiled -> compiled 337 final MyValue3 test17_vt = MyValue3.create(); 338 @DontInline 339 public MyValue3 test17_comp() { 340 return test17_vt; 341 } 342 343 MyValue3 test17_vt2; 344 @Test(valid = ValueTypeReturnedAsFieldsOn, failOn = ALLOC + LOAD + TRAP) 345 @Test(valid = ValueTypeReturnedAsFieldsOff) 346 public void test17() { 347 test17_vt2 = test17_comp(); 348 } 349 350 @DontCompile 351 public void test17_verifier(boolean warmup) throws Exception { 352 Method helper_m = getClass().getDeclaredMethod("test17_comp"); 353 if (!warmup && USE_COMPILER && !WHITE_BOX.isMethodCompiled(helper_m, false)) { 354 WHITE_BOX.enqueueMethodForCompilation(helper_m, COMP_LEVEL_FULL_OPTIMIZATION); 355 Asserts.assertTrue(WHITE_BOX.isMethodCompiled(helper_m, false), "test17_comp not compiled"); 356 } 357 test17(); 358 test17_vt.verify(test17_vt2); 359 } 360 361 // Same tests as above but with a value type that cannot be returned in registers 362 363 // Return value types in registers from interpreter -> compiled 364 final MyValue4 test18_vt = MyValue4.create(); 365 @DontCompile 366 public MyValue4 test18_interp() { 367 return test18_vt; 368 } 369 370 MyValue4 test18_vt2; 371 @Test 372 public void test18() { 373 test18_vt2 = test18_interp(); 374 } 375 376 @DontCompile 377 public void test18_verifier(boolean warmup) { 378 test18(); 379 test18_vt.verify(test18_vt2); 380 } 381 382 // Return value types in registers from compiled -> interpreter 383 final MyValue4 test19_vt = MyValue4.create(); 384 @Test 385 public MyValue4 test19() { 386 return test19_vt; 387 } 388 389 @DontCompile 390 public void test19_verifier(boolean warmup) { 391 MyValue4 vt = test19(); 392 test19_vt.verify(vt); 393 } 394 395 // Return value types in registers from compiled -> compiled 396 final MyValue4 test20_vt = MyValue4.create(); 397 @DontInline 398 public MyValue4 test20_comp() { 399 return test20_vt; 400 } 401 402 MyValue4 test20_vt2; 403 @Test 404 public void test20() { 405 test20_vt2 = test20_comp(); 406 } 407 408 @DontCompile 409 public void test20_verifier(boolean warmup) throws Exception { 410 Method helper_m = getClass().getDeclaredMethod("test20_comp"); 411 if (!warmup && USE_COMPILER && !WHITE_BOX.isMethodCompiled(helper_m, false)) { 412 WHITE_BOX.enqueueMethodForCompilation(helper_m, COMP_LEVEL_FULL_OPTIMIZATION); 413 Asserts.assertTrue(WHITE_BOX.isMethodCompiled(helper_m, false), "test20_comp not compiled"); 414 } 415 test20(); 416 test20_vt.verify(test20_vt2); 417 } 418 419 // Test no result from inlined method for incremental inlining 420 final MyValue3 test21_vt = MyValue3.create(); 421 public MyValue3 test21_inlined() { 422 throw new RuntimeException(); 423 } 424 425 @Test 426 public MyValue3 test21() { 427 try { 428 return test21_inlined(); 429 } catch (RuntimeException ex) { 430 return test21_vt; 431 } 432 } 433 434 @DontCompile 435 public void test21_verifier(boolean warmup) { 436 MyValue3 vt = test21(); 437 test21_vt.verify(vt); 438 } 439 440 // Test returning a non-flattened value type as fields 441 MyValue3? test22_vt = MyValue3.create(); 442 443 @Test 444 public MyValue3 test22() { 445 return (MyValue3) test22_vt; 446 } 447 448 @DontCompile 449 public void test22_verifier(boolean warmup) { 450 MyValue3 vt = test22(); 451 test22_vt.verify(vt); 452 } 453 454 // Test calling a method that has circular register/stack dependencies when unpacking value type arguments 455 inline class TestValue23 { 456 final double f1; 457 TestValue23(double val) { 458 f1 = val; 459 } 460 } 461 462 static double test23Callee(int i1, int i2, int i3, int i4, int i5, int i6, 463 TestValue23 v1, TestValue23 v2, TestValue23 v3, TestValue23 v4, TestValue23 v5, TestValue23 v6, TestValue23 v7, TestValue23 v8, 464 double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8) { 465 return i1 + i2 + i3 + i4 + i5 + i6 + v1.f1 + v2.f1 + v3.f1 + v4.f1 + v5.f1 + v6.f1 + v7.f1 + v8.f1 + d1 + d2 + d3 + d4 + d5 + d6 + d7 + d8; 466 } 467 468 @Test 469 public double test23(int i1, int i2, int i3, int i4, int i5, int i6, 470 TestValue23 v1, TestValue23 v2, TestValue23 v3, TestValue23 v4, TestValue23 v5, TestValue23 v6, TestValue23 v7, TestValue23 v8, 471 double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8) { 472 return test23Callee(i1, i2, i3, i4, i5, i6, 473 v1, v2, v3, v4, v5, v6, v7, v8, 474 d1, d2, d3, d4, d5, d6, d7, d8); 475 } 476 477 @DontCompile 478 public void test23_verifier(boolean warmup) { 479 TestValue23 vt = new TestValue23(rI); 480 double res1 = test23(rI, rI, rI, rI, rI, rI, 481 vt, vt, vt, vt, vt, vt, vt, vt, 482 rI, rI, rI, rI, rI, rI, rI, rI); 483 double res2 = test23Callee(rI, rI, rI, rI, rI, rI, 484 vt, vt, vt, vt, vt, vt, vt, vt, 485 rI, rI, rI, rI, rI, rI, rI, rI); 486 double res3 = 6*rI + 8*rI + 8*rI; 487 Asserts.assertEQ(res1, res2); 488 Asserts.assertEQ(res2, res3); 489 } 490 491 // Should not return a nullable value type as fields 492 @Test 493 public MyValue2? test24() { 494 return null; 495 } 496 497 @DontCompile 498 public void test24_verifier(boolean warmup) { 499 MyValue2? vt = test24(); 500 Asserts.assertEQ(vt, null); 501 } 502 503 // Same as test24 but with control flow and inlining 504 @ForceInline 505 public MyValue2? test26_callee(boolean b) { 506 if (b) { 507 return null; 508 } else { 509 return MyValue2.createWithFieldsInline(rI, true); 510 } 511 } 512 513 @Test 514 public MyValue2? test26(boolean b) { 515 return test26_callee(b); 516 } 517 518 @DontCompile 519 public void test26_verifier(boolean warmup) { 520 MyValue2? vt = test26(true); 521 Asserts.assertEQ(vt, null); 522 vt = test26(false); 523 Asserts.assertEQ(vt.hash(), MyValue2.createWithFieldsInline(rI, true).hash()); 524 } 525 526 // Test calling convention with deep hierarchy of flattened fields 527 final inline class Test27Value1 { 528 final Test27Value2 valueField; 529 530 private Test27Value1(Test27Value2 val2) { 531 valueField = val2; 532 } 533 534 @DontInline 535 public int test(Test27Value1 val1) { 536 return valueField.test(valueField) + val1.valueField.test(valueField); 537 } 538 } 539 540 final inline class Test27Value2 { 541 final Test27Value3 valueField; 542 543 private Test27Value2(Test27Value3 val3) { 544 valueField = val3; 545 } 546 547 @DontInline 548 public int test(Test27Value2 val2) { 549 return valueField.test(valueField) + val2.valueField.test(valueField); 550 } 551 } 552 553 final inline class Test27Value3 { 554 final int x; 555 556 private Test27Value3(int x) { 557 this.x = x; 558 } 559 560 @DontInline 561 public int test(Test27Value3 val3) { 562 return x + val3.x; 563 } 564 } 565 566 @Test 567 public int test27(Test27Value1 val) { 568 return val.test(val); 569 } 570 571 @DontCompile 572 public void test27_verifier(boolean warmup) { 573 Test27Value3 val3 = new Test27Value3(rI); 574 Test27Value2 val2 = new Test27Value2(val3); 575 Test27Value1 val1 = new Test27Value1(val2); 576 int result = test27(val1); 577 Asserts.assertEQ(result, 8*rI); 578 } 579 580 static final MyValue1? test28Val = MyValue1.createWithFieldsDontInline(rI, rL); 581 582 @Test 583 @Warmup(0) 584 public String test28() { 585 return test28Val.toString(); 586 } 587 588 @DontCompile 589 public void test28_verifier(boolean warmup) { 590 String result = test28(); 591 } 592 593 // Test calling a method returning a value type as fields via reflection 594 MyValue3 test29_vt = MyValue3.create(); 595 596 @Test 597 public MyValue3 test29() { 598 return test29_vt; 599 } 600 601 @DontCompile 602 public void test29_verifier(boolean warmup) throws Exception { 603 MyValue3 vt = (MyValue3)TestCallingConvention.class.getDeclaredMethod("test29").invoke(this); 604 test29_vt.verify(vt); 605 } 606 607 @Test 608 public MyValue3 test30(MyValue3[] array) { 609 MyValue3 result = MyValue3.create(); 610 array[0] = result; 611 return result; 612 } 613 614 @DontCompile 615 public void test30_verifier(boolean warmup) throws Exception { 616 MyValue3[] array = new MyValue3[1]; 617 MyValue3 vt = (MyValue3)TestCallingConvention.class.getDeclaredMethod("test30", MyValue3[].class).invoke(this, (Object)array); 618 array[0].verify(vt); 619 } 620 621 MyValue3 test31_vt; 622 623 @Test 624 public MyValue3 test31() { 625 MyValue3 result = MyValue3.create(); 626 test31_vt = result; 627 return result; 628 } 629 630 @DontCompile 631 public void test31_verifier(boolean warmup) throws Exception { 632 MyValue3 vt = (MyValue3)TestCallingConvention.class.getDeclaredMethod("test31").invoke(this); 633 test31_vt.verify(vt); 634 } 635 636 // Test deoptimization at call return with return value in registers. Same as test14, except the interpreted method 637 // is called via a MethodHandle. 638 static MethodHandle test32_mh; 639 640 @DontCompile 641 public MyValue2 test32_interp(boolean deopt) { 642 if (deopt) { 643 // uncommon trap 644 WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test32")); 645 } 646 return MyValue2.createWithFieldsInline(rI+32, true); 647 } 648 649 @Test() 650 public MyValue2 test32(boolean flag) throws Throwable { 651 return (MyValue2)test32_mh.invokeExact(this, flag); 652 } 653 654 @DontCompile 655 public void test32_verifier(boolean warmup) throws Throwable { 656 MyValue2 result = test32(!warmup); 657 MyValue2 v = MyValue2.createWithFieldsInline(rI+32, true); 658 Asserts.assertEQ(result.hash(), v.hash()); 659 } 660 661 // Same as test32, except the return type is not flattenable. 662 static MethodHandle test33_mh; 663 664 @DontCompile 665 public Object test33_interp(boolean deopt) { 666 if (deopt) { 667 // uncommon trap 668 WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test33")); 669 } 670 return MyValue2.createWithFieldsInline(rI+33, true); 671 } 672 673 @Test() 674 public MyValue2 test33(boolean flag) throws Throwable { 675 Object o = test33_mh.invokeExact(this, flag); 676 return (MyValue2)o; 677 } 678 679 @DontCompile 680 public void test33_verifier(boolean warmup) throws Throwable { 681 MyValue2 result = test33(!warmup); 682 MyValue2 v = MyValue2.createWithFieldsInline(rI+33, true); 683 Asserts.assertEQ(result.hash(), v.hash()); 684 } 685 }