Mercurial > hg > graal-compiler
diff graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/TruffleRuntimeTest.java @ 16992:5a1d764f6afc
Truffle: added support for Runtime#getCallTargets()
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Thu, 28 Aug 2014 15:35:29 +0200 |
parents | 5e3d1a68664e |
children | 7b45e33b7986 |
line wrap: on
line diff
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/TruffleRuntimeTest.java Thu Aug 28 11:42:02 2014 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/TruffleRuntimeTest.java Thu Aug 28 15:35:29 2014 +0200 @@ -22,13 +22,20 @@ */ package com.oracle.truffle.api.test; +import static org.junit.Assert.*; + +import java.util.*; + import org.junit.*; import com.oracle.truffle.api.*; +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; /** * <h3>Accessing the Truffle Runtime</h3> - * + * * <p> * The Truffle runtime can be accessed at any point in time globally using the static method * {@link Truffle#getRuntime()}. This method is guaranteed to return a non-null Truffle runtime @@ -36,7 +43,7 @@ * default implementation of the {@link TruffleRuntime} interface with its own implementation for * providing improved performance. * </p> - * + * * <p> * The next part of the Truffle API introduction is at * {@link com.oracle.truffle.api.test.RootNodeTest}. @@ -44,10 +51,104 @@ */ public class TruffleRuntimeTest { + private TruffleRuntime runtime; + + @Before + public void setup() { + this.runtime = Truffle.getRuntime(); + } + + private static RootNode createTestRootNode() { + return new RootNode() { + @Override + public Object execute(VirtualFrame frame) { + return 42; + } + }; + } + @Test public void test() { - TruffleRuntime runtime = Truffle.getRuntime(); - Assert.assertNotNull(runtime); - Assert.assertNotNull(runtime.getName()); + assertNotNull(runtime); + assertNotNull(runtime.getName()); + } + + @Test + public void testCreateCallTarget() { + RootNode rootNode = createTestRootNode(); + RootCallTarget target = runtime.createCallTarget(rootNode); + assertNotNull(target); + assertEquals(target.call(), 42); + assertSame(rootNode, target.getRootNode()); + } + + @Test + public void testGetCallTargets1() { + RootNode rootNode = createTestRootNode(); + RootCallTarget target = runtime.createCallTarget(rootNode); + assertTrue(runtime.getCallTargets().indexOf(target) != -1); + } + + @Test + public void testGetCallTargets2() { + RootNode rootNode = createTestRootNode(); + RootCallTarget target1 = runtime.createCallTarget(rootNode); + RootCallTarget target2 = runtime.createCallTarget(rootNode); + assertTrue(runtime.getCallTargets().indexOf(target1) != -1); + assertTrue(runtime.getCallTargets().indexOf(target2) != -1); + } + + /* + * This test case documents the use case for profilers and debuggers where they need to access + * multiple call targets for the same source section. This case may happen when the optimization + * system decides to duplicate call targets to achieve better performance. + */ + @Test + public void testGetCallTargets3() { + Source source1 = Source.fromText("a\nb\n", ""); + SourceSection sourceSection1 = source1.createSection("foo", 1); + SourceSection sourceSection2 = source1.createSection("bar", 2); + + RootNode rootNode1 = createTestRootNode(); + rootNode1.assignSourceSection(sourceSection1); + RootNode rootNode2 = createTestRootNode(); + rootNode2.assignSourceSection(sourceSection2); + RootNode rootNode2Copy = NodeUtil.cloneNode(rootNode2); + + assertSame(rootNode2.getSourceSection(), rootNode2Copy.getSourceSection()); + + RootCallTarget target1 = runtime.createCallTarget(rootNode1); + RootCallTarget target2 = runtime.createCallTarget(rootNode2); + RootCallTarget target2Copy = runtime.createCallTarget(rootNode2Copy); + + Map<SourceSection, List<RootCallTarget>> groupedTargets = groupUniqueCallTargets(); + + List<RootCallTarget> targets1 = groupedTargets.get(sourceSection1); + assertEquals(1, targets1.size()); + assertEquals(target1, targets1.get(0)); + + List<RootCallTarget> targets2 = groupedTargets.get(sourceSection2); + assertEquals(2, targets2.size()); + // order of targets2 is not guaranteed + assertTrue(target2 == targets2.get(0) ^ target2Copy == targets2.get(0)); + assertTrue(target2 == targets2.get(1) ^ target2Copy == targets2.get(1)); + } + + private static Map<SourceSection, List<RootCallTarget>> groupUniqueCallTargets() { + Map<SourceSection, List<RootCallTarget>> groupedTargets = new HashMap<>(); + for (RootCallTarget target : Truffle.getRuntime().getCallTargets()) { + SourceSection section = target.getRootNode().getSourceSection(); + if (section == null) { + // can not identify root node to a unique call target. Print warning? + continue; + } + List<RootCallTarget> targets = groupedTargets.get(section); + if (targets == null) { + targets = new ArrayList<>(); + groupedTargets.put(section, targets); + } + targets.add(target); + } + return groupedTargets; } }