Path: blob/master/test/jdk/com/sun/jdi/EATests.java
41152 views
/*1* Copyright (c) 2020 SAP SE. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324/**25* @test26* @bug 822774527* @summary Collection of test cases that check if optimizations based on escape analysis are reverted just before non-escaping objects escape through JVMTI.28* @author Richard Reingruber richard DOT reingruber AT sap DOT com29*30* @requires ((vm.compMode == "Xmixed") & vm.compiler2.enabled)31* @library /test/lib /test/hotspot/jtreg32*33* @run build TestScaffold VMConnection TargetListener TargetAdapter sun.hotspot.WhiteBox34* @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox35* @run compile -g EATests.java36* @run driver EATests37* -XX:+UnlockDiagnosticVMOptions38* -Xms256m -Xmx256m39* -Xbootclasspath/a:.40* -XX:CompileCommand=dontinline,*::dontinline_*41* -XX:+WhiteBoxAPI42* -Xbatch43* -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:+UseBiasedLocking44* @run driver EATests45* -XX:+UnlockDiagnosticVMOptions46* -Xms256m -Xmx256m47* -Xbootclasspath/a:.48* -XX:CompileCommand=dontinline,*::dontinline_*49* -XX:+WhiteBoxAPI50* -Xbatch51* -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:-EliminateLocks -XX:+EliminateNestedLocks -XX:+UseBiasedLocking -XX:-UseOptoBiasInlining52* @run driver EATests53* -XX:+UnlockDiagnosticVMOptions54* -Xms256m -Xmx256m55* -Xbootclasspath/a:.56* -XX:CompileCommand=dontinline,*::dontinline_*57* -XX:+WhiteBoxAPI58* -Xbatch59* -XX:+DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:+UseBiasedLocking60* @run driver EATests61* -XX:+UnlockDiagnosticVMOptions62* -Xms256m -Xmx256m63* -Xbootclasspath/a:.64* -XX:CompileCommand=dontinline,*::dontinline_*65* -XX:+WhiteBoxAPI66* -Xbatch67* -XX:-DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:+UseBiasedLocking68* @run driver EATests69* -XX:+UnlockDiagnosticVMOptions70* -Xms256m -Xmx256m71* -Xbootclasspath/a:.72* -XX:CompileCommand=dontinline,*::dontinline_*73* -XX:+WhiteBoxAPI74* -Xbatch75* -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:-UseBiasedLocking76* @run driver EATests77* -XX:+UnlockDiagnosticVMOptions78* -Xms256m -Xmx256m79* -Xbootclasspath/a:.80* -XX:CompileCommand=dontinline,*::dontinline_*81* -XX:+WhiteBoxAPI82* -Xbatch83* -XX:+DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:-UseBiasedLocking84* @run driver EATests85* -XX:+UnlockDiagnosticVMOptions86* -Xms256m -Xmx256m87* -Xbootclasspath/a:.88* -XX:CompileCommand=dontinline,*::dontinline_*89* -XX:+WhiteBoxAPI90* -Xbatch91* -XX:-DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:-UseBiasedLocking92*93* @comment Excercise -XX:+DeoptimizeObjectsALot. Mostly to prevent bit-rot because the option is meant to stress object deoptimization94* with non-synthetic workloads.95* @run driver EATests96* -XX:+UnlockDiagnosticVMOptions97* -Xms256m -Xmx256m98* -Xbootclasspath/a:.99* -XX:CompileCommand=dontinline,*::dontinline_*100* -XX:+WhiteBoxAPI101* -Xbatch102* -XX:-DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:-UseBiasedLocking103* -XX:+IgnoreUnrecognizedVMOptions -XX:+DeoptimizeObjectsALot104*105*/106/**107* @test108* @bug 8227745109*110* @summary This is another configuration of EATests.java to test Graal. Some testcases are expected111* to fail because Graal does not provide all information about non-escaping objects in112* scope. These are skipped.113*114* @author Richard Reingruber richard DOT reingruber AT sap DOT com115*116* @requires ((vm.compMode == "Xmixed") & vm.graal.enabled)117*118* @library /test/lib /test/hotspot/jtreg119*120* @run build TestScaffold VMConnection TargetListener TargetAdapter sun.hotspot.WhiteBox121* @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox122* @run compile -g EATests.java123*124* @comment Test with Graal. Some testcases are expected to fail because Graal does not provide all information about non-escaping125* objects in scope. These are skipped.126* @run driver EATests127* -XX:+UnlockDiagnosticVMOptions128* -Xms256m -Xmx256m129* -Xbootclasspath/a:.130* -XX:CompileCommand=dontinline,*::dontinline_*131* -XX:+WhiteBoxAPI132* -Xbatch133* -XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler134*/135136import com.sun.jdi.*;137import com.sun.jdi.event.*;138import compiler.testlibrary.CompilerUtils;139import compiler.whitebox.CompilerWhiteBoxTest;140141import java.lang.reflect.Array;142import java.util.Arrays;143import java.util.List;144import java.util.Map;145import java.util.function.Function;146147import jdk.test.lib.Asserts;148import sun.hotspot.WhiteBox;149import sun.hotspot.gc.GC;150151152//153// ANALYZING TEST FAILURES154//155// - Executing just a single test case with the property EATests.onlytestcase.156//157// Example: java -DEATests.onlytestcase=<test case name> ... EATests158//159// - Interactive execution allows for attaching a native debugger, e.g. gdb160//161// Example: java -DEATests.interactive=true ... EATests162//163// - Java arguments to the test are passed as vm options to the debuggee:164//165// Example: java ... EATests -XX:+UseNewCode166//167168169170/////////////////////////////////////////////////////////////////////////////171//172// Shared base class for test cases for both, debugger and debuggee.173//174/////////////////////////////////////////////////////////////////////////////175176class EATestCaseBaseShared {177// In interactive mode we wait for a keypress before every test case.178public static final boolean INTERACTIVE =179System.getProperty("EATests.interactive") != null &&180System.getProperty("EATests.interactive").equals("true");181182// If the property is given, then just the test case it refers to is executed.183// Use it to diagnose test failures.184public static final String RUN_ONLY_TEST_CASE_PROPERTY = "EATests.onlytestcase";185public static final String RUN_ONLY_TEST_CASE = System.getProperty(RUN_ONLY_TEST_CASE_PROPERTY);186187public final String testCaseName;188189public EATestCaseBaseShared() {190String clName = getClass().getName();191int tidx = clName.lastIndexOf("Target");192testCaseName = tidx > 0 ? clName.substring(0, tidx) : clName;193}194195public boolean shouldSkip() {196return EATestCaseBaseShared.RUN_ONLY_TEST_CASE != null &&197EATestCaseBaseShared.RUN_ONLY_TEST_CASE.length() > 0 &&198!testCaseName.equals(EATestCaseBaseShared.RUN_ONLY_TEST_CASE);199}200}201202/////////////////////////////////////////////////////////////////////////////203//204// Target main class, i.e. the program to be debugged.205//206/////////////////////////////////////////////////////////////////////////////207208class EATestsTarget {209210public static void main(String[] args) {211EATestCaseBaseTarget.staticSetUp();212EATestCaseBaseTarget.staticSetUpDone();213214// Materializing test cases, i.e. reallocating objects on the heap215new EAMaterializeLocalVariableUponGetTarget() .run();216new EAGetWithoutMaterializeTarget() .run();217new EAMaterializeLocalAtObjectReturnTarget() .run();218new EAMaterializeLocalAtObjectPollReturnReturnTarget() .run();219new EAMaterializeIntArrayTarget() .run();220new EAMaterializeLongArrayTarget() .run();221new EAMaterializeFloatArrayTarget() .run();222new EAMaterializeDoubleArrayTarget() .run();223new EAMaterializeObjectArrayTarget() .run();224new EAMaterializeObjectWithConstantAndNotConstantValuesTarget() .run();225new EAMaterializeObjReferencedBy2LocalsTarget() .run();226new EAMaterializeObjReferencedBy2LocalsAndModifyTarget() .run();227new EAMaterializeObjReferencedBy2LocalsInDifferentVirtFramesTarget() .run();228new EAMaterializeObjReferencedBy2LocalsInDifferentVirtFramesAndModifyTarget() .run();229new EAMaterializeObjReferencedFromOperandStackTarget() .run();230new EAMaterializeLocalVariableUponGetAfterSetIntegerTarget() .run();231232// Relocking test cases233new EARelockingSimpleTarget() .run();234new EARelockingSimple_2Target() .run();235new EARelockingRecursiveTarget() .run();236new EARelockingNestedInflatedTarget() .run();237new EARelockingNestedInflated_02Target() .run();238new EARelockingArgEscapeLWLockedInCalleeFrameTarget() .run();239new EARelockingArgEscapeLWLockedInCalleeFrame_2Target() .run();240new EARelockingArgEscapeLWLockedInCalleeFrame_3Target() .run();241new EARelockingArgEscapeLWLockedInCalleeFrame_4Target() .run();242new EAGetOwnedMonitorsTarget() .run();243new EAEntryCountTarget() .run();244new EARelockingObjectCurrentlyWaitingOnTarget() .run();245246// Test cases that require deoptimization even though neither247// locks nor allocations are eliminated at the point where248// escape state is changed.249new EADeoptFrameAfterReadLocalObject_01Target() .run();250new EADeoptFrameAfterReadLocalObject_01BTarget() .run();251new EADeoptFrameAfterReadLocalObject_02Target() .run();252new EADeoptFrameAfterReadLocalObject_02BTarget() .run();253new EADeoptFrameAfterReadLocalObject_02CTarget() .run();254new EADeoptFrameAfterReadLocalObject_03Target() .run();255256// PopFrame test cases257new EAPopFrameNotInlinedTarget() .run();258new EAPopFrameNotInlinedReallocFailureTarget() .run();259new EAPopInlinedMethodWithScalarReplacedObjectsReallocFailureTarget() .run();260261// ForceEarlyReturn test cases262new EAForceEarlyReturnNotInlinedTarget() .run();263new EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsTarget() .run();264new EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsReallocFailureTarget().run();265266// Instances of ReferenceType267new EAGetInstancesOfReferenceTypeTarget() .run();268}269}270271/////////////////////////////////////////////////////////////////////////////272//273// Debugger main class274//275/////////////////////////////////////////////////////////////////////////////276277public class EATests extends TestScaffold {278279public TargetVMOptions targetVMOptions;280public ThreadReference targetMainThread;281282EATests(String args[]) {283super(args);284}285286public static void main(String[] args) throws Exception {287if (EATestCaseBaseShared.RUN_ONLY_TEST_CASE != null) {288args = Arrays.copyOf(args, args.length + 1);289args[args.length - 1] = "-D" + EATestCaseBaseShared.RUN_ONLY_TEST_CASE_PROPERTY + "=" + EATestCaseBaseShared.RUN_ONLY_TEST_CASE;290}291new EATests(args).startTests();292}293294public static class TargetVMOptions {295296public final boolean UseJVMCICompiler;297public final boolean EliminateAllocations;298public final boolean DeoptimizeObjectsALot;299public final boolean DoEscapeAnalysis;300public final boolean ZGCIsSelected;301302public TargetVMOptions(EATests env, ClassType testCaseBaseTargetClass) {303Value val;304val = testCaseBaseTargetClass.getValue(testCaseBaseTargetClass.fieldByName("DoEscapeAnalysis"));305DoEscapeAnalysis = ((PrimitiveValue) val).booleanValue();306// Escape analysis is a prerequisite for scalar replacement (EliminateAllocations)307val = testCaseBaseTargetClass.getValue(testCaseBaseTargetClass.fieldByName("EliminateAllocations"));308EliminateAllocations = DoEscapeAnalysis && ((PrimitiveValue) val).booleanValue();309val = testCaseBaseTargetClass.getValue(testCaseBaseTargetClass.fieldByName("DeoptimizeObjectsALot"));310DeoptimizeObjectsALot = ((PrimitiveValue) val).booleanValue();311val = testCaseBaseTargetClass.getValue(testCaseBaseTargetClass.fieldByName("UseJVMCICompiler"));312UseJVMCICompiler = ((PrimitiveValue) val).booleanValue();313val = testCaseBaseTargetClass.getValue(testCaseBaseTargetClass.fieldByName("ZGCIsSelected"));314ZGCIsSelected = ((PrimitiveValue) val).booleanValue();315}316317}318319// Execute known test cases320protected void runTests() throws Exception {321String targetProgName = EATestsTarget.class.getName();322msg("starting to main method in class " + targetProgName);323startToMain(targetProgName);324msg("resuming to EATestCaseBaseTarget.staticSetUpDone()V");325targetMainThread = resumeTo("EATestCaseBaseTarget", "staticSetUpDone", "()V").thread();326Location loc = targetMainThread.frame(0).location();327Asserts.assertEQ("staticSetUpDone", loc.method().name());328329targetVMOptions = new TargetVMOptions(this, (ClassType) loc.declaringType());330331// Materializing test cases, i.e. reallocating objects on the heap332new EAMaterializeLocalVariableUponGet() .run(this);333new EAGetWithoutMaterialize() .run(this);334new EAMaterializeLocalAtObjectReturn() .run(this);335new EAMaterializeLocalAtObjectPollReturnReturn() .run(this);336new EAMaterializeIntArray() .run(this);337new EAMaterializeLongArray() .run(this);338new EAMaterializeFloatArray() .run(this);339new EAMaterializeDoubleArray() .run(this);340new EAMaterializeObjectArray() .run(this);341new EAMaterializeObjectWithConstantAndNotConstantValues() .run(this);342new EAMaterializeObjReferencedBy2Locals() .run(this);343new EAMaterializeObjReferencedBy2LocalsAndModify() .run(this);344new EAMaterializeObjReferencedBy2LocalsInDifferentVirtFrames() .run(this);345new EAMaterializeObjReferencedBy2LocalsInDifferentVirtFramesAndModify() .run(this);346new EAMaterializeObjReferencedFromOperandStack() .run(this);347new EAMaterializeLocalVariableUponGetAfterSetInteger() .run(this);348349// Relocking test cases350new EARelockingSimple() .run(this);351new EARelockingSimple_2() .run(this);352new EARelockingRecursive() .run(this);353new EARelockingNestedInflated() .run(this);354new EARelockingNestedInflated_02() .run(this);355new EARelockingArgEscapeLWLockedInCalleeFrame() .run(this);356new EARelockingArgEscapeLWLockedInCalleeFrame_2() .run(this);357new EARelockingArgEscapeLWLockedInCalleeFrame_3() .run(this);358new EARelockingArgEscapeLWLockedInCalleeFrame_4() .run(this);359new EAGetOwnedMonitors() .run(this);360new EAEntryCount() .run(this);361new EARelockingObjectCurrentlyWaitingOn() .run(this);362363// Test cases that require deoptimization even though neither364// locks nor allocations are eliminated at the point where365// escape state is changed.366new EADeoptFrameAfterReadLocalObject_01() .run(this);367new EADeoptFrameAfterReadLocalObject_01B() .run(this);368new EADeoptFrameAfterReadLocalObject_02() .run(this);369new EADeoptFrameAfterReadLocalObject_02B() .run(this);370new EADeoptFrameAfterReadLocalObject_02C() .run(this);371new EADeoptFrameAfterReadLocalObject_03() .run(this);372373// PopFrame test cases374new EAPopFrameNotInlined() .run(this);375new EAPopFrameNotInlinedReallocFailure() .run(this);376new EAPopInlinedMethodWithScalarReplacedObjectsReallocFailure() .run(this);377378// ForceEarlyReturn test cases379new EAForceEarlyReturnNotInlined() .run(this);380new EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjects() .run(this);381new EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsReallocFailure().run(this);382383// Instances of ReferenceType384new EAGetInstancesOfReferenceType() .run(this);385386// resume the target listening for events387listenUntilVMDisconnect();388}389390// Print a Message391public void msg(String m) {392System.out.println();393System.out.println("###(Debugger) " + m);394System.out.println();395}396397// Highlighted message.398public void msgHL(String m) {399System.out.println();400System.out.println();401System.out.println("##########################################################");402System.out.println("### " + m);403System.out.println("### ");404System.out.println();405System.out.println();406}407}408409/////////////////////////////////////////////////////////////////////////////410//411// Base class for debugger side of test cases.412//413/////////////////////////////////////////////////////////////////////////////414415abstract class EATestCaseBaseDebugger extends EATestCaseBaseShared {416417protected EATests env;418419public ObjectReference testCase;420421public static final String TARGET_TESTCASE_BASE_NAME = EATestCaseBaseTarget.class.getName();422423public static final String XYVAL_NAME = XYVal.class.getName();424425public abstract void runTestCase() throws Exception;426427public void run(EATests env) {428this.env = env;429if (shouldSkip()) {430msg("skipping " + testCaseName);431return;432}433try {434msgHL("Executing test case " + getClass().getName());435env.testFailed = false;436437if (INTERACTIVE)438env.waitForInput();439440resumeToWarmupDone();441runTestCase();442Asserts.assertTrue(env.targetMainThread.isSuspended(), "must be suspended after the testcase");443resumeToTestCaseDone();444checkPostConditions();445} catch (Exception e) {446Asserts.fail("Unexpected exception in test case " + getClass().getName(), e);447}448}449450/**451* Set a breakpoint in the given method and resume all threads. The452* breakpoint is configured to suspend just the thread that reaches it453* instead of all threads. This is important when running with graal.454*/455public BreakpointEvent resumeTo(String clsName, String methodName, String signature) {456boolean suspendThreadOnly = true;457return env.resumeTo(clsName, methodName, signature, suspendThreadOnly);458}459460public void resumeToWarmupDone() throws Exception {461msg("resuming to " + TARGET_TESTCASE_BASE_NAME + ".warmupDone()V");462resumeTo(TARGET_TESTCASE_BASE_NAME, "warmupDone", "()V");463testCase = env.targetMainThread.frame(0).thisObject();464}465466public void resumeToTestCaseDone() {467msg("resuming to " + TARGET_TESTCASE_BASE_NAME + ".testCaseDone()V");468resumeTo(TARGET_TESTCASE_BASE_NAME, "testCaseDone", "()V");469}470471public void checkPostConditions() throws Exception {472Asserts.assertFalse(env.getExceptionCaught(), "Uncaught exception in Debuggee");473474String testName = getClass().getName();475if (!env.testFailed) {476env.println(testName + ": passed");477} else {478throw new Exception(testName + ": failed");479}480}481482public void printStack(ThreadReference thread) throws Exception {483msg("Debuggee Stack:");484List<StackFrame> stack_frames = thread.frames();485int i = 0;486for (StackFrame ff : stack_frames) {487System.out.println("frame[" + i++ +"]: " + ff.location().method() + " (bci:" + ff.location().codeIndex() + ")");488}489}490491public void msg(String m) {492env.msg(m);493}494495public void msgHL(String m) {496env.msgHL(m);497}498499// See Field Descriptors in The Java Virtual Machine Specification500// (https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html#jvms-4.3.2)501enum FD {502I, // int503J, // long504F, // float505D, // double506}507508// Map field descriptor to jdi type string509public static final Map<FD, String> FD2JDIArrType = Map.of(FD.I, "int[]", FD.J, "long[]", FD.F, "float[]", FD.D, "double[]");510511// Map field descriptor to PrimitiveValue getter512public static final Function<PrimitiveValue, Integer> v2I = PrimitiveValue::intValue;513public static final Function<PrimitiveValue, Long> v2J = PrimitiveValue::longValue;514public static final Function<PrimitiveValue, Float> v2F = PrimitiveValue::floatValue;515public static final Function<PrimitiveValue, Double> v2D = PrimitiveValue::doubleValue;516Map<FD, Function<PrimitiveValue, ?>> FD2getter = Map.of(FD.I, v2I, FD.J, v2J, FD.F, v2F, FD.D, v2D);517518/**519* Retrieve array of primitive values referenced by a local variable in target and compare with520* an array of expected values.521* @param frame Frame in the target holding the local variable522* @param lName Name of the local variable referencing the array to be retrieved523* @param desc Array element type given as field descriptor.524* @param expVals Array of expected values.525* @throws Exception526*/527protected void checkLocalPrimitiveArray(StackFrame frame, String lName, FD desc, Object expVals) throws Exception {528String lType = FD2JDIArrType.get(desc);529Asserts.assertNotNull(lType, "jdi type not found");530Asserts.assertEQ(EATestCaseBaseTarget.TESTMETHOD_DEFAULT_NAME, frame .location().method().name());531List<LocalVariable> localVars = frame.visibleVariables();532msg("Check if the local array variable '" + lName + "' in " + EATestCaseBaseTarget.TESTMETHOD_DEFAULT_NAME + " has the expected elements: ");533boolean found = false;534for (LocalVariable lv : localVars) {535if (lv.name().equals(lName)) {536found = true;537Value lVal = frame.getValue(lv);538Asserts.assertNotNull(lVal);539Asserts.assertEQ(lVal.type().name(), lType);540ArrayReference aRef = (ArrayReference) lVal;541Asserts.assertEQ(3, aRef.length());542// now check the elements543for (int i = 0; i < aRef.length(); i++) {544Object actVal = FD2getter.get(desc).apply((PrimitiveValue)aRef.getValue(i));545Object expVal = Array.get(expVals, i);546Asserts.assertEQ(expVal, actVal, "checking element at index " + i);547}548}549}550Asserts.assertTrue(found);551msg("OK.");552}553554/**555* Retrieve array of objects referenced by a local variable in target and compare with an array556* of expected values.557* @param frame Frame in the target holding the local variable558* @param lName Name of the local variable referencing the array to be retrieved559* @param lType Local type, e.g. java.lang.Long[]560* @param expVals Array of expected values.561* @throws Exception562*/563protected void checkLocalObjectArray(StackFrame frame, String lName, String lType, ObjectReference[] expVals) throws Exception {564Asserts.assertEQ(EATestCaseBaseTarget.TESTMETHOD_DEFAULT_NAME, frame .location().method().name());565List<LocalVariable> localVars = frame.visibleVariables();566msg("Check if the local array variable '" + lName + "' in " + EATestCaseBaseTarget.TESTMETHOD_DEFAULT_NAME + " has the expected elements: ");567boolean found = false;568for (LocalVariable lv : localVars) {569if (lv.name().equals(lName)) {570found = true;571Value lVal = frame.getValue(lv);572Asserts.assertNotNull(lVal);573Asserts.assertEQ(lType, lVal.type().name());574ArrayReference aRef = (ArrayReference) lVal;575Asserts.assertEQ(3, aRef.length());576// now check the elements577for (int i = 0; i < aRef.length(); i++) {578ObjectReference actVal = (ObjectReference)aRef.getValue(i);579Asserts.assertSame(expVals[i], actVal, "checking element at index " + i);580}581}582}583Asserts.assertTrue(found);584msg("OK.");585}586587/**588* Retrieve a reference held by a local variable in the given frame. Check if the frame's method589* is the expected method if the retrieved local value has the expected type and is not null.590* @param frame The frame to retrieve the local variable value from.591* @param expectedMethodName The name of the frames method should match the expectedMethodName.592* @param lName The name of the local variable which is read.593* @param expectedType Is the expected type of the object referenced by the local variable.594* @return595* @throws Exception596*/597protected ObjectReference getLocalRef(StackFrame frame, String expectedMethodName, String lName, String expectedType) throws Exception {598Asserts.assertEQ(expectedMethodName, frame.location().method().name());599List<LocalVariable> localVars = frame.visibleVariables();600msg("Get and check local variable '" + lName + "' in " + expectedMethodName);601ObjectReference lRef = null;602for (LocalVariable lv : localVars) {603if (lv.name().equals(lName)) {604Value lVal = frame.getValue(lv);605Asserts.assertNotNull(lVal);606Asserts.assertEQ(expectedType, lVal.type().name());607lRef = (ObjectReference) lVal;608break;609}610}611Asserts.assertNotNull(lRef, "Local variable '" + lName + "' not found");612msg("OK.");613return lRef;614}615616/**617* Retrieve a reference held by a local variable in the given frame. Check if the frame's method618* matches {@link EATestCaseBaseTarget#TESTMETHOD_DEFAULT_NAME} if the retrieved local value has619* the expected type and is not null.620* @param frame The frame to retrieve the local variable value from.621* @param expectedMethodName The name of the frames method should match the expectedMethodName.622* @param lName The name of the local variable which is read.623* @param expectedType Is the expected type of the object referenced by the local variable.624* @return625* @throws Exception626*/627protected ObjectReference getLocalRef(StackFrame frame, String lType, String lName) throws Exception {628return getLocalRef(frame, EATestCaseBaseTarget.TESTMETHOD_DEFAULT_NAME, lName, lType);629}630631/**632* Set the value of a local variable in the given frame. Check if the frame's method is the expected method.633* @param frame The frame holding the local variable.634* @param expectedMethodName The expected name of the frame's method.635* @param lName The name of the local variable to change.636* @param val The new value of the local variable.637* @throws Exception638*/639public void setLocal(StackFrame frame, String expectedMethodName, String lName, Value val) throws Exception {640Asserts.assertEQ(expectedMethodName, frame.location().method().name());641List<LocalVariable> localVars = frame.visibleVariables();642msg("Set local variable '" + lName + "' = " + val + " in " + expectedMethodName);643for (LocalVariable lv : localVars) {644if (lv.name().equals(lName)) {645frame.setValue(lv, val);646break;647}648}649msg("OK.");650}651652/**653* Set the value of a local variable in the given frame. Check if the frame's method matches654* {@link EATestCaseBaseTarget#TESTMETHOD_DEFAULT_NAME}.655* @param frame The frame holding the local variable.656* @param expectedMethodName The expected name of the frame's method.657* @param lName The name of the local variable to change.658* @param val The new value of the local variable.659* @throws Exception660*/661public void setLocal(StackFrame frame, String lName, Value val) throws Exception {662setLocal(frame, EATestCaseBaseTarget.TESTMETHOD_DEFAULT_NAME, lName, val);663}664665/**666* Check if a field has the expected primitive value.667* @param o Object holding the field.668* @param desc Field descriptor.669* @param fName Field name670* @param expVal Expected primitive value671* @throws Exception672*/673protected void checkPrimitiveField(ObjectReference o, FD desc, String fName, Object expVal) throws Exception {674msg("check field " + fName);675ReferenceType rt = o.referenceType();676Field fld = rt.fieldByName(fName);677Value val = o.getValue(fld);678Object actVal = FD2getter.get(desc).apply((PrimitiveValue) val);679Asserts.assertEQ(expVal, actVal, "field '" + fName + "' has unexpected value.");680msg("ok");681}682683/**684* Check if a field references the expected object.685* @param obj Object holding the field.686* @param fName Field name687* @param expVal Object expected to be referenced by the field688* @throws Exception689*/690protected void checkObjField(ObjectReference obj, String fName, ObjectReference expVal) throws Exception {691msg("check field " + fName);692ReferenceType rt = obj.referenceType();693Field fld = rt.fieldByName(fName);694Value actVal = obj.getValue(fld);695Asserts.assertEQ(expVal, actVal, "field '" + fName + "' has unexpected value.");696msg("ok");697}698699protected void setField(ObjectReference obj, String fName, Value val) throws Exception {700msg("set field " + fName + " = " + val);701ReferenceType rt = obj.referenceType();702Field fld = rt.fieldByName(fName);703obj.setValue(fld, val);704msg("ok");705}706707protected Value getField(ObjectReference obj, String fName) throws Exception {708msg("get field " + fName);709ReferenceType rt = obj.referenceType();710Field fld = rt.fieldByName(fName);711Value val = obj.getValue(fld);712msg("result : " + val);713return val;714}715716/**717* Free the memory consumed in the target by {@link EATestCaseBaseTarget#consumedMemory}718* @throws Exception719*/720public void freeAllMemory() throws Exception {721msg("free consumed memory");722setField(testCase, "consumedMemory", null);723}724725/**726* @return The value of {@link EATestCaseBaseTarget#targetIsInLoop}. The target must set that field to true as soon as it727* enters the endless loop.728* @throws Exception729*/730public boolean targetHasEnteredEndlessLoop() throws Exception {731Value v = getField(testCase, "targetIsInLoop");732return ((PrimitiveValue) v).booleanValue();733}734735/**736* Poll {@link EATestCaseBaseTarget#targetIsInLoop} and return if it is found to be true.737* @throws Exception738*/739public void waitUntilTargetHasEnteredEndlessLoop() throws Exception {740while(!targetHasEnteredEndlessLoop()) {741msg("Target has not yet entered the loop. Sleep 200ms.");742try { Thread.sleep(200); } catch (InterruptedException e) { /*ignore */ }743}744}745746/**747* Set {@link EATestCaseBaseTarget#doLoop} to <code>false</code>. This will allow the target to748* leave the endless loop.749* @throws Exception750*/751public void terminateEndlessLoop() throws Exception {752msg("terminate loop");753setField(testCase, "doLoop", env.vm().mirrorOf(false));754}755}756757/////////////////////////////////////////////////////////////////////////////758//759// Base class for debuggee side of test cases.760//761/////////////////////////////////////////////////////////////////////////////762763abstract class EATestCaseBaseTarget extends EATestCaseBaseShared implements Runnable {764765/**766* The target must set that field to true as soon as it enters the endless loop.767*/768public volatile boolean targetIsInLoop;769770/**771* Used for busy loops. See {@link #dontinline_endlessLoop()}.772*/773public volatile long loopCount;774775/**776* Used in {@link EATestCaseBaseDebugger#terminateEndlessLoop()} to signal target to leave the endless loop.777*/778public volatile boolean doLoop;779780public long checkSum;781782public static final String TESTMETHOD_DEFAULT_NAME = "dontinline_testMethod";783784public static final WhiteBox WB = WhiteBox.getWhiteBox();785786public static boolean unbox(Boolean value, boolean dflt) {787return value == null ? dflt : value;788}789790// Some of the fields are only read by the debugger791public static final boolean UseJVMCICompiler = unbox(WB.getBooleanVMFlag("UseJVMCICompiler"), false);792public static final boolean DoEscapeAnalysis = unbox(WB.getBooleanVMFlag("DoEscapeAnalysis"), UseJVMCICompiler);793public static final boolean EliminateAllocations = unbox(WB.getBooleanVMFlag("EliminateAllocations"), UseJVMCICompiler);794public static final boolean DeoptimizeObjectsALot = WB.getBooleanVMFlag("DeoptimizeObjectsALot");795public static final long BiasedLockingBulkRebiasThreshold = WB.getIntxVMFlag("BiasedLockingBulkRebiasThreshold");796public static final long BiasedLockingBulkRevokeThreshold = WB.getIntxVMFlag("BiasedLockingBulkRevokeThreshold");797public static final boolean ZGCIsSelected = GC.Z.isSelected();798799public String testMethodName;800public int testMethodDepth;801802// Results produced by dontinline_testMethod()803public int iResult;804public long lResult;805public float fResult;806public double dResult;807808809public boolean warmupDone;810811public volatile Object biasToBeRevoked;812813// an object with an inflated monitor814public static XYVal inflatedLock;815public static Thread inflatorThread;816public static boolean inflatedLockIsPermanentlyInflated;817818public static int NOT_CONST_1I = 1;819public static long NOT_CONST_1L = 1L;820public static float NOT_CONST_1F = 1.1F;821public static double NOT_CONST_1D = 1.1D;822823public static Long NOT_CONST_1_OBJ = Long.valueOf(1);824825826public static final Long CONST_2_OBJ = Long.valueOf(2);827public static final Long CONST_3_OBJ = Long.valueOf(3);828829/**830* Main driver of a test case.831* <ul>832* <li> Skips test case if not selected (see {@link EATestCaseBaseShared#RUN_ONLY_TEST_CASE}833* <li> Call {@link #setUp()}834* <li> warm-up and compile {@link #dontinline_testMethod()} (see {@link #compileTestMethod()}835* <li> calling {@link #dontinline_testMethod()}836* <li> checking the result (see {@link #checkResult()}837* <ul>838*/839public void run() {840try {841if (shouldSkip()) {842msg("skipping " + testCaseName);843return;844}845setUp();846msg(testCaseName + " is up and running.");847compileTestMethod();848msg(testCaseName + " warmup done.");849warmupDone();850checkCompLevel();851dontinline_testMethod();852checkResult();853msg(testCaseName + " done.");854testCaseDone();855} catch (Exception e) {856Asserts.fail("Caught unexpected exception", e);857}858}859860public static void staticSetUp() {861inflatedLock = new XYVal(1, 1);862synchronized (inflatedLock) {863inflatorThread = new Thread("Lock Inflator (test thread)") {864@Override865public void run() {866synchronized (inflatedLock) {867inflatedLockIsPermanentlyInflated = true;868inflatedLock.notify(); // main thread869while (true) {870try {871// calling wait() on a monitor will cause inflation into a heavy monitor872inflatedLock.wait();873} catch (InterruptedException e) { /* ignored */ }874}875}876}877};878inflatorThread.setDaemon(true);879inflatorThread.start();880881// wait until the lock is permanently inflated by the inflatorThread882while(!inflatedLockIsPermanentlyInflated) {883try {884inflatedLock.wait(); // until inflated885} catch (InterruptedException e1) { /* ignored */ }886}887}888}889890// Debugger will set breakpoint here to sync with target.891public static void staticSetUpDone() {892}893894public void setUp() {895testMethodDepth = 1;896testMethodName = TESTMETHOD_DEFAULT_NAME;897}898899public abstract void dontinline_testMethod() throws Exception;900901public int dontinline_brkpt_iret() {902dontinline_brkpt();903return 42;904}905906/**907* It is a common protocol to have the debugger set a breakpoint in this method and have {@link908* #dontinline_testMethod()} call it and then perform some test actions on debugger side.909* After that it is checked if a frame of {@link #dontinline_testMethod()} is found at the910* expected depth on stack and if it is (not) marked for deoptimization as expected.911*/912public void dontinline_brkpt() {913// will set breakpoint here after warmup914if (warmupDone) {915// check if test method is at expected depth916StackTraceElement[] frames = Thread.currentThread().getStackTrace();917int stackTraceDepth = testMethodDepth + 1; // ignore java.lang.Thread.getStackTrace()918Asserts.assertEQ(testMethodName, frames[stackTraceDepth].getMethodName(),919testCaseName + ": test method not found at depth " + testMethodDepth);920// check if the frame is (not) deoptimized as expected921if (!DeoptimizeObjectsALot) {922if (testFrameShouldBeDeoptimized()) {923Asserts.assertTrue(WB.isFrameDeoptimized(testMethodDepth+1),924testCaseName + ": expected test method frame at depth " + testMethodDepth + " to be deoptimized");925} else {926Asserts.assertFalse(WB.isFrameDeoptimized(testMethodDepth+1),927testCaseName + ": expected test method frame at depth " + testMethodDepth + " not to be deoptimized");928}929}930}931}932933/**934* Some test cases run busy endless loops by initializing {@link #loopCount}935* to {@link Long#MAX_VALUE} after warm-up and then counting down to 0 in their main test method.936* During warm-up {@link #loopCount} is initialized to a small value.937*/938public long dontinline_endlessLoop() {939long cs = checkSum;940doLoop = true;941while (loopCount-- > 0 && doLoop) {942targetIsInLoop = true;943checkSum += checkSum % ++cs;944}945loopCount = 3;946targetIsInLoop = false;947return checkSum;948}949950public boolean testFrameShouldBeDeoptimized() {951return DoEscapeAnalysis;952}953954public void warmupDone() {955warmupDone = true;956}957958// Debugger will set breakpoint here to sync with target.959public void testCaseDone() {960}961962public void compileTestMethod() throws Exception {963int callCount = CompilerWhiteBoxTest.THRESHOLD;964while (callCount-- > 0) {965dontinline_testMethod();966}967}968969public void checkCompLevel() {970java.lang.reflect.Method m = null;971try {972m = getClass().getMethod(TESTMETHOD_DEFAULT_NAME);973} catch (NoSuchMethodException | SecurityException e) {974Asserts.fail("could not check compilation level of", e);975}976int highestLevel = CompilerUtils.getMaxCompilationLevel();977int compLevel = WB.getMethodCompilationLevel(m);978if (!UseJVMCICompiler) {979Asserts.assertEQ(highestLevel, compLevel,980m + " not on expected compilation level");981} else {982// Background compilation (-Xbatch) will block a thread with timeout983// (see CompileBroker::wait_for_jvmci_completion()). Therefore it is984// possible to reach here before the main test method is compiled.985// In that case we wait for it to be compiled.986while (compLevel != highestLevel) {987msg(TESTMETHOD_DEFAULT_NAME + " is compiled on level " + compLevel +988". Wait until highes level (" + highestLevel + ") is reached.");989try {990Thread.sleep(200);991} catch (InterruptedException e) { /* ignored */ }992compLevel = WB.getMethodCompilationLevel(m);993}994}995}996997// to be overridden as appropriate998public int getExpectedIResult() {999return 0;1000}10011002// to be overridden as appropriate1003public long getExpectedLResult() {1004return 0;1005}10061007// to be overridden as appropriate1008public float getExpectedFResult() {1009return 0f;1010}10111012// to be overridden as appropriate1013public double getExpectedDResult() {1014return 0d;1015}10161017private void checkResult() {1018Asserts.assertEQ(getExpectedIResult(), iResult, "checking iResult");1019Asserts.assertEQ(getExpectedLResult(), lResult, "checking lResult");1020Asserts.assertEQ(getExpectedFResult(), fResult, "checking fResult");1021Asserts.assertEQ(getExpectedDResult(), dResult, "checking dResult");1022}10231024public void msg(String m) {1025System.out.println();1026System.out.println("###(Target) " + m);1027System.out.println();1028}10291030// The object passed will be ArgEscape if it was NoEscape before.1031public final void dontinline_make_arg_escape(XYVal xy) {1032}10331034/**1035* Call a method indirectly using reflection. The indirection is a limit for escape1036* analysis in the sense that the VM need not search beyond for frames that might have1037* an object being read by an JVMTI agent as ArgEscape.1038* @param receiver The receiver object of the call.1039* @param methodName The name of the method to be called.1040*/1041public final void dontinline_call_with_entry_frame(Object receiver, String methodName) {1042Asserts.assertTrue(warmupDone, "We want to take the slow path through jni, so don't call in warmup");10431044Class<?> cls = receiver.getClass();1045Class<?>[] none = {};10461047java.lang.reflect.Method m;1048try {1049m = cls.getDeclaredMethod(methodName, none);1050m.invoke(receiver);1051} catch (Exception e) {1052Asserts.fail("Call through reflection failed", e);1053}1054}10551056/**1057* Trigger bulk rebiasing for the given class by creating new instances and calling <code> hashCode() </code> on them.1058* @param cls The class to bulk rebias1059*/1060public void dontinline_bulkRebiasAfterWarmup(Class<?> cls) {1061if (warmupDone) {1062try {1063for (int i=0; i < BiasedLockingBulkRebiasThreshold+2; i++) {1064biasToBeRevoked = cls.getDeclaredConstructor(int.class, int.class).newInstance(1, 1);1065synchronized (biasToBeRevoked) { // bias towards current thread1066checkSum++;1067}1068biasToBeRevoked.hashCode(); // calling hashCode triggers revocation1069}1070} catch (Throwable e) {1071Asserts.fail("failed to create new instance of " + cls.getName(), e);1072}1073}1074}10751076/**1077* Trigger bulk revoke of biases for the given class by creating new instances and calling <code> hashCode() </code> on them.1078* @param cls The class to bulk rebias1079*/1080public void dontinline_bulkRevokeAfterWarmup(Class<?> cls) {1081if (warmupDone) {1082try {1083for (int i=0; i < BiasedLockingBulkRevokeThreshold+2; i++) {1084biasToBeRevoked = cls.getDeclaredConstructor(int.class, int.class).newInstance(1, 1);1085synchronized (biasToBeRevoked) { // bias towards current thread1086checkSum++;1087}1088biasToBeRevoked.hashCode(); // calling hashCode triggers revocation1089}1090} catch (Throwable e) {1091Asserts.fail("failed to create new instance of " + cls.getName(), e);1092}1093}1094}10951096static class LinkedList {1097LinkedList l;1098public long[] array;1099public LinkedList(LinkedList l, int size) {1100this.array = size > 0 ? new long[size] : null;1101this.l = l;1102}1103}11041105public LinkedList consumedMemory;11061107public void consumeAllMemory() {1108msg("consume all memory");1109int size = 128 * 1024 * 1024;1110while(true) {1111try {1112while(true) {1113consumedMemory = new LinkedList(consumedMemory, size);1114}1115} catch(OutOfMemoryError oom) {1116if (size == 0) break;1117}1118size = size / 2;1119}1120}1121}11221123/////////////////////////////////////////////////////////////////////////////1124//1125// Test Cases1126//1127/////////////////////////////////////////////////////////////////////////////11281129// make sure a compiled frame is not deoptimized if an escaping local is accessed1130class EAGetWithoutMaterializeTarget extends EATestCaseBaseTarget {11311132public XYVal getAway;11331134public void dontinline_testMethod() {1135XYVal xy = new XYVal(4, 2);1136getAway = xy; // allocated object escapes1137dontinline_brkpt();1138iResult = xy.x + xy.y;1139}11401141@Override1142public int getExpectedIResult() {1143return 4 + 2;1144}11451146@Override1147public boolean testFrameShouldBeDeoptimized() {1148return false;1149}1150}11511152class EAGetWithoutMaterialize extends EATestCaseBaseDebugger {11531154public void runTestCase() throws Exception {1155BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");1156printStack(bpe.thread());1157ObjectReference o = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "xy");1158checkPrimitiveField(o, FD.I, "x", 4);1159checkPrimitiveField(o, FD.I, "y", 2);1160}1161}11621163/////////////////////////////////////////////////////////////////////////////11641165//1166// Tests the following:1167//1168// 1. Debugger can obtain a reference to a scalar replaced object R from java thread J.1169// See runTestCase.1170//1171// 2. Subsequent modifications of R by J are noticed by the debugger.1172// See checkPostConditions.1173//1174class EAMaterializeLocalVariableUponGet extends EATestCaseBaseDebugger {11751176private ObjectReference o;11771178public void runTestCase() throws Exception {1179BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");1180printStack(bpe.thread());1181// check 1.1182o = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "xy");1183// o is referenced in checkPostConditions() and must not be gc'ed.1184o.disableCollection();1185checkPrimitiveField(o, FD.I, "x", 4);1186checkPrimitiveField(o, FD.I, "y", 2);1187}11881189@Override1190public void checkPostConditions() throws Exception {1191super.checkPostConditions();1192// check 2.1193checkPrimitiveField(o, FD.I, "x", 5);1194}1195}11961197class EAMaterializeLocalVariableUponGetTarget extends EATestCaseBaseTarget {11981199public void dontinline_testMethod() {1200XYVal xy = new XYVal(4, 2);1201dontinline_brkpt(); // Debugger obtains scalar replaced object at this point.1202xy.x += 1; // Change scalar replaced object after debugger obtained a reference to it.1203iResult = xy.x + xy.y;1204}12051206@Override1207public int getExpectedIResult() {1208return 4 + 2 + 1;1209}1210}12111212/////////////////////////////////////////////////////////////////////////////12131214// Test if an eliminated object can be reallocated in a frame with an active1215// call that will return another object1216class EAMaterializeLocalAtObjectReturn extends EATestCaseBaseDebugger {1217public void runTestCase() throws Exception {1218BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");1219printStack(bpe.thread());1220ObjectReference o = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "xy");1221checkPrimitiveField(o, FD.I, "x", 4);1222checkPrimitiveField(o, FD.I, "y", 2);1223}1224}12251226class EAMaterializeLocalAtObjectReturnTarget extends EATestCaseBaseTarget {1227@Override1228public void setUp() {1229super.setUp();1230testMethodDepth = 2;1231}12321233public void dontinline_testMethod() {1234XYVal xy = new XYVal(4, 2);1235Integer io = // Read xy here triggers reallocation1236dontinline_brkpt_return_Integer();1237iResult = xy.x + xy.y + io;1238}12391240public Integer dontinline_brkpt_return_Integer() {1241// We can't break directly in this method, as this results in making1242// the test method not entrant caused by an existing dependency1243dontinline_brkpt();1244return Integer.valueOf(23);1245}12461247@Override1248public int getExpectedIResult() {1249return 4 + 2 + 23;1250}1251}12521253/////////////////////////////////////////////////////////////////////////////12541255// Test if an eliminated object can be reallocated *just* before a call returns an object.1256// (See CompiledMethod::is_at_poll_return())1257// Details: the callee method has just one safepoint poll at the return. The other safepoint1258// is at the end of an iteration of the endless loop. We can detect if we suspended the target1259// there because the local xy is out of scope there.1260class EAMaterializeLocalAtObjectPollReturnReturn extends EATestCaseBaseDebugger {1261public void runTestCase() throws Exception {1262msg("Resume " + env.targetMainThread);1263env.vm().resume();1264waitUntilTargetHasEnteredEndlessLoop();1265ObjectReference o = null;1266int retryCount = 0;1267do {1268env.targetMainThread.suspend();1269printStack(env.targetMainThread);1270try {1271o = getLocalRef(env.targetMainThread.frame(0), XYVAL_NAME, "xy");1272} catch (Exception e) {1273++retryCount;1274msg("The local variable xy is out of scope because we suspended at the wrong bci. Resume and try again! (" + retryCount + ")");1275env.targetMainThread.resume();1276if ((retryCount % 10) == 0) {1277Thread.sleep(200);1278}1279}1280} while (o == null);1281checkPrimitiveField(o, FD.I, "x", 4);1282checkPrimitiveField(o, FD.I, "y", 2);1283terminateEndlessLoop();1284}1285}12861287class EAMaterializeLocalAtObjectPollReturnReturnTarget extends EATestCaseBaseTarget {1288@Override1289public void setUp() {1290super.setUp();1291loopCount = 3;1292doLoop = true;1293}12941295public void warmupDone() {1296super.warmupDone();1297msg("enter 'endless' loop by setting loopCount = Long.MAX_VALUE");1298loopCount = Long.MAX_VALUE; // endless loop1299}13001301public void dontinline_testMethod() {1302long result = 0;1303while (doLoop && loopCount-- > 0) {1304targetIsInLoop = true;1305XYVal xy = new XYVal(4, 2);1306Integer io = // Read xy here triggers reallocation just before the call returns1307dontinline_brkpt_return_Integer();1308result += xy.x + xy.y + io;1309} // Here is a second safepoint. We were suspended here if xy is not in scope.1310targetIsInLoop = false;1311lResult = result;1312}13131314public Integer dontinline_brkpt_return_Integer() {1315return Integer.valueOf(23);1316}13171318@Override1319public long getExpectedLResult() {1320return (Long.MAX_VALUE - loopCount) * (4+2+23);1321}1322}13231324/////////////////////////////////////////////////////////////////////////////1325// Test case collection that tests rematerialization of different1326// array types where the first element is always not constant and the1327// other elements are constants. Not constant values are stored in1328// the stack frame for rematerialization whereas constants are kept1329// in the debug info of the nmethod.13301331class EAMaterializeIntArrayTarget extends EATestCaseBaseTarget {13321333public void dontinline_testMethod() {1334int nums[] = {NOT_CONST_1I , 2, 3};1335dontinline_brkpt();1336iResult = nums[0] + nums[1] + nums[2];1337}13381339@Override1340public int getExpectedIResult() {1341return NOT_CONST_1I + 2 + 3;1342}1343}13441345class EAMaterializeIntArray extends EATestCaseBaseDebugger {1346public void runTestCase() throws Exception {1347BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");1348printStack(bpe.thread());1349int[] expectedVals = {1, 2, 3};1350checkLocalPrimitiveArray(bpe.thread().frame(1), "nums", FD.I, expectedVals);1351}1352}13531354/////////////////////////////////////////////////////////////////////////////13551356class EAMaterializeLongArrayTarget extends EATestCaseBaseTarget {13571358public void dontinline_testMethod() {1359long nums[] = {NOT_CONST_1L , 2, 3};1360dontinline_brkpt();1361lResult = nums[0] + nums[1] + nums[2];1362}13631364@Override1365public long getExpectedLResult() {1366return NOT_CONST_1L + 2 + 3;1367}1368}13691370class EAMaterializeLongArray extends EATestCaseBaseDebugger {1371public void runTestCase() throws Exception {1372BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");1373printStack(bpe.thread());1374long[] expectedVals = {1, 2, 3};1375checkLocalPrimitiveArray(bpe.thread().frame(1), "nums", FD.J, expectedVals);1376}1377}13781379/////////////////////////////////////////////////////////////////////////////13801381class EAMaterializeFloatArrayTarget extends EATestCaseBaseTarget {13821383public void dontinline_testMethod() {1384float nums[] = {NOT_CONST_1F , 2.2f, 3.3f};1385dontinline_brkpt();1386fResult = nums[0] + nums[1] + nums[2];1387}13881389@Override1390public float getExpectedFResult() {1391return NOT_CONST_1F + 2.2f + 3.3f;1392}1393}13941395class EAMaterializeFloatArray extends EATestCaseBaseDebugger {1396public void runTestCase() throws Exception {1397BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");1398printStack(bpe.thread());1399float[] expectedVals = {1.1f, 2.2f, 3.3f};1400checkLocalPrimitiveArray(bpe.thread().frame(1), "nums", FD.F, expectedVals);1401}1402}14031404/////////////////////////////////////////////////////////////////////////////14051406class EAMaterializeDoubleArrayTarget extends EATestCaseBaseTarget {14071408public void dontinline_testMethod() {1409double nums[] = {NOT_CONST_1D , 2.2d, 3.3d};1410dontinline_brkpt();1411dResult = nums[0] + nums[1] + nums[2];1412}14131414@Override1415public double getExpectedDResult() {1416return NOT_CONST_1D + 2.2d + 3.3d;1417}1418}14191420class EAMaterializeDoubleArray extends EATestCaseBaseDebugger {1421public void runTestCase() throws Exception {1422BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");1423printStack(bpe.thread());1424double[] expectedVals = {1.1d, 2.2d, 3.3d};1425checkLocalPrimitiveArray(bpe.thread().frame(1), "nums", FD.D, expectedVals);1426}1427}14281429/////////////////////////////////////////////////////////////////////////////14301431class EAMaterializeObjectArrayTarget extends EATestCaseBaseTarget {14321433public void dontinline_testMethod() {1434Long nums[] = {NOT_CONST_1_OBJ , CONST_2_OBJ, CONST_3_OBJ};1435dontinline_brkpt();1436lResult = nums[0] + nums[1] + nums[2];1437}14381439@Override1440public long getExpectedLResult() {1441return 1 + 2 + 3;1442}1443}14441445class EAMaterializeObjectArray extends EATestCaseBaseDebugger {1446public void runTestCase() throws Exception {1447BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");1448printStack(bpe.thread());1449ReferenceType clazz = bpe.thread().frame(0).location().declaringType();1450ObjectReference[] expectedVals = {1451(ObjectReference) clazz.getValue(clazz.fieldByName("NOT_CONST_1_OBJ")),1452(ObjectReference) clazz.getValue(clazz.fieldByName("CONST_2_OBJ")),1453(ObjectReference) clazz.getValue(clazz.fieldByName("CONST_3_OBJ"))1454};1455checkLocalObjectArray(bpe.thread().frame(1), "nums", "java.lang.Long[]", expectedVals);1456}1457}14581459/////////////////////////////////////////////////////////////////////////////14601461// Materialize an object whose fields have constant and not constant values at1462// the point where the object is materialized.1463class EAMaterializeObjectWithConstantAndNotConstantValuesTarget extends EATestCaseBaseTarget {14641465public void dontinline_testMethod() {1466ILFDO o = new ILFDO(NOT_CONST_1I, 2,1467NOT_CONST_1L, 2L,1468NOT_CONST_1F, 2.1F,1469NOT_CONST_1D, 2.1D,1470NOT_CONST_1_OBJ, CONST_2_OBJ1471);1472dontinline_brkpt();1473dResult =1474o.i + o.i2 + o.l + o.l2 + o.f + o.f2 + o.d + o.d2 + o.o + o.o2;1475}14761477@Override1478public double getExpectedDResult() {1479return 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;1480}1481}14821483class EAMaterializeObjectWithConstantAndNotConstantValues extends EATestCaseBaseDebugger {1484public void runTestCase() throws Exception {1485BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");1486printStack(bpe.thread());1487ObjectReference o = getLocalRef(bpe.thread().frame(1), "ILFDO", "o");1488checkPrimitiveField(o, FD.I, "i", 1);1489checkPrimitiveField(o, FD.I, "i2", 2);1490checkPrimitiveField(o, FD.J, "l", 1L);1491checkPrimitiveField(o, FD.J, "l2", 2L);1492checkPrimitiveField(o, FD.F, "f", 1.1f);1493checkPrimitiveField(o, FD.F, "f2", 2.1f);1494checkPrimitiveField(o, FD.D, "d", 1.1d);1495checkPrimitiveField(o, FD.D, "d2", 2.1d);1496ReferenceType clazz = bpe.thread().frame(1).location().declaringType();1497ObjectReference[] expVals = {1498(ObjectReference) clazz.getValue(clazz.fieldByName("NOT_CONST_1_OBJ")),1499(ObjectReference) clazz.getValue(clazz.fieldByName("CONST_2_OBJ")),1500};1501checkObjField(o, "o", expVals[0]);1502checkObjField(o, "o2", expVals[1]);1503}1504}15051506/////////////////////////////////////////////////////////////////////////////15071508// Two local variables reference the same object.1509// Check if the debugger obtains the same object when reading the two variables1510class EAMaterializeObjReferencedBy2LocalsTarget extends EATestCaseBaseTarget {15111512public void dontinline_testMethod() {1513XYVal xy = new XYVal(2, 3);1514XYVal alias = xy;1515dontinline_brkpt();1516iResult = xy.x + alias.x;1517}15181519@Override1520public int getExpectedIResult() {1521return 2 + 2;1522}1523}15241525class EAMaterializeObjReferencedBy2Locals extends EATestCaseBaseDebugger {15261527public void runTestCase() throws Exception {1528BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");1529printStack(bpe.thread());1530ObjectReference xy = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "xy");1531ObjectReference alias = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "alias");1532Asserts.assertSame(xy, alias, "xy and alias are expected to reference the same object");1533}15341535}15361537/////////////////////////////////////////////////////////////////////////////15381539// Two local variables reference the same object.1540// Check if it has the expected effect in the target if the debugger modifies the object.1541class EAMaterializeObjReferencedBy2LocalsAndModifyTarget extends EATestCaseBaseTarget {15421543public void dontinline_testMethod() {1544XYVal xy = new XYVal(2, 3);1545XYVal alias = xy;1546dontinline_brkpt(); // debugger: alias.x = 421547iResult = xy.x + alias.x;1548}15491550@Override1551public int getExpectedIResult() {1552return 42 + 42;1553}1554}15551556class EAMaterializeObjReferencedBy2LocalsAndModify extends EATestCaseBaseDebugger {15571558public void runTestCase() throws Exception {1559BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");1560printStack(bpe.thread());1561ObjectReference alias = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "alias");1562setField(alias, "x", env.vm().mirrorOf(42));1563}1564}15651566/////////////////////////////////////////////////////////////////////////////15671568// Two local variables of the same compiled frame but in different virtual frames reference the same1569// object.1570// Check if the debugger obtains the same object when reading the two variables1571class EAMaterializeObjReferencedBy2LocalsInDifferentVirtFramesTarget extends EATestCaseBaseTarget {15721573@Override1574public void setUp() {1575super.setUp();1576testMethodDepth = 2;1577}15781579public void dontinline_testMethod() {1580XYVal xy = new XYVal(2, 3);1581testMethod_inlined(xy);1582iResult += xy.x;1583}15841585public void testMethod_inlined(XYVal xy) {1586XYVal alias = xy;1587dontinline_brkpt();1588iResult = alias.x;1589}15901591@Override1592public int getExpectedIResult() {1593return 2 + 2;1594}1595}15961597class EAMaterializeObjReferencedBy2LocalsInDifferentVirtFrames extends EATestCaseBaseDebugger {15981599public void runTestCase() throws Exception {1600BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");1601printStack(bpe.thread());1602ObjectReference xy = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "xy");1603ObjectReference alias = getLocalRef(bpe.thread().frame(1), "testMethod_inlined", "alias", XYVAL_NAME);1604Asserts.assertSame(xy, alias, "xy and alias are expected to reference the same object");1605}16061607}16081609/////////////////////////////////////////////////////////////////////////////16101611// Two local variables of the same compiled frame but in different virtual frames reference the same1612// object.1613// Check if it has the expected effect in the target if the debugger modifies the object.1614class EAMaterializeObjReferencedBy2LocalsInDifferentVirtFramesAndModifyTarget extends EATestCaseBaseTarget {16151616@Override1617public void setUp() {1618super.setUp();1619testMethodDepth = 2;1620}16211622public void dontinline_testMethod() {1623XYVal xy = new XYVal(2, 3);1624testMethod_inlined(xy); // debugger: xy.x = 421625iResult += xy.x;1626}16271628public void testMethod_inlined(XYVal xy) {1629XYVal alias = xy;1630dontinline_brkpt();1631iResult = alias.x;1632}16331634@Override1635public int getExpectedIResult() {1636return 42 + 42;1637}1638}16391640class EAMaterializeObjReferencedBy2LocalsInDifferentVirtFramesAndModify extends EATestCaseBaseDebugger {16411642public void runTestCase() throws Exception {1643BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");1644printStack(bpe.thread());1645ObjectReference alias = getLocalRef(bpe.thread().frame(1), "testMethod_inlined", "alias", XYVAL_NAME);1646setField(alias, "x", env.vm().mirrorOf(42));1647}16481649}16501651/////////////////////////////////////////////////////////////////////////////16521653// Test materialization of an object referenced only from expression stack1654class EAMaterializeObjReferencedFromOperandStackTarget extends EATestCaseBaseTarget {16551656@Override1657public void setUp() {1658super.setUp();1659testMethodDepth = 2;1660}16611662public void dontinline_testMethod() {1663@SuppressWarnings("unused")1664XYVal xy1 = new XYVal(2, 3);1665// Debugger breaks in call to dontinline_brkpt_ret_100() and reads1666// the value of the local 'xy1'. This triggers materialization1667// of the object on the operand stack1668iResult = testMethodInlined(new XYVal(4, 2), dontinline_brkpt_ret_100());1669}16701671public int testMethodInlined(XYVal xy2, int dontinline_brkpt_ret_100) {1672return xy2.x + dontinline_brkpt_ret_100;1673}16741675public int dontinline_brkpt_ret_100() {1676dontinline_brkpt();1677return 100;1678}16791680@Override1681public int getExpectedIResult() {1682return 4 + 100;1683}1684}16851686class EAMaterializeObjReferencedFromOperandStack extends EATestCaseBaseDebugger {16871688public void runTestCase() throws Exception {1689BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");1690printStack(bpe.thread());1691ObjectReference xy1 = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "xy1");1692checkPrimitiveField(xy1, FD.I, "x", 2);1693checkPrimitiveField(xy1, FD.I, "y", 3);1694}16951696}16971698/////////////////////////////////////////////////////////////////////////////16991700/**1701* Tests a regression in the implementation by setting the value of a local int which triggers the1702* creation of a deferred update and then getting the reference to a scalar replaced object. The1703* issue was that the scalar replaced object was not reallocated. Because of the deferred update it1704* was assumed that the reallocation already happened.1705*/1706class EAMaterializeLocalVariableUponGetAfterSetInteger extends EATestCaseBaseDebugger {17071708public void runTestCase() throws Exception {1709BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");1710printStack(bpe.thread());1711setLocal(bpe.thread().frame(1), "i", env.vm().mirrorOf(43));1712ObjectReference o = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "xy");1713checkPrimitiveField(o, FD.I, "x", 4);1714checkPrimitiveField(o, FD.I, "y", 2);1715}1716}17171718class EAMaterializeLocalVariableUponGetAfterSetIntegerTarget extends EATestCaseBaseTarget {17191720public void dontinline_testMethod() {1721XYVal xy = new XYVal(4, 2);1722int i = 42;1723dontinline_brkpt();1724iResult = xy.x + xy.y + i;1725}17261727@Override1728public int getExpectedIResult() {1729return 4 + 2 + 43;1730}17311732@Override1733public boolean testFrameShouldBeDeoptimized() {1734return true; // setting local variable i always triggers deoptimization1735}1736}17371738/////////////////////////////////////////////////////////////////////////////1739//1740// Locking Tests1741//1742/////////////////////////////////////////////////////////////////////////////17431744class EARelockingSimple extends EATestCaseBaseDebugger {17451746public void runTestCase() throws Exception {1747BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");1748printStack(bpe.thread());1749@SuppressWarnings("unused")1750ObjectReference o = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "l1");1751}1752}17531754class EARelockingSimpleTarget extends EATestCaseBaseTarget {17551756public void dontinline_testMethod() {1757XYVal l1 = new XYVal(4, 2);1758synchronized (l1) {1759dontinline_brkpt();1760}1761}1762}17631764/////////////////////////////////////////////////////////////////////////////17651766/**1767* Test if the bias of an object O that escapes globally is revoked correctly if local objects1768* escape through JVMTI. O is referenced by field l0.1769* This tests a regression of a previous version of the implementation.1770*/1771class EARelockingSimple_2 extends EATestCaseBaseDebugger {17721773public void runTestCase() throws Exception {1774BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");1775printStack(bpe.thread());1776@SuppressWarnings("unused")1777ObjectReference o = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "l1");1778}1779}17801781class EARelockingSimple_2Target extends EATestCaseBaseTarget {17821783public XYVal l0;17841785public void dontinline_testMethod() {1786l0 = new XYVal(4, 2); // GobalEscape1787XYVal l1 = new XYVal(4, 2);1788synchronized (l0) {1789synchronized (l1) {1790dontinline_brkpt();1791}1792}1793}1794}17951796/////////////////////////////////////////////////////////////////////////////17971798// Test recursive locking1799class EARelockingRecursiveTarget extends EATestCaseBaseTarget {18001801@Override1802public void setUp() {1803super.setUp();1804testMethodDepth = 2;1805}18061807public void dontinline_testMethod() {1808XYVal l1 = new XYVal(4, 2);1809synchronized (l1) {1810testMethod_inlined(l1);1811}1812}18131814public void testMethod_inlined(XYVal l2) {1815synchronized (l2) {1816dontinline_brkpt();1817}1818}1819}18201821class EARelockingRecursive extends EATestCaseBaseDebugger {18221823public void runTestCase() throws Exception {1824BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");1825printStack(bpe.thread());1826@SuppressWarnings("unused")1827ObjectReference o = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "l1");1828}1829}18301831/////////////////////////////////////////////////////////////////////////////18321833// Object ref l1 is retrieved by the debugger at a location where nested locks are omitted. The1834// accessed object is globally reachable already before the access, therefore no relocking is done.1835class EARelockingNestedInflatedTarget extends EATestCaseBaseTarget {18361837@Override1838public void setUp() {1839super.setUp();1840testMethodDepth = 2;1841}18421843@Override1844public boolean testFrameShouldBeDeoptimized() {1845// Access does not trigger deopt., as escape state is already global escape.1846return false;1847}18481849public void dontinline_testMethod() {1850XYVal l1 = inflatedLock;1851synchronized (l1) {1852testMethod_inlined(l1);1853}1854}18551856public void testMethod_inlined(XYVal l2) {1857synchronized (l2) { // eliminated nested locking1858dontinline_brkpt();1859}1860}1861}18621863class EARelockingNestedInflated extends EATestCaseBaseDebugger {18641865public void runTestCase() throws Exception {1866BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");1867printStack(bpe.thread());1868@SuppressWarnings("unused")1869ObjectReference o = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "l1");1870}1871}18721873/////////////////////////////////////////////////////////////////////////////18741875/**1876* Like {@link EARelockingNestedInflated} with the difference that there is1877* a scalar replaced object in the scope from which the object with eliminated nested locking1878* is read. This triggers materialization and relocking.1879*/1880class EARelockingNestedInflated_02 extends EATestCaseBaseDebugger {18811882public void runTestCase() throws Exception {1883BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");1884printStack(bpe.thread());1885@SuppressWarnings("unused")1886ObjectReference o = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "l1");1887}1888}18891890class EARelockingNestedInflated_02Target extends EATestCaseBaseTarget {18911892@Override1893public void setUp() {1894super.setUp();1895testMethodDepth = 2;1896}18971898public void dontinline_testMethod() {1899@SuppressWarnings("unused")1900XYVal xy = new XYVal(1, 1); // scalar replaced1901XYVal l1 = inflatedLock; // read by debugger1902synchronized (l1) {1903testMethod_inlined(l1);1904}1905}19061907public void testMethod_inlined(XYVal l2) {1908synchronized (l2) { // eliminated nested locking1909dontinline_brkpt();1910}1911}1912}19131914/////////////////////////////////////////////////////////////////////////////19151916/**1917* Checks if an eliminated lock of an ArgEscape object l1 can be relocked if1918* l1 is locked in a callee frame.1919*/1920class EARelockingArgEscapeLWLockedInCalleeFrame extends EATestCaseBaseDebugger {19211922public void runTestCase() throws Exception {1923BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");1924printStack(bpe.thread());1925@SuppressWarnings("unused")1926ObjectReference o = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "l1");1927}1928}19291930class EARelockingArgEscapeLWLockedInCalleeFrameTarget extends EATestCaseBaseTarget {19311932@Override1933public void setUp() {1934super.setUp();1935testMethodDepth = 2;1936}19371938public void dontinline_testMethod() {1939XYVal l1 = new XYVal(1, 1); // ArgEscape1940synchronized (l1) { // eliminated1941l1.dontinline_sync_method(this); // l1 escapes1942}1943}19441945@Override1946public boolean testFrameShouldBeDeoptimized() {1947// Graal does not provide debug info about arg escape objects, therefore the frame is not deoptimized1948return !UseJVMCICompiler && super.testFrameShouldBeDeoptimized();1949}1950}19511952/////////////////////////////////////////////////////////////////////////////19531954/**1955* Similar to {@link EARelockingArgEscapeLWLockedInCalleeFrame}. In addition1956* the test method has got a scalar replaced object with eliminated locking.1957* This pattern matches a regression in the implementation.1958*/1959class EARelockingArgEscapeLWLockedInCalleeFrame_2 extends EATestCaseBaseDebugger {19601961public void runTestCase() throws Exception {1962BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");1963printStack(bpe.thread());1964@SuppressWarnings("unused")1965ObjectReference o = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "l1");1966}1967}19681969class EARelockingArgEscapeLWLockedInCalleeFrame_2Target extends EATestCaseBaseTarget {19701971@Override1972public void setUp() {1973super.setUp();1974testMethodDepth = 2;1975}19761977public void dontinline_testMethod() {1978XYVal l1 = new XYVal(1, 1); // ArgEscape1979XYVal l2 = new XYVal(4, 2); // NoEscape, scalar replaced1980synchronized (l1) { // eliminated1981synchronized (l2) { // eliminated1982l1.dontinline_sync_method(this); // l1 escapes1983}1984}1985iResult = l2.x + l2.y;1986}19871988@Override1989public int getExpectedIResult() {1990return 6;1991}1992}19931994/////////////////////////////////////////////////////////////////////////////19951996/**1997* Similar to {@link EARelockingArgEscapeLWLockedInCalleeFrame}.1998* A bulk rebias operation is triggered at a position where all locks on the local object referenced1999* by l1 are eliminated. This leaves the object with an outdated biased locking epoch which has to be2000* considered when relocking.2001* This tests a regression in a previous version.2002*/2003class EARelockingArgEscapeLWLockedInCalleeFrame_3 extends EATestCaseBaseDebugger {20042005public static final String XYVAL_LOCAL_NAME = EARelockingArgEscapeLWLockedInCalleeFrame_3Target.XYValLocal.class.getName();20062007public void runTestCase() throws Exception {2008BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");2009printStack(bpe.thread());2010@SuppressWarnings("unused")2011ObjectReference o = getLocalRef(bpe.thread().frame(1), XYVAL_LOCAL_NAME, "l1");2012}2013}20142015class EARelockingArgEscapeLWLockedInCalleeFrame_3Target extends EATestCaseBaseTarget {20162017// Using local type to avoid side effects on biased locking heuristics2018public static class XYValLocal extends XYVal {2019public XYValLocal(int x, int y) {2020super(x,y);2021}2022}20232024public void dontinline_testMethod() {2025XYVal l1 = new XYValLocal(1, 1); // ArgEscape2026synchronized (l1) { // eliminated2027l1.dontinline_sync_method_no_brkpt(this); // l1 escapes2028// trigger bulk rebias2029dontinline_bulkRebiasAfterWarmup(l1.getClass());2030// Now the epoch of l1 does not match the epoch of its class.2031// This has to be considered when relocking because of JVMTI access2032dontinline_brkpt();2033}2034}20352036@Override2037public boolean testFrameShouldBeDeoptimized() {2038// Graal does not provide debug info about arg escape objects, therefore the frame is not deoptimized2039return !UseJVMCICompiler && super.testFrameShouldBeDeoptimized();2040}2041}20422043/////////////////////////////////////////////////////////////////////////////20442045/**2046* Similar to {@link EARelockingArgEscapeLWLockedInCalleeFrame_3}.2047* But instead of a bulk rebias a bulk revoke operation is triggered.2048* This leaves the object with a stale bias as the prototype header of its calls lost its bias2049* pattern in the bulk revoke which has to be considered during relocking.2050* This tests a regression in a previous version.2051*/2052class EARelockingArgEscapeLWLockedInCalleeFrame_4 extends EATestCaseBaseDebugger {20532054public static final String XYVAL_LOCAL_NAME = EARelockingArgEscapeLWLockedInCalleeFrame_4Target.XYValLocal.class.getName();20552056public void runTestCase() throws Exception {2057BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");2058printStack(bpe.thread());2059@SuppressWarnings("unused")2060ObjectReference o = getLocalRef(bpe.thread().frame(1), XYVAL_LOCAL_NAME, "l1");2061}2062}20632064class EARelockingArgEscapeLWLockedInCalleeFrame_4Target extends EATestCaseBaseTarget {20652066// Using local type to avoid side effects on biased locking heuristics2067public static class XYValLocal extends XYVal {2068public XYValLocal(int x, int y) {2069super(x,y);2070}2071}20722073public void dontinline_testMethod() {2074XYVal l1 = new XYValLocal(1, 1); // ArgEscape2075synchronized (l1) { // eliminated2076l1.dontinline_sync_method_no_brkpt(this); // l1 escapes2077// trigger bulk rebias2078dontinline_bulkRevokeAfterWarmup(l1.getClass());2079// Now the epoch of l1 does not match the epoch of its class.2080// This has to be considered when relocking because of JVMTI access2081dontinline_brkpt();2082}2083}208420852086@Override2087public boolean testFrameShouldBeDeoptimized() {2088// Graal does not provide debug info about arg escape objects, therefore the frame is not deoptimized2089return !UseJVMCICompiler && super.testFrameShouldBeDeoptimized();2090}2091}20922093/////////////////////////////////////////////////////////////////////////////20942095/**2096* Test relocking eliminated (nested) locks of an object on which the2097* target thread currently waits.2098*/2099class EARelockingObjectCurrentlyWaitingOn extends EATestCaseBaseDebugger {21002101public void runTestCase() throws Exception {2102env.vm().resume();2103boolean inWait = false;2104do {2105Thread.sleep(100);2106env.targetMainThread.suspend();2107printStack(env.targetMainThread);2108inWait = env.targetMainThread.frame(0).location().method().name().equals("wait");2109if (!inWait) {2110msg("Target not yet in java.lang.Object.wait(long).");2111env.targetMainThread.resume();2112}2113} while(!inWait);2114StackFrame testMethodFrame = env.targetMainThread.frame(4);2115// Access triggers relocking of all eliminated locks, including nested locks of l1 which references2116// the object on which the target main thread is currently waiting.2117ObjectReference l0 = getLocalRef(testMethodFrame, EARelockingObjectCurrentlyWaitingOnTarget.ForLocking.class.getName(), "l0");2118Asserts.assertEQ(l0.entryCount(), 1, "wrong entry count");2119ObjectReference l1 = getLocalRef(testMethodFrame, EARelockingObjectCurrentlyWaitingOnTarget.ForLocking.class.getName(), "l1");2120Asserts.assertEQ(l1.entryCount(), 0, "wrong entry count");2121setField(testCase, "objToNotifyOn", l1);2122}2123}21242125class EARelockingObjectCurrentlyWaitingOnTarget extends EATestCaseBaseTarget {21262127public static class ForLocking {2128}21292130public volatile Object objToNotifyOn; // debugger assigns value when notify thread should call objToNotifyOn.notifyAll()21312132@Override2133public void setUp() {2134super.setUp();2135testMethodDepth = 2;2136}21372138@Override2139public void warmupDone() {2140super.warmupDone();2141Thread t = new Thread(() -> doNotify());2142t.start();2143}21442145public void doNotify() {2146while (objToNotifyOn == null) {2147try {2148msg("objToNotifyOn is still null");2149Thread.sleep(100);2150} catch (InterruptedException e) { /* ignored */ }2151}2152synchronized (objToNotifyOn) {2153// will be received by the target main thread waiting in dontinline_waitWhenWarmupDone2154msg("calling objToNotifyOn.notifyAll()");2155objToNotifyOn.notifyAll();2156}2157}21582159@Override2160public boolean testFrameShouldBeDeoptimized() {2161return false;2162}21632164@Override2165public void dontinline_testMethod() throws Exception {2166ForLocking l0 = new ForLocking(); // will be scalar replaced; access triggers realloc/relock2167ForLocking l1 = new ForLocking();2168synchronized (l0) {2169synchronized (l1) {2170testMethod_inlined(l1);2171}2172}2173}21742175public void testMethod_inlined(ForLocking l2) throws Exception {2176synchronized (l2) { // eliminated nested locking2177dontinline_waitWhenWarmupDone(l2);2178}2179}21802181public void dontinline_waitWhenWarmupDone(ForLocking l2) throws Exception {2182if (warmupDone) {2183l2.wait();2184}2185}2186}21872188/////////////////////////////////////////////////////////////////////////////2189//2190// Test cases that require deoptimization even though neither locks2191// nor allocations are eliminated at the point where escape state is changed.2192//2193/////////////////////////////////////////////////////////////////////////////21942195/**2196* Let xy be NoEscape whose allocation cannot be eliminated (simulated by2197* -XX:-EliminateAllocations). The holding compiled frame has to be deoptimized when debugger2198* accesses xy because afterwards locking on xy is omitted.2199* Note: there are no EA based optimizations at the escape point.2200*/2201class EADeoptFrameAfterReadLocalObject_01 extends EATestCaseBaseDebugger {22022203public void runTestCase() throws Exception {2204BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");2205printStack(bpe.thread());2206@SuppressWarnings("unused")2207ObjectReference xy = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "xy");2208}2209}22102211class EADeoptFrameAfterReadLocalObject_01Target extends EATestCaseBaseTarget {22122213public void dontinline_testMethod() {2214XYVal xy = new XYVal(1, 1);2215dontinline_brkpt(); // Debugger reads xy, when there are no virtual objects or eliminated locks in scope2216synchronized (xy) { // Locking is eliminated.2217xy.x++;2218xy.y++;2219}2220}2221}22222223/////////////////////////////////////////////////////////////////////////////22242225/**2226* Similar to {@link EADeoptFrameAfterReadLocalObject_01} with the difference that the debugger2227* reads xy from an inlined callee. So xy is NoEscape instead of ArgEscape.2228*/2229class EADeoptFrameAfterReadLocalObject_01BTarget extends EATestCaseBaseTarget {22302231@Override2232public void setUp() {2233super.setUp();2234testMethodDepth = 2;2235}22362237public void dontinline_testMethod() {2238XYVal xy = new XYVal(1, 1);2239callee(xy); // Debugger acquires ref to xy from inlined callee2240// xy is NoEscape, nevertheless the object is not replaced2241// by scalars if running with -XX:-EliminateAllocations.2242// In that case there are no EA based optimizations were2243// the debugger reads the NoEscape object.2244synchronized (xy) { // Locking is eliminated.2245xy.x++;2246xy.y++;2247}2248}22492250public void callee(XYVal xy) {2251dontinline_brkpt(); // Debugger reads xy.2252// There are no virtual objects or eliminated locks.2253}2254}22552256class EADeoptFrameAfterReadLocalObject_01B extends EATestCaseBaseDebugger {22572258public void runTestCase() throws Exception {2259BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");2260printStack(bpe.thread());2261@SuppressWarnings("unused")2262ObjectReference xy = getLocalRef(bpe.thread().frame(1), "callee", "xy", XYVAL_NAME);2263}2264}22652266/////////////////////////////////////////////////////////////////////////////22672268/**2269* Let xy be ArgEscape. The frame dontinline_testMethod() has to be deoptimized when debugger2270* acquires xy from dontinline_callee() because afterwards locking on xy is omitted.2271* Note: there are no EA based optimizations at the escape point.2272*/2273class EADeoptFrameAfterReadLocalObject_02 extends EATestCaseBaseDebugger {22742275public void runTestCase() throws Exception {2276BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");2277printStack(bpe.thread());2278@SuppressWarnings("unused")2279ObjectReference xy = getLocalRef(bpe.thread().frame(1), "dontinline_callee", "xy", XYVAL_NAME);2280}2281}22822283class EADeoptFrameAfterReadLocalObject_02Target extends EATestCaseBaseTarget {22842285public void dontinline_testMethod() {2286XYVal xy = new XYVal(1, 1);2287dontinline_callee(xy); // xy is ArgEscape, debugger acquires ref to xy from callee2288synchronized (xy) { // Locking is eliminated.2289xy.x++;2290xy.y++;2291}2292}22932294public void dontinline_callee(XYVal xy) {2295dontinline_brkpt(); // Debugger reads xy.2296// There are no virtual objects or eliminated locks.2297}22982299@Override2300public void setUp() {2301super.setUp();2302testMethodDepth = 2;2303}23042305@Override2306public boolean testFrameShouldBeDeoptimized() {2307// Graal does not provide debug info about arg escape objects, therefore the frame is not deoptimized2308return !UseJVMCICompiler && super.testFrameShouldBeDeoptimized();2309}2310}23112312/////////////////////////////////////////////////////////////////////////////23132314/**2315* Similar to {@link EADeoptFrameAfterReadLocalObject_02} there is an ArgEscape object xy, but in2316* contrast it is not in the parameter list of a call when the debugger reads an object.2317* Therefore the frame of the test method should not be deoptimized2318*/2319class EADeoptFrameAfterReadLocalObject_02B extends EATestCaseBaseDebugger {23202321public void runTestCase() throws Exception {2322BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");2323printStack(bpe.thread());2324@SuppressWarnings("unused")2325ObjectReference xy = getLocalRef(bpe.thread().frame(1), "dontinline_callee", "xy", XYVAL_NAME);2326}2327}23282329class EADeoptFrameAfterReadLocalObject_02BTarget extends EATestCaseBaseTarget {23302331public void dontinline_testMethod() {2332XYVal xy = new XYVal(1, 1);2333dontinline_make_arg_escape(xy); // because of this call xy is ArgEscape2334dontinline_callee(); // xy is ArgEscape, but not a parameter of this call2335synchronized (xy) { // Locking is eliminated.2336xy.x++;2337xy.y++;2338}2339}23402341public void dontinline_callee() {2342@SuppressWarnings("unused")2343XYVal xy = new XYVal(2, 2);2344dontinline_brkpt(); // Debugger reads xy.2345// No need to deoptimize the caller frame2346}23472348@Override2349public void setUp() {2350super.setUp();2351testMethodDepth = 2;2352}23532354@Override2355public boolean testFrameShouldBeDeoptimized() {2356return false;2357}2358}23592360/////////////////////////////////////////////////////////////////////////////23612362/**2363* Similar to {@link EADeoptFrameAfterReadLocalObject_02} there is an ArgEscape object xy in2364* dontinline_testMethod() which is being passed as parameter when the debugger accesses a local object.2365* Nevertheless dontinline_testMethod must not be deoptimized because there is an entry frame2366* between it and the frame accessed by the debugger.2367*/2368class EADeoptFrameAfterReadLocalObject_02C extends EATestCaseBaseDebugger {23692370public void runTestCase() throws Exception {2371BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");2372printStack(bpe.thread());2373@SuppressWarnings("unused")2374ObjectReference xy = getLocalRef(bpe.thread().frame(1), "dontinline_callee_accessed_by_debugger", "xy", XYVAL_NAME);2375}2376}23772378class EADeoptFrameAfterReadLocalObject_02CTarget extends EATestCaseBaseTarget {23792380public void dontinline_testMethod() {2381XYVal xy = new XYVal(1, 1);2382dontinline_callee(xy); // xy is ArgEscape and being passed as parameter2383synchronized (xy) { // Locking is eliminated.2384xy.x++;2385xy.y++;2386}2387}23882389public void dontinline_callee(XYVal xy) {2390if (warmupDone) {2391dontinline_call_with_entry_frame(this, "dontinline_callee_accessed_by_debugger");2392}2393}23942395public void dontinline_callee_accessed_by_debugger() {2396@SuppressWarnings("unused")2397XYVal xy = new XYVal(2, 2);2398dontinline_brkpt(); // Debugger reads xy.2399// No need to deoptimize the caller frame2400}24012402@Override2403public void setUp() {2404super.setUp();2405testMethodDepth = 8;2406}24072408@Override2409public boolean testFrameShouldBeDeoptimized() {2410return false;2411}2412}24132414/////////////////////////////////////////////////////////////////////////////24152416/**2417* Let xy be NoEscape whose allocation cannot be eliminated (e.g. because of2418* -XX:-EliminateAllocations). The holding compiled frame has to be deoptimized when debugger2419* accesses xy because the following field accesses get eliminated. Note: there are no EA based2420* optimizations at the escape point.2421*/2422class EADeoptFrameAfterReadLocalObject_03 extends EATestCaseBaseDebugger {24232424public void runTestCase() throws Exception {2425BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");2426printStack(bpe.thread());2427ObjectReference xy = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "xy");2428setField(xy, "x", env.vm().mirrorOf(1));2429}2430}24312432class EADeoptFrameAfterReadLocalObject_03Target extends EATestCaseBaseTarget {24332434public void dontinline_testMethod() {2435XYVal xy = new XYVal(0, 1);2436dontinline_brkpt(); // Debugger reads xy, when there are no virtual objects or2437// eliminated locks in scope and modifies xy.x2438iResult = xy.x + xy.y; // Loads are replaced by constants 0 and 1.2439}24402441@Override2442public int getExpectedIResult() {2443return 1 + 1;2444}2445}24462447/////////////////////////////////////////////////////////////////////////////2448//2449// Monitor info tests2450//2451/////////////////////////////////////////////////////////////////////////////24522453class EAGetOwnedMonitorsTarget extends EATestCaseBaseTarget {24542455public long checkSum;24562457public void dontinline_testMethod() {2458XYVal l1 = new XYVal(4, 2);2459synchronized (l1) {2460dontinline_endlessLoop();2461}2462}24632464@Override2465public void setUp() {2466super.setUp();2467testMethodDepth = 2;2468loopCount = 3;2469}24702471public void warmupDone() {2472super.warmupDone();2473msg("enter 'endless' loop by setting loopCount = Long.MAX_VALUE");2474loopCount = Long.MAX_VALUE; // endless loop2475}2476}24772478class EAGetOwnedMonitors extends EATestCaseBaseDebugger {24792480public void runTestCase() throws Exception {2481msg("resume");2482env.vm().resume();2483waitUntilTargetHasEnteredEndlessLoop();2484// In contrast to JVMTI, JDWP requires a target thread to be suspended, before the owned monitors can be queried2485msg("suspend target");2486env.targetMainThread.suspend();2487msg("Get owned monitors");2488List<ObjectReference> monitors = env.targetMainThread.ownedMonitors();2489Asserts.assertEQ(monitors.size(), 1, "unexpected number of owned monitors");2490terminateEndlessLoop();2491}2492}24932494/////////////////////////////////////////////////////////////////////////////24952496class EAEntryCountTarget extends EATestCaseBaseTarget {24972498public long checkSum;24992500public void dontinline_testMethod() {2501XYVal l1 = new XYVal(4, 2);2502synchronized (l1) {2503inline_testMethod2(l1);2504}2505}25062507public void inline_testMethod2(XYVal l1) {2508synchronized (l1) {2509dontinline_endlessLoop();2510}2511}25122513@Override2514public void setUp() {2515super.setUp();2516testMethodDepth = 2;2517loopCount = 3;2518}25192520public void warmupDone() {2521super.warmupDone();2522msg("enter 'endless' loop by setting loopCount = Long.MAX_VALUE");2523loopCount = Long.MAX_VALUE; // endless loop2524}2525}25262527class EAEntryCount extends EATestCaseBaseDebugger {25282529public void runTestCase() throws Exception {2530msg("resume");2531env.vm().resume();2532waitUntilTargetHasEnteredEndlessLoop();2533// In contrast to JVMTI, JDWP requires a target thread to be suspended, before the owned monitors can be queried2534msg("suspend target");2535env.targetMainThread.suspend();2536msg("Get owned monitors");2537List<ObjectReference> monitors = env.targetMainThread.ownedMonitors();2538Asserts.assertEQ(monitors.size(), 1, "unexpected number of owned monitors");2539msg("Get entry count");2540int entryCount = monitors.get(0).entryCount();2541Asserts.assertEQ(entryCount, 2, "wrong entry count");2542terminateEndlessLoop();2543}2544}25452546/////////////////////////////////////////////////////////////////////////////2547//2548// PopFrame tests2549//2550/////////////////////////////////////////////////////////////////////////////25512552/**2553* PopFrame into caller frame with scalar replaced objects.2554*/2555class EAPopFrameNotInlined extends EATestCaseBaseDebugger {25562557public void runTestCase() throws Exception {2558BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");2559printStack(bpe.thread());2560msg("PopFrame");2561bpe.thread().popFrames(bpe.thread().frame(0));2562msg("PopFrame DONE");2563}25642565@Override2566public boolean shouldSkip() {2567// And Graal currently doesn't support PopFrame2568return super.shouldSkip() || env.targetVMOptions.UseJVMCICompiler;2569}2570}25712572class EAPopFrameNotInlinedTarget extends EATestCaseBaseTarget {25732574public void dontinline_testMethod() {2575XYVal xy = new XYVal(4, 2);2576dontinline_brkpt();2577iResult = xy.x + xy.y;2578}25792580@Override2581public boolean testFrameShouldBeDeoptimized() {2582// Test is only performed after the frame pop.2583// Then dontinline_testMethod is interpreted.2584return false;2585}25862587@Override2588public int getExpectedIResult() {2589return 4 + 2;2590}25912592@Override2593public boolean shouldSkip() {2594// And Graal currently doesn't support PopFrame2595return super.shouldSkip() || UseJVMCICompiler;2596}2597}25982599/////////////////////////////////////////////////////////////////////////////26002601/**2602* Pop frames into {@link EAPopFrameNotInlinedReallocFailureTarget#dontinline_testMethod()} which2603* holds scalar replaced objects. In preparation of the pop frame operations the vm eagerly2604* reallocates scalar replaced objects to avoid failures when actually popping the frames. We provoke2605* a reallocation failures and expect {@link VMOutOfMemoryException}.2606*/2607class EAPopFrameNotInlinedReallocFailure extends EATestCaseBaseDebugger {26082609public void runTestCase() throws Exception {2610BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");2611ThreadReference thread = bpe.thread();2612printStack(thread);2613// frame[0]: EATestCaseBaseTarget.dontinline_brkpt()2614// frame[1]: EAPopFrameNotInlinedReallocFailureTarget.dontinline_consume_all_memory_brkpt()2615// frame[2]: EAPopFrameNotInlinedReallocFailureTarget.dontinline_testMethod()2616// frame[3]: EATestCaseBaseTarget.run()2617// frame[4]: EATestsTarget.main(java.lang.String[])2618msg("PopFrame");2619boolean coughtOom = false;2620try {2621// try to pop dontinline_consume_all_memory_brkpt2622thread.popFrames(thread.frame(1));2623} catch (VMOutOfMemoryException oom) {2624// as expected2625msg("cought OOM");2626coughtOom = true;2627}2628freeAllMemory();2629// We succeeded to pop just one frame. When we continue, we will call dontinline_brkpt() again.2630Asserts.assertTrue(coughtOom, "PopFrame should have triggered an OOM exception in target");2631String expectedTopFrame = "dontinline_consume_all_memory_brkpt";2632Asserts.assertEQ(expectedTopFrame, thread.frame(0).location().method().name());2633printStack(thread);2634}26352636@Override2637public boolean shouldSkip() {2638// OOMEs because of realloc failures with DeoptimizeObjectsALot are too random.2639// And Graal currently doesn't provide all information about non-escaping objects in debug info2640return super.shouldSkip() ||2641!env.targetVMOptions.EliminateAllocations ||2642// With ZGC the OOME is not always thrown as expected2643env.targetVMOptions.ZGCIsSelected ||2644env.targetVMOptions.DeoptimizeObjectsALot ||2645env.targetVMOptions.UseJVMCICompiler;2646}2647}26482649class EAPopFrameNotInlinedReallocFailureTarget extends EATestCaseBaseTarget {26502651public boolean doneAlready;26522653public void dontinline_testMethod() {2654long a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // scalar replaced2655Vector10 v = new Vector10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // scalar replaced2656dontinline_consume_all_memory_brkpt();2657lResult = a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] + a[8] + a[9]2658+ v.i0 + v.i1 + v.i2 + v.i3 + v.i4 + v.i5 + v.i6 + v.i7 + v.i8 + v.i9;2659}26602661public void dontinline_consume_all_memory_brkpt() {2662if (warmupDone && !doneAlready) {2663doneAlready = true;2664consumeAllMemory(); // provoke reallocation failure2665dontinline_brkpt();2666}2667}26682669@Override2670public void setUp() {2671super.setUp();2672testMethodDepth = 2;2673}26742675@Override2676public long getExpectedLResult() {2677long n = 10;2678return 2*n*(n+1)/2;2679}26802681@Override2682public boolean shouldSkip() {2683// OOMEs because of realloc failures with DeoptimizeObjectsALot are too random.2684// And Graal currently doesn't provide all information about non-escaping objects in debug info2685return super.shouldSkip() ||2686!EliminateAllocations ||2687// With ZGC the OOME is not always thrown as expected2688ZGCIsSelected ||2689DeoptimizeObjectsALot ||2690UseJVMCICompiler;2691}2692}26932694/////////////////////////////////////////////////////////////////////////////26952696/**2697* Pop inlined top frame dropping into method with scalar replaced opjects.2698*/2699class EAPopInlinedMethodWithScalarReplacedObjectsReallocFailure extends EATestCaseBaseDebugger {27002701public void runTestCase() throws Exception {2702ThreadReference thread = env.targetMainThread;2703env.vm().resume();2704waitUntilTargetHasEnteredEndlessLoop();27052706thread.suspend();2707printStack(thread);2708// frame[0]: EAPopInlinedMethodWithScalarReplacedObjectsReallocFailureTarget.inlinedCallForcedToReturn()2709// frame[1]: EAPopInlinedMethodWithScalarReplacedObjectsReallocFailureTarget.dontinline_testMethod()2710// frame[2]: EATestCaseBaseTarget.run()27112712msg("Pop Frames");2713boolean coughtOom = false;2714try {2715thread.popFrames(thread.frame(0)); // Request pop frame of inlinedCallForcedToReturn()2716// reallocation is triggered here2717} catch (VMOutOfMemoryException oom) {2718// as expected2719msg("cought OOM");2720coughtOom = true;2721}2722printStack(thread);2723// frame[0]: EAPopInlinedMethodWithScalarReplacedObjectsReallocFailureTarget.inlinedCallForcedToReturn()2724// frame[1]: EAPopInlinedMethodWithScalarReplacedObjectsReallocFailureTarget.dontinline_testMethod()2725// frame[2]: EATestCaseBaseTarget.run()27262727freeAllMemory();2728setField(testCase, "loopCount", env.vm().mirrorOf(0)); // terminate loop2729Asserts.assertTrue(coughtOom, "PopFrame should have triggered an OOM exception in target");2730String expectedTopFrame = "inlinedCallForcedToReturn";2731Asserts.assertEQ(expectedTopFrame, thread.frame(0).location().method().name());2732}27332734@Override2735public boolean shouldSkip() {2736// OOMEs because of realloc failures with DeoptimizeObjectsALot are too random.2737// And Graal currently doesn't provide all information about non-escaping objects in debug info2738return super.shouldSkip() ||2739!env.targetVMOptions.EliminateAllocations ||2740// With ZGC the OOME is not always thrown as expected2741env.targetVMOptions.ZGCIsSelected ||2742env.targetVMOptions.DeoptimizeObjectsALot ||2743env.targetVMOptions.UseJVMCICompiler;2744}2745}27462747class EAPopInlinedMethodWithScalarReplacedObjectsReallocFailureTarget extends EATestCaseBaseTarget {27482749public long checkSum;27502751public void dontinline_testMethod() {2752long a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // scalar replaced2753Vector10 v = new Vector10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // scalar replaced2754long l = inlinedCallForcedToReturn();2755lResult = a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] + a[8] + a[9]2756+ v.i0 + v.i1 + v.i2 + v.i3 + v.i4 + v.i5 + v.i6 + v.i7 + v.i8 + v.i9;2757}27582759public long inlinedCallForcedToReturn() {2760long cs = checkSum;2761dontinline_consumeAllMemory();2762while (loopCount-- > 0) {2763targetIsInLoop = true;2764checkSum += checkSum % ++cs;2765}2766loopCount = 3;2767targetIsInLoop = false;2768return checkSum;2769}27702771public void dontinline_consumeAllMemory() {2772if (warmupDone && (loopCount > 3)) {2773consumeAllMemory();2774}2775}27762777@Override2778public long getExpectedLResult() {2779long n = 10;2780return 2*n*(n+1)/2;2781}27822783@Override2784public void setUp() {2785super.setUp();2786loopCount = 3;2787}27882789public void warmupDone() {2790super.warmupDone();2791msg("enter 'endless' loop by setting loopCount = Long.MAX_VALUE");2792loopCount = Long.MAX_VALUE; // endless loop2793}27942795@Override2796public boolean shouldSkip() {2797// OOMEs because of realloc failures with DeoptimizeObjectsALot are too random.2798// And Graal currently doesn't provide all information about non-escaping objects in debug info2799return super.shouldSkip() ||2800!EliminateAllocations ||2801// With ZGC the OOME is not always thrown as expected2802ZGCIsSelected ||2803DeoptimizeObjectsALot ||2804UseJVMCICompiler;2805}2806}28072808/////////////////////////////////////////////////////////////////////////////2809//2810// ForceEarlyReturn tests2811//2812/////////////////////////////////////////////////////////////////////////////28132814/**2815* ForceEarlyReturn into caller frame with scalar replaced objects.2816*/2817class EAForceEarlyReturnNotInlined extends EATestCaseBaseDebugger {28182819public void runTestCase() throws Exception {2820BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");2821ThreadReference thread = bpe.thread();2822printStack(thread);2823// frame[0]: EATestCaseBaseTarget.dontinline_brkpt()2824// frame[1]: EATestCaseBaseTarget.dontinline_brkpt_iret()2825// frame[2]: EAForceEarlyReturnNotInlinedTarget.dontinline_testMethod()2826// frame[3]: EATestCaseBaseTarget.run()2827// frame[4]: EATestsTarget.main(java.lang.String[])28282829msg("Step out");2830env.stepOut(thread); // return from dontinline_brkpt2831printStack(thread);2832msg("ForceEarlyReturn");2833thread.forceEarlyReturn(env.vm().mirrorOf(43)); // return from dontinline_brkpt_iret,2834// does not trigger reallocation in contrast to PopFrame2835msg("Step over line");2836env.stepOverLine(thread); // reallocation is triggered here2837printStack(thread);2838msg("ForceEarlyReturn DONE");2839}28402841@Override2842public boolean shouldSkip() {2843// Graal currently doesn't support Force Early Return2844return super.shouldSkip() || env.targetVMOptions.UseJVMCICompiler;2845}2846}28472848class EAForceEarlyReturnNotInlinedTarget extends EATestCaseBaseTarget {28492850public void dontinline_testMethod() {2851XYVal xy = new XYVal(4, 2);2852int i = dontinline_brkpt_iret();2853iResult = xy.x + xy.y + i;2854}28552856@Override2857public int getExpectedIResult() {2858return 4 + 2 + 43;2859}28602861@Override2862public void setUp() {2863super.setUp();2864testMethodDepth = 2;2865}28662867public boolean testFrameShouldBeDeoptimized() {2868return true; // because of stepping2869}28702871@Override2872public boolean shouldSkip() {2873// Graal currently doesn't support Force Early Return2874return super.shouldSkip() || UseJVMCICompiler;2875}2876}28772878/////////////////////////////////////////////////////////////////////////////28792880/**2881* ForceEarlyReturn at safepoint in frame with scalar replaced objects.2882*/2883class EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjects extends EATestCaseBaseDebugger {28842885public void runTestCase() throws Exception {2886ThreadReference thread = env.targetMainThread;2887env.vm().resume();2888waitUntilTargetHasEnteredEndlessLoop();28892890thread.suspend();2891printStack(thread);2892// frame[0]: EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsTarget.inlinedCallForcedToReturn()2893// frame[1]: EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsTarget.dontinline_testMethod()2894// frame[2]: EATestCaseBaseTarget.run()28952896msg("ForceEarlyReturn");2897thread.forceEarlyReturn(env.vm().mirrorOf(43)); // Request force return 43 from inlinedCallForcedToReturn()2898// reallocation is triggered here2899msg("Step over instruction to do the forced return");2900env.stepOverInstruction(thread);2901printStack(thread);2902msg("ForceEarlyReturn DONE");2903}29042905@Override2906public boolean shouldSkip() {2907// Graal currently doesn't support Force Early Return2908return super.shouldSkip() || env.targetVMOptions.UseJVMCICompiler;2909}2910}29112912class EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsTarget extends EATestCaseBaseTarget {29132914public int checkSum;29152916public void dontinline_testMethod() {2917XYVal xy = new XYVal(4, 2);2918int i = inlinedCallForcedToReturn();2919iResult = xy.x + xy.y + i;2920}29212922public int inlinedCallForcedToReturn() { // forced to return 432923int i = checkSum;2924while (loopCount-- > 0) {2925targetIsInLoop = true;2926checkSum += checkSum % ++i;2927}2928loopCount = 3;2929targetIsInLoop = false;2930return checkSum;2931}29322933@Override2934public int getExpectedIResult() {2935return 4 + 2 + 43;2936}29372938@Override2939public void setUp() {2940super.setUp();2941testMethodDepth = 2;2942loopCount = 3;2943}29442945public void warmupDone() {2946super.warmupDone();2947msg("enter 'endless' loop by setting loopCount = Long.MAX_VALUE");2948loopCount = Long.MAX_VALUE; // endless loop2949}29502951public boolean testFrameShouldBeDeoptimized() {2952return true; // because of stepping2953}29542955@Override2956public boolean shouldSkip() {2957// Graal currently doesn't support Force Early Return2958return super.shouldSkip() || UseJVMCICompiler;2959}2960}29612962/////////////////////////////////////////////////////////////////////////////29632964/**2965* ForceEarlyReturn with reallocation failure.2966*/2967class EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsReallocFailure extends EATestCaseBaseDebugger {29682969public void runTestCase() throws Exception {2970ThreadReference thread = env.targetMainThread;2971env.vm().resume();2972waitUntilTargetHasEnteredEndlessLoop();29732974thread.suspend();2975printStack(thread);2976// frame[0]: EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsReallocFailureTarget.inlinedCallForcedToReturn()2977// frame[1]: EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsReallocFailureTarget.dontinline_testMethod()2978// frame[2]: EATestCaseBaseTarget.run()29792980msg("ForceEarlyReturn");2981boolean coughtOom = false;2982try {2983thread.forceEarlyReturn(env.vm().mirrorOf(43)); // Request force return 43 from inlinedCallForcedToReturn()2984// reallocation is triggered here2985} catch (VMOutOfMemoryException oom) {2986// as expected2987msg("cought OOM");2988coughtOom = true;2989}2990freeAllMemory();2991Asserts.assertTrue(coughtOom, "ForceEarlyReturn should have triggered an OOM exception in target");2992printStack(thread);2993msg("ForceEarlyReturn(2)");2994thread.forceEarlyReturn(env.vm().mirrorOf(43));2995msg("Step over instruction to do the forced return");2996env.stepOverInstruction(thread);2997printStack(thread);2998msg("ForceEarlyReturn DONE");2999}30003001@Override3002public boolean shouldSkip() {3003// OOMEs because of realloc failures with DeoptimizeObjectsALot are too random.3004// And Graal currently doesn't support Force Early Return3005return super.shouldSkip() ||3006!env.targetVMOptions.EliminateAllocations ||3007// With ZGC the OOME is not always thrown as expected3008env.targetVMOptions.ZGCIsSelected ||3009env.targetVMOptions.DeoptimizeObjectsALot ||3010env.targetVMOptions.UseJVMCICompiler;3011}3012}30133014class EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsReallocFailureTarget extends EATestCaseBaseTarget {30153016public int checkSum;30173018public void dontinline_testMethod() {3019long a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // scalar replaced3020Vector10 v = new Vector10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // scalar replaced3021long l = inlinedCallForcedToReturn();3022lResult = a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] + a[8] + a[9]3023+ v.i0 + v.i1 + v.i2 + v.i3 + v.i4 + v.i5 + v.i6 + v.i7 + v.i8 + v.i9 + l;3024}30253026public long inlinedCallForcedToReturn() { // forced to return 433027long cs = checkSum;3028dontinline_consumeAllMemory();3029while (loopCount-- > 0) {3030targetIsInLoop = true;3031checkSum += checkSum % ++cs;3032}3033loopCount = 3;3034targetIsInLoop = false;3035return checkSum;3036}30373038public void dontinline_consumeAllMemory() {3039if (warmupDone) {3040consumeAllMemory();3041}3042}30433044@Override3045public long getExpectedLResult() {3046long n = 10;3047return 2*n*(n+1)/2 + 43;3048}30493050@Override3051public void setUp() {3052super.setUp();3053testMethodDepth = 2;3054loopCount = 3;3055}30563057public void warmupDone() {3058super.warmupDone();3059msg("enter 'endless' loop by setting loopCount = Long.MAX_VALUE");3060loopCount = Long.MAX_VALUE; // endless loop3061}30623063@Override3064public boolean shouldSkip() {3065// OOMEs because of realloc failures with DeoptimizeObjectsALot are too random.3066// And Graal currently doesn't support Force Early Return3067return super.shouldSkip() ||3068!EliminateAllocations ||3069// With ZGC the OOME is not always thrown as expected3070ZGCIsSelected ||3071DeoptimizeObjectsALot ||3072UseJVMCICompiler;3073}3074}30753076/////////////////////////////////////////////////////////////////////////////3077//3078// Get Instances of ReferenceType3079//3080/////////////////////////////////////////////////////////////////////////////30813082/**3083* Check if instances of a type are found even if they are scalar replaced. To stress the3084* implementation a little more, the instances should be retrieved while the target is running.3085*/3086class EAGetInstancesOfReferenceType extends EATestCaseBaseDebugger {30873088public void runTestCase() throws Exception {3089printStack(env.targetMainThread);3090ReferenceType cls = ((ClassObjectReference)getField(testCase, "cls")).reflectedType();3091msg("reflected type is " + cls);3092msg("resume");3093env.vm().resume();3094waitUntilTargetHasEnteredEndlessLoop();3095// do this while thread is running!3096msg("Retrieve instances of " + cls.name());3097List<ObjectReference> instances = cls.instances(10);3098Asserts.assertEQ(instances.size(), 3, "unexpected number of instances of " + cls.name());3099// invariant: main thread is suspended at the end of the test case3100msg("suspend");3101env.targetMainThread.suspend();3102terminateEndlessLoop();3103}3104}31053106class EAGetInstancesOfReferenceTypeTarget extends EATestCaseBaseTarget {31073108public long checkSum;31093110public static Class<LocalXYVal> cls = LocalXYVal.class;31113112public static class LocalXYVal {3113public int x, y;31143115public LocalXYVal(int x, int y) {3116this.x = x; this.y = y;3117}3118}31193120@Override3121public void dontinline_testMethod() {3122LocalXYVal p1 = new LocalXYVal(4, 2);3123LocalXYVal p2 = new LocalXYVal(5, 3);3124LocalXYVal p3 = new LocalXYVal(6, 4);3125dontinline_endlessLoop();3126iResult = p1.x+p1.y + p2.x+p2.y + p3.x+p3.y;3127}31283129@Override3130public int getExpectedIResult() {3131return 6+8+10;3132}31333134@Override3135public void setUp() {3136super.setUp();3137testMethodDepth = 2;3138loopCount = 3;3139}31403141public void warmupDone() {3142super.warmupDone();3143msg("enter 'endless' loop by setting loopCount = Long.MAX_VALUE");3144loopCount = Long.MAX_VALUE; // endless loop3145}3146}314731483149// End of test case collection3150/////////////////////////////////////////////////////////////////////////////31513152/////////////////////////////////////////////////////////////////////////////3153// Helper classes3154class XYVal {31553156public int x, y;31573158public XYVal(int x, int y) {3159this.x = x;3160this.y = y;3161}31623163/**3164* Note that we don't use a sync block here because javac would generate an synthetic exception3165* handler for the synchronized block that catches Throwable E, unlocks and throws E3166* again. The throw bytecode causes the BCEscapeAnalyzer to set the escape state to GlobalEscape3167* (see comment on exception handlers in BCEscapeAnalyzer::iterate_blocks())3168*/3169public synchronized void dontinline_sync_method(EATestCaseBaseTarget target) {3170target.dontinline_brkpt();3171}31723173/**3174* Just like {@link #dontinline_sync_method(EATestCaseBaseTarget)} but without the call to3175* {@link EATestCaseBaseTarget#dontinline_brkpt()}.3176*/3177public synchronized void dontinline_sync_method_no_brkpt(EATestCaseBaseTarget target) {3178}3179}31803181class Vector10 {3182int i0, i1, i2, i3, i4, i5, i6, i7, i8, i9;3183public Vector10(int j0, int j1, int j2, int j3, int j4, int j5, int j6, int j7, int j8, int j9) {3184i0=j0; i1=j1; i2=j2; i3=j3; i4=j4; i5=j5; i6=j6; i7=j7; i8=j8; i9=j9;3185}3186}31873188class ILFDO {31893190public int i;3191public int i2;3192public long l;3193public long l2;3194public float f;3195public float f2;3196public double d;3197public double d2;3198public Long o;3199public Long o2;32003201public ILFDO(int i,3202int i2,3203long l,3204long l2,3205float f,3206float f2,3207double d,3208double d2,3209Long o,3210Long o2) {3211this.i = i;3212this.i2 = i2;3213this.l = l;3214this.l2 = l2;3215this.f = f;3216this.f2 = f2;3217this.d = d;3218this.d2 = d2;3219this.o = o;3220this.o2 = o2;3221}32223223}322432253226