Skip to content

Commit 7689d6f

Browse files
committed
Added support to step until next node with given tag
Signed-off-by: Stefan Marr <git@stefan-marr.de>
1 parent d448d9c commit 7689d6f

File tree

4 files changed

+128
-10
lines changed

4 files changed

+128
-10
lines changed

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
import com.oracle.truffle.api.instrumentation.SourceSectionFilter.Builder;
6767
import com.oracle.truffle.api.instrumentation.StandardTags.CallTag;
6868
import com.oracle.truffle.api.instrumentation.StandardTags.RootTag;
69+
import com.oracle.truffle.api.instrumentation.Tag;
6970
import com.oracle.truffle.api.nodes.ExecutableNode;
7071
import com.oracle.truffle.api.nodes.LanguageInfo;
7172
import com.oracle.truffle.api.nodes.Node;
@@ -416,6 +417,17 @@ synchronized void resume(Thread t) {
416417
setSteppingStrategy(t, SteppingStrategy.createContinue(), true);
417418
}
418419

420+
/**
421+
* Prepare interpreter to step to the next source section with the given tag.
422+
*
423+
* @since smarr/debugger
424+
*/
425+
public void prepareStepUntilNext(Class<? extends Tag> tag, SuspendAnchor anchor, Thread thread) {
426+
StepConfig stepConfig = StepConfig.newBuilder().tag(tag, anchor).build();
427+
SteppingStrategy strat = SteppingStrategy.createStepNext(this, stepConfig);
428+
setSteppingStrategy(thread, strat, true);
429+
}
430+
419431
private synchronized void setSteppingStrategy(Thread thread, SteppingStrategy strategy, boolean updateStepping) {
420432
if (closed) {
421433
return;

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

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import java.util.Set;
3131

3232
import com.oracle.truffle.api.instrumentation.EventContext;
33+
import com.oracle.truffle.api.instrumentation.Tag;
3334

3435
/**
3536
* Represents a debugger step configuration. A debugger step is defined by it's depth and a set of
@@ -52,14 +53,19 @@
5253
*/
5354
public final class StepConfig {
5455

55-
private static final StepConfig EMPTY = new StepConfig(null, 0);
56+
private static final StepConfig EMPTY = new StepConfig(null, 0, null, null);
5657

5758
private final Set<SourceElement> sourceElements;
5859
private final int stepCount;
5960

60-
StepConfig(Set<SourceElement> sourceElements, int count) {
61+
private final Class<? extends Tag> tag;
62+
private final SuspendAnchor tagAnchor;
63+
64+
StepConfig(Set<SourceElement> sourceElements, int count, Class<? extends Tag> tag, SuspendAnchor tagAnchor) {
6165
this.sourceElements = sourceElements;
6266
this.stepCount = count;
67+
this.tag = tag;
68+
this.tagAnchor = tagAnchor;
6369
}
6470

6571
/**
@@ -104,9 +110,20 @@ boolean matches(DebuggerSession session, EventContext context, SuspendAnchor anc
104110
return true;
105111
}
106112
}
113+
if (tag != null) {
114+
return context.hasTag(tag) && this.tagAnchor == anchor;
115+
}
107116
return false;
108117
}
109118

119+
Class<? extends Tag> getTag() {
120+
return tag;
121+
}
122+
123+
SuspendAnchor getTagAnchor() {
124+
return tagAnchor;
125+
}
126+
110127
boolean containsSourceElement(DebuggerSession session, SourceElement sourceElement) {
111128
Set<SourceElement> elements = sourceElements;
112129
if (elements == null) {
@@ -134,6 +151,9 @@ public final class Builder {
134151
private Set<SourceElement> stepElements;
135152
private int stepCount = -1;
136153

154+
private Class<? extends Tag> tag;
155+
private SuspendAnchor tagAnchor;
156+
137157
private Builder() {
138158
}
139159

@@ -162,6 +182,23 @@ public Builder sourceElements(SourceElement... elements) {
162182
return this;
163183
}
164184

185+
/**
186+
* Set a tag to filter the applicable source sections.
187+
*
188+
* @since smarr/debugger
189+
*/
190+
public Builder tag(@SuppressWarnings("hiding") Class<? extends Tag> tag, @SuppressWarnings("hiding") SuspendAnchor tagAnchor) {
191+
if (this.tag != null && this.tagAnchor != null) {
192+
throw new IllegalStateException("Tag and anchor can only be set once per the builder.");
193+
}
194+
if (tag == null && tagAnchor == null) {
195+
throw new IllegalArgumentException("Tag and anchor cannot be null");
196+
}
197+
this.tag = tag;
198+
this.tagAnchor = tagAnchor;
199+
return this;
200+
}
201+
165202
/**
166203
* Provide the step count. It specifies the number of times the step repeats itself before
167204
* it suspends the execution. Can only be invoked once per builder.
@@ -189,7 +226,7 @@ public StepConfig build() {
189226
if (stepCount < 0) {
190227
stepCount = 1;
191228
}
192-
return new StepConfig(stepElements, stepCount);
229+
return new StepConfig(stepElements, stepCount, tag, tagAnchor);
193230
}
194231
}
195232
}

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

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
import com.oracle.truffle.api.instrumentation.EventContext;
2828
import com.oracle.truffle.api.instrumentation.ProbeNode;
29+
import com.oracle.truffle.api.nodes.Node;
2930

3031
/**
3132
* Implementation of a strategy for a debugger <em>action</em> that allows execution to continue
@@ -147,6 +148,10 @@ static SteppingStrategy createStepOver(DebuggerSession session, StepConfig confi
147148
return new StepOver(session, config);
148149
}
149150

151+
static SteppingStrategy createStepNext(DebuggerSession session, StepConfig config) {
152+
return new StepNext(session, config);
153+
}
154+
150155
static SteppingStrategy createUnwind(int depth) {
151156
return new Unwind(depth);
152157
}
@@ -512,6 +517,56 @@ public String toString() {
512517

513518
}
514519

520+
private static final class StepNext extends SteppingStrategy {
521+
private final DebuggerSession session;
522+
private final StepConfig stepConfig;
523+
524+
private int stackCounter;
525+
private boolean activeFrame;
526+
private Node targetNode;
527+
528+
StepNext(DebuggerSession session, StepConfig stepConfig) {
529+
this.session = session;
530+
this.stepConfig = stepConfig;
531+
}
532+
533+
@Override
534+
void notifyCallEntry() {
535+
stackCounter += 1;
536+
activeFrame = stackCounter == 0;
537+
}
538+
539+
@Override
540+
void notifyCallExit() {
541+
stackCounter -= 1;
542+
if (stackCounter == 0) {
543+
activeFrame = true;
544+
}
545+
}
546+
547+
@Override
548+
void notifyNodeEntry(EventContext context) {
549+
if (targetNode == null && context.hasTag(stepConfig.getTag())) {
550+
// record the target node
551+
targetNode = context.getInstrumentedNode();
552+
553+
// adjust the stackCounter to reflect that this is where we want to be
554+
stackCounter = 0;
555+
activeFrame = true;
556+
}
557+
}
558+
559+
@Override
560+
boolean isActive(EventContext context, SuspendAnchor suspendAnchor) {
561+
return activeFrame && targetNode == context.getInstrumentedNode() && stepConfig.matches(session, context, suspendAnchor);
562+
}
563+
564+
@Override
565+
boolean step(DebuggerSession steppingSession, EventContext context, SuspendAnchor suspendAnchor) {
566+
return isActive(context, suspendAnchor);
567+
}
568+
}
569+
515570
static final class Unwind extends SteppingStrategy {
516571

517572
private final int depth; // Negative depth

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

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import com.oracle.truffle.api.frame.FrameInstanceVisitor;
4141
import com.oracle.truffle.api.frame.MaterializedFrame;
4242
import com.oracle.truffle.api.instrumentation.Instrumenter;
43+
import com.oracle.truffle.api.instrumentation.Tag;
4344
import com.oracle.truffle.api.nodes.Node;
4445
import com.oracle.truffle.api.nodes.RootNode;
4546
import com.oracle.truffle.api.source.SourceSection;
@@ -216,13 +217,6 @@ InsertableNode getInsertableNode() {
216217
return insertableNode;
217218
}
218219

219-
/**
220-
* @since smarr/debugger
221-
*/
222-
public SteppingLocation getLocation() {
223-
return location;
224-
}
225-
226220
/**
227221
* SM: Reintroduce getNode(). Removed from Truffle 0.25
228222
*
@@ -590,6 +584,26 @@ public SuspendedEvent prepareStepOver(StepConfig stepConfig) {
590584
return this;
591585
}
592586

587+
/**
588+
* Step until the next element with the give tag.
589+
*
590+
* @since smarr/debugger
591+
*/
592+
public SuspendedEvent prepareStepUntilNext(Class<? extends Tag> tag, SuspendAnchor anchor) {
593+
return prepareStepUntilNext(StepConfig.newBuilder().tag(tag, anchor).build());
594+
}
595+
596+
/**
597+
* Step next with the given stepConfig.
598+
*
599+
* @since smarr/debugger
600+
*/
601+
public SuspendedEvent prepareStepUntilNext(StepConfig stepConfig) {
602+
verifyConfig(stepConfig);
603+
setNextStrategy(SteppingStrategy.createStepNext(session, stepConfig));
604+
return this;
605+
}
606+
593607
private void verifyConfig(StepConfig stepConfig) {
594608
Set<SourceElement> sessionElements = session.getSourceElements();
595609
if (sessionElements.isEmpty()) {

0 commit comments

Comments
 (0)