# HG changeset patch # User Michael Van De Vanter # Date 1409086493 25200 # Node ID a1427e40deaf2f065336948f1a910dabf32ed843 # Parent 7ef0a23555402c71734ccee51efa300dc145333f Truffle/Instrumentation: some Javadoc revistions; minor code cleanups; remove one redundant operation; add tracing to the LineLocation maps. diff -r 7ef0a2355540 -r a1427e40deaf graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrumentable.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrumentable.java Tue Aug 26 09:35:08 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrumentable.java Tue Aug 26 13:54:53 2014 -0700 @@ -26,23 +26,22 @@ import com.oracle.truffle.api.*; +/** + * Any Truffle node implementing this interface can be "instrumented" by installing a {@link Probe} + * that intercepts {@link ExecutionEvents} at the node and routes them to any {@link Instrument}s + * that have been attached to the {@link Probe}. Only one {@link Probe} may be installed at each + * node; subsequent calls return the one already installed. + */ public interface Instrumentable { /** - * Optionally applies instrumentation at a Truffle AST node, depending on guest - * language characteristics and use-case policy. Ideally, the parent node of the guest language - * implements this interface. - * + * Enables "instrumentation" of this Truffle node by tools, where this node is presumed to be + * part (and not the root of) of a well-formed Truffle AST that is not being executed. The AST + * may be modified. * - * @param context The {@link ExecutionContext} of the guest language used to create probes on - * the wrapper. - * @return The probe that was created. + * @param context access to language implementation context + * @return a {@link Probe} to which tools may attach {@link Instrument}s that will receive + * {@link ExecutionEvents} */ public Probe probe(ExecutionContext context); } diff -r 7ef0a2355540 -r a1427e40deaf graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/LineLocationToProbeCollectionMap.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/LineLocationToProbeCollectionMap.java Tue Aug 26 09:35:08 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/LineLocationToProbeCollectionMap.java Tue Aug 26 13:54:53 2014 -0700 @@ -24,6 +24,7 @@ */ package com.oracle.truffle.api.instrument.impl; +import java.io.*; import java.util.*; import com.oracle.truffle.api.instrument.*; @@ -35,6 +36,9 @@ */ public class LineLocationToProbeCollectionMap implements ProbeListener { + private static final boolean TRACE = false; + private static final PrintStream OUT = System.out; + /** * Map: Source line ==> probes associated with source sections starting on the line. */ @@ -44,8 +48,13 @@ } public void newProbeInserted(SourceSection source, Probe probe) { - if (source != null && !(source instanceof NullSourceSection)) - this.addProbeToLine(source.getLineLocation(), probe); + if (source != null && !(source instanceof NullSourceSection)) { + final LineLocation lineLocation = source.getLineLocation(); + if (TRACE) { + OUT.println("LineLocationToProbeCollectionMap: adding " + lineLocation + " Probe=" + probe); + } + this.addProbeToLine(lineLocation, probe); + } } public void probeTaggedAs(Probe probe, SyntaxTag tag) { @@ -98,9 +107,9 @@ } /** - * + * * Returns a collection of {@link Probe}s whose associated source begins at the given - * {@link LineLocation}. If there are no probes at that line, an empty list is returned. + * {@link LineLocation}, an empty list if none. * * @param line The line to check. * @return A collection of probes at the given line. @@ -108,24 +117,28 @@ public Collection getProbesAtLine(LineLocation line) { Collection probeList = lineToProbesMap.get(line); - if (probeList == null) - probeList = new ArrayList<>(1); - + if (probeList == null) { + return Collections.emptyList(); + } return probeList; } /** * Convenience method to get probes according to a int line number. Returns a collection of - * {@link Probe}s at the given line number. If there are no probes at that line, a new empty - * list is returned. + * {@link Probe}s at the given line number, an empty list if none. * * @param lineNumber The line number to check. - * @return A iterable collection of probes at the given line. + * @return A collection of probes at the given line. */ public Collection getProbesAtLineNumber(int lineNumber) { - ArrayList probes = new ArrayList<>(); - for (LineLocation line : lineToProbesMap.keySet()) { + final Set keySet = lineToProbesMap.keySet(); + if (keySet.size() == 0) { + return Collections.emptyList(); + } + + ArrayList probes = new ArrayList<>(); + for (LineLocation line : keySet) { if (line.getLineNumber() == lineNumber) probes.addAll(lineToProbesMap.get(line)); } diff -r 7ef0a2355540 -r a1427e40deaf graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/LineLocationToSourceSectionCollectionMap.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/LineLocationToSourceSectionCollectionMap.java Tue Aug 26 09:35:08 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/LineLocationToSourceSectionCollectionMap.java Tue Aug 26 13:54:53 2014 -0700 @@ -24,6 +24,7 @@ */ package com.oracle.truffle.api.instrument.impl; +import java.io.*; import java.util.*; import com.oracle.truffle.api.instrument.*; @@ -37,18 +38,24 @@ */ public class LineLocationToSourceSectionCollectionMap implements ProbeListener { + private static final boolean TRACE = false; + private static final PrintStream OUT = System.out; + /** * Map: Source line ==> source sections that exist on the line. */ private final Map> lineToSourceSectionsMap = new HashMap<>(); public LineLocationToSourceSectionCollectionMap() { - } public void newProbeInserted(SourceSection sourceSection, Probe probe) { if (sourceSection != null && !(sourceSection instanceof NullSourceSection)) { - this.addSourceSectionToLine(sourceSection.getLineLocation(), sourceSection); + final LineLocation lineLocation = sourceSection.getLineLocation(); + if (TRACE) { + OUT.println("LineLocationToSourceSectionCollectionMap: adding " + lineLocation + " Probe=" + probe); + } + this.addSourceSectionToLine(lineLocation, sourceSection); } } @@ -82,33 +89,38 @@ } /** - * Returns a collection of {@link SourceSection}s at the given {@link LineLocation}. If there - * are no source sections at that line, a new empty list of size 1 is returned. + * Returns a collection of {@link SourceSection}s at the given {@link LineLocation}, an empty + * list if none. * * @param line The line to check. - * @return A iterable collection of source sections at the given line. + * @return the source sections at the given line. */ public Collection getSourceSectionsAtLine(LineLocation line) { Collection sourceSectionList = lineToSourceSectionsMap.get(line); - if (sourceSectionList == null) - sourceSectionList = new ArrayList<>(1); - + if (sourceSectionList == null) { + return Collections.emptyList(); + } return sourceSectionList; } /** * Convenience method to get source sections according to a int line number. Returns a * collection of {@link SourceSection}s at the given line number. If there are no source - * sections at that line, a new empty list is returned. + * sections at that line, an empty list is returned. * * @param lineNumber The line number to check. - * @return A iterable collection of source sections at the given line. + * @return A collection of source sections at the given line. */ public Collection getSourceSectionsAtLineNumber(int lineNumber) { - ArrayList sourceSections = new ArrayList<>(); - for (LineLocation line : lineToSourceSectionsMap.keySet()) { + final Set keySet = lineToSourceSectionsMap.keySet(); + if (keySet.size() == 0) { + return Collections.emptyList(); + } + + final ArrayList sourceSections = new ArrayList<>(); + for (LineLocation line : keySet) { if (line.getLineNumber() == lineNumber) sourceSections.addAll(lineToSourceSectionsMap.get(line)); } diff -r 7ef0a2355540 -r a1427e40deaf graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLStatementNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLStatementNode.java Tue Aug 26 09:35:08 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLStatementNode.java Tue Aug 26 13:54:53 2014 -0700 @@ -93,12 +93,16 @@ if (parent == null) throw new IllegalStateException("Cannot probe a node without a parent"); - if (parent instanceof SLStatementWrapper) + if (parent instanceof SLStatementWrapper) { return ((SLStatementWrapper) parent).getProbe(); + } + // Create a new wrapper/probe with this node as its child. SLStatementWrapper wrapper = new SLStatementWrapper((SLContext) context, this); + + // Replace this node in the AST with the wrapper this.replace(wrapper); - wrapper.insertChild(); + return wrapper.getProbe(); } } diff -r 7ef0a2355540 -r a1427e40deaf graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLExpressionWrapper.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLExpressionWrapper.java Tue Aug 26 09:35:08 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLExpressionWrapper.java Tue Aug 26 13:54:53 2014 -0700 @@ -32,15 +32,12 @@ import com.oracle.truffle.sl.runtime.*; /** - * SLExpressionWrapper is a Truffle AST node that gets inserted as the parent to the node that it is - * wrapping. Any debugging instruments are attached to this wrapper through {@link Probe}s (which - * themselves contain the instruments. It is through this mechanism that tools can interact directly - * with the AST.
- * {@link SLExpressionWrapper} specifically wraps {@link SLExpressionNode}s and overrides the - * various execute functions in {@link SLExpressionNode} to operate on the child of the wrapper - * instead of the wrapper itself. - * + * A Truffle node that can be inserted into a Simple AST (assumed not to have executed yet) to + * enable "instrumentation" of an {@link SLExpressionNode}. Tools wishing to interact with AST + * execution may attach {@link Instrument}s to the {@link Probe} uniquely associated with the + * wrapper, and to which this wrapper routes {@link ExecutionEvents}. */ + public final class SLExpressionWrapper extends SLExpressionNode implements Wrapper { @Child private SLExpressionNode child; diff -r 7ef0a2355540 -r a1427e40deaf graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLInstrumenter.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLInstrumenter.java Tue Aug 26 09:35:08 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLInstrumenter.java Tue Aug 26 13:54:53 2014 -0700 @@ -32,10 +32,8 @@ import com.oracle.truffle.sl.runtime.*; /** - * This is a general purpose visitor which traverses a completely parsed Simple AST and instruments - * all the nodes within it. This visitor is designed to visit the tree immediately after it has been - * parsed. - * + * A visitor which traverses a completely parsed Simple (not yet executed) AST and instruments some + * of them. */ public class SLInstrumenter implements NodeVisitor { diff -r 7ef0a2355540 -r a1427e40deaf graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLStatementWrapper.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLStatementWrapper.java Tue Aug 26 09:35:08 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLStatementWrapper.java Tue Aug 26 13:54:53 2014 -0700 @@ -30,14 +30,10 @@ import com.oracle.truffle.sl.runtime.*; /** - * SLStatmentWrapper is a Truffle AST node that gets inserted as the parent to the node that it is - * wrapping. Any debugging instruments are attached to this wrapper through {@link Probe}s (which - * themselves contain the instruments). It is through this mechanism that tools can interact - * directly with the AST.
- * SLStatmentWrapper specifically wraps {@link SLStatementWrapper}s and overrides the executeVoid - * function of {@link SLStatementNode} to operate on the child of the wrapper instead of the wrapper - * itself. - * + * A Truffle node that can be inserted into a Simple AST (assumed not to have executed yet) to + * enable "instrumentation" of a {@link SLStatementNode}. Tools wishing to interact with AST + * execution may attach {@link Instrument}s to the {@link Probe} uniquely associated with the + * wrapper, and to which this wrapper routes {@link ExecutionEvents}. */ public final class SLStatementWrapper extends SLStatementNode implements Wrapper { @@ -50,8 +46,6 @@ assert !(child instanceof SLStatementWrapper); this.probe = context.createProbe(child.getSourceSection()); this.child = child; - // The child should only be inserted after a replace, so we defer inserting the child to the - // creator of the wrapper. } @Override @@ -98,10 +92,4 @@ } } - /** - * Sets the parent pointer of this wrapper's child. - */ - public void insertChild() { - insert(this.child); - } }