1 /*
   2  * Copyright (c) 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 java.lang.classfile.Label;
  27 import java.lang.invoke.MethodHandle;
  28 import java.lang.invoke.MethodHandles;
  29 import java.lang.invoke.MethodType;
  30 import java.util.Random;
  31 
  32 import jdk.test.lib.Asserts;
  33 import jdk.test.lib.Utils;
  34 import jdk.test.whitebox.WhiteBox;
  35 import test.java.lang.invoke.lib.InstructionHelper;
  36 
  37 /**
  38  * @test id=Xbatch
  39  * @summary Test construction of value objects.
  40  * @key randomness
  41  * @library /testlibrary /test/lib /compiler/whitebox /test/jdk/java/lang/invoke/common /
  42  * @enablePreview
  43  * @build jdk.test.whitebox.WhiteBox test.java.lang.invoke.lib.InstructionHelper
  44  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
  45  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbatch
  46  *                   -XX:CompileCommand=inline,TestValueConstruction::checkDeopt
  47  *                   compiler.valhalla.inlinetypes.TestValueConstruction
  48  */
  49 
  50 /*
  51  * @test id=DeoptimizeALot
  52  * @key randomness
  53  * @library /testlibrary /test/lib /compiler/whitebox /test/jdk/java/lang/invoke/common /
  54  * @enablePreview
  55  * @build jdk.test.whitebox.WhiteBox test.java.lang.invoke.lib.InstructionHelper
  56  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
  57  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+DeoptimizeALot
  58  *                   -XX:CompileCommand=inline,TestValueConstruction::checkDeopt
  59  *                   compiler.valhalla.inlinetypes.TestValueConstruction
  60  */
  61 
  62 /*
  63  * @test id=CompileonlyTest
  64  * @key randomness
  65  * @library /testlibrary /test/lib /compiler/whitebox /test/jdk/java/lang/invoke/common /
  66  * @enablePreview
  67  * @build jdk.test.whitebox.WhiteBox test.java.lang.invoke.lib.InstructionHelper
  68  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
  69  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
  70  *                   -XX:CompileCommand=compileonly,*TestValueConstruction::test* -Xbatch
  71  *                   -XX:CompileCommand=inline,TestValueConstruction::checkDeopt
  72  *                   compiler.valhalla.inlinetypes.TestValueConstruction
  73  */
  74 
  75 /**
  76  * @test id=DontInlineHelper
  77  * @summary Test construction of value objects.
  78  * @key randomness
  79  * @library /testlibrary /test/lib /compiler/whitebox /test/jdk/java/lang/invoke/common /
  80  * @enablePreview
  81  * @build jdk.test.whitebox.WhiteBox test.java.lang.invoke.lib.InstructionHelper
  82  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
  83  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbatch
  84  *                   -XX:CompileCommand=dontinline,compiler*::helper*
  85  *                   -XX:CompileCommand=inline,TestValueConstruction::checkDeopt
  86  *                   compiler.valhalla.inlinetypes.TestValueConstruction
  87  */
  88 
  89 /*
  90  * @test id=DontInlineMyValueInit
  91  * @key randomness
  92  * @library /testlibrary /test/lib /compiler/whitebox /test/jdk/java/lang/invoke/common /
  93  * @enablePreview
  94  * @build jdk.test.whitebox.WhiteBox test.java.lang.invoke.lib.InstructionHelper
  95  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
  96  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
  97  *                   -XX:CompileCommand=dontinline,*MyValue*::<init> -Xbatch
  98  *                   -XX:CompileCommand=inline,TestValueConstruction::checkDeopt
  99  *                   compiler.valhalla.inlinetypes.TestValueConstruction
 100  */
 101 
 102 /*
 103  * @test id=DontInlineObjectInit
 104  * @key randomness
 105  * @library /testlibrary /test/lib /compiler/whitebox /test/jdk/java/lang/invoke/common /
 106  * @enablePreview
 107  * @build jdk.test.whitebox.WhiteBox test.java.lang.invoke.lib.InstructionHelper
 108  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
 109  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
 110  *                   -XX:CompileCommand=dontinline,*Object::<init> -Xbatch
 111  *                   -XX:CompileCommand=inline,TestValueConstruction::checkDeopt
 112  *                   compiler.valhalla.inlinetypes.TestValueConstruction
 113  */
 114 
 115 /*
 116  * @test id=DontInlineObjectInitDeoptimizeALot
 117  * @key randomness
 118  * @library /testlibrary /test/lib /compiler/whitebox /test/jdk/java/lang/invoke/common /
 119  * @enablePreview
 120  * @build jdk.test.whitebox.WhiteBox test.java.lang.invoke.lib.InstructionHelper
 121  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
 122  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+IgnoreUnrecognizedVMOptions
 123  *                   -XX:+DeoptimizeALot -XX:CompileCommand=dontinline,*Object::<init> -Xbatch
 124  *                   -XX:CompileCommand=inline,TestValueConstruction::checkDeopt
 125  *                   compiler.valhalla.inlinetypes.TestValueConstruction
 126  */
 127 
 128 /*
 129  * @test id=DontInlineMyAbstractInit
 130  * @key randomness
 131  * @library /testlibrary /test/lib /compiler/whitebox /test/jdk/java/lang/invoke/common /
 132  * @enablePreview
 133  * @build jdk.test.whitebox.WhiteBox test.java.lang.invoke.lib.InstructionHelper
 134  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
 135  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
 136  *                   -XX:CompileCommand=dontinline,*MyAbstract::<init> -Xbatch
 137  *                   -XX:CompileCommand=inline,TestValueConstruction::checkDeopt
 138  *                   compiler.valhalla.inlinetypes.TestValueConstruction
 139  */
 140 
 141 /*
 142  * @test id=StressIncrementalInlining
 143  * @key randomness
 144  * @library /testlibrary /test/lib /compiler/whitebox /test/jdk/java/lang/invoke/common /
 145  * @enablePreview
 146  * @build jdk.test.whitebox.WhiteBox test.java.lang.invoke.lib.InstructionHelper
 147  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
 148  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbatch
 149  *                   -XX:-TieredCompilation -XX:+StressIncrementalInlining
 150  *                   -XX:CompileCommand=inline,TestValueConstruction::checkDeopt
 151  *                   compiler.valhalla.inlinetypes.TestValueConstruction
 152  */
 153 
 154 /*
 155  * @test id=StressIncrementalInliningCompileOnlyTest
 156  * @key randomness
 157  * @library /testlibrary /test/lib /compiler/whitebox /test/jdk/java/lang/invoke/common /
 158  * @enablePreview
 159  * @build jdk.test.whitebox.WhiteBox test.java.lang.invoke.lib.InstructionHelper
 160  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
 161  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
 162  *                   -XX:-TieredCompilation -XX:+StressIncrementalInlining
 163  *                   -XX:CompileCommand=inline,TestValueConstruction::checkDeopt
 164  *                   -XX:CompileCommand=compileonly,*TestValueConstruction::test* -Xbatch
 165  *                   compiler.valhalla.inlinetypes.TestValueConstruction
 166  */
 167 
 168 /* @test id=StressIncrementalInliningDontInlineMyValueInit
 169  * @key randomness
 170  * @library /testlibrary /test/lib /compiler/whitebox /test/jdk/java/lang/invoke/common /
 171  * @enablePreview
 172  * @build jdk.test.whitebox.WhiteBox test.java.lang.invoke.lib.InstructionHelper
 173  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
 174  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
 175  *                   -XX:-TieredCompilation -XX:+StressIncrementalInlining
 176  *                   -XX:CompileCommand=inline,TestValueConstruction::checkDeopt
 177  *                   -XX:CompileCommand=dontinline,*MyValue*::<init> -Xbatch
 178  *                   compiler.valhalla.inlinetypes.TestValueConstruction
 179  */
 180 
 181 /*
 182  * @test id=StressIncrementalInliningDontInlineObjectInit
 183  * @key randomness
 184  * @library /testlibrary /test/lib /compiler/whitebox /test/jdk/java/lang/invoke/common /
 185  * @enablePreview
 186  * @build jdk.test.whitebox.WhiteBox test.java.lang.invoke.lib.InstructionHelper
 187  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
 188  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
 189  *                   -XX:-TieredCompilation -XX:+StressIncrementalInlining
 190  *                   -XX:CompileCommand=inline,TestValueConstruction::checkDeopt
 191  *                   -XX:CompileCommand=dontinline,*Object::<init> -Xbatch
 192  *                   compiler.valhalla.inlinetypes.TestValueConstruction
 193  */
 194 
 195 /*
 196  * @test id=StressIncrementalInliningDontInlineMyAbstractInit
 197  * @key randomness
 198  * @library /testlibrary /test/lib /compiler/whitebox /test/jdk/java/lang/invoke/common /
 199  * @enablePreview
 200  * @build jdk.test.whitebox.WhiteBox test.java.lang.invoke.lib.InstructionHelper
 201  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
 202  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
 203  *                   -XX:-TieredCompilation -XX:+StressIncrementalInlining
 204  *                   -XX:CompileCommand=inline,TestValueConstruction::checkDeopt
 205  *                   -XX:CompileCommand=dontinline,*MyAbstract::<init> -Xbatch
 206  *                   compiler.valhalla.inlinetypes.TestValueConstruction
 207  */
 208 
 209 /*
 210  * @test id=StressIncrementalInliningOnStackReplacement
 211  * @key randomness
 212  * @library /testlibrary /test/lib /compiler/whitebox /test/jdk/java/lang/invoke/common /
 213  * @enablePreview
 214  * @build jdk.test.whitebox.WhiteBox test.java.lang.invoke.lib.InstructionHelper
 215  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
 216  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
 217  *                   -XX:-TieredCompilation -XX:+StressIncrementalInlining
 218  *                   -XX:Tier0BackedgeNotifyFreqLog=0 -XX:Tier2BackedgeNotifyFreqLog=0 -XX:Tier3BackedgeNotifyFreqLog=0
 219  *                   -XX:Tier2BackEdgeThreshold=1 -XX:Tier3BackEdgeThreshold=1 -XX:Tier4BackEdgeThreshold=1 -Xbatch
 220  *                   compiler.valhalla.inlinetypes.TestValueConstruction
 221  */
 222 
 223 public class TestValueConstruction {
 224     static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
 225 
 226     static boolean VERBOSE = false;
 227     static boolean[] deopt = new boolean[14];
 228     static boolean[] deoptBig = new boolean[24];
 229     static boolean[] deoptHuge = new boolean[37];
 230 
 231     static Object o = new Object();
 232 
 233     static void reportDeopt(int deoptNum) {
 234         System.out.println("Deopt " + deoptNum + " triggered");
 235         if (VERBOSE) {
 236             new Exception().printStackTrace(System.out);
 237         }
 238     }
 239 
 240     // Trigger deopts at various places
 241     static void checkDeopt(int deoptNum) {
 242         if (deopt[deoptNum]) {
 243             // C2 will add an uncommon trap here
 244             reportDeopt(deoptNum);
 245         }
 246     }
 247 
 248     // Trigger deopts at various places
 249     static void checkDeoptBig(int deoptNum) {
 250         if (deoptBig[deoptNum]) {
 251             // C2 will add an uncommon trap here
 252             reportDeopt(deoptNum);
 253         }
 254     }
 255 
 256     // Trigger deopts at various places
 257     static void checkDeoptHuge(int deoptNum) {
 258         if (deoptHuge[deoptNum]) {
 259             // C2 will add an uncommon trap here
 260             reportDeopt(deoptNum);
 261         }
 262     }
 263 
 264     static interface MyInterface {
 265 
 266     }
 267 
 268     static value class MyValue1 implements MyInterface {
 269         int x;
 270 
 271         public MyValue1(int x) {
 272             checkDeopt(0);
 273             this.x = x;
 274             checkDeopt(1);
 275             super();
 276             checkDeopt(2);
 277         }
 278 
 279         public MyValue1(int x, int deoptNum1, int deoptNum2, int deoptNum3) {
 280             checkDeopt(deoptNum1);
 281             this.x = x;
 282             checkDeopt(deoptNum2);
 283             super();
 284             checkDeopt(deoptNum3);
 285         }
 286 
 287         public String toString() {
 288             return "x: " + x;
 289         }
 290     }
 291 
 292     static value class MyValue1a extends MyAbstract1 implements MyInterface {
 293         int x;
 294 
 295         public MyValue1a(int x) {
 296             checkDeopt(0);
 297             this.x = x;
 298             checkDeopt(1);
 299             super();
 300             checkDeopt(2);
 301         }
 302 
 303         public MyValue1a(int x, int deoptNum1, int deoptNum2, int deoptNum3) {
 304             checkDeopt(deoptNum1);
 305             this.x = x;
 306             checkDeopt(deoptNum2);
 307             super();
 308             checkDeopt(deoptNum3);
 309         }
 310 
 311         public String toString() {
 312             return "x: " + x;
 313         }
 314     }
 315 
 316     static abstract value class AMyValue1 implements MyInterface {
 317         int x;
 318 
 319         public AMyValue1(int x) {
 320             checkDeopt(3);
 321             this.x = x;
 322             checkDeopt(4);
 323             super();
 324             checkDeopt(5);
 325         }
 326 
 327         public AMyValue1(int x, int deoptNum1, int deoptNum2, int deoptNum3) {
 328             checkDeopt(deoptNum1);
 329             this.x = x;
 330             checkDeopt(deoptNum2);
 331             super();
 332             checkDeopt(deoptNum3);
 333         }
 334 
 335         public String toString() {
 336             return "x: " + x;
 337         }
 338     }
 339 
 340     static value class MyValue1b extends AMyValue1 implements MyInterface {
 341         int x;
 342 
 343         public MyValue1b(int x) {
 344             checkDeopt(0);
 345             this.x = x;
 346             checkDeopt(1);
 347             super(x);
 348             checkDeopt(2);
 349         }
 350 
 351         public MyValue1b(int x, int deoptNum1, int deoptNum2, int deoptNum3) {
 352             checkDeopt(deoptNum1);
 353             this.x = x;
 354             checkDeopt(deoptNum2);
 355             super(x, deoptNum1 + 3, deoptNum2 + 3, deoptNum3 + 3);
 356             checkDeopt(deoptNum3);
 357         }
 358 
 359         public String toString() {
 360             return "x: " + x;
 361         }
 362     }
 363 
 364 
 365     static abstract value class MyAbstract1 { }
 366 
 367     static value class MyValue2 extends MyAbstract1 {
 368         int x;
 369 
 370         public MyValue2(int x) {
 371             checkDeopt(0);
 372             this.x = x;
 373             checkDeopt(1);
 374             super();
 375             checkDeopt(2);
 376         }
 377 
 378         public String toString() {
 379             return "x: " + x;
 380         }
 381     }
 382 
 383     static abstract value class MyAbstract2 {
 384         public MyAbstract2(int x) {
 385             checkDeopt(0);
 386         }
 387     }
 388 
 389     static value class MyValue3 extends MyAbstract2 {
 390         int x;
 391 
 392         public MyValue3(int x) {
 393             checkDeopt(1);
 394             this(x, 0);
 395             helper1(this, x, 2); // 'this' escapes through argument
 396             helper2(x, 3); // 'this' escapes through receiver
 397             checkDeopt(4);
 398         }
 399 
 400         public MyValue3(int x, int unused) {
 401             this.x = helper3(x, 5);
 402             super(x);
 403             helper1(this, x, 6); // 'this' escapes through argument
 404             helper2(x, 7); // 'this' escapes through receiver
 405             checkDeopt(8);
 406         }
 407 
 408         public static void helper1(MyValue3 obj, int x, int deoptNum) {
 409             checkDeopt(deoptNum);
 410             Asserts.assertEQ(obj.x, x);
 411         }
 412 
 413         public void helper2(int x, int deoptNum) {
 414             checkDeopt(deoptNum);
 415             Asserts.assertEQ(this.x, x);
 416         }
 417 
 418         public static int helper3(int x, int deoptNum) {
 419             checkDeopt(deoptNum);
 420             return x;
 421         }
 422 
 423         public String toString() {
 424             return "x: " + x;
 425         }
 426     }
 427 
 428     static abstract value class AMyValue3a {
 429         int x;
 430 
 431         public AMyValue3a(int x) {
 432             this.x = helper3(x, 5);
 433             super();
 434             helper1(this, x, 6); // 'this' escapes through argument
 435             helper2(x, 7); // 'this' escapes through receiver
 436             checkDeopt(8);
 437         }
 438 
 439         public static void helper1(AMyValue3a obj, int x, int deoptNum) {
 440             checkDeopt(deoptNum);
 441             Asserts.assertEQ(obj.x, x);
 442         }
 443 
 444         public void helper2(int x, int deoptNum) {
 445             checkDeopt(deoptNum);
 446             Asserts.assertEQ(this.x, x);
 447         }
 448 
 449         public static int helper3(int x, int deoptNum) {
 450             checkDeopt(deoptNum);
 451             return x;
 452         }
 453     }
 454 
 455     static value class MyValue3a extends AMyValue3a {
 456         int y;
 457 
 458         public MyValue3a(int y) {
 459             checkDeopt(1);
 460             this.y = helper3(y, 5);
 461             super(y);
 462             helper1(this, y, 2); // 'this' escapes through argument
 463             helper2(y, 3); // 'this' escapes through receiver
 464             checkDeopt(4);
 465         }
 466 
 467 
 468         public static void helper1(MyValue3a obj, int y, int deoptNum) {
 469             checkDeopt(deoptNum);
 470             Asserts.assertEQ(obj.y, y);
 471         }
 472 
 473         public void helper2(int y, int deoptNum) {
 474             checkDeopt(deoptNum);
 475             Asserts.assertEQ(this.y, y);
 476         }
 477 
 478         public static int helper3(int y, int deoptNum) {
 479             checkDeopt(deoptNum);
 480             return y;
 481         }
 482 
 483         public String toString() {
 484             return "x: " + y;
 485         }
 486     }
 487 
 488     static value class MyValue4 {
 489         Integer x;
 490 
 491         public MyValue4(int x) {
 492             checkDeopt(0);
 493             this.x = x;
 494             checkDeopt(1);
 495             super();
 496             checkDeopt(2);
 497         }
 498 
 499         public String toString() {
 500             return "x: " + x;
 501         }
 502     }
 503 
 504     abstract static value class AMyValue4a {
 505         Integer y;
 506 
 507         public AMyValue4a(int y) {
 508             checkDeopt(3);
 509             this.y = y;
 510             checkDeopt(4);
 511             super();
 512             checkDeopt(5);
 513         }
 514 
 515         public String toString() {
 516             return "y: " + y;
 517         }
 518     }
 519 
 520     static value class MyValue4a extends AMyValue4a {
 521         Integer x;
 522 
 523         public MyValue4a(int x) {
 524             checkDeopt(0);
 525             this.x = x;
 526             checkDeopt(1);
 527             super(x);
 528             checkDeopt(2);
 529         }
 530 
 531         public String toString() {
 532             return "x: " + x;
 533         }
 534     }
 535 
 536     static value class MyValue5 extends MyAbstract1 {
 537         int x;
 538 
 539         public MyValue5(int x, boolean b) {
 540             checkDeopt(0);
 541             if (b) {
 542                 checkDeopt(1);
 543                 this.x = 42;
 544                 checkDeopt(2);
 545             } else {
 546                 checkDeopt(3);
 547                 this.x = x;
 548                 checkDeopt(4);
 549             }
 550             checkDeopt(5);
 551             super();
 552             checkDeopt(6);
 553         }
 554 
 555         public String toString() {
 556             return "x: " + x;
 557         }
 558     }
 559 
 560     static abstract value class AMyValue5a {
 561         int y;
 562 
 563         public AMyValue5a(int y, boolean b) {
 564             checkDeopt(7);
 565             if (b) {
 566                 checkDeopt(8);
 567                 this.y = 42;
 568                 checkDeopt(9);
 569             } else {
 570                 checkDeopt(10);
 571                 this.y = y;
 572                 checkDeopt(11);
 573             }
 574             checkDeopt(12);
 575             super();
 576             checkDeopt(13);
 577         }
 578 
 579         public String toString() {
 580             return "y: " + y;
 581         }
 582     }
 583 
 584     static value class MyValue5a extends AMyValue5a {
 585         int x;
 586 
 587         public MyValue5a(int x, boolean b) {
 588             checkDeopt(0);
 589             if (b) {
 590                 checkDeopt(1);
 591                 this.x = 42;
 592                 checkDeopt(2);
 593             } else {
 594                 checkDeopt(3);
 595                 this.x = x;
 596                 checkDeopt(4);
 597             }
 598             checkDeopt(5);
 599             super(x, b);
 600             checkDeopt(6);
 601         }
 602 
 603         public String toString() {
 604             return "x: " + x;
 605         }
 606     }
 607 
 608     static value class MyValue6 {
 609         int x;
 610         MyValue1 val1;
 611         MyValue1 val2;
 612 
 613         public MyValue6(int x) {
 614             checkDeopt(0);
 615             this.x = x;
 616             checkDeopt(1);
 617             this.val1 = new MyValue1(x, 2, 3, 4);
 618             checkDeopt(5);
 619             this.val2 = new MyValue1(x + 1, 6, 7, 8);
 620             checkDeopt(9);
 621             super();
 622             checkDeopt(10);
 623         }
 624 
 625         public String toString() {
 626             return "x: " + x + ", val1: [" + val1 + "], val2: [" + val2 + "]";
 627         }
 628     }
 629 
 630     static value class MyValue6a {
 631         int x;
 632         MyValue1a val1;
 633         MyValue1a val2;
 634 
 635         public MyValue6a(int x) {
 636             checkDeopt(0);
 637             this.x = x;
 638             checkDeopt(1);
 639             this.val1 = new MyValue1a(x, 2, 3, 4);
 640             checkDeopt(5);
 641             this.val2 = new MyValue1a(x + 1, 6, 7, 8);
 642             checkDeopt(9);
 643             super();
 644             checkDeopt(10);
 645         }
 646 
 647         public String toString() {
 648             return "x: " + x + ", val1: [" + val1 + "], val2: [" + val2 + "]";
 649         }
 650     }
 651 
 652     static value class MyValue6b {
 653         int x;
 654         MyValue1b val1;
 655         MyValue1b val2;
 656 
 657         public MyValue6b(int x) {
 658             checkDeopt(0);
 659             this.x = x;
 660             checkDeopt(1);
 661             this.val1 = new MyValue1b(x, 2, 3, 4);
 662             checkDeopt(5);
 663             this.val2 = new MyValue1b(x + 1, 6, 7, 8);
 664             checkDeopt(12);
 665             super();
 666             checkDeopt(13);
 667         }
 668 
 669         public String toString() {
 670             return "x: " + x + ", val1: [" + val1 + "], val2: [" + val2 + "]";
 671         }
 672     }
 673 
 674     // Same as MyValue6 but unused MyValue1 construction
 675     static value class MyValue7 {
 676         int x;
 677 
 678         public MyValue7(int x) {
 679             checkDeopt(0);
 680             this.x = x;
 681             checkDeopt(1);
 682             new MyValue1(42, 2, 3, 4);
 683             checkDeopt(5);
 684             new MyValue1(43, 6, 7, 8);
 685             checkDeopt(9);
 686             super();
 687             checkDeopt(10);
 688         }
 689 
 690         public String toString() {
 691             return "x: " + x;
 692         }
 693     }
 694 
 695     // Same as MyValue6 but unused MyValue1 construction
 696     static value class MyValue7a {
 697         int x;
 698 
 699         public MyValue7a(int x) {
 700             checkDeopt(0);
 701             this.x = x;
 702             checkDeopt(1);
 703             new MyValue1a(42, 2, 3, 4);
 704             checkDeopt(5);
 705             new MyValue1a(43, 6, 7, 8);
 706             checkDeopt(9);
 707             super();
 708             checkDeopt(10);
 709         }
 710 
 711         public String toString() {
 712             return "x: " + x;
 713         }
 714     }
 715 
 716     // Same as MyValue6 but unused MyValue1 construction
 717     static value class MyValue7b {
 718         int x;
 719 
 720         public MyValue7b(int x) {
 721             checkDeopt(0);
 722             this.x = x;
 723             checkDeopt(1);
 724             new MyValue1b(42, 2, 3, 4);
 725             checkDeopt(5);
 726             new MyValue1b(43, 6, 7, 8);
 727             checkDeopt(12);
 728             super();
 729             checkDeopt(13);
 730         }
 731 
 732         public String toString() {
 733             return "x: " + x;
 734         }
 735     }
 736 
 737     // Constructor calling another constructor of the same value class with control flow dependent initialization
 738     static value class MyValue8 {
 739         int x;
 740 
 741         public MyValue8(int x) {
 742             checkDeopt(0);
 743             this(x, 0);
 744             checkDeopt(1);
 745         }
 746 
 747         public MyValue8(int x, int unused1) {
 748             checkDeopt(2);
 749             if ((x % 2) == 0) {
 750                 checkDeopt(3);
 751                 this.x = 42;
 752                 checkDeopt(4);
 753             } else {
 754                 checkDeopt(5);
 755                 this.x = x;
 756                 checkDeopt(6);
 757             }
 758             checkDeopt(7);
 759             super();
 760             checkDeopt(8);
 761         }
 762 
 763         public MyValue8(int x, int unused1, int unused2) {
 764             checkDeopt(3);
 765             this.x = x;
 766             checkDeopt(4);
 767         }
 768 
 769         public static MyValue8 valueOf(int x) {
 770             checkDeopt(0);
 771             if ((x % 2) == 0) {
 772                 checkDeopt(1);
 773                 return new MyValue8(42, 0, 0);
 774             } else {
 775                 checkDeopt(2);
 776                 return new MyValue8(x, 0, 0);
 777             }
 778         }
 779 
 780         public String toString() {
 781             return "x: " + x;
 782         }
 783     }
 784 
 785     // Constructor calling another constructor of the same value class with control flow dependent initialization
 786     static abstract value class AMyValue8a {
 787         int y;
 788 
 789         public AMyValue8a(int y) {
 790             checkDeoptBig(9);
 791             this(y, 0);
 792             checkDeoptBig(10);
 793         }
 794 
 795         public AMyValue8a(int y, int unused1) {
 796             checkDeoptBig(11);
 797             if ((y % 2) == 0) {
 798                 checkDeoptBig(12);
 799                 this.y = 42;
 800                 checkDeoptBig(13);
 801             } else {
 802                 checkDeoptBig(14);
 803                 this.y = y;
 804                 checkDeoptBig(15);
 805             }
 806             checkDeoptBig(16);
 807             super();
 808             checkDeoptBig(17);
 809         }
 810 
 811         public AMyValue8a(int y, int unused1, int unused2) {
 812             checkDeoptBig(12);
 813             this.y = y;
 814             checkDeoptBig(13);
 815         }
 816 
 817         public static AMyValue8a valueOf(int y) {
 818             checkDeoptBig(0);
 819             if ((y % 2) == 0) {
 820                 checkDeoptBig(1);
 821                 return new MyValue8a(42, 0, 0);
 822             } else {
 823                 checkDeoptBig(2);
 824                 return new MyValue8a(y, 0, 0);
 825             }
 826         }
 827 
 828         public String toString() {
 829             return "y: " + y;
 830         }
 831     }
 832 
 833     // Constructor calling another constructor of the same value class with control flow dependent initialization
 834     static value class MyValue8a extends AMyValue8a {
 835         int x;
 836 
 837         public MyValue8a(int x) {
 838             checkDeoptBig(0);
 839             this(x, 0);
 840             checkDeoptBig(1);
 841         }
 842 
 843         public MyValue8a(int x, int unused1) {
 844             checkDeoptBig(2);
 845             if ((x % 2) == 0) {
 846                 checkDeoptBig(3);
 847                 this.x = 42;
 848                 checkDeoptBig(4);
 849             } else {
 850                 checkDeoptBig(5);
 851                 this.x = x;
 852                 checkDeoptBig(6);
 853             }
 854             checkDeoptBig(7);
 855             super(unused1);
 856             checkDeoptBig(8);
 857         }
 858 
 859         public MyValue8a(int x, int unused1, int unused2) {
 860             checkDeoptBig(3);
 861             this.x = x;
 862             checkDeoptBig(4);
 863             super(x, unused1, unused2);
 864         }
 865 
 866         public static MyValue8a valueOf(int x) {
 867             checkDeoptBig(0);
 868             if ((x % 2) == 0) {
 869                 checkDeoptBig(1);
 870                 return new MyValue8a(42, 0, 0);
 871             } else {
 872                 checkDeoptBig(2);
 873                 return new MyValue8a(x, 0, 0);
 874             }
 875         }
 876 
 877         public String toString() {
 878             return "x: " + x;
 879         }
 880     }
 881 
 882     // Constructor calling another constructor of a different value class
 883     static value class MyValue9 {
 884         MyValue8 val;
 885 
 886         public MyValue9(int x) {
 887             checkDeopt(9);
 888             this(x, 0);
 889             checkDeopt(10);
 890         }
 891 
 892         public MyValue9(int i, int unused1) {
 893             checkDeopt(11);
 894             val = new MyValue8(i);
 895             checkDeopt(12);
 896         }
 897 
 898         public MyValue9(int x, int unused1, int unused2) {
 899             checkDeopt(5);
 900             this(x, 0, 0, 0);
 901             checkDeopt(6);
 902         }
 903 
 904         public MyValue9(int i, int unused1, int unused2, int unused3) {
 905             checkDeopt(7);
 906             val = MyValue8.valueOf(i);
 907             checkDeopt(8);
 908         }
 909 
 910         public String toString() {
 911             return "val: [" + val + "]";
 912         }
 913     }
 914 
 915     abstract static value class AMyValue9a {
 916         AMyValue8a valA;
 917 
 918         public AMyValue9a(int x) {
 919             checkDeoptHuge(22);
 920             this(x, 0);
 921             checkDeoptHuge(23);
 922         }
 923 
 924         public AMyValue9a(int i, int unused1) {
 925             checkDeoptHuge(24);
 926             valA = new MyValue8a(i);
 927             checkDeoptHuge(25);
 928         }
 929 
 930         public AMyValue9a(int x, int unused1, int unused2) {
 931             checkDeoptHuge(18);
 932             this(x, 0, 0, 0);
 933             checkDeoptHuge(19);
 934         }
 935 
 936         public AMyValue9a(int i, int unused1, int unused2, int unused3) {
 937             checkDeoptHuge(20);
 938             valA = MyValue8a.valueOf(i);
 939             checkDeoptHuge(21);
 940         }
 941 
 942         public String toString() {
 943             return "valA: [" + valA + "]";
 944         }
 945     }
 946 
 947     // Constructor calling another constructor of a different value class
 948     static value class MyValue9a extends AMyValue9a {
 949         MyValue8a val;
 950 
 951         public MyValue9a(int x) {
 952             checkDeoptHuge(18);
 953             this(x, 0);
 954             checkDeoptHuge(19);
 955         }
 956 
 957         public MyValue9a(int i, int unused1) {
 958             checkDeoptHuge(20);
 959             val = new MyValue8a(i);
 960             checkDeoptHuge(21);
 961             super(i, unused1);
 962             checkDeoptHuge(26);
 963         }
 964 
 965         public MyValue9a(int x, int unused1, int unused2) {
 966             checkDeoptHuge(14);
 967             this(x, 0, 0, 0);
 968             checkDeoptHuge(15);
 969         }
 970 
 971         public MyValue9a(int i, int unused1, int unused2, int unused3) {
 972             checkDeoptHuge(16);
 973             val = MyValue8a.valueOf(i);
 974             checkDeoptHuge(17);
 975             super(i, unused1, unused2, unused3);
 976             checkDeoptHuge(27);
 977         }
 978 
 979         public String toString() {
 980             return "val: [" + val + "]";
 981         }
 982     }
 983 
 984     // Constructor with a loop
 985     static value class MyValue10 {
 986         int x;
 987         int y;
 988 
 989         public MyValue10(int x, int cnt) {
 990             checkDeopt(0);
 991             this.x = x;
 992             checkDeopt(1);
 993             int res = 0;
 994             for (int i = 0; i < cnt; ++i) {
 995                 checkDeopt(2);
 996                 res += x;
 997                 checkDeopt(3);
 998             }
 999             checkDeopt(4);
1000             this.y = res;
1001             checkDeopt(5);
1002             super();
1003             checkDeopt(6);
1004         }
1005 
1006         public String toString() {
1007             return "x: " + x + ", y: " + y;
1008         }
1009     }
1010 
1011     // Constructor with a loop
1012     static abstract value class AMyValue10a {
1013         int a;
1014         int b;
1015 
1016         public AMyValue10a(int a, int cnt) {
1017             checkDeopt(7);
1018             this.a = a;
1019             checkDeopt(8);
1020             int res = 0;
1021             for (int i = 0; i < cnt; ++i) {
1022                 checkDeopt(9);
1023                 res += a;
1024                 checkDeopt(10);
1025             }
1026             checkDeopt(11);
1027             this.b = res;
1028             checkDeopt(12);
1029             super();
1030             checkDeopt(13);
1031         }
1032 
1033         public String toString() {
1034             return "x: " + a + ", y: " + b;
1035         }
1036     }
1037 
1038     // Constructor with a loop
1039     static value class MyValue10a extends AMyValue10a {
1040         int x;
1041         int y;
1042 
1043         public MyValue10a(int x, int cnt) {
1044             checkDeopt(0);
1045             this.x = x;
1046             checkDeopt(1);
1047             int res = 0;
1048             for (int i = 0; i < cnt; ++i) {
1049                 checkDeopt(2);
1050                 res += x;
1051                 checkDeopt(3);
1052             }
1053             checkDeopt(4);
1054             this.y = res;
1055             checkDeopt(5);
1056             super(x, cnt);
1057             checkDeopt(6);
1058         }
1059 
1060         public String toString() {
1061             return "x: " + x + ", y: " + y;
1062         }
1063     }
1064 
1065     // Value class with recursive field definitions
1066     static value class MyValue11 {
1067         int x;
1068         MyValue11 val1;
1069         MyValue11 val2;
1070 
1071         public MyValue11(int x) {
1072             checkDeopt(0);
1073             this.x = x;
1074             checkDeopt(1);
1075             this.val1 = new MyValue11(x + 1, 2, 3, 4, 5);
1076             checkDeopt(6);
1077             this.val2 = new MyValue11(x + 2, 7, 8, 9, 10);
1078             checkDeopt(11);
1079         }
1080 
1081         public MyValue11(int x, int deoptNum1, int deoptNum2, int deoptNum3, int deoptNum4) {
1082             checkDeopt(deoptNum1);
1083             this.x = x;
1084             checkDeopt(deoptNum2);
1085             this.val1 = null;
1086             checkDeopt(deoptNum3);
1087             this.val2 = null;
1088             checkDeopt(deoptNum4);
1089         }
1090 
1091         public String toString() {
1092             return "x: " + x + ", val1: [" + (val1 != this ? val1 : "this") + "], val2: [" + (val2 != this ? val2 : "this") + "]";
1093         }
1094     }
1095 
1096     // Value class with recursive field definitions
1097     static abstract value class AMyValue11a {
1098         int y;
1099         AMyValue11a valA1;
1100         AMyValue11a valA2;
1101 
1102         public AMyValue11a(int y) {
1103             checkDeoptHuge(19);
1104             this.y = y;
1105             checkDeoptHuge(20);
1106             this.valA1 = new MyValue11a(y + 1, 21, 22, 23, 24, 25);
1107             checkDeoptHuge(26);
1108             this.valA2 = new MyValue11a(y + 2, 27, 28, 29, 30, 31);
1109             checkDeoptHuge(36);
1110         }
1111 
1112         public AMyValue11a(int y, int deoptNum1, int deoptNum2, int deoptNum3, int deoptNum4) {
1113             checkDeoptHuge(deoptNum1);
1114             this.y = y;
1115             checkDeoptHuge(deoptNum2);
1116             this.valA1 = null;
1117             checkDeoptHuge(deoptNum3);
1118             this.valA2 = null;
1119             checkDeoptHuge(deoptNum4);
1120         }
1121 
1122         public String toString() {
1123             return "x: " + y + ", val1: [" + (valA1 != this ? valA1 : "this") + "], val2: [" + (valA2 != this ? valA2 : "this") + "]";
1124         }
1125     }
1126 
1127     // Value class with recursive field definitions
1128     static value class MyValue11a extends AMyValue11a {
1129         int x;
1130         MyValue11a val1;
1131         MyValue11a val2;
1132 
1133         public MyValue11a(int x) {
1134             checkDeoptHuge(0);
1135             this.x = x;
1136             checkDeoptHuge(1);
1137             this.val1 = new MyValue11a(x + 1, 2, 3, 4, 5, 6);
1138             checkDeoptHuge(7);
1139             this.val2 = new MyValue11a(x + 2, 8, 9, 10, 11, 12);
1140             checkDeoptHuge(17);
1141             super(x);
1142             checkDeoptHuge(18);
1143         }
1144 
1145         public MyValue11a(int x, int deoptNum1, int deoptNum2, int deoptNum3, int deoptNum4, int deoptNum5) {
1146             checkDeoptHuge(deoptNum1);
1147             this.x = x;
1148             checkDeoptHuge(deoptNum2);
1149             this.val1 = null;
1150             checkDeoptHuge(deoptNum3);
1151             this.val2 = null;
1152             checkDeoptHuge(deoptNum4);
1153             super(x, deoptNum5 + 1, deoptNum5 + 2, deoptNum5 + 3, deoptNum5 + 4);
1154             checkDeoptHuge(deoptNum5);
1155         }
1156 
1157         public String toString() {
1158             return "x: " + x + ", val1: [" + (val1 != this ? val1 : "this") + "], val2: [" + (val2 != this ? val2 : "this") + "]";
1159         }
1160     }
1161 
1162     static value class MyValue12 {
1163         Object o;
1164 
1165         public MyValue12() {
1166             checkDeopt(0);
1167             this.o = new Object();
1168             checkDeopt(1);
1169             super();
1170             checkDeopt(2);
1171         }
1172     }
1173 
1174     static abstract value class MyAbstract13b {
1175         MyAbstract13b() {
1176             checkDeopt(4);
1177             super();
1178             checkDeopt(5);
1179         }
1180     }
1181 
1182     static abstract value class MyAbstract13a extends MyAbstract13b {
1183         MyAbstract13a() {
1184             checkDeopt(2);
1185             super();
1186             checkDeopt(3);
1187         }
1188     }
1189 
1190     static value class MyValue13 extends MyAbstract13a {
1191         public MyValue13() {
1192             checkDeopt(0);
1193             super();
1194             checkDeopt(1);
1195         }
1196     }
1197 
1198     static value class MyValue14 {
1199         private Object o;
1200 
1201         public MyValue14(Object o) {
1202             this.o = o;
1203         }
1204 
1205         public static MyValue14 get(Object o) {
1206             return new MyValue14(getO(o));
1207         }
1208 
1209         public static Object getO(Object obj) {
1210             return obj;
1211         }
1212     }
1213 
1214     static abstract value class MyAbstract15 {
1215         int i;
1216 
1217         public MyAbstract15(int i) {
1218             checkDeoptBig(2);
1219             this.i = 34;
1220             checkDeoptBig(3);
1221             super();
1222             checkDeoptBig(4);
1223             MyValue15 v = new MyValue15();
1224             checkDeoptBig(11);
1225             foo(v);
1226             checkDeoptBig(13);
1227         }
1228 
1229         MyValue15 foo(MyValue15 v) {
1230             checkDeoptBig(12);
1231             return v;
1232         }
1233 
1234         public MyAbstract15() {
1235             checkDeoptBig(17);
1236             this.i = 4;
1237             checkDeoptBig(18);
1238             super();
1239             checkDeoptBig(19);
1240         }
1241     }
1242 
1243     static value class MyValue15 extends MyAbstract15 {
1244         int i;
1245 
1246         public MyValue15(int i) {
1247             checkDeoptBig(0);
1248             this.i = 3;
1249             checkDeoptBig(1);
1250             super(i);
1251             checkDeoptBig(14);
1252             MyValue15 v = new MyValue15();
1253             checkDeoptBig(21);
1254             getO(v);
1255             checkDeoptBig(23);
1256         }
1257 
1258 
1259         public MyValue15() {
1260             checkDeoptBig( 15);
1261             this.i = 43;
1262             checkDeoptBig(16);
1263             super();
1264             checkDeoptBig(20);
1265         }
1266 
1267         static Object getO(Object o) {
1268             checkDeoptBig(22);
1269             return o;
1270         }
1271     }
1272 
1273     static abstract value class MyAbstract16 {
1274         int i;
1275         public MyAbstract16() {
1276             checkDeoptBig(8);
1277             this.i = 4;
1278             checkDeoptBig(9);
1279             super();
1280             checkDeoptBig(10);
1281         }
1282 
1283         public MyAbstract16(int i) {
1284             checkDeoptBig(2);
1285             this.i = 34;
1286             checkDeoptBig(3);
1287             super();
1288             checkDeoptBig(4);
1289             getV();
1290             checkDeoptBig(13);
1291         }
1292 
1293         public MyAbstract16(boolean ignore) {
1294             checkDeoptBig(17);
1295             this.i = 4;
1296             checkDeoptBig(18);
1297             super();
1298             checkDeoptBig(19);
1299         }
1300 
1301         public static MyValue16 getV() {
1302             checkDeoptBig(5);
1303             MyValue16 v = new MyValue16();
1304             checkDeoptBig(12);
1305             return v;
1306         }
1307     }
1308 
1309     static value class MyValue16 extends MyAbstract16 {
1310         int i;
1311 
1312         public MyValue16(int i) {
1313             checkDeoptBig(0);
1314             this.i = 3;
1315             checkDeoptBig(1);
1316             super(i);
1317             checkDeoptBig(14);
1318             MyValue16 v = new MyValue16(true);
1319             checkDeoptBig(21);
1320             getO(v);
1321             checkDeoptBig(23);
1322         }
1323 
1324         public MyValue16() {
1325             checkDeoptBig( 6);
1326             this.i = 34;
1327             checkDeoptBig(7);
1328             super();
1329             checkDeoptBig(11);
1330         }
1331 
1332         public MyValue16(boolean ignore) {
1333             checkDeoptBig( 15);
1334             this.i = 43;
1335             checkDeoptBig(16);
1336             super(true);
1337             checkDeoptBig(20);
1338         }
1339 
1340         static Object getO(Object o) {
1341             checkDeoptBig(22);
1342             return o;
1343         }
1344     }
1345 
1346     public static int test1(int x) {
1347         MyValue1 val = new MyValue1(x);
1348         checkDeopt(3);
1349         return val.x;
1350     }
1351 
1352     public static int test1a(int x) {
1353         MyValue1a val = new MyValue1a(x);
1354         checkDeopt(3);
1355         return val.x;
1356     }
1357 
1358     public static int test1b(int x) {
1359         MyValue1b val = new MyValue1b(x);
1360         checkDeopt(6);
1361         return val.x;
1362     }
1363 
1364     public static MyValue1 helper1(int x) {
1365         return new MyValue1(x);
1366     }
1367 
1368     public static MyValue1a helper1a(int x) {
1369         return new MyValue1a(x);
1370     }
1371 
1372     public static MyValue1b helper1b(int x) {
1373         return new MyValue1b(x);
1374     }
1375 
1376     public static Object test2(int x) {
1377         return helper1(x);
1378     }
1379     public static Object test2a(int x) {
1380         return helper1a(x);
1381     }
1382     public static Object test2b(int x) {
1383         return helper1b(x);
1384     }
1385 
1386     public static Object test3(int limit) {
1387         MyValue1 res = null;
1388         for (int i = 0; i <= 10; ++i) {
1389             res = new MyValue1(i);
1390             checkDeopt(3);
1391         }
1392         return res;
1393     }
1394 
1395     public static Object test3a(int limit) {
1396         MyValue1a res = null;
1397         for (int i = 0; i <= 10; ++i) {
1398             res = new MyValue1a(i);
1399             checkDeopt(3);
1400         }
1401         return res;
1402     }
1403 
1404     public static Object test3b(int limit) {
1405         MyValue1b res = null;
1406         for (int i = 0; i <= 10; ++i) {
1407             res = new MyValue1b(i);
1408             checkDeopt(6);
1409         }
1410         return res;
1411     }
1412 
1413     public static MyValue1 test4(int x) {
1414         MyValue1 v = new MyValue1(x);
1415         checkDeopt(3);
1416         v = new MyValue1(x);
1417         return v;
1418     }
1419 
1420     public static MyValue1a test4a(int x) {
1421         MyValue1a v = new MyValue1a(x);
1422         checkDeopt(3);
1423         v = new MyValue1a(x);
1424         return v;
1425     }
1426 
1427     public static MyValue1b test4b(int x) {
1428         MyValue1b v = new MyValue1b(x);
1429         checkDeopt(6);
1430         v = new MyValue1b(x);
1431         return v;
1432     }
1433 
1434     public static int test5(int x) {
1435         MyValue2 val = new MyValue2(x);
1436         checkDeopt(3);
1437         return val.x;
1438     }
1439 
1440     public static MyValue2 helper2(int x) {
1441         return new MyValue2(x);
1442     }
1443 
1444     public static Object test6(int x) {
1445         return helper2(x);
1446     }
1447 
1448     public static Object test7(int limit) {
1449         MyValue2 res = null;
1450         for (int i = 0; i <= 10; ++i) {
1451             res = new MyValue2(i);
1452             checkDeopt(3);
1453         }
1454         return res;
1455     }
1456 
1457     public static MyValue2 test8(int x) {
1458         MyValue2 v = new MyValue2(x);
1459         checkDeopt(3);
1460         v = new MyValue2(x);
1461         return v;
1462     }
1463 
1464     public static int test9(int x) {
1465         MyValue3 val = new MyValue3(x);
1466         checkDeopt(9);
1467         return val.x;
1468     }
1469 
1470     public static int test9a(int x) {
1471         MyValue3a val = new MyValue3a(x);
1472         checkDeopt(9);
1473         return val.x + val.y;
1474     }
1475 
1476     public static MyValue3 helper3(int x) {
1477         return new MyValue3(x);
1478     }
1479 
1480     public static Object test10(int x) {
1481         return helper3(x);
1482     }
1483 
1484     public static MyValue3a helper3a(int x) {
1485         return new MyValue3a(x);
1486     }
1487 
1488     public static Object test10a(int x) {
1489         return helper3a(x);
1490     }
1491 
1492     public static Object test11(int limit) {
1493         MyValue3 res = null;
1494         for (int i = 0; i <= 10; ++i) {
1495             checkDeopt(9);
1496             res = new MyValue3(i);
1497         }
1498         return res;
1499     }
1500 
1501     public static Object test11a(int limit) {
1502         MyValue3a res = null;
1503         for (int i = 0; i <= 10; ++i) {
1504             checkDeopt(9);
1505             res = new MyValue3a(i);
1506         }
1507         return res;
1508     }
1509 
1510     public static MyValue3 test12(int x) {
1511         MyValue3 v = new MyValue3(x);
1512         checkDeopt(9);
1513         v = new MyValue3(x);
1514         return v;
1515     }
1516 
1517     public static MyValue3a test12a(int x) {
1518         MyValue3a v = new MyValue3a(x);
1519         checkDeopt(9);
1520         v = new MyValue3a(x);
1521         return v;
1522     }
1523 
1524     public static MyValue4 test13(int x) {
1525         return new MyValue4(x);
1526     }
1527 
1528     public static MyValue4a test13a(int x) {
1529         return new MyValue4a(x);
1530     }
1531 
1532     public static MyValue5 test14(int x, boolean b) {
1533         return new MyValue5(x, b);
1534     }
1535 
1536     public static MyValue5a test14a(int x, boolean b) {
1537         return new MyValue5a(x, b);
1538     }
1539 
1540     public static Object test15(int x) {
1541         return new MyValue6(x);
1542     }
1543 
1544     public static Object test15a(int x) {
1545         return new MyValue6a(x);
1546     }
1547 
1548     public static Object test15b(int x) {
1549         return new MyValue6b(x);
1550     }
1551 
1552     public static Object test16(int x) {
1553         return new MyValue7(x);
1554     }
1555 
1556     public static Object test16a(int x) {
1557         return new MyValue7a(x);
1558     }
1559 
1560     public static Object test16b(int x) {
1561         return new MyValue7b(x);
1562     }
1563 
1564     public static MyValue8 test17(int x) {
1565         return new MyValue8(x);
1566     }
1567 
1568     public static MyValue8a test17a(int x) {
1569         return new MyValue8a(x);
1570     }
1571 
1572     public static MyValue8 test18(int x) {
1573         return new MyValue8(x, 0);
1574     }
1575 
1576     public static MyValue8a test18a(int x) {
1577         return new MyValue8a(x, 0);
1578     }
1579 
1580     public static MyValue8 test19(int x) {
1581         return MyValue8.valueOf(x);
1582     }
1583 
1584     public static MyValue8a test19a(int x) {
1585         return MyValue8a.valueOf(x);
1586     }
1587 
1588     public static AMyValue8a test19b(int x) {
1589         return AMyValue8a.valueOf(x);
1590     }
1591 
1592     public static MyValue9 test20(int x) {
1593         return new MyValue9(x);
1594     }
1595 
1596     public static MyValue9a test20a(int x) {
1597         return new MyValue9a(x);
1598     }
1599 
1600     public static MyValue9 test21(int x) {
1601         return new MyValue9(x, 0);
1602     }
1603 
1604     public static MyValue9a test21a(int x) {
1605         return new MyValue9a(x, 0);
1606     }
1607 
1608     public static MyValue9 test22(int x) {
1609         return new MyValue9(x, 0, 0);
1610     }
1611 
1612     public static MyValue9a test22a(int x) {
1613         return new MyValue9a(x, 0, 0);
1614     }
1615 
1616     public static MyValue9 test23(int x) {
1617         return new MyValue9(x, 0, 0, 0);
1618     }
1619 
1620     public static MyValue9a test23a(int x) {
1621         return new MyValue9a(x, 0, 0, 0);
1622     }
1623 
1624     public static MyValue10 test24(int x, int cnt) {
1625         return new MyValue10(x, cnt);
1626     }
1627 
1628     public static MyValue10a test24a(int x, int cnt) {
1629         return new MyValue10a(x, cnt);
1630     }
1631 
1632     public static MyValue11 test25(int x) {
1633         return new MyValue11(x);
1634     }
1635 
1636     public static MyValue11a test25a(int x) {
1637         return new MyValue11a(x);
1638     }
1639 
1640     public static MyValue12 testObjectCallInsideConstructor() {
1641         return new MyValue12();
1642     }
1643 
1644     public static MyValue13 testMultipleAbstract() {
1645         return new MyValue13();
1646     }
1647 
1648     public static MyValue14 testCallAsConstructorArgument() {
1649         return MyValue14.get(o);
1650     }
1651 
1652     public static MyValue15 testBackAndForthAbstract(int x) {
1653         return new MyValue15(x);
1654     }
1655 
1656     public static MyValue16 testBackAndForthAbstract2(int x) {
1657         return new MyValue16(x);
1658     }
1659 
1660     private static final MethodHandle MULTIPLE_OCCURRENCES_IN_JVMS = InstructionHelper.buildMethodHandle(MethodHandles.lookup(),
1661             "multipleOccurrencesInJVMSReturnStack",
1662             MethodType.methodType(MyValue1.class, int.class),
1663             CODE -> {
1664                 Label loopHead = CODE.newLabel();
1665                 Label loopExit = CODE.newLabel();
1666                 CODE.
1667                         new_(MyValue1.class.describeConstable().get()).
1668                         dup().
1669                         astore(1).
1670                         astore(2).
1671                         iconst_0().
1672                         istore(3).
1673                         labelBinding(loopHead).
1674                         iload(3).
1675                         ldc(100).
1676                         if_icmpge(loopExit).
1677                         iinc(3, 1).
1678                         goto_(loopHead).
1679                         labelBinding(loopExit).
1680                         aload(2).
1681                         iload(0).
1682                         invokespecial(MyValue1.class.describeConstable().get(), "<init>", MethodType.methodType(void.class, int.class).describeConstable().get()).
1683                         aload(2).
1684                         areturn();
1685             });
1686 
1687     public static MyValue1 testMultipleOccurrencesInJVMS(int x) throws Throwable {
1688         return (MyValue1) MULTIPLE_OCCURRENCES_IN_JVMS.invokeExact(x);
1689     }
1690 
1691     public static void main(String[] args) throws Throwable {
1692         Random rand = Utils.getRandomInstance();
1693 
1694         // Randomly exclude some constructors from inlining via the WhiteBox API because CompileCommands don't match on different signatures.
1695         WHITE_BOX.testSetDontInlineMethod(MyValue1.class.getConstructor(int.class), rand.nextBoolean());
1696         WHITE_BOX.testSetDontInlineMethod(MyValue1a.class.getConstructor(int.class), rand.nextBoolean());
1697         WHITE_BOX.testSetDontInlineMethod(MyValue1b.class.getConstructor(int.class), rand.nextBoolean());
1698         WHITE_BOX.testSetDontInlineMethod(MyValue1.class.getConstructor(int.class, int.class, int.class, int.class), rand.nextBoolean());
1699         WHITE_BOX.testSetDontInlineMethod(MyValue1a.class.getConstructor(int.class, int.class, int.class, int.class), rand.nextBoolean());
1700         WHITE_BOX.testSetDontInlineMethod(MyValue1b.class.getConstructor(int.class, int.class, int.class, int.class), rand.nextBoolean());
1701         WHITE_BOX.testSetDontInlineMethod(MyValue3.class.getConstructor(int.class), rand.nextBoolean());
1702         WHITE_BOX.testSetDontInlineMethod(MyValue3.class.getConstructor(int.class, int.class), rand.nextBoolean());
1703         WHITE_BOX.testSetDontInlineMethod(MyValue8.class.getConstructor(int.class), rand.nextBoolean());
1704         WHITE_BOX.testSetDontInlineMethod(MyValue8.class.getConstructor(int.class, int.class), rand.nextBoolean());
1705         WHITE_BOX.testSetDontInlineMethod(MyValue8.class.getConstructor(int.class, int.class, int.class), rand.nextBoolean());
1706         WHITE_BOX.testSetDontInlineMethod(MyValue9.class.getConstructor(int.class), rand.nextBoolean());
1707         WHITE_BOX.testSetDontInlineMethod(MyValue9.class.getConstructor(int.class, int.class), rand.nextBoolean());
1708         WHITE_BOX.testSetDontInlineMethod(MyValue9.class.getConstructor(int.class, int.class, int.class), rand.nextBoolean());
1709         WHITE_BOX.testSetDontInlineMethod(MyValue9.class.getConstructor(int.class, int.class, int.class, int.class), rand.nextBoolean());
1710         WHITE_BOX.testSetDontInlineMethod(MyValue11.class.getConstructor(int.class), rand.nextBoolean());
1711         WHITE_BOX.testSetDontInlineMethod(MyValue11.class.getConstructor(int.class, int.class, int.class, int.class, int.class), rand.nextBoolean());
1712         int randValue = rand.nextInt(0, 4);
1713         if (randValue > 0) {
1714             // Some variation
1715             WHITE_BOX.testSetDontInlineMethod(MyValue15.class.getConstructor(), rand.nextBoolean());
1716             WHITE_BOX.testSetDontInlineMethod(MyValue15.class.getConstructor(int.class), rand.nextBoolean());
1717             WHITE_BOX.testSetDontInlineMethod(MyValue16.class.getConstructor(), rand.nextBoolean());
1718             WHITE_BOX.testSetDontInlineMethod(MyValue16.class.getConstructor(int.class), rand.nextBoolean());
1719             if (randValue > 1) {
1720                 WHITE_BOX.testSetDontInlineMethod(MyAbstract15.class.getConstructor(), rand.nextBoolean());
1721                 WHITE_BOX.testSetDontInlineMethod(MyAbstract15.class.getConstructor(int.class), rand.nextBoolean());
1722                 WHITE_BOX.testSetDontInlineMethod(MyAbstract16.class.getConstructor(), rand.nextBoolean());
1723                 WHITE_BOX.testSetDontInlineMethod(MyAbstract16.class.getConstructor(int.class), rand.nextBoolean());
1724             }
1725         }
1726 
1727         Integer deoptNum = Integer.getInteger("deoptNum");
1728         Integer deoptNumBig = Integer.getInteger("deoptNumBig");
1729         Integer deoptNumHuge = Integer.getInteger("deoptNumHuge");
1730         if (deoptNum == null) {
1731             deoptNum = rand.nextInt(deopt.length);
1732             System.out.println("deoptNum = " + deoptNum);
1733         }
1734         if (deoptNumBig == null) {
1735             deoptNumBig = rand.nextInt(deoptBig.length);
1736             System.out.println("deoptNumBig = " + deoptNumBig);
1737         }
1738         if (deoptNumHuge == null) {
1739             deoptNumHuge = rand.nextInt(deoptHuge.length);
1740             System.out.println("deoptNumHuge = " + deoptNumHuge);
1741         }
1742         run(0, true);
1743         for (int x = 1; x <= 50_000; ++x) {
1744             if (x == 50_000) {
1745                 // Last iteration, trigger deoptimization
1746                 run(x, true);
1747                 deopt[deoptNum] = true;
1748                 deoptBig[deoptNumBig] = true;
1749                 deoptHuge[deoptNumHuge] = true;
1750                 run(x, true);
1751             } else {
1752                 run(x, false);
1753             }
1754         }
1755     }
1756 
1757     private static void run(int x, boolean doCheck) throws Throwable {
1758         check(test1(x), x, doCheck);
1759         check(test1a(x), x, doCheck);
1760         check(test1b(x), x, doCheck);
1761         check(test2(x), new MyValue1(x), doCheck);
1762         check(test2a(x), new MyValue1a(x), doCheck);
1763         check(test2b(x), new MyValue1b(x), doCheck);
1764         check(test3(10), new MyValue1(10), doCheck);
1765         check(test3a(10), new MyValue1a(10), doCheck);
1766         check(test3b(10), new MyValue1b(10), doCheck);
1767         check(test4(x), new MyValue1(x), doCheck);
1768         check(test4a(x), new MyValue1a(x), doCheck);
1769         check(test4b(x), new MyValue1b(x), doCheck);
1770         check(test5(x), x, doCheck);
1771         check(test5(x), x, doCheck);
1772         check(test6(x), new MyValue2(x), doCheck);
1773         check(test6(x), new MyValue2(x), doCheck);
1774         check(test7(10), new MyValue2(10), doCheck);
1775         check(test8(x), new MyValue2(x), doCheck);
1776         check(test9(x), x, doCheck);
1777         check(test9a(x), x + x, doCheck);
1778         check(test10(x), new MyValue3(x), doCheck);
1779         check(test10a(x), new MyValue3a(x), doCheck);
1780         check(test11(10), new MyValue3(10), doCheck);
1781         check(test11a(10), new MyValue3a(10), doCheck);
1782         check(test12(x), new MyValue3(x), doCheck);
1783         check(test12a(x), new MyValue3a(x), doCheck);
1784         check(test13(x), new MyValue4(x), doCheck);
1785         check(test13a(x), new MyValue4a(x), doCheck);
1786         check(test14(x, (x % 2) == 0), new MyValue5(x, (x % 2) == 0), doCheck);
1787         check(test14a(x, (x % 2) == 0), new MyValue5a(x, (x % 2) == 0), doCheck);
1788         check(test15(x), new MyValue6(x), doCheck);
1789         check(test15a(x), new MyValue6a(x), doCheck);
1790         check(test15b(x), new MyValue6b(x), doCheck);
1791         check(test16(x), new MyValue7(x), doCheck);
1792         check(test16a(x), new MyValue7a(x), doCheck);
1793         check(test16b(x), new MyValue7b(x), doCheck);
1794         check(test17(x), new MyValue8(x), doCheck);
1795         check(test17a(x), new MyValue8a(x), doCheck);
1796         check(test18(x), new MyValue8(x), doCheck);
1797         check(test18a(x), new MyValue8a(x), doCheck);
1798         check(test19(x), new MyValue8(x), doCheck);
1799         check(test19a(x), new MyValue8a(x), doCheck);
1800         check(test19b(x), new MyValue8a(x), doCheck);
1801         check(test20(x), new MyValue9(x), doCheck);
1802         check(test20a(x), new MyValue9a(x), doCheck);
1803         check(test21(x), new MyValue9(x), doCheck);
1804         check(test21a(x), new MyValue9a(x), doCheck);
1805         check(test22(x), new MyValue9(x), doCheck);
1806         check(test22a(x), new MyValue9a(x), doCheck);
1807         check(test23(x), new MyValue9(x), doCheck);
1808         check(test23a(x), new MyValue9a(x), doCheck);
1809         check(test24(x, x % 10), new MyValue10(x, x % 10), doCheck);
1810         check(test24a(x, x % 10), new MyValue10a(x, x % 10), doCheck);
1811         check(test25(x), new MyValue11(x), doCheck);
1812         check(test25a(x), new MyValue11a(x), doCheck);
1813         testObjectCallInsideConstructor(); // Creates a new Object each time - cannot compare on equality.
1814         check(testMultipleAbstract(), new MyValue13(), doCheck);
1815         check(testCallAsConstructorArgument(), new MyValue14(o), doCheck);
1816         check(testBackAndForthAbstract(x), new MyValue15(x), doCheck);
1817         check(testBackAndForthAbstract2(x), new MyValue16(x), doCheck);
1818         check(testMultipleOccurrencesInJVMS(x), new MyValue1(x), doCheck);
1819     }
1820 
1821     private static void check(Object testResult, Object expectedResult, boolean check) {
1822         if (check) {
1823             Asserts.assertEQ(testResult, expectedResult);
1824         }
1825     }
1826 }