changeset 16777:3841273677a3

Merge with db2ac421649a00f0f8e1022d9daa682a0e9dd114
author Michael Van De Vanter <michael.van.de.vanter@oracle.com>
date Mon, 11 Aug 2014 13:53:37 -0700
parents a24beb9c9993 (diff) db2ac421649a (current diff)
children 8a05a498ab76
files graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/GuardsTest.java graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/SlowPathTest.java graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/Generic.java graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/PolymorphicLimit.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/AbstractParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/Utils.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/ExtensionContext.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/element/WritableAnnotationMirror.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/element/WritableElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/element/WritableElementFactory.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/element/WritableExecutableElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/element/WritableVariableElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeAnnotationMirror.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeAnnotationValue.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeCompilationUnit.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeElementScanner.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeExecutableElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeImport.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeNames.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTree.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTreeBuilder.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTreeKind.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTypeElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTypeMirror.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeVariableElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/GeneratedElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/AbstractCodeWriter.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/FixWarningsVisitor.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/GenerateOverrideVisitor.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/OrganizedImports.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/AbstractCompiler.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/Compiler.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/CompilerFactory.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/JDTCompiler.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/JavaCCompiler.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/CreateCastData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/CreateCastParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ExecutableTypeData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ExecutableTypeMethodParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/GenericParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeChildData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeExecutionData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeFieldData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeMethodParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ShortCircuitData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ShortCircuitParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGroup.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGuardData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationMethodParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationThrowsData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ActualParameter.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ClassElementFactory.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/CodeElementFactory.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/CompilationUnitFactory.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MessageContainer.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MethodSpec.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ParameterSpec.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/Template.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethod.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethodParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/ImplicitCastData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/ImplicitCastParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeCastData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeCastParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeCheckData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeCheckParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemCodeGenerator.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemMethodParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemParser.java
diffstat 9 files changed, 317 insertions(+), 294 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/InstrumentationTest.java	Mon Aug 11 13:53:37 2014 -0700
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.test;
+
+import java.util.*;
+
+import org.junit.*;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.instrument.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.api.source.*;
+
+/**
+ * <h3>AST Instrumentation</h3>
+ *
+ * Instrumentation allows the insertion into Truffle ASTs language-specific instances of
+ * {@link Wrapper} that propagate {@link ExecutionEvents} through a {@link Probe} to any instances
+ * of {@link Instrument} that might be attached to the particular probe by tools.
+ * <ol>
+ * <li>Creates a simple add AST</li>
+ * <li>Verifies its structure</li>
+ * <li>"Probes" the add node by adding a {@link Wrapper} and associated {@link Probe}</li>
+ * <li>Attaches a simple {@link Instrument} to the node via its {@link Probe}</li>
+ * <li>Verifies the structure of the probed AST</li>
+ * <li>Verifies the execution of the probed AST</li>
+ * <li>Verifies the results observed by the instrument.</li>
+ * </ol>
+ * To do these tests, several required classes have been implemented in their most basic form, only
+ * implementing the methods necessary for the tests to pass, with stubs elsewhere.
+ */
+public class InstrumentationTest {
+
+    @Test
+    public void test() {
+        // Build a tree
+        TruffleRuntime runtime = Truffle.getRuntime();
+        TestChildNode leftChild = new TestChildNode();
+        TestChildNode rightChild = new TestChildNode();
+        TestSourceSection sourceSection = new TestSourceSection();
+        TestAddNode addNode = new TestAddNode(leftChild, rightChild, sourceSection);
+        TestRootNode rootNode = new TestRootNode(addNode);
+
+        // Have to create a call target before checking parent/child relationships
+        CallTarget target = runtime.createCallTarget(rootNode);
+
+        // Check tree structure
+        Assert.assertEquals(addNode, leftChild.getParent());
+        Assert.assertEquals(addNode, rightChild.getParent());
+        Iterator<Node> iterator = addNode.getChildren().iterator();
+        Assert.assertEquals(leftChild, iterator.next());
+        Assert.assertEquals(rightChild, iterator.next());
+        Assert.assertFalse(iterator.hasNext());
+        Assert.assertEquals(rootNode, addNode.getParent());
+        iterator = rootNode.getChildren().iterator();
+        Assert.assertEquals(addNode, iterator.next());
+        Assert.assertFalse(iterator.hasNext());
+        Object result = target.call();
+        Assert.assertEquals(42, result);
+
+        // Create another call target, this time with the "probed" add node
+        TestExecutionContext context = new TestExecutionContext();
+        TestWrapper wrapper = new TestWrapper(addNode, context);
+        rootNode = new TestRootNode(wrapper);
+        target = runtime.createCallTarget(rootNode);
+
+        // Check the new tree structure
+        Assert.assertEquals(addNode, leftChild.getParent());
+        Assert.assertEquals(addNode, rightChild.getParent());
+        iterator = addNode.getChildren().iterator();
+        Assert.assertEquals(leftChild, iterator.next());
+        Assert.assertEquals(rightChild, iterator.next());
+        Assert.assertFalse(iterator.hasNext());
+        Assert.assertEquals(wrapper, addNode.getParent());
+        iterator = wrapper.getChildren().iterator();
+        Assert.assertEquals(addNode, iterator.next());
+        Assert.assertFalse(iterator.hasNext());
+        Assert.assertEquals(rootNode, wrapper.getParent());
+        iterator = rootNode.getChildren().iterator();
+        Assert.assertEquals(wrapper, iterator.next());
+        Assert.assertFalse(iterator.hasNext());
+        result = target.call();
+        Assert.assertEquals(42, result);
+
+        // Create some instruments
+        final TestInstrument instrumentA = new TestInstrument();
+        final TestInstrument instrumentB = new TestInstrument();
+
+        wrapper.getProbe().addInstrument(instrumentA);
+
+        result = target.call();
+        Assert.assertEquals(instrumentA.numInstrumentEnter, 1);
+        Assert.assertEquals(instrumentA.numInstrumentLeave, 1);
+        Assert.assertEquals(instrumentB.numInstrumentEnter, 0);
+        Assert.assertEquals(instrumentB.numInstrumentLeave, 0);
+        Assert.assertEquals(42, result);
+
+        wrapper.getProbe().addInstrument(instrumentB);
+
+        result = target.call();
+        Assert.assertEquals(instrumentA.numInstrumentEnter, 2);
+        Assert.assertEquals(instrumentA.numInstrumentLeave, 2);
+        Assert.assertEquals(instrumentB.numInstrumentEnter, 1);
+        Assert.assertEquals(instrumentB.numInstrumentLeave, 1);
+        Assert.assertEquals(42, result);
+
+        wrapper.getProbe().removeInstrument(instrumentA);
+
+        result = target.call();
+        Assert.assertEquals(instrumentA.numInstrumentEnter, 2);
+        Assert.assertEquals(instrumentA.numInstrumentLeave, 2);
+        Assert.assertEquals(instrumentB.numInstrumentEnter, 2);
+        Assert.assertEquals(instrumentB.numInstrumentLeave, 2);
+        Assert.assertEquals(42, result);
+
+    }
+
+    private class TestRootNode extends RootNode {
+        @Child private RootNode child;
+
+        public TestRootNode(RootNode child) {
+            super(null);
+            this.child = child;
+        }
+
+        @Override
+        public Object execute(VirtualFrame frame) {
+            return child.execute(frame);
+        }
+    }
+
+    private class TestAddNode extends RootNode {
+
+        @Child private TestChildNode left;
+        @Child private TestChildNode right;
+
+        public TestAddNode(TestChildNode left, TestChildNode right, TestSourceSection sourceSection) {
+            super(sourceSection);
+            this.left = left;
+            this.right = right;
+        }
+
+        @Override
+        public Object execute(VirtualFrame frame) {
+            return left.execute() + right.execute();
+        }
+    }
+
+    private class TestChildNode extends Node {
+
+        public TestChildNode() {
+            super(null);
+        }
+
+        public int execute() {
+            return 21;
+        }
+    }
+
+    /**
+     * The wrapper node class is usually language-specific and inherits from the language-specific
+     * subclass of {@link Node}, not {@RootNode}.
+     */
+    private class TestWrapper extends RootNode implements Wrapper {
+        @Child private RootNode child;
+        private Probe probe;
+
+        public TestWrapper(RootNode child, ExecutionContext context) {
+            this.child = insert(child);
+            this.probe = context.getProbe(child.getSourceSection());
+        }
+
+        public boolean isTaggedAs(SyntaxTag tag) {
+            return false;
+        }
+
+        public Iterable<SyntaxTag> getSyntaxTags() {
+            return null;
+        }
+
+        public Node getChild() {
+            return child;
+        }
+
+        public Probe getProbe() {
+            return probe;
+        }
+
+        @Override
+        public Object execute(VirtualFrame frame) {
+            probe.enter(child, frame);
+            Object result;
+
+            try {
+                result = child.execute(frame);
+                probe.leave(child, frame, result);
+            } catch (Exception e) {
+                probe.leaveExceptional(child, frame, e);
+                throw (e);
+            }
+            return result;
+        }
+    }
+
+    /**
+     * An "empty" description of the source code that might correspond to a particular AST node. The
+     * instrumentation framework tracks probes that have been inserted by their source location,
+     * using this as a key.
+     */
+    private class TestSourceSection implements SourceSection {
+
+        public Source getSource() {
+            return null;
+        }
+
+        public int getStartLine() {
+            return 0;
+        }
+
+        public LineLocation getLineLocation() {
+            return null;
+        }
+
+        public int getStartColumn() {
+            return 0;
+        }
+
+        public int getCharIndex() {
+            return 0;
+        }
+
+        public int getCharLength() {
+            return 0;
+        }
+
+        public int getCharEndIndex() {
+            return 0;
+        }
+
+        public String getIdentifier() {
+            return null;
+        }
+
+        public String getCode() {
+            return null;
+        }
+
+        public String getShortDescription() {
+            return null;
+        }
+
+    }
+
+    private class TestExecutionContext extends ExecutionContext {
+
+        @Override
+        public String getLanguageShortName() {
+            return "test";
+        }
+
+        @Override
+        protected void setSourceCallback(SourceCallback sourceCallback) {
+        }
+
+    }
+
+    private class TestInstrument extends Instrument {
+
+        public int numInstrumentEnter = 0;
+        public int numInstrumentLeave = 0;
+
+        @Override
+        public void enter(Node astNode, VirtualFrame frame) {
+            numInstrumentEnter++;
+        }
+
+        @Override
+        public void leave(Node astNode, VirtualFrame frame, Object result) {
+            numInstrumentLeave++;
+        }
+    }
+
+}
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/WrapperTest.java	Mon Aug 11 18:53:38 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,270 +0,0 @@
-/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.test.instrument;
-
-import java.util.*;
-
-import org.junit.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.instrument.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.api.source.*;
-
-/**
- * This test does the following:
- * <ol>
- * <li>Creates a simple add AST</li>
- * <li>Verifies its structure</li>
- * <li>Instruments the add node</li>
- * <li>Attaches a simple probe to the instrumented node</li>
- * <li>Verifies the structure of the instrumented AST</li>
- * <li>Verifies the execution of the instrumented AST</li>
- * </ol>
- * To do these tests, several required classes have been implemented in their most basic form, only
- * implementing the methods necessary for the tests to pass, with stubs elsewhere.
- */
-public class WrapperTest {
-
-    @Test
-    public void test() {
-        // Build a tree
-        TruffleRuntime runtime = Truffle.getRuntime();
-        TestChildNode leftChild = new TestChildNode();
-        TestChildNode rightChild = new TestChildNode();
-        TestSourceSection sourceSection = new TestSourceSection();
-        TestAddNode addNode = new TestAddNode(leftChild, rightChild, sourceSection);
-        TestRootNode rootNode = new TestRootNode(addNode);
-
-        // Have to create a call target before checking parent/child relationships
-        CallTarget target = runtime.createCallTarget(rootNode);
-
-        // Check tree structure
-        Assert.assertEquals(addNode, leftChild.getParent());
-        Assert.assertEquals(addNode, rightChild.getParent());
-        Iterator<Node> iterator = addNode.getChildren().iterator();
-        Assert.assertEquals(leftChild, iterator.next());
-        Assert.assertEquals(rightChild, iterator.next());
-        Assert.assertFalse(iterator.hasNext());
-        Assert.assertEquals(rootNode, addNode.getParent());
-        iterator = rootNode.getChildren().iterator();
-        Assert.assertEquals(addNode, iterator.next());
-        Assert.assertFalse(iterator.hasNext());
-        Object result = target.call();
-        Assert.assertEquals(42, result);
-
-        // Add a wrapper
-        TestExecutionContext context = new TestExecutionContext();
-        TestWrapper wrapper = new TestWrapper(addNode, context);
-        rootNode = new TestRootNode(wrapper);
-        target = runtime.createCallTarget(rootNode);
-
-        // Check the new tree structure
-        Assert.assertEquals(addNode, leftChild.getParent());
-        Assert.assertEquals(addNode, rightChild.getParent());
-        iterator = addNode.getChildren().iterator();
-        Assert.assertEquals(leftChild, iterator.next());
-        Assert.assertEquals(rightChild, iterator.next());
-        Assert.assertFalse(iterator.hasNext());
-        Assert.assertEquals(wrapper, addNode.getParent());
-        iterator = wrapper.getChildren().iterator();
-        Assert.assertEquals(addNode, iterator.next());
-        Assert.assertFalse(iterator.hasNext());
-        Assert.assertEquals(rootNode, wrapper.getParent());
-        iterator = rootNode.getChildren().iterator();
-        Assert.assertEquals(wrapper, iterator.next());
-        Assert.assertFalse(iterator.hasNext());
-        result = target.call();
-        Assert.assertEquals(42, result);
-
-        // Add an instrument
-        wrapper.getProbe().addInstrument(new TestInstrument());
-
-        // Check instrument and result
-        result = target.call();
-        Assert.assertEquals(Counter.numInstrumentEnter, 1);
-        Assert.assertEquals(Counter.numInstrumentLeave, 1);
-        Assert.assertEquals(42, result);
-
-    }
-
-    private class TestRootNode extends RootNode {
-        @Child private RootNode child;
-
-        public TestRootNode(RootNode child) {
-            super(null);
-            this.child = child;
-        }
-
-        @Override
-        public Object execute(VirtualFrame frame) {
-            return child.execute(frame);
-        }
-    }
-
-    private class TestAddNode extends RootNode {
-
-        @Child private TestChildNode left;
-        @Child private TestChildNode right;
-
-        public TestAddNode(TestChildNode left, TestChildNode right, TestSourceSection sourceSection) {
-            super(sourceSection);
-            this.left = left;
-            this.right = right;
-        }
-
-        @Override
-        public Object execute(VirtualFrame frame) {
-            return left.execute() + right.execute();
-        }
-    }
-
-    private class TestChildNode extends Node {
-
-        public TestChildNode() {
-            super(null);
-        }
-
-        public int execute() {
-            return 21;
-        }
-    }
-
-    private class TestWrapper extends RootNode implements Wrapper {
-        @Child private RootNode child;
-        private Probe probe;
-
-        public TestWrapper(RootNode child, ExecutionContext context) {
-            this.child = insert(child);
-            this.probe = context.getProbe(child.getSourceSection());
-        }
-
-        public boolean isTaggedAs(SyntaxTag tag) {
-            return false;
-        }
-
-        public Iterable<SyntaxTag> getSyntaxTags() {
-            return null;
-        }
-
-        public Node getChild() {
-            return child;
-        }
-
-        public Probe getProbe() {
-            return probe;
-        }
-
-        @Override
-        public Object execute(VirtualFrame frame) {
-            probe.enter(child, frame);
-            Object result;
-
-            try {
-                result = child.execute(frame);
-                probe.leave(child, frame, result);
-            } catch (Exception e) {
-                probe.leaveExceptional(child, frame, e);
-                throw (e);
-            }
-            return result;
-        }
-    }
-
-    private class TestSourceSection implements SourceSection {
-
-        public Source getSource() {
-            return null;
-        }
-
-        public int getStartLine() {
-            return 0;
-        }
-
-        public LineLocation getLineLocation() {
-            return null;
-        }
-
-        public int getStartColumn() {
-            return 0;
-        }
-
-        public int getCharIndex() {
-            return 0;
-        }
-
-        public int getCharLength() {
-            return 0;
-        }
-
-        public int getCharEndIndex() {
-            return 0;
-        }
-
-        public String getIdentifier() {
-            return null;
-        }
-
-        public String getCode() {
-            return null;
-        }
-
-        public String getShortDescription() {
-            return null;
-        }
-
-    }
-
-    private class TestExecutionContext extends ExecutionContext {
-
-        @Override
-        public String getLanguageShortName() {
-            return "test";
-        }
-
-        @Override
-        protected void setSourceCallback(SourceCallback sourceCallback) {
-
-        }
-
-    }
-
-    private class TestInstrument extends Instrument {
-        @Override
-        public void enter(Node astNode, VirtualFrame frame) {
-            Counter.numInstrumentEnter++;
-        }
-
-        @Override
-        public void leave(Node astNode, VirtualFrame frame, Object result) {
-            Counter.numInstrumentLeave++;
-        }
-    }
-
-    public static class Counter {
-
-        public static int numInstrumentEnter = 0;
-        public static int numInstrumentLeave = 0;
-    }
-}
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/package-info.java	Mon Aug 11 18:53:38 2014 +0200
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/package-info.java	Mon Aug 11 13:53:37 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -44,6 +44,7 @@
  * <li>How to use frames and frame slots to store values local to an activation? {@link com.oracle.truffle.api.test.FrameTest}</li>
  * <li>How to use type specialization and speculation for frame slots? {@link com.oracle.truffle.api.test.FrameSlotTypeSpecializationTest}</li>
  * <li>How to use type specialization and speculation for node return values? {@link com.oracle.truffle.api.test.ReturnTypeSpecializationTest}</li>
+ * <li>How to "instrument" an AST with nodes that can provide access to runtime state from external tools {@link com.oracle.truffle.api.test.InstrumentationTest}</li>
  * </ul>
  *
  *
--- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLCheckVariableEqualityInstrument.java	Mon Aug 11 18:53:38 2014 +0200
+++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLCheckVariableEqualityInstrument.java	Mon Aug 11 13:53:37 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,7 @@
 /**
  * This sample instrument provides an example of a naive way to check if two numbers in SL are
  * equivalent using their variable names. This instrument is designed to be attached to an
- * {@link SLReturnNode}, but provides no guards against this.
+ * {@link SLReturnNode}, but provides no guards ensuring this.
  */
 public class SLCheckVariableEqualityInstrument extends Instrument {
 
--- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLInstrumentTestNodeProber.java	Mon Aug 11 18:53:38 2014 +0200
+++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLInstrumentTestNodeProber.java	Mon Aug 11 13:53:37 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -65,11 +65,11 @@
         SLStatementWrapper wrapper = null;
         if (node instanceof SLStatementWrapper) {
             wrapper = (SLStatementWrapper) node;
-            tagStatementNode(wrapper);
+            wrapper.tagAs(STATEMENT);
             return wrapper;
         } else if (node instanceof SLReturnNode) {
             wrapper = new SLStatementWrapper(slContext, node);
-            tagStatementNode(wrapper);
+            wrapper.tagAs(STATEMENT);
             return wrapper;
         }
         return node;
@@ -94,26 +94,14 @@
         SLExpressionWrapper wrapper = null;
         if (node instanceof SLExpressionWrapper) {
             wrapper = (SLExpressionWrapper) node;
-            tagAssignmentNode(wrapper);
+            wrapper.tagAs(ASSIGNMENT);
             return wrapper;
         } else if (node instanceof SLWriteLocalVariableNode) {
             wrapper = new SLExpressionWrapper(slContext, node);
-            tagAssignmentNode(wrapper);
+            wrapper.tagAs(ASSIGNMENT);
             return wrapper;
         }
         return node;
     }
 
-    private static void tagAssignmentNode(SLExpressionWrapper wrapper) {
-        if (!wrapper.isTaggedAs(ASSIGNMENT)) {
-            wrapper.tagAs(ASSIGNMENT);
-        }
-    }
-
-    private static void tagStatementNode(SLStatementWrapper wrapper) {
-        if (!wrapper.isTaggedAs(STATEMENT)) {
-            wrapper.tagAs(STATEMENT);
-        }
-    }
-
 }
\ No newline at end of file
--- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLInstrumentTestRunner.java	Mon Aug 11 18:53:38 2014 +0200
+++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLInstrumentTestRunner.java	Mon Aug 11 13:53:37 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLInstrumentTestSuite.java	Mon Aug 11 18:53:38 2014 +0200
+++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLInstrumentTestSuite.java	Mon Aug 11 13:53:37 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLPrintAssigmentValueInstrument.java	Mon Aug 11 18:53:38 2014 +0200
+++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLPrintAssigmentValueInstrument.java	Mon Aug 11 13:53:37 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLSimpleInstrumentTestSuite.java	Mon Aug 11 18:53:38 2014 +0200
+++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLSimpleInstrumentTestSuite.java	Mon Aug 11 13:53:37 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it