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