@@ -899,6 +899,8 @@ private RootNode getRootNode(FrameInstance frameInstance) {
899
899
900
900
private class SuspendedCallbackImpl implements SuspendedCallback {
901
901
902
+ private final ThreadLocal <SuspendedLine > lastSuspendedLine = new ThreadLocal <>();
903
+
902
904
@ Override
903
905
public void onSuspend (SuspendedEvent event ) {
904
906
Thread hostThread = Thread .currentThread ();
@@ -914,6 +916,7 @@ public void onSuspend(SuspendedEvent event) {
914
916
Object currentThread = getContext ().asGuestThread (hostThread );
915
917
fine (() -> "Suspended at: " + event .getSourceSection () + " in thread: " + getThreadName (currentThread ));
916
918
919
+ SuspendedLine suspendedLine = null ;
917
920
SteppingInfo steppingInfo = commandRequestIds .remove (currentThread );
918
921
if (steppingInfo != null ) {
919
922
if (steppingInfo .isForceEarlyReturn ()) {
@@ -927,10 +930,12 @@ public void onSuspend(SuspendedEvent event) {
927
930
if (callFrames .length > 0 ) {
928
931
callFrame = callFrames [0 ];
929
932
}
933
+ suspendedLine = getSuspendedLine (callFrame );
930
934
EventInfo eventInfo = callFrame != null ? new EventInfo .Frame (context , callFrame , currentThread ) : null ;
931
- if (checkExclusionFilters (steppingInfo , event , eventInfo )) {
935
+ if (isOnPreviousLine ( suspendedLine ) || checkExclusionFilters (steppingInfo , eventInfo )) {
932
936
fine (() -> "not suspending here: " + event .getSourceSection ());
933
937
// continue stepping until completed
938
+ continueStepping (event , steppingInfo );
934
939
RequestFilter requestFilter = eventFilters .getRequestFilter (steppingInfo .getRequestId ());
935
940
if (requestFilter != null && requestFilter .isActive ()) {
936
941
commandRequestIds .put (currentThread , steppingInfo );
@@ -975,10 +980,35 @@ public void onSuspend(SuspendedEvent event) {
975
980
if (result .skipSuspend ) {
976
981
return ;
977
982
}
983
+ if (suspendedLine == null && callFrames .length > 0 ) {
984
+ suspendedLine = getSuspendedLine (callFrames [0 ]);
985
+ }
986
+ lastSuspendedLine .set (suspendedLine );
978
987
// now, suspend the current thread until resumed by e.g. a debugger command
979
988
suspend (currentThread , result .suspendPolicy , jobs , result .breakpointHit || event .isStep () || event .isUnwind ());
980
989
}
981
990
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
+
982
1012
private BreakpointHitResult checkForBreakpoints (SuspendedEvent event , List <Callable <Void >> jobs , SuspendedInfo suspendedInfo , Object currentThread , CallFrame [] callFrames ) {
983
1013
boolean handledLineBreakpoint = false ;
984
1014
boolean hit = false ;
@@ -1086,10 +1116,9 @@ private BreakpointHitResult checkForBreakpoints(SuspendedEvent event, List<Calla
1086
1116
return new BreakpointHitResult (hit , suspendPolicy , false );
1087
1117
}
1088
1118
1089
- private boolean checkExclusionFilters (SteppingInfo info , SuspendedEvent event , EventInfo eventInfo ) {
1119
+ private boolean checkExclusionFilters (SteppingInfo info , EventInfo eventInfo ) {
1090
1120
if (info != null ) {
1091
1121
if (isSingleSteppingSuspended ()) {
1092
- continueStepping (event , info );
1093
1122
return true ;
1094
1123
}
1095
1124
if (eventInfo == null ) {
@@ -1101,7 +1130,6 @@ private boolean checkExclusionFilters(SteppingInfo info, SuspendedEvent event, E
1101
1130
// we're currently stepping, so check if suspension point
1102
1131
// matches any exclusion filters
1103
1132
if (!requestFilter .isHit (eventInfo )) {
1104
- continueStepping (event , info );
1105
1133
return true ;
1106
1134
}
1107
1135
}
@@ -1190,6 +1218,9 @@ private static final class BreakpointHitResult {
1190
1218
this .skipSuspend = skipSuspend ;
1191
1219
}
1192
1220
}
1221
+
1222
+ private static record SuspendedLine (long methodId , int line ) {
1223
+ }
1193
1224
}
1194
1225
1195
1226
private boolean isSingleSteppingSuspended () {
0 commit comments