// // ANALYZING TEST FAILURES // // - Executing just a single test case with the property EATests.onlytestcase. // // Example: java -DEATests.onlytestcase=<test case name> ... EATests // // - Interactive execution allows for attaching a native debugger, e.g. gdb // // Example: java -DEATests.interactive=true ... EATests // // - Java arguments to the test are passed as vm options to the debuggee: // // Example: java ... EATests -XX:+UseNewCode //
///////////////////////////////////////////////////////////////////////////// // // Shared base class for test cases for both, debugger and debuggee. // /////////////////////////////////////////////////////////////////////////////
class EATestCaseBaseShared { // In interactive mode we wait for a keypress before every test case. publicstaticfinalboolean INTERACTIVE =
System.getProperty("EATests.interactive") != null &&
System.getProperty("EATests.interactive").equals("true");
// If the property is given, then just the test case it refers to is executed. // Use it to diagnose test failures. publicstaticfinal String RUN_ONLY_TEST_CASE_PROPERTY = "EATests.onlytestcase"; publicstaticfinal String RUN_ONLY_TEST_CASE = System.getProperty(RUN_ONLY_TEST_CASE_PROPERTY);
///////////////////////////////////////////////////////////////////////////// // // Target main class, i.e. the program to be debugged. // /////////////////////////////////////////////////////////////////////////////
// Materializing test cases, i.e. reallocating objects on the heap new EAMaterializeLocalVariableUponGetTarget() .run(); new EAGetWithoutMaterializeTarget() .run(); new EAMaterializeLocalAtObjectReturnTarget() .run(); new EAMaterializeLocalAtObjectPollReturnReturnTarget() .run(); new EAMaterializeIntArrayTarget() .run(); new EAMaterializeLongArrayTarget() .run(); new EAMaterializeFloatArrayTarget() .run(); new EAMaterializeDoubleArrayTarget() .run(); new EAMaterializeObjectArrayTarget() .run(); new EAMaterializeObjectWithConstantAndNotConstantValuesTarget() .run(); new EAMaterializeObjReferencedBy2LocalsTarget() .run(); new EAMaterializeObjReferencedBy2LocalsAndModifyTarget() .run(); new EAMaterializeObjReferencedBy2LocalsInDifferentVirtFramesTarget() .run(); new EAMaterializeObjReferencedBy2LocalsInDifferentVirtFramesAndModifyTarget() .run(); new EAMaterializeObjReferencedFromOperandStackTarget() .run(); new EAMaterializeLocalVariableUponGetAfterSetIntegerTarget() .run();
// Relocking test cases new EARelockingSimpleTarget() .run(); new EARelockingRecursiveTarget() .run(); new EARelockingNestedInflatedTarget() .run(); new EARelockingNestedInflated_02Target() .run(); new EARelockingArgEscapeLWLockedInCalleeFrameTarget() .run(); new EARelockingArgEscapeLWLockedInCalleeFrame_2Target() .run(); new EAGetOwnedMonitorsTarget() .run(); new EAEntryCountTarget() .run(); new EARelockingObjectCurrentlyWaitingOnTarget() .run();
// Test cases that require deoptimization even though neither // locks nor allocations are eliminated at the point where // escape state is changed. new EADeoptFrameAfterReadLocalObject_01Target() .run(); new EADeoptFrameAfterReadLocalObject_01BTarget() .run(); new EADeoptFrameAfterReadLocalObject_02Target() .run(); new EADeoptFrameAfterReadLocalObject_02BTarget() .run(); new EADeoptFrameAfterReadLocalObject_02CTarget() .run(); new EADeoptFrameAfterReadLocalObject_03Target() .run();
// PopFrame test cases new EAPopFrameNotInlinedTarget() .run(); new EAPopFrameNotInlinedReallocFailureTarget() .run(); new EAPopInlinedMethodWithScalarReplacedObjectsReallocFailureTarget() .run();
// ForceEarlyReturn test cases new EAForceEarlyReturnNotInlinedTarget() .run(); new EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsTarget() .run(); new EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsReallocFailureTarget().run();
// Instances of ReferenceType new EAGetInstancesOfReferenceTypeTarget() .run();
}
}
///////////////////////////////////////////////////////////////////////////// // // Debugger main class // /////////////////////////////////////////////////////////////////////////////
publicclass EATests extends TestScaffold {
public TargetVMOptions targetVMOptions; public ThreadReference targetMainThread;
public TargetVMOptions(EATests env, ClassType testCaseBaseTargetClass) {
Value val;
val = testCaseBaseTargetClass.getValue(testCaseBaseTargetClass.fieldByName("DoEscapeAnalysis"));
DoEscapeAnalysis = ((PrimitiveValue) val).booleanValue(); // Escape analysis is a prerequisite for scalar replacement (EliminateAllocations)
val = testCaseBaseTargetClass.getValue(testCaseBaseTargetClass.fieldByName("EliminateAllocations"));
EliminateAllocations = DoEscapeAnalysis && ((PrimitiveValue) val).booleanValue();
val = testCaseBaseTargetClass.getValue(testCaseBaseTargetClass.fieldByName("DeoptimizeObjectsALot"));
DeoptimizeObjectsALot = ((PrimitiveValue) val).booleanValue();
val = testCaseBaseTargetClass.getValue(testCaseBaseTargetClass.fieldByName("UseJVMCICompiler"));
UseJVMCICompiler = ((PrimitiveValue) val).booleanValue();
val = testCaseBaseTargetClass.getValue(testCaseBaseTargetClass.fieldByName("ZGCIsSelected"));
ZGCIsSelected = ((PrimitiveValue) val).booleanValue();
val = testCaseBaseTargetClass.getValue(testCaseBaseTargetClass.fieldByName("StressReflectiveCode"));
StressReflectiveCode = ((PrimitiveValue) val).booleanValue();
}
}
// Execute known test cases protectedvoid runTests() throws Exception {
String targetProgName = EATestsTarget.class.getName();
msg("starting to main method in class " + targetProgName);
startToMain(targetProgName);
msg("resuming to EATestCaseBaseTarget.staticSetUpDone()V");
targetMainThread = resumeTo("EATestCaseBaseTarget", "staticSetUpDone", "()V").thread();
Location loc = targetMainThread.frame(0).location();
Asserts.assertEQ("staticSetUpDone", loc.method().name());
targetVMOptions = new TargetVMOptions(this, (ClassType) loc.declaringType());
// Materializing test cases, i.e. reallocating objects on the heap new EAMaterializeLocalVariableUponGet() .run(this); new EAGetWithoutMaterialize() .run(this); new EAMaterializeLocalAtObjectReturn() .run(this); new EAMaterializeLocalAtObjectPollReturnReturn() .run(this); new EAMaterializeIntArray() .run(this); new EAMaterializeLongArray() .run(this); new EAMaterializeFloatArray() .run(this); new EAMaterializeDoubleArray() .run(this); new EAMaterializeObjectArray() .run(this); new EAMaterializeObjectWithConstantAndNotConstantValues() .run(this); new EAMaterializeObjReferencedBy2Locals() .run(this); new EAMaterializeObjReferencedBy2LocalsAndModify() .run(this); new EAMaterializeObjReferencedBy2LocalsInDifferentVirtFrames() .run(this); new EAMaterializeObjReferencedBy2LocalsInDifferentVirtFramesAndModify() .run(this); new EAMaterializeObjReferencedFromOperandStack() .run(this); new EAMaterializeLocalVariableUponGetAfterSetInteger() .run(this);
// Relocking test cases new EARelockingSimple() .run(this); new EARelockingRecursive() .run(this); new EARelockingNestedInflated() .run(this); new EARelockingNestedInflated_02() .run(this); new EARelockingArgEscapeLWLockedInCalleeFrame() .run(this); new EARelockingArgEscapeLWLockedInCalleeFrame_2() .run(this); new EAGetOwnedMonitors() .run(this); new EAEntryCount() .run(this); new EARelockingObjectCurrentlyWaitingOn() .run(this);
// Test cases that require deoptimization even though neither // locks nor allocations are eliminated at the point where // escape state is changed. new EADeoptFrameAfterReadLocalObject_01() .run(this); new EADeoptFrameAfterReadLocalObject_01B() .run(this); new EADeoptFrameAfterReadLocalObject_02() .run(this); new EADeoptFrameAfterReadLocalObject_02B() .run(this); new EADeoptFrameAfterReadLocalObject_02C() .run(this); new EADeoptFrameAfterReadLocalObject_03() .run(this);
// PopFrame test cases new EAPopFrameNotInlined() .run(this); new EAPopFrameNotInlinedReallocFailure() .run(this); new EAPopInlinedMethodWithScalarReplacedObjectsReallocFailure() .run(this);
// ForceEarlyReturn test cases new EAForceEarlyReturnNotInlined() .run(this); new EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjects() .run(this); new EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsReallocFailure().run(this);
// Instances of ReferenceType new EAGetInstancesOfReferenceType() .run(this);
// resume the target listening for events
listenUntilVMDisconnect();
}
// Print a Message publicvoid msg(String m) {
System.out.println();
System.out.println("###(Debugger) " + m);
System.out.println();
}
///////////////////////////////////////////////////////////////////////////// // // Base class for debugger side of test cases. // /////////////////////////////////////////////////////////////////////////////
@Override publicboolean shouldSkip() { // Skip if StressReflectiveCode because it effectively disables escape analysis returnsuper.shouldSkip() || env.targetVMOptions.StressReflectiveCode;
}
publicvoid run(EATests env) { this.env = env; if (shouldSkip()) {
msg("skipping " + testCaseName); return;
} try {
msgHL("Executing test case " + getClass().getName());
env.testFailed = false;
if (INTERACTIVE)
env.waitForInput();
resumeToWarmupDone();
runTestCase();
Asserts.assertTrue(env.targetMainThread.isSuspended(), "must be suspended after the testcase");
resumeToTestCaseDone();
checkPostConditions();
} catch (Exception e) {
Asserts.fail("Unexpected exception in test case " + getClass().getName(), e);
}
}
///////////////////////////////////////////////////////////////////////////// // // Base class for debuggee side of test cases. // /////////////////////////////////////////////////////////////////////////////
// Some of the fields are only read by the debugger publicstaticfinalboolean UseJVMCICompiler = unbox(WB.getBooleanVMFlag("UseJVMCICompiler"), false); publicstaticfinalboolean DoEscapeAnalysis = unbox(WB.getBooleanVMFlag("DoEscapeAnalysis"), UseJVMCICompiler); publicstaticfinalboolean EliminateAllocations = unbox(WB.getBooleanVMFlag("EliminateAllocations"), UseJVMCICompiler); publicstaticfinalboolean DeoptimizeObjectsALot = WB.getBooleanVMFlag("DeoptimizeObjectsALot"); publicstaticfinalboolean ZGCIsSelected = GC.Z.isSelected(); publicstaticfinalboolean StressReflectiveCode = unbox(WB.getBooleanVMFlag("StressReflectiveCode"), false);
public String testMethodName; publicint testMethodDepth;
// Results produced by dontinline_testMethod() publicint iResult; publiclong lResult; publicfloat fResult; publicdouble dResult;
publicboolean warmupDone;
// an object with an inflated monitor publicstatic XYVal inflatedLock; publicstaticThread inflatorThread; publicstaticboolean inflatedLockIsPermanentlyInflated;
/** *Itisacommonprotocoltohavethedebuggersetabreakpointinthismethodandhave{@link *#dontinline_testMethod()}callitandthenperformsometestactionsondebuggerside. *Afterthatitischeckedifaframeof{@link#dontinline_testMethod()}isfoundatthe *expecteddepthonstackandifitis(not)markedfordeoptimizationasexpected.
*/ publicvoid dontinline_brkpt() { // will set breakpoint here after warmup if (warmupDone) { // check if test method is at expected depth
StackTraceElement[] frames = Thread.currentThread().getStackTrace(); int stackTraceDepth = testMethodDepth + 1; // ignore java.lang.Thread.getStackTrace()
Asserts.assertEQ(testMethodName, frames[stackTraceDepth].getMethodName(),
testCaseName + ": test method not found at depth " + testMethodDepth); // check if the frame is (not) deoptimized as expected if (!DeoptimizeObjectsALot) { if (testFrameShouldBeDeoptimized()) {
Asserts.assertTrue(WB.isFrameDeoptimized(testMethodDepth+1),
testCaseName + ": expected test method frame at depth " + testMethodDepth + " to be deoptimized");
} else {
Asserts.assertFalse(WB.isFrameDeoptimized(testMethodDepth+1),
testCaseName + ": expected test method frame at depth " + testMethodDepth + " not to be deoptimized");
}
}
}
}
// Debugger will set breakpoint here to sync with target. publicvoid testCaseDone() {
}
publicvoid compileTestMethod() throws Exception { int callCount = CompilerWhiteBoxTest.THRESHOLD; while (callCount-- > 0) {
dontinline_testMethod();
}
}
publicvoid checkCompLevel() {
java.lang.reflect.Method m = null; try {
m = getClass().getMethod(TESTMETHOD_DEFAULT_NAME);
} catch (NoSuchMethodException | SecurityException e) {
Asserts.fail("could not check compilation level of", e);
} int highestLevel = CompilerUtils.getMaxCompilationLevel(); int compLevel = WB.getMethodCompilationLevel(m); if (!UseJVMCICompiler) {
Asserts.assertEQ(highestLevel, compLevel,
m + " not on expected compilation level");
} else { // Background compilation (-Xbatch) will block a thread with timeout // (see CompileBroker::wait_for_jvmci_completion()). Therefore it is // possible to reach here before the main test method is compiled. // In that case we wait for it to be compiled. while (compLevel != highestLevel) {
msg(TESTMETHOD_DEFAULT_NAME + " is compiled on level " + compLevel + ". Wait until highes level (" + highestLevel + ") is reached."); try { Thread.sleep(200);
} catch (InterruptedException e) { /* ignored */ }
compLevel = WB.getMethodCompilationLevel(m);
}
}
}
// to be overridden as appropriate publicint getExpectedIResult() { return0;
}
// to be overridden as appropriate publiclong getExpectedLResult() { return0;
}
// to be overridden as appropriate publicfloat getExpectedFResult() { return0f;
}
// to be overridden as appropriate publicdouble getExpectedDResult() { return0d;
}
// The object passed will be ArgEscape if it was NoEscape before. publicfinalvoid dontinline_make_arg_escape(XYVal xy) {
}
/** *Callamethodindirectlyusingreflection.Theindirectionisalimitforescape *analysisinthesensethattheVMneednotsearchbeyondforframesthatmighthave *anobjectbeingreadbyanJVMTIagentasArgEscape. *@paramreceiverThereceiverobjectofthecall. *@parammethodNameThenameofthemethodtobecalled.
*/ publicfinalvoid dontinline_call_with_entry_frame(Object receiver, String methodName) {
Asserts.assertTrue(warmupDone, "We want to take the slow path through jni, so don't call in warmup");
// // Tests the following: // // 1. Debugger can obtain a reference to a scalar replaced object R from java thread J. // See runTestCase. // // 2. Subsequent modifications of R by J are noticed by the debugger. // See checkPostConditions. // class EAMaterializeLocalVariableUponGet extends EATestCaseBaseDebugger {
private ObjectReference o;
publicvoid runTestCase() throws Exception {
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
printStack(bpe.thread()); // check 1.
o = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "xy"); // o is referenced in checkPostConditions() and must not be gc'ed.
o.disableCollection();
checkPrimitiveField(o, FD.I, "x", 4);
checkPrimitiveField(o, FD.I, "y", 2);
}
// Test if an eliminated object can be reallocated in a frame with an active // call that will return another object class EAMaterializeLocalAtObjectReturn extends EATestCaseBaseDebugger { publicvoid runTestCase() throws Exception {
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
printStack(bpe.thread());
ObjectReference o = getLocalRef(bpe.thread().frame(2), XYVAL_NAME, "xy");
checkPrimitiveField(o, FD.I, "x", 4);
checkPrimitiveField(o, FD.I, "y", 2);
}
}
public Integer dontinline_brkpt_return_Integer() { // We can't break directly in this method, as this results in making // the test method not entrant caused by an existing dependency
dontinline_brkpt(); return Integer.valueOf(23);
}
// Test if an eliminated object can be reallocated *just* before a call returns an object. // (See CompiledMethod::is_at_poll_return()) // Details: the callee method has just one safepoint poll at the return. The other safepoint // is at the end of an iteration of the endless loop. We can detect if we suspended the target // there because the local xy is out of scope there. class EAMaterializeLocalAtObjectPollReturnReturn extends EATestCaseBaseDebugger { publicvoid runTestCase() throws Exception {
msg("Resume " + env.targetMainThread);
env.vm().resume();
waitUntilTargetHasEnteredEndlessLoop();
ObjectReference o = null; int retryCount = 0; do {
env.targetMainThread.suspend();
printStack(env.targetMainThread); try {
o = getLocalRef(env.targetMainThread.frame(0), XYVAL_NAME, "xy");
} catch (Exception e) {
++retryCount;
msg("The local variable xy is out of scope because we suspended at the wrong bci. Resume and try again! (" + retryCount + ")");
env.targetMainThread.resume(); if ((retryCount % 10) == 0) { Thread.sleep(200);
}
}
} while (o == null);
checkPrimitiveField(o, FD.I, "x", 4);
checkPrimitiveField(o, FD.I, "y", 2);
terminateEndlessLoop();
}
}
publicvoid dontinline_testMethod() { long result = 0; while (doLoop && loopCount-- > 0) {
targetIsInLoop = true;
XYVal xy = new XYVal(4, 2);
Integer io = // Read xy here triggers reallocation just before the call returns
dontinline_brkpt_return_Integer();
result += xy.x + xy.y + io;
} // Here is a second safepoint. We were suspended here if xy is not in scope.
targetIsInLoop = false;
lResult = result;
}
public Integer dontinline_brkpt_return_Integer() { return Integer.valueOf(23);
}
///////////////////////////////////////////////////////////////////////////// // Test case collection that tests rematerialization of different // array types where the first element is always not constant and the // other elements are constants. Not constant values are stored in // the stack frame for rematerialization whereas constants are kept // in the debug info of the nmethod.
class EAMaterializeIntArrayTarget extends EATestCaseBaseTarget {
// Materialize an object whose fields have constant and not constant values at // the point where the object is materialized. class EAMaterializeObjectWithConstantAndNotConstantValuesTarget extends EATestCaseBaseTarget {
// Two local variables reference the same object. // Check if the debugger obtains the same object when reading the two variables class EAMaterializeObjReferencedBy2LocalsTarget extends EATestCaseBaseTarget {
publicvoid dontinline_testMethod() {
XYVal xy = new XYVal(2, 3);
XYVal alias = xy;
dontinline_brkpt();
iResult = xy.x + alias.x;
}
// Two local variables reference the same object. // Check if it has the expected effect in the target if the debugger modifies the object. class EAMaterializeObjReferencedBy2LocalsAndModifyTarget extends EATestCaseBaseTarget {
// Two local variables of the same compiled frame but in different virtual frames reference the same // object. // Check if the debugger obtains the same object when reading the two variables class EAMaterializeObjReferencedBy2LocalsInDifferentVirtFramesTarget extends EATestCaseBaseTarget {
// Two local variables of the same compiled frame but in different virtual frames reference the same // object. // Check if it has the expected effect in the target if the debugger modifies the object. class EAMaterializeObjReferencedBy2LocalsInDifferentVirtFramesAndModifyTarget extends EATestCaseBaseTarget {
// Test materialization of an object referenced only from expression stack class EAMaterializeObjReferencedFromOperandStackTarget extends EATestCaseBaseTarget {
publicvoid dontinline_testMethod() {
@SuppressWarnings("unused")
XYVal xy1 = new XYVal(2, 3); // Debugger breaks in call to dontinline_brkpt_ret_100() and reads // the value of the local 'xy1'. This triggers materialization // of the object on the operand stack
iResult = testMethodInlined(new XYVal(4, 2), dontinline_brkpt_ret_100());
}
// Object ref l1 is retrieved by the debugger at a location where nested locks are omitted. The // accessed object is globally reachable already before the access, therefore no relocking is done. class EARelockingNestedInflatedTarget extends EATestCaseBaseTarget {
@Override publicboolean testFrameShouldBeDeoptimized() { // Graal does not provide debug info about arg escape objects, therefore the frame is not deoptimized return !UseJVMCICompiler && super.testFrameShouldBeDeoptimized();
}
}
publicvoid doNotify() { while (objToNotifyOn == null) { try {
msg("objToNotifyOn is still null"); Thread.sleep(100);
} catch (InterruptedException e) { /* ignored */ }
} synchronized (objToNotifyOn) { // will be received by the target main thread waiting in dontinline_waitWhenWarmupDone
msg("calling objToNotifyOn.notifyAll()");
objToNotifyOn.notifyAll();
}
}
///////////////////////////////////////////////////////////////////////////// // // Test cases that require deoptimization even though neither locks // nor allocations are eliminated at the point where escape state is changed. // /////////////////////////////////////////////////////////////////////////////
class EADeoptFrameAfterReadLocalObject_01Target extends EATestCaseBaseTarget {
publicvoid dontinline_testMethod() {
XYVal xy = new XYVal(1, 1);
dontinline_brkpt(); // Debugger reads xy, when there are no virtual objects or eliminated locks in scope synchronized (xy) { // Locking is eliminated.
xy.x++;
xy.y++;
}
}
}
publicvoid dontinline_testMethod() {
XYVal xy = new XYVal(1, 1);
callee(xy); // Debugger acquires ref to xy from inlined callee // xy is NoEscape, nevertheless the object is not replaced // by scalars if running with -XX:-EliminateAllocations. // In that case there are no EA based optimizations were // the debugger reads the NoEscape object. synchronized (xy) { // Locking is eliminated.
xy.x++;
xy.y++;
}
}
publicvoid callee(XYVal xy) {
dontinline_brkpt(); // Debugger reads xy. // There are no virtual objects or eliminated locks.
}
}
class EADeoptFrameAfterReadLocalObject_01B extends EATestCaseBaseDebugger {
@Override publicboolean testFrameShouldBeDeoptimized() { // Graal does not provide debug info about arg escape objects, therefore the frame is not deoptimized return !UseJVMCICompiler && super.testFrameShouldBeDeoptimized();
}
}
class EADeoptFrameAfterReadLocalObject_02BTarget extends EATestCaseBaseTarget {
publicvoid dontinline_testMethod() {
XYVal xy = new XYVal(1, 1);
dontinline_make_arg_escape(xy); // because of this call xy is ArgEscape
dontinline_callee(); // xy is ArgEscape, but not a parameter of this call synchronized (xy) { // Locking is eliminated.
xy.x++;
xy.y++;
}
}
publicvoid dontinline_callee() {
@SuppressWarnings("unused")
XYVal xy = new XYVal(2, 2);
dontinline_brkpt(); // Debugger reads xy. // No need to deoptimize the caller frame
}
class EADeoptFrameAfterReadLocalObject_02CTarget extends EATestCaseBaseTarget {
publicvoid dontinline_testMethod() {
XYVal xy = new XYVal(1, 1);
dontinline_callee(xy); // xy is ArgEscape and being passed as parameter synchronized (xy) { // Locking is eliminated.
xy.x++;
xy.y++;
}
}
publicvoid dontinline_callee_accessed_by_debugger() {
@SuppressWarnings("unused")
XYVal xy = new XYVal(2, 2);
dontinline_brkpt(); // Debugger reads xy. // No need to deoptimize the caller frame
}
@Override publicvoid setUp() { super.setUp(); // the method depth in debuggee is 11 as it includes all hidden frames // the expected method depth is 6 excluding 5 hidden frames
testMethodDepth = 11-5;
}
class EADeoptFrameAfterReadLocalObject_03Target extends EATestCaseBaseTarget {
publicvoid dontinline_testMethod() {
XYVal xy = new XYVal(0, 1);
dontinline_brkpt(); // Debugger reads xy, when there are no virtual objects or // eliminated locks in scope and modifies xy.x
iResult = xy.x + xy.y; // Loads are replaced by constants 0 and 1.
}
class EAGetOwnedMonitors extends EATestCaseBaseDebugger {
publicvoid runTestCase() throws Exception {
msg("resume");
env.vm().resume();
waitUntilTargetHasEnteredEndlessLoop(); // In contrast to JVMTI, JDWP requires a target thread to be suspended, before the owned monitors can be queried
msg("suspend target");
env.targetMainThread.suspend();
msg("Get owned monitors");
List<ObjectReference> monitors = env.targetMainThread.ownedMonitors();
Asserts.assertEQ(monitors.size(), 1, "unexpected number of owned monitors");
terminateEndlessLoop();
}
}
class EAEntryCount extends EATestCaseBaseDebugger {
publicvoid runTestCase() throws Exception {
msg("resume");
env.vm().resume();
waitUntilTargetHasEnteredEndlessLoop(); // In contrast to JVMTI, JDWP requires a target thread to be suspended, before the owned monitors can be queried
msg("suspend target");
env.targetMainThread.suspend();
msg("Get owned monitors");
List<ObjectReference> monitors = env.targetMainThread.ownedMonitors();
Asserts.assertEQ(monitors.size(), 1, "unexpected number of owned monitors");
msg("Get entry count"); int entryCount = monitors.get(0).entryCount();
Asserts.assertEQ(entryCount, 2, "wrong entry count");
terminateEndlessLoop();
}
}
@Override publicboolean testFrameShouldBeDeoptimized() { // Test is only performed after the frame pop. // Then dontinline_testMethod is interpreted. returnfalse;
}
publicvoid runTestCase() throws Exception {
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
ThreadReference thread = bpe.thread();
printStack(thread); // frame[0]: EATestCaseBaseTarget.dontinline_brkpt() // frame[1]: EAPopFrameNotInlinedReallocFailureTarget.dontinline_consume_all_memory_brkpt() // frame[2]: EAPopFrameNotInlinedReallocFailureTarget.dontinline_testMethod() // frame[3]: EATestCaseBaseTarget.run() // frame[4]: EATestsTarget.main(java.lang.String[])
msg("PopFrame"); boolean coughtOom = false; try { // try to pop dontinline_consume_all_memory_brkpt thread.popFrames(thread.frame(1));
} catch (VMOutOfMemoryException oom) { // as expected
msg("cought OOM");
coughtOom = true;
}
freeAllMemory(); // We succeeded to pop just one frame. When we continue, we will call dontinline_brkpt() again.
Asserts.assertTrue(coughtOom, "PopFrame should have triggered an OOM exception in target");
String expectedTopFrame = "dontinline_consume_all_memory_brkpt";
Asserts.assertEQ(expectedTopFrame, thread.frame(0).location().method().name());
printStack(thread);
}
@Override publicboolean shouldSkip() { // OOMEs because of realloc failures with DeoptimizeObjectsALot are too random. // And Graal currently doesn't provide all information about non-escaping objects in debug info returnsuper.shouldSkip() ||
!env.targetVMOptions.EliminateAllocations || // With ZGC the OOME is not always thrown as expected
env.targetVMOptions.ZGCIsSelected ||
env.targetVMOptions.DeoptimizeObjectsALot ||
env.targetVMOptions.UseJVMCICompiler;
}
}
class EAPopFrameNotInlinedReallocFailureTarget extends EATestCaseBaseTarget {
@Override publiclong getExpectedLResult() { long n = 10; return2*n*(n+1)/2;
}
@Override publicboolean shouldSkip() { // OOMEs because of realloc failures with DeoptimizeObjectsALot are too random. // And Graal currently doesn't provide all information about non-escaping objects in debug info returnsuper.shouldSkip() ||
!EliminateAllocations || // With ZGC the OOME is not always thrown as expected
ZGCIsSelected ||
DeoptimizeObjectsALot ||
UseJVMCICompiler;
}
}
msg("Pop Frames"); boolean coughtOom = false; try { thread.popFrames(thread.frame(0)); // Request pop frame of inlinedCallForcedToReturn() // reallocation is triggered here
} catch (VMOutOfMemoryException oom) { // as expected
msg("cought OOM");
coughtOom = true;
}
printStack(thread); // frame[0]: EAPopInlinedMethodWithScalarReplacedObjectsReallocFailureTarget.inlinedCallForcedToReturn() // frame[1]: EAPopInlinedMethodWithScalarReplacedObjectsReallocFailureTarget.dontinline_testMethod() // frame[2]: EATestCaseBaseTarget.run()
freeAllMemory();
setField(testCase, "loopCount", env.vm().mirrorOf(0)); // terminate loop
Asserts.assertTrue(coughtOom, "PopFrame should have triggered an OOM exception in target");
String expectedTopFrame = "inlinedCallForcedToReturn";
Asserts.assertEQ(expectedTopFrame, thread.frame(0).location().method().name());
}
@Override public boolean shouldSkip() { // OOMEs because of realloc failures with DeoptimizeObjectsALot are too random. // And Graal currently doesn't provide all information about non-escaping objects in debug info return super.shouldSkip() ||
!env.targetVMOptions.EliminateAllocations || // With ZGC the OOME is not always thrown as expected
env.targetVMOptions.ZGCIsSelected ||
env.targetVMOptions.DeoptimizeObjectsALot ||
env.targetVMOptions.UseJVMCICompiler;
}
}
class EAPopInlinedMethodWithScalarReplacedObjectsReallocFailureTarget extends EATestCaseBaseTarget {
@Override public boolean shouldSkip() { // OOMEs because of realloc failures with DeoptimizeObjectsALot are too random. // And Graal currently doesn't provide all information about non-escaping objects in debug info return super.shouldSkip() ||
!EliminateAllocations || // With ZGC the OOME is not always thrown as expected
ZGCIsSelected ||
DeoptimizeObjectsALot ||
UseJVMCICompiler;
}
}
msg("Step out");
env.stepOut(thread); // return from dontinline_brkpt
printStack(thread);
msg("ForceEarlyReturn");
thread.forceEarlyReturn(env.vm().mirrorOf(43)); // return from dontinline_brkpt_iret, // does not trigger reallocation in contrast to PopFrame
msg("Step over line");
env.stepOverLine(thread); // reallocation is triggered here
printStack(thread);
msg("ForceEarlyReturn DONE");
}
@Override public boolean shouldSkip() { // Graal currently doesn't support Force Early Return return super.shouldSkip() || env.targetVMOptions.UseJVMCICompiler;
}
}
class EAForceEarlyReturnNotInlinedTarget extends EATestCaseBaseTarget {
publicvoid dontinline_testMethod() {
XYVal xy = new XYVal(4, 2); int i = dontinline_brkpt_iret();
iResult = xy.x + xy.y + i;
}
msg("ForceEarlyReturn");
thread.forceEarlyReturn(env.vm().mirrorOf(43)); // Request force return 43 from inlinedCallForcedToReturn() // reallocation is triggered here
msg("Step over instruction to do the forced return");
env.stepOverInstruction(thread);
printStack(thread);
msg("ForceEarlyReturn DONE");
}
@Override public boolean shouldSkip() { // Graal currently doesn't support Force Early Return return super.shouldSkip() || env.targetVMOptions.UseJVMCICompiler;
}
}
class EAForceEarlyReturnOfInlinedMethodWithScalarReplacedObjectsTarget extends EATestCaseBaseTarget {
publicint checkSum;
publicvoid dontinline_testMethod() {
XYVal xy = new XYVal(4, 2); int i = inlinedCallForcedToReturn();
iResult = xy.x + xy.y + i;
}
publicint inlinedCallForcedToReturn() { // forced to return 43 int i = checkSum; while (loopCount-- > 0) {
targetIsInLoop = true;
checkSum += checkSum % ++i;
}
loopCount = 3;
targetIsInLoop = false; return checkSum;
}
(ForceEarlyReturn;
boolean coughtOom = false; tryjava.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
thread.java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
} catchhb_user_data_key_ key // as expected
msg("cought OOM");
coughtOom = true;
}
freeAllMemory();
Asserts.assertTrue(coughtOom, "ForceEarlyReturn should have triggered an OOM exception in target");
printStack(thread);
msg("ForceEarlyReturn(2)");
thread.forceEarlyReturn(env.vm().mirrorOf(43));
Stepover java.lang.StringIndexOutOfBoundsException: Range [52, 51) out of bounds for length 61
env.stepOverInstruction(thread);
(hread
msg("* @font: #hb_font_t work java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
}
@Override
* A virtual hjava.lang.StringIndexOutOfBoundsException: Range [61, 44) out of bounds for length 69 // OOMEs because of realloc failures with DeoptimizeObjectsALot are too random. // And Graal currently doesn't support Force Early Return
hb_font_get_font_v_extents_func_t:
!env.targetVMOptions.EliminateAllocations || // With ZGC the OOME is not always thrown as expected
env.targetVMOptions.ZGCIsSelected ||
env.targetVMOptions.DeoptimizeObjectsALot ||
env.targetVMOptions.UseJVMCICompiler;
}
}
@
hb_font_get_glyph_advance java.lang.StringIndexOutOfBoundsException: Index 76 out of bounds for length 76
/ becauseDeoptimizeObjectsALotare // And Graal currently doesn't support Force Early Return return super.shouldSkip() ||
!EliminateAllocations || // With ZGC the OOME is not always thrown as expected
ZGCIsSelected ||
DeoptimizeObjectsALot ||
UseJVMCICompiler;
his should retrievetheadvances asequencejava.lang.StringIndexOutOfBoundsException: Range [69, 68) out of bounds for length 69
}
///////////////////////////////////////////////////////////////////////////// // // Get Instances of ReferenceType // /////////////////////////////////////////////////////////////////////////////
/** *Checkifinstancesofatypearefoundeveniftheyarescalarreplaced.Tostressthe *implementationalittlemore,theinstancesshouldberetrievedwhilethetargetisrunning.
*/ class EAGetInstancesOfReferenceType extends EATestCaseBaseDebugger {
publicvoid runTestCase() throws Exception {
printStack(env.targetMainThread);
*
msg("reflected type is " + cls);
msg("resume");
env
waitUntilTargetHasEnteredEndlessLoop(); // do this while thread is running!
msg("Retrieve instances of " + cls.name());
List<ObjectReference> instances = cls.instances(10);
Asserts.assertEQ(instances.size(), 3, "unexpected number of instances of " + cls.name());
msg("suspend"java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
env.targetMainThread.suspend();
terminateEndlessLoop();
}
}
public LocalXYVal(int x, int y) { this.x = x; this.y = y;
}
}
@Override publicvoid dontinline_testMethod() {
LocalXYVal p1 = new LocalXYVal glyph: The tojava.lang.StringIndexOutOfBoundsException: Range [32, 33) out of bounds for length 32
LocalXYVal p2 = new LocalXYVal(5, 3);
LocalXYVal p3 = new LocalXYVal(6, 4);
dontinline_endlessLoop();
java.lang.StringIndexOutOfBoundsException: Range [20, 15) out of bounds for length 52
}
@Override publicint _(*hb_font_get_glyph_extents_func_t)(*font,void *java.lang.StringIndexOutOfBoundsException: Range [88, 87) out of bounds for length 88 return6+8+10;
}
@java.lang.StringIndexOutOfBoundsException: Range [13, 14) out of bounds for length 13 publicvoid setUp() {
super.setUp();
testMethodDepth = 2;
loopCount = 3;
}
// End of test case collection /////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////// // Helper classes class XYVal {
publicint x, y;
public XYVal(intvoid *user_data; this.x = x; this.y = y;
}
/** *Notethatwedon'tuseasyncblockherebecausejavacwouldgenerateansyntheticexception *handlerforthesynchronizedblockthatcatchesThrowableE,unlocksandthrowsE *again.ThethrowbytecodecausestheBCEscapeAnalyzertosettheescapestatetoGlobalEscape *(eecommentonexceptionhandlersinBCEscapeAnalyzer::iterate_blocks())
*/ public synchronized void dontinline_sync_method(EATestCaseBaseTarget:h to
dontinline_brkpt(;
}
/** *Justlike{@link#dontinline_sync_method(EATestCaseBaseTarget)}butjava.lang.StringIndexOutOfBoundsException: Index 79 out of bounds for length 2 *{@linkEATestCaseBaseTarget#dontinline_brkpt()}.
*/ public synchronized void dontinline_sync_method_no_brkpt(EATestCaseBaseTarget target) {
}
}
class Vector10 { int i0, i1, i2, i3, i4, i5, i6, i7, i8, i9; public Vector10(int j0, int j1, int j2, int j3, int j4, int j5, int j6, int j7, int j8, int j9) {
i0=j0; i1=j1; i2=j2; i3=j3; i4=j4; i5=j5; i6=j6; i7=j7; i8=j8; i9=j9;
}
}
class java.lang.StringIndexOutOfBoundsException: Range [39, 1) out of bounds for length 83
public ILFDO( * @ A-function structure int i2, long l, long l2, float f, float f2, double d, double d2, Long o Since1.2java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15 Long o2) { this.i = i; this.i2 = i2; this.l = l; this.l2 = l2; this.f = f; this.f2 = f2; this.d = d; this.d2 = d2; this.o = o; this.o2 = o2;
}
}
Messung V0.5 in Prozent
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.257Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-10-11)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.