changeset 22224:776dc0a09749

Truffle/Instrumentation: Javadoc
author Michael Van De Vanter <michael.van.de.vanter@oracle.com>
date Sat, 19 Sep 2015 13:56:42 -0700
parents 964e789e17f7
children a0fa69e3e60e
files truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrumenter.java truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java
diffstat 2 files changed, 90 insertions(+), 78 deletions(-) [+]
line wrap: on
line diff
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrumenter.java	Sat Sep 19 13:26:06 2015 -0700
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrumenter.java	Sat Sep 19 13:56:42 2015 -0700
@@ -110,7 +110,8 @@
     }
 
     /**
-     * Returns {@code true} if the node can be "instrumented" by {@linkplain #probe(Node) probing}.
+     * Returns {@code true} if the AST node can be "instrumented" by {@linkplain #probe(Node)
+     * Probing}.
      * <p>
      * <b>Note:</b> instrumentation requires a appropriate {@linkplain #createWrapperNode(Node)
      * WrapperNode}.
@@ -120,11 +121,11 @@
     }
 
     /**
-     * For nodes that are {@linkplain #isInstrumentable() instrumentable}, this method must return
-     * an {@linkplain Node AST node} that:
+     * For AST nodes that are {@linkplain #isInstrumentable() instrumentable}, returns a
+     * <em>wrapper node</em> that:
      * <ol>
      * <li>implements {@link WrapperNode}</li>
-     * <li>has the node argument as it's child, and</li>
+     * <li>has the node as its single child, and</li>
      * <li>whose type is safe for replacement of the node in the parent.</li>
      * </ol>
      *
@@ -135,13 +136,19 @@
     }
 
     /**
-     * Enables {@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. If this node has not already
-     * been probed, 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 Node#createWrapperNode()}. No more than one {@link Probe} may be associated with a
-     * node, so a {@linkplain WrapperNode wrapper} may not wrap another {@linkplain WrapperNode
-     * wrapper}.
+     * Prepares an AST node for {@linkplain Instrument instrumentation}, where the node is presumed
+     * to be part of a well-formed Truffle AST that has not yet been executed.
+     * <p>
+     * <em>Probing</em> a node is idempotent:
+     * <ul>
+     * <li>If the node has not been Probed, modifies the AST by first inserting a
+     * {@linkplain #createWrapperNode(Node) wrapper node} between the node and its parent and then
+     * returning the newly created Probe associated with the wrapper.</li>
+     * <li>If the node has been Probed, returns the Probe associated with its existing wrapper.</li>
+     * <li>No more than one {@link Probe} may be associated with a node, so a wrapper may not wrap
+     * another wrapper.</li>
+     * </ul>
+     * It is a runtime error to attempt Probing an AST node with no parent.
      *
      * @return a (possibly newly created) {@link Probe} associated with this node.
      * @throws ProbeException (unchecked) when a probe cannot be created, leaving the AST unchanged
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java	Sat Sep 19 13:26:06 2015 -0700
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java	Sat Sep 19 13:56:42 2015 -0700
@@ -43,61 +43,21 @@
 /**
  * A <em>binding</em> between:
  * <ol>
- * <li>A program location in an executing Truffle AST (corresponding to a {@link SourceSection}),
- * and</li>
- * <li>A dynamically managed collection of "attached" {@linkplain Instrument Instruments} that
- * receive event notifications on behalf of external clients.</li>
+ * <li>A <em>guest language program location</em> in an executing Truffle AST (corresponding to a
+ * {@link SourceSection}), and</li>
+ * <li>A dynamically managed collection of <em>attached</em> {@linkplain Instrument Instruments}
+ * that receive event notifications from the Probe's AST location on behalf of external clients.</li>
  * </ol>
+ * <strong>Note</strong>:The relationship must be with an AST <em>location</em>, not a specific
+ * {@link Node}, because ASTs are routinely <em>cloned</em> at runtime. An AST <em>location</em> is
+ * best represented as the {@link SourceSection} from which the original AST Node was created.
  * <p>
  * Client-oriented documentation for the use of Probes is available online at <a
  * HREF="https://wiki.openjdk.java.net/display/Graal/Finding+Probes" >https://wiki.openjdk.java.
  * net/display/Graal/Finding+Probes</a>
  * <p>
- * <h4>Implementation notes:</h4>
- * <p>
- * <ul>
- * <li>A Probe must be permanently associated with a <em>program location</em>, defined by a
- * particular {@link SourceSection}, even though:
- * <ul>
- * <li>that location is represented in an AST as a {@link Node}, which might be replaced through
- * optimizations such as specialization, and</li>
- * <li>Truffle may <em>clone</em> the AST so that the location is actually represented by multiple
- * Nodes in multiple ASTs.</li>
- * </ul>
- * </li>
  *
- * <li>The effect of the binding is to intercept {@linkplain TruffleEvents execution events}
- * arriving at the "probed" AST Node and notify each attached {@link Instrument} before execution is
- * allowed to proceed to the child and again after execution completes.</li>
- *
- * <li>The method {@link Instrumenter#probe(Node)} creates a Probe on an AST Node; redundant calls
- * return the same Probe.</li>
- *
- * <li>The "probing" of a Truffle AST must be done after the AST is complete (i.e. parent pointers
- * correctly assigned), but before any cloning or executions. This is done by applying instances of
- * {@link ASTProber} provided by each language implementation, combined with any instances
- * registered by tools via {@link Instrumenter#registerASTProber(ASTProber)}. Once registered, these
- * will be applied automatically to every newly created AST.</li>
- *
- * <li>The "probing" of an AST Node is implemented by insertion of a {@link ProbeNode.WrapperNode}
- * into the AST (as new parent of the Node being probed), together with an associated
- * {@link ProbeNode} that routes execution events at the probed Node to all the
- * {@linkplain Instrument Instruments} attached to the Probe's <em>instrument chain</em>.</li>
- *
- * <li>When Truffle clones an AST, any attached WrapperNodes and ProbeNodes are cloned as well,
- * together with their attached instrument chains. Each Probe instance intercepts cloning events and
- * keeps track of all AST copies.</li>
- *
- * <li>All attached {@link InstrumentationNode}s effectively become part of the running program:
- * <ul>
- * <li>Good News: instrumentation code implicitly benefits from every kind of Truffle optimization.</li>
- * <li>Bad News: instrumentation code must be implemented carefully to avoid interfering with any
- * Truffle optimizations.</li>
- * </ul>
- * </li>
- *
- * </ul>
- *
+ * @see Instrumenter
  * @see Instrument
  * @see ASTProber
  * @see ProbeListener
@@ -141,7 +101,51 @@
     @CompilationFinal private boolean isAfterTrapActive = false;
 
     /**
-     * Intended for use only by {@link ProbeNode}.
+     * Constructor for use only by {@link ProbeNode}.
+     * <p>
+     * <h4>Probe Implementation notes:</h4>
+     * <p>
+     * <ul>
+     * <li>A Probe must be permanently associated with a <em>program location</em>, defined by a
+     * particular {@link SourceSection}, even though:
+     * <ul>
+     * <li>that location is represented in an AST as a {@link Node}, which might be replaced through
+     * optimizations such as specialization, and</li>
+     * <li>Truffle may <em>clone</em> the AST so that the location is actually represented by
+     * multiple Nodes in multiple ASTs.</li>
+     * </ul>
+     * </li>
+     * <li>The effect of the binding is to intercept {@linkplain TruffleEvents execution events}
+     * arriving at the "probed" AST Node and notify each attached {@link Instrument} before
+     * execution is allowed to proceed to the child and again after execution completes.</li>
+     *
+     * <li>The method {@link Instrumenter#probe(Node)} creates a Probe on an AST Node; redundant
+     * calls return the same Probe.</li>
+     *
+     * <li>The "probing" of a Truffle AST must be done after the AST is complete (i.e. parent
+     * pointers correctly assigned), but before any cloning or executions. This is done by applying
+     * instances of {@link ASTProber} provided by each language implementation, combined with any
+     * instances registered by tools via {@link Instrumenter#registerASTProber(ASTProber)}. Once
+     * registered, these will be applied automatically to every newly created AST.</li>
+     *
+     * <li>The "probing" of an AST Node is implemented by insertion of a
+     * {@link ProbeNode.WrapperNode} into the AST (as new parent of the Node being probed), together
+     * with an associated {@link ProbeNode} that routes execution events at the probed Node to all
+     * the {@linkplain Instrument Instruments} attached to the Probe's <em>instrument chain</em>.</li>
+     *
+     * <li>When Truffle clones an AST, any attached WrapperNodes and ProbeNodes are cloned as well,
+     * together with their attached instrument chains. Each Probe instance intercepts cloning events
+     * and keeps track of all AST copies.</li>
+     *
+     * <li>All attached {@link InstrumentationNode}s effectively become part of the running program:
+     * <ul>
+     * <li>Good News: instrumentation code implicitly benefits from every kind of Truffle
+     * optimization.</li>
+     * <li>Bad News: instrumentation code must be implemented carefully to avoid interfering with
+     * any Truffle optimizations.</li>
+     * </ul>
+     * </li>
+     * </ul>
      */
     Probe(Instrumenter instrumenter, Class<? extends TruffleLanguage> l, ProbeNode probeNode, SourceSection sourceSection) {
         this.instrumenter = instrumenter;
@@ -151,22 +155,6 @@
     }
 
     /**
-     * Is this node tagged as belonging to a particular human-sensible category of language
-     * constructs?
-     */
-    public boolean isTaggedAs(SyntaxTag tag) {
-        assert tag != null;
-        return tags.contains(tag);
-    }
-
-    /**
-     * In which user-sensible categories has this node been tagged (<em>empty set</em> if none).
-     */
-    public Collection<SyntaxTag> getSyntaxTags() {
-        return Collections.unmodifiableCollection(tags);
-    }
-
-    /**
      * Adds a {@linkplain SyntaxTag tag} to the set of tags associated with this {@link Probe};
      * {@code no-op} if already in the set.
      */
@@ -198,6 +186,23 @@
     }
 
     /**
+     * Is the <em>Probed node</em> tagged as belonging to a particular human-sensible category of
+     * language constructs?
+     */
+    public boolean isTaggedAs(SyntaxTag tag) {
+        assert tag != null;
+        return tags.contains(tag);
+    }
+
+    /**
+     * In which user-sensible categories has the <em>Probed node</em> been tagged (
+     * <em>empty set</em> if none).
+     */
+    public Collection<SyntaxTag> getSyntaxTags() {
+        return Collections.unmodifiableCollection(tags);
+    }
+
+    /**
      * Adds instrumentation at this Probe.
      *
      * @param instrument an instrument not yet attached to a probe
@@ -221,8 +226,8 @@
     }
 
     /**
-     * Gets the {@link SourceSection} associated with the Guest Language AST node being
-     * instrumented, possibly {@code null}.
+     * Gets the {@link SourceSection} associated with the <en>Probed AST node</em>, possibly
+     * {@code null}.
      */
     public SourceSection getProbedSourceSection() {
         return sourceSection;