1 /*
   2  * Copyright (c) 2020 SAP SE. 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 
  25 /**
  26  * @test
  27  * @bug 8227745
  28  * @summary Collection of test cases that check if optimizations based on escape analysis are reverted just before non-escaping objects escape through JVMTI.
  29  * @author Richard Reingruber richard DOT reingruber AT sap DOT com
  30  *
  31  * @requires ((vm.compMode == "Xmixed") & vm.compiler2.enabled)
  32  * @library /test/lib /test/hotspot/jtreg
  33  *
  34  * @run build TestScaffold VMConnection TargetListener TargetAdapter jdk.test.whitebox.WhiteBox
  35  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
  36  * @run compile -g EATests.java
  37  * @run driver EATests
  38  *                 -XX:+UnlockDiagnosticVMOptions
  39  *                 -Xms256m -Xmx256m
  40  *                 -Xbootclasspath/a:.
  41  *                 -XX:CompileCommand=dontinline,*::dontinline_*
  42  *                 -XX:+WhiteBoxAPI
  43  *                 -Xbatch
  44  *                 -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:+UseBiasedLocking
  45  *                 -XX:+UnlockExperimentalVMOptions -XX:LockingMode=1
  46  * @run driver EATests
  47  *                 -XX:+UnlockDiagnosticVMOptions
  48  *                 -Xms256m -Xmx256m
  49  *                 -Xbootclasspath/a:.
  50  *                 -XX:CompileCommand=dontinline,*::dontinline_*
  51  *                 -XX:+WhiteBoxAPI
  52  *                 -Xbatch
  53  *                 -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:-EliminateLocks -XX:+EliminateNestedLocks -XX:+UseBiasedLocking -XX:-UseOptoBiasInlining
  54  *                 -XX:+UnlockExperimentalVMOptions -XX:LockingMode=1
  55  * @run driver EATests
  56  *                 -XX:+UnlockDiagnosticVMOptions
  57  *                 -Xms256m -Xmx256m
  58  *                 -Xbootclasspath/a:.
  59  *                 -XX:CompileCommand=dontinline,*::dontinline_*
  60  *                 -XX:+WhiteBoxAPI
  61  *                 -Xbatch
  62  *                 -XX:+DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:+UseBiasedLocking
  63  *                 -XX:+UnlockExperimentalVMOptions -XX:LockingMode=1
  64  * @run driver EATests
  65  *                 -XX:+UnlockDiagnosticVMOptions
  66  *                 -Xms256m -Xmx256m
  67  *                 -Xbootclasspath/a:.
  68  *                 -XX:CompileCommand=dontinline,*::dontinline_*
  69  *                 -XX:+WhiteBoxAPI
  70  *                 -Xbatch
  71  *                 -XX:-DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:+UseBiasedLocking
  72  *                 -XX:+UnlockExperimentalVMOptions -XX:LockingMode=1
  73  * @run driver EATests
  74  *                 -XX:+UnlockDiagnosticVMOptions
  75  *                 -Xms256m -Xmx256m
  76  *                 -Xbootclasspath/a:.
  77  *                 -XX:CompileCommand=dontinline,*::dontinline_*
  78  *                 -XX:+WhiteBoxAPI
  79  *                 -Xbatch
  80  *                 -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:-UseBiasedLocking
  81  *                 -XX:+UnlockExperimentalVMOptions -XX:LockingMode=1
  82  * @run driver EATests
  83  *                 -XX:+UnlockDiagnosticVMOptions
  84  *                 -Xms256m -Xmx256m
  85  *                 -Xbootclasspath/a:.
  86  *                 -XX:CompileCommand=dontinline,*::dontinline_*
  87  *                 -XX:+WhiteBoxAPI
  88  *                 -Xbatch
  89  *                 -XX:+DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:-UseBiasedLocking
  90  *                 -XX:+UnlockExperimentalVMOptions -XX:LockingMode=1
  91  * @run driver EATests
  92  *                 -XX:+UnlockDiagnosticVMOptions
  93  *                 -Xms256m -Xmx256m
  94  *                 -Xbootclasspath/a:.
  95  *                 -XX:CompileCommand=dontinline,*::dontinline_*
  96  *                 -XX:+WhiteBoxAPI
  97  *                 -Xbatch
  98  *                 -XX:-DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:-UseBiasedLocking
  99  *                 -XX:+UnlockExperimentalVMOptions -XX:LockingMode=1
 100  *
 101  * @run driver EATests
 102  *                 -XX:+UnlockDiagnosticVMOptions
 103  *                 -Xms256m -Xmx256m
 104  *                 -Xbootclasspath/a:.
 105  *                 -XX:CompileCommand=dontinline,*::dontinline_*
 106  *                 -XX:+WhiteBoxAPI
 107  *                 -Xbatch
 108  *                 -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks
 109  *                 -XX:+UnlockExperimentalVMOptions -XX:LockingMode=2
 110  * @run driver EATests
 111  *                 -XX:+UnlockDiagnosticVMOptions
 112  *                 -Xms256m -Xmx256m
 113  *                 -Xbootclasspath/a:.
 114  *                 -XX:CompileCommand=dontinline,*::dontinline_*
 115  *                 -XX:+WhiteBoxAPI
 116  *                 -Xbatch
 117  *                 -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:-EliminateLocks -XX:+EliminateNestedLocks
 118  *                 -XX:+UnlockExperimentalVMOptions -XX:LockingMode=2
 119  * @run driver EATests
 120  *                 -XX:+UnlockDiagnosticVMOptions
 121  *                 -Xms256m -Xmx256m
 122  *                 -Xbootclasspath/a:.
 123  *                 -XX:CompileCommand=dontinline,*::dontinline_*
 124  *                 -XX:+WhiteBoxAPI
 125  *                 -Xbatch
 126  *                 -XX:+DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks
 127  *                 -XX:+UnlockExperimentalVMOptions -XX:LockingMode=2
 128  * @run driver EATests
 129  *                 -XX:+UnlockDiagnosticVMOptions
 130  *                 -Xms256m -Xmx256m
 131  *                 -Xbootclasspath/a:.
 132  *                 -XX:CompileCommand=dontinline,*::dontinline_*
 133  *                 -XX:+WhiteBoxAPI
 134  *                 -Xbatch
 135  *                 -XX:-DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks
 136  *                 -XX:+UnlockExperimentalVMOptions -XX:LockingMode=2
 137  *
 138  * @comment Excercise -XX:+DeoptimizeObjectsALot. Mostly to prevent bit-rot because the option is meant to stress object deoptimization
 139  *          with non-synthetic workloads.
 140  * @run driver EATests
 141  *                 -XX:+UnlockDiagnosticVMOptions
 142  *                 -Xms256m -Xmx256m
 143  *                 -Xbootclasspath/a:.
 144  *                 -XX:CompileCommand=dontinline,*::dontinline_*
 145  *                 -XX:+WhiteBoxAPI
 146  *                 -Xbatch
 147  *                 -XX:-DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:-UseBiasedLocking
 148  *                 -XX:+IgnoreUnrecognizedVMOptions -XX:+DeoptimizeObjectsALot
 149  *
 150  * @bug 8324881
 151  * @comment Regression test for using the wrong thread when logging during re-locking from deoptimization.
 152  *
 153  * @comment DiagnoseSyncOnValueBasedClasses=2 will cause logging when locking on \@ValueBased objects.
 154  * @run driver EATests
 155  *                 -XX:+UnlockDiagnosticVMOptions
 156  *                 -Xms256m -Xmx256m
 157  *                 -Xbootclasspath/a:.
 158  *                 -XX:CompileCommand=dontinline,*::dontinline_*
 159  *                 -XX:+WhiteBoxAPI
 160  *                 -Xbatch
 161  *                 -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks
 162  *                 -XX:+UnlockExperimentalVMOptions -XX:LockingMode=1
 163  *                 -XX:DiagnoseSyncOnValueBasedClasses=2
 164  *
 165  * @comment Re-lock may inflate monitors when re-locking, which cause monitorinflation trace logging.
 166  * @run driver EATests
 167  *                 -XX:+UnlockDiagnosticVMOptions
 168  *                 -Xms256m -Xmx256m
 169  *                 -Xbootclasspath/a:.
 170  *                 -XX:CompileCommand=dontinline,*::dontinline_*
 171  *                 -XX:+WhiteBoxAPI
 172  *                 -Xbatch
 173  *                 -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks
 174  *                 -XX:+UnlockExperimentalVMOptions -XX:LockingMode=2
 175  *                 -Xlog:monitorinflation=trace:file=monitorinflation.log
 176  *
 177  * @comment Re-lock may race with deflation.
 178  * @run driver EATests
 179  *                 -XX:+UnlockDiagnosticVMOptions
 180  *                 -Xms256m -Xmx256m
 181  *                 -Xbootclasspath/a:.
 182  *                 -XX:CompileCommand=dontinline,*::dontinline_*
 183  *                 -XX:+WhiteBoxAPI
 184  *                 -Xbatch
 185  *                 -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks
 186  *                 -XX:+UnlockExperimentalVMOptions -XX:LockingMode=0
 187  *                 -XX:GuaranteedAsyncDeflationInterval=1000
 188  */
 189 
 190 /**
 191  * @test
 192  * @bug 8227745
 193  *
 194  * @summary This is another configuration of EATests.java to test Graal. Some testcases are expected
 195  *          to fail because Graal does not provide all information about non-escaping objects in
 196  *          scope. These are skipped.
 197  *
 198  * @author Richard Reingruber richard DOT reingruber AT sap DOT com
 199  *
 200  * @requires ((vm.compMode == "Xmixed") & vm.graal.enabled)
 201  *
 202  * @library /test/lib /test/hotspot/jtreg
 203  *
 204  * @run build TestScaffold VMConnection TargetListener TargetAdapter jdk.test.whitebox.WhiteBox
 205  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
 206  * @run compile -g EATests.java
 207  *
 208  * @comment Test with Graal. Some testcases are expected to fail because Graal does not provide all information about non-escaping
 209  *          objects in scope. These are skipped.
 210  * @run driver EATests
 211  *                 -XX:+UnlockDiagnosticVMOptions
 212  *                 -Xms256m -Xmx256m
 213  *                 -Xbootclasspath/a:.
 214  *                 -XX:CompileCommand=dontinline,*::dontinline_*
 215  *                 -XX:+WhiteBoxAPI
 216  *                 -Xbatch
 217  *                 -XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler
 218  */
 219 
 220 import com.sun.jdi.*;
 221 import com.sun.jdi.event.*;
 222 import compiler.testlibrary.CompilerUtils;
 223 import compiler.whitebox.CompilerWhiteBoxTest;
 224 
 225 import java.lang.reflect.Array;
 226 import java.util.Arrays;
 227 import java.util.List;
 228 import java.util.Map;
 229 import java.util.function.Function;
 230 
 231 import jdk.test.lib.Asserts;
 232 import jdk.test.whitebox.WhiteBox;
 233 import jdk.test.whitebox.gc.GC;
 234 
 235 
 236 //
 237 // ANALYZING TEST FAILURES
 238 //
 239 // - Executing just a single test case with the property EATests.onlytestcase.
 240 //
 241 //      Example: java -DEATests.onlytestcase=<test case name> ... EATests
 242 //
 243 // - Interactive execution allows for attaching a native debugger, e.g. gdb
 244 //
 245 //      Example: java -DEATests.interactive=true ... EATests
 246 //
 247 // - Java arguments to the test are passed as vm options to the debuggee:
 248 //
 249 //      Example: java ... EATests -XX:+UseNewCode
 250 //
 251 
 252 
 253 
 254 /////////////////////////////////////////////////////////////////////////////
 255 //
 256 // Shared base class for test cases for both, debugger and debuggee.
 257 //
 258 /////////////////////////////////////////////////////////////////////////////
 259 
 260 class EATestCaseBaseShared {
 261     // In interactive mode we wait for a keypress before every test case.
 262     public static final boolean INTERACTIVE =
 263             System.getProperty("EATests.interactive") != null &&
 264             System.getProperty("EATests.interactive").equals("true");
 265 
 266     // If the property is given, then just the test case it refers to is executed.
 267     // Use it to diagnose test failures.
 268     public static final String RUN_ONLY_TEST_CASE_PROPERTY = "EATests.onlytestcase";
 269     public static final String RUN_ONLY_TEST_CASE = System.getProperty(RUN_ONLY_TEST_CASE_PROPERTY);
 270 
 271     public final String testCaseName;
 272 
 273     public EATestCaseBaseShared() {
 274         String clName = getClass().getName();
 275         int tidx = clName.lastIndexOf("Target");
 276         testCaseName = tidx > 0 ? clName.substring(0, tidx) : clName;
 277     }
 278 
 279     public boolean shouldSkip() {
 280         return EATestCaseBaseShared.RUN_ONLY_TEST_CASE != null &&
 281                EATestCaseBaseShared.RUN_ONLY_TEST_CASE.length() > 0 &&
 282                !testCaseName.equals(EATestCaseBaseShared.RUN_ONLY_TEST_CASE);
 283     }
 284 }
 285 
 286 /////////////////////////////////////////////////////////////////////////////
 287 //
 288 // Target main class, i.e. the program to be debugged.
 289 //
 290 /////////////////////////////////////////////////////////////////////////////
 291 
 292 class EATestsTarget {
 293 
 294     public static void main(String[] args) {
 295         EATestCaseBaseTarget.staticSetUp();
 296         EATestCaseBaseTarget.staticSetUpDone();
 297 
 298         // Materializing test cases, i.e. reallocating objects on the heap
 299         new EAMaterializeLocalVariableUponGetTarget()                                       .run();
 300         new EAGetWithoutMaterializeTarget()                                                 .run();
 301         new EAMaterializeLocalAtObjectReturnTarget()                                        .run();
 302         new EAMaterializeLocalAtObjectPollReturnReturnTarget()                              .run();
 303         new EAMaterializeIntArrayTarget()                                                   .run();
 304         new EAMaterializeLongArrayTarget()                                                  .run();
 305         new EAMaterializeFloatArrayTarget()                                                 .run();
 306         new EAMaterializeDoubleArrayTarget()                                                .run();
 307         new EAMaterializeObjectArrayTarget()                                                .run();
 308         new EAMaterializeObjectWithConstantAndNotConstantValuesTarget()                     .run();
 309         new EAMaterializeObjReferencedBy2LocalsTarget()                                     .run();
 310         new EAMaterializeObjReferencedBy2LocalsAndModifyTarget()                            .run();
 311         new EAMaterializeObjReferencedBy2LocalsInDifferentVirtFramesTarget()                .run();
 312         new EAMaterializeObjReferencedBy2LocalsInDifferentVirtFramesAndModifyTarget()       .run();
 313         new EAMaterializeObjReferencedFromOperandStackTarget()                              .run();
 314         new EAMaterializeLocalVariableUponGetAfterSetIntegerTarget()                        .run();
 315 
 316         // Relocking test cases
 317         new EARelockingSimpleTarget()                                                       .run();
 318         new EARelockingSimple_2Target()                                                     .run();
 319         new EARelockingSimpleWithAccessInOtherThreadTarget()                                .run();
 320         new EARelockingRecursiveTarget()                                                    .run();
 321         new EARelockingNestedInflatedTarget()                                               .run();
 322         new EARelockingNestedInflated_02Target()                                            .run();
 323         new EARelockingNestedInflated_03Target()                                            .run();
 324         new EARelockingArgEscapeLWLockedInCalleeFrameTarget()                               .run();
 325         new EARelockingArgEscapeLWLockedInCalleeFrame_2Target()                             .run();
 326         new EARelockingArgEscapeLWLockedInCalleeFrame_3Target()                             .run();
 327         new EARelockingArgEscapeLWLockedInCalleeFrame_4Target()                             .run();
 328         new EAGetOwnedMonitorsTarget()                                                      .run();
 329         new EAEntryCountTarget()                                                            .run();
 330         new EARelockingObjectCurrentlyWaitingOnTarget()                                     .run();
 331         new EARelockingValueBasedTarget()                                                   .run();
 332 
 333         // Test cases that require deoptimization even though neither
 334         // locks nor allocations are eliminated at the point where
 335         // escape state is changed.
 336         new EADeoptFrameAfterReadLocalObject_01Target()                                     .run();
 337         new EADeoptFrameAfterReadLocalObject_01BTarget()                                    .run();
 338         new EADeoptFrameAfterReadLocalObject_02Target()                                     .run();
 339         new EADeoptFrameAfterReadLocalObject_02BTarget()                                    .run();
 340         new EADeoptFrameAfterReadLocalObject_02CTarget()                                    .run();
 341         new EADeoptFrameAfterReadLocalObject_03Target()                                     .run();
 342 
 343         // PopFrame test cases
 344         new EAPopFrameNotInlinedTarget()                                                    .run();
 345         new EAPopFrameNotInlinedReallocFailureTarget()                                      .run();
 346         new EAPopInlinedMethodWithScalarReplacedObjectsReallocFailureTarget()               .run();
 347 
 348         // ForceEarlyReturn test cases
 349         new EAForceEarlyReturnNotInlinedTarget()                                            .run();
 350         new EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsTarget()              .run();
 351         new EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsReallocFailureTarget().run();
 352 
 353         // Instances of ReferenceType
 354         new EAGetInstancesOfReferenceTypeTarget()                                           .run();
 355     }
 356 }
 357 
 358 /////////////////////////////////////////////////////////////////////////////
 359 //
 360 // Debugger main class
 361 //
 362 /////////////////////////////////////////////////////////////////////////////
 363 
 364 public class EATests extends TestScaffold {
 365 
 366     public TargetVMOptions targetVMOptions;
 367     public ThreadReference targetMainThread;
 368 
 369     EATests(String args[]) {
 370         super(args);
 371     }
 372 
 373     public static void main(String[] args) throws Exception {
 374         if (EATestCaseBaseShared.RUN_ONLY_TEST_CASE != null) {
 375             args = Arrays.copyOf(args, args.length + 1);
 376             args[args.length - 1] = "-D" + EATestCaseBaseShared.RUN_ONLY_TEST_CASE_PROPERTY + "=" + EATestCaseBaseShared.RUN_ONLY_TEST_CASE;
 377         }
 378         new EATests(args).startTests();
 379     }
 380 
 381     public static class TargetVMOptions {
 382 
 383         public final boolean UseJVMCICompiler;
 384         public final boolean EliminateAllocations;
 385         public final boolean DeoptimizeObjectsALot;
 386         public final boolean DoEscapeAnalysis;
 387         public final boolean ZGCIsSelected;
 388         public final boolean StressReflectiveCode;
 389 
 390         public TargetVMOptions(EATests env, ClassType testCaseBaseTargetClass) {
 391             Value val;
 392             val = testCaseBaseTargetClass.getValue(testCaseBaseTargetClass.fieldByName("DoEscapeAnalysis"));
 393             DoEscapeAnalysis = ((PrimitiveValue) val).booleanValue();
 394             // Escape analysis is a prerequisite for scalar replacement (EliminateAllocations)
 395             val = testCaseBaseTargetClass.getValue(testCaseBaseTargetClass.fieldByName("EliminateAllocations"));
 396             EliminateAllocations = DoEscapeAnalysis && ((PrimitiveValue) val).booleanValue();
 397             val = testCaseBaseTargetClass.getValue(testCaseBaseTargetClass.fieldByName("DeoptimizeObjectsALot"));
 398             DeoptimizeObjectsALot = ((PrimitiveValue) val).booleanValue();
 399             val = testCaseBaseTargetClass.getValue(testCaseBaseTargetClass.fieldByName("UseJVMCICompiler"));
 400             UseJVMCICompiler = ((PrimitiveValue) val).booleanValue();
 401             val = testCaseBaseTargetClass.getValue(testCaseBaseTargetClass.fieldByName("ZGCIsSelected"));
 402             ZGCIsSelected = ((PrimitiveValue) val).booleanValue();
 403             val = testCaseBaseTargetClass.getValue(testCaseBaseTargetClass.fieldByName("StressReflectiveCode"));
 404             StressReflectiveCode = ((PrimitiveValue) val).booleanValue();
 405         }
 406 
 407     }
 408 
 409     // Execute known test cases
 410     protected void runTests() throws Exception {
 411         String targetProgName = EATestsTarget.class.getName();
 412         msg("starting to main method in class " +  targetProgName);
 413         startToMain(targetProgName);
 414         msg("resuming to EATestCaseBaseTarget.staticSetUpDone()V");
 415         targetMainThread = resumeTo("EATestCaseBaseTarget", "staticSetUpDone", "()V").thread();
 416         Location loc = targetMainThread.frame(0).location();
 417         Asserts.assertEQ("staticSetUpDone", loc.method().name());
 418 
 419         targetVMOptions = new TargetVMOptions(this, (ClassType) loc.declaringType());
 420 
 421         // Materializing test cases, i.e. reallocating objects on the heap
 422         new EAMaterializeLocalVariableUponGet()                                       .run(this);
 423         new EAGetWithoutMaterialize()                                                 .run(this);
 424         new EAMaterializeLocalAtObjectReturn()                                        .run(this);
 425         new EAMaterializeLocalAtObjectPollReturnReturn()                              .run(this);
 426         new EAMaterializeIntArray()                                                   .run(this);
 427         new EAMaterializeLongArray()                                                  .run(this);
 428         new EAMaterializeFloatArray()                                                 .run(this);
 429         new EAMaterializeDoubleArray()                                                .run(this);
 430         new EAMaterializeObjectArray()                                                .run(this);
 431         new EAMaterializeObjectWithConstantAndNotConstantValues()                     .run(this);
 432         new EAMaterializeObjReferencedBy2Locals()                                     .run(this);
 433         new EAMaterializeObjReferencedBy2LocalsAndModify()                            .run(this);
 434         new EAMaterializeObjReferencedBy2LocalsInDifferentVirtFrames()                .run(this);
 435         new EAMaterializeObjReferencedBy2LocalsInDifferentVirtFramesAndModify()       .run(this);
 436         new EAMaterializeObjReferencedFromOperandStack()                              .run(this);
 437         new EAMaterializeLocalVariableUponGetAfterSetInteger()                        .run(this);
 438 
 439         // Relocking test cases
 440         new EARelockingSimple()                                                       .run(this);
 441         new EARelockingSimple_2()                                                     .run(this);
 442         new EARelockingSimpleWithAccessInOtherThread()                                .run(this);
 443         new EARelockingRecursive()                                                    .run(this);
 444         new EARelockingNestedInflated()                                               .run(this);
 445         new EARelockingNestedInflated_02()                                            .run(this);
 446         new EARelockingNestedInflated_03()                                            .run(this);
 447         new EARelockingArgEscapeLWLockedInCalleeFrame()                               .run(this);
 448         new EARelockingArgEscapeLWLockedInCalleeFrame_2()                             .run(this);
 449         new EARelockingArgEscapeLWLockedInCalleeFrame_3()                             .run(this);
 450         new EARelockingArgEscapeLWLockedInCalleeFrame_4()                             .run(this);
 451         new EAGetOwnedMonitors()                                                      .run(this);
 452         new EAEntryCount()                                                            .run(this);
 453         new EARelockingObjectCurrentlyWaitingOn()                                     .run(this);
 454         new EARelockingValueBased()                                                   .run(this);
 455 
 456         // Test cases that require deoptimization even though neither
 457         // locks nor allocations are eliminated at the point where
 458         // escape state is changed.
 459         new EADeoptFrameAfterReadLocalObject_01()                                     .run(this);
 460         new EADeoptFrameAfterReadLocalObject_01B()                                    .run(this);
 461         new EADeoptFrameAfterReadLocalObject_02()                                     .run(this);
 462         new EADeoptFrameAfterReadLocalObject_02B()                                    .run(this);
 463         new EADeoptFrameAfterReadLocalObject_02C()                                    .run(this);
 464         new EADeoptFrameAfterReadLocalObject_03()                                     .run(this);
 465 
 466         // PopFrame test cases
 467         new EAPopFrameNotInlined()                                                    .run(this);
 468         new EAPopFrameNotInlinedReallocFailure()                                      .run(this);
 469         new EAPopInlinedMethodWithScalarReplacedObjectsReallocFailure()               .run(this);
 470 
 471         // ForceEarlyReturn test cases
 472         new EAForceEarlyReturnNotInlined()                                            .run(this);
 473         new EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjects()              .run(this);
 474         new EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsReallocFailure().run(this);
 475 
 476         // Instances of ReferenceType
 477         new EAGetInstancesOfReferenceType()                                           .run(this);
 478 
 479         // resume the target listening for events
 480         listenUntilVMDisconnect();
 481     }
 482 
 483     // Print a Message
 484     public void msg(String m) {
 485         System.out.println();
 486         System.out.println("###(Debugger) " + m);
 487         System.out.println();
 488     }
 489 
 490     // Highlighted message.
 491     public void msgHL(String m) {
 492         System.out.println();
 493         System.out.println();
 494         System.out.println("##########################################################");
 495         System.out.println("### " + m);
 496         System.out.println("### ");
 497         System.out.println();
 498         System.out.println();
 499     }
 500 }
 501 
 502 /////////////////////////////////////////////////////////////////////////////
 503 //
 504 // Base class for debugger side of test cases.
 505 //
 506 /////////////////////////////////////////////////////////////////////////////
 507 
 508 abstract class EATestCaseBaseDebugger  extends EATestCaseBaseShared {
 509 
 510     protected EATests env;
 511 
 512     public ObjectReference testCase;
 513 
 514     public static final String TARGET_TESTCASE_BASE_NAME = EATestCaseBaseTarget.class.getName();
 515 
 516     public static final String XYVAL_NAME = XYVal.class.getName();
 517 
 518     public abstract void runTestCase() throws Exception;
 519 
 520     @Override
 521     public boolean shouldSkip() {
 522         // Skip if StressReflectiveCode because it effectively disables escape analysis
 523         return super.shouldSkip() || env.targetVMOptions.StressReflectiveCode;
 524     }
 525 
 526     public void run(EATests env) {
 527         this.env = env;
 528         if (shouldSkip()) {
 529             msg("skipping " + testCaseName);
 530             return;
 531         }
 532         try {
 533             msgHL("Executing test case " + getClass().getName());
 534             env.testFailed = false;
 535 
 536             if (INTERACTIVE)
 537                 env.waitForInput();
 538 
 539             resumeToWarmupDone();
 540             runTestCase();
 541             Asserts.assertTrue(env.targetMainThread.isSuspended(), "must be suspended after the testcase");
 542             resumeToTestCaseDone();
 543             checkPostConditions();
 544         } catch (Exception e) {
 545             Asserts.fail("Unexpected exception in test case " + getClass().getName(), e);
 546         }
 547     }
 548 
 549     /**
 550      * Set a breakpoint in the given method and resume all threads. The
 551      * breakpoint is configured to suspend just the thread that reaches it
 552      * instead of all threads. This is important when running with graal.
 553      */
 554     public BreakpointEvent resumeTo(String clsName, String methodName, String signature) {
 555         boolean suspendThreadOnly = true;
 556         return env.resumeTo(clsName, methodName, signature, suspendThreadOnly);
 557     }
 558 
 559     public void resumeToWarmupDone() throws Exception {
 560         msg("resuming to " + TARGET_TESTCASE_BASE_NAME + ".warmupDone()V");
 561         resumeTo(TARGET_TESTCASE_BASE_NAME, "warmupDone", "()V");
 562         testCase = env.targetMainThread.frame(0).thisObject();
 563     }
 564 
 565     public void resumeToTestCaseDone() {
 566         msg("resuming to " + TARGET_TESTCASE_BASE_NAME + ".testCaseDone()V");
 567         resumeTo(TARGET_TESTCASE_BASE_NAME, "testCaseDone", "()V");
 568     }
 569 
 570     public void checkPostConditions() throws Exception {
 571         Asserts.assertFalse(env.getExceptionCaught(), "Uncaught exception in Debuggee");
 572 
 573         String testName = getClass().getName();
 574         if (!env.testFailed) {
 575             env.println(testName  + ": passed");
 576         } else {
 577             throw new Exception(testName + ": failed");
 578         }
 579     }
 580 
 581     public void printStack(ThreadReference thread) throws Exception {
 582         msg("Debuggee Stack:");
 583         List<StackFrame> stack_frames = thread.frames();
 584         int i = 0;
 585         for (StackFrame ff : stack_frames) {
 586             System.out.println("frame[" + i++ +"]: " + ff.location().method() + " (bci:" + ff.location().codeIndex() + ")");
 587         }
 588     }
 589 
 590     public void msg(String m) {
 591         env.msg(m);
 592     }
 593 
 594     public void msgHL(String m) {
 595         env.msgHL(m);
 596     }
 597 
 598     // See Field Descriptors in The Java Virtual Machine Specification
 599     // (https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html#jvms-4.3.2)
 600     enum FD {
 601         I, // int
 602         J, // long
 603         F, // float
 604         D, // double
 605     }
 606 
 607     // Map field descriptor to jdi type string
 608     public static final Map<FD, String> FD2JDIArrType = Map.of(FD.I, "int[]", FD.J, "long[]", FD.F, "float[]", FD.D, "double[]");
 609 
 610     // Map field descriptor to PrimitiveValue getter
 611     public static final Function<PrimitiveValue, Integer> v2I = PrimitiveValue::intValue;
 612     public static final Function<PrimitiveValue, Long>    v2J = PrimitiveValue::longValue;
 613     public static final Function<PrimitiveValue, Float>   v2F = PrimitiveValue::floatValue;
 614     public static final Function<PrimitiveValue, Double>  v2D = PrimitiveValue::doubleValue;
 615     Map<FD, Function<PrimitiveValue, ?>> FD2getter = Map.of(FD.I, v2I, FD.J, v2J, FD.F, v2F, FD.D, v2D);
 616 
 617     /**
 618      * Retrieve array of primitive values referenced by a local variable in target and compare with
 619      * an array of expected values.
 620      * @param frame Frame in the target holding the local variable
 621      * @param lName Name of the local variable referencing the array to be retrieved
 622      * @param desc Array element type given as field descriptor.
 623      * @param expVals Array of expected values.
 624      * @throws Exception
 625      */
 626     protected void checkLocalPrimitiveArray(StackFrame frame, String lName, FD desc, Object expVals) throws Exception {
 627         String lType = FD2JDIArrType.get(desc);
 628         Asserts.assertNotNull(lType, "jdi type not found");
 629         Asserts.assertEQ(EATestCaseBaseTarget.TESTMETHOD_DEFAULT_NAME, frame .location().method().name());
 630         List<LocalVariable> localVars = frame.visibleVariables();
 631         msg("Check if the local array variable '" + lName  + "' in " + EATestCaseBaseTarget.TESTMETHOD_DEFAULT_NAME + " has the expected elements: ");
 632         boolean found = false;
 633         for (LocalVariable lv : localVars) {
 634             if (lv.name().equals(lName)) {
 635                 found  = true;
 636                 Value lVal = frame.getValue(lv);
 637                 Asserts.assertNotNull(lVal);
 638                 Asserts.assertEQ(lVal.type().name(), lType);
 639                 ArrayReference aRef = (ArrayReference) lVal;
 640                 Asserts.assertEQ(3, aRef.length());
 641                 // now check the elements
 642                 for (int i = 0; i < aRef.length(); i++) {
 643                     Object actVal = FD2getter.get(desc).apply((PrimitiveValue)aRef.getValue(i));
 644                     Object expVal = Array.get(expVals, i);
 645                     Asserts.assertEQ(expVal, actVal, "checking element at index " + i);
 646                 }
 647             }
 648         }
 649         Asserts.assertTrue(found);
 650         msg("OK.");
 651     }
 652 
 653     /**
 654      * Retrieve array of objects referenced by a local variable in target and compare with an array
 655      * of expected values.
 656      * @param frame Frame in the target holding the local variable
 657      * @param lName Name of the local variable referencing the array to be retrieved
 658      * @param lType Local type, e.g. java.lang.Long[]
 659      * @param expVals Array of expected values.
 660      * @throws Exception
 661      */
 662     protected void checkLocalObjectArray(StackFrame frame, String lName, String lType, ObjectReference[] expVals) throws Exception {
 663         Asserts.assertEQ(EATestCaseBaseTarget.TESTMETHOD_DEFAULT_NAME, frame .location().method().name());
 664         List<LocalVariable> localVars = frame.visibleVariables();
 665         msg("Check if the local array variable '" + lName  + "' in " + EATestCaseBaseTarget.TESTMETHOD_DEFAULT_NAME + " has the expected elements: ");
 666         boolean found = false;
 667         for (LocalVariable lv : localVars) {
 668             if (lv.name().equals(lName)) {
 669                 found  = true;
 670                 Value lVal = frame.getValue(lv);
 671                 Asserts.assertNotNull(lVal);
 672                 Asserts.assertEQ(lType, lVal.type().name());
 673                 ArrayReference aRef = (ArrayReference) lVal;
 674                 Asserts.assertEQ(3, aRef.length());
 675                 // now check the elements
 676                 for (int i = 0; i < aRef.length(); i++) {
 677                     ObjectReference actVal = (ObjectReference)aRef.getValue(i);
 678                     Asserts.assertSame(expVals[i], actVal, "checking element at index " + i);
 679                 }
 680             }
 681         }
 682         Asserts.assertTrue(found);
 683         msg("OK.");
 684     }
 685 
 686     /**
 687      * Retrieve a reference held by a local variable in the given frame. Check if the frame's method
 688      * is the expected method if the retrieved local value has the expected type and is not null.
 689      * @param frame The frame to retrieve the local variable value from.
 690      * @param expectedMethodName The name of the frames method should match the expectedMethodName.
 691      * @param lName The name of the local variable which is read.
 692      * @param expectedType Is the expected type of the object referenced by the local variable.
 693      * @return
 694      * @throws Exception
 695      */
 696     protected ObjectReference getLocalRef(StackFrame frame, String expectedMethodName, String lName, String expectedType) throws Exception {
 697         Asserts.assertEQ(expectedMethodName, frame.location().method().name());
 698         List<LocalVariable> localVars = frame.visibleVariables();
 699         msg("Get and check local variable '" + lName + "' in " + expectedMethodName);
 700         ObjectReference lRef = null;
 701         for (LocalVariable lv : localVars) {
 702             if (lv.name().equals(lName)) {
 703                 Value lVal = frame.getValue(lv);
 704                 Asserts.assertNotNull(lVal);
 705                 Asserts.assertEQ(expectedType, lVal.type().name());
 706                 lRef = (ObjectReference) lVal;
 707                 break;
 708             }
 709         }
 710         Asserts.assertNotNull(lRef, "Local variable '" + lName + "' not found");
 711         msg("OK.");
 712         return lRef;
 713     }
 714 
 715     /**
 716      * Retrieve a reference held by a local variable in the given frame. Check if the frame's method
 717      * matches {@link EATestCaseBaseTarget#TESTMETHOD_DEFAULT_NAME} if the retrieved local value has
 718      * the expected type and is not null.
 719      * @param frame The frame to retrieve the local variable value from.
 720      * @param expectedMethodName The name of the frames method should match the expectedMethodName.
 721      * @param lName The name of the local variable which is read.
 722      * @param expectedType Is the expected type of the object referenced by the local variable.
 723      * @return
 724      * @throws Exception
 725      */
 726     protected ObjectReference getLocalRef(StackFrame frame, String lType, String lName) throws Exception {
 727         return getLocalRef(frame, EATestCaseBaseTarget.TESTMETHOD_DEFAULT_NAME, lName, lType);
 728     }
 729 
 730     /**
 731      * Set the value of a local variable in the given frame. Check if the frame's method is the expected method.
 732      * @param frame The frame holding the local variable.
 733      * @param expectedMethodName The expected name of the frame's method.
 734      * @param lName The name of the local variable to change.
 735      * @param val The new value of the local variable.
 736      * @throws Exception
 737      */
 738     public void setLocal(StackFrame frame, String expectedMethodName, String lName, Value val) throws Exception {
 739         Asserts.assertEQ(expectedMethodName, frame.location().method().name());
 740         List<LocalVariable> localVars = frame.visibleVariables();
 741         msg("Set local variable '" + lName + "' = " + val + " in " + expectedMethodName);
 742         for (LocalVariable lv : localVars) {
 743             if (lv.name().equals(lName)) {
 744                 frame.setValue(lv, val);
 745                 break;
 746             }
 747         }
 748         msg("OK.");
 749     }
 750 
 751     /**
 752      * Set the value of a local variable in the given frame. Check if the frame's method matches
 753      * {@link EATestCaseBaseTarget#TESTMETHOD_DEFAULT_NAME}.
 754      * @param frame The frame holding the local variable.
 755      * @param expectedMethodName The expected name of the frame's method.
 756      * @param lName The name of the local variable to change.
 757      * @param val The new value of the local variable.
 758      * @throws Exception
 759      */
 760     public void setLocal(StackFrame frame, String lName, Value val) throws Exception {
 761         setLocal(frame, EATestCaseBaseTarget.TESTMETHOD_DEFAULT_NAME, lName, val);
 762     }
 763 
 764     /**
 765      * Check if a field has the expected primitive value.
 766      * @param o Object holding the field.
 767      * @param desc Field descriptor.
 768      * @param fName Field name
 769      * @param expVal Expected primitive value
 770      * @throws Exception
 771      */
 772     protected void checkPrimitiveField(ObjectReference o, FD desc, String fName, Object expVal) throws Exception {
 773         msg("check field " + fName);
 774         ReferenceType rt = o.referenceType();
 775         Field fld = rt.fieldByName(fName);
 776         Value val = o.getValue(fld);
 777         Object actVal = FD2getter.get(desc).apply((PrimitiveValue) val);
 778         Asserts.assertEQ(expVal, actVal, "field '" + fName + "' has unexpected value.");
 779         msg("ok");
 780     }
 781 
 782     /**
 783      * Check if a field references the expected object.
 784      * @param obj Object holding the field.
 785      * @param fName Field name
 786      * @param expVal Object expected to be referenced by the field
 787      * @throws Exception
 788      */
 789     protected void checkObjField(ObjectReference obj, String fName, ObjectReference expVal) throws Exception {
 790         msg("check field " + fName);
 791         ReferenceType rt = obj.referenceType();
 792         Field fld = rt.fieldByName(fName);
 793         Value actVal = obj.getValue(fld);
 794         Asserts.assertEQ(expVal, actVal, "field '" + fName + "' has unexpected value.");
 795         msg("ok");
 796     }
 797 
 798     protected void setField(ObjectReference obj, String fName, Value val) throws Exception {
 799         msg("set field " + fName + " = " + val);
 800         ReferenceType rt = obj.referenceType();
 801         Field fld = rt.fieldByName(fName);
 802         obj.setValue(fld, val);
 803         msg("ok");
 804     }
 805 
 806     protected Value getField(ObjectReference obj, String fName) throws Exception {
 807         msg("get field " + fName);
 808         ReferenceType rt = obj.referenceType();
 809         Field fld = rt.fieldByName(fName);
 810         Value val = obj.getValue(fld);
 811         msg("result : " + val);
 812         return val;
 813     }
 814 
 815     /**
 816      * Free the memory consumed in the target by {@link EATestCaseBaseTarget#consumedMemory}
 817      * @throws Exception
 818      */
 819     public void freeAllMemory() throws Exception {
 820         msg("free consumed memory");
 821         setField(testCase, "consumedMemory", null);
 822     }
 823 
 824     /**
 825      * @return The value of {@link EATestCaseBaseTarget#targetIsInLoop}. The target must set that field to true as soon as it
 826      *         enters the endless loop.
 827      * @throws Exception
 828      */
 829     public boolean targetHasEnteredEndlessLoop() throws Exception {
 830         Value v = getField(testCase, "targetIsInLoop");
 831         return ((PrimitiveValue) v).booleanValue();
 832     }
 833 
 834     /**
 835      * Poll {@link EATestCaseBaseTarget#targetIsInLoop} and return if it is found to be true.
 836      * @throws Exception
 837      */
 838     public void waitUntilTargetHasEnteredEndlessLoop() throws Exception {
 839         while(!targetHasEnteredEndlessLoop()) {
 840             msg("Target has not yet entered the loop. Sleep 200ms.");
 841             try { Thread.sleep(200); } catch (InterruptedException e) { /*ignore */ }
 842         }
 843     }
 844 
 845     /**
 846      * Set {@link EATestCaseBaseTarget#doLoop} to <code>false</code>. This will allow the target to
 847      * leave the endless loop.
 848      * @throws Exception
 849      */
 850     public void terminateEndlessLoop() throws Exception {
 851         msg("terminate loop");
 852         setField(testCase, "doLoop", env.vm().mirrorOf(false));
 853     }
 854 }
 855 
 856 /////////////////////////////////////////////////////////////////////////////
 857 //
 858 // Base class for debuggee side of test cases.
 859 //
 860 /////////////////////////////////////////////////////////////////////////////
 861 
 862 abstract class EATestCaseBaseTarget extends EATestCaseBaseShared implements Runnable {
 863 
 864     /**
 865      * The target must set that field to true as soon as it enters the endless loop.
 866      */
 867     public volatile boolean targetIsInLoop;
 868 
 869     /**
 870      * Used for busy loops. See {@link #dontinline_endlessLoop()}.
 871      */
 872     public volatile long loopCount;
 873 
 874     /**
 875      * Used in {@link EATestCaseBaseDebugger#terminateEndlessLoop()} to signal target to leave the endless loop.
 876      */
 877     public volatile boolean doLoop;
 878 
 879     public long checkSum;
 880 
 881     public static final String TESTMETHOD_DEFAULT_NAME = "dontinline_testMethod";
 882 
 883     public static final WhiteBox WB = WhiteBox.getWhiteBox();
 884 
 885     public static boolean unbox(Boolean value, boolean dflt) {
 886         return value == null ? dflt : value;
 887     }
 888 
 889     // Some of the fields are only read by the debugger
 890     public static final boolean UseJVMCICompiler = unbox(WB.getBooleanVMFlag("UseJVMCICompiler"), false);
 891     public static final boolean DoEscapeAnalysis = unbox(WB.getBooleanVMFlag("DoEscapeAnalysis"), UseJVMCICompiler);
 892     public static final boolean EliminateAllocations = unbox(WB.getBooleanVMFlag("EliminateAllocations"), UseJVMCICompiler);
 893     public static final boolean DeoptimizeObjectsALot = WB.getBooleanVMFlag("DeoptimizeObjectsALot");
 894     public static final long BiasedLockingBulkRebiasThreshold = WB.getIntxVMFlag("BiasedLockingBulkRebiasThreshold");
 895     public static final long BiasedLockingBulkRevokeThreshold = WB.getIntxVMFlag("BiasedLockingBulkRevokeThreshold");
 896     public static final boolean ZGCIsSelected = GC.Z.isSelected();
 897     public static final boolean StressReflectiveCode = unbox(WB.getBooleanVMFlag("StressReflectiveCode"), false);
 898 
 899     public String testMethodName;
 900     public int testMethodDepth;
 901 
 902     // Results produced by dontinline_testMethod()
 903     public int  iResult;
 904     public long lResult;
 905     public float  fResult;
 906     public double dResult;
 907 
 908 
 909     public boolean warmupDone;
 910 
 911     public volatile Object biasToBeRevoked;
 912 
 913     // an object with an inflated monitor
 914     public static XYVal inflatedLock;
 915     public static Thread  inflatorThread;
 916     public static boolean inflatedLockIsPermanentlyInflated;
 917 
 918     public static int    NOT_CONST_1I = 1;
 919     public static long   NOT_CONST_1L = 1L;
 920     public static float  NOT_CONST_1F = 1.1F;
 921     public static double NOT_CONST_1D = 1.1D;
 922 
 923     public static          Long NOT_CONST_1_OBJ = Long.valueOf(1);
 924 
 925 
 926     public static final    Long CONST_2_OBJ     = Long.valueOf(2);
 927     public static final    Long CONST_3_OBJ     = Long.valueOf(3);
 928 
 929     @Override
 930     public boolean shouldSkip() {
 931         // Skip if StressReflectiveCode because it effectively disables escape analysis
 932         return super.shouldSkip() || StressReflectiveCode;
 933     }
 934 
 935     /**
 936      * Main driver of a test case.
 937      * <ul>
 938      * <li> Skips test case if not selected (see {@link EATestCaseBaseShared#RUN_ONLY_TEST_CASE}
 939      * <li> Call {@link #setUp()}
 940      * <li> warm-up and compile {@link #dontinline_testMethod()} (see {@link #compileTestMethod()}
 941      * <li> calling {@link #dontinline_testMethod()}
 942      * <li> checking the result (see {@link #checkResult()}
 943      * <ul>
 944      */
 945     public void run() {
 946         try {
 947             if (shouldSkip()) {
 948                 msg("skipping " + testCaseName);
 949                 return;
 950             }
 951             setUp();
 952             msg(testCaseName + " is up and running.");
 953             compileTestMethod();
 954             msg(testCaseName + " warmup done.");
 955             warmupDone();
 956             checkCompLevel();
 957             dontinline_testMethod();
 958             checkResult();
 959             msg(testCaseName + " done.");
 960             testCaseDone();
 961         } catch (Exception e) {
 962             Asserts.fail("Caught unexpected exception", e);
 963         }
 964     }
 965 
 966     public static void staticSetUp() {
 967         inflatedLock = new XYVal(1, 1);
 968         synchronized (inflatedLock) {
 969             inflatorThread = new Thread("Lock Inflator (test thread)") {
 970                 @Override
 971                 public void run() {
 972                     synchronized (inflatedLock) {
 973                         inflatedLockIsPermanentlyInflated = true;
 974                         inflatedLock.notify(); // main thread
 975                         while (true) {
 976                             try {
 977                                 // calling wait() on a monitor will cause inflation into a heavy monitor
 978                                 inflatedLock.wait();
 979                             } catch (InterruptedException e) { /* ignored */ }
 980                         }
 981                     }
 982                 }
 983             };
 984             inflatorThread.setDaemon(true);
 985             inflatorThread.start();
 986 
 987             // wait until the lock is permanently inflated by the inflatorThread
 988             while(!inflatedLockIsPermanentlyInflated) {
 989                 try {
 990                     inflatedLock.wait(); // until inflated
 991                 } catch (InterruptedException e1) { /* ignored */ }
 992             }
 993         }
 994     }
 995 
 996     // Debugger will set breakpoint here to sync with target.
 997     public static void staticSetUpDone() {
 998     }
 999 
1000     public void setUp() {
1001         testMethodDepth = 1;
1002         testMethodName = TESTMETHOD_DEFAULT_NAME;
1003     }
1004 
1005     public abstract void dontinline_testMethod() throws Exception;
1006 
1007     public int dontinline_brkpt_iret() {
1008         dontinline_brkpt();
1009         return 42;
1010     }
1011 
1012     /**
1013      * It is a common protocol to have the debugger set a breakpoint in this method and have {@link
1014      * #dontinline_testMethod()} call it and then perform some test actions on debugger side.
1015      * After that it is checked if a frame of {@link #dontinline_testMethod()} is found at the
1016      * expected depth on stack and if it is (not) marked for deoptimization as expected.
1017      */
1018     public void dontinline_brkpt() {
1019         // will set breakpoint here after warmup
1020         if (warmupDone) {
1021             // check if test method is at expected depth
1022             StackTraceElement[] frames = Thread.currentThread().getStackTrace();
1023             int stackTraceDepth = testMethodDepth + 1; // ignore java.lang.Thread.getStackTrace()
1024             Asserts.assertEQ(testMethodName, frames[stackTraceDepth].getMethodName(),
1025                     testCaseName + ": test method not found at depth " + testMethodDepth);
1026             // check if the frame is (not) deoptimized as expected
1027             if (!DeoptimizeObjectsALot) {
1028                 if (testFrameShouldBeDeoptimized()) {
1029                     Asserts.assertTrue(WB.isFrameDeoptimized(testMethodDepth+1),
1030                             testCaseName + ": expected test method frame at depth " + testMethodDepth + " to be deoptimized");
1031                 } else {
1032                     Asserts.assertFalse(WB.isFrameDeoptimized(testMethodDepth+1),
1033                             testCaseName + ": expected test method frame at depth " + testMethodDepth + " not to be deoptimized");
1034                 }
1035             }
1036         }
1037     }
1038 
1039     /**
1040      * Some test cases run busy endless loops by initializing {@link #loopCount}
1041      * to {@link Long#MAX_VALUE} after warm-up and then counting down to 0 in their main test method.
1042      * During warm-up {@link #loopCount} is initialized to a small value.
1043      */
1044     public long dontinline_endlessLoop() {
1045         long cs = checkSum;
1046         doLoop = true;
1047         while (loopCount-- > 0 && doLoop) {
1048             targetIsInLoop = true;
1049             checkSum += checkSum % ++cs;
1050         }
1051         loopCount = 3;
1052         targetIsInLoop = false;
1053         return checkSum;
1054     }
1055 
1056     public boolean testFrameShouldBeDeoptimized() {
1057         return DoEscapeAnalysis;
1058     }
1059 
1060     public void warmupDone() {
1061         warmupDone = true;
1062     }
1063 
1064     // Debugger will set breakpoint here to sync with target.
1065     public void testCaseDone() {
1066     }
1067 
1068     public void compileTestMethod() throws Exception {
1069         int callCount = CompilerWhiteBoxTest.THRESHOLD;
1070         while (callCount-- > 0) {
1071             dontinline_testMethod();
1072         }
1073     }
1074 
1075     public void checkCompLevel() {
1076         java.lang.reflect.Method m = null;
1077         try {
1078             m = getClass().getMethod(TESTMETHOD_DEFAULT_NAME);
1079         } catch (NoSuchMethodException | SecurityException e) {
1080             Asserts.fail("could not check compilation level of", e);
1081         }
1082         int highestLevel = CompilerUtils.getMaxCompilationLevel();
1083         int compLevel = WB.getMethodCompilationLevel(m);
1084         if (!UseJVMCICompiler) {
1085             Asserts.assertEQ(highestLevel, compLevel,
1086                              m + " not on expected compilation level");
1087         } else {
1088             // Background compilation (-Xbatch) will block a thread with timeout
1089             // (see CompileBroker::wait_for_jvmci_completion()). Therefore it is
1090             // possible to reach here before the main test method is compiled.
1091             // In that case we wait for it to be compiled.
1092             while (compLevel != highestLevel) {
1093                 msg(TESTMETHOD_DEFAULT_NAME + " is compiled on level " + compLevel +
1094                     ". Wait until highes level (" + highestLevel + ") is reached.");
1095                 try {
1096                     Thread.sleep(200);
1097                 } catch (InterruptedException e) { /* ignored */ }
1098                 compLevel = WB.getMethodCompilationLevel(m);
1099             }
1100         }
1101     }
1102 
1103     // to be overridden as appropriate
1104     public int getExpectedIResult() {
1105         return 0;
1106     }
1107 
1108     // to be overridden as appropriate
1109     public long getExpectedLResult() {
1110         return 0;
1111     }
1112 
1113     // to be overridden as appropriate
1114     public float getExpectedFResult() {
1115         return 0f;
1116     }
1117 
1118     // to be overridden as appropriate
1119     public double getExpectedDResult() {
1120         return 0d;
1121     }
1122 
1123     private void checkResult() {
1124         Asserts.assertEQ(getExpectedIResult(), iResult, "checking iResult");
1125         Asserts.assertEQ(getExpectedLResult(), lResult, "checking lResult");
1126         Asserts.assertEQ(getExpectedFResult(), fResult, "checking fResult");
1127         Asserts.assertEQ(getExpectedDResult(), dResult, "checking dResult");
1128     }
1129 
1130     public void msg(String m) {
1131         System.out.println();
1132         System.out.println("###(Target) " + m);
1133         System.out.println();
1134     }
1135 
1136     // The object passed will be ArgEscape if it was NoEscape before.
1137     public final void dontinline_make_arg_escape(XYVal xy) {
1138     }
1139 
1140     /**
1141      * Call a method indirectly using reflection. The indirection is a limit for escape
1142      * analysis in the sense that the VM need not search beyond for frames that might have
1143      * an object being read by an JVMTI agent as ArgEscape.
1144      * @param receiver The receiver object of the call.
1145      * @param methodName The name of the method to be called.
1146      */
1147     public final void dontinline_call_with_entry_frame(Object receiver, String methodName) {
1148         Asserts.assertTrue(warmupDone, "We want to take the slow path through jni, so don't call in warmup");
1149 
1150         Class<?> cls = receiver.getClass();
1151         Class<?>[] none = {};
1152 
1153         java.lang.reflect.Method m;
1154         try {
1155             m = cls.getDeclaredMethod(methodName, none);
1156             m.invoke(receiver);
1157         } catch (Exception e) {
1158             Asserts.fail("Call through reflection failed", e);
1159         }
1160     }
1161 
1162     /**
1163      * Trigger bulk rebiasing for the given class by creating new instances and calling <code> hashCode() </code> on them.
1164      * @param cls The class to bulk rebias
1165      */
1166     public void dontinline_bulkRebiasAfterWarmup(Class<?> cls) {
1167         if (warmupDone) {
1168             try {
1169                 for (int i=0; i < BiasedLockingBulkRebiasThreshold+2; i++) {
1170                     biasToBeRevoked = cls.getDeclaredConstructor(int.class, int.class).newInstance(1, 1);
1171                     synchronized (biasToBeRevoked) { // bias towards current thread
1172                         checkSum++;
1173                     }
1174                     biasToBeRevoked.hashCode(); // calling hashCode triggers revocation
1175                 }
1176             } catch (Throwable e) {
1177                 Asserts.fail("failed to create new instance of " + cls.getName(), e);
1178             }
1179         }
1180     }
1181 
1182     /**
1183      * Trigger bulk revoke of biases for the given class by creating new instances and calling <code> hashCode() </code> on them.
1184      * @param cls The class to bulk rebias
1185      */
1186     public void dontinline_bulkRevokeAfterWarmup(Class<?> cls) {
1187         if (warmupDone) {
1188             try {
1189                 for (int i=0; i < BiasedLockingBulkRevokeThreshold+2; i++) {
1190                     biasToBeRevoked = cls.getDeclaredConstructor(int.class, int.class).newInstance(1, 1);
1191                     synchronized (biasToBeRevoked) { // bias towards current thread
1192                         checkSum++;
1193                     }
1194                     biasToBeRevoked.hashCode(); // calling hashCode triggers revocation
1195                 }
1196             } catch (Throwable e) {
1197                 Asserts.fail("failed to create new instance of " + cls.getName(), e);
1198             }
1199         }
1200     }
1201 
1202     static class LinkedList {
1203         LinkedList l;
1204         public long[] array;
1205         public LinkedList(LinkedList l, int size) {
1206             this.array = size > 0 ? new long[size] : null;
1207             this.l = l;
1208         }
1209     }
1210 
1211     public LinkedList consumedMemory;
1212 
1213     public void consumeAllMemory() {
1214         msg("consume all memory");
1215         int size = 128 * 1024 * 1024;
1216         while(true) {
1217             try {
1218                 while(true) {
1219                     consumedMemory = new LinkedList(consumedMemory, size);
1220                 }
1221             } catch(OutOfMemoryError oom) {
1222                 if (size == 0) break;
1223             }
1224             size = size / 2;
1225         }
1226     }
1227 }
1228 
1229 /////////////////////////////////////////////////////////////////////////////
1230 //
1231 // Test Cases
1232 //
1233 /////////////////////////////////////////////////////////////////////////////
1234 
1235 // make sure a compiled frame is not deoptimized if an escaping local is accessed
1236 class EAGetWithoutMaterializeTarget extends EATestCaseBaseTarget {
1237 
1238     public XYVal getAway;
1239 
1240     public void dontinline_testMethod() {
1241         XYVal xy = new XYVal(4, 2);
1242         getAway = xy;  // allocated object escapes
1243         dontinline_brkpt();
1244         iResult = xy.x + xy.y;
1245     }
1246 
1247     @Override
1248     public int getExpectedIResult() {
1249         return 4 + 2;
1250     }
1251 
1252     @Override
1253     public boolean testFrameShouldBeDeoptimized() {
1254         return false;
1255     }
1256 }
1257 
1258 class EAGetWithoutMaterialize extends EATestCaseBaseDebugger {
1259 
1260     public void runTestCase() throws Exception {
1261         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1262         printStack(bpe.thread());
1263         ObjectReference o = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "xy");
1264         checkPrimitiveField(o, FD.I, "x", 4);
1265         checkPrimitiveField(o, FD.I, "y", 2);
1266     }
1267 }
1268 
1269 /////////////////////////////////////////////////////////////////////////////
1270 
1271 //
1272 // Tests the following:
1273 //
1274 // 1. Debugger can obtain a reference to a scalar replaced object R from java thread J.
1275 //    See runTestCase.
1276 //
1277 // 2. Subsequent modifications of R by J are noticed by the debugger.
1278 //    See checkPostConditions.
1279 //
1280 class EAMaterializeLocalVariableUponGet extends EATestCaseBaseDebugger {
1281 
1282     private ObjectReference o;
1283 
1284     public void runTestCase() throws Exception {
1285         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1286         printStack(bpe.thread());
1287         // check 1.
1288         o = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "xy");
1289         // o is referenced in checkPostConditions() and must not be gc'ed.
1290         o.disableCollection();
1291         checkPrimitiveField(o, FD.I, "x", 4);
1292         checkPrimitiveField(o, FD.I, "y", 2);
1293     }
1294 
1295     @Override
1296     public void checkPostConditions() throws Exception {
1297         super.checkPostConditions();
1298         // check 2.
1299         checkPrimitiveField(o, FD.I, "x", 5);
1300     }
1301 }
1302 
1303 class EAMaterializeLocalVariableUponGetTarget extends EATestCaseBaseTarget {
1304 
1305     public void dontinline_testMethod() {
1306         XYVal xy = new XYVal(4, 2);
1307         dontinline_brkpt();       // Debugger obtains scalar replaced object at this point.
1308         xy.x += 1;                // Change scalar replaced object after debugger obtained a reference to it.
1309         iResult = xy.x + xy.y;
1310     }
1311 
1312     @Override
1313     public int getExpectedIResult() {
1314         return 4 + 2 + 1;
1315     }
1316 }
1317 
1318 /////////////////////////////////////////////////////////////////////////////
1319 
1320 // Test if an eliminated object can be reallocated in a frame with an active
1321 // call that will return another object
1322 class EAMaterializeLocalAtObjectReturn extends EATestCaseBaseDebugger {
1323     public void runTestCase() throws Exception {
1324         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1325         printStack(bpe.thread());
1326         ObjectReference o = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "xy");
1327         checkPrimitiveField(o, FD.I, "x", 4);
1328         checkPrimitiveField(o, FD.I, "y", 2);
1329     }
1330 }
1331 
1332 class EAMaterializeLocalAtObjectReturnTarget extends EATestCaseBaseTarget {
1333     @Override
1334     public void setUp() {
1335         super.setUp();
1336         testMethodDepth = 2;
1337     }
1338 
1339     public void dontinline_testMethod() {
1340         XYVal xy = new XYVal(4, 2);
1341         Integer io =                 // Read xy here triggers reallocation
1342                 dontinline_brkpt_return_Integer();
1343         iResult = xy.x + xy.y + io;
1344     }
1345 
1346     public Integer dontinline_brkpt_return_Integer() {
1347         // We can't break directly in this method, as this results in making
1348         // the test method not entrant caused by an existing dependency
1349         dontinline_brkpt();
1350         return Integer.valueOf(23);
1351     }
1352 
1353     @Override
1354     public int getExpectedIResult() {
1355         return 4 + 2 + 23;
1356     }
1357 }
1358 
1359 /////////////////////////////////////////////////////////////////////////////
1360 
1361 // Test if an eliminated object can be reallocated *just* before a call returns an object.
1362 // (See CompiledMethod::is_at_poll_return())
1363 // Details: the callee method has just one safepoint poll at the return. The other safepoint
1364 // is at the end of an iteration of the endless loop. We can detect if we suspended the target
1365 // there because the local xy is out of scope there.
1366 class EAMaterializeLocalAtObjectPollReturnReturn extends EATestCaseBaseDebugger {
1367     public void runTestCase() throws Exception {
1368         msg("Resume " + env.targetMainThread);
1369         env.vm().resume();
1370         waitUntilTargetHasEnteredEndlessLoop();
1371         ObjectReference o = null;
1372         int retryCount = 0;
1373         do {
1374             env.targetMainThread.suspend();
1375             printStack(env.targetMainThread);
1376             try {
1377                 o = getLocalRef(env.targetMainThread.frame(0), XYVAL_NAME, "xy");
1378             } catch (Exception e) {
1379                 ++retryCount;
1380                 msg("The local variable xy is out of scope because we suspended at the wrong bci. Resume and try again! (" + retryCount + ")");
1381                 env.targetMainThread.resume();
1382                 if ((retryCount % 10) == 0) {
1383                     Thread.sleep(200);
1384                 }
1385             }
1386         } while (o == null);
1387         checkPrimitiveField(o, FD.I, "x", 4);
1388         checkPrimitiveField(o, FD.I, "y", 2);
1389         terminateEndlessLoop();
1390     }
1391 }
1392 
1393 class EAMaterializeLocalAtObjectPollReturnReturnTarget extends EATestCaseBaseTarget {
1394     @Override
1395     public void setUp() {
1396         super.setUp();
1397         loopCount = 3;
1398         doLoop = true;
1399     }
1400 
1401     public void warmupDone() {
1402         super.warmupDone();
1403         msg("enter 'endless' loop by setting loopCount = Long.MAX_VALUE");
1404         loopCount = Long.MAX_VALUE; // endless loop
1405     }
1406 
1407     public void dontinline_testMethod() {
1408         long result = 0;
1409         while (doLoop && loopCount-- > 0) {
1410             targetIsInLoop = true;
1411             XYVal xy = new XYVal(4, 2);
1412             Integer io =           // Read xy here triggers reallocation just before the call returns
1413                     dontinline_brkpt_return_Integer();
1414             result += xy.x + xy.y + io;
1415         }  // Here is a second safepoint. We were suspended here if xy is not in scope.
1416         targetIsInLoop = false;
1417         lResult = result;
1418     }
1419 
1420     public Integer dontinline_brkpt_return_Integer() {
1421         return Integer.valueOf(23);
1422     }
1423 
1424     @Override
1425     public long getExpectedLResult() {
1426         return (Long.MAX_VALUE - loopCount) * (4+2+23);
1427     }
1428 }
1429 
1430 /////////////////////////////////////////////////////////////////////////////
1431 // Test case collection that tests rematerialization of different
1432 // array types where the first element is always not constant and the
1433 // other elements are constants. Not constant values are stored in
1434 // the stack frame for rematerialization whereas constants are kept
1435 // in the debug info of the nmethod.
1436 
1437 class EAMaterializeIntArrayTarget extends EATestCaseBaseTarget {
1438 
1439     public void dontinline_testMethod() {
1440         int nums[] = {NOT_CONST_1I , 2, 3};
1441         dontinline_brkpt();
1442         iResult = nums[0] + nums[1] + nums[2];
1443     }
1444 
1445     @Override
1446     public int getExpectedIResult() {
1447         return NOT_CONST_1I + 2 + 3;
1448     }
1449 }
1450 
1451 class EAMaterializeIntArray extends EATestCaseBaseDebugger {
1452     public void runTestCase() throws Exception {
1453         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1454         printStack(bpe.thread());
1455         int[] expectedVals = {1, 2, 3};
1456         checkLocalPrimitiveArray(bpe.thread().frame(1), "nums", FD.I, expectedVals);
1457     }
1458 }
1459 
1460 /////////////////////////////////////////////////////////////////////////////
1461 
1462 class EAMaterializeLongArrayTarget extends EATestCaseBaseTarget {
1463 
1464     public void dontinline_testMethod() {
1465         long nums[] = {NOT_CONST_1L , 2, 3};
1466         dontinline_brkpt();
1467         lResult = nums[0] + nums[1] + nums[2];
1468     }
1469 
1470     @Override
1471     public long getExpectedLResult() {
1472         return NOT_CONST_1L + 2 + 3;
1473     }
1474 }
1475 
1476 class EAMaterializeLongArray extends EATestCaseBaseDebugger {
1477     public void runTestCase() throws Exception {
1478         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1479         printStack(bpe.thread());
1480         long[] expectedVals = {1, 2, 3};
1481         checkLocalPrimitiveArray(bpe.thread().frame(1), "nums", FD.J, expectedVals);
1482     }
1483 }
1484 
1485 /////////////////////////////////////////////////////////////////////////////
1486 
1487 class EAMaterializeFloatArrayTarget extends EATestCaseBaseTarget {
1488 
1489     public void dontinline_testMethod() {
1490         float nums[] = {NOT_CONST_1F , 2.2f, 3.3f};
1491         dontinline_brkpt();
1492         fResult = nums[0] + nums[1] + nums[2];
1493     }
1494 
1495     @Override
1496     public float getExpectedFResult() {
1497         return NOT_CONST_1F + 2.2f + 3.3f;
1498     }
1499 }
1500 
1501 class EAMaterializeFloatArray extends EATestCaseBaseDebugger {
1502     public void runTestCase() throws Exception {
1503         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1504         printStack(bpe.thread());
1505         float[] expectedVals = {1.1f, 2.2f, 3.3f};
1506         checkLocalPrimitiveArray(bpe.thread().frame(1), "nums", FD.F, expectedVals);
1507     }
1508 }
1509 
1510 /////////////////////////////////////////////////////////////////////////////
1511 
1512 class EAMaterializeDoubleArrayTarget extends EATestCaseBaseTarget {
1513 
1514     public void dontinline_testMethod() {
1515         double nums[] = {NOT_CONST_1D , 2.2d, 3.3d};
1516         dontinline_brkpt();
1517         dResult = nums[0] + nums[1] + nums[2];
1518     }
1519 
1520     @Override
1521     public double getExpectedDResult() {
1522         return NOT_CONST_1D + 2.2d + 3.3d;
1523     }
1524 }
1525 
1526 class EAMaterializeDoubleArray extends EATestCaseBaseDebugger {
1527     public void runTestCase() throws Exception {
1528         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1529         printStack(bpe.thread());
1530         double[] expectedVals = {1.1d, 2.2d, 3.3d};
1531         checkLocalPrimitiveArray(bpe.thread().frame(1), "nums", FD.D, expectedVals);
1532     }
1533 }
1534 
1535 /////////////////////////////////////////////////////////////////////////////
1536 
1537 class EAMaterializeObjectArrayTarget extends EATestCaseBaseTarget {
1538 
1539     public void dontinline_testMethod() {
1540         Long nums[] = {NOT_CONST_1_OBJ , CONST_2_OBJ, CONST_3_OBJ};
1541         dontinline_brkpt();
1542         lResult = nums[0] + nums[1] + nums[2];
1543     }
1544 
1545     @Override
1546     public long getExpectedLResult() {
1547         return 1 + 2 + 3;
1548     }
1549 }
1550 
1551 class EAMaterializeObjectArray extends EATestCaseBaseDebugger {
1552     public void runTestCase() throws Exception {
1553         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1554         printStack(bpe.thread());
1555         ReferenceType clazz = bpe.thread().frame(0).location().declaringType();
1556         ObjectReference[] expectedVals = {
1557                 (ObjectReference) clazz.getValue(clazz.fieldByName("NOT_CONST_1_OBJ")),
1558                 (ObjectReference) clazz.getValue(clazz.fieldByName("CONST_2_OBJ")),
1559                 (ObjectReference) clazz.getValue(clazz.fieldByName("CONST_3_OBJ"))
1560         };
1561         checkLocalObjectArray(bpe.thread().frame(1), "nums", "java.lang.Long[]", expectedVals);
1562     }
1563 }
1564 
1565 /////////////////////////////////////////////////////////////////////////////
1566 
1567 // Materialize an object whose fields have constant and not constant values at
1568 // the point where the object is materialized.
1569 class EAMaterializeObjectWithConstantAndNotConstantValuesTarget extends EATestCaseBaseTarget {
1570 
1571     public void dontinline_testMethod() {
1572         ILFDO o = new ILFDO(NOT_CONST_1I, 2,
1573                             NOT_CONST_1L, 2L,
1574                             NOT_CONST_1F, 2.1F,
1575                             NOT_CONST_1D, 2.1D,
1576                             NOT_CONST_1_OBJ, CONST_2_OBJ
1577                             );
1578         dontinline_brkpt();
1579         dResult =
1580             o.i + o.i2 + o.l + o.l2 + o.f + o.f2 + o.d + o.d2 + o.o + o.o2;
1581     }
1582 
1583     @Override
1584     public double getExpectedDResult() {
1585         return NOT_CONST_1I + 2 + NOT_CONST_1L + 2L + NOT_CONST_1F + 2.1F + NOT_CONST_1D + 2.1D + NOT_CONST_1_OBJ + CONST_2_OBJ;
1586     }
1587 }
1588 
1589 class EAMaterializeObjectWithConstantAndNotConstantValues extends EATestCaseBaseDebugger {
1590     public void runTestCase() throws Exception {
1591         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1592         printStack(bpe.thread());
1593         ObjectReference o = getLocalRef(bpe.thread().frame(1), "ILFDO", "o");
1594         checkPrimitiveField(o, FD.I, "i", 1);
1595         checkPrimitiveField(o, FD.I, "i2", 2);
1596         checkPrimitiveField(o, FD.J, "l", 1L);
1597         checkPrimitiveField(o, FD.J, "l2", 2L);
1598         checkPrimitiveField(o, FD.F, "f", 1.1f);
1599         checkPrimitiveField(o, FD.F, "f2", 2.1f);
1600         checkPrimitiveField(o, FD.D, "d", 1.1d);
1601         checkPrimitiveField(o, FD.D, "d2", 2.1d);
1602         ReferenceType clazz = bpe.thread().frame(1).location().declaringType();
1603         ObjectReference[] expVals = {
1604                 (ObjectReference) clazz.getValue(clazz.fieldByName("NOT_CONST_1_OBJ")),
1605                 (ObjectReference) clazz.getValue(clazz.fieldByName("CONST_2_OBJ")),
1606         };
1607         checkObjField(o, "o", expVals[0]);
1608         checkObjField(o, "o2", expVals[1]);
1609     }
1610 }
1611 
1612 /////////////////////////////////////////////////////////////////////////////
1613 
1614 // Two local variables reference the same object.
1615 // Check if the debugger obtains the same object when reading the two variables
1616 class EAMaterializeObjReferencedBy2LocalsTarget extends EATestCaseBaseTarget {
1617 
1618     public void dontinline_testMethod() {
1619         XYVal xy = new XYVal(2, 3);
1620         XYVal alias = xy;
1621         dontinline_brkpt();
1622         iResult = xy.x + alias.x;
1623     }
1624 
1625     @Override
1626     public int getExpectedIResult() {
1627         return 2 + 2;
1628     }
1629 }
1630 
1631 class EAMaterializeObjReferencedBy2Locals extends EATestCaseBaseDebugger {
1632 
1633     public void runTestCase() throws Exception {
1634         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1635         printStack(bpe.thread());
1636         ObjectReference xy = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "xy");
1637         ObjectReference alias = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "alias");
1638         Asserts.assertSame(xy, alias, "xy and alias are expected to reference the same object");
1639     }
1640 
1641 }
1642 
1643 /////////////////////////////////////////////////////////////////////////////
1644 
1645 // Two local variables reference the same object.
1646 // Check if it has the expected effect in the target if the debugger modifies the object.
1647 class EAMaterializeObjReferencedBy2LocalsAndModifyTarget extends EATestCaseBaseTarget {
1648 
1649     public void dontinline_testMethod() {
1650         XYVal xy = new XYVal(2, 3);
1651         XYVal alias = xy;
1652         dontinline_brkpt(); // debugger: alias.x = 42
1653         iResult = xy.x + alias.x;
1654     }
1655 
1656     @Override
1657     public int getExpectedIResult() {
1658         return 42 + 42;
1659     }
1660 }
1661 
1662 class EAMaterializeObjReferencedBy2LocalsAndModify extends EATestCaseBaseDebugger {
1663 
1664     public void runTestCase() throws Exception {
1665         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1666         printStack(bpe.thread());
1667         ObjectReference alias = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "alias");
1668         setField(alias, "x", env.vm().mirrorOf(42));
1669     }
1670 }
1671 
1672 /////////////////////////////////////////////////////////////////////////////
1673 
1674 // Two local variables of the same compiled frame but in different virtual frames reference the same
1675 // object.
1676 // Check if the debugger obtains the same object when reading the two variables
1677 class EAMaterializeObjReferencedBy2LocalsInDifferentVirtFramesTarget extends EATestCaseBaseTarget {
1678 
1679     @Override
1680     public void setUp() {
1681         super.setUp();
1682         testMethodDepth = 2;
1683     }
1684 
1685     public void dontinline_testMethod() {
1686         XYVal xy = new XYVal(2, 3);
1687         testMethod_inlined(xy);
1688         iResult += xy.x;
1689     }
1690 
1691     public void testMethod_inlined(XYVal xy) {
1692         XYVal alias = xy;
1693         dontinline_brkpt();
1694         iResult = alias.x;
1695     }
1696 
1697     @Override
1698     public int getExpectedIResult() {
1699         return 2 + 2;
1700     }
1701 }
1702 
1703 class EAMaterializeObjReferencedBy2LocalsInDifferentVirtFrames extends EATestCaseBaseDebugger {
1704 
1705     public void runTestCase() throws Exception {
1706         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1707         printStack(bpe.thread());
1708         ObjectReference xy = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "xy");
1709         ObjectReference alias = getLocalRef(bpe.thread().frame(1), "testMethod_inlined", "alias", XYVAL_NAME);
1710         Asserts.assertSame(xy, alias, "xy and alias are expected to reference the same object");
1711     }
1712 
1713 }
1714 
1715 /////////////////////////////////////////////////////////////////////////////
1716 
1717 // Two local variables of the same compiled frame but in different virtual frames reference the same
1718 // object.
1719 // Check if it has the expected effect in the target if the debugger modifies the object.
1720 class EAMaterializeObjReferencedBy2LocalsInDifferentVirtFramesAndModifyTarget extends EATestCaseBaseTarget {
1721 
1722     @Override
1723     public void setUp() {
1724         super.setUp();
1725         testMethodDepth = 2;
1726     }
1727 
1728     public void dontinline_testMethod() {
1729         XYVal xy = new XYVal(2, 3);
1730         testMethod_inlined(xy);   // debugger: xy.x = 42
1731         iResult += xy.x;
1732     }
1733 
1734     public void testMethod_inlined(XYVal xy) {
1735         XYVal alias = xy;
1736         dontinline_brkpt();
1737         iResult = alias.x;
1738     }
1739 
1740     @Override
1741     public int getExpectedIResult() {
1742         return 42 + 42;
1743     }
1744 }
1745 
1746 class EAMaterializeObjReferencedBy2LocalsInDifferentVirtFramesAndModify extends EATestCaseBaseDebugger {
1747 
1748     public void runTestCase() throws Exception {
1749         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1750         printStack(bpe.thread());
1751         ObjectReference alias = getLocalRef(bpe.thread().frame(1), "testMethod_inlined", "alias", XYVAL_NAME);
1752         setField(alias, "x", env.vm().mirrorOf(42));
1753     }
1754 
1755 }
1756 
1757 /////////////////////////////////////////////////////////////////////////////
1758 
1759 // Test materialization of an object referenced only from expression stack
1760 class EAMaterializeObjReferencedFromOperandStackTarget extends EATestCaseBaseTarget {
1761 
1762     @Override
1763     public void setUp() {
1764         super.setUp();
1765         testMethodDepth = 2;
1766     }
1767 
1768     public void dontinline_testMethod() {
1769         @SuppressWarnings("unused")
1770         XYVal xy1 = new XYVal(2, 3);
1771         // Debugger breaks in call to dontinline_brkpt_ret_100() and reads
1772         // the value of the local 'xy1'. This triggers materialization
1773         // of the object on the operand stack
1774         iResult = testMethodInlined(new XYVal(4, 2), dontinline_brkpt_ret_100());
1775     }
1776 
1777     public int testMethodInlined(XYVal xy2, int dontinline_brkpt_ret_100) {
1778         return xy2.x + dontinline_brkpt_ret_100;
1779     }
1780 
1781     public int dontinline_brkpt_ret_100() {
1782         dontinline_brkpt();
1783         return 100;
1784     }
1785 
1786     @Override
1787     public int getExpectedIResult() {
1788         return 4 + 100;
1789     }
1790 }
1791 
1792 class EAMaterializeObjReferencedFromOperandStack extends EATestCaseBaseDebugger {
1793 
1794     public void runTestCase() throws Exception {
1795         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1796         printStack(bpe.thread());
1797         ObjectReference xy1 = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "xy1");
1798         checkPrimitiveField(xy1, FD.I, "x", 2);
1799         checkPrimitiveField(xy1, FD.I, "y", 3);
1800     }
1801 
1802 }
1803 
1804 /////////////////////////////////////////////////////////////////////////////
1805 
1806 /**
1807  * Tests a regression in the implementation by setting the value of a local int which triggers the
1808  * creation of a deferred update and then getting the reference to a scalar replaced object.  The
1809  * issue was that the scalar replaced object was not reallocated. Because of the deferred update it
1810  * was assumed that the reallocation already happened.
1811  */
1812 class EAMaterializeLocalVariableUponGetAfterSetInteger extends EATestCaseBaseDebugger {
1813 
1814     public void runTestCase() throws Exception {
1815         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1816         printStack(bpe.thread());
1817         setLocal(bpe.thread().frame(1), "i", env.vm().mirrorOf(43));
1818         ObjectReference o = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "xy");
1819         checkPrimitiveField(o, FD.I, "x", 4);
1820         checkPrimitiveField(o, FD.I, "y", 2);
1821     }
1822 }
1823 
1824 class EAMaterializeLocalVariableUponGetAfterSetIntegerTarget extends EATestCaseBaseTarget {
1825 
1826     public void dontinline_testMethod() {
1827         XYVal xy = new XYVal(4, 2);
1828         int i = 42;
1829         dontinline_brkpt();
1830         iResult = xy.x + xy.y + i;
1831     }
1832 
1833     @Override
1834     public int getExpectedIResult() {
1835         return 4 + 2 + 43;
1836     }
1837 
1838     @Override
1839     public boolean testFrameShouldBeDeoptimized() {
1840         return true; // setting local variable i always triggers deoptimization
1841     }
1842 }
1843 
1844 /////////////////////////////////////////////////////////////////////////////
1845 //
1846 // Locking Tests
1847 //
1848 /////////////////////////////////////////////////////////////////////////////
1849 
1850 class EARelockingSimple extends EATestCaseBaseDebugger {
1851 
1852     public void runTestCase() throws Exception {
1853         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1854         printStack(bpe.thread());
1855         @SuppressWarnings("unused")
1856         ObjectReference o = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "l1");
1857     }
1858 }
1859 
1860 class EARelockingSimpleTarget extends EATestCaseBaseTarget {
1861 
1862     public void dontinline_testMethod() {
1863         XYVal l1 = new XYVal(4, 2);
1864         synchronized (l1) {
1865             dontinline_brkpt();
1866         }
1867     }
1868 }
1869 
1870 /////////////////////////////////////////////////////////////////////////////
1871 
1872 /**
1873  * Test if the bias of an object O that escapes globally is revoked correctly if local objects
1874  * escape through JVMTI. O is referenced by field l0.
1875  * This tests a regression of a previous version of the implementation.
1876  */
1877 class EARelockingSimple_2 extends EATestCaseBaseDebugger {
1878 
1879 
1880     public void runTestCase() throws Exception {
1881         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1882         printStack(bpe.thread());
1883         @SuppressWarnings("unused")
1884         ObjectReference o = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "l1");
1885     }
1886 }
1887 
1888 class EARelockingSimple_2Target extends EATestCaseBaseTarget {
1889 
1890     public XYVal l0;
1891 
1892     public void dontinline_testMethod() {
1893         l0 = new XYVal(4, 2);         // GobalEscape
1894         XYVal l1 = new XYVal(4, 2);
1895         synchronized (l0) {
1896             synchronized (l1) {
1897                 dontinline_brkpt();
1898             }
1899         }
1900     }
1901 }
1902 
1903 /////////////////////////////////////////////////////////////////////////////
1904 
1905 // The debugger reads and publishes an object with eliminated locking to an instance field.
1906 // A 2nd thread in the debuggee finds it there and changes its state using a synchronized method.
1907 // Without eager relocking the accesses are unsynchronized which can be observed.
1908 class EARelockingSimpleWithAccessInOtherThread extends EATestCaseBaseDebugger {
1909 
1910     public void runTestCase() throws Exception {
1911         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1912         printStack(bpe.thread());
1913         String l1ClassName = EARelockingSimpleWithAccessInOtherThreadTarget.SyncCounter.class.getName();
1914         ObjectReference ctr = getLocalRef(bpe.thread().frame(1), l1ClassName, "l1");
1915         setField(testCase, "sharedCounter", ctr);
1916         terminateEndlessLoop();
1917     }
1918 }
1919 
1920 class EARelockingSimpleWithAccessInOtherThreadTarget extends EATestCaseBaseTarget {
1921 
1922     public static class SyncCounter {
1923         private int val;
1924         public synchronized int inc() { return val++; }
1925     }
1926 
1927     public volatile SyncCounter sharedCounter;
1928 
1929     @Override
1930     public void setUp() {
1931         super.setUp();
1932         doLoop = true;
1933         Thread t = new Thread() {
1934             public void run() {
1935                 while (doLoop) {
1936                     SyncCounter ctr = sharedCounter;
1937                     if (ctr != null) {
1938                         ctr.inc();
1939                     }
1940                 }
1941             }
1942         };
1943         t.setDaemon(true);
1944         t.start();
1945     }
1946 
1947     public void dontinline_testMethod() {
1948         SyncCounter l1 = new SyncCounter();
1949         synchronized (l1) {      // Eliminated locking
1950             l1.inc();
1951             dontinline_brkpt();  // Debugger publishes l1 to sharedCounter.
1952             iResult = l1.inc();  // Changes by the 2nd thread will be observed if l1
1953                                  // was not relocked before passing it to the debugger.
1954         }
1955     }
1956 
1957     @Override
1958     public int getExpectedIResult() {
1959         return 1;
1960     }
1961 }
1962 
1963 /////////////////////////////////////////////////////////////////////////////
1964 
1965 // Test recursive locking
1966 class EARelockingRecursiveTarget extends EATestCaseBaseTarget {
1967 
1968     @Override
1969     public void setUp() {
1970         super.setUp();
1971         testMethodDepth = 2;
1972     }
1973 
1974     public void dontinline_testMethod() {
1975         XYVal l1 = new XYVal(4, 2);
1976         synchronized (l1) {
1977             testMethod_inlined(l1);
1978         }
1979     }
1980 
1981     public void testMethod_inlined(XYVal l2) {
1982         synchronized (l2) {
1983             dontinline_brkpt();
1984         }
1985     }
1986 }
1987 
1988 class EARelockingRecursive extends EATestCaseBaseDebugger {
1989 
1990     public void runTestCase() throws Exception {
1991         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1992         printStack(bpe.thread());
1993         @SuppressWarnings("unused")
1994         ObjectReference o = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "l1");
1995     }
1996 }
1997 
1998 /////////////////////////////////////////////////////////////////////////////
1999 
2000 // Object ref l1 is retrieved by the debugger at a location where nested locks are omitted. The
2001 // accessed object is globally reachable already before the access, therefore no relocking is done.
2002 class EARelockingNestedInflatedTarget extends EATestCaseBaseTarget {
2003 
2004     @Override
2005     public void setUp() {
2006         super.setUp();
2007         testMethodDepth = 2;
2008     }
2009 
2010     @Override
2011     public boolean testFrameShouldBeDeoptimized() {
2012         // Access does not trigger deopt., as escape state is already global escape.
2013         return false;
2014     }
2015 
2016     public void dontinline_testMethod() {
2017         XYVal l1 = inflatedLock;
2018         synchronized (l1) {
2019             testMethod_inlined(l1);
2020         }
2021     }
2022 
2023     public void testMethod_inlined(XYVal l2) {
2024         synchronized (l2) {                 // eliminated nested locking
2025             dontinline_brkpt();
2026         }
2027     }
2028 }
2029 
2030 class EARelockingNestedInflated extends EATestCaseBaseDebugger {
2031 
2032     public void runTestCase() throws Exception {
2033         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2034         printStack(bpe.thread());
2035         @SuppressWarnings("unused")
2036         ObjectReference o = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "l1");
2037     }
2038 }
2039 
2040 /////////////////////////////////////////////////////////////////////////////
2041 
2042 /**
2043  * Like {@link EARelockingNestedInflated} with the difference that there is
2044  * a scalar replaced object in the scope from which the object with eliminated nested locking
2045  * is read. This triggers materialization and relocking.
2046  */
2047 class EARelockingNestedInflated_02 extends EATestCaseBaseDebugger {
2048 
2049     public void runTestCase() throws Exception {
2050         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2051         printStack(bpe.thread());
2052         @SuppressWarnings("unused")
2053         ObjectReference o = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "l1");
2054     }
2055 }
2056 
2057 class EARelockingNestedInflated_02Target extends EATestCaseBaseTarget {
2058 
2059     @Override
2060     public void setUp() {
2061         super.setUp();
2062         testMethodDepth = 2;
2063     }
2064 
2065     public void dontinline_testMethod() {
2066         @SuppressWarnings("unused")
2067         XYVal xy = new XYVal(1, 1);     // scalar replaced
2068         XYVal l1 = inflatedLock;          // read by debugger
2069         synchronized (l1) {
2070             testMethod_inlined(l1);
2071         }
2072     }
2073 
2074     public void testMethod_inlined(XYVal l2) {
2075         synchronized (l2) {                 // eliminated nested locking
2076             dontinline_brkpt();
2077         }
2078     }
2079 }
2080 
2081 /////////////////////////////////////////////////////////////////////////////
2082 
2083 /**
2084  * Like {@link EARelockingNestedInflated_02} with the difference that the
2085  * inflation of the lock happens because of contention.
2086  */
2087 class EARelockingNestedInflated_03 extends EATestCaseBaseDebugger {
2088 
2089     public void runTestCase() throws Exception {
2090         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2091         printStack(bpe.thread());
2092         @SuppressWarnings("unused")
2093         ObjectReference o = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "l1");
2094     }
2095 }
2096 
2097 class EARelockingNestedInflated_03Target extends EATestCaseBaseTarget {
2098 
2099     public XYVal lockInflatedByContention;
2100     public boolean doLockNow;
2101     public EATestCaseBaseTarget testCase;
2102 
2103     @Override
2104     public void setUp() {
2105         super.setUp();
2106         testMethodDepth = 2;
2107         lockInflatedByContention = new XYVal(1, 1);
2108         testCase = this;
2109     }
2110 
2111     @Override
2112     public void warmupDone() {
2113         super.warmupDone();
2114         // Use new lock. lockInflatedByContention might have been inflated because of recursion.
2115         lockInflatedByContention = new XYVal(1, 1);
2116         // Start thread that tries to enter lockInflatedByContention while the main thread owns it -> inflation
2117         new Thread(() -> {
2118             while (true) {
2119                 synchronized (testCase) {
2120                     try {
2121                         if (doLockNow) {
2122                             doLockNow = false; // reset for main thread
2123                             testCase.notify();
2124                             break;
2125                         }
2126                         testCase.wait();
2127                     } catch (InterruptedException e) { /* ignored */ }
2128                 }
2129             }
2130             synchronized (lockInflatedByContention) { // will block and trigger inflation
2131                 msg(Thread.currentThread().getName() + ": acquired lockInflatedByContention");
2132             }
2133             }, testCaseName + ": Lock Contender (test thread)").start();
2134     }
2135 
2136     public void dontinline_testMethod() {
2137         @SuppressWarnings("unused")
2138         XYVal xy = new XYVal(1, 1);            // scalar replaced
2139         XYVal l1 = lockInflatedByContention;   // read by debugger
2140         synchronized (l1) {
2141             testMethod_inlined(l1);
2142         }
2143     }
2144 
2145     public void testMethod_inlined(XYVal l2) {
2146         synchronized (l2) {                 // eliminated nested locking
2147             dontinline_notifyOtherThread();
2148             dontinline_brkpt();
2149         }
2150     }
2151 
2152     public void dontinline_notifyOtherThread() {
2153         if (!warmupDone) {
2154             return;
2155         }
2156         synchronized (testCase) {
2157             doLockNow = true;
2158             testCase.notify();
2159             // wait for other thread to reset doLockNow again
2160             while (doLockNow) {
2161                 try {
2162                     testCase.wait();
2163                 } catch (InterruptedException e) { /* ignored */ }
2164             }
2165         }
2166     }
2167 }
2168 
2169 /////////////////////////////////////////////////////////////////////////////
2170 
2171 /**
2172  * Checks if an eliminated lock of an ArgEscape object l1 can be relocked if
2173  * l1 is locked in a callee frame.
2174  */
2175 class EARelockingArgEscapeLWLockedInCalleeFrame extends EATestCaseBaseDebugger {
2176 
2177     public void runTestCase() throws Exception {
2178         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2179         printStack(bpe.thread());
2180         @SuppressWarnings("unused")
2181         ObjectReference o = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "l1");
2182     }
2183 }
2184 
2185 class EARelockingArgEscapeLWLockedInCalleeFrameTarget extends EATestCaseBaseTarget {
2186 
2187     @Override
2188     public void setUp() {
2189         super.setUp();
2190         testMethodDepth = 2;
2191     }
2192 
2193     public void dontinline_testMethod() {
2194         XYVal l1 = new XYVal(1, 1);       // ArgEscape
2195         synchronized (l1) {                   // eliminated
2196             l1.dontinline_sync_method(this);  // l1 escapes
2197         }
2198     }
2199 
2200     @Override
2201     public boolean testFrameShouldBeDeoptimized() {
2202         // Graal does not provide debug info about arg escape objects, therefore the frame is not deoptimized
2203         return !UseJVMCICompiler && super.testFrameShouldBeDeoptimized();
2204     }
2205 }
2206 
2207 /////////////////////////////////////////////////////////////////////////////
2208 
2209 /**
2210  * Similar to {@link EARelockingArgEscapeLWLockedInCalleeFrame}. In addition
2211  * the test method has got a scalar replaced object with eliminated locking.
2212  * This pattern matches a regression in the implementation.
2213  */
2214 class EARelockingArgEscapeLWLockedInCalleeFrame_2 extends EATestCaseBaseDebugger {
2215 
2216     public void runTestCase() throws Exception {
2217         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2218         printStack(bpe.thread());
2219         @SuppressWarnings("unused")
2220         ObjectReference o = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "l1");
2221     }
2222 }
2223 
2224 class EARelockingArgEscapeLWLockedInCalleeFrame_2Target extends EATestCaseBaseTarget {
2225 
2226     @Override
2227     public void setUp() {
2228         super.setUp();
2229         testMethodDepth = 2;
2230     }
2231 
2232     public void dontinline_testMethod() {
2233         XYVal l1 = new XYVal(1, 1);       // ArgEscape
2234         XYVal l2 = new XYVal(4, 2);       // NoEscape, scalar replaced
2235         synchronized (l1) {                   // eliminated
2236             synchronized (l2) {               // eliminated
2237                 l1.dontinline_sync_method(this);  // l1 escapes
2238             }
2239         }
2240         iResult = l2.x + l2.y;
2241     }
2242 
2243     @Override
2244     public int getExpectedIResult() {
2245         return 6;
2246     }
2247 }
2248 
2249 /////////////////////////////////////////////////////////////////////////////
2250 
2251 /**
2252  * Similar to {@link EARelockingArgEscapeLWLockedInCalleeFrame}.
2253  * A bulk rebias operation is triggered at a position where all locks on the local object referenced
2254  * by l1 are eliminated. This leaves the object with an outdated biased locking epoch which has to be
2255  * considered when relocking.
2256  * This tests a regression in a previous version.
2257  */
2258 class EARelockingArgEscapeLWLockedInCalleeFrame_3 extends EATestCaseBaseDebugger {
2259 
2260     public static final String XYVAL_LOCAL_NAME = EARelockingArgEscapeLWLockedInCalleeFrame_3Target.XYValLocal.class.getName();
2261 
2262     public void runTestCase() throws Exception {
2263         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2264         printStack(bpe.thread());
2265         @SuppressWarnings("unused")
2266         ObjectReference o = getLocalRef(bpe.thread().frame(1), XYVAL_LOCAL_NAME, "l1");
2267     }
2268 }
2269 
2270 class EARelockingArgEscapeLWLockedInCalleeFrame_3Target extends EATestCaseBaseTarget {
2271 
2272     // Using local type to avoid side effects on biased locking heuristics
2273     public static class XYValLocal extends XYVal {
2274         public XYValLocal(int x, int y) {
2275             super(x,y);
2276         }
2277     }
2278 
2279     public void dontinline_testMethod() {
2280         XYVal l1 = new XYValLocal(1, 1);       // ArgEscape
2281         synchronized (l1) {                    // eliminated
2282             l1.dontinline_sync_method_no_brkpt(this);  // l1 escapes
2283             // trigger bulk rebias
2284             dontinline_bulkRebiasAfterWarmup(l1.getClass());
2285             // Now the epoch of l1 does not match the epoch of its class.
2286             // This has to be considered when relocking because of JVMTI access
2287             dontinline_brkpt();
2288         }
2289     }
2290 
2291     @Override
2292     public boolean testFrameShouldBeDeoptimized() {
2293         // Graal does not provide debug info about arg escape objects, therefore the frame is not deoptimized
2294         return !UseJVMCICompiler && super.testFrameShouldBeDeoptimized();
2295     }
2296 }
2297 
2298 /////////////////////////////////////////////////////////////////////////////
2299 
2300 /**
2301  * Similar to {@link EARelockingArgEscapeLWLockedInCalleeFrame_3}.
2302  * But instead of a bulk rebias a bulk revoke operation is triggered.
2303  * This leaves the object with a stale bias as the prototype header of its calls lost its bias
2304  * pattern in the bulk revoke which has to be considered during relocking.
2305  * This tests a regression in a previous version.
2306  */
2307 class EARelockingArgEscapeLWLockedInCalleeFrame_4 extends EATestCaseBaseDebugger {
2308 
2309     public static final String XYVAL_LOCAL_NAME = EARelockingArgEscapeLWLockedInCalleeFrame_4Target.XYValLocal.class.getName();
2310 
2311     public void runTestCase() throws Exception {
2312         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2313         printStack(bpe.thread());
2314         @SuppressWarnings("unused")
2315         ObjectReference o = getLocalRef(bpe.thread().frame(1), XYVAL_LOCAL_NAME, "l1");
2316     }
2317 }
2318 
2319 class EARelockingArgEscapeLWLockedInCalleeFrame_4Target extends EATestCaseBaseTarget {
2320 
2321     // Using local type to avoid side effects on biased locking heuristics
2322     public static class XYValLocal extends XYVal {
2323         public XYValLocal(int x, int y) {
2324             super(x,y);
2325         }
2326     }
2327 
2328     public void dontinline_testMethod() {
2329         XYVal l1 = new XYValLocal(1, 1);       // ArgEscape
2330         synchronized (l1) {                    // eliminated
2331             l1.dontinline_sync_method_no_brkpt(this);  // l1 escapes
2332             // trigger bulk rebias
2333             dontinline_bulkRevokeAfterWarmup(l1.getClass());
2334             // Now the epoch of l1 does not match the epoch of its class.
2335             // This has to be considered when relocking because of JVMTI access
2336             dontinline_brkpt();
2337         }
2338     }
2339 
2340 
2341     @Override
2342     public boolean testFrameShouldBeDeoptimized() {
2343         // Graal does not provide debug info about arg escape objects, therefore the frame is not deoptimized
2344         return !UseJVMCICompiler && super.testFrameShouldBeDeoptimized();
2345     }
2346 }
2347 
2348 /////////////////////////////////////////////////////////////////////////////
2349 
2350 /**
2351  * Similar to {@link EARelockingArgEscapeLWLockedInCalleeFrame_2Target}. It does
2352  * not use recursive locking and exposed a bug in the lightweight-locking implementation.
2353  */
2354 class EARelockingArgEscapeLWLockedInCalleeFrameNoRecursive extends EATestCaseBaseDebugger {
2355 
2356     public void runTestCase() throws Exception {
2357         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2358         printStack(bpe.thread());
2359         @SuppressWarnings("unused")
2360         ObjectReference o = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "l1");
2361     }
2362 }
2363 
2364 class EARelockingArgEscapeLWLockedInCalleeFrameNoRecursiveTarget extends EATestCaseBaseTarget {
2365 
2366     @Override
2367     public void setUp() {
2368         super.setUp();
2369         testMethodDepth = 2;
2370     }
2371 
2372     public void dontinline_testMethod() {
2373         XYVal l1 = new XYVal(1, 1);       // NoEscape, scalar replaced
2374         XYVal l2 = new XYVal(4, 2);       // NoEscape, scalar replaced
2375         XYVal l3 = new XYVal(5, 3);       // ArgEscape
2376         synchronized (l1) {                   // eliminated
2377             synchronized (l2) {               // eliminated
2378                 l3.dontinline_sync_method(this);  // l3 escapes
2379             }
2380         }
2381         iResult = l2.x + l2.y;
2382     }
2383 
2384     @Override
2385     public int getExpectedIResult() {
2386         return 6;
2387     }
2388 }
2389 
2390 /////////////////////////////////////////////////////////////////////////////
2391 
2392 /**
2393  * Test relocking eliminated (nested) locks of an object on which the
2394  * target thread currently waits.
2395  */
2396 class EARelockingObjectCurrentlyWaitingOn extends EATestCaseBaseDebugger {
2397 
2398     public void runTestCase() throws Exception {
2399         env.vm().resume();
2400         boolean inWait = false;
2401         do {
2402             Thread.sleep(100);
2403             env.targetMainThread.suspend();
2404             printStack(env.targetMainThread);
2405             inWait = env.targetMainThread.frame(0).location().method().name().equals("wait");
2406             if (!inWait) {
2407                 msg("Target not yet in java.lang.Object.wait(long).");
2408                 env.targetMainThread.resume();
2409             }
2410         } while(!inWait);
2411         StackFrame testMethodFrame = env.targetMainThread.frame(4);
2412         // Access triggers relocking of all eliminated locks, including nested locks of l1 which references
2413         // the object on which the target main thread is currently waiting.
2414         ObjectReference l0 = getLocalRef(testMethodFrame, EARelockingObjectCurrentlyWaitingOnTarget.ForLocking.class.getName(), "l0");
2415         Asserts.assertEQ(l0.entryCount(), 1, "wrong entry count");
2416         ObjectReference l1 = getLocalRef(testMethodFrame, EARelockingObjectCurrentlyWaitingOnTarget.ForLocking.class.getName(), "l1");
2417         Asserts.assertEQ(l1.entryCount(), 0, "wrong entry count");
2418         setField(testCase, "objToNotifyOn", l1);
2419     }
2420 }
2421 
2422 class EARelockingObjectCurrentlyWaitingOnTarget extends EATestCaseBaseTarget {
2423 
2424     public static class ForLocking {
2425     }
2426 
2427     public volatile Object objToNotifyOn; // debugger assigns value when notify thread should call objToNotifyOn.notifyAll()
2428 
2429     @Override
2430     public void setUp() {
2431         super.setUp();
2432         testMethodDepth = 2;
2433     }
2434 
2435     @Override
2436     public void warmupDone() {
2437         super.warmupDone();
2438         Thread t = new Thread(() -> doNotify());
2439         t.start();
2440     }
2441 
2442     public void doNotify() {
2443         while (objToNotifyOn == null) {
2444             try {
2445                 msg("objToNotifyOn is still null");
2446                 Thread.sleep(100);
2447             } catch (InterruptedException e) { /* ignored */ }
2448         }
2449         synchronized (objToNotifyOn) {
2450             // will be received by the target main thread waiting in dontinline_waitWhenWarmupDone
2451             msg("calling objToNotifyOn.notifyAll()");
2452             objToNotifyOn.notifyAll();
2453         }
2454     }
2455 
2456     @Override
2457     public boolean testFrameShouldBeDeoptimized() {
2458         return false;
2459     }
2460 
2461     @Override
2462     public void dontinline_testMethod() throws Exception {
2463         ForLocking l0 = new ForLocking(); // will be scalar replaced; access triggers realloc/relock
2464         ForLocking l1 = new ForLocking();
2465         synchronized (l0) {
2466             synchronized (l1) {
2467                 testMethod_inlined(l1);
2468             }
2469         }
2470     }
2471 
2472     public void testMethod_inlined(ForLocking l2) throws Exception {
2473         synchronized (l2) {                 // eliminated nested locking
2474             dontinline_waitWhenWarmupDone(l2);
2475         }
2476     }
2477 
2478     public void dontinline_waitWhenWarmupDone(ForLocking l2) throws Exception {
2479         if (warmupDone) {
2480             l2.wait();
2481         }
2482     }
2483 }
2484 
2485 
2486 /////////////////////////////////////////////////////////////////////////////
2487 
2488 /**
2489  * Test relocking eliminated @ValueBased object.
2490  */
2491 class EARelockingValueBased extends EATestCaseBaseDebugger {
2492 
2493     public void runTestCase() throws Exception {
2494         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2495         printStack(bpe.thread());
2496         @SuppressWarnings("unused")
2497         ObjectReference o = getLocalRef(bpe.thread().frame(1), Integer.class.getName(), "l1");
2498     }
2499 }
2500 
2501 class EARelockingValueBasedTarget extends EATestCaseBaseTarget {
2502 
2503     public void dontinline_testMethod() {
2504         Integer l1 = new Integer(255);
2505         synchronized (l1) {
2506             dontinline_brkpt();
2507         }
2508     }
2509 }
2510 
2511 /////////////////////////////////////////////////////////////////////////////
2512 //
2513 // Test cases that require deoptimization even though neither locks
2514 // nor allocations are eliminated at the point where escape state is changed.
2515 //
2516 /////////////////////////////////////////////////////////////////////////////
2517 
2518 /**
2519  * Let xy be NoEscape whose allocation cannot be eliminated (simulated by
2520  * -XX:-EliminateAllocations). The holding compiled frame has to be deoptimized when debugger
2521  * accesses xy because afterwards locking on xy is omitted.
2522  * Note: there are no EA based optimizations at the escape point.
2523  */
2524 class EADeoptFrameAfterReadLocalObject_01 extends EATestCaseBaseDebugger {
2525 
2526     public void runTestCase() throws Exception {
2527         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2528         printStack(bpe.thread());
2529         @SuppressWarnings("unused")
2530         ObjectReference xy = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "xy");
2531     }
2532 }
2533 
2534 class EADeoptFrameAfterReadLocalObject_01Target extends EATestCaseBaseTarget {
2535 
2536     public void dontinline_testMethod() {
2537         XYVal xy = new XYVal(1, 1);
2538         dontinline_brkpt();              // Debugger reads xy, when there are no virtual objects or eliminated locks in scope
2539         synchronized (xy) {              // Locking is eliminated.
2540             xy.x++;
2541             xy.y++;
2542         }
2543     }
2544 }
2545 
2546 /////////////////////////////////////////////////////////////////////////////
2547 
2548 /**
2549  * Similar to {@link EADeoptFrameAfterReadLocalObject_01} with the difference that the debugger
2550  * reads xy from an inlined callee. So xy is NoEscape instead of ArgEscape.
2551  */
2552 class EADeoptFrameAfterReadLocalObject_01BTarget extends EATestCaseBaseTarget {
2553 
2554     @Override
2555     public void setUp() {
2556         super.setUp();
2557         testMethodDepth = 2;
2558     }
2559 
2560     public void dontinline_testMethod() {
2561         XYVal xy  = new XYVal(1, 1);
2562         callee(xy);                 // Debugger acquires ref to xy from inlined callee
2563                                     // xy is NoEscape, nevertheless the object is not replaced
2564                                     // by scalars if running with -XX:-EliminateAllocations.
2565                                     // In that case there are no EA based optimizations were
2566                                     // the debugger reads the NoEscape object.
2567         synchronized (xy) {         // Locking is eliminated.
2568             xy.x++;
2569             xy.y++;
2570         }
2571     }
2572 
2573     public void callee(XYVal xy) {
2574         dontinline_brkpt();              // Debugger reads xy.
2575                                          // There are no virtual objects or eliminated locks.
2576     }
2577 }
2578 
2579 class EADeoptFrameAfterReadLocalObject_01B extends EATestCaseBaseDebugger {
2580 
2581     public void runTestCase() throws Exception {
2582         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2583         printStack(bpe.thread());
2584         @SuppressWarnings("unused")
2585         ObjectReference xy = getLocalRef(bpe.thread().frame(1), "callee", "xy", XYVAL_NAME);
2586     }
2587 }
2588 
2589 /////////////////////////////////////////////////////////////////////////////
2590 
2591 /**
2592  * Let xy be ArgEscape. The frame dontinline_testMethod() has to be deoptimized when debugger
2593  * acquires xy from dontinline_callee() because afterwards locking on xy is omitted.
2594  * Note: there are no EA based optimizations at the escape point.
2595  */
2596 class EADeoptFrameAfterReadLocalObject_02 extends EATestCaseBaseDebugger {
2597 
2598     public void runTestCase() throws Exception {
2599         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2600         printStack(bpe.thread());
2601         @SuppressWarnings("unused")
2602         ObjectReference xy = getLocalRef(bpe.thread().frame(1), "dontinline_callee", "xy", XYVAL_NAME);
2603     }
2604 }
2605 
2606 class EADeoptFrameAfterReadLocalObject_02Target extends EATestCaseBaseTarget {
2607 
2608     public void dontinline_testMethod() {
2609         XYVal xy  = new XYVal(1, 1);
2610         dontinline_callee(xy);      // xy is ArgEscape, debugger acquires ref to xy from callee
2611         synchronized (xy) {         // Locking is eliminated.
2612             xy.x++;
2613             xy.y++;
2614         }
2615     }
2616 
2617     public void dontinline_callee(XYVal xy) {
2618         dontinline_brkpt();              // Debugger reads xy.
2619                                          // There are no virtual objects or eliminated locks.
2620     }
2621 
2622     @Override
2623     public void setUp() {
2624         super.setUp();
2625         testMethodDepth = 2;
2626     }
2627 
2628     @Override
2629     public boolean testFrameShouldBeDeoptimized() {
2630         // Graal does not provide debug info about arg escape objects, therefore the frame is not deoptimized
2631         return !UseJVMCICompiler && super.testFrameShouldBeDeoptimized();
2632     }
2633 }
2634 
2635 /////////////////////////////////////////////////////////////////////////////
2636 
2637 /**
2638  * Similar to {@link EADeoptFrameAfterReadLocalObject_02} there is an ArgEscape object xy, but in
2639  * contrast it is not in the parameter list of a call when the debugger reads an object.
2640  * Therefore the frame of the test method should not be deoptimized
2641  */
2642 class EADeoptFrameAfterReadLocalObject_02B extends EATestCaseBaseDebugger {
2643 
2644     public void runTestCase() throws Exception {
2645         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2646         printStack(bpe.thread());
2647         @SuppressWarnings("unused")
2648         ObjectReference xy = getLocalRef(bpe.thread().frame(1), "dontinline_callee", "xy", XYVAL_NAME);
2649     }
2650 }
2651 
2652 class EADeoptFrameAfterReadLocalObject_02BTarget extends EATestCaseBaseTarget {
2653 
2654     public void dontinline_testMethod() {
2655         XYVal xy  = new XYVal(1, 1);
2656         dontinline_make_arg_escape(xy);  // because of this call xy is ArgEscape
2657         dontinline_callee();             // xy is ArgEscape, but not a parameter of this call
2658         synchronized (xy) {              // Locking is eliminated.
2659             xy.x++;
2660             xy.y++;
2661         }
2662     }
2663 
2664     public void dontinline_callee() {
2665         @SuppressWarnings("unused")
2666         XYVal xy  = new XYVal(2, 2);
2667         dontinline_brkpt();              // Debugger reads xy.
2668                                          // No need to deoptimize the caller frame
2669     }
2670 
2671     @Override
2672     public void setUp() {
2673         super.setUp();
2674         testMethodDepth = 2;
2675     }
2676 
2677     @Override
2678     public boolean testFrameShouldBeDeoptimized() {
2679         return false;
2680     }
2681 }
2682 
2683 /////////////////////////////////////////////////////////////////////////////
2684 
2685 /**
2686  * Similar to {@link EADeoptFrameAfterReadLocalObject_02} there is an ArgEscape object xy in
2687  * dontinline_testMethod() which is being passed as parameter when the debugger accesses a local object.
2688  * Nevertheless dontinline_testMethod must not be deoptimized because there is an entry frame
2689  * between it and the frame accessed by the debugger.
2690  */
2691 class EADeoptFrameAfterReadLocalObject_02C extends EATestCaseBaseDebugger {
2692 
2693     public void runTestCase() throws Exception {
2694         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2695         printStack(bpe.thread());
2696         @SuppressWarnings("unused")
2697         ObjectReference xy = getLocalRef(bpe.thread().frame(1), "dontinline_callee_accessed_by_debugger", "xy", XYVAL_NAME);
2698     }
2699 }
2700 
2701 class EADeoptFrameAfterReadLocalObject_02CTarget extends EATestCaseBaseTarget {
2702 
2703     public void dontinline_testMethod() {
2704         XYVal xy  = new XYVal(1, 1);
2705         dontinline_callee(xy);           // xy is ArgEscape and being passed as parameter
2706         synchronized (xy) {              // Locking is eliminated.
2707             xy.x++;
2708             xy.y++;
2709         }
2710     }
2711 
2712     public void dontinline_callee(XYVal xy) {
2713         if (warmupDone) {
2714             dontinline_call_with_entry_frame(this, "dontinline_callee_accessed_by_debugger");
2715         }
2716     }
2717 
2718     public void dontinline_callee_accessed_by_debugger() {
2719         @SuppressWarnings("unused")
2720         XYVal xy  = new XYVal(2, 2);
2721         dontinline_brkpt();              // Debugger reads xy.
2722                                          // No need to deoptimize the caller frame
2723     }
2724 
2725     @Override
2726     public void setUp() {
2727         super.setUp();
2728         testMethodDepth = 8;
2729     }
2730 
2731     @Override
2732     public boolean testFrameShouldBeDeoptimized() {
2733         return false;
2734     }
2735 }
2736 
2737 /////////////////////////////////////////////////////////////////////////////
2738 
2739 /**
2740  * Let xy be NoEscape whose allocation cannot be eliminated (e.g. because of
2741  * -XX:-EliminateAllocations).  The holding compiled frame has to be deoptimized when debugger
2742  * accesses xy because the following field accesses get eliminated.  Note: there are no EA based
2743  * optimizations at the escape point.
2744  */
2745 class EADeoptFrameAfterReadLocalObject_03 extends EATestCaseBaseDebugger {
2746 
2747     public void runTestCase() throws Exception {
2748         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2749         printStack(bpe.thread());
2750         ObjectReference xy = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "xy");
2751         setField(xy, "x", env.vm().mirrorOf(1));
2752     }
2753 }
2754 
2755 class EADeoptFrameAfterReadLocalObject_03Target extends EATestCaseBaseTarget {
2756 
2757     public void dontinline_testMethod() {
2758         XYVal xy = new XYVal(0, 1);
2759         dontinline_brkpt();              // Debugger reads xy, when there are no virtual objects or
2760                                          // eliminated locks in scope and modifies xy.x
2761         iResult = xy.x + xy.y;           // Loads are replaced by constants 0 and 1.
2762     }
2763 
2764     @Override
2765     public int getExpectedIResult() {
2766         return 1 + 1;
2767     }
2768 }
2769 
2770 /////////////////////////////////////////////////////////////////////////////
2771 //
2772 // Monitor info tests
2773 //
2774 /////////////////////////////////////////////////////////////////////////////
2775 
2776 class EAGetOwnedMonitorsTarget extends EATestCaseBaseTarget {
2777 
2778     public long checkSum;
2779 
2780     public void dontinline_testMethod() {
2781         XYVal l1 = new XYVal(4, 2);
2782         synchronized (l1) {
2783             dontinline_endlessLoop();
2784         }
2785     }
2786 
2787     @Override
2788     public void setUp() {
2789         super.setUp();
2790         testMethodDepth = 2;
2791         loopCount = 3;
2792     }
2793 
2794     public void warmupDone() {
2795         super.warmupDone();
2796         msg("enter 'endless' loop by setting loopCount = Long.MAX_VALUE");
2797         loopCount = Long.MAX_VALUE; // endless loop
2798     }
2799 }
2800 
2801 class EAGetOwnedMonitors extends EATestCaseBaseDebugger {
2802 
2803     public void runTestCase() throws Exception {
2804         msg("resume");
2805         env.vm().resume();
2806         waitUntilTargetHasEnteredEndlessLoop();
2807         // In contrast to JVMTI, JDWP requires a target thread to be suspended, before the owned monitors can be queried
2808         msg("suspend target");
2809         env.targetMainThread.suspend();
2810         msg("Get owned monitors");
2811         List<ObjectReference> monitors = env.targetMainThread.ownedMonitors();
2812         Asserts.assertEQ(monitors.size(), 1, "unexpected number of owned monitors");
2813         terminateEndlessLoop();
2814     }
2815 }
2816 
2817 /////////////////////////////////////////////////////////////////////////////
2818 
2819 class EAEntryCountTarget extends EATestCaseBaseTarget {
2820 
2821     public long checkSum;
2822 
2823     public void dontinline_testMethod() {
2824         XYVal l1 = new XYVal(4, 2);
2825         synchronized (l1) {
2826             inline_testMethod2(l1);
2827         }
2828     }
2829 
2830     public void inline_testMethod2(XYVal l1) {
2831         synchronized (l1) {
2832             dontinline_endlessLoop();
2833         }
2834     }
2835 
2836     @Override
2837     public void setUp() {
2838         super.setUp();
2839         testMethodDepth = 2;
2840         loopCount = 3;
2841     }
2842 
2843     public void warmupDone() {
2844         super.warmupDone();
2845         msg("enter 'endless' loop by setting loopCount = Long.MAX_VALUE");
2846         loopCount = Long.MAX_VALUE; // endless loop
2847     }
2848 }
2849 
2850 class EAEntryCount extends EATestCaseBaseDebugger {
2851 
2852     public void runTestCase() throws Exception {
2853         msg("resume");
2854         env.vm().resume();
2855         waitUntilTargetHasEnteredEndlessLoop();
2856         // In contrast to JVMTI, JDWP requires a target thread to be suspended, before the owned monitors can be queried
2857         msg("suspend target");
2858         env.targetMainThread.suspend();
2859         msg("Get owned monitors");
2860         List<ObjectReference> monitors = env.targetMainThread.ownedMonitors();
2861         Asserts.assertEQ(monitors.size(), 1, "unexpected number of owned monitors");
2862         msg("Get entry count");
2863         int entryCount = monitors.get(0).entryCount();
2864         Asserts.assertEQ(entryCount, 2, "wrong entry count");
2865         terminateEndlessLoop();
2866     }
2867 }
2868 
2869 /////////////////////////////////////////////////////////////////////////////
2870 //
2871 // PopFrame tests
2872 //
2873 /////////////////////////////////////////////////////////////////////////////
2874 
2875 /**
2876  * PopFrame into caller frame with scalar replaced objects.
2877  */
2878 class EAPopFrameNotInlined extends EATestCaseBaseDebugger {
2879 
2880     public void runTestCase() throws Exception {
2881         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2882         printStack(bpe.thread());
2883         msg("PopFrame");
2884         bpe.thread().popFrames(bpe.thread().frame(0));
2885         msg("PopFrame DONE");
2886     }
2887 
2888     @Override
2889     public boolean shouldSkip() {
2890         // And Graal currently doesn't support PopFrame
2891         return super.shouldSkip() || env.targetVMOptions.UseJVMCICompiler;
2892     }
2893 }
2894 
2895 class EAPopFrameNotInlinedTarget extends EATestCaseBaseTarget {
2896 
2897     public void dontinline_testMethod() {
2898         XYVal xy = new XYVal(4, 2);
2899         dontinline_brkpt();
2900         iResult = xy.x + xy.y;
2901     }
2902 
2903     @Override
2904     public boolean testFrameShouldBeDeoptimized() {
2905         // Test is only performed after the frame pop.
2906         // Then dontinline_testMethod is interpreted.
2907         return false;
2908     }
2909 
2910     @Override
2911     public int getExpectedIResult() {
2912         return 4 + 2;
2913     }
2914 
2915     @Override
2916     public boolean shouldSkip() {
2917         // And Graal currently doesn't support PopFrame
2918         return super.shouldSkip() || UseJVMCICompiler;
2919     }
2920 }
2921 
2922 /////////////////////////////////////////////////////////////////////////////
2923 
2924 /**
2925  * Pop frames into {@link EAPopFrameNotInlinedReallocFailureTarget#dontinline_testMethod()} which
2926  * holds scalar replaced objects. In preparation of the pop frame operations the vm eagerly
2927  * reallocates scalar replaced objects to avoid failures when actually popping the frames. We provoke
2928  * a reallocation failures and expect {@link VMOutOfMemoryException}.
2929  */
2930 class EAPopFrameNotInlinedReallocFailure extends EATestCaseBaseDebugger {
2931 
2932     public void runTestCase() throws Exception {
2933         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
2934         ThreadReference thread = bpe.thread();
2935         printStack(thread);
2936         // frame[0]: EATestCaseBaseTarget.dontinline_brkpt()
2937         // frame[1]: EAPopFrameNotInlinedReallocFailureTarget.dontinline_consume_all_memory_brkpt()
2938         // frame[2]: EAPopFrameNotInlinedReallocFailureTarget.dontinline_testMethod()
2939         // frame[3]: EATestCaseBaseTarget.run()
2940         // frame[4]: EATestsTarget.main(java.lang.String[])
2941         msg("PopFrame");
2942         boolean coughtOom = false;
2943         try {
2944             // try to pop dontinline_consume_all_memory_brkpt
2945             thread.popFrames(thread.frame(1));
2946         } catch (VMOutOfMemoryException oom) {
2947             // as expected
2948             msg("cought OOM");
2949             coughtOom  = true;
2950         }
2951         freeAllMemory();
2952         // We succeeded to pop just one frame. When we continue, we will call dontinline_brkpt() again.
2953         Asserts.assertTrue(coughtOom, "PopFrame should have triggered an OOM exception in target");
2954         String expectedTopFrame = "dontinline_consume_all_memory_brkpt";
2955         Asserts.assertEQ(expectedTopFrame, thread.frame(0).location().method().name());
2956         printStack(thread);
2957     }
2958 
2959     @Override
2960     public boolean shouldSkip() {
2961         // OOMEs because of realloc failures with DeoptimizeObjectsALot are too random.
2962         // And Graal currently doesn't provide all information about non-escaping objects in debug info
2963         return super.shouldSkip() ||
2964                 !env.targetVMOptions.EliminateAllocations ||
2965                 // With ZGC the OOME is not always thrown as expected
2966                 env.targetVMOptions.ZGCIsSelected ||
2967                 env.targetVMOptions.DeoptimizeObjectsALot ||
2968                 env.targetVMOptions.UseJVMCICompiler;
2969     }
2970 }
2971 
2972 class EAPopFrameNotInlinedReallocFailureTarget extends EATestCaseBaseTarget {
2973 
2974     public boolean doneAlready;
2975 
2976     public void dontinline_testMethod() {
2977         long a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};                // scalar replaced
2978         Vector10 v = new Vector10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);  // scalar replaced
2979         dontinline_consume_all_memory_brkpt();
2980         lResult = a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] + a[8] + a[9]
2981                + v.i0 + v.i1 + v.i2 + v.i3 + v.i4 + v.i5 + v.i6 + v.i7 + v.i8 + v.i9;
2982     }
2983 
2984     public void dontinline_consume_all_memory_brkpt() {
2985         if (warmupDone && !doneAlready) {
2986             doneAlready = true;
2987             consumeAllMemory(); // provoke reallocation failure
2988             dontinline_brkpt();
2989         }
2990     }
2991 
2992     @Override
2993     public void setUp() {
2994         super.setUp();
2995         testMethodDepth = 2;
2996     }
2997 
2998     @Override
2999     public long getExpectedLResult() {
3000         long n = 10;
3001         return 2*n*(n+1)/2;
3002     }
3003 
3004     @Override
3005     public boolean shouldSkip() {
3006         // OOMEs because of realloc failures with DeoptimizeObjectsALot are too random.
3007         // And Graal currently doesn't provide all information about non-escaping objects in debug info
3008         return super.shouldSkip() ||
3009                 !EliminateAllocations ||
3010                 // With ZGC the OOME is not always thrown as expected
3011                 ZGCIsSelected ||
3012                 DeoptimizeObjectsALot ||
3013                 UseJVMCICompiler;
3014     }
3015 }
3016 
3017 /////////////////////////////////////////////////////////////////////////////
3018 
3019 /**
3020  * Pop inlined top frame dropping into method with scalar replaced opjects.
3021  */
3022 class EAPopInlinedMethodWithScalarReplacedObjectsReallocFailure extends EATestCaseBaseDebugger {
3023 
3024     public void runTestCase() throws Exception {
3025         ThreadReference thread = env.targetMainThread;
3026         env.vm().resume();
3027         waitUntilTargetHasEnteredEndlessLoop();
3028 
3029         thread.suspend();
3030         printStack(thread);
3031         // frame[0]: EAPopInlinedMethodWithScalarReplacedObjectsReallocFailureTarget.inlinedCallForcedToReturn()
3032         // frame[1]: EAPopInlinedMethodWithScalarReplacedObjectsReallocFailureTarget.dontinline_testMethod()
3033         // frame[2]: EATestCaseBaseTarget.run()
3034 
3035         msg("Pop Frames");
3036         boolean coughtOom = false;
3037         try {
3038             thread.popFrames(thread.frame(0));    // Request pop frame of inlinedCallForcedToReturn()
3039                                                   // reallocation is triggered here
3040         } catch (VMOutOfMemoryException oom) {
3041             // as expected
3042             msg("cought OOM");
3043             coughtOom = true;
3044         }
3045         printStack(thread);
3046         // frame[0]: EAPopInlinedMethodWithScalarReplacedObjectsReallocFailureTarget.inlinedCallForcedToReturn()
3047         // frame[1]: EAPopInlinedMethodWithScalarReplacedObjectsReallocFailureTarget.dontinline_testMethod()
3048         // frame[2]: EATestCaseBaseTarget.run()
3049 
3050         freeAllMemory();
3051         setField(testCase, "loopCount", env.vm().mirrorOf(0)); // terminate loop
3052         Asserts.assertTrue(coughtOom, "PopFrame should have triggered an OOM exception in target");
3053         String expectedTopFrame = "inlinedCallForcedToReturn";
3054         Asserts.assertEQ(expectedTopFrame, thread.frame(0).location().method().name());
3055     }
3056 
3057     @Override
3058     public boolean shouldSkip() {
3059         // OOMEs because of realloc failures with DeoptimizeObjectsALot are too random.
3060         // And Graal currently doesn't provide all information about non-escaping objects in debug info
3061         return super.shouldSkip() ||
3062                 !env.targetVMOptions.EliminateAllocations ||
3063                 // With ZGC the OOME is not always thrown as expected
3064                 env.targetVMOptions.ZGCIsSelected ||
3065                 env.targetVMOptions.DeoptimizeObjectsALot ||
3066                 env.targetVMOptions.UseJVMCICompiler;
3067     }
3068 }
3069 
3070 class EAPopInlinedMethodWithScalarReplacedObjectsReallocFailureTarget extends EATestCaseBaseTarget {
3071 
3072     public long checkSum;
3073 
3074     public void dontinline_testMethod() {
3075         long a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};                // scalar replaced
3076         Vector10 v = new Vector10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);  // scalar replaced
3077         long l = inlinedCallForcedToReturn();
3078         lResult = a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] + a[8] + a[9]
3079                + v.i0 + v.i1 + v.i2 + v.i3 + v.i4 + v.i5 + v.i6 + v.i7 + v.i8 + v.i9;
3080     }
3081 
3082     public long inlinedCallForcedToReturn() {
3083         long cs = checkSum;
3084         dontinline_consumeAllMemory();
3085         while (loopCount-- > 0) {
3086             targetIsInLoop = true;
3087             checkSum += checkSum % ++cs;
3088         }
3089         loopCount = 3;
3090         targetIsInLoop = false;
3091         return checkSum;
3092     }
3093 
3094     public void dontinline_consumeAllMemory() {
3095         if (warmupDone && (loopCount > 3)) {
3096             consumeAllMemory();
3097         }
3098     }
3099 
3100     @Override
3101     public long getExpectedLResult() {
3102         long n = 10;
3103         return 2*n*(n+1)/2;
3104     }
3105 
3106     @Override
3107     public void setUp() {
3108         super.setUp();
3109         loopCount = 3;
3110     }
3111 
3112     public void warmupDone() {
3113         super.warmupDone();
3114         msg("enter 'endless' loop by setting loopCount = Long.MAX_VALUE");
3115         loopCount = Long.MAX_VALUE; // endless loop
3116     }
3117 
3118     @Override
3119     public boolean shouldSkip() {
3120         // OOMEs because of realloc failures with DeoptimizeObjectsALot are too random.
3121         // And Graal currently doesn't provide all information about non-escaping objects in debug info
3122         return super.shouldSkip() ||
3123                 !EliminateAllocations ||
3124                 // With ZGC the OOME is not always thrown as expected
3125                 ZGCIsSelected ||
3126                 DeoptimizeObjectsALot ||
3127                 UseJVMCICompiler;
3128     }
3129 }
3130 
3131 /////////////////////////////////////////////////////////////////////////////
3132 //
3133 // ForceEarlyReturn tests
3134 //
3135 /////////////////////////////////////////////////////////////////////////////
3136 
3137 /**
3138  * ForceEarlyReturn into caller frame with scalar replaced objects.
3139  */
3140 class EAForceEarlyReturnNotInlined extends EATestCaseBaseDebugger {
3141 
3142     public void runTestCase() throws Exception {
3143         BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
3144         ThreadReference thread = bpe.thread();
3145         printStack(thread);
3146         // frame[0]: EATestCaseBaseTarget.dontinline_brkpt()
3147         // frame[1]: EATestCaseBaseTarget.dontinline_brkpt_iret()
3148         // frame[2]: EAForceEarlyReturnNotInlinedTarget.dontinline_testMethod()
3149         // frame[3]: EATestCaseBaseTarget.run()
3150         // frame[4]: EATestsTarget.main(java.lang.String[])
3151 
3152         msg("Step out");
3153         env.stepOut(thread);                               // return from dontinline_brkpt
3154         printStack(thread);
3155         msg("ForceEarlyReturn");
3156         thread.forceEarlyReturn(env.vm().mirrorOf(43));    // return from dontinline_brkpt_iret,
3157                                                            // does not trigger reallocation in contrast to PopFrame
3158         msg("Step over line");
3159         env.stepOverLine(thread);                          // reallocation is triggered here
3160         printStack(thread);
3161         msg("ForceEarlyReturn DONE");
3162     }
3163 
3164     @Override
3165     public boolean shouldSkip() {
3166         // Graal currently doesn't support Force Early Return
3167         return super.shouldSkip() || env.targetVMOptions.UseJVMCICompiler;
3168     }
3169 }
3170 
3171 class EAForceEarlyReturnNotInlinedTarget extends EATestCaseBaseTarget {
3172 
3173     public void dontinline_testMethod() {
3174         XYVal xy = new XYVal(4, 2);
3175         int i = dontinline_brkpt_iret();
3176         iResult = xy.x + xy.y + i;
3177     }
3178 
3179     @Override
3180     public int getExpectedIResult() {
3181         return 4 + 2 + 43;
3182     }
3183 
3184     @Override
3185     public void setUp() {
3186         super.setUp();
3187         testMethodDepth = 2;
3188     }
3189 
3190     public boolean testFrameShouldBeDeoptimized() {
3191         return true; // because of stepping
3192     }
3193 
3194     @Override
3195     public boolean shouldSkip() {
3196         // Graal currently doesn't support Force Early Return
3197         return super.shouldSkip() || UseJVMCICompiler;
3198     }
3199 }
3200 
3201 /////////////////////////////////////////////////////////////////////////////
3202 
3203 /**
3204  * ForceEarlyReturn at safepoint in frame with scalar replaced objects.
3205  */
3206 class EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjects extends EATestCaseBaseDebugger {
3207 
3208     public void runTestCase() throws Exception {
3209         ThreadReference thread = env.targetMainThread;
3210         env.vm().resume();
3211         waitUntilTargetHasEnteredEndlessLoop();
3212 
3213         thread.suspend();
3214         printStack(thread);
3215         // frame[0]: EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsTarget.inlinedCallForcedToReturn()
3216         // frame[1]: EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsTarget.dontinline_testMethod()
3217         // frame[2]: EATestCaseBaseTarget.run()
3218 
3219         msg("ForceEarlyReturn");
3220         thread.forceEarlyReturn(env.vm().mirrorOf(43));    // Request force return 43 from inlinedCallForcedToReturn()
3221                                                            // reallocation is triggered here
3222         msg("Step over instruction to do the forced return");
3223         env.stepOverInstruction(thread);
3224         printStack(thread);
3225         msg("ForceEarlyReturn DONE");
3226     }
3227 
3228     @Override
3229     public boolean shouldSkip() {
3230         // Graal currently doesn't support Force Early Return
3231         return super.shouldSkip() || env.targetVMOptions.UseJVMCICompiler;
3232     }
3233 }
3234 
3235 class EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsTarget extends EATestCaseBaseTarget {
3236 
3237     public int checkSum;
3238 
3239     public void dontinline_testMethod() {
3240         XYVal xy = new XYVal(4, 2);
3241         int i = inlinedCallForcedToReturn();
3242         iResult = xy.x + xy.y + i;
3243     }
3244 
3245     public int inlinedCallForcedToReturn() {               // forced to return 43
3246         int i = checkSum;
3247         while (loopCount-- > 0) {
3248             targetIsInLoop = true;
3249             checkSum += checkSum % ++i;
3250         }
3251         loopCount = 3;
3252         targetIsInLoop = false;
3253         return checkSum;
3254     }
3255 
3256     @Override
3257     public int getExpectedIResult() {
3258         return 4 + 2 + 43;
3259     }
3260 
3261     @Override
3262     public void setUp() {
3263         super.setUp();
3264         testMethodDepth = 2;
3265         loopCount = 3;
3266     }
3267 
3268     public void warmupDone() {
3269         super.warmupDone();
3270         msg("enter 'endless' loop by setting loopCount = Long.MAX_VALUE");
3271         loopCount = Long.MAX_VALUE; // endless loop
3272     }
3273 
3274     public boolean testFrameShouldBeDeoptimized() {
3275         return true; // because of stepping
3276     }
3277 
3278     @Override
3279     public boolean shouldSkip() {
3280         // Graal currently doesn't support Force Early Return
3281         return super.shouldSkip() || UseJVMCICompiler;
3282     }
3283 }
3284 
3285 /////////////////////////////////////////////////////////////////////////////
3286 
3287 /**
3288  * ForceEarlyReturn with reallocation failure.
3289  */
3290 class EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsReallocFailure extends EATestCaseBaseDebugger {
3291 
3292     public void runTestCase() throws Exception {
3293         ThreadReference thread = env.targetMainThread;
3294         env.vm().resume();
3295         waitUntilTargetHasEnteredEndlessLoop();
3296 
3297         thread.suspend();
3298         printStack(thread);
3299         // frame[0]: EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsReallocFailureTarget.inlinedCallForcedToReturn()
3300         // frame[1]: EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsReallocFailureTarget.dontinline_testMethod()
3301         // frame[2]: EATestCaseBaseTarget.run()
3302 
3303         msg("ForceEarlyReturn");
3304         boolean coughtOom = false;
3305         try {
3306             thread.forceEarlyReturn(env.vm().mirrorOf(43));    // Request force return 43 from inlinedCallForcedToReturn()
3307                                                                // reallocation is triggered here
3308         } catch (VMOutOfMemoryException oom) {
3309             // as expected
3310             msg("cought OOM");
3311             coughtOom   = true;
3312         }
3313         freeAllMemory();
3314         Asserts.assertTrue(coughtOom, "ForceEarlyReturn should have triggered an OOM exception in target");
3315         printStack(thread);
3316         msg("ForceEarlyReturn(2)");
3317         thread.forceEarlyReturn(env.vm().mirrorOf(43));
3318         msg("Step over instruction to do the forced return");
3319         env.stepOverInstruction(thread);
3320         printStack(thread);
3321         msg("ForceEarlyReturn DONE");
3322     }
3323 
3324     @Override
3325     public boolean shouldSkip() {
3326         // OOMEs because of realloc failures with DeoptimizeObjectsALot are too random.
3327         // And Graal currently doesn't support Force Early Return
3328         return super.shouldSkip() ||
3329                 !env.targetVMOptions.EliminateAllocations ||
3330                 // With ZGC the OOME is not always thrown as expected
3331                 env.targetVMOptions.ZGCIsSelected ||
3332                 env.targetVMOptions.DeoptimizeObjectsALot ||
3333                 env.targetVMOptions.UseJVMCICompiler;
3334     }
3335 }
3336 
3337 class EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsReallocFailureTarget extends EATestCaseBaseTarget {
3338 
3339     public int checkSum;
3340 
3341     public void dontinline_testMethod() {
3342         long a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};                // scalar replaced
3343         Vector10 v = new Vector10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);  // scalar replaced
3344         long l = inlinedCallForcedToReturn();
3345         lResult = a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] + a[8] + a[9]
3346                + v.i0 + v.i1 + v.i2 + v.i3 + v.i4 + v.i5 + v.i6 + v.i7 + v.i8 + v.i9 + l;
3347     }
3348 
3349     public long inlinedCallForcedToReturn() {                      // forced to return 43
3350         long cs = checkSum;
3351         dontinline_consumeAllMemory();
3352         while (loopCount-- > 0) {
3353             targetIsInLoop = true;
3354             checkSum += checkSum % ++cs;
3355         }
3356         loopCount = 3;
3357         targetIsInLoop = false;
3358         return checkSum;
3359     }
3360 
3361     public void dontinline_consumeAllMemory() {
3362         if (warmupDone) {
3363             consumeAllMemory();
3364         }
3365     }
3366 
3367     @Override
3368     public long getExpectedLResult() {
3369         long n = 10;
3370         return 2*n*(n+1)/2 + 43;
3371     }
3372 
3373     @Override
3374     public void setUp() {
3375         super.setUp();
3376         testMethodDepth = 2;
3377         loopCount = 3;
3378     }
3379 
3380     public void warmupDone() {
3381         super.warmupDone();
3382         msg("enter 'endless' loop by setting loopCount = Long.MAX_VALUE");
3383         loopCount = Long.MAX_VALUE; // endless loop
3384     }
3385 
3386     @Override
3387     public boolean shouldSkip() {
3388         // OOMEs because of realloc failures with DeoptimizeObjectsALot are too random.
3389         // And Graal currently doesn't support Force Early Return
3390         return super.shouldSkip() ||
3391                 !EliminateAllocations ||
3392                 // With ZGC the OOME is not always thrown as expected
3393                 ZGCIsSelected ||
3394                 DeoptimizeObjectsALot ||
3395                 UseJVMCICompiler;
3396     }
3397 }
3398 
3399 /////////////////////////////////////////////////////////////////////////////
3400 //
3401 // Get Instances of ReferenceType
3402 //
3403 /////////////////////////////////////////////////////////////////////////////
3404 
3405 /**
3406  * Check if instances of a type are found even if they are scalar replaced.  To stress the
3407  * implementation a little more, the instances should be retrieved while the target is running.
3408  */
3409 class EAGetInstancesOfReferenceType extends EATestCaseBaseDebugger {
3410 
3411     public void runTestCase() throws Exception {
3412         printStack(env.targetMainThread);
3413         ReferenceType cls = ((ClassObjectReference)getField(testCase, "cls")).reflectedType();
3414         msg("reflected type is " + cls);
3415         msg("resume");
3416         env.vm().resume();
3417         waitUntilTargetHasEnteredEndlessLoop();
3418         // do this while thread is running!
3419         msg("Retrieve instances of " + cls.name());
3420         List<ObjectReference> instances = cls.instances(10);
3421         Asserts.assertEQ(instances.size(), 3, "unexpected number of instances of " + cls.name());
3422         // invariant: main thread is suspended at the end of the test case
3423         msg("suspend");
3424         env.targetMainThread.suspend();
3425         terminateEndlessLoop();
3426     }
3427 }
3428 
3429 class EAGetInstancesOfReferenceTypeTarget extends EATestCaseBaseTarget {
3430 
3431     public long checkSum;
3432 
3433     public static Class<LocalXYVal> cls = LocalXYVal.class;
3434 
3435     public static class LocalXYVal {
3436         public int x, y;
3437 
3438         public LocalXYVal(int x, int y) {
3439             this.x = x; this.y = y;
3440         }
3441     }
3442 
3443     @Override
3444     public void dontinline_testMethod() {
3445         LocalXYVal p1 = new LocalXYVal(4, 2);
3446         LocalXYVal p2 = new LocalXYVal(5, 3);
3447         LocalXYVal p3 = new LocalXYVal(6, 4);
3448         dontinline_endlessLoop();
3449         iResult = p1.x+p1.y + p2.x+p2.y + p3.x+p3.y;
3450     }
3451 
3452     @Override
3453     public int getExpectedIResult() {
3454         return 6+8+10;
3455     }
3456 
3457     @Override
3458     public void setUp() {
3459         super.setUp();
3460         testMethodDepth = 2;
3461         loopCount = 3;
3462     }
3463 
3464     public void warmupDone() {
3465         super.warmupDone();
3466         msg("enter 'endless' loop by setting loopCount = Long.MAX_VALUE");
3467         loopCount = Long.MAX_VALUE; // endless loop
3468     }
3469 }
3470 
3471 
3472 // End of test case collection
3473 /////////////////////////////////////////////////////////////////////////////
3474 
3475 /////////////////////////////////////////////////////////////////////////////
3476 // Helper classes
3477 class XYVal {
3478 
3479     public int x, y;
3480 
3481     public XYVal(int x, int y) {
3482         this.x = x;
3483         this.y = y;
3484     }
3485 
3486     /**
3487      * Note that we don't use a sync block here because javac would generate an synthetic exception
3488      * handler for the synchronized block that catches Throwable E, unlocks and throws E
3489      * again. The throw bytecode causes the BCEscapeAnalyzer to set the escape state to GlobalEscape
3490      * (see comment on exception handlers in BCEscapeAnalyzer::iterate_blocks())
3491      */
3492     public synchronized void dontinline_sync_method(EATestCaseBaseTarget target) {
3493         target.dontinline_brkpt();
3494     }
3495 
3496     /**
3497      * Just like {@link #dontinline_sync_method(EATestCaseBaseTarget)} but without the call to
3498      * {@link EATestCaseBaseTarget#dontinline_brkpt()}.
3499      */
3500     public synchronized void dontinline_sync_method_no_brkpt(EATestCaseBaseTarget target) {
3501     }
3502 }
3503 
3504 class Vector10 {
3505     int i0, i1, i2, i3, i4, i5, i6, i7, i8, i9;
3506     public Vector10(int j0, int j1, int j2, int j3, int j4, int j5, int j6, int j7, int j8, int j9) {
3507         i0=j0; i1=j1; i2=j2; i3=j3; i4=j4; i5=j5; i6=j6; i7=j7; i8=j8; i9=j9;
3508     }
3509 }
3510 
3511 class ILFDO {
3512 
3513     public int i;
3514     public int i2;
3515     public long l;
3516     public long l2;
3517     public float f;
3518     public float f2;
3519     public double d;
3520     public double d2;
3521     public Long o;
3522     public Long o2;
3523 
3524     public ILFDO(int i,
3525                  int i2,
3526                  long l,
3527                  long l2,
3528                  float f,
3529                  float f2,
3530                  double d,
3531                  double d2,
3532                  Long o,
3533                  Long o2) {
3534         this.i = i;
3535         this.i2 = i2;
3536         this.l = l;
3537         this.l2 = l2;
3538         this.f = f;
3539         this.f2 = f2;
3540         this.d = d;
3541         this.d2 = d2;
3542         this.o = o;
3543         this.o2 = o2;
3544     }
3545 
3546 }