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 sun.hotspot.WhiteBox; 27 import jdk.test.lib.Asserts; 28 29 /* 30 * @test 31 * @summary Test calls from {C1} to {C2, Interpreter}, and vice versa. 32 * @library /testlibrary /test/lib /compiler/whitebox / 33 * @requires os.simpleArch == "x64" 34 * @requires vm.compMode != "Xcomp" 35 * @compile TestCallingConventionC1.java 36 * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform 37 * @run main/othervm/timeout=120 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions 38 * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:+EnableValhalla 39 * compiler.valhalla.valuetypes.ValueTypeTest 40 * compiler.valhalla.valuetypes.TestCallingConventionC1 41 */ 42 public class TestCallingConventionC1 extends ValueTypeTest { 43 public static final int C1 = COMP_LEVEL_SIMPLE; 44 public static final int C2 = COMP_LEVEL_FULL_OPTIMIZATION; 45 46 @Override 47 public int getNumScenarios() { 48 return 2; 49 } 50 51 @Override 52 public String[] getVMParameters(int scenario) { 53 switch (scenario) { 54 55 // Default: both C1 and C2 are enabled, tierd compilation enabled 56 case 0: return new String[] {"-XX:+EnableValhallaC1", "-XX:CICompilerCount=2" 57 // , "-XX:-CheckCompressedOops", "-XX:CompileCommand=print,*::test78*" 58 //, "-XX:CompileCommand=print,*::func_c1" 59 }; 60 // Only C1. Tierd compilation disabled. 61 case 1: return new String[] {"-XX:+EnableValhallaC1", "-XX:TieredStopAtLevel=1" 62 // , "-XX:-CheckCompressedOops", "-XX:CompileCommand=print,*::test76*" 63 }; 64 } 65 return null; 66 } 67 68 public static void main(String[] args) throws Throwable { 69 System.gc(); // Resolve this call, to avoid C1 code patching in the test cases. 70 TestCallingConventionC1 test = new TestCallingConventionC1(); 71 test.run(args, 72 Point.class, 73 Functor.class, 74 Functor1.class, 75 Functor2.class, 76 Functor3.class, 77 Functor4.class, 78 MyImplPojo0.class, 79 MyImplPojo1.class, 80 MyImplPojo2.class, 81 MyImplVal1.class, 82 MyImplVal2.class, 83 FixedPoints.class, 84 FloatPoint.class, 85 RefPoint.class); 86 } 87 88 static inline class Point { 89 final int x; 90 final int y; 91 public Point(int x, int y) { 92 this.x = x; 93 this.y = y; 94 } 95 96 @DontCompile 97 @DontInline 98 public int func() { 99 return x + y; 100 } 101 102 @ForceCompile(compLevel = C1) 103 @DontInline 104 public int func_c1(Point p) { 105 return x + y + p.x + p.y; 106 } 107 } 108 109 static interface FunctorInterface { 110 public int apply_interp(Point p); 111 } 112 113 static class Functor implements FunctorInterface { 114 @DontCompile 115 @DontInline 116 public int apply_interp(Point p) { 117 return p.func() + 0; 118 } 119 } 120 static class Functor1 extends Functor { 121 @DontCompile 122 @DontInline 123 public int apply_interp(Point p) { 124 return p.func() + 10000; 125 } 126 } 127 static class Functor2 extends Functor { 128 @DontCompile 129 @DontInline 130 public int apply_interp(Point p) { 131 return p.func() + 20000; 132 } 133 } 134 static class Functor3 extends Functor { 135 @DontCompile 136 @DontInline 137 public int apply_interp(Point p) { 138 return p.func() + 30000; 139 } 140 } 141 static class Functor4 extends Functor { 142 @DontCompile 143 @DontInline 144 public int apply_interp(Point p) { 145 return p.func() + 40000; 146 } 147 } 148 149 static Functor functors[] = { 150 new Functor(), 151 new Functor1(), 152 new Functor2(), 153 new Functor3(), 154 new Functor4() 155 }; 156 static int functorCounter = 0; 157 static Functor getFunctor() { 158 int n = (++ functorCounter) % functors.length; 159 return functors[n]; 160 } 161 162 static Point pointField = new Point(123, 456); 163 static Point pointField1 = new Point(1123, 1456); 164 static Point pointField2 = new Point(2123, 2456); 165 166 static interface Intf { 167 public int func1(int a, int b); 168 public int func2(int a, int b, Point p); 169 } 170 171 static class MyImplPojo0 implements Intf { 172 int field = 0; 173 @DontInline @DontCompile 174 public int func1(int a, int b) { return field + a + b + 1; } 175 @DontInline @DontCompile 176 public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 1; } 177 } 178 179 static class MyImplPojo1 implements Intf { 180 int field = 1000; 181 182 @DontInline @ForceCompile(compLevel = C1) 183 public int func1(int a, int b) { return field + a + b + 20; } 184 @DontInline @ForceCompile(compLevel = C1) 185 public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 20; } 186 } 187 188 static class MyImplPojo2 implements Intf { 189 int field = 2000; 190 191 @DontInline @ForceCompile(compLevel = C2) 192 public int func1(int a, int b) { return field + a + b + 20; } 193 @DontInline @ForceCompile(compLevel = C2) 194 public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 20; } 195 } 196 197 static inline class MyImplVal1 implements Intf { 198 final int field; 199 MyImplVal1() { 200 field = 11000; 201 } 202 203 @DontInline @ForceCompile(compLevel = C1) 204 public int func1(int a, int b) { return field + a + b + 300; } 205 206 @DontInline @ForceCompile(compLevel = C1) 207 public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 300; } 208 } 209 210 static inline class MyImplVal2 implements Intf { 211 final int field; 212 MyImplVal2() { 213 field = 12000; 214 } 215 216 @DontInline @ForceCompile(compLevel = C2) 217 public int func1(int a, int b) { return field + a + b + 300; } 218 219 @DontInline @ForceCompile(compLevel = C2) 220 public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 300; } 221 } 222 223 static Intf intfs[] = { 224 new MyImplPojo0(), // methods not compiled 225 new MyImplPojo1(), // methods compiled by C1 226 new MyImplPojo2(), // methods compiled by C2 227 new MyImplVal1(), // methods compiled by C1 228 new MyImplVal2() // methods compiled by C2 229 }; 230 static Intf getIntf(int i) { 231 int n = i % intfs.length; 232 return intfs[n]; 233 } 234 235 static inline class FixedPoints { 236 final boolean Z0 = false; 237 final boolean Z1 = true; 238 final byte B = (byte)2; 239 final char C = (char)34; 240 final short S = (short)456; 241 final int I = 5678; 242 final long J = 0x1234567800abcdefL; 243 } 244 static FixedPoints fixedPointsField = new FixedPoints(); 245 246 static inline class FloatPoint { 247 final float x; 248 final float y; 249 public FloatPoint(float x, float y) { 250 this.x = x; 251 this.y = y; 252 } 253 } 254 static inline class DoublePoint { 255 final double x; 256 final double y; 257 public DoublePoint(double x, double y) { 258 this.x = x; 259 this.y = y; 260 } 261 } 262 static FloatPoint floatPointField = new FloatPoint(123.456f, 789.012f); 263 static DoublePoint doublePointField = new DoublePoint(123.456, 789.012); 264 265 static inline class EightFloats { 266 float f1, f2, f3, f4, f5, f6, f7, f8; 267 public EightFloats() { 268 f1 = 1.1f; 269 f2 = 2.2f; 270 f3 = 3.3f; 271 f4 = 4.4f; 272 f5 = 5.5f; 273 f6 = 6.6f; 274 f7 = 7.7f; 275 f8 = 8.8f; 276 } 277 } 278 static EightFloats eightFloatsField = new EightFloats(); 279 280 static class Number { 281 int n; 282 Number(int v) { 283 n = v; 284 } 285 void set(int v) { 286 n = v; 287 } 288 } 289 290 static interface RefPoint_Access { 291 public int func1(RefPoint rp2); 292 public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2); 293 } 294 295 static inline class RefPoint implements RefPoint_Access { 296 final Number x; 297 final Number y; 298 public RefPoint(int x, int y) { 299 this.x = new Number(x); 300 this.y = new Number(y); 301 } 302 303 @DontInline 304 @ForceCompile(compLevel = C1) 305 public final int final_func(RefPoint rp2) { // opt_virtual_call 306 return this.x.n + this.y.n + rp2.x.n + rp2.y.n; 307 } 308 309 @DontInline 310 @ForceCompile(compLevel = C1) 311 public int func1(RefPoint rp2) { 312 return this.x.n + this.y.n + rp2.x.n + rp2.y.n; 313 } 314 315 @DontInline 316 @ForceCompile(compLevel = C1) 317 public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { 318 return x.n + y.n + 319 rp1.x.n + rp1.y.n + 320 rp2.x.n + rp2.y.n + 321 n1.n + 322 rp3.x.n + rp3.y.n + 323 rp4.x.n + rp4.y.n + 324 n2.n; 325 } 326 } 327 328 static class RefPoint_Access_Impl1 implements RefPoint_Access { 329 @DontInline @DontCompile 330 public int func1(RefPoint rp2) { 331 return rp2.x.n + rp2.y.n + 1111111; 332 } 333 @DontInline @DontCompile 334 public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { 335 return 111111 + 336 rp1.x.n + rp1.y.n + 337 rp2.x.n + rp2.y.n + 338 n1.n + 339 rp3.x.n + rp3.y.n + 340 rp4.x.n + rp4.y.n + 341 n2.n; 342 } 343 } 344 static class RefPoint_Access_Impl2 implements RefPoint_Access { 345 @DontInline @DontCompile 346 public int func1(RefPoint rp2) { 347 return rp2.x.n + rp2.y.n + 2222222; 348 } 349 @DontInline @DontCompile 350 public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { 351 return 222222 + 352 rp1.x.n + rp1.y.n + 353 rp2.x.n + rp2.y.n + 354 n1.n + 355 rp3.x.n + rp3.y.n + 356 rp4.x.n + rp4.y.n + 357 n2.n; 358 } 359 } 360 361 static RefPoint_Access refPoint_Access_impls[] = { 362 new RefPoint_Access_Impl1(), 363 new RefPoint_Access_Impl2(), 364 new RefPoint(0x12345, 0x6789a) 365 }; 366 367 static int next_RefPoint_Access = 0; 368 static RefPoint_Access get_RefPoint_Access() { 369 int i = next_RefPoint_Access ++; 370 return refPoint_Access_impls[i % refPoint_Access_impls.length]; 371 } 372 373 static RefPoint refPointField1 = new RefPoint(12, 34); 374 static RefPoint refPointField2 = new RefPoint(56789, 0x12345678); 375 376 // This inline class has too many fields to fit in registers on x64 for 377 // ValueTypeReturnedAsFields. 378 static inline class TooBigToReturnAsFields { 379 int a0 = 0; 380 int a1 = 1; 381 int a2 = 2; 382 int a3 = 3; 383 int a4 = 4; 384 int a5 = 5; 385 int a6 = 6; 386 int a7 = 7; 387 int a8 = 8; 388 int a9 = 9; 389 } 390 391 static TooBigToReturnAsFields tooBig = new TooBigToReturnAsFields(); 392 393 //********************************************************************** 394 // PART 1 - C1 calls interpreted code 395 //********************************************************************** 396 397 398 //** C1 passes value to interpreter (static) 399 @Test(compLevel = C1) 400 public int test1() { 401 return test1_helper(pointField); 402 } 403 404 @DontInline 405 @DontCompile 406 private static int test1_helper(Point p) { 407 return p.func(); 408 } 409 410 @DontCompile 411 public void test1_verifier(boolean warmup) { 412 int count = warmup ? 1 : 10; 413 for (int i=0; i<count; i++) { // need a loop to test inline cache 414 int result = test1() + i; 415 Asserts.assertEQ(result, pointField.func() + i); 416 } 417 } 418 419 420 //** C1 passes value to interpreter (monomorphic) 421 @Test(compLevel = C1) 422 public int test2() { 423 return test2_helper(pointField); 424 } 425 426 @DontInline 427 @DontCompile 428 private int test2_helper(Point p) { 429 return p.func(); 430 } 431 432 @DontCompile 433 public void test2_verifier(boolean warmup) { 434 int count = warmup ? 1 : 10; 435 for (int i=0; i<count; i++) { // need a loop to test inline cache 436 int result = test2() + i; 437 Asserts.assertEQ(result, pointField.func() + i); 438 } 439 } 440 441 // C1 passes value to interpreter (megamorphic: vtable) 442 @Test(compLevel = C1) 443 public int test3(Functor functor) { 444 return functor.apply_interp(pointField); 445 } 446 447 @DontCompile 448 public void test3_verifier(boolean warmup) { 449 int count = warmup ? 1 : 100; 450 for (int i=0; i<count; i++) { // need a loop to test inline cache and vtable indexing 451 Functor functor = warmup ? functors[0] : getFunctor(); 452 int result = test3(functor) + i; 453 Asserts.assertEQ(result, functor.apply_interp(pointField) + i); 454 } 455 } 456 457 // Same as test3, but compiled with C2. Test the hastable of VtableStubs 458 @Test(compLevel = C2) 459 public int test3b(Functor functor) { 460 return functor.apply_interp(pointField); 461 } 462 463 @DontCompile 464 public void test3b_verifier(boolean warmup) { 465 int count = warmup ? 1 : 100; 466 for (int i=0; i<count; i++) { // need a loop to test inline cache and vtable indexing 467 Functor functor = warmup ? functors[0] : getFunctor(); 468 int result = test3b(functor) + i; 469 Asserts.assertEQ(result, functor.apply_interp(pointField) + i); 470 } 471 } 472 473 // C1 passes value to interpreter (megamorphic: itable) 474 @Test(compLevel = C1) 475 public int test4(FunctorInterface fi) { 476 return fi.apply_interp(pointField); 477 } 478 479 @DontCompile 480 public void test4_verifier(boolean warmup) { 481 int count = warmup ? 1 : 100; 482 for (int i=0; i<count; i++) { // need a loop to test inline cache and itable indexing 483 Functor functor = warmup ? functors[0] : getFunctor(); 484 int result = test4(functor) + i; 485 Asserts.assertEQ(result, functor.apply_interp(pointField) + i); 486 } 487 } 488 489 //********************************************************************** 490 // PART 2 - interpreter calls C1 491 //********************************************************************** 492 493 // Interpreter passes value to C1 (static) 494 @Test(compLevel = C1) 495 static public int test20(Point p1, long l, Point p2) { 496 return p1.x + p2.y; 497 } 498 499 @DontCompile 500 public void test20_verifier(boolean warmup) { 501 int result = test20(pointField1, 0, pointField2); 502 int n = pointField1.x + pointField2.y; 503 Asserts.assertEQ(result, n); 504 } 505 506 // Interpreter passes value to C1 (instance method in inline class) 507 @Test 508 public int test21(Point p) { 509 return test21_helper(p); 510 } 511 512 @DontCompile 513 @DontInline 514 int test21_helper(Point p) { 515 return p.func_c1(p); 516 } 517 518 @DontCompile 519 public void test21_verifier(boolean warmup) { 520 int result = test21(pointField); 521 int n = 2 * (pointField.x + pointField.y); 522 Asserts.assertEQ(result, n); 523 } 524 525 526 //********************************************************************** 527 // PART 3 - C2 calls C1 528 //********************************************************************** 529 530 // C2->C1 invokestatic, single value arg 531 @Test(compLevel = C2) 532 public int test30() { 533 return test30_helper(pointField); 534 } 535 536 @DontInline 537 @ForceCompile(compLevel = C1) 538 private static int test30_helper(Point p) { 539 return p.x + p.y; 540 } 541 542 @DontCompile 543 public void test30_verifier(boolean warmup) { 544 int count = warmup ? 1 : 2; 545 for (int i=0; i<count; i++) { // need a loop to test inline cache 546 int result = test30(); 547 int n = pointField.x + pointField.y; 548 Asserts.assertEQ(result, n); 549 } 550 } 551 552 // C2->C1 invokestatic, two single value args 553 @Test(compLevel = C2) 554 public int test31() { 555 return test31_helper(pointField1, pointField2); 556 } 557 558 @DontInline 559 @ForceCompile(compLevel = C1) 560 private static int test31_helper(Point p1, Point p2) { 561 return p1.x + p2.y; 562 } 563 564 @DontCompile 565 public void test31_verifier(boolean warmup) { 566 int count = warmup ? 1 : 2; 567 for (int i=0; i<count; i++) { // need a loop to test inline cache 568 int result = test31(); 569 int n = pointField1.x + pointField2.y; 570 Asserts.assertEQ(result, n); 571 } 572 } 573 574 // C2->C1 invokestatic, two single value args and interleaving ints (all passed in registers on x64) 575 @Test(compLevel = C2) 576 public int test32() { 577 return test32_helper(0, pointField1, 1, pointField2); 578 } 579 580 @DontInline 581 @ForceCompile(compLevel = C1) 582 private static int test32_helper(int x, Point p1, int y, Point p2) { 583 return p1.x + p2.y + x + y; 584 } 585 586 @DontCompile 587 public void test32_verifier(boolean warmup) { 588 int count = warmup ? 1 : 2; 589 for (int i=0; i<count; i++) { // need a loop to test inline cache 590 int result = test32(); 591 int n = pointField1.x + pointField2.y + 0 + 1; 592 Asserts.assertEQ(result, n); 593 } 594 } 595 596 // C2->C1 invokeinterface -- no verified_ro_entry (no value args except for receiver) 597 @Test(compLevel = C2) 598 public int test33(Intf intf, int a, int b) { 599 return intf.func1(a, b); 600 } 601 602 @DontCompile 603 public void test33_verifier(boolean warmup) { 604 int count = warmup ? 1 : 20; 605 for (int i=0; i<count; i++) { 606 Intf intf = warmup ? intfs[0] : getIntf(i+1); 607 int result = test33(intf, 123, 456) + i; 608 Asserts.assertEQ(result, intf.func1(123, 456) + i); 609 } 610 } 611 612 // C2->C1 invokeinterface -- use verified_ro_entry (has value args other than receiver) 613 @Test(compLevel = C2) 614 public int test34(Intf intf, int a, int b) { 615 return intf.func2(a, b, pointField); 616 } 617 618 @DontCompile 619 public void test34_verifier(boolean warmup) { 620 int count = warmup ? 1 : 20; 621 for (int i=0; i<count; i++) { 622 Intf intf = warmup ? intfs[0] : getIntf(i+1); 623 int result = test34(intf, 123, 456) + i; 624 Asserts.assertEQ(result, intf.func2(123, 456, pointField) + i); 625 } 626 } 627 628 // C2->C1 invokestatic, Point.y is on stack (x64) 629 @Test(compLevel = C2) 630 public int test35() { 631 return test35_helper(1, 2, 3, 4, 5, pointField); 632 } 633 634 @DontInline 635 @ForceCompile(compLevel = C1) 636 private static int test35_helper(int a1, int a2, int a3, int a4, int a5, Point p) { 637 return a1 + a2 + a3 + a4 + a5 + p.x + p.y; 638 } 639 640 @DontCompile 641 public void test35_verifier(boolean warmup) { 642 int count = warmup ? 1 : 2; 643 for (int i=0; i<count; i++) { // need a loop to test inline cache 644 int result = test35(); 645 int n = 1 + 2 + 3 + 4 + 5 + pointField.x + pointField.y; 646 Asserts.assertEQ(result, n); 647 } 648 } 649 650 // C2->C1 invokestatic, shuffling arguments that are passed on stack 651 @Test(compLevel = C2) 652 public int test36() { 653 return test36_helper(pointField, 1, 2, 3, 4, 5, 6, 7, 8); 654 } 655 656 @DontInline 657 @ForceCompile(compLevel = C1) 658 private static int test36_helper(Point p, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { 659 return a6 + a8; 660 } 661 662 @DontCompile 663 public void test36_verifier(boolean warmup) { 664 int count = warmup ? 1 : 2; 665 for (int i=0; i<count; i++) { // need a loop to test inline cache 666 int result = test36(); 667 int n = 6 + 8; 668 Asserts.assertEQ(result, n); 669 } 670 } 671 672 // C2->C1 invokestatic, shuffling long arguments 673 @Test(compLevel = C2) 674 public int test37() { 675 return test37_helper(pointField, 1, 2, 3, 4, 5, 6, 7, 8); 676 } 677 678 @DontInline 679 @ForceCompile(compLevel = C1) 680 private static int test37_helper(Point p, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) { 681 return (int)(a6 + a8); 682 } 683 684 @DontCompile 685 public void test37_verifier(boolean warmup) { 686 int count = warmup ? 1 : 2; 687 for (int i=0; i<count; i++) { // need a loop to test inline cache 688 int result = test37(); 689 int n = 6 + 8; 690 Asserts.assertEQ(result, n); 691 } 692 } 693 694 // C2->C1 invokestatic, shuffling boolean, byte, char, short, int, long arguments 695 @Test(compLevel = C2) 696 public int test38() { 697 return test38_helper(pointField, true, (byte)1, (char)2, (short)3, 4, 5, (byte)6, (short)7, 8); 698 } 699 700 @DontInline 701 @ForceCompile(compLevel = C1) 702 private static int test38_helper(Point p, boolean a0, byte a1, char a2, short a3, int a4, long a5, byte a6, short a7, int a8) { 703 if (a0) { 704 return (int)(a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8); 705 } else { 706 return -1; 707 } 708 } 709 710 @DontCompile 711 public void test38_verifier(boolean warmup) { 712 int count = warmup ? 1 : 2; 713 for (int i=0; i<count; i++) { // need a loop to test inline cache 714 int result = test38(); 715 int n = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8; 716 Asserts.assertEQ(result, n); 717 } 718 } 719 720 // C2->C1 invokestatic, packing a value object with all types of fixed point primitive fields. 721 @Test(compLevel = C2) 722 public long test39() { 723 return test39_helper(1, fixedPointsField, 2, fixedPointsField); 724 } 725 726 @DontInline 727 @ForceCompile(compLevel = C1) 728 private static long test39_helper(int a1, FixedPoints f1, int a2, FixedPoints f2) { 729 if (f1.Z0 == false && f1.Z1 == true && f2.Z0 == false && f2.Z1 == true) { 730 return f1.B + f2.C + f1.S + f2.I + f1.J; 731 } else { 732 return -1; 733 } 734 } 735 736 @DontCompile 737 public void test39_verifier(boolean warmup) { 738 int count = warmup ? 1 : 2; 739 for (int i=0; i<count; i++) { // need a loop to test inline cache 740 long result = test39(); 741 long n = test39_helper(1, fixedPointsField, 2, fixedPointsField); 742 Asserts.assertEQ(result, n); 743 } 744 } 745 746 // C2->C1 invokestatic, shuffling floating point args 747 @Test(compLevel = C2) 748 public double test40() { 749 return test40_helper(1.1f, 1.2, floatPointField, doublePointField, 1.3f, 1.4, 1.5f, 1.7, 1.7, 1.8, 1.9, 1.10, 1.11, 1.12); 750 } 751 752 @DontInline 753 @ForceCompile(compLevel = C1) 754 private static double test40_helper(float a1, double a2, FloatPoint fp, DoublePoint dp, float a3, double a4, float a5, double a6, double a7, double a8, double a9, double a10, double a11, double a12) { 755 return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12 + fp.x + fp.y - dp.x - dp.y; 756 } 757 758 @DontCompile 759 public void test40_verifier(boolean warmup) { 760 int count = warmup ? 1 : 2; 761 for (int i=0; i<count; i++) { // need a loop to test inline cache 762 double result = test40(); 763 double n = test40_helper(1.1f, 1.2, floatPointField, doublePointField, 1.3f, 1.4, 1.5f, 1.7, 1.7, 1.8, 1.9, 1.10, 1.11, 1.12); 764 Asserts.assertEQ(result, n); 765 } 766 } 767 768 // C2->C1 invokestatic, mixing floats and ints 769 @Test(compLevel = C2) 770 public double test41() { 771 return test41_helper(1, 1.2, pointField, floatPointField, doublePointField, 1.3f, 4, 1.5f, 1.7, 1.7, 1.8, 9, 1.10, 1.11, 1.12); 772 } 773 774 @DontInline 775 @ForceCompile(compLevel = C1) 776 private static double test41_helper(int a1, double a2, Point p, FloatPoint fp, DoublePoint dp, float a3, int a4, float a5, double a6, double a7, double a8, long a9, double a10, double a11, double a12) { 777 return a1 + a2 + fp.x + fp.y - dp.x - dp.y + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12; 778 } 779 780 @DontCompile 781 public void test41_verifier(boolean warmup) { 782 int count = warmup ? 1 : 2; 783 for (int i=0; i<count; i++) { // need a loop to test inline cache 784 double result = test41(); 785 double n = test41_helper(1, 1.2, pointField, floatPointField, doublePointField, 1.3f, 4, 1.5f, 1.7, 1.7, 1.8, 9, 1.10, 1.11, 1.12); 786 Asserts.assertEQ(result, n); 787 } 788 } 789 790 // C2->C1 invokestatic, circular dependency (between rdi and first stack slot on x64) 791 @Test(compLevel = C2) 792 public float test42() { 793 return test42_helper(eightFloatsField, pointField, 3, 4, 5, floatPointField, 7); 794 } 795 796 @DontInline 797 @ForceCompile(compLevel = C1) 798 private static float test42_helper(EightFloats ep1, // (xmm0 ... xmm7) -> rsi 799 Point p2, // (rsi, rdx) -> rdx 800 int i3, // rcx -> rcx 801 int i4, // r8 -> r8 802 int i5, // r9 -> r9 803 FloatPoint fp6, // (stk[0], stk[1]) -> rdi ** circ depend 804 int i7) // rdi -> stk[0] ** circ depend 805 { 806 return ep1.f1 + ep1.f2 + ep1.f3 + ep1.f4 + ep1.f5 + ep1.f6 + ep1.f7 + ep1.f8 + 807 p2.x + p2.y + i3 + i4 + i5 + fp6.x + fp6.y + i7; 808 } 809 810 @DontCompile 811 public void test42_verifier(boolean warmup) { 812 int count = warmup ? 1 : 2; 813 for (int i=0; i<count; i++) { // need a loop to test inline cache 814 float result = test42(); 815 float n = test42_helper(eightFloatsField, pointField, 3, 4, 5, floatPointField, 7); 816 Asserts.assertEQ(result, n); 817 } 818 } 819 820 // C2->C1 invokestatic, packing causes stack growth (1 extra stack word) 821 @Test(compLevel = C2) 822 public float test43() { 823 return test43_helper(floatPointField, 1, 2, 3, 4, 5, 6); 824 } 825 826 @DontInline 827 @ForceCompile(compLevel = C1) 828 private static float test43_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5, int a6) { 829 // On x64: 830 // Scalarized entry -- all parameters are passed in registers 831 // Non-scalarized entry -- a6 is passed on stack[0] 832 return fp.x + fp.y + a1 + a2 + a3 + a4 + a5 + a6; 833 } 834 835 @DontCompile 836 public void test43_verifier(boolean warmup) { 837 int count = warmup ? 1 : 2; 838 for (int i=0; i<count; i++) { // need a loop to test inline cache 839 float result = test43(); 840 float n = test43_helper(floatPointField, 1, 2, 3, 4, 5, 6); 841 Asserts.assertEQ(result, n); 842 } 843 } 844 845 // C2->C1 invokestatic, packing causes stack growth (2 extra stack words) 846 @Test(compLevel = C2) 847 public float test44() { 848 return test44_helper(floatPointField, floatPointField, 1, 2, 3, 4, 5, 6); 849 } 850 851 @DontInline 852 @ForceCompile(compLevel = C1) 853 private static float test44_helper(FloatPoint fp1, FloatPoint fp2, int a1, int a2, int a3, int a4, int a5, int a6) { 854 // On x64: 855 // Scalarized entry -- all parameters are passed in registers 856 // Non-scalarized entry -- a5 is passed on stack[0] 857 // Non-scalarized entry -- a6 is passed on stack[1] 858 return fp1.x + fp1.y + 859 fp2.x + fp2.y + 860 a1 + a2 + a3 + a4 + a5 + a6; 861 } 862 863 @DontCompile 864 public void test44_verifier(boolean warmup) { 865 int count = warmup ? 1 : 2; 866 for (int i=0; i<count; i++) { // need a loop to test inline cache 867 float result = test44(); 868 float n = test44_helper(floatPointField, floatPointField, 1, 2, 3, 4, 5, 6); 869 Asserts.assertEQ(result, n); 870 } 871 } 872 873 // C2->C1 invokestatic, packing causes stack growth (5 extra stack words) 874 @Test(compLevel = C2) 875 public float test45() { 876 return test45_helper(floatPointField, floatPointField, floatPointField, floatPointField, floatPointField, 1, 2, 3, 4, 5, 6, 7); 877 } 878 879 @DontInline 880 @ForceCompile(compLevel = C1) 881 private static float test45_helper(FloatPoint fp1, FloatPoint fp2, FloatPoint fp3, FloatPoint fp4, FloatPoint fp5, int a1, int a2, int a3, int a4, int a5, int a6, int a7) { 882 return fp1.x + fp1.y + 883 fp2.x + fp2.y + 884 fp3.x + fp3.y + 885 fp4.x + fp4.y + 886 fp5.x + fp5.y + 887 a1 + a2 + a3 + a4 + a5 + a6 + a7; 888 } 889 890 @DontCompile 891 public void test45_verifier(boolean warmup) { 892 int count = warmup ? 1 : 2; 893 for (int i=0; i<count; i++) { // need a loop to test inline cache 894 float result = test45(); 895 float n = test45_helper(floatPointField, floatPointField, floatPointField, floatPointField, floatPointField, 1, 2, 3, 4, 5, 6, 7); 896 Asserts.assertEQ(result, n); 897 } 898 } 899 900 // C2->C1 invokestatic, packing causes stack growth (1 extra stack word -- mixing Point and FloatPoint) 901 @Test(compLevel = C2) 902 public float test46() { 903 return test46_helper(floatPointField, floatPointField, pointField, floatPointField, floatPointField, pointField, floatPointField, 1, 2, 3, 4, 5, 6, 7); 904 } 905 906 @DontInline 907 @ForceCompile(compLevel = C1) 908 private static float test46_helper(FloatPoint fp1, FloatPoint fp2, Point p1, FloatPoint fp3, FloatPoint fp4, Point p2, FloatPoint fp5, int a1, int a2, int a3, int a4, int a5, int a6, int a7) { 909 return p1.x + p1.y + 910 p2.x + p2.y + 911 fp1.x + fp1.y + 912 fp2.x + fp2.y + 913 fp3.x + fp3.y + 914 fp4.x + fp4.y + 915 fp5.x + fp5.y + 916 a1 + a2 + a3 + a4 + a5 + a6 + a7; 917 } 918 919 @DontCompile 920 public void test46_verifier(boolean warmup) { 921 int count = warmup ? 1 : 2; 922 for (int i=0; i<count; i++) { // need a loop to test inline cache 923 float result = test46(); 924 float n = test46_helper(floatPointField, floatPointField, pointField, floatPointField, floatPointField, pointField, floatPointField, 1, 2, 3, 4, 5, 6, 7); 925 Asserts.assertEQ(result, n); 926 } 927 } 928 929 static class MyRuntimeException extends RuntimeException { 930 MyRuntimeException(String s) { 931 super(s); 932 } 933 } 934 935 static void checkStackTrace(Throwable t, String... methodNames) { 936 StackTraceElement[] trace = t.getStackTrace(); 937 for (int i=0; i<methodNames.length; i++) { 938 if (!methodNames[i].equals(trace[i].getMethodName())) { 939 String error = "Unexpected stack trace: level " + i + " should be " + methodNames[i]; 940 System.out.println(error); 941 t.printStackTrace(System.out); 942 throw new RuntimeException(error, t); 943 } 944 } 945 } 946 //* 947 948 // C2->C1 invokestatic, make sure stack walking works (with static variable) 949 @Test(compLevel = C2) 950 public void test47(int n) { 951 try { 952 test47_helper(floatPointField, 1, 2, 3, 4, 5); 953 test47_value = 666; 954 } catch (MyRuntimeException e) { 955 // expected; 956 } 957 test47_value = n; 958 } 959 960 @DontInline 961 @ForceCompile(compLevel = C1) 962 private static float test47_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5) { 963 test47_thrower(); 964 return 0.0f; 965 } 966 967 @DontInline @DontCompile 968 private static void test47_thrower() { 969 MyRuntimeException e = new MyRuntimeException("This exception should have been caught!"); 970 checkStackTrace(e, "test47_thrower", "test47_helper", "test47", "test47_verifier"); 971 throw e; 972 } 973 974 static int test47_value = 999; 975 976 @DontCompile 977 public void test47_verifier(boolean warmup) { 978 int count = warmup ? 1 : 5; 979 for (int i=0; i<count; i++) { // need a loop to test inline cache 980 test47_value = 777 + i; 981 test47(i); 982 Asserts.assertEQ(test47_value, i); 983 } 984 } 985 986 // C2->C1 invokestatic, make sure stack walking works (with returned value) 987 @Test(compLevel = C2) 988 public int test48(int n) { 989 try { 990 test48_helper(floatPointField, 1, 2, 3, 4, 5); 991 return 666; 992 } catch (MyRuntimeException e) { 993 // expected; 994 } 995 return n; 996 } 997 998 @DontInline 999 @ForceCompile(compLevel = C1) 1000 private static float test48_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5) { 1001 test48_thrower(); 1002 return 0.0f; 1003 } 1004 1005 @DontInline @DontCompile 1006 private static void test48_thrower() { 1007 MyRuntimeException e = new MyRuntimeException("This exception should have been caught!"); 1008 checkStackTrace(e, "test48_thrower", "test48_helper", "test48", "test48_verifier"); 1009 throw e; 1010 } 1011 1012 @DontCompile 1013 public void test48_verifier(boolean warmup) { 1014 int count = warmup ? 1 : 5; 1015 for (int i=0; i<count; i++) { // need a loop to test inline cache 1016 int n = test48(i); 1017 Asserts.assertEQ(n, i); 1018 } 1019 } 1020 1021 // C2->interpreter invokestatic, make sure stack walking works (same as test 48, but with stack extension/repair) 1022 // (this is the baseline for test50 -- 1023 // the only difference is: test49_helper is interpreted but test50_helper is compiled by C1). 1024 @Test(compLevel = C2) 1025 public int test49(int n) { 1026 try { 1027 test49_helper(floatPointField, 1, 2, 3, 4, 5, 6); 1028 return 666; 1029 } catch (MyRuntimeException e) { 1030 // expected; 1031 } 1032 return n; 1033 } 1034 1035 @DontInline @DontCompile 1036 private static float test49_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5, int a6) { 1037 test49_thrower(); 1038 return 0.0f; 1039 } 1040 1041 @DontInline @DontCompile 1042 private static void test49_thrower() { 1043 MyRuntimeException e = new MyRuntimeException("This exception should have been caught!"); 1044 checkStackTrace(e, "test49_thrower", "test49_helper", "test49", "test49_verifier"); 1045 throw e; 1046 } 1047 1048 @DontCompile 1049 public void test49_verifier(boolean warmup) { 1050 int count = warmup ? 1 : 5; 1051 for (int i=0; i<count; i++) { // need a loop to test inline cache 1052 int n = test49(i); 1053 Asserts.assertEQ(n, i); 1054 } 1055 } 1056 1057 // C2->C1 invokestatic, make sure stack walking works (same as test 48, but with stack extension/repair) 1058 @Test(compLevel = C2) 1059 public int test50(int n) { 1060 try { 1061 test50_helper(floatPointField, 1, 2, 3, 4, 5, 6); 1062 return 666; 1063 } catch (MyRuntimeException e) { 1064 // expected; 1065 } 1066 return n; 1067 } 1068 1069 @DontInline 1070 @ForceCompile(compLevel = C1) 1071 private static float test50_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5, int a6) { 1072 test50_thrower(); 1073 return 0.0f; 1074 } 1075 1076 @DontInline @DontCompile 1077 private static void test50_thrower() { 1078 MyRuntimeException e = new MyRuntimeException("This exception should have been caught!"); 1079 checkStackTrace(e, "test50_thrower", "test50_helper", "test50", "test50_verifier"); 1080 throw e; 1081 } 1082 1083 @DontCompile 1084 public void test50_verifier(boolean warmup) { 1085 int count = warmup ? 1 : 5; 1086 for (int i=0; i<count; i++) { // need a loop to test inline cache 1087 int n = test50(i); 1088 Asserts.assertEQ(n, i); 1089 } 1090 } 1091 1092 1093 // C2->C1 invokestatic, inline class with ref fields (RefPoint) 1094 @Test(compLevel = C2) 1095 public int test51() { 1096 return test51_helper(refPointField1); 1097 } 1098 1099 @DontInline 1100 @ForceCompile(compLevel = C1) 1101 private static int test51_helper(RefPoint rp1) { 1102 return rp1.x.n + rp1.y.n; 1103 } 1104 1105 @DontCompile 1106 public void test51_verifier(boolean warmup) { 1107 int count = warmup ? 1 : 5; 1108 for (int i=0; i<count; i++) { // need a loop to test inline cache 1109 int result = test51(); 1110 int n = test51_helper(refPointField1); 1111 Asserts.assertEQ(result, n); 1112 } 1113 } 1114 1115 // C2->C1 invokestatic, inline class with ref fields (Point, RefPoint) 1116 @Test(compLevel = C2) 1117 public int test52() { 1118 return test52_helper(pointField, refPointField1); 1119 } 1120 1121 @DontInline 1122 @ForceCompile(compLevel = C1) 1123 private static int test52_helper(Point p1, RefPoint rp1) { 1124 return p1.x + p1.y + rp1.x.n + rp1.y.n; 1125 } 1126 1127 @DontCompile 1128 public void test52_verifier(boolean warmup) { 1129 int count = warmup ? 1 : 5; 1130 for (int i=0; i<count; i++) { // need a loop to test inline cache 1131 int result = test52(); 1132 int n = test52_helper(pointField, refPointField1); 1133 Asserts.assertEQ(result, n); 1134 } 1135 } 1136 1137 // C2->C1 invokestatic, inline class with ref fields (RefPoint, RefPoint, RefPoint, RefPoint) 1138 @Test(compLevel = C2) 1139 public int test53() { 1140 return test53_helper(refPointField1, refPointField2, refPointField1, refPointField2); 1141 } 1142 1143 @DontInline 1144 @ForceCompile(compLevel = C1) 1145 private static int test53_helper(RefPoint rp1, RefPoint rp2, RefPoint rp3, RefPoint rp4) { 1146 return rp1.x.n + rp1.y.n + 1147 rp2.x.n + rp2.y.n + 1148 rp3.x.n + rp3.y.n + 1149 rp4.x.n + rp4.y.n; 1150 } 1151 1152 @DontCompile 1153 public void test53_verifier(boolean warmup) { 1154 int count = warmup ? 1 : 5; 1155 for (int i=0; i<count; i++) { // need a loop to test inline cache 1156 int result = test53(); 1157 int n = test53_helper(refPointField1, refPointField2, refPointField1, refPointField2); 1158 Asserts.assertEQ(result, n); 1159 } 1160 } 1161 1162 // C2->C1 invokestatic, inline class with ref fields (RefPoint, RefPoint, float, int, RefPoint, RefPoint) 1163 @Test(compLevel = C2) 1164 public int test54() { 1165 return test54_helper(refPointField1, refPointField2, 1.0f, 2, refPointField1, refPointField2); 1166 } 1167 1168 @DontInline 1169 @ForceCompile(compLevel = C1) 1170 private static int test54_helper(RefPoint rp1, RefPoint rp2, float f, int i, RefPoint rp3, RefPoint rp4) { 1171 return rp1.x.n + rp1.y.n + 1172 rp2.x.n + rp2.y.n + 1173 (int)(f) + i + 1174 rp3.x.n + rp3.y.n + 1175 rp4.x.n + rp4.y.n; 1176 } 1177 1178 @DontCompile 1179 public void test54_verifier(boolean warmup) { 1180 int count = warmup ? 1 : 5; 1181 for (int i=0; i<count; i++) { // need a loop to test inline cache 1182 int result = test54(); 1183 int n = test54_helper(refPointField1, refPointField2, 1.0f, 2, refPointField1, refPointField2); 1184 Asserts.assertEQ(result, n); 1185 } 1186 } 1187 1188 static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); 1189 static final String ScavengeALot = "ScavengeALot"; 1190 1191 1192 /** 1193 * Each allocation with a "try" block like this will cause a GC 1194 * 1195 * try (ForceGCMarker m = ForceGCMarker.mark(warmup)) { 1196 * result = test55(p1); 1197 * } 1198 */ 1199 static class ForceGCMarker implements java.io.Closeable { 1200 static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); 1201 1202 ForceGCMarker() { 1203 WHITE_BOX.setBooleanVMFlag(ScavengeALot, true); 1204 } 1205 public void close() { 1206 WHITE_BOX.setBooleanVMFlag(ScavengeALot, false); 1207 } 1208 1209 static ForceGCMarker mark(boolean warmup) { 1210 return warmup ? null : new ForceGCMarker(); 1211 } 1212 } 1213 1214 // C2->C1 invokestatic, force GC for every allocation when entering a C1 VEP (Point) 1215 @Test(compLevel = C2) 1216 public int test55(Point p1) { 1217 return test55_helper(p1); 1218 } 1219 1220 @DontInline 1221 @ForceCompile(compLevel = C1) 1222 private static int test55_helper(Point p1) { 1223 return p1.x + p1.y; 1224 } 1225 1226 @DontCompile 1227 public void test55_verifier(boolean warmup) { 1228 int count = warmup ? 1 : 5; 1229 for (int i=0; i<count; i++) { // need a loop to test inline cache 1230 Point p1 = new Point(1, 2); 1231 int result; 1232 try (ForceGCMarker m = ForceGCMarker.mark(warmup)) { 1233 result = test55(p1); 1234 } 1235 int n = test55_helper(p1); 1236 Asserts.assertEQ(result, n); 1237 } 1238 } 1239 1240 // C2->C1 invokestatic, force GC for every allocation when entering a C1 VEP (RefPoint) 1241 @Test(compLevel = C2) 1242 public int test56(RefPoint rp1) { 1243 return test56_helper(rp1); 1244 } 1245 1246 @DontInline 1247 @ForceCompile(compLevel = C1) 1248 private static int test56_helper(RefPoint rp1) { 1249 return rp1.x.n + rp1.y.n; 1250 } 1251 1252 @DontCompile 1253 public void test56_verifier(boolean warmup) { 1254 int count = warmup ? 1 : 5; 1255 for (int i=0; i<count; i++) { // need a loop to test inline cache 1256 RefPoint rp1 = new RefPoint(1, 2); 1257 int result; 1258 try (ForceGCMarker m = ForceGCMarker.mark(warmup)) { 1259 result = test56(rp1); 1260 } 1261 int n = test56_helper(rp1); 1262 Asserts.assertEQ(result, n); 1263 } 1264 } 1265 1266 // C2->Interpreter (same as test56, but test c2i entry instead of C1) 1267 @Test(compLevel = C2) 1268 public int test57(RefPoint rp1) { 1269 return test57_helper(rp1); 1270 } 1271 1272 @DontInline @DontCompile 1273 private static int test57_helper(RefPoint rp1) { 1274 return rp1.x.n + rp1.y.n; 1275 } 1276 1277 @DontCompile 1278 public void test57_verifier(boolean warmup) { 1279 int count = warmup ? 1 : 5; 1280 for (int i=0; i<count; i++) { // need a loop to test inline cache 1281 RefPoint rp1 = new RefPoint(1, 2); 1282 int result; 1283 try (ForceGCMarker m = ForceGCMarker.mark(warmup)) { 1284 result = test57(rp1); 1285 } 1286 int n = test57_helper(rp1); 1287 Asserts.assertEQ(result, n); 1288 } 1289 } 1290 1291 // C2->C1 invokestatic, force GC for every allocation when entering a C1 VEP (a bunch of RefPoints and Numbers); 1292 @Test(compLevel = C2) 1293 public int test58(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { 1294 return test58_helper(rp1, rp2, n1, rp3, rp4, n2); 1295 } 1296 1297 @DontInline 1298 @ForceCompile(compLevel = C1) 1299 private static int test58_helper(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { 1300 return rp1.x.n + rp1.y.n + 1301 rp2.x.n + rp2.y.n + 1302 n1.n + 1303 rp3.x.n + rp3.y.n + 1304 rp4.x.n + rp4.y.n + 1305 n2.n; 1306 } 1307 1308 @DontCompile 1309 public void test58_verifier(boolean warmup) { 1310 int count = warmup ? 1 : 5; 1311 for (int i=0; i<count; i++) { // need a loop to test inline cache 1312 RefPoint rp1 = new RefPoint(1, 2); 1313 RefPoint rp2 = refPointField1; 1314 RefPoint rp3 = new RefPoint(222, 777); 1315 RefPoint rp4 = refPointField2; 1316 Number n1 = new Number(5878); 1317 Number n2 = new Number(1234); 1318 int result; 1319 try (ForceGCMarker m = ForceGCMarker.mark(warmup)) { 1320 result = test58(rp1, rp2, n1, rp3, rp4, n2); 1321 } 1322 int n = test58_helper(rp1, rp2, n1, rp3, rp4, n2); 1323 Asserts.assertEQ(result, n); 1324 } 1325 } 1326 1327 // C2->C1 invokestatic, GC inside main body of C1-compiled method (caller's args should not be GC'ed). 1328 @Test(compLevel = C2) 1329 public int test59(RefPoint rp1, boolean doGC) { 1330 return test59_helper(rp1, 11, 222, 3333, 4444, doGC); 1331 } 1332 1333 @DontInline 1334 @ForceCompile(compLevel = C1) 1335 private static int test59_helper(RefPoint rp1, int a1, int a2, int a3, int a4, boolean doGC) { 1336 if (doGC) { 1337 System.gc(); 1338 } 1339 return rp1.x.n + rp1.y.n + a1 + a2 + a3 + a4; 1340 } 1341 1342 @DontCompile 1343 public void test59_verifier(boolean warmup) { 1344 int count = warmup ? 1 : 5; 1345 boolean doGC = !warmup; 1346 for (int i=0; i<count; i++) { // need a loop to test inline cache 1347 RefPoint rp1 = new RefPoint(1, 2); 1348 int result = test59(rp1, doGC); 1349 int n = test59_helper(rp1, 11, 222, 3333, 4444, doGC); 1350 Asserts.assertEQ(result, n); 1351 } 1352 } 1353 1354 // C2->C1 invokestatic, GC inside main body of C1-compiled method (caller's args should not be GC'ed). 1355 // same as test59, but the incoming (scalarized) oops are passed in both registers and stack. 1356 @Test(compLevel = C2) 1357 public int test60(RefPoint rp1, RefPoint rp2, boolean doGC) { 1358 return test60_helper(555, 6666, 77777, rp1, rp2, 11, 222, 3333, 4444, doGC); 1359 } 1360 1361 @DontInline 1362 @ForceCompile(compLevel = C1) 1363 private static int test60_helper(int x0, int x1, int x2, RefPoint rp1, RefPoint rp2,int a1, int a2, int a3, int a4, boolean doGC) { 1364 // On x64, C2 passes: reg0=x1, reg1=x1, reg2=x2, reg3=rp1.x, reg4=rp1.y, reg5=rp2.x stack0=rp2.y .... 1365 // C1 expects: reg0=x1, reg1=x1, reg2=x2, reg3=rp1, reg4=rp2, reg5=a1 stack0=a2 ... 1366 // When GC happens, make sure it does not treat reg5 and stack0 as oops! 1367 if (doGC) { 1368 System.gc(); 1369 } 1370 return x0 + x1 + x2 + rp1.x.n + rp1.y.n + rp2.x.n + rp2.y.n + a1 + a2 + a3 + a4; 1371 } 1372 1373 @DontCompile 1374 public void test60_verifier(boolean warmup) { 1375 int count = warmup ? 1 : 5; 1376 boolean doGC = !warmup; 1377 for (int i=0; i<count; i++) { // need a loop to test inline cache 1378 RefPoint rp1 = new RefPoint(1, 2); 1379 RefPoint rp2 = new RefPoint(33, 44); 1380 int result = test60(rp1, rp2, doGC); 1381 int n = test60_helper(555, 6666, 77777, rp1, rp2, 11, 222, 3333, 4444, doGC); 1382 Asserts.assertEQ(result, n); 1383 } 1384 } 1385 1386 // C2->C1 invokeinterface via VVEP(RO) 1387 @Test(compLevel = C2) 1388 public int test61(RefPoint_Access rpa, RefPoint rp2) { 1389 return rpa.func1(rp2); 1390 } 1391 1392 @DontCompile 1393 public void test61_verifier(boolean warmup) { 1394 int count = warmup ? 1 : 20; 1395 for (int i=0; i<count; i++) { // need a loop to test inline cache 1396 RefPoint_Access rpa = get_RefPoint_Access(); 1397 RefPoint rp2 = refPointField2; 1398 int result = test61(rpa, rp2); 1399 int n = rpa.func1(rp2); 1400 Asserts.assertEQ(result, n); 1401 } 1402 } 1403 1404 // C2->C1 invokeinterface via VVEP(RO) -- force GC for every allocation when entering a C1 VVEP(RO) (RefPoint) 1405 @Test(compLevel = C2) 1406 public int test62(RefPoint_Access rpa, RefPoint rp2) { 1407 return rpa.func1(rp2); 1408 } 1409 1410 @DontCompile 1411 public void test62_verifier(boolean warmup) { 1412 int count = warmup ? 1 : 20; 1413 for (int i=0; i<count; i++) { // need a loop to test inline cache 1414 RefPoint_Access rpa = get_RefPoint_Access(); 1415 RefPoint rp2 = new RefPoint(111, 2222); 1416 int result; 1417 try (ForceGCMarker m = ForceGCMarker.mark(warmup)) { 1418 result = test62(rpa, rp2); 1419 } 1420 int n = rpa.func1(rp2); 1421 Asserts.assertEQ(result, n); 1422 } 1423 } 1424 1425 /* disabled due to bug JDK-8224944 1426 1427 1428 // C2->C1 invokeinterface via VVEP(RO) -- force GC for every allocation when entering a C1 VVEP(RO) (a bunch of RefPoints and Numbers) 1429 @Test(compLevel = C2) 1430 public int test63(RefPoint_Access rpa, RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { 1431 return rpa.func2(rp1, rp2, n1, rp3, rp4, n2); 1432 } 1433 1434 @DontCompile 1435 public void test63_verifier(boolean warmup) { 1436 int count = warmup ? 1 : 20; 1437 for (int i=0; i<count; i++) { // need a loop to test inline cache 1438 RefPoint_Access rpa = get_RefPoint_Access(); 1439 RefPoint rp1 = new RefPoint(1, 2); 1440 RefPoint rp2 = refPointField1; 1441 RefPoint rp3 = new RefPoint(222, 777); 1442 RefPoint rp4 = refPointField2; 1443 Number n1 = new Number(5878); 1444 Number n2 = new Number(1234); 1445 int result; 1446 try (ForceGCMarker m = ForceGCMarker.mark(warmup)) { 1447 result = test63(rpa, rp1, rp2, n1, rp3, rp4, n2); 1448 } 1449 int n = rpa.func2(rp1, rp2, n1, rp3, rp4, n2); 1450 Asserts.assertEQ(result, n); 1451 } 1452 } 1453 /**/ 1454 1455 // C2->C1 invokevirtual via VVEP(RO) (opt_virtual_call) 1456 @Test(compLevel = C2) 1457 public int test76(RefPoint rp1, RefPoint rp2) { 1458 return rp1.final_func(rp2); 1459 } 1460 1461 @DontCompile 1462 public void test76_verifier(boolean warmup) { 1463 int count = warmup ? 1 : 5; 1464 for (int i=0; i<count; i++) { // need a loop to test inline cache 1465 RefPoint rp1 = refPointField1; 1466 RefPoint rp2 = refPointField2; 1467 int result = test76(rp1, rp2); 1468 int n = rp1.final_func(rp2); 1469 Asserts.assertEQ(result, n); 1470 } 1471 } 1472 1473 // C2->C1 invokevirtual, force GC for every allocation when entering a C1 VEP (RefPoint) 1474 // Same as test56, except we call the VVEP(RO) instead of VEP. 1475 @Test(compLevel = C2) 1476 public int test77(RefPoint rp1, RefPoint rp2) { 1477 return rp1.final_func(rp2); 1478 } 1479 1480 @DontCompile 1481 public void test77_verifier(boolean warmup) { 1482 int count = warmup ? 1 : 5; 1483 for (int i=0; i<count; i++) { // need a loop to test inline cache 1484 RefPoint rp1 = new RefPoint(1, 2); 1485 RefPoint rp2 = new RefPoint(22, 33); 1486 int result; 1487 try (ForceGCMarker m = ForceGCMarker.mark(warmup)) { 1488 result = test77(rp1, rp2); 1489 } 1490 int n = rp1.final_func(rp2); 1491 Asserts.assertEQ(result, n); 1492 } 1493 } 1494 1495 //------------------------------------------------------------------------------- 1496 // Tests for how C1 handles ValueTypeReturnedAsFields in both calls and returns 1497 //------------------------------------------------------------------------------- 1498 // C2->C1 invokestatic with ValueTypeReturnedAsFields (Point) 1499 @Test(compLevel = C2) 1500 public int test78(Point p) { 1501 Point np = test78_helper(p); 1502 return np.x + np.y; 1503 } 1504 1505 @DontInline 1506 @ForceCompile(compLevel = C1) 1507 private static Point test78_helper(Point p) { 1508 return p; 1509 } 1510 1511 @DontCompile 1512 public void test78_verifier(boolean warmup) { 1513 int result = test78(pointField1); 1514 int n = pointField1.x + pointField1.y; 1515 Asserts.assertEQ(result, n); 1516 } 1517 1518 // C2->C1 invokestatic with ValueTypeReturnedAsFields (RefPoint) 1519 @Test(compLevel = C2) 1520 public int test79(RefPoint p) { 1521 RefPoint np = test79_helper(p); 1522 return np.x.n + np.y.n; 1523 } 1524 1525 @DontInline 1526 @ForceCompile(compLevel = C1) 1527 private static RefPoint test79_helper(RefPoint p) { 1528 return p; 1529 } 1530 1531 @DontCompile 1532 public void test79_verifier(boolean warmup) { 1533 int result = test79(refPointField1); 1534 int n = refPointField1.x.n + refPointField1.y.n; 1535 Asserts.assertEQ(result, n); 1536 } 1537 1538 // C1->C2 invokestatic with ValueTypeReturnedAsFields (RefPoint) 1539 @Test(compLevel = C1) 1540 public int test80(RefPoint p) { 1541 RefPoint np = test80_helper(p); 1542 return np.x.n + np.y.n; 1543 } 1544 1545 @DontInline 1546 @ForceCompile(compLevel = C2) 1547 private static RefPoint test80_helper(RefPoint p) { 1548 return p; 1549 } 1550 1551 @DontCompile 1552 public void test80_verifier(boolean warmup) { 1553 int result = test80(refPointField1); 1554 int n = refPointField1.x.n + refPointField1.y.n; 1555 Asserts.assertEQ(result, n); 1556 } 1557 1558 // Interpreter->C1 invokestatic with ValueTypeReturnedAsFields (Point) 1559 @Test(compLevel = C1) 1560 public Point test81(Point p) { 1561 return p; 1562 } 1563 1564 @DontCompile 1565 public void test81_verifier(boolean warmup) { 1566 Point p = test81(pointField1); 1567 Asserts.assertEQ(p.x, pointField1.x); 1568 Asserts.assertEQ(p.y, pointField1.y); 1569 p = test81(pointField2); 1570 Asserts.assertEQ(p.x, pointField2.x); 1571 Asserts.assertEQ(p.y, pointField2.y); 1572 } 1573 1574 // C1->Interpreter invokestatic with ValueTypeReturnedAsFields (RefPoint) 1575 @Test(compLevel = C1) 1576 public int test82(RefPoint p) { 1577 RefPoint np = test82_helper(p); 1578 return np.x.n + np.y.n; 1579 } 1580 1581 @DontInline @DontCompile 1582 private static RefPoint test82_helper(RefPoint p) { 1583 return p; 1584 } 1585 1586 @DontCompile 1587 public void test82_verifier(boolean warmup) { 1588 int result = test82(refPointField1); 1589 int n = refPointField1.x.n + refPointField1.y.n; 1590 Asserts.assertEQ(result, n); 1591 } 1592 1593 //------------------------------------------------------------------------------- 1594 // Tests for ValueTypeReturnedAsFields vs the inline class TooBigToReturnAsFields 1595 //------------------------------------------------------------------------------- 1596 1597 // C2->C1 invokestatic with ValueTypeReturnedAsFields (TooBigToReturnAsFields) 1598 @Test(compLevel = C2) 1599 public int test83(TooBigToReturnAsFields p) { 1600 TooBigToReturnAsFields np = test83_helper(p); 1601 return p.a0 + p.a5; 1602 } 1603 1604 @DontInline 1605 @ForceCompile(compLevel = C1) 1606 private static TooBigToReturnAsFields test83_helper(TooBigToReturnAsFields p) { 1607 return p; 1608 } 1609 1610 @DontCompile 1611 public void test83_verifier(boolean warmup) { 1612 int result = test83(tooBig); 1613 int n = tooBig.a0 + tooBig.a5; 1614 Asserts.assertEQ(result, n); 1615 } 1616 1617 // C1->C2 invokestatic with ValueTypeReturnedAsFields (TooBigToReturnAsFields) 1618 @Test(compLevel = C1) 1619 public int test84(TooBigToReturnAsFields p) { 1620 TooBigToReturnAsFields np = test84_helper(p); 1621 return p.a0 + p.a5; 1622 } 1623 1624 @DontInline 1625 @ForceCompile(compLevel = C2) 1626 private static TooBigToReturnAsFields test84_helper(TooBigToReturnAsFields p) { 1627 return p; 1628 } 1629 1630 @DontCompile 1631 public void test84_verifier(boolean warmup) { 1632 int result = test84(tooBig); 1633 int n = tooBig.a0 + tooBig.a5; 1634 Asserts.assertEQ(result, n); 1635 } 1636 1637 // Interpreter->C1 invokestatic with ValueTypeReturnedAsFields (TooBigToReturnAsFields) 1638 @Test(compLevel = C1) 1639 public TooBigToReturnAsFields test85(TooBigToReturnAsFields p) { 1640 return p; 1641 } 1642 1643 @DontCompile 1644 public void test85_verifier(boolean warmup) { 1645 TooBigToReturnAsFields p = test85(tooBig); 1646 Asserts.assertEQ(p.a0, tooBig.a0); 1647 Asserts.assertEQ(p.a2, tooBig.a2); 1648 } 1649 1650 // C1->Interpreter invokestatic with ValueTypeReturnedAsFields (TooBigToReturnAsFields) 1651 @Test(compLevel = C1) 1652 public int test86(TooBigToReturnAsFields p) { 1653 TooBigToReturnAsFields np = test86_helper(p); 1654 return p.a0 + p.a5; 1655 } 1656 1657 @DontInline @DontCompile 1658 private static TooBigToReturnAsFields test86_helper(TooBigToReturnAsFields p) { 1659 return p; 1660 } 1661 1662 @DontCompile 1663 public void test86_verifier(boolean warmup) { 1664 int result = test86(tooBig); 1665 int n = tooBig.a0 + tooBig.a5; 1666 Asserts.assertEQ(result, n); 1667 } 1668 1669 //------------------------------------------------------------------------------- 1670 // Tests for how C1 handles ValueTypeReturnedAsFields in both calls and returns (RefPoint?) 1671 //------------------------------------------------------------------------------- 1672 1673 // C2->C1 invokestatic with ValueTypeReturnedAsFields (RefPoint?) 1674 @Test(compLevel = C2) 1675 public RefPoint? test87(RefPoint? p) { 1676 return test87_helper(p); 1677 } 1678 1679 @DontInline 1680 @ForceCompile(compLevel = C1) 1681 private static RefPoint? test87_helper(RefPoint? p) { 1682 return p; 1683 } 1684 1685 @DontCompile 1686 public void test87_verifier(boolean warmup) { 1687 Object result = test87(null); 1688 Asserts.assertEQ(result, null); 1689 } 1690 1691 // C2->C1 invokestatic with ValueTypeReturnedAsFields (RefPoint? with constant null) 1692 @Test(compLevel = C2) 1693 public RefPoint? test88() { 1694 return test88_helper(); 1695 } 1696 1697 @DontInline 1698 @ForceCompile(compLevel = C1) 1699 private static RefPoint? test88_helper() { 1700 return null; 1701 } 1702 1703 @DontCompile 1704 public void test88_verifier(boolean warmup) { 1705 Object result = test88(); 1706 Asserts.assertEQ(result, null); 1707 } 1708 1709 // C1->C2 invokestatic with ValueTypeReturnedAsFields (RefPoint?) 1710 @Test(compLevel = C1) 1711 public RefPoint? test89(RefPoint? p) { 1712 return test89_helper(p); 1713 } 1714 1715 @DontInline 1716 @ForceCompile(compLevel = C2) 1717 private static RefPoint? test89_helper(RefPoint? p) { 1718 return p; 1719 } 1720 1721 @DontCompile 1722 public void test89_verifier(boolean warmup) { 1723 Object result = test89(null); 1724 Asserts.assertEQ(result, null); 1725 } 1726 1727 //---------------------------------------------------------------------------------- 1728 // Tests for unverified entries: there are 6 cases: 1729 // C1 -> Unverified Value Entry compiled by C1 1730 // C1 -> Unverified Value Entry compiled by C2 1731 // C2 -> Unverified Entry compiled by C1 (target is NOT a value type) 1732 // C2 -> Unverified Entry compiled by C2 (target is NOT a value type) 1733 // C2 -> Unverified Entry compiled by C1 (target IS a value type, i.e., has VVEP_RO) 1734 // C2 -> Unverified Entry compiled by C2 (target IS a value type, i.e., has VVEP_RO) 1735 //---------------------------------------------------------------------------------- 1736 1737 // C1->C1 invokeinterface -- call Unverified Value Entry of MyImplPojo1.func2 (compiled by C1) 1738 @Test(compLevel = C1) 1739 public int test90(Intf intf, int a, int b) { 1740 return intf.func2(a, b, pointField); 1741 } 1742 1743 static Intf test90_intfs[] = { 1744 new MyImplPojo1(), 1745 new MyImplPojo2(), 1746 }; 1747 1748 @DontCompile 1749 public void test90_verifier(boolean warmup) { 1750 int count = warmup ? 1 : 20; 1751 for (int i=0; i<count; i++) { 1752 Intf intf = test90_intfs[i % test90_intfs.length]; 1753 int result = test90(intf, 123, 456) + i; 1754 Asserts.assertEQ(result, intf.func2(123, 456, pointField) + i); 1755 } 1756 } 1757 1758 // C1->C2 invokeinterface -- call Unverified Value Entry of MyImplPojo2.func2 (compiled by C2) 1759 @Test(compLevel = C1) 1760 public int test91(Intf intf, int a, int b) { 1761 return intf.func2(a, b, pointField); 1762 } 1763 1764 static Intf test91_intfs[] = { 1765 new MyImplPojo2(), 1766 new MyImplPojo1(), 1767 }; 1768 1769 @DontCompile 1770 public void test91_verifier(boolean warmup) { 1771 int count = warmup ? 1 : 20; 1772 for (int i=0; i<count; i++) { 1773 Intf intf = test91_intfs[i % test91_intfs.length]; 1774 int result = test91(intf, 123, 456) + i; 1775 Asserts.assertEQ(result, intf.func2(123, 456, pointField) + i); 1776 } 1777 } 1778 1779 // C2->C1 invokeinterface -- call Unverified Entry of MyImplPojo1.func2 (compiled by C1) 1780 @Test(compLevel = C2) 1781 public int test92(Intf intf, int a, int b) { 1782 return intf.func2(a, b, pointField); 1783 } 1784 1785 static Intf test92_intfs[] = { 1786 new MyImplPojo1(), 1787 new MyImplPojo2(), 1788 }; 1789 1790 @DontCompile 1791 public void test92_verifier(boolean warmup) { 1792 int count = warmup ? 1 : 20; 1793 for (int i=0; i<count; i++) { 1794 Intf intf = test92_intfs[i % test92_intfs.length]; 1795 int result = test92(intf, 123, 456) + i; 1796 Asserts.assertEQ(result, intf.func2(123, 456, pointField) + i); 1797 } 1798 } 1799 1800 // C2->C2 invokeinterface -- call Unverified Entry of MyImplPojo2.func2 (compiled by C2) 1801 @Test(compLevel = C2) 1802 public int test93(Intf intf, int a, int b) { 1803 return intf.func2(a, b, pointField); 1804 } 1805 1806 static Intf test93_intfs[] = { 1807 new MyImplPojo2(), 1808 new MyImplPojo1(), 1809 }; 1810 1811 @DontCompile 1812 public void test93_verifier(boolean warmup) { 1813 int count = warmup ? 1 : 20; 1814 for (int i=0; i<count; i++) { 1815 Intf intf = test93_intfs[i % test93_intfs.length]; 1816 int result = test93(intf, 123, 456) + i; 1817 Asserts.assertEQ(result, intf.func2(123, 456, pointField) + i); 1818 } 1819 } 1820 1821 // C2->C1 invokeinterface -- call Unverified Entry of MyImplVal1.func2 (compiled by C1 - has VVEP_RO) 1822 @Test(compLevel = C2) 1823 public int test94(Intf intf, int a, int b) { 1824 return intf.func2(a, b, pointField); 1825 } 1826 1827 static Intf test94_intfs[] = { 1828 new MyImplVal1(), 1829 new MyImplVal2(), 1830 }; 1831 1832 @DontCompile 1833 public void test94_verifier(boolean warmup) { 1834 int count = warmup ? 1 : 20; 1835 for (int i=0; i<count; i++) { 1836 Intf intf = test94_intfs[i % test94_intfs.length]; 1837 int result = test94(intf, 123, 456) + i; 1838 Asserts.assertEQ(result, intf.func2(123, 456, pointField) + i); 1839 } 1840 } 1841 1842 // C2->C2 invokeinterface -- call Unverified Entry of MyImplVal2.func2 (compiled by C2 - has VVEP_RO) 1843 @Test(compLevel = C2) 1844 public int test95(Intf intf, int a, int b) { 1845 return intf.func2(a, b, pointField); 1846 } 1847 1848 static Intf test95_intfs[] = { 1849 new MyImplVal2(), 1850 new MyImplVal1(), 1851 }; 1852 1853 @DontCompile 1854 public void test95_verifier(boolean warmup) { 1855 int count = warmup ? 1 : 20; 1856 for (int i=0; i<count; i++) { 1857 Intf intf = test95_intfs[i % test95_intfs.length]; 1858 int result = test95(intf, 123, 456) + i; 1859 Asserts.assertEQ(result, intf.func2(123, 456, pointField) + i); 1860 } 1861 } 1862 }