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  * @compile TestCallingConventionC1.java
  35  * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform
  36  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  37  *                               -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:+EnableValhalla
  38  *                               compiler.valhalla.valuetypes.ValueTypeTest
  39  *                               compiler.valhalla.valuetypes.TestCallingConventionC1
  40  */
  41 public class TestCallingConventionC1 extends ValueTypeTest {
  42     public static final int C1 = COMP_LEVEL_SIMPLE;
  43     public static final int C2 = COMP_LEVEL_FULL_OPTIMIZATION;
  44 
  45     @Override
  46     public int getNumScenarios() {
  47         return 2;
  48     }
  49 
  50     @Override
  51     public String[] getVMParameters(int scenario) {
  52         switch (scenario) {
  53 
  54         // Default: both C1 and C2 are enabled, tierd compilation enabled
  55         case 0: return new String[] {"-XX:+EnableValhallaC1", "-XX:CICompilerCount=2"
  56                                      , "-XX:-CheckCompressedOops", "-XX:CompileCommand=print,*::test60*"
  57                                    //, "-XX:CompileCommand=print,*::func_c1"
  58                                      };
  59         // Only C1. Tierd compilation disabled.
  60         case 1: return new String[] {"-XX:+EnableValhallaC1", "-XX:TieredStopAtLevel=1"
  61                                      , "-XX:-CheckCompressedOops", "-XX:CompileCommand=print,*::test76*"
  62                                      };
  63         }
  64         return null;
  65     }
  66 
  67     public static void main(String[] args) throws Throwable {
  68         System.gc(); // Resolve this call, to avoid C1 code patching in the test cases.
  69         TestCallingConventionC1 test = new TestCallingConventionC1();
  70         test.run(args,
  71                  Point.class,
  72                  Functor.class,
  73                  Functor1.class,
  74                  Functor2.class,
  75                  Functor3.class,
  76                  Functor4.class,
  77                  MyImplPojo1.class,
  78                  MyImplPojo2.class,
  79                  MyImplVal.class,
  80                  FixedPoints.class,
  81                  FloatPoint.class,
  82                  RefPoint.class);
  83     }
  84 
  85     static inline class Point {
  86         final int x;
  87         final int y;
  88         public Point(int x, int y) {
  89             this.x = x;
  90             this.y = y;
  91         }
  92 
  93         @DontCompile
  94         @DontInline
  95         public int func() {
  96             return x + y;
  97         }
  98 
  99         @ForceCompile(compLevel = C1)
 100         @DontInline
 101         public int func_c1(Point p) {
 102             return x + y + p.x + p.y;
 103         }
 104     }
 105 
 106     static interface FunctorInterface {
 107         public int apply_interp(Point p);
 108     }
 109 
 110     static class Functor implements FunctorInterface {
 111         @DontCompile
 112         @DontInline
 113         public int apply_interp(Point p) {
 114             return p.func() + 0;
 115         }
 116     }
 117     static class Functor1 extends Functor {
 118         @DontCompile
 119         @DontInline
 120         public int apply_interp(Point p) {
 121             return p.func() + 10000;
 122         }
 123     }
 124     static class Functor2 extends Functor {
 125         @DontCompile
 126         @DontInline
 127         public int apply_interp(Point p) {
 128             return p.func() + 20000;
 129         }
 130     }
 131     static class Functor3 extends Functor {
 132         @DontCompile
 133         @DontInline
 134         public int apply_interp(Point p) {
 135             return p.func() + 30000;
 136         }
 137     }
 138     static class Functor4 extends Functor {
 139         @DontCompile
 140         @DontInline
 141         public int apply_interp(Point p) {
 142             return p.func() + 40000;
 143         }
 144     }
 145 
 146     static Functor functors[] = {
 147         new Functor(),
 148         new Functor1(),
 149         new Functor2(),
 150         new Functor3(),
 151         new Functor4()
 152     };
 153     static int functorCounter = 0;
 154     static Functor getFunctor() {
 155         int n = (++ functorCounter) % functors.length;
 156         return functors[n];
 157     }
 158 
 159     static Point pointField  = new Point(123, 456);
 160     static Point pointField1 = new Point(1123, 1456);
 161     static Point pointField2 = new Point(2123, 2456);
 162 
 163     static interface Intf {
 164         public int func1(int a, int b);
 165         public int func2(int a, int b, Point p);
 166     }
 167 
 168     static class MyImplPojo1 implements Intf {
 169         int field = 1000;
 170         @DontInline @DontCompile
 171         public int func1(int a, int b)             { return field + a + b + 1; }
 172         @DontInline @DontCompile
 173         public int func2(int a, int b, Point p)     { return field + a + b + p.x + p.y + 1; }
 174     }
 175 
 176     static class MyImplPojo2 implements Intf {
 177         int field = 2000;
 178 
 179         @DontInline @ForceCompile(compLevel = C1)
 180         public int func1(int a, int b)             { return field + a + b + 20; }
 181         @DontInline @ForceCompile(compLevel = C1)
 182         public int func2(int a, int b, Point p)    { return field + a + b + p.x + p.y + 20; }
 183     }
 184 
 185     static inline class MyImplVal implements Intf {
 186         final int field;
 187         MyImplVal(int f) {
 188             field = f;
 189         }
 190         MyImplVal() {
 191             field = 3000;
 192         }
 193 
 194         @DontInline @ForceCompile(compLevel = C1)
 195         public int func1(int a, int b)             { return field + a + b + 300; }
 196 
 197         @DontInline @ForceCompile(compLevel = C1)
 198         public int func2(int a, int b, Point p)    { return field + a + b + p.x + p.y + 300; }
 199     }
 200 
 201     static Intf intfs[] = {
 202         new MyImplPojo1(),
 203         new MyImplPojo2(),
 204         new MyImplVal()
 205     };
 206     static int intfCounter = 0;
 207     static Intf getIntf() {
 208         int n = (++ intfCounter) % intfs.length;
 209         return intfs[n];
 210     }
 211 
 212     static inline class FixedPoints {
 213         final boolean Z0 = false;
 214         final boolean Z1 = true;
 215         final byte    B  = (byte)2;
 216         final char    C  = (char)34;
 217         final short   S  = (short)456;
 218         final int     I  = 5678;
 219         final long    J  = 0x1234567800abcdefL;
 220     }
 221     static FixedPoints fixedPointsField = new FixedPoints();
 222 
 223     static inline class FloatPoint {
 224         final float x;
 225         final float y;
 226         public FloatPoint(float x, float y) {
 227             this.x = x;
 228             this.y = y;
 229         }
 230     }
 231     static inline class DoublePoint {
 232         final double x;
 233         final double y;
 234         public DoublePoint(double x, double y) {
 235             this.x = x;
 236             this.y = y;
 237         }
 238     }
 239     static FloatPoint floatPointField = new FloatPoint(123.456f, 789.012f);
 240     static DoublePoint doublePointField = new DoublePoint(123.456, 789.012);
 241 
 242     static inline class EightFloats {
 243         float f1, f2, f3, f4, f5, f6, f7, f8;
 244         public EightFloats() {
 245             f1 = 1.1f;
 246             f2 = 2.2f;
 247             f3 = 3.3f;
 248             f4 = 4.4f;
 249             f5 = 5.5f;
 250             f6 = 6.6f;
 251             f7 = 7.7f;
 252             f8 = 8.8f;
 253         }
 254     }
 255     static EightFloats eightFloatsField = new EightFloats();
 256 
 257     static class Number {
 258         int n;
 259         Number(int v) {
 260             n = v;
 261         }
 262         void set(int v) {
 263             n = v;
 264         }
 265     }
 266 
 267     static interface RefPoint_Access {
 268         public int func1(RefPoint rp2);
 269         public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2);
 270     }
 271 
 272     static inline class RefPoint implements RefPoint_Access {
 273         final Number x;
 274         final Number y;
 275         public RefPoint(int x, int y) {
 276             this.x = new Number(x);
 277             this.y = new Number(y);
 278         }
 279 
 280         @DontInline
 281         @ForceCompile(compLevel = C1)
 282         public final int test76_helper(RefPoint rp2) { // opt_virtual_call
 283             return this.x.n + this.y.n + rp2.x.n + rp2.y.n;
 284         }
 285 
 286         @DontInline
 287         @ForceCompile(compLevel = C1)
 288         public int func1(RefPoint rp2) {
 289             return this.x.n + this.y.n + rp2.x.n + rp2.y.n;
 290         }
 291 
 292         @DontInline
 293         @ForceCompile(compLevel = C1)
 294         public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) {
 295             return x.n + y.n +
 296                    rp1.x.n + rp1.y.n +
 297                    rp2.x.n + rp2.y.n +
 298                    n1.n +
 299                    rp3.x.n + rp3.y.n +
 300                    rp4.x.n + rp4.y.n +
 301                    n2.n;
 302         }
 303     }
 304 
 305     static class RefPoint_Access_Impl1 implements RefPoint_Access {
 306         @DontInline @DontCompile
 307         public int func1(RefPoint rp2) {
 308             return rp2.x.n + rp2.y.n + 1111111;
 309         }
 310         @DontInline @DontCompile
 311         public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) {
 312             return 111111 +
 313                    rp1.x.n + rp1.y.n +
 314                    rp2.x.n + rp2.y.n +
 315                    n1.n +
 316                    rp3.x.n + rp3.y.n +
 317                    rp4.x.n + rp4.y.n +
 318                    n2.n;
 319         }
 320     }
 321     static class RefPoint_Access_Impl2 implements RefPoint_Access {
 322         @DontInline @DontCompile
 323         public int func1(RefPoint rp2) {
 324             return rp2.x.n + rp2.y.n + 2222222;
 325         }
 326         @DontInline @DontCompile
 327         public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) {
 328             return 222222 +
 329                    rp1.x.n + rp1.y.n +
 330                    rp2.x.n + rp2.y.n +
 331                    n1.n +
 332                    rp3.x.n + rp3.y.n +
 333                    rp4.x.n + rp4.y.n +
 334                    n2.n;
 335         }
 336     }
 337 
 338     static RefPoint_Access refPoint_Access_impls[] = {
 339         new RefPoint_Access_Impl1(),
 340         new RefPoint_Access_Impl2(),
 341         new RefPoint(0x12345, 0x6789a)
 342     };
 343 
 344     static int next_RefPoint_Access = 0;
 345     static RefPoint_Access get_RefPoint_Access() {
 346         int i = next_RefPoint_Access ++;
 347         return refPoint_Access_impls[i % refPoint_Access_impls.length];
 348     }
 349 
 350     static RefPoint refPointField1 = new RefPoint(12, 34);
 351     static RefPoint refPointField2 = new RefPoint(56789, 0x12345678);
 352 
 353     //**********************************************************************
 354     // PART 1 - C1 calls interpreted code
 355     //**********************************************************************
 356 
 357 
 358     //** C1 passes value to interpreter (static)
 359     @Test(compLevel = C1)
 360     public int test1() {
 361         return test1_helper(pointField);
 362     }
 363 
 364     @DontInline
 365     @DontCompile
 366     private static int test1_helper(Point p) {
 367         return p.func();
 368     }
 369 
 370     @DontCompile
 371     public void test1_verifier(boolean warmup) {
 372         int count = warmup ? 1 : 10;
 373         for (int i=0; i<count; i++) { // need a loop to test inline cache
 374             int result = test1() + i;
 375             Asserts.assertEQ(result, pointField.func() + i);
 376         }
 377     }
 378 
 379 
 380     //** C1 passes value to interpreter (monomorphic)
 381     @Test(compLevel = C1)
 382     public int test2() {
 383         return test2_helper(pointField);
 384     }
 385 
 386     @DontInline
 387     @DontCompile
 388     private int test2_helper(Point p) {
 389         return p.func();
 390     }
 391 
 392     @DontCompile
 393     public void test2_verifier(boolean warmup) {
 394         int count = warmup ? 1 : 10;
 395         for (int i=0; i<count; i++) { // need a loop to test inline cache
 396             int result = test2() + i;
 397             Asserts.assertEQ(result, pointField.func() + i);
 398         }
 399     }
 400 
 401     // C1 passes value to interpreter (megamorphic: vtable)
 402     @Test(compLevel = C1)
 403     public int test3(Functor functor) {
 404         return functor.apply_interp(pointField);
 405     }
 406 
 407     @DontCompile
 408     public void test3_verifier(boolean warmup) {
 409         int count = warmup ? 1 : 100;
 410         for (int i=0; i<count; i++) {  // need a loop to test inline cache and vtable indexing
 411             Functor functor = warmup ? functors[0] : getFunctor();
 412             int result = test3(functor) + i;
 413             Asserts.assertEQ(result, functor.apply_interp(pointField) + i);
 414         }
 415     }
 416 
 417     // Same as test3, but compiled with C2. Test the hastable of VtableStubs
 418     @Test(compLevel = C2)
 419     public int test3b(Functor functor) {
 420         return functor.apply_interp(pointField);
 421     }
 422 
 423     @DontCompile
 424     public void test3b_verifier(boolean warmup) {
 425         int count = warmup ? 1 : 100;
 426         for (int i=0; i<count; i++) {  // need a loop to test inline cache and vtable indexing
 427             Functor functor = warmup ? functors[0] : getFunctor();
 428             int result = test3b(functor) + i;
 429             Asserts.assertEQ(result, functor.apply_interp(pointField) + i);
 430         }
 431     }
 432 
 433     // C1 passes value to interpreter (megamorphic: itable)
 434     @Test(compLevel = C1)
 435     public int test4(FunctorInterface fi) {
 436         return fi.apply_interp(pointField);
 437     }
 438 
 439     @DontCompile
 440     public void test4_verifier(boolean warmup) {
 441         int count = warmup ? 1 : 100;
 442         for (int i=0; i<count; i++) {  // need a loop to test inline cache and itable indexing
 443             Functor functor = warmup ? functors[0] : getFunctor();
 444             int result = test4(functor) + i;
 445             Asserts.assertEQ(result, functor.apply_interp(pointField) + i);
 446         }
 447     }
 448 
 449     //**********************************************************************
 450     // PART 2 - interpreter calls C1
 451     //**********************************************************************
 452 
 453     // Interpreter passes value to C1 (static)
 454     @Test(compLevel = C1)
 455     static public int test20(Point p1, long l, Point p2) {
 456         return p1.x + p2.y;
 457     }
 458 
 459     @DontCompile
 460     public void test20_verifier(boolean warmup) {
 461         int result = test20(pointField1, 0, pointField2);
 462         int n = pointField1.x + pointField2.y;
 463         Asserts.assertEQ(result, n);
 464     }
 465 
 466     // Interpreter passes value to C1 (instance method in inline class)
 467     @Test
 468     public int test21(Point p) {
 469         return test21_helper(p);
 470     }
 471 
 472     @DontCompile
 473     @DontInline
 474     int test21_helper(Point p) {
 475         return p.func_c1(p);
 476     }
 477 
 478     @DontCompile
 479     public void test21_verifier(boolean warmup) {
 480         int result = test21(pointField);
 481         int n = 2 * (pointField.x + pointField.y);
 482         Asserts.assertEQ(result, n);
 483     }
 484 
 485 
 486     //**********************************************************************
 487     // PART 3 - C2 calls C1
 488     //**********************************************************************
 489 
 490     // C2->C1 invokestatic, single value arg
 491     @Test(compLevel = C2)
 492     public int test30() {
 493         return test30_helper(pointField);
 494     }
 495 
 496     @DontInline
 497     @ForceCompile(compLevel = C1)
 498     private static int test30_helper(Point p) {
 499         return p.x + p.y;
 500     }
 501 
 502     @DontCompile
 503     public void test30_verifier(boolean warmup) {
 504         int count = warmup ? 1 : 2;
 505         for (int i=0; i<count; i++) { // need a loop to test inline cache
 506             int result = test30();
 507             int n = pointField.x + pointField.y;
 508             Asserts.assertEQ(result, n);
 509         }
 510     }
 511 
 512     // C2->C1 invokestatic, two single value args
 513     @Test(compLevel = C2)
 514       public int test31() {
 515       return test31_helper(pointField1, pointField2);
 516     }
 517 
 518     @DontInline
 519     @ForceCompile(compLevel = C1)
 520       private static int test31_helper(Point p1, Point p2) {
 521         return p1.x + p2.y;
 522     }
 523 
 524     @DontCompile
 525     public void test31_verifier(boolean warmup) {
 526         int count = warmup ? 1 : 2;
 527         for (int i=0; i<count; i++) { // need a loop to test inline cache
 528             int result = test31();
 529             int n = pointField1.x + pointField2.y;
 530             Asserts.assertEQ(result, n);
 531         }
 532     }
 533 
 534     // C2->C1 invokestatic, two single value args and interleaving ints (all passed in registers on x64)
 535     @Test(compLevel = C2)
 536     public int test32() {
 537       return test32_helper(0, pointField1, 1, pointField2);
 538     }
 539 
 540     @DontInline
 541     @ForceCompile(compLevel = C1)
 542     private static int test32_helper(int x, Point p1, int y, Point p2) {
 543         return p1.x + p2.y + x + y;
 544     }
 545 
 546     @DontCompile
 547     public void test32_verifier(boolean warmup) {
 548         int count = warmup ? 1 : 2;
 549         for (int i=0; i<count; i++) { // need a loop to test inline cache
 550             int result = test32();
 551             int n = pointField1.x + pointField2.y + 0 + 1;
 552             Asserts.assertEQ(result, n);
 553         }
 554     }
 555 
 556     // C2->C1 invokeinterface -- no verified_ro_entry (no value args except for receiver)
 557     @Test(compLevel = C2)
 558     public int test33(Intf intf, int a, int b) {
 559         return intf.func1(a, b);
 560     }
 561 
 562     @DontCompile
 563     public void test33_verifier(boolean warmup) {
 564         int count = warmup ? 1 : 20;
 565         for (int i=0; i<count; i++) {
 566             Intf intf = warmup ? intfs[0] : getIntf();
 567             int result = test33(intf, 123, 456) + i;
 568             Asserts.assertEQ(result, intf.func1(123, 456) + i);
 569         }
 570     }
 571 
 572     // C2->C1 invokeinterface -- use verified_ro_entry (has value args other than receiver)
 573     @Test(compLevel = C2)
 574     public int test34(Intf intf, int a, int b) {
 575         return intf.func2(a, b, pointField);
 576     }
 577 
 578     @DontCompile
 579     public void test34_verifier(boolean warmup) {
 580         int count = warmup ? 1 : 20;
 581         for (int i=0; i<count; i++) {
 582             Intf intf = warmup ? intfs[0] : getIntf();
 583             int result = test34(intf, 123, 456) + i;
 584             Asserts.assertEQ(result, intf.func2(123, 456, pointField) + i);
 585         }
 586     }
 587 
 588     // C2->C1 invokestatic, Point.y is on stack (x64)
 589     @Test(compLevel = C2)
 590     public int test35() {
 591         return test35_helper(1, 2, 3, 4, 5, pointField);
 592     }
 593 
 594     @DontInline
 595     @ForceCompile(compLevel = C1)
 596     private static int test35_helper(int a1, int a2, int a3, int a4, int a5, Point p) {
 597         return a1 + a2 + a3 + a4 + a5 + p.x + p.y;
 598     }
 599 
 600     @DontCompile
 601     public void test35_verifier(boolean warmup) {
 602         int count = warmup ? 1 : 2;
 603         for (int i=0; i<count; i++) { // need a loop to test inline cache
 604             int result = test35();
 605             int n = 1 + 2 + 3  + 4 + 5 + pointField.x + pointField.y;
 606             Asserts.assertEQ(result, n);
 607         }
 608     }
 609 
 610     // C2->C1 invokestatic, shuffling arguments that are passed on stack
 611     @Test(compLevel = C2)
 612     public int test36() {
 613         return test36_helper(pointField, 1, 2, 3, 4, 5, 6, 7, 8);
 614     }
 615 
 616     @DontInline
 617     @ForceCompile(compLevel = C1)
 618     private static int test36_helper(Point p, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) {
 619         return a6 + a8;
 620     }
 621 
 622     @DontCompile
 623     public void test36_verifier(boolean warmup) {
 624         int count = warmup ? 1 : 2;
 625         for (int i=0; i<count; i++) { // need a loop to test inline cache
 626             int result = test36();
 627             int n = 6 + 8;
 628             Asserts.assertEQ(result, n);
 629         }
 630     }
 631 
 632     // C2->C1 invokestatic, shuffling long arguments
 633     @Test(compLevel = C2)
 634     public int test37() {
 635         return test37_helper(pointField, 1, 2, 3, 4, 5, 6, 7, 8);
 636     }
 637 
 638     @DontInline
 639     @ForceCompile(compLevel = C1)
 640     private static int test37_helper(Point p, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) {
 641         return (int)(a6 + a8);
 642     }
 643 
 644     @DontCompile
 645     public void test37_verifier(boolean warmup) {
 646         int count = warmup ? 1 : 2;
 647         for (int i=0; i<count; i++) { // need a loop to test inline cache
 648             int result = test37();
 649             int n = 6 + 8;
 650             Asserts.assertEQ(result, n);
 651         }
 652     }
 653 
 654     // C2->C1 invokestatic, shuffling boolean, byte, char, short, int, long arguments
 655     @Test(compLevel = C2)
 656     public int test38() {
 657         return test38_helper(pointField, true, (byte)1, (char)2, (short)3, 4, 5, (byte)6, (short)7, 8);
 658     }
 659 
 660     @DontInline
 661     @ForceCompile(compLevel = C1)
 662     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) {
 663         if (a0) {
 664             return (int)(a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8);
 665         } else {
 666             return -1;
 667         }
 668     }
 669 
 670     @DontCompile
 671     public void test38_verifier(boolean warmup) {
 672         int count = warmup ? 1 : 2;
 673         for (int i=0; i<count; i++) { // need a loop to test inline cache
 674             int result = test38();
 675             int n = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8;
 676             Asserts.assertEQ(result, n);
 677         }
 678     }
 679 
 680     // C2->C1 invokestatic, packing a value object with all types of fixed point primitive fields.
 681     @Test(compLevel = C2)
 682     public long test39() {
 683         return test39_helper(1, fixedPointsField, 2, fixedPointsField);
 684     }
 685 
 686     @DontInline
 687     @ForceCompile(compLevel = C1)
 688     private static long test39_helper(int a1, FixedPoints f1, int a2, FixedPoints f2) {
 689         if (f1.Z0 == false && f1.Z1 == true && f2.Z0 == false && f2.Z1 == true) {
 690             return f1.B + f2.C + f1.S + f2.I + f1.J;
 691         } else {
 692             return -1;
 693         }
 694     }
 695 
 696     @DontCompile
 697     public void test39_verifier(boolean warmup) {
 698         int count = warmup ? 1 : 2;
 699         for (int i=0; i<count; i++) { // need a loop to test inline cache
 700             long result = test39();
 701             long n = test39_helper(1, fixedPointsField, 2, fixedPointsField);
 702             Asserts.assertEQ(result, n);
 703         }
 704     }
 705 
 706     // C2->C1 invokestatic, shuffling floating point args
 707     @Test(compLevel = C2)
 708     public double test40() {
 709         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);
 710     }
 711 
 712     @DontInline
 713     @ForceCompile(compLevel = C1)
 714     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) {
 715         return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12 + fp.x + fp.y - dp.x - dp.y;
 716     }
 717 
 718     @DontCompile
 719     public void test40_verifier(boolean warmup) {
 720         int count = warmup ? 1 : 2;
 721         for (int i=0; i<count; i++) { // need a loop to test inline cache
 722             double result = test40();
 723             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);
 724             Asserts.assertEQ(result, n);
 725         }
 726     }
 727 
 728     // C2->C1 invokestatic, mixing floats and ints
 729     @Test(compLevel = C2)
 730     public double test41() {
 731         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);
 732     }
 733 
 734     @DontInline
 735     @ForceCompile(compLevel = C1)
 736     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) {
 737       return a1 + a2  + fp.x + fp.y - dp.x - dp.y + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12;
 738     }
 739 
 740     @DontCompile
 741     public void test41_verifier(boolean warmup) {
 742         int count = warmup ? 1 : 2;
 743         for (int i=0; i<count; i++) { // need a loop to test inline cache
 744             double result = test41();
 745             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);
 746             Asserts.assertEQ(result, n);
 747         }
 748     }
 749 
 750     // C2->C1 invokestatic, circular dependency (between rdi and first stack slot on x64)
 751     @Test(compLevel = C2)
 752     public float test42() {
 753         return test42_helper(eightFloatsField, pointField, 3, 4, 5, floatPointField, 7);
 754     }
 755 
 756     @DontInline
 757     @ForceCompile(compLevel = C1)
 758     private static float test42_helper(EightFloats ep1, // (xmm0 ... xmm7) -> rsi
 759                                        Point p2,        // (rsi, rdx) -> rdx
 760                                        int i3,          // rcx -> rcx
 761                                        int i4,          // r8 -> r8
 762                                        int i5,          // r9 -> r9
 763                                        FloatPoint fp6,  // (stk[0], stk[1]) -> rdi   ** circ depend
 764                                        int i7)          // rdi -> stk[0]             ** circ depend
 765     {
 766         return ep1.f1 + ep1.f2 + ep1.f3 + ep1.f4 + ep1.f5 + ep1.f6 + ep1.f7 + ep1.f8 +
 767             p2.x + p2.y + i3 + i4 + i5 + fp6.x + fp6.y + i7;
 768     }
 769 
 770     @DontCompile
 771     public void test42_verifier(boolean warmup) {
 772         int count = warmup ? 1 : 2;
 773         for (int i=0; i<count; i++) { // need a loop to test inline cache
 774             float result = test42();
 775             float n = test42_helper(eightFloatsField, pointField, 3, 4, 5, floatPointField, 7);
 776             Asserts.assertEQ(result, n);
 777         }
 778     }
 779 
 780     // C2->C1 invokestatic, packing causes stack growth (1 extra stack word)
 781     @Test(compLevel = C2)
 782     public float test43() {
 783         return test43_helper(floatPointField, 1, 2, 3, 4, 5, 6);
 784     }
 785 
 786     @DontInline
 787     @ForceCompile(compLevel = C1)
 788     private static float test43_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5, int a6) {
 789         // On x64:
 790         //    Scalarized entry -- all parameters are passed in registers
 791         //    Non-scalarized entry -- a6 is passed on stack[0]
 792         return fp.x + fp.y + a1 + a2 + a3 + a4 + a5 + a6;
 793     }
 794 
 795     @DontCompile
 796     public void test43_verifier(boolean warmup) {
 797         int count = warmup ? 1 : 2;
 798         for (int i=0; i<count; i++) { // need a loop to test inline cache
 799             float result = test43();
 800             float n = test43_helper(floatPointField, 1, 2, 3, 4, 5, 6);
 801             Asserts.assertEQ(result, n);
 802         }
 803     }
 804 
 805     // C2->C1 invokestatic, packing causes stack growth (2 extra stack words)
 806     @Test(compLevel = C2)
 807     public float test44() {
 808       return test44_helper(floatPointField, floatPointField, 1, 2, 3, 4, 5, 6);
 809     }
 810 
 811     @DontInline
 812     @ForceCompile(compLevel = C1)
 813       private static float test44_helper(FloatPoint fp1, FloatPoint fp2, int a1, int a2, int a3, int a4, int a5, int a6) {
 814         // On x64:
 815         //    Scalarized entry -- all parameters are passed in registers
 816         //    Non-scalarized entry -- a5 is passed on stack[0]
 817         //    Non-scalarized entry -- a6 is passed on stack[1]
 818         return fp1.x + fp1.y +
 819                fp2.x + fp2.y +
 820                a1 + a2 + a3 + a4 + a5 + a6;
 821     }
 822 
 823     @DontCompile
 824     public void test44_verifier(boolean warmup) {
 825         int count = warmup ? 1 : 2;
 826         for (int i=0; i<count; i++) { // need a loop to test inline cache
 827             float result = test44();
 828             float n = test44_helper(floatPointField, floatPointField, 1, 2, 3, 4, 5, 6);
 829             Asserts.assertEQ(result, n);
 830         }
 831     }
 832 
 833     // C2->C1 invokestatic, packing causes stack growth (5 extra stack words)
 834     @Test(compLevel = C2)
 835     public float test45() {
 836       return test45_helper(floatPointField, floatPointField, floatPointField, floatPointField, floatPointField, 1, 2, 3, 4, 5, 6, 7);
 837     }
 838 
 839     @DontInline
 840     @ForceCompile(compLevel = C1)
 841     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) {
 842         return fp1.x + fp1.y +
 843                fp2.x + fp2.y +
 844                fp3.x + fp3.y +
 845                fp4.x + fp4.y +
 846                fp5.x + fp5.y +
 847                a1 + a2 + a3 + a4 + a5 + a6 + a7;
 848     }
 849 
 850     @DontCompile
 851     public void test45_verifier(boolean warmup) {
 852         int count = warmup ? 1 : 2;
 853         for (int i=0; i<count; i++) { // need a loop to test inline cache
 854             float result = test45();
 855             float n = test45_helper(floatPointField, floatPointField, floatPointField, floatPointField, floatPointField, 1, 2, 3, 4, 5, 6, 7);
 856             Asserts.assertEQ(result, n);
 857         }
 858     }
 859 
 860     // C2->C1 invokestatic, packing causes stack growth (1 extra stack word -- mixing Point and FloatPoint)
 861     @Test(compLevel = C2)
 862     public float test46() {
 863       return test46_helper(floatPointField, floatPointField, pointField, floatPointField, floatPointField, pointField, floatPointField, 1, 2, 3, 4, 5, 6, 7);
 864     }
 865 
 866     @DontInline
 867     @ForceCompile(compLevel = C1)
 868       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) {
 869         return p1.x + p1.y +
 870                p2.x + p2.y +
 871                fp1.x + fp1.y +
 872                fp2.x + fp2.y +
 873                fp3.x + fp3.y +
 874                fp4.x + fp4.y +
 875                fp5.x + fp5.y +
 876                a1 + a2 + a3 + a4 + a5 + a6 + a7;
 877     }
 878 
 879     @DontCompile
 880     public void test46_verifier(boolean warmup) {
 881         int count = warmup ? 1 : 2;
 882         for (int i=0; i<count; i++) { // need a loop to test inline cache
 883             float result = test46();
 884             float n = test46_helper(floatPointField, floatPointField, pointField, floatPointField, floatPointField, pointField, floatPointField, 1, 2, 3, 4, 5, 6, 7);
 885             Asserts.assertEQ(result, n);
 886         }
 887     }
 888 
 889     static class MyRuntimeException extends RuntimeException {
 890         MyRuntimeException(String s) {
 891             super(s);
 892         }
 893     }
 894 
 895     static void checkStackTrace(Throwable t, String... methodNames) {
 896         StackTraceElement[] trace = t.getStackTrace();
 897         for (int i=0; i<methodNames.length; i++) {
 898             if (!methodNames[i].equals(trace[i].getMethodName())) {
 899                 String error = "Unexpected stack trace: level " + i + " should be " + methodNames[i];
 900                 System.out.println(error);
 901                 t.printStackTrace(System.out);
 902                 throw new RuntimeException(error, t);
 903             }
 904         }
 905     }
 906     //*
 907 
 908     // C2->C1 invokestatic, make sure stack walking works (with static variable)
 909     @Test(compLevel = C2)
 910     public void test47(int n) {
 911         try {
 912             test47_helper(floatPointField, 1, 2, 3, 4, 5);
 913             test47_value = 666;
 914         } catch (MyRuntimeException e) {
 915             // expected;
 916         }
 917         test47_value = n;
 918     }
 919 
 920     @DontInline
 921     @ForceCompile(compLevel = C1)
 922     private static float test47_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5) {
 923         test47_thrower();
 924         return 0.0f;
 925     }
 926 
 927     @DontInline @DontCompile
 928     private static void test47_thrower() {
 929         MyRuntimeException e = new MyRuntimeException("This exception should have been caught!");
 930         checkStackTrace(e, "test47_thrower", "test47_helper", "test47", "test47_verifier");
 931         throw e;
 932     }
 933 
 934     static int test47_value = 999;
 935 
 936     @DontCompile
 937     public void test47_verifier(boolean warmup) {
 938         int count = warmup ? 1 : 5;
 939         for (int i=0; i<count; i++) { // need a loop to test inline cache
 940             test47_value = 777 + i;
 941             test47(i);
 942             Asserts.assertEQ(test47_value, i);
 943         }
 944     }
 945 
 946     // C2->C1 invokestatic, make sure stack walking works (with returned value)
 947     @Test(compLevel = C2)
 948     public int test48(int n) {
 949         try {
 950             test48_helper(floatPointField, 1, 2, 3, 4, 5);
 951             return 666;
 952         } catch (MyRuntimeException e) {
 953             // expected;
 954         }
 955         return n;
 956     }
 957 
 958     @DontInline
 959     @ForceCompile(compLevel = C1)
 960     private static float test48_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5) {
 961         test48_thrower();
 962         return 0.0f;
 963     }
 964 
 965     @DontInline @DontCompile
 966     private static void test48_thrower() {
 967         MyRuntimeException e = new MyRuntimeException("This exception should have been caught!");
 968         checkStackTrace(e, "test48_thrower", "test48_helper", "test48", "test48_verifier");
 969         throw e;
 970     }
 971 
 972     @DontCompile
 973     public void test48_verifier(boolean warmup) {
 974         int count = warmup ? 1 : 5;
 975         for (int i=0; i<count; i++) { // need a loop to test inline cache
 976             int n = test48(i);
 977             Asserts.assertEQ(n, i);
 978         }
 979     }
 980 
 981     // C2->interpreter invokestatic, make sure stack walking works (same as test 48, but with stack extension/repair)
 982     // (this is the baseline for test50 --
 983     // the only difference is: test49_helper is interpreted but test50_helper is compiled by C1).
 984     @Test(compLevel = C2)
 985     public int test49(int n) {
 986         try {
 987             test49_helper(floatPointField, 1, 2, 3, 4, 5, 6);
 988             return 666;
 989         } catch (MyRuntimeException e) {
 990             // expected;
 991         }
 992         return n;
 993     }
 994 
 995     @DontInline @DontCompile
 996     private static float test49_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5, int a6) {
 997         test49_thrower();
 998         return 0.0f;
 999     }
1000 
1001     @DontInline @DontCompile
1002     private static void test49_thrower() {
1003         MyRuntimeException e = new MyRuntimeException("This exception should have been caught!");
1004         checkStackTrace(e, "test49_thrower", "test49_helper", "test49", "test49_verifier");
1005         throw e;
1006     }
1007 
1008     @DontCompile
1009     public void test49_verifier(boolean warmup) {
1010         int count = warmup ? 1 : 5;
1011         for (int i=0; i<count; i++) { // need a loop to test inline cache
1012             int n = test49(i);
1013             Asserts.assertEQ(n, i);
1014         }
1015     }
1016 
1017     // C2->C1 invokestatic, make sure stack walking works (same as test 48, but with stack extension/repair)
1018     @Test(compLevel = C2)
1019     public int test50(int n) {
1020         try {
1021             test50_helper(floatPointField, 1, 2, 3, 4, 5, 6);
1022             return 666;
1023         } catch (MyRuntimeException e) {
1024             // expected;
1025         }
1026         return n;
1027     }
1028 
1029     @DontInline
1030     @ForceCompile(compLevel = C1)
1031     private static float test50_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5, int a6) {
1032         test50_thrower();
1033         return 0.0f;
1034     }
1035 
1036     @DontInline @DontCompile
1037     private static void test50_thrower() {
1038         MyRuntimeException e = new MyRuntimeException("This exception should have been caught!");
1039         checkStackTrace(e, "test50_thrower", "test50_helper", "test50", "test50_verifier");
1040         throw e;
1041     }
1042 
1043     @DontCompile
1044     public void test50_verifier(boolean warmup) {
1045         int count = warmup ? 1 : 5;
1046         for (int i=0; i<count; i++) { // need a loop to test inline cache
1047             int n = test50(i);
1048             Asserts.assertEQ(n, i);
1049         }
1050     }
1051 
1052 
1053     // C2->C1 invokestatic, inline class with ref fields (RefPoint)
1054     @Test(compLevel = C2)
1055     public int test51() {
1056         return test51_helper(refPointField1);
1057     }
1058 
1059     @DontInline
1060     @ForceCompile(compLevel = C1)
1061     private static int test51_helper(RefPoint rp1) {
1062         return rp1.x.n + rp1.y.n;
1063     }
1064 
1065     @DontCompile
1066     public void test51_verifier(boolean warmup) {
1067         int count = warmup ? 1 : 5;
1068         for (int i=0; i<count; i++) { // need a loop to test inline cache
1069             int result = test51();
1070             int n = test51_helper(refPointField1);
1071             Asserts.assertEQ(result, n);
1072         }
1073     }
1074 
1075     // C2->C1 invokestatic, inline class with ref fields (Point, RefPoint)
1076     @Test(compLevel = C2)
1077     public int test52() {
1078         return test52_helper(pointField, refPointField1);
1079     }
1080 
1081     @DontInline
1082     @ForceCompile(compLevel = C1)
1083     private static int test52_helper(Point p1, RefPoint rp1) {
1084         return p1.x + p1.y + rp1.x.n + rp1.y.n;
1085     }
1086 
1087     @DontCompile
1088     public void test52_verifier(boolean warmup) {
1089         int count = warmup ? 1 : 5;
1090         for (int i=0; i<count; i++) { // need a loop to test inline cache
1091             int result = test52();
1092             int n = test52_helper(pointField, refPointField1);
1093             Asserts.assertEQ(result, n);
1094         }
1095     }
1096 
1097     // C2->C1 invokestatic, inline class with ref fields (RefPoint, RefPoint, RefPoint, RefPoint)
1098     @Test(compLevel = C2)
1099     public int test53() {
1100         return test53_helper(refPointField1, refPointField2, refPointField1, refPointField2);
1101     }
1102 
1103     @DontInline
1104     @ForceCompile(compLevel = C1)
1105     private static int test53_helper(RefPoint rp1, RefPoint rp2, RefPoint rp3, RefPoint rp4) {
1106         return rp1.x.n + rp1.y.n +
1107                rp2.x.n + rp2.y.n +
1108                rp3.x.n + rp3.y.n +
1109                rp4.x.n + rp4.y.n;
1110     }
1111 
1112     @DontCompile
1113     public void test53_verifier(boolean warmup) {
1114         int count = warmup ? 1 : 5;
1115         for (int i=0; i<count; i++) { // need a loop to test inline cache
1116             int result = test53();
1117             int n = test53_helper(refPointField1, refPointField2, refPointField1, refPointField2);
1118             Asserts.assertEQ(result, n);
1119         }
1120     }
1121 
1122     // C2->C1 invokestatic, inline class with ref fields (RefPoint, RefPoint, float, int, RefPoint, RefPoint)
1123     @Test(compLevel = C2)
1124     public int test54() {
1125         return test54_helper(refPointField1, refPointField2, 1.0f, 2, refPointField1, refPointField2);
1126     }
1127 
1128     @DontInline
1129     @ForceCompile(compLevel = C1)
1130     private static int test54_helper(RefPoint rp1, RefPoint rp2, float f, int i, RefPoint rp3, RefPoint rp4) {
1131         return rp1.x.n + rp1.y.n +
1132                rp2.x.n + rp2.y.n +
1133                (int)(f) + i +
1134                rp3.x.n + rp3.y.n +
1135                rp4.x.n + rp4.y.n;
1136     }
1137 
1138     @DontCompile
1139     public void test54_verifier(boolean warmup) {
1140         int count = warmup ? 1 : 5;
1141         for (int i=0; i<count; i++) { // need a loop to test inline cache
1142             int result = test54();
1143             int n = test54_helper(refPointField1, refPointField2, 1.0f, 2, refPointField1, refPointField2);
1144             Asserts.assertEQ(result, n);
1145         }
1146     }
1147 
1148     static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
1149     static final String ScavengeALot = "ScavengeALot";
1150 
1151 
1152     /**
1153      * Each allocation with a "try" block like this will cause a GC
1154      *
1155      *       try (ForceGCMarker m = ForceGCMarker.mark(warmup)) {
1156      *           result = test55(p1);
1157      *       }
1158      */
1159     static class ForceGCMarker implements java.io.Closeable {
1160         static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
1161 
1162         ForceGCMarker() {
1163             WHITE_BOX.setBooleanVMFlag(ScavengeALot, true);
1164         }
1165         public void close() {
1166             WHITE_BOX.setBooleanVMFlag(ScavengeALot, false);
1167         }
1168 
1169         static ForceGCMarker mark(boolean warmup) {
1170             return warmup ? null : new ForceGCMarker();
1171         }
1172     }
1173 
1174     // C2->C1 invokestatic, force GC for every allocation when entering a C1 VEP (Point)
1175     @Test(compLevel = C2)
1176     public int test55(Point p1) {
1177         return test55_helper(p1);
1178     }
1179 
1180     @DontInline
1181     @ForceCompile(compLevel = C1)
1182     private static int test55_helper(Point p1) {
1183         return p1.x + p1.y;
1184     }
1185 
1186     @DontCompile
1187     public void test55_verifier(boolean warmup) {
1188         int count = warmup ? 1 : 5;
1189         for (int i=0; i<count; i++) { // need a loop to test inline cache
1190             Point p1 = new Point(1, 2);
1191             int result;
1192             try (ForceGCMarker m = ForceGCMarker.mark(warmup)) {
1193                 result = test55(p1);
1194             }
1195             int n = test55_helper(p1);
1196             Asserts.assertEQ(result, n);
1197         }
1198     }
1199 
1200     // C2->C1 invokestatic, force GC for every allocation when entering a C1 VEP (RefPoint)
1201     @Test(compLevel = C2)
1202     public int test56(RefPoint rp1) {
1203         return test56_helper(rp1);
1204     }
1205 
1206     @DontInline
1207     @ForceCompile(compLevel = C1)
1208     private static int test56_helper(RefPoint rp1) {
1209         return rp1.x.n + rp1.y.n;
1210     }
1211 
1212     @DontCompile
1213     public void test56_verifier(boolean warmup) {
1214         int count = warmup ? 1 : 5;
1215         for (int i=0; i<count; i++) { // need a loop to test inline cache
1216             RefPoint rp1 = new RefPoint(1, 2);
1217             int result;
1218             try (ForceGCMarker m = ForceGCMarker.mark(warmup)) {
1219                 result = test56(rp1);
1220             }
1221             int n = test56_helper(rp1);
1222             Asserts.assertEQ(result, n);
1223         }
1224     }
1225 
1226     // C2->Interpreter (same as test56, but test c2i entry instead of C1)
1227     @Test(compLevel = C2)
1228     public int test57(RefPoint rp1) {
1229         return test57_helper(rp1);
1230     }
1231 
1232     @DontInline @DontCompile
1233     private static int test57_helper(RefPoint rp1) {
1234         return rp1.x.n + rp1.y.n;
1235     }
1236 
1237     @DontCompile
1238     public void test57_verifier(boolean warmup) {
1239         int count = warmup ? 1 : 5;
1240         for (int i=0; i<count; i++) { // need a loop to test inline cache
1241             RefPoint rp1 = new RefPoint(1, 2);
1242             int result;
1243             try (ForceGCMarker m = ForceGCMarker.mark(warmup)) {
1244                 result = test57(rp1);
1245             }
1246             int n = test57_helper(rp1);
1247             Asserts.assertEQ(result, n);
1248         }
1249     }
1250 
1251     // C2->C1 invokestatic, force GC for every allocation when entering a C1 VEP (a bunch of RefPoints and Numbers);
1252     @Test(compLevel = C2)
1253     public int test58(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) {
1254         return test58_helper(rp1, rp2, n1, rp3, rp4, n2);
1255     }
1256 
1257     @DontInline
1258     @ForceCompile(compLevel = C1)
1259     private static int test58_helper(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) {
1260         return rp1.x.n + rp1.y.n +
1261                rp2.x.n + rp2.y.n +
1262                n1.n +
1263                rp3.x.n + rp3.y.n +
1264                rp4.x.n + rp4.y.n +
1265                n2.n;
1266     }
1267 
1268     @DontCompile
1269     public void test58_verifier(boolean warmup) {
1270         int count = warmup ? 1 : 5;
1271         for (int i=0; i<count; i++) { // need a loop to test inline cache
1272             RefPoint rp1 = new RefPoint(1, 2);
1273             RefPoint rp2 = refPointField1;
1274             RefPoint rp3 = new RefPoint(222, 777);
1275             RefPoint rp4 = refPointField2;
1276             Number n1 = new Number(5878);
1277             Number n2 = new Number(1234);
1278             int result;
1279             try (ForceGCMarker m = ForceGCMarker.mark(warmup)) {
1280                 result = test58(rp1, rp2, n1, rp3, rp4, n2);
1281             }
1282             int n = test58_helper(rp1, rp2, n1, rp3, rp4, n2);
1283             Asserts.assertEQ(result, n);
1284         }
1285     }
1286 
1287     // C2->C1 invokestatic, GC inside main body of C1-compiled method (caller's args should not be GC'ed).
1288     @Test(compLevel = C2)
1289     public int test59(RefPoint rp1, boolean doGC) {
1290       return test59_helper(rp1, 11, 222, 3333, 4444, doGC);
1291     }
1292 
1293     @DontInline
1294     @ForceCompile(compLevel = C1)
1295     private static int test59_helper(RefPoint rp1, int a1, int a2, int a3, int a4, boolean doGC) {
1296         if (doGC) {
1297             System.gc();
1298         }
1299         return rp1.x.n + rp1.y.n + a1 + a2 + a3 + a4;
1300     }
1301 
1302     @DontCompile
1303     public void test59_verifier(boolean warmup) {
1304         int count = warmup ? 1 : 5;
1305         boolean doGC = !warmup;
1306         for (int i=0; i<count; i++) { // need a loop to test inline cache
1307             RefPoint rp1 = new RefPoint(1, 2);
1308             int result = test59(rp1, doGC);
1309             int n = test59_helper(rp1, 11, 222, 3333, 4444, doGC);
1310             Asserts.assertEQ(result, n);
1311         }
1312     }
1313 
1314     // C2->C1 invokestatic, GC inside main body of C1-compiled method (caller's args should not be GC'ed).
1315     // same as test59, but the incoming (scalarized) oops are passed in both registers and stack.
1316     @Test(compLevel = C2)
1317     public int test60(RefPoint rp1, RefPoint rp2, boolean doGC) {
1318         return test60_helper(555, 6666, 77777, rp1, rp2, 11, 222, 3333, 4444, doGC);
1319     }
1320 
1321     @DontInline
1322     @ForceCompile(compLevel = C1)
1323     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) {
1324         // On x64, C2 passes:   reg0=x1, reg1=x1, reg2=x2, reg3=rp1.x, reg4=rp1.y, reg5=rp2.x stack0=rp2.y ....
1325         //         C1 expects:  reg0=x1, reg1=x1, reg2=x2, reg3=rp1,   reg4=rp2,   reg5=a1    stack0=a2 ...
1326         // When GC happens, make sure it does not treat reg5 and stack0 as oops!
1327         if (doGC) {
1328             System.gc();
1329         }
1330         return x0 + x1 + x2 + rp1.x.n + rp1.y.n + rp2.x.n + rp2.y.n + a1 + a2 + a3 + a4;
1331     }
1332 
1333     @DontCompile
1334     public void test60_verifier(boolean warmup) {
1335         int count = warmup ? 1 : 5;
1336         boolean doGC = !warmup;
1337         for (int i=0; i<count; i++) { // need a loop to test inline cache
1338             RefPoint rp1 = new RefPoint(1, 2);
1339             RefPoint rp2 = new RefPoint(33, 44);
1340             int result = test60(rp1, rp2, doGC);
1341             int n = test60_helper(555, 6666, 77777, rp1, rp2, 11, 222, 3333, 4444, doGC);
1342             Asserts.assertEQ(result, n);
1343         }
1344     }
1345 
1346     // C2->C1 invokeinterface via VVEP(RO)
1347     @Test(compLevel = C2)
1348     public int test61(RefPoint_Access rpa, RefPoint rp2) {
1349         return rpa.func1(rp2);
1350     }
1351 
1352     @DontCompile
1353     public void test61_verifier(boolean warmup) {
1354         int count = warmup ? 1 : 20;
1355         for (int i=0; i<count; i++) { // need a loop to test inline cache
1356             RefPoint_Access rpa = get_RefPoint_Access();
1357             RefPoint rp2 = refPointField2;
1358             int result = test61(rpa, rp2);
1359             int n = rpa.func1(rp2);
1360             Asserts.assertEQ(result, n);
1361         }
1362     }
1363 
1364     // C2->C1 invokeinterface via VVEP(RO) -- force GC for every allocation when entering a C1 VVEP(RO) (RefPoint)
1365     @Test(compLevel = C2)
1366     public int test62(RefPoint_Access rpa, RefPoint rp2) {
1367         return rpa.func1(rp2);
1368     }
1369 
1370     @DontCompile
1371     public void test62_verifier(boolean warmup) {
1372         int count = warmup ? 1 : 20;
1373         for (int i=0; i<count; i++) { // need a loop to test inline cache
1374             RefPoint_Access rpa = get_RefPoint_Access();
1375             RefPoint rp2 = new RefPoint(111, 2222);
1376             int result;
1377             try (ForceGCMarker m = ForceGCMarker.mark(warmup)) {
1378                 result = test62(rpa, rp2);
1379             }
1380             int n = rpa.func1(rp2);
1381             Asserts.assertEQ(result, n);
1382         }
1383     }
1384 
1385 
1386     /*
1387 
1388     // FIXME: C1 fails with "Could not resolve circular dependency when shuffling value type arguments" when compiling test63()
1389 
1390     // C2->C1 invokeinterface via VVEP(RO) -- force GC for every allocation when entering a C1 VVEP(RO) (a bunch of RefPoints and Numbers)
1391     @Test(compLevel = C2)
1392     public int test63(RefPoint_Access rpa, RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) {
1393         return rpa.func2(rp1, rp2, n1, rp3, rp4, n2);
1394     }
1395 
1396     @DontCompile
1397     public void test63_verifier(boolean warmup) {
1398         int count = warmup ? 1 : 20;
1399         for (int i=0; i<count; i++) { // need a loop to test inline cache
1400             RefPoint_Access rpa = get_RefPoint_Access();
1401             RefPoint rp1 = new RefPoint(1, 2);
1402             RefPoint rp2 = refPointField1;
1403             RefPoint rp3 = new RefPoint(222, 777);
1404             RefPoint rp4 = refPointField2;
1405             Number n1 = new Number(5878);
1406             Number n2 = new Number(1234);
1407             int result;
1408             try (ForceGCMarker m = ForceGCMarker.mark(warmup)) {
1409                 result = test63(rpa, rp1, rp2, n1, rp3, rp4, n2);
1410             }
1411             int n = rpa.func2(rp1, rp2, n1, rp3, rp4, n2);
1412             Asserts.assertEQ(result, n);
1413         }
1414     }
1415     /**/
1416 
1417     /*
1418 
1419 
1420     // FIXME: when C1 makes opt_virtual_call to RefPoint::test76_helper, method resolution fails with an assert
1421 
1422     // C2->C1 invokevirtual via VVEP(RO) (opt_virtual_call)
1423     @Test(compLevel = C2)
1424     public int test76(RefPoint rp1, RefPoint rp2) {
1425         return rp1.test76_helper(rp2);
1426     }
1427 
1428     @DontCompile
1429     public void test76_verifier(boolean warmup) {
1430         int count = warmup ? 1 : 5;
1431         for (int i=0; i<count; i++) { // need a loop to test inline cache
1432             RefPoint rp1 = refPointField1;
1433             RefPoint rp2 = refPointField2;
1434             int result = test76(rp1, rp2);
1435             int n = rp1.test76_helper(rp2);
1436             Asserts.assertEQ(result, n);
1437         }
1438     }
1439     /**/
1440 
1441     /*
1442 
1443     // C2->C1 invokevirtual, force GC for every allocation when entering a C1 VEP (RefPoint)
1444     // Same as test56, except we call the VVEP(RO) instead of VEP.
1445     @Test(compLevel = C2)
1446     public int test77(RefPoint rp1, RefPoint rp2) {
1447         return rp1.test76_helper(rp2);
1448     }
1449 
1450     @DontCompile
1451     public void test77_verifier(boolean warmup) {
1452         int count = warmup ? 1 : 5;
1453         for (int i=0; i<count; i++) { // need a loop to test inline cache
1454             RefPoint rp1 = new RefPoint(1, 2);
1455             RefPoint rp2 = new RefPoint(22, 33);
1456             int result;
1457             if (!warmup) {
1458                 System.out.println("Hello: " + i);
1459             }
1460             try (ForceGCMarker m = ForceGCMarker.mark(warmup)) {
1461                 result = test77(rp1, rp2);
1462             }
1463             int n = rp1.test77_helper(rp2);
1464             Asserts.assertEQ(result, n);
1465         }
1466     }
1467     /**/
1468 }