# HG changeset patch # User Michael Van De Vanter # Date 1442694366 25200 # Node ID 964e789e17f78b6954c96d4dc71ac9fe1fe9aa68 # Parent 69156ed8192b10d1495ecd23731196e171146324 Truffle/Tools; rewrite tests for simple counting tools, e.g. CoverageTracker diff -r 69156ed8192b -r 964e789e17f7 truffle/com.oracle.truffle.tools.test/src/com/oracle/truffle/tools/test/CoverageTrackerTest.java --- a/truffle/com.oracle.truffle.tools.test/src/com/oracle/truffle/tools/test/CoverageTrackerTest.java Sat Sep 19 13:25:41 2015 -0700 +++ b/truffle/com.oracle.truffle.tools.test/src/com/oracle/truffle/tools/test/CoverageTrackerTest.java Sat Sep 19 13:26:06 2015 -0700 @@ -24,33 +24,24 @@ */ package com.oracle.truffle.tools.test; -import static com.oracle.truffle.tools.test.TestNodes.createExpr13TestRootNode; -import static com.oracle.truffle.tools.test.ToolTestingLanguage.VALUE_TAG; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.io.IOException; import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.Map; -import org.junit.Ignore; import org.junit.Test; import com.oracle.truffle.api.instrument.Instrumenter; -import com.oracle.truffle.api.instrument.Probe; -import com.oracle.truffle.api.instrument.StandardSyntaxTag; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.vm.TruffleVM; import com.oracle.truffle.tools.CoverageTracker; +import com.oracle.truffle.tools.test.ToolTestUtil.ToolTestTag; public class CoverageTrackerTest { - @SuppressWarnings("unused") private static com.oracle.truffle.tools.test.ToolTestingLanguage DUMMY = null; - @SuppressWarnings("unused") private static ToolTestingLanguage INSTANCE = ToolTestingLanguage.INSTANCE; - @Test public void testNoExecution() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { final TruffleVM vm = TruffleVM.newVM().build(); @@ -71,75 +62,55 @@ assertEquals(tool.getCounts().entrySet().size(), 0); } + void checkCounts(Source source, CoverageTracker coverage, Long[] expectedCounts) { + final Map countMap = coverage.getCounts(); + assertEquals(countMap.size(), 1); + final Long[] resultCounts = countMap.get(source); + assertTrue(Arrays.equals(resultCounts, expectedCounts)); + } + @Test - public void testToolCreatedTooLate() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, IOException { + public void testCountingCoverage() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, IOException { final TruffleVM vm = TruffleVM.newVM().build(); final Field field = TruffleVM.class.getDeclaredField("instrumenter"); field.setAccessible(true); final Instrumenter instrumenter = (Instrumenter) field.get(vm); - final CoverageTracker tool = new CoverageTracker(VALUE_TAG); - tool.install(instrumenter); - final Source source = Source.fromText("testToolCreatedTooLate text", "testToolCreatedTooLate").withMimeType("text/x-toolTest"); - assertEquals(vm.eval(source).get(), 13); - assertTrue(tool.getCounts().isEmpty()); - tool.dispose(); - } + final Source source = ToolTestUtil.createTestSource("testCountingCoverage"); - @Ignore - @Test - public void testToolInstalledcTooLate() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - final Instrumenter instrumenter = TestNodes.createInstrumenter(); - final CoverageTracker tool = new CoverageTracker(); - final RootNode expr13rootNode = createExpr13TestRootNode(instrumenter); + final CoverageTracker valueCoverage = new CoverageTracker(ToolTestTag.VALUE_TAG); + final CoverageTracker addCoverage = new CoverageTracker(ToolTestTag.ADD_TAG); + + valueCoverage.install(instrumenter); + assertTrue(valueCoverage.getCounts().isEmpty()); - tool.install(instrumenter); - assertEquals(13, expr13rootNode.execute(null)); - assertTrue(tool.getCounts().isEmpty()); - tool.dispose(); - } + assertEquals(vm.eval(source).get(), 13); + + checkCounts(source, valueCoverage, new Long[]{Long.valueOf(1), null, Long.valueOf(1), null}); - @Ignore - @Test - public void testCountingCoverage() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - final Instrumenter instrumenter = TestNodes.createInstrumenter(); - final CoverageTracker tool = new CoverageTracker(); - tool.install(instrumenter); - final RootNode expr13rootNode = createExpr13TestRootNode(instrumenter); + addCoverage.install(instrumenter); - // Not probed yet. - assertEquals(13, expr13rootNode.execute(null)); - assertTrue(tool.getCounts().isEmpty()); + assertEquals(vm.eval(source).get(), 13); + + checkCounts(source, valueCoverage, new Long[]{Long.valueOf(2), null, Long.valueOf(2), null}); + checkCounts(source, addCoverage, new Long[]{null, Long.valueOf(1), null, null}); - final Node addNode = expr13rootNode.getChildren().iterator().next(); - final Probe probe = instrumenter.probe(addNode); + valueCoverage.setEnabled(false); + assertEquals(vm.eval(source).get(), 13); - // Probed but not tagged yet. - assertEquals(13, expr13rootNode.execute(null)); - assertTrue(tool.getCounts().isEmpty()); + checkCounts(source, valueCoverage, new Long[]{Long.valueOf(2), null, Long.valueOf(2), null}); + checkCounts(source, addCoverage, new Long[]{null, Long.valueOf(2), null, null}); - probe.tagAs(StandardSyntaxTag.STATEMENT, "fake statement for testing"); - - // Counting now; execute once - assertEquals(13, expr13rootNode.execute(null)); + valueCoverage.setEnabled(true); + assertEquals(vm.eval(source).get(), 13); - final Long[] longs1 = tool.getCounts().get(addNode.getSourceSection().getSource()); - assertNotNull(longs1); - assertEquals(longs1.length, 2); - assertNull(longs1[0]); // Line 1 is empty (text lines are 1-based) - assertEquals(1L, longs1[1].longValue()); // Expression is on line 2 + checkCounts(source, valueCoverage, new Long[]{Long.valueOf(3), null, Long.valueOf(3), null}); + checkCounts(source, addCoverage, new Long[]{null, Long.valueOf(3), null, null}); - // Execute 99 more times - for (int i = 0; i < 99; i++) { - assertEquals(13, expr13rootNode.execute(null)); - } + valueCoverage.dispose(); + assertEquals(vm.eval(source).get(), 13); - final Long[] longs100 = tool.getCounts().get(addNode.getSourceSection().getSource()); - assertNotNull(longs100); - assertEquals(longs100.length, 2); - assertNull(longs100[0]); - assertEquals(100L, longs100[1].longValue()); + checkCounts(source, addCoverage, new Long[]{null, Long.valueOf(4), null, null}); - tool.dispose(); + addCoverage.dispose(); } - } diff -r 69156ed8192b -r 964e789e17f7 truffle/com.oracle.truffle.tools.test/src/com/oracle/truffle/tools/test/LineToProbesMapTest.java --- a/truffle/com.oracle.truffle.tools.test/src/com/oracle/truffle/tools/test/LineToProbesMapTest.java Sat Sep 19 13:25:41 2015 -0700 +++ b/truffle/com.oracle.truffle.tools.test/src/com/oracle/truffle/tools/test/LineToProbesMapTest.java Sat Sep 19 13:26:06 2015 -0700 @@ -24,73 +24,97 @@ */ package com.oracle.truffle.tools.test; -import static com.oracle.truffle.tools.test.TestNodes.createExpr13TestRootNode; -import static com.oracle.truffle.tools.test.TestNodes.expr13Line1; -import static com.oracle.truffle.tools.test.TestNodes.expr13Line2; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.lang.reflect.Field; import org.junit.Test; import com.oracle.truffle.api.instrument.Instrumenter; import com.oracle.truffle.api.instrument.Probe; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.source.LineLocation; +import com.oracle.truffle.api.source.Source; +import com.oracle.truffle.api.vm.TruffleVM; import com.oracle.truffle.tools.LineToProbesMap; +import com.oracle.truffle.tools.test.ToolTestUtil.ToolTestTag; public class LineToProbesMapTest { @Test - public void testToolCreatedTooLate() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - final Instrumenter instrumenter = TestNodes.createInstrumenter(); - final RootNode expr13rootNode = createExpr13TestRootNode(instrumenter); - final Node addNode = expr13rootNode.getChildren().iterator().next(); - final Probe probe = instrumenter.probe(addNode); - final LineLocation lineLocation = probe.getProbedSourceSection().getLineLocation(); - assertEquals(lineLocation, expr13Line2); - - final LineToProbesMap tool = new LineToProbesMap(); - tool.install(instrumenter); - - assertNull(tool.findFirstProbe(expr13Line1)); - assertNull(tool.findFirstProbe(expr13Line2)); - tool.dispose(); + public void testNoExecution() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { + final TruffleVM vm = TruffleVM.newVM().build(); + final Field field = TruffleVM.class.getDeclaredField("instrumenter"); + field.setAccessible(true); + final Instrumenter instrumenter = (Instrumenter) field.get(vm); + final Source source = ToolTestUtil.createTestSource("testNoExecution"); + final LineToProbesMap probesMap = new LineToProbesMap(); + probesMap.install(instrumenter); + assertNull(probesMap.findFirstProbe(source.createLineLocation(1))); + assertNull(probesMap.findFirstProbe(source.createLineLocation(2))); + assertNull(probesMap.findFirstProbe(source.createLineLocation(3))); + probesMap.dispose(); } @Test - public void testToolInstalledTooLate() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - final Instrumenter instrumenter = TestNodes.createInstrumenter(); - final LineToProbesMap tool = new LineToProbesMap(); + public void testMapping1() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, IOException { + final TruffleVM vm = TruffleVM.newVM().build(); + final Field field = TruffleVM.class.getDeclaredField("instrumenter"); + field.setAccessible(true); + final Instrumenter instrumenter = (Instrumenter) field.get(vm); + final Source source = ToolTestUtil.createTestSource("testMapping1"); + final LineToProbesMap probesMap = new LineToProbesMap(); + + assertNull(probesMap.findFirstProbe(source.createLineLocation(1))); + assertNull(probesMap.findFirstProbe(source.createLineLocation(2))); + assertNull(probesMap.findFirstProbe(source.createLineLocation(3))); - final RootNode expr13rootNode = createExpr13TestRootNode(instrumenter); - final Node addNode = expr13rootNode.getChildren().iterator().next(); - final Probe probe = instrumenter.probe(addNode); - final LineLocation lineLocation = probe.getProbedSourceSection().getLineLocation(); - assertEquals(lineLocation, expr13Line2); + // Map installed before AST gets created + probesMap.install(instrumenter); + assertEquals(vm.eval(source).get(), 13); - tool.install(instrumenter); + final Probe probe1 = probesMap.findFirstProbe(source.createLineLocation(1)); + assertNotNull(probe1); + assertTrue(probe1.isTaggedAs(ToolTestTag.VALUE_TAG)); + final Probe probe2 = probesMap.findFirstProbe(source.createLineLocation(2)); + assertNotNull(probe2); + assertTrue(probe2.isTaggedAs(ToolTestTag.ADD_TAG)); + final Probe probe3 = probesMap.findFirstProbe(source.createLineLocation(3)); + assertNotNull(probe3); + assertTrue(probe3.isTaggedAs(ToolTestTag.VALUE_TAG)); - assertNull(tool.findFirstProbe(expr13Line1)); - assertNull(tool.findFirstProbe(expr13Line2)); - tool.dispose(); + probesMap.dispose(); } @Test - public void testMapping() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - final Instrumenter instrumenter = TestNodes.createInstrumenter(); - final LineToProbesMap tool = new LineToProbesMap(); - tool.install(instrumenter); + public void testMapping2() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, IOException { + final TruffleVM vm = TruffleVM.newVM().build(); + final Field field = TruffleVM.class.getDeclaredField("instrumenter"); + field.setAccessible(true); + final Instrumenter instrumenter = (Instrumenter) field.get(vm); + final Source source = ToolTestUtil.createTestSource("testMapping2"); + final LineToProbesMap probesMap = new LineToProbesMap(); + + assertNull(probesMap.findFirstProbe(source.createLineLocation(1))); + assertNull(probesMap.findFirstProbe(source.createLineLocation(2))); + assertNull(probesMap.findFirstProbe(source.createLineLocation(3))); - final RootNode expr13rootNode = createExpr13TestRootNode(instrumenter); - final Node addNode = expr13rootNode.getChildren().iterator().next(); - final Probe probe = instrumenter.probe(addNode); - final LineLocation lineLocation = probe.getProbedSourceSection().getLineLocation(); - assertEquals(lineLocation, expr13Line2); + // Map installed after AST gets created + assertEquals(vm.eval(source).get(), 13); + probesMap.install(instrumenter); - assertNull(tool.findFirstProbe(expr13Line1)); - assertEquals(tool.findFirstProbe(expr13Line2), probe); - tool.dispose(); + final Probe probe1 = probesMap.findFirstProbe(source.createLineLocation(1)); + assertNotNull(probe1); + assertTrue(probe1.isTaggedAs(ToolTestTag.VALUE_TAG)); + final Probe probe2 = probesMap.findFirstProbe(source.createLineLocation(2)); + assertNotNull(probe2); + assertTrue(probe2.isTaggedAs(ToolTestTag.ADD_TAG)); + final Probe probe3 = probesMap.findFirstProbe(source.createLineLocation(3)); + assertNotNull(probe3); + assertTrue(probe3.isTaggedAs(ToolTestTag.VALUE_TAG)); + + probesMap.dispose(); } - } diff -r 69156ed8192b -r 964e789e17f7 truffle/com.oracle.truffle.tools.test/src/com/oracle/truffle/tools/test/NodeExecCounterTest.java --- a/truffle/com.oracle.truffle.tools.test/src/com/oracle/truffle/tools/test/NodeExecCounterTest.java Sat Sep 19 13:25:41 2015 -0700 +++ b/truffle/com.oracle.truffle.tools.test/src/com/oracle/truffle/tools/test/NodeExecCounterTest.java Sat Sep 19 13:26:06 2015 -0700 @@ -24,30 +24,28 @@ */ package com.oracle.truffle.tools.test; -import static com.oracle.truffle.tools.test.TestNodes.createExpr13TestCallTarget; -import static com.oracle.truffle.tools.test.TestNodes.createExpr13TestRootNode; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; +import java.io.IOException; +import java.lang.reflect.Field; + import org.junit.Test; -import com.oracle.truffle.api.CallTarget; import com.oracle.truffle.api.instrument.Instrumenter; -import com.oracle.truffle.api.instrument.Probe; -import com.oracle.truffle.api.instrument.StandardSyntaxTag; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.RootNode; +import com.oracle.truffle.api.source.Source; +import com.oracle.truffle.api.vm.TruffleVM; import com.oracle.truffle.tools.NodeExecCounter; import com.oracle.truffle.tools.NodeExecCounter.NodeExecutionCount; -import com.oracle.truffle.tools.test.TestNodes.TestAddNode; -import com.oracle.truffle.tools.test.TestNodes.TestValueNode; public class NodeExecCounterTest { @Test public void testNoExecution() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - final Instrumenter instrumenter = TestNodes.createInstrumenter(); + final TruffleVM vm = TruffleVM.newVM().build(); + final Field field = TruffleVM.class.getDeclaredField("instrumenter"); + field.setAccessible(true); + final Instrumenter instrumenter = (Instrumenter) field.get(vm); final NodeExecCounter tool = new NodeExecCounter(); assertEquals(tool.getCounts().length, 0); tool.install(instrumenter); @@ -62,117 +60,45 @@ assertEquals(tool.getCounts().length, 0); } - @Test - public void testToolCreatedTooLate() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - final Instrumenter instrumenter = TestNodes.createInstrumenter(); - final CallTarget expr13callTarget = createExpr13TestCallTarget(instrumenter); - final NodeExecCounter tool = new NodeExecCounter(); - tool.install(instrumenter); - assertEquals(13, expr13callTarget.call()); - assertEquals(tool.getCounts().length, 0); - tool.dispose(); - } - - @Test - public void testToolInstalledcTooLate() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - final Instrumenter instrumenter = TestNodes.createInstrumenter(); - final NodeExecCounter tool = new NodeExecCounter(); - final CallTarget expr13callTarget = createExpr13TestCallTarget(instrumenter); - tool.install(instrumenter); - assertEquals(13, expr13callTarget.call()); - assertEquals(tool.getCounts().length, 0); - tool.dispose(); + void checkCounts(NodeExecCounter execTool, int addCount, int valueCount) { + NodeExecutionCount[] counts = execTool.getCounts(); + assertEquals(counts.length, 2); + for (NodeExecutionCount counter : counts) { + if (counter.nodeClass() == ToolTestUtil.TestAdditionNode.class) { + assertEquals(counter.executionCount(), addCount); + } else if (counter.nodeClass() == ToolTestUtil.TestValueNode.class) { + assertEquals(counter.executionCount(), valueCount); + } else { + fail("correct classes counted"); + } + } } @Test - public void testCountingAll() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - final Instrumenter instrumenter = TestNodes.createInstrumenter(); - final NodeExecCounter tool = new NodeExecCounter(); - tool.install(instrumenter); - final CallTarget expr13callTarget = createExpr13TestCallTarget(instrumenter); + public void testCounting() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, IOException { + final TruffleVM vm = TruffleVM.newVM().build(); + final Field field = TruffleVM.class.getDeclaredField("instrumenter"); + field.setAccessible(true); + final Instrumenter instrumenter = (Instrumenter) field.get(vm); + final Source source = ToolTestUtil.createTestSource("testCounting"); + final NodeExecCounter execTool = new NodeExecCounter(); + execTool.install(instrumenter); - // execute once - assertEquals(13, expr13callTarget.call()); - final NodeExecutionCount[] count1 = tool.getCounts(); - assertNotNull(count1); - assertEquals(count1.length, 2); - for (NodeExecutionCount count : count1) { - final Class class1 = count.nodeClass(); - final long executionCount = count.executionCount(); - if (class1 == TestAddNode.class) { - assertEquals(executionCount, 1); - } else if (class1 == TestValueNode.class) { - assertEquals(executionCount, 2); - } else { - fail(); - } - } + assertEquals(execTool.getCounts().length, 0); - // Execute 99 more times - for (int i = 0; i < 99; i++) { - assertEquals(13, expr13callTarget.call()); - } - final NodeExecutionCount[] counts100 = tool.getCounts(); - assertNotNull(counts100); - assertEquals(counts100.length, 2); - for (NodeExecutionCount count : counts100) { - final Class class1 = count.nodeClass(); - final long executionCount = count.executionCount(); - if (class1 == TestAddNode.class) { - assertEquals(executionCount, 100); - } else if (class1 == TestValueNode.class) { - assertEquals(executionCount, 200); - } else { - fail(); - } - } - - tool.dispose(); - } + assertEquals(vm.eval(source).get(), 13); - @Test - public void testCountingTagged() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - final Instrumenter instrumenter = TestNodes.createInstrumenter(); - final NodeExecCounter tool = new NodeExecCounter(StandardSyntaxTag.STATEMENT); - tool.install(instrumenter); - final RootNode expr13rootNode = createExpr13TestRootNode(instrumenter); - - // Not probed yet. - assertEquals(13, expr13rootNode.execute(null)); - assertEquals(tool.getCounts().length, 0); - - final Node addNode = expr13rootNode.getChildren().iterator().next(); - final Probe probe = instrumenter.probe(addNode); - - // Probed but not tagged yet. - assertEquals(13, expr13rootNode.execute(null)); - assertEquals(tool.getCounts().length, 0); - - probe.tagAs(StandardSyntaxTag.STATEMENT, "fake statement for testing"); + checkCounts(execTool, 1, 2); - // Counting now; execute once - assertEquals(13, expr13rootNode.execute(null)); - final NodeExecutionCount[] counts1 = tool.getCounts(); - assertNotNull(counts1); - assertEquals(counts1.length, 1); - final NodeExecutionCount count1 = counts1[0]; - assertNotNull(count1); - assertEquals(count1.nodeClass(), addNode.getClass()); - assertEquals(count1.executionCount(), 1); + for (int i = 0; i < 99; i++) { + assertEquals(vm.eval(source).get(), 13); + } + checkCounts(execTool, 100, 200); - // Execute 99 more times - for (int i = 0; i < 99; i++) { - assertEquals(13, expr13rootNode.execute(null)); - } + execTool.setEnabled(false); + assertEquals(vm.eval(source).get(), 13); + checkCounts(execTool, 100, 200); - final NodeExecutionCount[] counts100 = tool.getCounts(); - assertNotNull(counts100); - assertEquals(counts100.length, 1); - final NodeExecutionCount count100 = counts100[0]; - assertNotNull(count100); - assertEquals(count100.nodeClass(), addNode.getClass()); - assertEquals(count100.executionCount(), 100); - - tool.dispose(); + execTool.dispose(); } } diff -r 69156ed8192b -r 964e789e17f7 truffle/com.oracle.truffle.tools.test/src/com/oracle/truffle/tools/test/TestNodes.java --- a/truffle/com.oracle.truffle.tools.test/src/com/oracle/truffle/tools/test/TestNodes.java Sat Sep 19 13:25:41 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,254 +0,0 @@ -/* - * Copyright (c) 2014, 2015, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tools.test; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.TruffleLanguage; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.instrument.Instrumenter; -import com.oracle.truffle.api.instrument.KillException; -import com.oracle.truffle.api.instrument.Probe; -import com.oracle.truffle.api.instrument.ProbeNode; -import com.oracle.truffle.api.instrument.ProbeNode.WrapperNode; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.NodeCost; -import com.oracle.truffle.api.nodes.NodeInfo; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.source.LineLocation; -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.source.SourceSection; -import com.oracle.truffle.api.vm.TruffleVM; - -/** - * Nodes and an {@linkplain CallTarget executable ASTs} for testing. - */ -class TestNodes { - - /** - * A fake source used for testing: empty line 1, expression on line 2. - */ - public static final Source expr13Source = Source.fromText("\n6+7\n", "Test Source: expression on line 2 that evaluates to 13"); - public static final LineLocation expr13Line1 = expr13Source.createLineLocation(1); - public static final LineLocation expr13Line2 = expr13Source.createLineLocation(2); - - /** - * An executable addition expression that evaluates to 13. - */ - static CallTarget createExpr13TestCallTarget(Instrumenter instrumenter) { - final RootNode rootNode = createExpr13TestRootNode(instrumenter); - return Truffle.getRuntime().createCallTarget(rootNode); - } - - /** - * Root holding an addition expression that evaluates to 13. - */ - static RootNode createExpr13TestRootNode(Instrumenter instrumenter) { - final TestLanguageNode ast = createExpr13AST(); - final TestRootNode rootNode = new TestRootNode(ast, instrumenter); - rootNode.adoptChildren(); - return rootNode; - } - - static Instrumenter createInstrumenter() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - TruffleVM vm = TruffleVM.newVM().build(); - final Field field = TruffleVM.class.getDeclaredField("instrumenter"); - field.setAccessible(true); - final Instrumenter instrument = (Instrumenter) field.get(vm); - return instrument; - } - - /** - * Addition expression that evaluates to 13, with faked source attribution. - */ - static TestLanguageNode createExpr13AST() { - final SourceSection leftSourceSection = expr13Source.createSection("left", 1, 1); - final TestValueNode leftValueNode = new TestValueNode(6, leftSourceSection); - final SourceSection rightSourceSection = expr13Source.createSection("right", 3, 1); - final TestValueNode rightValueNode = new TestValueNode(7, rightSourceSection); - final SourceSection exprSourceSection = expr13Source.createSection("expr", 1, 3); - return new TestAddNode(leftValueNode, rightValueNode, exprSourceSection); - } - - abstract static class TestLanguageNode extends Node { - public abstract Object execute(VirtualFrame frame); - - public TestLanguageNode() { - } - - public TestLanguageNode(SourceSection srcSection) { - super(srcSection); - } - - @SuppressWarnings("deprecation") - @Override - public boolean isInstrumentable() { - return true; - } - - @SuppressWarnings("deprecation") - @Override - public WrapperNode createWrapperNode() { - return new TestWrapperNode(this); - } - } - - @NodeInfo(cost = NodeCost.NONE) - static class TestWrapperNode extends TestLanguageNode implements WrapperNode { - @Child private TestLanguageNode child; - @Child private ProbeNode probeNode; - - public TestWrapperNode(TestLanguageNode child) { - assert !(child instanceof TestWrapperNode); - this.child = child; - } - - @Override - public String instrumentationInfo() { - return "Wrapper node for testing"; - } - - @Override - public boolean isInstrumentable() { - return false; - } - - @Override - public void insertProbe(ProbeNode newProbeNode) { - this.probeNode = newProbeNode; - } - - @Override - public Probe getProbe() { - return probeNode.getProbe(); - } - - @Override - public Node getChild() { - return child; - } - - @Override - public Object execute(VirtualFrame frame) { - probeNode.enter(child, frame); - Object result; - - try { - result = child.execute(frame); - probeNode.returnValue(child, frame, result); - } catch (KillException e) { - throw (e); - } catch (Exception e) { - probeNode.returnExceptional(child, frame, e); - throw (e); - } - - return result; - } - } - - /** - * Truffle requires that all guest languages to have a {@link RootNode} which sits atop any AST - * of the guest language. This is necessary since creating a {@link CallTarget} is how Truffle - * completes an AST. The root nodes serves as our entry point into a program. - */ - static class TestRootNode extends RootNode { - @Child private TestLanguageNode body; - - private final Instrumenter instrumenter; - - /** - * This constructor emulates the global machinery that applies registered probers to every - * newly created AST. Global registry is not used, since that would interfere with other - * tests run in the same environment. - */ - public TestRootNode(TestLanguageNode body, Instrumenter instrumenter) { - super(TruffleLanguage.class, null, null); - this.instrumenter = instrumenter; - this.body = body; - } - - @Override - public Object execute(VirtualFrame frame) { - return body.execute(frame); - } - - @Override - public boolean isCloningAllowed() { - return true; - } - - @Override - public void applyInstrumentation() { - Method method; - try { - method = Instrumenter.class.getDeclaredMethod("applyInstrumentation", Node.class); - method.setAccessible(true); - method.invoke(instrumenter, body); - } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - throw new RuntimeException("TestNodes"); - } - } - } - - static class TestValueNode extends TestLanguageNode { - private final int value; - - public TestValueNode(int value) { - this.value = value; - } - - public TestValueNode(int value, SourceSection srcSection) { - super(srcSection); - this.value = value; - } - - @Override - public Object execute(VirtualFrame frame) { - return new Integer(this.value); - } - } - - static class TestAddNode extends TestLanguageNode { - @Child private TestLanguageNode leftChild; - @Child private TestLanguageNode rightChild; - - public TestAddNode(TestValueNode leftChild, TestValueNode rightChild, SourceSection sourceSection) { - super(sourceSection); - this.leftChild = insert(leftChild); - this.rightChild = insert(rightChild); - } - - @Override - public Object execute(VirtualFrame frame) { - return new Integer(((Integer) leftChild.execute(frame)).intValue() + ((Integer) rightChild.execute(frame)).intValue()); - } - } - -} diff -r 69156ed8192b -r 964e789e17f7 truffle/com.oracle.truffle.tools.test/src/com/oracle/truffle/tools/test/ToolTestUtil.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.tools.test/src/com/oracle/truffle/tools/test/ToolTestUtil.java Sat Sep 19 13:26:06 2015 -0700 @@ -0,0 +1,394 @@ +/* + * Copyright (c) 2015, 2015, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.tools.test; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.TruffleLanguage; +import com.oracle.truffle.api.TruffleRuntime; +import com.oracle.truffle.api.debug.DebugSupportProvider; +import com.oracle.truffle.api.frame.MaterializedFrame; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.instrument.ASTProber; +import com.oracle.truffle.api.instrument.AdvancedInstrumentResultListener; +import com.oracle.truffle.api.instrument.AdvancedInstrumentRootFactory; +import com.oracle.truffle.api.instrument.Instrumenter; +import com.oracle.truffle.api.instrument.KillException; +import com.oracle.truffle.api.instrument.Probe; +import com.oracle.truffle.api.instrument.ProbeNode; +import com.oracle.truffle.api.instrument.ProbeNode.WrapperNode; +import com.oracle.truffle.api.instrument.SyntaxTag; +import com.oracle.truffle.api.instrument.ToolSupportProvider; +import com.oracle.truffle.api.instrument.Visualizer; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.NodeCost; +import com.oracle.truffle.api.nodes.NodeInfo; +import com.oracle.truffle.api.nodes.NodeVisitor; +import com.oracle.truffle.api.nodes.RootNode; +import com.oracle.truffle.api.source.Source; +import com.oracle.truffle.api.source.SourceSection; + +public class ToolTestUtil { + + static final String MIME_TYPE = "text/x-toolTest"; + + static enum ToolTestTag implements SyntaxTag { + + ADD_TAG("addition", "test language addition node"), + + VALUE_TAG("value", "test language value node"); + + private final String name; + private final String description; + + private ToolTestTag(String name, String description) { + this.name = name; + this.description = description; + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + } + + static Source createTestSource(String description) { + return Source.fromText("6\n+\n7\n" + description, description).withMimeType(MIME_TYPE); + } + + @TruffleLanguage.Registration(name = "toolTestLanguage", version = "0", mimeType = MIME_TYPE) + public static final class ToolTestLang extends TruffleLanguage { + + public static final ToolTestLang INSTANCE = new ToolTestLang(); + + private final ASTProber prober = new TestASTProber(); + + private ToolTestLang() { + } + + @Override + protected CallTarget parse(Source source, Node context, String... argumentNames) throws IOException { + final TestValueNode leftValueNode = new TestValueNode(6, source.createSection("6", 0, 1)); + final TestValueNode rightValueNode = new TestValueNode(7, source.createSection("7", 4, 1)); + final TestAdditionNode addNode = new TestAdditionNode(leftValueNode, rightValueNode, source.createSection("+", 2, 1)); + final InstrumentationTestRootNode rootNode = new InstrumentationTestRootNode(addNode); + final TruffleRuntime runtime = Truffle.getRuntime(); + final CallTarget callTarget = runtime.createCallTarget(rootNode); + return callTarget; + } + + @Override + protected Object findExportedSymbol(Object context, String globalName, boolean onlyExplicit) { + return null; + } + + @Override + protected Object getLanguageGlobal(Object context) { + return null; + } + + @Override + protected boolean isObjectOfLanguage(Object object) { + return false; + } + + @Override + protected Visualizer getVisualizer() { + return null; + } + + @Override + protected ASTProber getDefaultASTProber() { + return prober; + } + + @Override + protected boolean isInstrumentable(Node node) { + return node instanceof TestAdditionNode || node instanceof TestValueNode; + } + + @Override + protected WrapperNode createWrapperNode(Node node) { + if (isInstrumentable(node)) { + return new ToolTestWrapperNode((ToolTestLangNode) node); + } + return null; + } + + @SuppressWarnings("deprecation") + @Override + protected void enableASTProbing(ASTProber astProber) { + throw new UnsupportedOperationException(); + } + + @Override + protected Object evalInContext(Source source, Node node, MaterializedFrame mFrame) throws IOException { + return null; + } + + @Override + protected AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(String expr, AdvancedInstrumentResultListener resultListener) throws IOException { + return null; + } + + @SuppressWarnings("deprecation") + @Override + protected ToolSupportProvider getToolSupport() { + throw new UnsupportedOperationException(); + } + + @SuppressWarnings("deprecation") + @Override + protected DebugSupportProvider getDebugSupport() { + throw new UnsupportedOperationException(); + } + + @Override + protected Object createContext(Env env) { + return null; + } + + } + + static final class TestASTProber implements ASTProber { + + public void probeAST(final Instrumenter instrumenter, Node startNode) { + startNode.accept(new NodeVisitor() { + + @Override + public boolean visit(Node node) { + if (node instanceof ToolTestLangNode) { + + final ToolTestLangNode testNode = (ToolTestLangNode) node; + + if (node instanceof TestValueNode) { + instrumenter.probe(testNode).tagAs(ToolTestTag.VALUE_TAG, null); + + } else if (node instanceof TestAdditionNode) { + instrumenter.probe(testNode).tagAs(ToolTestTag.ADD_TAG, null); + + } + } + return true; + } + }); + } + } + + abstract static class ToolTestLangNode extends Node { + public abstract Object execute(VirtualFrame vFrame); + + protected ToolTestLangNode(SourceSection ss) { + super(ss); + } + + @SuppressWarnings("deprecation") + @Override + public boolean isInstrumentable() { + throw new UnsupportedOperationException(); + } + + @SuppressWarnings("deprecation") + @Override + public WrapperNode createWrapperNode() { + throw new UnsupportedOperationException(); + } + } + + @NodeInfo(cost = NodeCost.NONE) + static class ToolTestWrapperNode extends ToolTestLangNode implements WrapperNode { + @Child private ToolTestLangNode child; + @Child private ProbeNode probeNode; + + public ToolTestWrapperNode(ToolTestLangNode child) { + super(null); + assert !(child instanceof ToolTestWrapperNode); + this.child = child; + } + + @Override + public String instrumentationInfo() { + return "Wrapper node for testing"; + } + + @Override + public boolean isInstrumentable() { + return false; + } + + @Override + public void insertProbe(ProbeNode newProbeNode) { + this.probeNode = newProbeNode; + } + + @Override + public Probe getProbe() { + return probeNode.getProbe(); + } + + @Override + public Node getChild() { + return child; + } + + @Override + public Object execute(VirtualFrame vFrame) { + probeNode.enter(child, vFrame); + Object result; + try { + result = child.execute(vFrame); + probeNode.returnValue(child, vFrame, result); + } catch (KillException e) { + throw (e); + } catch (Exception e) { + probeNode.returnExceptional(child, vFrame, e); + throw (e); + } + return result; + } + } + + /** + * A simple node for our test language to store a value. + */ + static class TestValueNode extends ToolTestLangNode { + private final int value; + + public TestValueNode(int value, SourceSection s) { + super(s); + this.value = value; + } + + @Override + public Object execute(VirtualFrame vFrame) { + return new Integer(this.value); + } + } + + /** + * A node for our test language that adds up two {@link TestValueNode}s. + */ + static class TestAdditionNode extends ToolTestLangNode { + @Child private ToolTestLangNode leftChild; + @Child private ToolTestLangNode rightChild; + + public TestAdditionNode(TestValueNode leftChild, TestValueNode rightChild, SourceSection s) { + super(s); + this.leftChild = insert(leftChild); + this.rightChild = insert(rightChild); + } + + @Override + public Object execute(VirtualFrame vFrame) { + return new Integer(((Integer) leftChild.execute(vFrame)).intValue() + ((Integer) rightChild.execute(vFrame)).intValue()); + } + } + + /** + * Truffle requires that all guest languages to have a {@link RootNode} which sits atop any AST + * of the guest language. This is necessary since creating a {@link CallTarget} is how Truffle + * completes an AST. The root nodes serves as our entry point into a program. + */ + static class InstrumentationTestRootNode extends RootNode { + @Child private ToolTestLangNode body; + + /** + * This constructor emulates the global machinery that applies registered probers to every + * newly created AST. Global registry is not used, since that would interfere with other + * tests run in the same environment. + */ + public InstrumentationTestRootNode(ToolTestLangNode body) { + super(ToolTestLang.class, null, null); + this.body = body; + } + + @Override + public Object execute(VirtualFrame vFrame) { + return body.execute(vFrame); + } + + @Override + public boolean isCloningAllowed() { + return true; + } + + @Override + public void applyInstrumentation() { + super.applyInstrumentation(body); + } + } + + /** + * Truffle requires that all guest languages to have a {@link RootNode} which sits atop any AST + * of the guest language. This is necessary since creating a {@link CallTarget} is how Truffle + * completes an AST. The root nodes serves as our entry point into a program. + */ + static class TestRootNode extends RootNode { + @Child private ToolTestLangNode body; + + final Instrumenter instrumenter; + + /** + * This constructor emulates the global machinery that applies registered probers to every + * newly created AST. Global registry is not used, since that would interfere with other + * tests run in the same environment. + */ + public TestRootNode(ToolTestLangNode body, Instrumenter instrumenter) { + super(ToolTestLang.class, null, null); + this.instrumenter = instrumenter; + this.body = body; + } + + @Override + public Object execute(VirtualFrame vFrame) { + return body.execute(vFrame); + } + + @Override + public boolean isCloningAllowed() { + return true; + } + + @Override + public void applyInstrumentation() { + Method method; + try { + method = Instrumenter.class.getDeclaredMethod("applyInstrumentation", Node.class); + method.setAccessible(true); + method.invoke(instrumenter, body); + } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + throw new RuntimeException("InstrumentationTestNodes"); + } + } + } + +} diff -r 69156ed8192b -r 964e789e17f7 truffle/com.oracle.truffle.tools.test/src/com/oracle/truffle/tools/test/ToolTestingLanguage.java --- a/truffle/com.oracle.truffle.tools.test/src/com/oracle/truffle/tools/test/ToolTestingLanguage.java Sat Sep 19 13:25:41 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,379 +0,0 @@ -/* - * Copyright (c) 2014, 2015, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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.tools.test; - -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.TruffleLanguage; -import com.oracle.truffle.api.TruffleRuntime; -import com.oracle.truffle.api.debug.DebugSupportProvider; -import com.oracle.truffle.api.frame.MaterializedFrame; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.instrument.ASTProber; -import com.oracle.truffle.api.instrument.AdvancedInstrumentResultListener; -import com.oracle.truffle.api.instrument.AdvancedInstrumentRootFactory; -import com.oracle.truffle.api.instrument.Instrumenter; -import com.oracle.truffle.api.instrument.KillException; -import com.oracle.truffle.api.instrument.Probe; -import com.oracle.truffle.api.instrument.ProbeNode; -import com.oracle.truffle.api.instrument.ProbeNode.WrapperNode; -import com.oracle.truffle.api.instrument.SyntaxTag; -import com.oracle.truffle.api.instrument.ToolSupportProvider; -import com.oracle.truffle.api.instrument.Visualizer; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.NodeCost; -import com.oracle.truffle.api.nodes.NodeInfo; -import com.oracle.truffle.api.nodes.NodeVisitor; -import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.source.Source; - -@TruffleLanguage.Registration(name = "toolTestLanguage", version = "0", mimeType = "text/x-toolTest") -public final class ToolTestingLanguage extends TruffleLanguage { - - public static final ToolTestingLanguage INSTANCE = new ToolTestingLanguage(); - - static final SyntaxTag ADD_TAG = new SyntaxTag() { - - @Override - public String name() { - return "Addition"; - } - - @Override - public String getDescription() { - return "Test Language Addition Node"; - } - }; - - static final SyntaxTag VALUE_TAG = new SyntaxTag() { - - @Override - public String name() { - return "Value"; - } - - @Override - public String getDescription() { - return "Test Language Value Node"; - } - }; - - private final ASTProber prober = new TestASTProber(); - - private ToolTestingLanguage() { - } - - @Override - protected CallTarget parse(Source code, Node context, String... argumentNames) throws IOException { - final TestValueNode leftValueNode = new TestValueNode(6); - final TestValueNode rightValueNode = new TestValueNode(7); - final TestAdditionNode addNode = new TestAdditionNode(leftValueNode, rightValueNode); - final InstrumentationTestRootNode rootNode = new InstrumentationTestRootNode(addNode); - final TruffleRuntime runtime = Truffle.getRuntime(); - final CallTarget callTarget = runtime.createCallTarget(rootNode); - return callTarget; - } - - @Override - protected Object findExportedSymbol(Object context, String globalName, boolean onlyExplicit) { - return null; - } - - @Override - protected Object getLanguageGlobal(Object context) { - return null; - } - - @Override - protected boolean isObjectOfLanguage(Object object) { - return false; - } - - @Override - protected Visualizer getVisualizer() { - return null; - } - - @Override - protected ASTProber getDefaultASTProber() { - return prober; - } - - @Override - protected boolean isInstrumentable(Node node) { - return node instanceof TestAdditionNode || node instanceof TestValueNode; - } - - @Override - protected WrapperNode createWrapperNode(Node node) { - if (isInstrumentable(node)) { - return new TestLanguageWrapperNode((TestLanguageNode) node); - } - return null; - } - - @SuppressWarnings("deprecation") - @Override - protected void enableASTProbing(ASTProber astProber) { - throw new UnsupportedOperationException(); - } - - @Override - protected Object evalInContext(Source source, Node node, MaterializedFrame mFrame) throws IOException { - return null; - } - - @Override - protected AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(String expr, AdvancedInstrumentResultListener resultListener) throws IOException { - return null; - } - - @SuppressWarnings("deprecation") - @Override - protected ToolSupportProvider getToolSupport() { - throw new UnsupportedOperationException(); - } - - @SuppressWarnings("deprecation") - @Override - protected DebugSupportProvider getDebugSupport() { - throw new UnsupportedOperationException(); - } - - @Override - protected Object createContext(Env env) { - return null; - } - - static final class TestASTProber implements ASTProber { - - public void probeAST(final Instrumenter instrumenter, Node startNode) { - startNode.accept(new NodeVisitor() { - - @Override - public boolean visit(Node node) { - if (node instanceof TestLanguageNode) { - - final TestLanguageNode testNode = (TestLanguageNode) node; - - if (node instanceof TestValueNode) { - instrumenter.probe(testNode).tagAs(VALUE_TAG, null); - - } else if (node instanceof TestAdditionNode) { - instrumenter.probe(testNode).tagAs(ADD_TAG, null); - - } - } - return true; - } - }); - } - } - - abstract static class TestLanguageNode extends Node { - public abstract Object execute(VirtualFrame vFrame); - - @SuppressWarnings("deprecation") - @Override - public boolean isInstrumentable() { - throw new UnsupportedOperationException(); - } - - @SuppressWarnings("deprecation") - @Override - public WrapperNode createWrapperNode() { - throw new UnsupportedOperationException(); - } - } - - @NodeInfo(cost = NodeCost.NONE) - static class TestLanguageWrapperNode extends TestLanguageNode implements WrapperNode { - @Child private TestLanguageNode child; - @Child private ProbeNode probeNode; - - public TestLanguageWrapperNode(TestLanguageNode child) { - assert !(child instanceof TestLanguageWrapperNode); - this.child = child; - } - - @Override - public String instrumentationInfo() { - return "Wrapper node for testing"; - } - - @Override - public boolean isInstrumentable() { - return false; - } - - @Override - public void insertProbe(ProbeNode newProbeNode) { - this.probeNode = newProbeNode; - } - - @Override - public Probe getProbe() { - return probeNode.getProbe(); - } - - @Override - public Node getChild() { - return child; - } - - @Override - public Object execute(VirtualFrame vFrame) { - probeNode.enter(child, vFrame); - Object result; - try { - result = child.execute(vFrame); - probeNode.returnValue(child, vFrame, result); - } catch (KillException e) { - throw (e); - } catch (Exception e) { - probeNode.returnExceptional(child, vFrame, e); - throw (e); - } - return result; - } - } - - /** - * A simple node for our test language to store a value. - */ - static class TestValueNode extends TestLanguageNode { - private final int value; - - public TestValueNode(int value) { - this.value = value; - } - - @Override - public Object execute(VirtualFrame vFrame) { - return new Integer(this.value); - } - } - - /** - * A node for our test language that adds up two {@link TestValueNode}s. - */ - static class TestAdditionNode extends TestLanguageNode { - @Child private TestLanguageNode leftChild; - @Child private TestLanguageNode rightChild; - - public TestAdditionNode(TestValueNode leftChild, TestValueNode rightChild) { - this.leftChild = insert(leftChild); - this.rightChild = insert(rightChild); - } - - @Override - public Object execute(VirtualFrame vFrame) { - return new Integer(((Integer) leftChild.execute(vFrame)).intValue() + ((Integer) rightChild.execute(vFrame)).intValue()); - } - } - - /** - * Truffle requires that all guest languages to have a {@link RootNode} which sits atop any AST - * of the guest language. This is necessary since creating a {@link CallTarget} is how Truffle - * completes an AST. The root nodes serves as our entry point into a program. - */ - static class InstrumentationTestRootNode extends RootNode { - @Child private TestLanguageNode body; - - /** - * This constructor emulates the global machinery that applies registered probers to every - * newly created AST. Global registry is not used, since that would interfere with other - * tests run in the same environment. - */ - public InstrumentationTestRootNode(TestLanguageNode body) { - super(ToolTestingLanguage.class, null, null); - this.body = body; - } - - @Override - public Object execute(VirtualFrame vFrame) { - return body.execute(vFrame); - } - - @Override - public boolean isCloningAllowed() { - return true; - } - - @Override - public void applyInstrumentation() { - super.applyInstrumentation(body); - } - } - - /** - * Truffle requires that all guest languages to have a {@link RootNode} which sits atop any AST - * of the guest language. This is necessary since creating a {@link CallTarget} is how Truffle - * completes an AST. The root nodes serves as our entry point into a program. - */ - static class TestRootNode extends RootNode { - @Child private TestLanguageNode body; - - final Instrumenter instrumenter; - - /** - * This constructor emulates the global machinery that applies registered probers to every - * newly created AST. Global registry is not used, since that would interfere with other - * tests run in the same environment. - */ - public TestRootNode(TestLanguageNode body, Instrumenter instrumenter) { - super(ToolTestingLanguage.class, null, null); - this.instrumenter = instrumenter; - this.body = body; - } - - @Override - public Object execute(VirtualFrame vFrame) { - return body.execute(vFrame); - } - - @Override - public boolean isCloningAllowed() { - return true; - } - - @Override - public void applyInstrumentation() { - Method method; - try { - method = Instrumenter.class.getDeclaredMethod("applyInstrumentation", Node.class); - method.setAccessible(true); - method.invoke(instrumenter, body); - } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - throw new RuntimeException("InstrumentationTestNodes"); - } - } - } - -} diff -r 69156ed8192b -r 964e789e17f7 truffle/com.oracle.truffle.tools.test/src/com/oracle/truffle/tools/test/TruffleToolTest.java --- a/truffle/com.oracle.truffle.tools.test/src/com/oracle/truffle/tools/test/TruffleToolTest.java Sat Sep 19 13:25:41 2015 -0700 +++ b/truffle/com.oracle.truffle.tools.test/src/com/oracle/truffle/tools/test/TruffleToolTest.java Sat Sep 19 13:26:06 2015 -0700 @@ -27,10 +27,13 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import java.lang.reflect.Field; + import org.junit.Test; import com.oracle.truffle.api.instrument.InstrumentationTool; import com.oracle.truffle.api.instrument.Instrumenter; +import com.oracle.truffle.api.vm.TruffleVM; /** * Test the basic life cycle properties shared by all instances of {@link InstrumentationTool}. @@ -39,7 +42,7 @@ @Test public void testEmptyLifeCycle() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - final Instrumenter instrumenter = TestNodes.createInstrumenter(); + final Instrumenter instrumenter = getInstrumenter(); final DummyTruffleTool tool = new DummyTruffleTool(); assertFalse(tool.isEnabled()); tool.install(instrumenter); @@ -78,7 +81,7 @@ @Test(expected = IllegalStateException.class) public void testAlreadyInstalled() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - final Instrumenter instrumenter = TestNodes.createInstrumenter(); + final Instrumenter instrumenter = getInstrumenter(); final DummyTruffleTool tool = new DummyTruffleTool(); tool.install(instrumenter); tool.install(instrumenter); @@ -86,7 +89,7 @@ @Test(expected = IllegalStateException.class) public void testAlreadyDisposed1() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - final Instrumenter instrumenter = TestNodes.createInstrumenter(); + final Instrumenter instrumenter = getInstrumenter(); final DummyTruffleTool tool = new DummyTruffleTool(); tool.install(instrumenter); tool.dispose(); @@ -95,7 +98,7 @@ @Test(expected = IllegalStateException.class) public void testAlreadyDisposed2() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - final Instrumenter instrumenter = TestNodes.createInstrumenter(); + final Instrumenter instrumenter = getInstrumenter(); final DummyTruffleTool tool = new DummyTruffleTool(); tool.install(instrumenter); tool.dispose(); @@ -104,7 +107,7 @@ @Test(expected = IllegalStateException.class) public void testAlreadyDisposed3() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - final Instrumenter instrumenter = TestNodes.createInstrumenter(); + final Instrumenter instrumenter = getInstrumenter(); final DummyTruffleTool tool = new DummyTruffleTool(); tool.install(instrumenter); tool.dispose(); @@ -113,13 +116,21 @@ @Test(expected = IllegalStateException.class) public void testAlreadyDisposed4() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - final Instrumenter instrumenter = TestNodes.createInstrumenter(); + final Instrumenter instrumenter = getInstrumenter(); final DummyTruffleTool tool = new DummyTruffleTool(); tool.install(instrumenter); tool.dispose(); tool.dispose(); } + private static Instrumenter getInstrumenter() throws NoSuchFieldException, IllegalAccessException { + final TruffleVM vm = TruffleVM.newVM().build(); + final Field field = TruffleVM.class.getDeclaredField("instrumenter"); + field.setAccessible(true); + final Instrumenter instrumenter = (Instrumenter) field.get(vm); + return instrumenter; + } + private static final class DummyTruffleTool extends InstrumentationTool { @Override