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