Skip to content

Commit be3ccbb

Browse files
committed
Do not step over roots and use the next BCI depending on the suspend anchor. (GR-67909)
1 parent b1fea44 commit be3ccbb

File tree

9 files changed

+34
-35
lines changed

9 files changed

+34
-35
lines changed

espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/JDWPContext.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -382,11 +382,12 @@ public interface JDWPContext {
382382
/**
383383
* Returns the bci of the next bytecode instruction within the current frame
384384
*
385-
* @param callerRoot the root node of the caller frame
385+
* @param method the current method
386+
* @param rawNode the current node
386387
* @param frame the frame to read the current bci from
387388
* @return the bci of the next instruction
388389
*/
389-
int getNextBCI(RootNode callerRoot, Frame frame);
390+
int getNextBCI(MethodRef method, Node rawNode, Frame frame);
390391

391392
/**
392393
* Returns the current BCI or -1 if the BCI cannot be read.
@@ -395,7 +396,7 @@ public interface JDWPContext {
395396
* @param frame the frame to read the bci from
396397
* @return the BCI or -1
397398
*/
398-
long readBCIFromFrame(RootNode root, Frame frame);
399+
int readBCIFromFrame(RootNode root, Frame frame);
399400

400401
/**
401402
* Returns a {@link CallFrame} representation of the location of
@@ -461,7 +462,7 @@ public interface JDWPContext {
461462
* @param frame the current frame
462463
* @return the current bci
463464
*/
464-
long getBCI(Node rawNode, Frame frame);
465+
int getBCI(Node rawNode, Frame frame);
465466

466467
/**
467468
* Returns the instrumentable delegate node for the language root node or <code>rootNode</code>

espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/MethodRef.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ public interface MethodRef {
231231
*
232232
* @return last bci
233233
*/
234-
long getLastBCI();
234+
int getLastBCI();
235235

236236
/**
237237
* Determines if the method is a constructor.

espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/VMEventListenerImpl.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
import com.oracle.truffle.api.interop.UnsupportedMessageException;
3939
import com.oracle.truffle.espresso.jdwp.impl.BreakpointInfo;
4040
import com.oracle.truffle.espresso.jdwp.impl.ClassPrepareRequest;
41-
import com.oracle.truffle.espresso.jdwp.impl.DebuggerCommand;
4241
import com.oracle.truffle.espresso.jdwp.impl.DebuggerController;
4342
import com.oracle.truffle.espresso.jdwp.impl.FieldBreakpointEvent;
4443
import com.oracle.truffle.espresso.jdwp.impl.FieldBreakpointInfo;
@@ -532,13 +531,6 @@ public void stepCompleted(SteppingInfo info, CallFrame currentFrame) {
532531
stream.writeLong(currentFrame.getClassId());
533532
stream.writeLong(currentFrame.getMethodId());
534533
long codeIndex = currentFrame.getCodeIndex();
535-
if (info.getStepKind() == DebuggerCommand.Kind.STEP_OUT) {
536-
// Step out in Truffle is implemented on the callee exit, where the event's top
537-
// stack frame is set to the caller frame. Hence, to avoid sending the code index
538-
// from the caller location, we must fetch the next bci from the frame to pass the
539-
// correct location.
540-
codeIndex = context.getNextBCI(currentFrame.getRootNode(), currentFrame.getFrame());
541-
}
542534
stream.writeLong(codeIndex);
543535
debuggerController.fine(() -> "Sending step completed event");
544536

espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/DebuggerController.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ public void initialize(Debugger debug, JDWPOptions jdwpOptions, JDWPContext jdwp
127127
ids.injectLogger(jdwpLogger);
128128

129129
// set up the debug session object early to make sure instrumentable nodes are materialized
130-
debuggerSession = debug.startSession(new SuspendedCallbackImpl(), SourceElement.ROOT, SourceElement.STATEMENT);
130+
debuggerSession = debug.startSession(new SuspendedCallbackImpl(), SourceElement.STATEMENT);
131131
debuggerSession.setSteppingFilter(SuspensionFilter.newBuilder().ignoreLanguageContextInitialization(true).build());
132132

133133
init(jdwpContext);
@@ -957,8 +957,8 @@ public void onSuspend(SuspendedEvent event) {
957957
return;
958958
}
959959
}
960-
boolean isStepOut = steppingInfo != null && event.isStep() && steppingInfo.getStepKind() == DebuggerCommand.Kind.STEP_OUT;
961-
CallFrame[] callFrames = createCallFrames(ids.getIdAsLong(currentThread), event.getStackFrames(), -1, isStepOut);
960+
boolean isAfter = event.getSuspendAnchor() == SuspendAnchor.AFTER;
961+
CallFrame[] callFrames = createCallFrames(ids.getIdAsLong(currentThread), event.getStackFrames(), -1, isAfter);
962962
RootNode callerRootNode = callFrames.length > 1 ? callFrames[1].getRootNode() : null;
963963

964964
SuspendedInfo suspendedInfo = new SuspendedInfo(context, event, callFrames, currentThread, callerRootNode);
@@ -1179,7 +1179,7 @@ private void continueStepping(SuspendedEvent event, SteppingInfo steppingInfo) {
11791179
}
11801180
}
11811181

1182-
private CallFrame[] createCallFrames(long threadId, Iterable<DebugStackFrame> stackFrames, int frameLimit, boolean isStepOut) {
1182+
private CallFrame[] createCallFrames(long threadId, Iterable<DebugStackFrame> stackFrames, int frameLimit, boolean isAfter) {
11831183
LinkedList<CallFrame> list = new LinkedList<>();
11841184
int frameCount = 0;
11851185
for (DebugStackFrame frame : stackFrames) {
@@ -1206,15 +1206,16 @@ private CallFrame[] createCallFrames(long threadId, Iterable<DebugStackFrame> st
12061206

12071207
Frame rawFrame = frame.getRawFrame(context.getLanguageClass(), FrameInstance.FrameAccess.READ_WRITE);
12081208
MethodVersionRef methodVersion = context.getMethodFromRootNode(root);
1209-
KlassRef klass = methodVersion.getMethod().getDeclaringKlassRef();
1209+
MethodRef method = methodVersion.getMethod();
1210+
KlassRef klass = method.getDeclaringKlassRef();
12101211

12111212
klassId = ids.getIdAsLong(klass);
1212-
methodId = ids.getIdAsLong(methodVersion.getMethod());
1213+
methodId = ids.getIdAsLong(method);
12131214
typeTag = TypeTag.getKind(klass);
1214-
if (isStepOut) {
1215-
// Truffle reports step out at the callers entry to the method, so we must fetch
1215+
if (isAfter && frameCount == 0) {
1216+
// Truffle reports anchor after this instruction, so we must fetch
12161217
// the BCI that follows to get the expected location within the frame.
1217-
codeIndex = context.getNextBCI(root, rawFrame);
1218+
codeIndex = context.getNextBCI(method, rawNode, rawFrame);
12181219
} else {
12191220
codeIndex = context.getBCI(rawNode, rawFrame);
12201221
}

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/Method.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1390,7 +1390,7 @@ public int getLastLine() {
13901390
}
13911391

13921392
@Override
1393-
public long getLastBCI() {
1393+
public int getLastBCI() {
13941394
int bci = 0;
13951395
BytecodeStream bs = new BytecodeStream(getOriginalCode());
13961396
int end = bs.endBCI();

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/JDWPContextImpl.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -654,19 +654,21 @@ public int getCatchLocation(MethodRef method, Object guestException, int bci) {
654654
}
655655

656656
@Override
657-
public int getNextBCI(RootNode callerRoot, Frame frame) {
658-
if (callerRoot instanceof EspressoRootNode espressoRootNode) {
659-
int bci = (int) readBCIFromFrame(callerRoot, frame);
660-
if (bci >= 0) {
661-
BytecodeStream bs = new BytecodeStream(espressoRootNode.getMethodVersion().getOriginalCode());
662-
return bs.nextBCI(bci);
657+
public int getNextBCI(MethodRef method, Node rawNode, Frame frame) {
658+
int bci = getBCI(rawNode, frame);
659+
if (bci >= 0) {
660+
BytecodeStream bs = new BytecodeStream(method.getOriginalCode());
661+
int nextBci = bs.nextBCI(bci);
662+
if (nextBci <= bs.endBCI()) {
663+
// Use the next only if it's in bounds.
664+
bci = nextBci;
663665
}
664666
}
665-
return -1;
667+
return bci;
666668
}
667669

668670
@Override
669-
public long readBCIFromFrame(RootNode root, Frame frame) {
671+
public int readBCIFromFrame(RootNode root, Frame frame) {
670672
if (root instanceof EspressoRootNode rootNode && frame != null) {
671673
return rootNode.readBCI(frame);
672674
}
@@ -792,7 +794,7 @@ private BciProvider getBciProviderNode(Node node) {
792794
return null;
793795
}
794796

795-
public long getBCI(Node rawNode, Frame frame) {
797+
public int getBCI(Node rawNode, Frame frame) {
796798
BciProvider bciProvider = getBciProviderNode(rawNode);
797799
if (bciProvider == null) {
798800
return -1;

tools/src/com.oracle.truffle.tools.chromeinspector.test/src/com/oracle/truffle/tools/chromeinspector/test/SLInspectDebugTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,7 +1322,7 @@ public void testRestartFrame() throws Exception {
13221322
"{\"name\":\"global\",\"type\":\"global\",\"object\":{\"description\":\"global\",\"type\":\"object\",\"objectId\":\"10\"}}]," +
13231323
"\"this\":null," +
13241324
"\"functionLocation\":{\"scriptId\":\"1\",\"columnNumber\":9,\"lineNumber\":4}," +
1325-
"\"location\":{\"scriptId\":\"1\",\"columnNumber\":28,\"lineNumber\":8}," +
1325+
"\"location\":{\"scriptId\":\"1\",\"columnNumber\":12,\"lineNumber\":8}," +
13261326
"\"url\":\"" + srcURL + "\"}," +
13271327
"{\"callFrameId\":\"1\",\"functionName\":\"factorial\"," +
13281328
"\"scopeChain\":[{\"name\":\"factorial\",\"type\":\"local\",\"object\":{\"description\":\"factorial\",\"type\":\"object\",\"objectId\":\"11\"}}," +
@@ -1347,7 +1347,7 @@ public void testRestartFrame() throws Exception {
13471347
"{\"name\":\"global\",\"type\":\"global\",\"object\":{\"description\":\"global\",\"type\":\"object\",\"objectId\":\"16\"}}]," +
13481348
"\"this\":null," +
13491349
"\"functionLocation\":{\"scriptId\":\"1\",\"columnNumber\":9,\"lineNumber\":0}," +
1350-
"\"location\":{\"scriptId\":\"1\",\"columnNumber\":14,\"lineNumber\":2}," +
1350+
"\"location\":{\"scriptId\":\"1\",\"columnNumber\":2,\"lineNumber\":2}," +
13511351
"\"url\":\"" + srcURL + "\"}]}," +
13521352
"\"id\":5}\n"));
13531353
tester.sendMessage("{\"id\":6,\"method\":\"Debugger.resume\"}");

truffle/src/com.oracle.truffle.api.debug.test/src/com/oracle/truffle/api/debug/test/ReenterStackFrameTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242

4343
import com.oracle.truffle.api.debug.DebugStackFrame;
4444
import com.oracle.truffle.api.debug.DebuggerSession;
45+
import com.oracle.truffle.api.debug.SuspendAnchor;
4546
import com.oracle.truffle.api.debug.SuspendedEvent;
4647
import java.util.Iterator;
4748
import org.graalvm.polyglot.Source;
@@ -88,6 +89,8 @@ public void testReenterCurrent() throws Throwable {
8889
expectSuspended((SuspendedEvent event) -> {
8990
DebugStackFrame currentFrame = event.getTopStackFrame();
9091
try {
92+
// Assert that we're before the CALL again after unwind
93+
Assert.assertEquals(SuspendAnchor.BEFORE, event.getSuspendAnchor());
9194
Assert.assertEquals("CALL(a)", currentFrame.getSourceSection().getCharacters());
9295
Iterator<DebugStackFrame> frames = event.getStackFrames().iterator();
9396
Assert.assertEquals("", frames.next().getName());

truffle/src/com.oracle.truffle.api.debug/src/com/oracle/truffle/api/debug/DebuggerSession.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1140,7 +1140,7 @@ private void notifyUnwindCallback(MaterializedFrame frame, InsertableNode insert
11401140
// Fake the caller context
11411141
Caller caller = findCurrentCaller(this, includeInternal);
11421142
SuspendedContext context = SuspendedContext.create(caller.node, ((SteppingStrategy.Unwind) s).unwind);
1143-
doSuspend(context, SuspendAnchor.AFTER, caller.frame, insertableNode, false, true);
1143+
doSuspend(context, SuspendAnchor.BEFORE, caller.frame, insertableNode, false, true);
11441144
}
11451145

11461146
static Caller findCurrentCaller(DebuggerSession session, boolean includeInternal) {

0 commit comments

Comments
 (0)