Mercurial > hg > graal-compiler
changeset 19717:e5028947ea79
Merge.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Sun, 08 Mar 2015 21:58:48 +0100 |
parents | 2fd45bb25118 (current diff) 48eeda5dfdbf (diff) |
children | 69369fd52245 |
files | graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java |
diffstat | 11 files changed, 266 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Sun Mar 08 21:58:34 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Sun Mar 08 21:58:48 2015 +0100 @@ -190,7 +190,6 @@ if (singleImplementor != null && !singleImplementor.equals(declaredReceiverType)) { ResolvedJavaMethod singleImplementorMethod = singleImplementor.resolveMethod(targetMethod(), invoke().getContextType(), true); if (singleImplementorMethod != null) { - assert graph().getGuardsStage().allowsFloatingGuards() : "Graph already fixed!"; /** * We have an invoke on an interface with a single implementor. We can replace this * with an invoke virtual. @@ -203,9 +202,8 @@ * properties by checking of the receiver is an instance of the single implementor. */ LogicNode condition = graph().unique(new InstanceOfNode(singleImplementor, receiver, getProfile())); - GuardNode guard = graph().unique( - new GuardNode(condition, AbstractBeginNode.prevBegin(invoke().asNode()), DeoptimizationReason.OptimizedTypeCheckViolated, DeoptimizationAction.InvalidateRecompile, - false, JavaConstant.NULL_POINTER)); + FixedGuardNode guard = graph().add(new FixedGuardNode(condition, DeoptimizationReason.OptimizedTypeCheckViolated, DeoptimizationAction.InvalidateRecompile, false)); + graph().addBeforeFixed(invoke().asNode(), guard); PiNode piNode = graph().unique(new PiNode(receiver, StampFactory.declaredNonNull(singleImplementor), guard)); arguments().set(0, piNode); setInvokeKind(InvokeKind.Virtual);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Sun Mar 08 21:58:34 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Sun Mar 08 21:58:48 2015 +0100 @@ -787,6 +787,7 @@ if (replacementAnchor == null) { replacementAnchor = AbstractBeginNode.prevBegin(checkCast); } + assert !(replacementAnchor instanceof FloatingNode) : "unsafe to mix unlowered Checkcast with floating guards"; PiNode piNode; if (isNull) { ConstantNode nullObject = ConstantNode.defaultForKind(Kind.Object, graph);
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Sun Mar 08 21:58:34 2015 +0100 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Sun Mar 08 21:58:48 2015 +0100 @@ -137,6 +137,7 @@ compilationPolicy = new InterpreterOnlyCompilationPolicy(); } OptimizedCallTarget target = new OptimizedCallTarget(source, rootNode, this, compilationPolicy, new HotSpotSpeculationLog()); + rootNode.setCallTarget(target); callTargets.put(target, null); return target;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Sun Mar 08 21:58:34 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Sun Mar 08 21:58:48 2015 +0100 @@ -91,7 +91,6 @@ this.compilationPolicy = compilationPolicy; this.rootNode.adoptChildren(); this.rootNode.applyInstrumentation(); - this.rootNode.setCallTarget(this); this.uninitializedRootNode = sourceCallTarget == null ? cloneRootNode(rootNode) : sourceCallTarget.uninitializedRootNode; if (TruffleCallTargetProfiling.getValue()) { this.compilationProfile = new TraceCompilationProfile();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/MergeSpecializationsTest.java Sun Mar 08 21:58:48 2015 +0100 @@ -0,0 +1,224 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.api.dsl.test; + +import static com.oracle.truffle.api.dsl.test.TestHelper.*; +import static org.junit.Assert.*; + +import java.util.*; +import java.util.concurrent.*; + +import org.junit.*; + +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.dsl.internal.*; +import com.oracle.truffle.api.dsl.test.MergeSpecializationsTestFactory.TestCachedNodeFactory; +import com.oracle.truffle.api.dsl.test.MergeSpecializationsTestFactory.TestNodeFactory; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; +import com.oracle.truffle.api.nodes.*; + +public class MergeSpecializationsTest { + + private static final int THREADS = 8; + + @NodeChild + @SuppressWarnings("unused") + abstract static class TestNode extends ValueNode { + + @Specialization + int s1(int a) { + return 1; + } + + @Specialization + int s2(long a) { + return 2; + } + + @Specialization + int s3(double a) { + return 3; + } + } + + @NodeChild + @SuppressWarnings("unused") + abstract static class TestCachedNode extends ValueNode { + + @Specialization(guards = "a == cachedA", limit = "3") + int s1(int a, @Cached("a") int cachedA) { + return 1; + } + + @Specialization + int s2(long a) { + return 2; + } + + @Specialization + int s3(double a) { + return 3; + } + } + + @Test + public void testMultithreadedMergeInOrder() { + multithreadedMerge(TestNodeFactory.getInstance(), new Executions(1, 1L << 32, 1.0), 1, 2, 3); + } + + @Test + public void testMultithreadedMergeReverse() { + multithreadedMerge(TestNodeFactory.getInstance(), new Executions(1.0, 1L << 32, 1), 3, 2, 1); + } + + @Ignore + @Test + public void testMultithreadedMergeCachedInOrder() { + multithreadedMerge(TestCachedNodeFactory.getInstance(), new Executions(1, 1L << 32, 1.0), 1, 2, 3); + } + + @Ignore + @Test + public void testMultithreadedMergeCachedTwoEntries() { + multithreadedMerge(TestCachedNodeFactory.getInstance(), new Executions(1, 2, 1.0), 1, 1, 3); + } + + @Ignore + @Test + public void testMultithreadedMergeCachedThreeEntries() { + multithreadedMerge(TestCachedNodeFactory.getInstance(), new Executions(1, 2, 3), 1, 1, 1); + } + + private static <T extends ValueNode> void multithreadedMerge(NodeFactory<T> factory, final Executions executions, int... order) { + assertEquals(3, order.length); + final TestRootNode<T> node = createRoot(factory); + + final CountDownLatch threadsStarted = new CountDownLatch(THREADS); + + final CountDownLatch beforeFirst = new CountDownLatch(1); + final CountDownLatch executedFirst = new CountDownLatch(THREADS); + + final CountDownLatch beforeSecond = new CountDownLatch(1); + final CountDownLatch executedSecond = new CountDownLatch(THREADS); + + final CountDownLatch beforeThird = new CountDownLatch(1); + final CountDownLatch executedThird = new CountDownLatch(THREADS); + + Thread[] threads = new Thread[THREADS]; + for (int i = 0; i < threads.length; i++) { + threads[i] = new Thread(new Runnable() { + public void run() { + threadsStarted.countDown(); + + MergeSpecializationsTest.await(beforeFirst); + executeWith(node, executions.firstValue); + executedFirst.countDown(); + + MergeSpecializationsTest.await(beforeSecond); + executeWith(node, executions.secondValue); + executedSecond.countDown(); + + MergeSpecializationsTest.await(beforeThird); + executeWith(node, executions.thirdValue); + executedThird.countDown(); + } + }); + threads[i].start(); + } + + final SpecializedNode gen = (SpecializedNode) node.getNode(); + + final SpecializationNode start0 = gen.getSpecializationNode(); + assertEquals("UninitializedNode_", start0.getClass().getSimpleName()); + + await(threadsStarted); + beforeFirst.countDown(); + await(executedFirst); + + final SpecializationNode start1 = gen.getSpecializationNode(); + assertEquals("S" + order[0] + "Node_", start1.getClass().getSimpleName()); + assertEquals("UninitializedNode_", nthChild(1, start1).getClass().getSimpleName()); + + beforeSecond.countDown(); + await(executedSecond); + + final SpecializationNode start2 = gen.getSpecializationNode(); + Arrays.sort(order, 0, 2); + assertEquals("PolymorphicNode_", start2.getClass().getSimpleName()); + assertEquals("S" + order[0] + "Node_", nthChild(1, start2).getClass().getSimpleName()); + assertEquals("S" + order[1] + "Node_", nthChild(2, start2).getClass().getSimpleName()); + assertEquals("UninitializedNode_", nthChild(3, start2).getClass().getSimpleName()); + + beforeThird.countDown(); + await(executedThird); + + final SpecializationNode start3 = gen.getSpecializationNode(); + Arrays.sort(order); + assertEquals("PolymorphicNode_", start3.getClass().getSimpleName()); + assertEquals("S" + order[0] + "Node_", nthChild(1, start3).getClass().getSimpleName()); + assertEquals("S" + order[1] + "Node_", nthChild(2, start3).getClass().getSimpleName()); + assertEquals("S" + order[2] + "Node_", nthChild(3, start3).getClass().getSimpleName()); + assertEquals("UninitializedNode_", nthChild(4, start3).getClass().getSimpleName()); + + for (Thread thread : threads) { + try { + thread.join(); + } catch (InterruptedException e) { + fail("interrupted"); + } + } + } + + private static class Executions { + public final Object firstValue; + public final Object secondValue; + public final Object thirdValue; + + public Executions(Object firstValue, Object secondValue, Object thirdValue) { + this.firstValue = firstValue; + this.secondValue = secondValue; + this.thirdValue = thirdValue; + } + } + + private static void await(final CountDownLatch latch) { + try { + latch.await(); + } catch (InterruptedException e) { + fail("interrupted"); + } + } + + private static Node firstChild(Node node) { + return node.getChildren().iterator().next(); + } + + private static Node nthChild(int n, Node node) { + if (n == 0) { + return node; + } else { + return nthChild(n - 1, firstChild(node)); + } + } +}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java Sun Mar 08 21:58:34 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java Sun Mar 08 21:58:48 2015 +0100 @@ -36,11 +36,10 @@ private final RootNode rootNode; - public DefaultCallTarget(RootNode function) { + protected DefaultCallTarget(RootNode function) { this.rootNode = function; this.rootNode.adoptChildren(); this.rootNode.applyInstrumentation(); - this.rootNode.setCallTarget(this); } @Override
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java Sun Mar 08 21:58:34 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java Sun Mar 08 21:58:48 2015 +0100 @@ -55,6 +55,7 @@ @Override public RootCallTarget createCallTarget(RootNode rootNode) { DefaultCallTarget target = new DefaultCallTarget(rootNode); + rootNode.setCallTarget(target); callTargets.put(target, null); return target; }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Visualizer.java Sun Mar 08 21:58:34 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Visualizer.java Sun Mar 08 21:58:48 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -60,9 +60,12 @@ String displayCallTargetName(CallTarget callTarget); /** - * Converts a value in the guest language to a display string. + * Converts a value in the guest language to a display string. If + * + * @param trim if {@code > 0}, them limit size of String to either the value of trim or the + * number of characters in the first line, whichever is lower. */ - String displayValue(ExecutionContext context, Object value); + String displayValue(ExecutionContext context, Object value, int trim); /** * Converts a slot identifier in the guest language to a display string.
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultVisualizer.java Sun Mar 08 21:58:34 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultVisualizer.java Sun Mar 08 21:58:48 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -70,12 +70,34 @@ return callTarget.toString(); } - public String displayValue(ExecutionContext context, Object value) { - return value.toString(); + public String displayValue(ExecutionContext context, Object value, int trim) { + return trim(value.toString(), trim); } public String displayIdentifier(FrameSlot slot) { return slot.getIdentifier().toString(); } + /** + * Trims text if {@code trim > 0} to the shorter of {@code trim} or the length of the first line + * of test. Identity if {@code trim <= 0}. + */ + protected String trim(String text, int trim) { + if (trim == 0) { + return text; + } + final String[] lines = text.split("\n"); + String result = lines[0]; + if (lines.length == 1) { + if (result.length() <= trim) { + return result; + } + if (trim <= 3) { + return result.substring(0, Math.min(result.length() - 1, trim - 1)); + } else { + return result.substring(0, trim - 4) + "..."; + } + } + return (result.length() < trim - 3 ? result : result.substring(0, trim - 4)) + "..."; + } }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/PrimitiveValueProfile.java Sun Mar 08 21:58:34 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/PrimitiveValueProfile.java Sun Mar 08 21:58:48 2015 +0100 @@ -175,11 +175,11 @@ } public boolean isGeneric() { - return getCachedValue() == GENERIC; + return cachedValue == GENERIC; } public boolean isUninitialized() { - return getCachedValue() == UNINITIALIZED; + return cachedValue == UNINITIALIZED; } public Object getCachedValue() {
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLDefaultVisualizer.java Sun Mar 08 21:58:34 2015 +0100 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLDefaultVisualizer.java Sun Mar 08 21:58:48 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -73,11 +73,11 @@ } @Override - public String displayValue(ExecutionContext context, Object value) { + public String displayValue(ExecutionContext context, Object value, int trim) { if (value == SLNull.SINGLETON) { return "null"; } - return value.toString(); + return trim(value.toString(), trim); } @Override