Skip to content

Commit 1dbd97c

Browse files
committed
[GR-69227] Do not skip entries in line number table, and suspend only once per line during consecutive steps.
PullRequest: graal/22035
2 parents 63fb070 + e6e83e9 commit 1dbd97c

File tree

2 files changed

+36
-25
lines changed

2 files changed

+36
-25
lines changed

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

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,8 @@ private RootNode getRootNode(FrameInstance frameInstance) {
899899

900900
private class SuspendedCallbackImpl implements SuspendedCallback {
901901

902+
private final ThreadLocal<SuspendedLine> lastSuspendedLine = new ThreadLocal<>();
903+
902904
@Override
903905
public void onSuspend(SuspendedEvent event) {
904906
Thread hostThread = Thread.currentThread();
@@ -914,6 +916,7 @@ public void onSuspend(SuspendedEvent event) {
914916
Object currentThread = getContext().asGuestThread(hostThread);
915917
fine(() -> "Suspended at: " + event.getSourceSection() + " in thread: " + getThreadName(currentThread));
916918

919+
SuspendedLine suspendedLine = null;
917920
SteppingInfo steppingInfo = commandRequestIds.remove(currentThread);
918921
if (steppingInfo != null) {
919922
if (steppingInfo.isForceEarlyReturn()) {
@@ -927,10 +930,12 @@ public void onSuspend(SuspendedEvent event) {
927930
if (callFrames.length > 0) {
928931
callFrame = callFrames[0];
929932
}
933+
suspendedLine = getSuspendedLine(callFrame);
930934
EventInfo eventInfo = callFrame != null ? new EventInfo.Frame(context, callFrame, currentThread) : null;
931-
if (checkExclusionFilters(steppingInfo, event, eventInfo)) {
935+
if (isOnPreviousLine(suspendedLine) || checkExclusionFilters(steppingInfo, eventInfo)) {
932936
fine(() -> "not suspending here: " + event.getSourceSection());
933937
// continue stepping until completed
938+
continueStepping(event, steppingInfo);
934939
RequestFilter requestFilter = eventFilters.getRequestFilter(steppingInfo.getRequestId());
935940
if (requestFilter != null && requestFilter.isActive()) {
936941
commandRequestIds.put(currentThread, steppingInfo);
@@ -975,10 +980,35 @@ public void onSuspend(SuspendedEvent event) {
975980
if (result.skipSuspend) {
976981
return;
977982
}
983+
if (suspendedLine == null && callFrames.length > 0) {
984+
suspendedLine = getSuspendedLine(callFrames[0]);
985+
}
986+
lastSuspendedLine.set(suspendedLine);
978987
// now, suspend the current thread until resumed by e.g. a debugger command
979988
suspend(currentThread, result.suspendPolicy, jobs, result.breakpointHit || event.isStep() || event.isUnwind());
980989
}
981990

991+
private static SuspendedLine getSuspendedLine(CallFrame callFrame) {
992+
if (callFrame == null) {
993+
return null;
994+
}
995+
long bci = callFrame.getCodeIndex();
996+
int line = callFrame.getMethod().bciToLineNumber((int) bci);
997+
if (line >= 0) {
998+
return new SuspendedLine(callFrame.getMethodId(), line);
999+
} else {
1000+
return null;
1001+
}
1002+
}
1003+
1004+
private boolean isOnPreviousLine(SuspendedLine currentLine) {
1005+
if (currentLine != null) {
1006+
return currentLine.equals(lastSuspendedLine.get());
1007+
} else {
1008+
return false;
1009+
}
1010+
}
1011+
9821012
private BreakpointHitResult checkForBreakpoints(SuspendedEvent event, List<Callable<Void>> jobs, SuspendedInfo suspendedInfo, Object currentThread, CallFrame[] callFrames) {
9831013
boolean handledLineBreakpoint = false;
9841014
boolean hit = false;
@@ -1086,10 +1116,9 @@ private BreakpointHitResult checkForBreakpoints(SuspendedEvent event, List<Calla
10861116
return new BreakpointHitResult(hit, suspendPolicy, false);
10871117
}
10881118

1089-
private boolean checkExclusionFilters(SteppingInfo info, SuspendedEvent event, EventInfo eventInfo) {
1119+
private boolean checkExclusionFilters(SteppingInfo info, EventInfo eventInfo) {
10901120
if (info != null) {
10911121
if (isSingleSteppingSuspended()) {
1092-
continueStepping(event, info);
10931122
return true;
10941123
}
10951124
if (eventInfo == null) {
@@ -1101,7 +1130,6 @@ private boolean checkExclusionFilters(SteppingInfo info, SuspendedEvent event, E
11011130
// we're currently stepping, so check if suspension point
11021131
// matches any exclusion filters
11031132
if (!requestFilter.isHit(eventInfo)) {
1104-
continueStepping(event, info);
11051133
return true;
11061134
}
11071135
}
@@ -1190,6 +1218,9 @@ private static final class BreakpointHitResult {
11901218
this.skipSuspend = skipSuspend;
11911219
}
11921220
}
1221+
1222+
private static record SuspendedLine(long methodId, int line) {
1223+
}
11931224
}
11941225

11951226
private boolean isSingleSteppingSuspended() {

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2941,32 +2941,12 @@ private static boolean assertionsEnabled() {
29412941

29422942
if (table != LineNumberTableAttribute.EMPTY) {
29432943
List<LineNumberTableAttribute.Entry> entries = table.getEntries();
2944-
// don't allow multiple entries with same line, keep only the first one
2945-
// reduce the checks needed heavily by keeping track of max seen line number
2946-
int[] seenLines = new int[entries.size()];
2947-
Arrays.fill(seenLines, -1);
2948-
int maxSeenLine = -1;
2949-
29502944
EspressoStatementNode[] statements = new EspressoStatementNode[entries.size()];
29512945
MapperBCI mapper = new MapperBCI(table);
29522946
for (int i = 0; i < entries.size(); i++) {
29532947
LineNumberTableAttribute.Entry entry = entries.get(i);
29542948
int lineNumber = entry.getLineNumber();
2955-
boolean seen = false;
2956-
boolean checkSeen = !(maxSeenLine < lineNumber);
2957-
if (checkSeen) {
2958-
for (int seenLine : seenLines) {
2959-
if (seenLine == lineNumber) {
2960-
seen = true;
2961-
break;
2962-
}
2963-
}
2964-
}
2965-
if (!seen) {
2966-
statements[mapper.initIndex(i, entry.getBCI())] = new EspressoStatementNode(method.getMethod().getSource().createSection(lineNumber));
2967-
seenLines[i] = lineNumber;
2968-
maxSeenLine = Math.max(maxSeenLine, lineNumber);
2969-
}
2949+
statements[mapper.initIndex(i, entry.getBCI())] = new EspressoStatementNode(method.getMethod().getSource().createSection(lineNumber));
29702950
}
29712951
this.hookBCIToNodeIndex = mapper;
29722952
this.statementNodes = statements;

0 commit comments

Comments
 (0)