diff graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java @ 21181:78a4b44420cf

Truffle/Instrumentation: rename the "SplicedNode" Instrument kind to the "ToolEval" instrument kind, along with some redesign based on earlier feedback.
author Michael Van De Vanter <michael.van.de.vanter@oracle.com>
date Sun, 03 May 2015 21:59:55 -0700
parents f96165ecb6f1
children 07c22c0ab91e
line wrap: on
line diff
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java	Sat May 02 14:40:49 2015 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java	Sun May 03 21:59:55 2015 -0700
@@ -103,10 +103,11 @@
 public abstract class Instrument {
 
     /**
-     * Creates an instrument that will route execution events to a listener.
+     * Creates a <em>Simple Instrument</em>: this Instrument routes execution events to a
+     * client-provided listener.
      *
-     * @param listener a minimal listener for event generated by the instrument.
-     * @param instrumentInfo optional description of the instrument's role, useful for debugging.
+     * @param listener a listener for execution events
+     * @param instrumentInfo optional description of the instrument's role, intended for debugging.
      * @return a new instrument, ready for attachment at a probe
      */
     public static Instrument create(SimpleInstrumentListener listener, String instrumentInfo) {
@@ -114,12 +115,11 @@
     }
 
     /**
-     * Creates an instrument that will route execution events to a listener, along with access to
-     * internal execution state.
+     * Creates a <em>Standard Instrument</em>: this Instrument routes execution events, together
+     * with access to Truffle execution state, to a client-provided listener.
      *
-     * @param standardListener a listener for event generated by the instrument that provides access
-     *            to internal execution state
-     * @param instrumentInfo optional description of the instrument's role, useful for debugging.
+     * @param standardListener a listener for execution events and execution state
+     * @param instrumentInfo optional description of the instrument's role, intended for debugging.
      * @return a new instrument, ready for attachment at a probe
      */
     public static Instrument create(StandardInstrumentListener standardListener, String instrumentInfo) {
@@ -127,17 +127,16 @@
     }
 
     /**
-     * Creates an instrument that, when executed the first time in any particular AST location,
-     * invites the tool to provide an AST fragment for <em>splicing</em> directly into the running
-     * AST.
+     * Creates a <em>Tool Eval Instrument</em>: this Instrument executes efficiently, subject to
+     * full Truffle optimization, a client-provided AST fragment every time the Probed node is
+     * entered.
      *
-     * @param spliceListener a callback to the client that requests an AST node to be splice.
-     * @param instrumentInfo instrumentInfo optional description of the instrument's role, useful
-     *            for debugging.
-     * @return a new instrument, ready for attachment at a probe.
+     * @param toolEvalNodeFactory provider of AST fragments on behalf of the client
+     * @param instrumentInfo optional description of the instrument's role, intended for debugging.
+     * @return a new instrument, ready for attachment at a probe
      */
-    public static Instrument create(SpliceInstrumentListener spliceListener, String instrumentInfo) {
-        return new SpliceInstrument(spliceListener, instrumentInfo);
+    public static Instrument create(ToolEvalNodeFactory toolEvalNodeFactory, String instrumentInfo) {
+        return new ToolEvalInstrument(toolEvalNodeFactory, instrumentInfo);
     }
 
     // TODO (mlvdv) experimental
@@ -165,7 +164,16 @@
     }
 
     /**
-     * Removes this instrument from the probe to which it attached and renders the instrument inert.
+     * Gets the {@link Probe} to which this Instrument is currently attached: {@code null} if not
+     * yet attached to a Probe or if this Instrument has been {@linkplain #dispose() disposed}.
+     */
+    public Probe getProbe() {
+        return probe;
+    }
+
+    /**
+     * Removes this Instrument from the Probe to which it attached and renders this Instrument
+     * inert.
      *
      * @throws IllegalStateException if this instrument has already been disposed
      */
@@ -176,14 +184,14 @@
         if (probe != null) {
             // It's attached
             probe.disposeInstrument(this);
+            probe = null;
         }
         this.isDisposed = true;
     }
 
-    Probe getProbe() {
-        return probe;
-    }
-
+    /**
+     * For internal implementation only.
+     */
     void setAttachedTo(Probe probe) {
         this.probe = probe;
     }
@@ -239,6 +247,9 @@
             return instrumentNode;
         }
 
+        /**
+         * Node that implements a {@link SimpleInstrument} in a particular AST.
+         */
         @NodeInfo(cost = NodeCost.NONE)
         private final class SimpleInstrumentNode extends AbstractInstrumentNode {
 
@@ -318,6 +329,9 @@
             return instrumentNode;
         }
 
+        /**
+         * Node that implements a {@link StandardInstrument} in a particular AST.
+         */
         @NodeInfo(cost = NodeCost.NONE)
         private final class StandardInstrumentNode extends AbstractInstrumentNode {
 
@@ -360,26 +374,27 @@
         }
     }
 
-    // TODO (mlvdv) EXPERIMENTAL- UNDER DEVELOPMENT
     /**
-     * An instrument that allows clients to "splice" an AST fragment directly into a Probe's
-     * <em>instrumentation chain</em>, and thus directly into the executing Truffle AST.
+     * An instrument that allows clients to provide an AST fragment to be executed directly from
+     * within a Probe's <em>instrumentation chain</em>, and thus directly in the executing Truffle
+     * AST with potential for full optimization.
      */
-    private static final class SpliceInstrument extends Instrument {
+    private static final class ToolEvalInstrument extends Instrument {
 
         /**
-         * Tool-supplied listener for AST events.
+         * Client-provided supplier of new node instances to attach.
          */
-        private final SpliceInstrumentListener spliceListener;
+        private final ToolEvalNodeFactory toolEvalNodeFactory;
 
-        private SpliceInstrument(SpliceInstrumentListener spliceListener, String instrumentInfo) {
+        private ToolEvalInstrument(ToolEvalNodeFactory toolEvalNodeFactory, String instrumentInfo) {
             super(instrumentInfo);
-            this.spliceListener = spliceListener;
+            this.toolEvalNodeFactory = toolEvalNodeFactory;
+
         }
 
         @Override
         AbstractInstrumentNode addToChain(AbstractInstrumentNode nextNode) {
-            return new SpliceInstrumentNode(nextNode);
+            return new ToolEvalNodeInstrumentNode(nextNode);
         }
 
         @Override
@@ -391,7 +406,7 @@
                     return instrumentNode.nextInstrumentNode;
                 }
                 // Match not at the head of the chain; remove it.
-                found = instrumentNode.removeFromChain(SpliceInstrument.this);
+                found = instrumentNode.removeFromChain(ToolEvalInstrument.this);
             }
             if (!found) {
                 throw new IllegalStateException("Couldn't find instrument node to remove: " + this);
@@ -399,26 +414,30 @@
             return instrumentNode;
         }
 
+        /**
+         * Node that implements a {@link ToolEvalInstrument} in a particular AST.
+         */
         @NodeInfo(cost = NodeCost.NONE)
-        private final class SpliceInstrumentNode extends AbstractInstrumentNode {
+        private final class ToolEvalNodeInstrumentNode extends AbstractInstrumentNode {
 
-            @Child SplicedNode splicedNode;
+            @Child ToolEvalNode toolEvalNode;
 
-            private SpliceInstrumentNode(AbstractInstrumentNode nextNode) {
+            private ToolEvalNodeInstrumentNode(AbstractInstrumentNode nextNode) {
                 super(nextNode);
             }
 
             public void enter(Node node, VirtualFrame vFrame) {
-                if (splicedNode == null) {
-                    final SplicedNode newSplicedNode = SpliceInstrument.this.spliceListener.getSpliceNode(SpliceInstrument.this.probe);
-                    if (newSplicedNode != null) {
-                        splicedNode = newSplicedNode;
+                if (toolEvalNode == null) {
+                    final ToolEvalNode newToolEvalNodeNode = ToolEvalInstrument.this.toolEvalNodeFactory.createToolEvalNode(ToolEvalInstrument.this.probe, node);
+                    if (newToolEvalNodeNode != null) {
+                        toolEvalNode = newToolEvalNodeNode;
                         adoptChildren();
-                        SpliceInstrument.this.probe.invalidateProbeUnchanged();
+                        ToolEvalInstrument.this.probe.invalidateProbeUnchanged();
                     }
                 }
-                if (splicedNode != null) {
-                    splicedNode.enter(node, vFrame);
+                if (toolEvalNode != null) {
+                    // TODO (mlvdv) should report exception ; non-trivial architectural change
+                    toolEvalNode.executeToolEvalNode(node, vFrame);
                 }
                 if (nextInstrumentNode != null) {
                     nextInstrumentNode.enter(node, vFrame);
@@ -426,27 +445,18 @@
             }
 
             public void returnVoid(Node node, VirtualFrame vFrame) {
-                if (splicedNode != null) {
-                    splicedNode.returnVoid(node, vFrame);
-                }
                 if (nextInstrumentNode != null) {
                     nextInstrumentNode.returnVoid(node, vFrame);
                 }
             }
 
             public void returnValue(Node node, VirtualFrame vFrame, Object result) {
-                if (splicedNode != null) {
-                    splicedNode.returnValue(node, vFrame, result);
-                }
                 if (nextInstrumentNode != null) {
                     nextInstrumentNode.returnValue(node, vFrame, result);
                 }
             }
 
             public void returnExceptional(Node node, VirtualFrame vFrame, Exception exception) {
-                if (splicedNode != null) {
-                    splicedNode.returnExceptional(node, vFrame, exception);
-                }
                 if (nextInstrumentNode != null) {
                     nextInstrumentNode.returnExceptional(node, vFrame, exception);
                 }
@@ -454,7 +464,7 @@
 
             public String instrumentationInfo() {
                 final String info = getInstrumentInfo();
-                return info != null ? info : spliceListener.getClass().getSimpleName();
+                return info != null ? info : toolEvalNodeFactory.getClass().getSimpleName();
             }
         }
     }