changeset 16962:f0c3de09f12a

Merge with e01b0b9a5f886f8810ba09668632acd675cccf76
author Michael Van De Vanter <michael.van.de.vanter@oracle.com>
date Tue, 26 Aug 2014 19:57:25 -0700
parents a1427e40deaf (diff) e01b0b9a5f88 (current diff)
children 80fb94b07db2
files graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrumentable.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLExpressionNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLStatementNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLExpressionWrapper.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLInstrumenter.java
diffstat 8 files changed, 86 insertions(+), 79 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrumentable.java	Tue Aug 26 18:22:31 2014 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrumentable.java	Tue Aug 26 19:57:25 2014 -0700
@@ -24,24 +24,20 @@
  */
 package com.oracle.truffle.api.instrument;
 
-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 <em>instrumentation</em> 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. This interfaces assumes that the instrumented node has access to
-     * the {@link ExecutionContext} for the guest language.
-     * <ul>
-     * <li>if no instrumentation is to be applied, returns the AST node unmodified;</li>
-     * <li>if an AST node is to be instrumented, then creates a new Wrapper that <em>decorates</em>
-     * the AST node. Additionally, this creates a probe on the wrapper that is to be used for
-     * attaching instruments. This {@link Probe} is notified of all {@link ExecutionEvents} at the
-     * wrapped AST node.</li>
-     * </ul>
+     * 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.
      *
      * @return The probe that was created.
      */
-    public Probe probe();
+    Probe probe();
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/LineLocationToProbeCollectionMap.java	Tue Aug 26 18:22:31 2014 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/LineLocationToProbeCollectionMap.java	Tue Aug 26 19:57:25 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<Probe> getProbesAtLine(LineLocation line) {
         Collection<Probe> 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<Probe> getProbesAtLineNumber(int lineNumber) {
-        ArrayList<Probe> probes = new ArrayList<>();
 
-        for (LineLocation line : lineToProbesMap.keySet()) {
+        final Set<LineLocation> keySet = lineToProbesMap.keySet();
+        if (keySet.size() == 0) {
+            return Collections.emptyList();
+        }
+
+        ArrayList<Probe> probes = new ArrayList<>();
+        for (LineLocation line : keySet) {
             if (line.getLineNumber() == lineNumber)
                 probes.addAll(lineToProbesMap.get(line));
         }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/LineLocationToSourceSectionCollectionMap.java	Tue Aug 26 18:22:31 2014 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/LineLocationToSourceSectionCollectionMap.java	Tue Aug 26 19:57:25 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<LineLocation, Collection<SourceSection>> 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<SourceSection> getSourceSectionsAtLine(LineLocation line) {
         Collection<SourceSection> 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<SourceSection> getSourceSectionsAtLineNumber(int lineNumber) {
-        ArrayList<SourceSection> sourceSections = new ArrayList<>();
 
-        for (LineLocation line : lineToSourceSectionsMap.keySet()) {
+        final Set<LineLocation> keySet = lineToSourceSectionsMap.keySet();
+        if (keySet.size() == 0) {
+            return Collections.emptyList();
+        }
+
+        final ArrayList<SourceSection> sourceSections = new ArrayList<>();
+        for (LineLocation line : keySet) {
             if (line.getLineNumber() == lineNumber)
                 sourceSections.addAll(lineToSourceSectionsMap.get(line));
         }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLExpressionNode.java	Tue Aug 26 18:22:31 2014 -0700
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLExpressionNode.java	Tue Aug 26 19:57:25 2014 -0700
@@ -94,15 +94,20 @@
     public Probe probe() {
         Node parent = getParent();
 
-        if (parent == null)
+        if (parent == null) {
             throw new IllegalStateException("Cannot probe a node without a parent");
+        }
 
-        if (parent instanceof SLExpressionWrapper)
+        if (parent instanceof SLExpressionWrapper) {
             return ((SLExpressionWrapper) parent).getProbe();
+        }
 
-        SLExpressionWrapper wrapper = new SLExpressionWrapper(getRootNodeSLContext(this), this);
+        // Create a new wrapper/probe with this node as its child.
+        final SLExpressionWrapper wrapper = new SLExpressionWrapper(getRootNodeSLContext(this), this);
+
+        // Replace this node in the AST with the wrapper
         this.replace(wrapper);
-        wrapper.insertChild();
+
         return wrapper.getProbe();
     }
 }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLStatementNode.java	Tue Aug 26 18:22:31 2014 -0700
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLStatementNode.java	Tue Aug 26 19:57:25 2014 -0700
@@ -92,12 +92,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();
+        }
 
-        SLStatementWrapper wrapper = new SLStatementWrapper(getRootNodeSLContext(this), this);
+        // Create a new wrapper/probe with this node as its child.
+        final SLStatementWrapper wrapper = new SLStatementWrapper(getRootNodeSLContext(this), this);
+
+        // Replace this node in the AST with the wrapper
         this.replace(wrapper);
-        wrapper.insertChild();
+
         return wrapper.getProbe();
     }
 
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLExpressionWrapper.java	Tue Aug 26 18:22:31 2014 -0700
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLExpressionWrapper.java	Tue Aug 26 19:57:25 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. <br/>
- * {@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;
 
@@ -154,10 +151,4 @@
         return SLTypesGen.SLTYPES.expectSLNull(executeGeneric(frame));
     }
 
-    /**
-     * Sets the parent pointer of this wrapper's child.
-     */
-    public void insertChild() {
-        insert(this.child);
-    }
 }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLInstrumenter.java	Tue Aug 26 18:22:31 2014 -0700
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLInstrumenter.java	Tue Aug 26 19:57:25 2014 -0700
@@ -31,10 +31,8 @@
 import com.oracle.truffle.sl.nodes.local.*;
 
 /**
- * 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 AST (presumed not yet executed) and
+ * instruments some of them.
  */
 public class SLInstrumenter implements NodeVisitor {
 
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLStatementWrapper.java	Tue Aug 26 18:22:31 2014 -0700
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLStatementWrapper.java	Tue Aug 26 19:57:25 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. <br/>
- * 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);
-    }
 }