Mercurial > hg > truffle
changeset 17011:ccd8c2ef112e
Merge.
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Tue, 02 Sep 2014 10:30:28 +0200 |
parents | 0a036547149c (current diff) 004e3f0a0517 (diff) |
children | ad10671d1bbd |
files | |
diffstat | 22 files changed, 974 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Tue Sep 02 10:30:05 2014 +0200 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Tue Sep 02 10:30:28 2014 +0200 @@ -345,6 +345,17 @@ return false; } + public void waitForCompilation(OptimizedCallTarget optimizedCallTarget, long timeout) throws ExecutionException, TimeoutException { + Future<?> codeTask = this.compilations.get(optimizedCallTarget); + if (codeTask != null && isCompiling(optimizedCallTarget)) { + try { + codeTask.get(timeout, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + // ignore interrupted + } + } + } + public boolean isCompiling(OptimizedCallTarget optimizedCallTarget) { Future<?> codeTask = this.compilations.get(optimizedCallTarget); if (codeTask != null) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/sl/TestCompilationThreshold.sl Tue Sep 02 10:30:28 2014 +0200 @@ -0,0 +1,19 @@ +/* + * This test verifies the compilation threshold property. + */ +function test() { +} + +function main() { + /* TODO disableSplitting is required because otherwise it needs more calls to warm up. This still needs to be fixed. */ + disableSplitting(test); + threshold = getOption("TruffleCompilationThreshold"); + i = 0; + while (i < threshold -1) { + test(); + i = i + 1; + } + assertFalse(isOptimized(waitForOptimization(test))); + test(); // triggers compilation + assertTrue(isOptimized(waitForOptimization(test))); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/sl/TestInliningMaxCallerSize.sl Tue Sep 02 10:30:28 2014 +0200 @@ -0,0 +1,26 @@ +/* + * This test verifies that CallTargets cannot exceed the TruffleInliningMaxCallerSize limit when inlining. + */ +function inlinableFunction() { + generateDummyNodes(getOption("TruffleInliningMaxCallerSize") - 8); +} + +function notInlinableFunction() { + generateDummyNodes(getOption("TruffleInliningMaxCallerSize") - 7); +} + +function test1() { + inlinableFunction(); +} + +function test2() { + notInlinableFunction(); +} + +function main() { + waitForOptimization(callUntilOptimized(test1)); + assertTrue(isInlined(test1, inlinableFunction), "inlinableFunction is not inlined"); + + waitForOptimization(callUntilOptimized(test2)); + assertFalse(isInlined(test2, notInlinableFunction), "notInlinableFunction is inlined"); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/SLTruffleGraalTestSuite.java Tue Sep 02 10:30:28 2014 +0200 @@ -0,0 +1,59 @@ +/* + * 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.graal.truffle.test; + +import org.junit.*; +import org.junit.runner.*; + +import com.oracle.graal.truffle.test.builtins.*; +import com.oracle.truffle.sl.test.*; + +@RunWith(SLTestRunner.class) +@SLTestSuite({"graal/com.oracle.graal.truffle.test/sl", "sl"}) +public class SLTruffleGraalTestSuite { + + public static void main(String[] args) throws Exception { + SLTestRunner.runInMain(SLTruffleGraalTestSuite.class, args); + } + + @BeforeClass + public static void setupTestRunner() { + SLTestRunner.setRepeats(1); + SLTestRunner.installBuiltin(SLGetOptionBuiltinFactory.getInstance()); + SLTestRunner.installBuiltin(SLSetOptionBuiltinFactory.getInstance()); + SLTestRunner.installBuiltin(SLIsOptimizedBuiltinFactory.getInstance()); + SLTestRunner.installBuiltin(SLWaitForOptimizationBuiltinFactory.getInstance()); + SLTestRunner.installBuiltin(SLDisableSplittingBuiltinFactory.getInstance()); + SLTestRunner.installBuiltin(SLCallUntilOptimizedBuiltinFactory.getInstance()); + SLTestRunner.installBuiltin(SLIsInlinedBuiltinFactory.getInstance()); + SLTestRunner.installBuiltin(SLGenerateDummyNodesBuiltinFactory.getInstance()); + } + + /* + * Our "mx unittest" command looks for methods that are annotated with @Test. By just defining + * an empty method, this class gets included and the test suite is properly executed. + */ + @Test + public void unittest() { + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/builtins/SLCallUntilOptimizedBuiltin.java Tue Sep 02 10:30:28 2014 +0200 @@ -0,0 +1,59 @@ +/* + * 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.graal.truffle.test.builtins; + +import com.oracle.graal.truffle.*; +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.sl.runtime.*; + +/** + * Calls a given function until the Graal runtime decides to optimize the function. Use + * <code>waitForOptimization(function)</code> to wait until the runtime system has completed the + * possibly parallel optimization. + * + * @see SLWaitForOptimizationBuiltin + */ +@NodeInfo(shortName = "callUntilOptimized") +public abstract class SLCallUntilOptimizedBuiltin extends SLGraalRuntimeBuiltin { + + private static final int MAX_CALLS = 10000; + private static final Object[] EMPTY_ARGS = new Object[0]; + + @Child private IndirectCallNode indirectCall = Truffle.getRuntime().createIndirectCallNode(); + + @Specialization + public SLFunction callUntilCompiled(VirtualFrame frame, SLFunction function) { + OptimizedCallTarget oct = ((OptimizedCallTarget) function.getCallTarget()); + for (int i = 0; i < MAX_CALLS; i++) { + if (((GraalTruffleRuntime) Truffle.getRuntime()).isCompiling(oct) || oct.isValid()) { + break; + } else { + indirectCall.call(frame, oct, EMPTY_ARGS); + } + } + return function; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/builtins/SLDisableSplittingBuiltin.java Tue Sep 02 10:30:28 2014 +0200 @@ -0,0 +1,58 @@ +/* + * 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.graal.truffle.test.builtins; + +import com.oracle.graal.truffle.*; +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.CompilerDirectives.*; +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.sl.nodes.*; +import com.oracle.truffle.sl.runtime.*; + +/** + * Disables splitting for a given {@link SLFunction} instance. If no function is given the splitting + * will be disabled for the calling function. + */ +@NodeInfo(shortName = "disableSplitting") +public abstract class SLDisableSplittingBuiltin extends SLGraalRuntimeBuiltin { + + @Specialization + @SlowPath + public SLFunction disableSplitting(SLFunction function) { + OptimizedCallTarget target = (OptimizedCallTarget) function.getCallTarget(); + for (OptimizedCallTarget oct : findDuplicateCallTargets(target)) { + ((SLRootNode) oct.getRootNode()).setSplittable(false); + } + return function; + } + + @Specialization + @SlowPath + public SLNull disableSplitting(@SuppressWarnings("unused") SLNull argument) { + RootNode parentRoot = Truffle.getRuntime().getCallerFrame().getCallNode().getRootNode(); + ((SLRootNode) parentRoot).setSplittable(false); + return SLNull.SINGLETON; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/builtins/SLGenerateDummyNodesBuiltin.java Tue Sep 02 10:30:28 2014 +0200 @@ -0,0 +1,95 @@ +/* + * 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.graal.truffle.test.builtins; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.sl.nodes.*; +import com.oracle.truffle.sl.runtime.*; + +/** + * Generates a given number of dummy nodes and replaces the root of the current method with them. + * This builtin is guaranteed to be executed only once. + */ +@NodeInfo(shortName = "generateDummyNodes") +public abstract class SLGenerateDummyNodesBuiltin extends SLGraalRuntimeBuiltin { + + @Specialization + public Object generateNodes(long count) { + CompilerAsserts.neverPartOfCompilation("generateNodes should never get optimized."); + FrameInstance callerFrame = Truffle.getRuntime().getCallerFrame(); + SLRootNode root = (SLRootNode) callerFrame.getCallNode().getRootNode(); + root.getBodyNode().replace(createBinaryTree((int) (count - 1))); + return SLNull.SINGLETON; + } + + private SLDummyNode createBinaryTree(int nodeCount) { + if (nodeCount > 3) { + int leftSize = nodeCount / 2; + SLDummyNode left = createBinaryTree(leftSize); + SLDummyNode right = createBinaryTree(nodeCount - leftSize - 1); + return new SLDummyNode(left, right); + } else { + if (nodeCount <= 0) { + return null; + } + SLDummyNode left = null; + SLDummyNode right = null; + if (nodeCount > 1) { + left = new SLDummyNode(null, null); + if (nodeCount > 2) { + right = new SLDummyNode(null, null); + } + } + return new SLDummyNode(left, right); + } + } + + @NodeInfo(cost = NodeCost.MONOMORPHIC) + private static class SLDummyNode extends SLExpressionNode { + + @Child private SLDummyNode left; + @Child private SLDummyNode right; + + public SLDummyNode(SLDummyNode left, SLDummyNode right) { + super(null); + this.left = left; + this.right = right; + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + if (left != null) { + left.executeGeneric(frame); + } + if (right != null) { + right.executeGeneric(frame); + } + return null; + } + + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/builtins/SLGetOptionBuiltin.java Tue Sep 02 10:30:28 2014 +0200 @@ -0,0 +1,58 @@ +/* + * 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.graal.truffle.test.builtins; + +import com.oracle.graal.options.*; +import com.oracle.graal.truffle.*; +import com.oracle.truffle.api.CompilerDirectives.*; +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.nodes.*; + +/** + * Looks up the value of an option in {@link TruffleCompilerOptions}. In the future this builtin + * might be extend to lookup other options as well. + */ +@NodeInfo(shortName = "getOption") +public abstract class SLGetOptionBuiltin extends SLGraalRuntimeBuiltin { + + @Specialization + @SlowPath + public Object getOption(String name) { + TruffleCompilerOptions_Options options = new TruffleCompilerOptions_Options(); + for (OptionDescriptor option : options) { + if (option.getName().equals(name)) { + return convertValue(option.getOptionValue().getValue()); + } + } + return null; + } + + private static Object convertValue(Object value) { + // Improve this method as you need it. + if (value instanceof Integer) { + return (long) (int) value; + } + return value; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/builtins/SLGraalRuntimeBuiltin.java Tue Sep 02 10:30:28 2014 +0200 @@ -0,0 +1,95 @@ +/* + * 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.graal.truffle.test.builtins; + +import java.util.*; + +import com.oracle.graal.truffle.*; +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.CompilerDirectives.*; +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; +import com.oracle.truffle.sl.builtins.*; + +public abstract class SLGraalRuntimeBuiltin extends SLBuiltinNode { + + public SLGraalRuntimeBuiltin() { + super(null); + assignSourceSection(new NullSourceSection("SL Builtin", getClass().getAnnotation(NodeInfo.class).shortName())); + if (!(Truffle.getRuntime() instanceof GraalTruffleRuntime)) { + throw new AssertionError("Graal runtime builtins can only be used inside of a Graal runtime."); + } + } + + /** + * Finds all call targets available for the same original call target. This might be useful if a + * {@link CallTarget} got duplicated due to splitting. + */ + @SlowPath + protected static final Set<OptimizedCallTarget> findDuplicateCallTargets(OptimizedCallTarget originalCallTarget) { + final Set<OptimizedCallTarget> allCallTargets = new HashSet<>(); + allCallTargets.add(originalCallTarget); + for (RootCallTarget target : Truffle.getRuntime().getCallTargets()) { + if (target instanceof OptimizedCallTarget) { + OptimizedCallTarget oct = (OptimizedCallTarget) target; + if (oct.getSplitSource() == originalCallTarget) { + allCallTargets.add(oct); + } + } + } + return allCallTargets; + } + + /** + * Finds all {@link DirectCallNode} instances calling a certain original {@link CallTarget} in + * the caller function. + */ + @SlowPath + protected static final Set<DirectCallNode> findCallsTo(OptimizedCallTarget originalCallTarget) { + FrameInstance frame = Truffle.getRuntime().getCallerFrame(); + RootNode root = frame.getCallNode().getRootNode(); + return findCallsTo(root, originalCallTarget); + } + + /** + * Finds all {@link DirectCallNode} instances calling a certain original {@link CallTarget} in a + * given {@link RootNode}. + */ + @SlowPath + protected static final Set<DirectCallNode> findCallsTo(RootNode root, OptimizedCallTarget originalCallTarget) { + final Set<DirectCallNode> allCallNodes = new HashSet<>(); + root.accept(new NodeVisitor() { + public boolean visit(Node node) { + if (node instanceof DirectCallNode) { + DirectCallNode callNode = (DirectCallNode) node; + if (callNode.getCallTarget() == originalCallTarget || callNode.getSplitCallTarget() == originalCallTarget) { + allCallNodes.add(callNode); + } + } + return true; + } + }); + return allCallNodes; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/builtins/SLIsInlinedBuiltin.java Tue Sep 02 10:30:28 2014 +0200 @@ -0,0 +1,67 @@ +/* + * 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.graal.truffle.test.builtins; + +import java.util.*; + +import com.oracle.graal.truffle.*; +import com.oracle.truffle.api.CompilerDirectives.SlowPath; +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.sl.runtime.*; + +/** + * Returns <code>true</code> if a function got inlined for all calls from a given {@link SLFunction} + * . If no direct calls to the given {@link SLFunction} could be resolved or the call got inlined + * for some callsites and for some not then an {@link AssertionError} is thrown. + */ +@NodeInfo(shortName = "isInlined") +public abstract class SLIsInlinedBuiltin extends SLGraalRuntimeBuiltin { + + @Specialization + @SlowPath + public Object isInlined(SLFunction parent, SLFunction inlinedFunction) { + boolean allFalse = true; + boolean allTrue = true; + for (OptimizedCallTarget parentTarget : findDuplicateCallTargets((OptimizedCallTarget) parent.getCallTarget())) { + Set<DirectCallNode> callNodes = findCallsTo(parentTarget.getRootNode(), (OptimizedCallTarget) inlinedFunction.getCallTarget()); + for (DirectCallNode directCall : callNodes) { + if (directCall.isInlined()) { + allFalse = false; + } else { + allTrue = false; + } + } + } + if (allFalse && allTrue) { + throw new AssertionError(String.format("No calls found from %s to %s .", parent, inlinedFunction)); + } else if (!allFalse && !allTrue) { + throw new AssertionError(String.format("Some calls from %s to %s are inlined and some are not.", parent, inlinedFunction)); + } + if (allTrue) { + return true; + } else { + return false; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/builtins/SLIsOptimizedBuiltin.java Tue Sep 02 10:30:28 2014 +0200 @@ -0,0 +1,48 @@ +/* + * 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.graal.truffle.test.builtins; + +import com.oracle.graal.truffle.*; +import com.oracle.truffle.api.CompilerDirectives.SlowPath; +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.sl.runtime.*; + +/** + * Checks whether or not a function is optimized by the Graal runtime. + */ +@NodeInfo(shortName = "isOptimized") +public abstract class SLIsOptimizedBuiltin extends SLGraalRuntimeBuiltin { + + @Specialization + @SlowPath + public boolean isOptimized(SLFunction function) { + OptimizedCallTarget target = (OptimizedCallTarget) function.getCallTarget(); + for (OptimizedCallTarget foundTarget : findDuplicateCallTargets(target)) { + if (foundTarget.isValid()) { + return true; + } + } + return false; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/builtins/SLSetOptionBuiltin.java Tue Sep 02 10:30:28 2014 +0200 @@ -0,0 +1,61 @@ +/* + * 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.graal.truffle.test.builtins; + +import com.oracle.graal.options.*; +import com.oracle.graal.truffle.*; +import com.oracle.truffle.api.CompilerDirectives.SlowPath; +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.nodes.*; + +/** + * Sets an option value in {@link TruffleCompilerOptions}. In the future this builtin might be + * extend to lookup other options as well. + */ +@NodeInfo(shortName = "setOption") +public abstract class SLSetOptionBuiltin extends SLGraalRuntimeBuiltin { + + @Specialization + @SlowPath + public Object setOption(String name, Object value) { + TruffleCompilerOptions_Options options = new TruffleCompilerOptions_Options(); + for (OptionDescriptor option : options) { + if (option.getName().equals(name)) { + option.getOptionValue().setValue(convertValue(value)); + } + } + return value; + } + + private static Object convertValue(Object value) { + // Improve this method as you need it. + if (value instanceof Long) { + long longValue = (long) value; + if (longValue == (int) longValue) { + return (int) longValue; + } + } + return value; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/builtins/SLWaitForOptimizationBuiltin.java Tue Sep 02 10:30:28 2014 +0200 @@ -0,0 +1,60 @@ +/* + * 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.graal.truffle.test.builtins; + +import java.util.concurrent.*; + +import com.oracle.graal.truffle.*; +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.sl.runtime.*; + +/** + * Waits for the optimization of a function to complete if it was already triggered. If no + * optimization was triggered then this builtin does nothing. + */ +@NodeInfo(shortName = "waitForOptimization") +public abstract class SLWaitForOptimizationBuiltin extends SLGraalRuntimeBuiltin { + + @Specialization + public SLFunction waitForOptimization(SLFunction function, long timeout) { + OptimizedCallTarget target = (OptimizedCallTarget) function.getCallTarget(); + GraalTruffleRuntime runtime = ((GraalTruffleRuntime) Truffle.getRuntime()); + + for (OptimizedCallTarget effectiveCallTarget : findDuplicateCallTargets(target)) { + try { + runtime.waitForCompilation(effectiveCallTarget, timeout); + } catch (ExecutionException | TimeoutException e) { + throw new RuntimeException(e); + } + } + return function; + } + + @Specialization + public SLFunction waitForCompilation(SLFunction function, @SuppressWarnings("unused") SLNull timeout) { + return waitForOptimization(function, 120000); + } + +}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java Tue Sep 02 10:30:05 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java Tue Sep 02 10:30:28 2014 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.truffle; +import java.util.concurrent.*; + import com.oracle.graal.nodes.spi.*; import com.oracle.truffle.api.*; @@ -33,6 +35,8 @@ boolean cancelInstalledTask(OptimizedCallTarget optimizedCallTarget); + void waitForCompilation(OptimizedCallTarget optimizedCallTarget, long timeout) throws ExecutionException, TimeoutException; + boolean isCompiling(OptimizedCallTarget optimizedCallTarget); void invalidateInstalledCode(OptimizedCallTarget optimizedCallTarget);
--- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java Tue Sep 02 10:30:05 2014 +0200 +++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java Tue Sep 02 10:30:28 2014 +0200 @@ -36,14 +36,16 @@ import org.junit.runners.*; import org.junit.runners.model.*; +import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.source.*; import com.oracle.truffle.sl.*; +import com.oracle.truffle.sl.builtins.*; import com.oracle.truffle.sl.runtime.*; import com.oracle.truffle.sl.test.SLTestRunner.TestCase; public final class SLTestRunner extends ParentRunner<TestCase> { - private static final int REPEATS = 10; + private static int repeats = 1; private static final String SOURCE_SUFFIX = ".sl"; private static final String INPUT_SUFFIX = ".input"; @@ -147,6 +149,16 @@ return outFile.toString(); } + public static void setRepeats(int repeats) { + SLTestRunner.repeats = repeats; + } + + private static final List<NodeFactory<? extends SLBuiltinNode>> builtins = new ArrayList<>(); + + public static void installBuiltin(NodeFactory<? extends SLBuiltinNode> builtin) { + builtins.add(builtin); + } + @Override protected void runChild(TestCase testCase, RunNotifier notifier) { notifier.fireTestStarted(testCase.name); @@ -154,12 +166,15 @@ ByteArrayOutputStream out = new ByteArrayOutputStream(); PrintStream printer = new PrintStream(out); try { - SLContext context = new SLContext(new BufferedReader(new StringReader(repeat(testCase.testInput, REPEATS))), printer); + SLContext context = new SLContext(new BufferedReader(new StringReader(repeat(testCase.testInput, repeats))), printer); + for (NodeFactory<? extends SLBuiltinNode> builtin : builtins) { + context.installBuiltin(builtin); + } final Source source = Source.fromText(readAllLines(testCase.path), testCase.sourceName); - SLMain.run(context, source, null, REPEATS); + SLMain.run(context, source, null, repeats); String actualOutput = new String(out.toByteArray()); - Assert.assertEquals(repeat(testCase.expectedOutput, REPEATS), actualOutput); + Assert.assertEquals(repeat(testCase.expectedOutput, repeats), actualOutput); } catch (Throwable ex) { notifier.fireTestFailure(new Failure(testCase.name, ex)); } finally {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLAssertionError.java Tue Sep 02 10:30:28 2014 +0200 @@ -0,0 +1,42 @@ +/* + * 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.sl; + +/** + * An implementation of an {@link AssertionError} also containing the guest language stack trace. + */ +public class SLAssertionError extends AssertionError { + + private static final long serialVersionUID = -9138475336963945873L; + + public SLAssertionError(String message) { + super(message); + initCause(new AssertionError("Java stack trace")); + } + + @Override + public synchronized Throwable fillInStackTrace() { + return SLException.fillInSLStackTrace(this); + } + +} \ No newline at end of file
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLException.java Tue Sep 02 10:30:05 2014 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLException.java Tue Sep 02 10:30:28 2014 +0200 @@ -22,15 +22,74 @@ */ package com.oracle.truffle.sl; +import java.util.*; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; +import com.oracle.truffle.sl.nodes.*; + /** * SL does not need a sophisticated error checking and reporting mechanism, so all unexpected * conditions just abort execution. This exception class is used when we abort from within the SL * implementation. */ public class SLException extends RuntimeException { + private static final long serialVersionUID = -6799734410727348507L; public SLException(String message) { super(message); + initCause(new Throwable("Java stack trace")); + } + + @Override + public synchronized Throwable fillInStackTrace() { + return fillInSLStackTrace(this); + } + + /** + * Uses the Truffle API to iterate the stack frames and to create and set Java + * {@link StackTraceElement} elements based on the source sections of the call nodes on the + * stack. + */ + static Throwable fillInSLStackTrace(Throwable t) { + final List<StackTraceElement> stackTrace = new ArrayList<>(); + Truffle.getRuntime().iterateFrames(new FrameInstanceVisitor<Void>() { + public Void visitFrame(FrameInstance frame) { + Node callNode = frame.getCallNode(); + if (callNode == null) { + return null; + } + RootNode root = callNode.getRootNode(); + + /* + * There should be no RootNodes other than SLRootNodes on the stack. Just for the + * case if this would change. + */ + String methodName = "$unknownFunction"; + if (root instanceof SLRootNode) { + methodName = ((SLRootNode) root).getName(); + } + + SourceSection sourceSection = callNode.getEncapsulatingSourceSection(); + Source source = sourceSection != null ? sourceSection.getSource() : null; + String sourceName = source != null ? source.getName() : null; + int lineNumber; + try { + lineNumber = sourceSection != null ? sourceSection.getLineLocation().getLineNumber() : -1; + } catch (UnsupportedOperationException e) { + /* + * SourceSection#getLineLocation() may throw an UnsupportedOperationException. + */ + lineNumber = -1; + } + stackTrace.add(new StackTraceElement("SL", methodName, sourceName, lineNumber)); + return null; + } + }); + t.setStackTrace(stackTrace.toArray(new StackTraceElement[stackTrace.size()])); + return t; } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLAssertFalseBuiltin.java Tue Sep 02 10:30:28 2014 +0200 @@ -0,0 +1,57 @@ +/* + * 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.sl.builtins; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; +import com.oracle.truffle.sl.*; +import com.oracle.truffle.sl.runtime.*; + +/** + * Asserts a given value to be <code>false</code> and throws an {@link AssertionError} if the value + * was <code>true</code>. + */ +@NodeInfo(shortName = "assertFalse") +public abstract class SLAssertFalseBuiltin extends SLBuiltinNode { + + public SLAssertFalseBuiltin() { + super(new NullSourceSection("SL builtin", "assertFalse")); + } + + @Specialization + public boolean doAssert(boolean value, String message) { + if (value) { + CompilerDirectives.transferToInterpreter(); + throw new SLAssertionError(message == null ? "" : message); + } + return value; + } + + @Specialization + public boolean doAssertNull(boolean value, @SuppressWarnings("unused") SLNull message) { + return doAssert(value, null); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLAssertTrueBuiltin.java Tue Sep 02 10:30:28 2014 +0200 @@ -0,0 +1,57 @@ +/* + * 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.sl.builtins; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; +import com.oracle.truffle.sl.*; +import com.oracle.truffle.sl.runtime.*; + +/** + * Asserts a given value to be <code>true</code> and throws an {@link AssertionError} if the value + * was <code>false</code>. + */ +@NodeInfo(shortName = "assertTrue") +public abstract class SLAssertTrueBuiltin extends SLBuiltinNode { + + public SLAssertTrueBuiltin() { + super(new NullSourceSection("SL builtin", "assertTrue")); + } + + @Specialization + public boolean doAssert(boolean value, String message) { + if (!value) { + CompilerDirectives.transferToInterpreter(); + throw new SLAssertionError(message == null ? "" : message); + } + return value; + } + + @Specialization + public boolean doAssertNull(boolean value, @SuppressWarnings("unused") SLNull message) { + return doAssert(value, null); + } + +}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLRootNode.java Tue Sep 02 10:30:05 2014 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLRootNode.java Tue Sep 02 10:30:28 2014 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.truffle.sl.nodes; +import com.oracle.truffle.api.CompilerDirectives.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; import com.oracle.truffle.sl.builtins.*; @@ -53,6 +54,8 @@ /** The Simple execution context for this tree **/ private final SLContext context; + @CompilationFinal private boolean isSplittable; + public SLRootNode(SLContext context, FrameDescriptor frameDescriptor, SLExpressionNode bodyNode, String name) { super(null, frameDescriptor); /* Deep copy the body before any specialization occurs during execution. */ @@ -67,9 +70,21 @@ return bodyNode.executeGeneric(frame); } + public String getName() { + return name; + } + + public void setSplittable(boolean isSplittable) { + this.isSplittable = isSplittable; + } + + public SLExpressionNode getBodyNode() { + return bodyNode; + } + @Override public boolean isSplittable() { - return true; + return isSplittable; } @Override
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java Tue Sep 02 10:30:05 2014 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java Tue Sep 02 10:30:28 2014 +0200 @@ -109,9 +109,11 @@ installBuiltin(SLDefineFunctionBuiltinFactory.getInstance()); installBuiltin(SLStackTraceBuiltinFactory.getInstance()); installBuiltin(SLHelloEqualsWorldBuiltinFactory.getInstance()); + installBuiltin(SLAssertTrueBuiltinFactory.getInstance()); + installBuiltin(SLAssertFalseBuiltinFactory.getInstance()); } - private void installBuiltin(NodeFactory<? extends SLBuiltinNode> factory) { + public void installBuiltin(NodeFactory<? extends SLBuiltinNode> factory) { /* * The builtin node factory is a class that is automatically generated by the Truffle DSL. * The signature returned by the factory reflects the signature of the @Specialization
--- a/mx/projects Tue Sep 02 10:30:05 2014 +0200 +++ b/mx/projects Tue Sep 02 10:30:28 2014 +0200 @@ -843,7 +843,7 @@ # graal.truffle.test project@com.oracle.graal.truffle.test@subDir=graal project@com.oracle.graal.truffle.test@sourceDirs=src -project@com.oracle.graal.truffle.test@dependencies=com.oracle.graal.truffle,com.oracle.graal.compiler.test +project@com.oracle.graal.truffle.test@dependencies=com.oracle.graal.truffle,com.oracle.graal.compiler.test,com.oracle.truffle.sl.test project@com.oracle.graal.truffle.test@checkstyle=com.oracle.graal.graph project@com.oracle.graal.truffle.test@javaCompliance=1.8 project@com.oracle.graal.truffle.test@workingSets=Graal,Truffle,Test