# HG changeset patch # User Thomas Wuerthinger # Date 1425938848 -3600 # Node ID cb4d01e1c0842ee6dcc889c4f44e8f78431be9a0 # Parent 0493ae8a552dcc612179976d455ac7f32db98562# Parent 415975c5550bfcb2cdc80164498cf4656daab8a4 Merge. diff -r 415975c5550b -r cb4d01e1c084 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/SourceStackTrace.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/SourceStackTrace.java Mon Mar 09 23:07:28 2015 +0100 @@ -0,0 +1,50 @@ +/* + * 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. + * + * 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.api.code; + +/** + * Class representing a exception with a stack trace of the currently processed position in the + * compiled Java program instead of the stack trace of the compiler. The exception of the compiler + * is saved as the cause of this exception. + */ +public abstract class SourceStackTrace extends BailoutException { + private static final long serialVersionUID = 2144811793442316776L; + + public static SourceStackTrace create(Throwable cause, String format, StackTraceElement[] elements) { + return new SourceStackTrace(cause, format) { + + private static final long serialVersionUID = 6279381376051787907L; + + @Override + public final synchronized Throwable fillInStackTrace() { + assert elements != null; + setStackTrace(elements); + return this; + } + }; + } + + private SourceStackTrace(Throwable cause, String format) { + super(cause, format); + } +} diff -r 415975c5550b -r cb4d01e1c084 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Mon Mar 09 13:11:36 2015 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Mon Mar 09 23:07:28 2015 +0100 @@ -539,9 +539,10 @@ private void peelIteration(BciBlock[] blocks, BciBlock header, ExplodedLoopContext context) { while (true) { processBlock(this, header); - for (int j = header.getId() + 1; j <= header.loopEnd; ++j) { + int j = header.getId() + 1; + while (j <= header.loopEnd) { BciBlock block = blocks[j]; - iterateBlock(blocks, block); + j = iterateBlock(blocks, block); } int[] targets = context.targetPeelIteration; diff -r 415975c5550b -r cb4d01e1c084 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Mon Mar 09 13:11:36 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Mon Mar 09 23:07:28 2015 +0100 @@ -298,36 +298,7 @@ * @return the exception */ public static BailoutException createBailoutException(String message, Throwable cause, StackTraceElement[] elements) { - @SuppressWarnings("serial") - BailoutException exception = new BailoutException(cause, message) { - - @Override - public final synchronized Throwable fillInStackTrace() { - setStackTrace(elements); - return this; - } - }; - return exception; - } - - /** - * Creates a runtime exception with the given stack trace elements and message. - * - * @param message the message of the exception - * @param elements the stack trace elements - * @return the exception - */ - public static RuntimeException createRuntimeException(String message, Throwable cause, StackTraceElement[] elements) { - @SuppressWarnings("serial") - RuntimeException exception = new RuntimeException(message, cause) { - - @Override - public final synchronized Throwable fillInStackTrace() { - setStackTrace(elements); - return this; - } - }; - return exception; + return SourceStackTrace.create(cause, message, elements); } /** diff -r 415975c5550b -r cb4d01e1c084 graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/SimplePartialEvaluationTest.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/SimplePartialEvaluationTest.java Mon Mar 09 13:11:36 2015 -0700 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/SimplePartialEvaluationTest.java Mon Mar 09 23:07:28 2015 +0100 @@ -24,6 +24,7 @@ import org.junit.*; +import com.oracle.graal.api.code.*; import com.oracle.graal.truffle.test.nodes.*; import com.oracle.truffle.api.frame.*; @@ -48,6 +49,32 @@ } @Test + public void neverPartOfCompilationTest() { + FrameDescriptor fd = new FrameDescriptor(); + AbstractTestNode firstTree = new NeverPartOfCompilationTestNode(new ConstantTestNode(1), 2); + assertPartialEvalEquals("constant42", new RootTestNode(fd, "neverPartOfCompilationTest", firstTree)); + + AbstractTestNode secondTree = new NeverPartOfCompilationTestNode(new ConstantTestNode(1), 1); + try { + assertPartialEvalEquals("constant42", new RootTestNode(fd, "neverPartOfCompilationTest", secondTree)); + Assert.fail("Expected verification error!"); + } catch (SourceStackTrace t) { + // Expected verification error occurred. + StackTraceElement[] trace = t.getStackTrace(); + Assert.assertEquals("com.oracle.truffle.api.nodes.RootNode.getFrameDescriptor(RootNode.java)", trace[0].toString()); + String secondString = trace[1].toString(); + Assert.assertEquals("com.oracle.graal.truffle.OptimizedCallTarget.callRoot(OptimizedCallTarget.java:" /* "259)" */, secondString.substring(0, secondString.length() - 4)); + } + } + + @Test + public void nestedLoopExplosion() { + FrameDescriptor fd = new FrameDescriptor(); + AbstractTestNode result = new AddTestNode(new NestedExplodedLoopTestNode(5), new ConstantTestNode(17)); + assertPartialEvalEquals("constant42", new RootTestNode(fd, "nestedLoopExplosion", result)); + } + + @Test public void sequenceConstants() { FrameDescriptor fd = new FrameDescriptor(); AbstractTestNode result = new BlockTestNode(new AbstractTestNode[]{new ConstantTestNode(40), new ConstantTestNode(42)}); diff -r 415975c5550b -r cb4d01e1c084 graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/NestedExplodedLoopTestNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/NestedExplodedLoopTestNode.java Mon Mar 09 23:07:28 2015 +0100 @@ -0,0 +1,48 @@ +/* + * 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. + * + * 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.nodes; + +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.nodes.*; + +@NodeInfo +public class NestedExplodedLoopTestNode extends AbstractTestNode { + + private final int count; + + public NestedExplodedLoopTestNode(int count) { + this.count = count; + } + + @ExplodeLoop + @Override + public int execute(VirtualFrame frame) { + int result = 0; + for (int i = 0; i < count; ++i) { + for (int j = 0; j < count; ++j) { + result++; + } + } + return result; + } +} diff -r 415975c5550b -r cb4d01e1c084 graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/NeverPartOfCompilationTestNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/NeverPartOfCompilationTestNode.java Mon Mar 09 23:07:28 2015 +0100 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.test.nodes; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.frame.*; + +public class NeverPartOfCompilationTestNode extends AbstractTestNode { + + @Child private AbstractTestNode left; + private final int value; + + private static class ValueContainer { + int value; + } + + public NeverPartOfCompilationTestNode(AbstractTestNode left, int value) { + this.left = left; + this.value = value; + } + + @Override + public int execute(VirtualFrame frame) { + ValueContainer v = new ValueContainer(); + v.value = value; + if (v.value == left.execute(frame)) { + CompilerAsserts.neverPartOfCompilation(); + } + return 42; + } +} diff -r 415975c5550b -r cb4d01e1c084 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Mon Mar 09 13:11:36 2015 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Mon Mar 09 23:07:28 2015 +0100 @@ -276,13 +276,14 @@ } } - // Perform dead code elimination. Dead nodes mainly come from parse time canonicalizations. - new DeadCodeEliminationPhase().apply(graph); + // Perform conditional elimination. + new DominatorConditionalEliminationPhase(false).apply(graph); + + canonicalizer.apply(graph, tierContext); // Do single partial escape and canonicalization pass. try (Scope pe = Debug.scope("TrufflePartialEscape", graph)) { new PartialEscapePhase(true, canonicalizer).apply(graph, tierContext); - new IncrementalCanonicalizerPhase<>(canonicalizer, new ConditionalEliminationPhase()).apply(graph, tierContext); } catch (Throwable t) { Debug.handle(t); } diff -r 415975c5550b -r cb4d01e1c084 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java Mon Mar 09 13:11:36 2015 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java Mon Mar 09 23:07:28 2015 +0100 @@ -53,35 +53,49 @@ @Override public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { + ValueNode result = findSynonym(forX, forY); + if (result == null) { + return this; + } else { + return result; + } + } + + private static ValueNode findSynonym(ValueNode forX, ValueNode forY) { if (forX.isConstant() && !forY.isConstant()) { return new IntegerAddExactNode(forY, forX); } if (forX.isConstant()) { - return canonicalXconstant(forX, forY); + ConstantNode constantNode = canonicalXconstant(forX, forY); + if (constantNode != null) { + return constantNode; + } } else if (forY.isConstant()) { long c = forY.asJavaConstant().asLong(); if (c == 0) { return forX; } } - return this; + return null; } - private ValueNode canonicalXconstant(ValueNode forX, ValueNode forY) { + private static ConstantNode canonicalXconstant(ValueNode forX, ValueNode forY) { JavaConstant xConst = forX.asJavaConstant(); JavaConstant yConst = forY.asJavaConstant(); - assert xConst.getKind() == yConst.getKind(); - try { - if (xConst.getKind() == Kind.Int) { - return ConstantNode.forInt(ExactMath.addExact(xConst.asInt(), yConst.asInt())); - } else { - assert xConst.getKind() == Kind.Long; - return ConstantNode.forLong(ExactMath.addExact(xConst.asLong(), yConst.asLong())); + if (xConst != null && yConst != null) { + assert xConst.getKind() == yConst.getKind(); + try { + if (xConst.getKind() == Kind.Int) { + return ConstantNode.forInt(ExactMath.addExact(xConst.asInt(), yConst.asInt())); + } else { + assert xConst.getKind() == Kind.Long; + return ConstantNode.forLong(ExactMath.addExact(xConst.asLong(), yConst.asLong())); + } + } catch (ArithmeticException ex) { + // The operation will result in an overflow exception, so do not canonicalize. } - } catch (ArithmeticException ex) { - // The operation will result in an overflow exception, so do not canonicalize. } - return this; + return null; } @Override diff -r 415975c5550b -r cb4d01e1c084 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java Mon Mar 09 13:11:36 2015 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java Mon Mar 09 23:07:28 2015 +0100 @@ -41,6 +41,7 @@ import com.oracle.graal.truffle.*; import com.oracle.graal.truffle.nodes.*; import com.oracle.graal.truffle.nodes.arithmetic.*; +import com.oracle.graal.truffle.nodes.asserts.*; import com.oracle.graal.truffle.nodes.frame.*; import com.oracle.graal.truffle.unsafe.*; import com.oracle.truffle.api.*; @@ -214,6 +215,16 @@ } } }); + r.register1("neverPartOfCompilation", String.class, new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder, ValueNode message) { + if (message.isConstant()) { + String messageString = message.asConstant().toValueString(); + builder.append(new NeverPartOfCompilationNode(messageString)); + return true; + } + throw builder.bailout("message for never part of compilation is non-constant"); + } + }); } public static void registerOptimizedCallTargetPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { diff -r 415975c5550b -r cb4d01e1c084 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerAsserts.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerAsserts.java Mon Mar 09 13:11:36 2015 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerAsserts.java Mon Mar 09 23:07:28 2015 +0100 @@ -51,7 +51,6 @@ * @param message text associated with the bailout exception */ public static void neverPartOfCompilation(String message) { - CompilerDirectives.bailout(message); } /**