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