changeset 19869:1d6a7ea5de59

Truffle/Instrumentation: remove support for "probe-lite", an optimization for a particular use case that no longer seems worth the complexity.
author Michael Van De Vanter <michael.van.de.vanter@oracle.com>
date Mon, 16 Mar 2015 15:59:57 -0700
parents 1cbbdc29ab45
children ab898f9f9c3c
files graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTest.java graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/tools/TestNodes.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeFailure.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeNode.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLExpressionWrapperNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLStatementWrapperNode.java
diffstat 7 files changed, 88 insertions(+), 258 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTest.java	Sat Mar 14 22:45:52 2015 +0100
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTest.java	Mon Mar 16 15:59:57 2015 -0700
@@ -380,11 +380,7 @@
 
         @Override
         public Probe getProbe() {
-            try {
-                return probeNode.getProbe();
-            } catch (IllegalStateException e) {
-                throw new IllegalStateException("Cannot call getProbe() on a wrapper that has no probe");
-            }
+            return probeNode.getProbe();
         }
 
         @Override
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/tools/TestNodes.java	Sat Mar 14 22:45:52 2015 +0100
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/tools/TestNodes.java	Mon Mar 16 15:59:57 2015 -0700
@@ -119,11 +119,7 @@
 
         @Override
         public Probe getProbe() {
-            try {
-                return probeNode.getProbe();
-            } catch (IllegalStateException e) {
-                throw new IllegalStateException("Cannot call getProbe() on a wrapper that has no probe");
-            }
+            return probeNode.getProbe();
         }
 
         @Override
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeFailure.java	Sat Mar 14 22:45:52 2015 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeFailure.java	Mon Mar 16 15:59:57 2015 -0700
@@ -58,12 +58,7 @@
         /**
          * Wrapper not assignable to the parent's child field.
          */
-        WRAPPER_TYPE("Wrapper not assignable to parent's child field"),
-
-        /**
-         * Attempt to \"probe lite\" an already probed node.
-         */
-        LITE_VIOLATION("Attempt to \"probe lite\" an already probed node");
+        WRAPPER_TYPE("Wrapper not assignable to parent's child field");
 
         final String message;
 
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeNode.java	Sat Mar 14 22:45:52 2015 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeNode.java	Mon Mar 16 15:59:57 2015 -0700
@@ -33,9 +33,20 @@
 import com.oracle.truffle.api.source.*;
 
 /**
- * Implementation interfaces and classes for attaching {@link Probe}s to {@link WrapperNode}s.
+ * Implementation class & interface for enabling the attachment of {@linkplain Probe Probes} to
+ * Truffle ASTs.
+ * <p>
+ * A {@link ProbeNode} is the head of a chain of nodes acting on behalf of {@linkplain Instrument
+ * instruments}. It is attached to an AST as a child of a guest-language-specific
+ * {@link WrapperNode} node.
+ * <p>
+ * When Truffle clones an AST, the chain, including all attached {@linkplain Instrument instruments}
+ * will be cloned along with the {@link WrapperNode} to which it is attached. An instance of
+ * {@link Probe} represents abstractly the instrumentation at a particular location in a GL AST,
+ * tracks the clones of the chain, and keeps the instrumentation attached to the clones consistent.
  */
-public abstract class ProbeNode extends Node implements TruffleEvents, InstrumentationNode {
+@NodeInfo(cost = NodeCost.NONE)
+public final class ProbeNode extends Node implements TruffleEvents, InstrumentationNode {
 
     /**
      * A node that can be inserted into a Truffle AST, and which enables {@linkplain Instrument
@@ -91,8 +102,7 @@
         Node getChild();
 
         /**
-         * Gets the {@link Probe} responsible for installing this wrapper; none if the wrapper
-         * installed via {@linkplain Node#probeLite(ASTInstrumentListener) "lite-Probing"}.
+         * Gets the {@link Probe} responsible for installing this wrapper.
          */
         Probe getProbe();
 
@@ -100,7 +110,6 @@
          * Implementation support for completing a newly created wrapper node.
          */
         void insertProbe(ProbeNode probeNode);
-
     }
 
     /**
@@ -109,202 +118,99 @@
      */
     public static Probe insertProbe(WrapperNode wrapper) {
         final SourceSection sourceSection = wrapper.getChild().getSourceSection();
-        final ProbeFullNode probeFullNode = new ProbeFullNode(); // private constructor
-        final Probe probe = new Probe(probeFullNode, sourceSection);  // package private access
-        probeFullNode.setProbe(probe);
-        wrapper.insertProbe(probeFullNode);
-        return probe;
+        final ProbeNode probeNode = new ProbeNode(); // private constructor
+        probeNode.probe = new Probe(probeNode, sourceSection);  // package private access
+        wrapper.insertProbe(probeNode);
+        return probeNode.probe;
     }
 
+    // Never changed once set.
+    @CompilationFinal Probe probe = null;
     /**
-     * Creates a new {@link ProbeLiteNode} associated with, and attached to, a Guest Language
-     * specific instance of {@link WrapperNode}.
+     * First {@link AbstractInstrumentNode} node in chain; {@code null} of no instruments in chain.
      */
-    public static void insertProbeLite(WrapperNode wrapper, ASTInstrumentListener instrumentListener) {
-        final ProbeLiteNode probeLiteNode = new ProbeLiteNode(instrumentListener);
-        wrapper.insertProbe(probeLiteNode);
-    }
+    @Child protected AbstractInstrumentNode firstInstrument;
 
     @Override
     public boolean isInstrumentable() {
         return false;
     }
 
+    @Override
+    public Node copy() {
+        Node node = super.copy();
+        probe.registerProbeNodeClone((ProbeNode) node);
+        return node;
+    }
+
     /**
      * @return the {@link Probe} permanently associated with this {@link ProbeNode}.
-     *
-     * @throws IllegalStateException if this location was "lite-Probed"
      */
-    public abstract Probe getProbe() throws IllegalStateException;
+    public Probe getProbe() {
+        return probe;
+    }
+
+    public void enter(Node node, VirtualFrame vFrame) {
+        this.probe.checkProbeUnchanged();
+        final SyntaxTagTrap trap = probe.getTrap();
+        if (trap != null) {
+            trap.tagTrappedAt(((WrapperNode) this.getParent()).getChild(), vFrame.materialize());
+        }
+        if (firstInstrument != null) {
+            firstInstrument.enter(node, vFrame);
+        }
+    }
+
+    public void returnVoid(Node node, VirtualFrame vFrame) {
+        this.probe.checkProbeUnchanged();
+        if (firstInstrument != null) {
+            firstInstrument.returnVoid(node, vFrame);
+        }
+    }
+
+    public void returnValue(Node node, VirtualFrame vFrame, Object result) {
+        this.probe.checkProbeUnchanged();
+        if (firstInstrument != null) {
+            firstInstrument.returnValue(node, vFrame, result);
+        }
+    }
+
+    public void returnExceptional(Node node, VirtualFrame vFrame, Exception exception) {
+        this.probe.checkProbeUnchanged();
+        if (firstInstrument != null) {
+            firstInstrument.returnExceptional(node, vFrame, exception);
+        }
+    }
+
+    public String instrumentationInfo() {
+        return "Standard probe";
+    }
 
     /**
      * Adds an {@link AbstractInstrumentNode} to this chain.
-     *
-     * @throws IllegalStateException if at a "lite-Probed" location.
      */
-    abstract void addInstrument(Instrument instrument);
+    @TruffleBoundary
+    void addInstrument(Instrument instrument) {
+        assert instrument.getProbe() == probe;
+        // The existing chain of nodes may be empty
+        // Attach the modified chain.
+        firstInstrument = insert(instrument.addToChain(firstInstrument));
+    }
 
     /**
      * Removes an instrument from this chain of instruments.
      *
-     * @throws IllegalStateException if at a "lite-Probed" location.
      * @throws RuntimeException if no matching instrument is found,
      */
-    abstract void removeInstrument(Instrument instrument);
-
-    /**
-     * Implementation class & interfaces for enabling the attachment of {@linkplain Probe Probes} to
-     * Truffle ASTs.
-     * <p>
-     * Head of a chain of nodes acting on behalf of {@linkplain Instrument instruments}, attached to
-     * a Guest Language (GL) AST as a child of a GL-specific {@link WrapperNode} node.
-     * <p>
-     * When Truffle clones an AST, the chain, including all attached {@linkplain Instrument
-     * instruments} will be cloned along with the {@link WrapperNode} to which it is attached. An
-     * instance of {@link Probe} represents abstractly the instrumentation at a particular location
-     * in a GL AST, tracks the clones of the chain, and keeps the instrumentation attached to the
-     * clones consistent.
-     */
-    @NodeInfo(cost = NodeCost.NONE)
-    private static final class ProbeFullNode extends ProbeNode {
-
-        /**
-         * First {@link AbstractInstrumentNode} node in chain; {@code null} of no instruments in
-         * chain.
-         */
-        @Child protected AbstractInstrumentNode firstInstrument;
-
-        // Never changed once set.
-        @CompilationFinal private Probe probe = null;
-
-        private ProbeFullNode() {
-            this.firstInstrument = null;
-        }
-
-        @Override
-        public Probe getProbe() throws IllegalStateException {
-            return probe;
-        }
-
-        @Override
-        public Node copy() {
-            Node node = super.copy();
-            probe.registerProbeNodeClone((ProbeNode) node);
-            return node;
-        }
-
-        private void setProbe(Probe probe) {
-            this.probe = probe;
-        }
-
-        @Override
-        @TruffleBoundary
-        void addInstrument(Instrument instrument) {
-            assert instrument.getProbe() == probe;
-            // The existing chain of nodes may be empty
-            // Attach the modified chain.
-            firstInstrument = insert(instrument.addToChain(firstInstrument));
-        }
-
-        @Override
-        @TruffleBoundary
-        void removeInstrument(Instrument instrument) {
-            assert instrument.getProbe() == probe;
-            final AbstractInstrumentNode modifiedChain = instrument.removeFromChain(firstInstrument);
-            if (modifiedChain == null) {
-                firstInstrument = null;
-            } else {
-                firstInstrument = insert(modifiedChain);
-            }
-        }
-
-        public void enter(Node node, VirtualFrame vFrame) {
-            this.probe.checkProbeUnchanged();
-            final SyntaxTagTrap trap = probe.getTrap();
-            if (trap != null) {
-                trap.tagTrappedAt(((WrapperNode) this.getParent()).getChild(), vFrame.materialize());
-            }
-            if (firstInstrument != null) {
-                firstInstrument.enter(node, vFrame);
-            }
-        }
-
-        public void returnVoid(Node node, VirtualFrame vFrame) {
-            this.probe.checkProbeUnchanged();
-            if (firstInstrument != null) {
-                firstInstrument.returnVoid(node, vFrame);
-            }
-        }
-
-        public void returnValue(Node node, VirtualFrame vFrame, Object result) {
-            this.probe.checkProbeUnchanged();
-            if (firstInstrument != null) {
-                firstInstrument.returnValue(node, vFrame, result);
-            }
-        }
-
-        public void returnExceptional(Node node, VirtualFrame vFrame, Exception exception) {
-            this.probe.checkProbeUnchanged();
-            if (firstInstrument != null) {
-                firstInstrument.returnExceptional(node, vFrame, exception);
-            }
-        }
-
-        public String instrumentationInfo() {
-            return "Standard probe";
+    @TruffleBoundary
+    void removeInstrument(Instrument instrument) {
+        assert instrument.getProbe() == probe;
+        final AbstractInstrumentNode modifiedChain = instrument.removeFromChain(firstInstrument);
+        if (modifiedChain == null) {
+            firstInstrument = null;
+        } else {
+            firstInstrument = insert(modifiedChain);
         }
     }
 
-    /**
-     * Implementation of a probe that only ever has a single "instrument" associated with it. No
-     * {@link Instrument} is ever created; instead this method simply delegates the various enter
-     * and return events to a {@link TruffleEvents} passed in during construction.
-     */
-    @NodeInfo(cost = NodeCost.NONE)
-    private static final class ProbeLiteNode extends ProbeNode {
-
-        private final ASTInstrumentListener instrumentListener;
-
-        private ProbeLiteNode(ASTInstrumentListener eventListener) {
-            this.instrumentListener = eventListener;
-        }
-
-        @Override
-        public Probe getProbe() throws IllegalStateException {
-            throw new IllegalStateException("\"lite-Probed\" nodes have no explicit Probe");
-        }
-
-        @Override
-        @TruffleBoundary
-        void addInstrument(Instrument instrument) {
-            throw new IllegalStateException("Instruments may not be added at a \"lite-probed\" location");
-        }
-
-        @Override
-        @TruffleBoundary
-        void removeInstrument(Instrument instrument) {
-            throw new IllegalStateException("Instruments may not be removed at a \"lite-probed\" location");
-        }
-
-        public void enter(Node node, VirtualFrame vFrame) {
-            instrumentListener.enter(getProbe(), node, vFrame);
-        }
-
-        public void returnVoid(Node node, VirtualFrame vFrame) {
-            instrumentListener.returnVoid(getProbe(), node, vFrame);
-        }
-
-        public void returnValue(Node node, VirtualFrame vFrame, Object result) {
-            instrumentListener.returnValue(getProbe(), node, vFrame, result);
-        }
-
-        public void returnExceptional(Node node, VirtualFrame vFrame, Exception exception) {
-            instrumentListener.returnExceptional(getProbe(), node, vFrame, exception);
-        }
-
-        public String instrumentationInfo() {
-            return "\"Lite\" probe";
-        }
-
-    }
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java	Sat Mar 14 22:45:52 2015 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java	Mon Mar 16 15:59:57 2015 -0700
@@ -497,61 +497,6 @@
     }
 
     /**
-     * Enables "one-shot", unmodifiable {@linkplain Instrument instrumentation} of a node, where the
-     * node is presumed to be part of a well-formed Truffle AST that is not being executed.
-     * <p>
-     * Modifies the AST by inserting a {@linkplain WrapperNode wrapper node} between the node and
-     * its parent; the wrapper node must be provided by implementations of
-     * {@link #createWrapperNode()}.
-     * <p>
-     * Unlike {@link #probe()}, once {@link #probeLite(ASTInstrumentListener)} is called at a node,
-     * no additional probing can be added and no additional instrumentation can be attached.
-     * <p>
-     * This restricted form of instrumentation is intended for special cases where only one kind of
-     * instrumentation is desired, and for which performance is a concern
-     *
-     * @param instrumentListener
-     * @throws ProbeException (unchecked) when a probe cannot be created, leaving the AST unchanged
-     */
-    public final void probeLite(ASTInstrumentListener instrumentListener) {
-
-        if (this instanceof WrapperNode) {
-            throw new ProbeException(ProbeFailure.Reason.WRAPPER_NODE, null, this, null);
-        }
-
-        if (parent == null) {
-            throw new ProbeException(ProbeFailure.Reason.NO_PARENT, null, this, null);
-        }
-
-        if (parent instanceof WrapperNode) {
-            throw new ProbeException(ProbeFailure.Reason.LITE_VIOLATION, null, this, null);
-        }
-
-        if (!isInstrumentable()) {
-            throw new ProbeException(ProbeFailure.Reason.NOT_INSTRUMENTABLE, parent, this, null);
-        }
-
-        // Create a new wrapper/probe with this node as its child.
-        final WrapperNode wrapper = createWrapperNode();
-
-        if (wrapper == null || !(wrapper instanceof Node)) {
-            throw new ProbeException(ProbeFailure.Reason.NO_WRAPPER, parent, this, wrapper);
-        }
-
-        final Node wrapperNode = (Node) wrapper;
-
-        if (!this.isSafelyReplaceableBy(wrapperNode)) {
-            throw new ProbeException(ProbeFailure.Reason.WRAPPER_TYPE, parent, this, wrapper);
-        }
-
-        // Connect it to a Probe
-        ProbeNode.insertProbeLite(wrapper, instrumentListener);
-
-        // Replace this node in the AST with the wrapper
-        this.replace(wrapperNode);
-    }
-
-    /**
      * Converts this node to a textual representation useful for debugging.
      */
     @Override
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLExpressionWrapperNode.java	Sat Mar 14 22:45:52 2015 +0100
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLExpressionWrapperNode.java	Mon Mar 16 15:59:57 2015 -0700
@@ -72,11 +72,7 @@
     }
 
     public Probe getProbe() {
-        try {
-            return probeNode.getProbe();
-        } catch (IllegalStateException e) {
-            throw new IllegalStateException("A lite-Probed wrapper has no explicit Probe");
-        }
+        return probeNode.getProbe();
     }
 
     public Node getChild() {
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLStatementWrapperNode.java	Sat Mar 14 22:45:52 2015 +0100
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLStatementWrapperNode.java	Mon Mar 16 15:59:57 2015 -0700
@@ -65,11 +65,7 @@
     }
 
     public Probe getProbe() {
-        try {
-            return probeNode.getProbe();
-        } catch (IllegalStateException e) {
-            throw new IllegalStateException("A lite-Probed wrapper has no explicit Probe");
-        }
+        return probeNode.getProbe();
     }
 
     @Override