changeset 19521:9c4168877444

Create CompilerAsserts tests. Add graph builder context on bailout. Consolidate CompilerAsserts Truffle API class.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Fri, 20 Feb 2015 13:58:56 +0100
parents 108fbab4e0e8
children c38f37298c10
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BailoutException.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderContext.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/CompilerAssertsTest.java graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/BlockTestNode.java graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/NonConstantTestNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/TraceCompilationFailureListener.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/CompilationConstantNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerAssertsSubstitutions.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerAsserts.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java
diffstat 18 files changed, 259 insertions(+), 214 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BailoutException.java	Fri Feb 20 01:15:31 2015 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BailoutException.java	Fri Feb 20 13:58:56 2015 +0100
@@ -48,6 +48,17 @@
     /**
      * Creates a new {@link BailoutException}.
      *
+     *
+     * @param args parameters to the formatter
+     */
+    public BailoutException(Throwable cause, String format, Object... args) {
+        super(String.format(Locale.ENGLISH, format, args), cause);
+        this.permanent = true;
+    }
+
+    /**
+     * Creates a new {@link BailoutException}.
+     *
      * @param permanent specifies whether this exception will occur again if compilation is retried
      * @param args parameters to the formatter
      */
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderContext.java	Fri Feb 20 01:15:31 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderContext.java	Fri Feb 20 13:58:56 2015 +0100
@@ -76,4 +76,6 @@
     }
 
     GuardingNode getCurrentBlockGuard();
+
+    BailoutException bailout(String string);
 }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Fri Feb 20 01:15:31 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Fri Feb 20 13:58:56 2015 +0100
@@ -1038,7 +1038,7 @@
 
                 synchronizedEpilogue(BytecodeFrame.AFTER_BCI, x);
                 if (frameState.lockDepth() != 0) {
-                    throw new BailoutException("unbalanced monitors");
+                    throw bailout("unbalanced monitors");
                 }
             }
 
@@ -1055,7 +1055,7 @@
                 MonitorIdNode monitorId = frameState.peekMonitorId();
                 ValueNode lockedObject = frameState.popLock();
                 if (GraphUtil.originalValue(lockedObject) != GraphUtil.originalValue(x)) {
-                    throw new BailoutException("unbalanced monitors: mismatch at monitorexit, %s != %s", GraphUtil.originalValue(x), GraphUtil.originalValue(lockedObject));
+                    throw bailout(String.format("unbalanced monitors: mismatch at monitorexit, %s != %s", GraphUtil.originalValue(x), GraphUtil.originalValue(lockedObject)));
                 }
                 MonitorExitNode monitorExit = append(new MonitorExitNode(x, monitorId, escapedReturnValue));
                 return monitorExit;
@@ -1377,7 +1377,7 @@
 
                 // We already saw this block before, so we have to merge states.
                 if (!((HIRFrameStateBuilder) getEntryState(block, operatingDimension)).isCompatibleWith(state)) {
-                    throw new BailoutException("stacks do not match; bytecodes would not verify");
+                    throw bailout("stacks do not match; bytecodes would not verify");
                 }
 
                 if (getFirstInstruction(block, operatingDimension) instanceof LoopBeginNode) {
@@ -1461,7 +1461,7 @@
                                 if (FailedLoopExplosionIsFatal.getValue()) {
                                     throw new RuntimeException(message);
                                 } else {
-                                    throw new BailoutException(message);
+                                    throw bailout(message);
                                 }
                             }
                         }
@@ -1962,6 +1962,13 @@
             public String toString() {
                 return method.format("%H.%n(%p)@") + bci();
             }
+
+            public BailoutException bailout(String string) {
+                FrameState currentFrameState = this.frameState.create(bci());
+                StackTraceElement[] elements = GraphUtil.approxSourceStackTraceElement(currentFrameState);
+                BailoutException bailout = new BailoutException(string);
+                throw GraphUtil.createBailoutException(string, bailout, elements);
+            }
         }
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Fri Feb 20 01:15:31 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Fri Feb 20 13:58:56 2015 +0100
@@ -24,6 +24,7 @@
 
 import java.util.*;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
@@ -241,13 +242,7 @@
 
             if (n instanceof StateSplit) {
                 FrameState state = ((StateSplit) n).stateAfter();
-                while (state != null) {
-                    ResolvedJavaMethod method = state.method();
-                    if (method != null) {
-                        elements.add(method.asStackTraceElement(state.bci - 1));
-                    }
-                    state = state.outerFrameState();
-                }
+                elements.addAll(Arrays.asList(approxSourceStackTraceElement(state)));
                 break;
             }
             n = n.predecessor();
@@ -256,6 +251,24 @@
     }
 
     /**
+     * Gets an approximate source code location for frame state.
+     *
+     * @return the StackTraceElements if an approximate source location is found, null otherwise
+     */
+    public static StackTraceElement[] approxSourceStackTraceElement(FrameState frameState) {
+        ArrayList<StackTraceElement> elements = new ArrayList<>();
+        FrameState state = frameState;
+        while (state != null) {
+            ResolvedJavaMethod method = state.method();
+            if (method != null) {
+                elements.add(method.asStackTraceElement(state.bci - 1));
+            }
+            state = state.outerFrameState();
+        }
+        return elements.toArray(new StackTraceElement[0]);
+    }
+
+    /**
      * Gets an approximate source code location for a node, encoded as an exception, if possible.
      *
      * @return the exception with the location
@@ -263,7 +276,47 @@
     public static RuntimeException approxSourceException(Node node, Throwable cause) {
         final StackTraceElement[] elements = approxSourceStackTraceElement(node);
         @SuppressWarnings("serial")
-        RuntimeException exception = new RuntimeException((cause == null) ? null : cause.getMessage(), cause) {
+        BailoutException exception = new BailoutException((cause == null) ? null : cause.getMessage(), cause) {
+
+            @Override
+            public final synchronized Throwable fillInStackTrace() {
+                setStackTrace(elements);
+                return this;
+            }
+        };
+        return exception;
+    }
+
+    /**
+     * Creates a bailout 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 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() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/CompilerAssertsTest.java	Fri Feb 20 13:58:56 2015 +0100
@@ -0,0 +1,91 @@
+/*
+ * 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;
+
+import org.junit.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.truffle.test.nodes.*;
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.frame.*;
+
+public class CompilerAssertsTest extends PartialEvaluationTest {
+
+    public static class NeverPartOfCompilationTestNode extends AbstractTestNode {
+
+        @Override
+        public int execute(VirtualFrame frame) {
+            CompilerAsserts.neverPartOfCompilation();
+            return 0;
+        }
+
+    }
+
+    public static class CompilationConstantTestNode extends AbstractTestNode {
+        @Child private AbstractTestNode child;
+
+        public CompilationConstantTestNode(AbstractTestNode child) {
+            this.child = child;
+        }
+
+        @Override
+        public int execute(VirtualFrame frame) {
+            CompilerAsserts.compilationConstant(child.execute(frame));
+            return 0;
+        }
+
+    }
+
+    @Test
+    public void neverPartOfCompilationTest() {
+        NeverPartOfCompilationTestNode result = new NeverPartOfCompilationTestNode();
+        RootTestNode rootNode = new RootTestNode(new FrameDescriptor(), "neverPartOfCompilation", result);
+        try {
+            compileHelper("neverPartOfCompilation", rootNode, new Object[0]);
+            Assert.fail("Expected bailout exception due to never part of compilation");
+        } catch (BailoutException e) {
+            // Bailout exception expected.
+        }
+    }
+
+    @Test
+    public void compilationNonConstantTest() {
+        FrameDescriptor descriptor = new FrameDescriptor();
+        CompilationConstantTestNode result = new CompilationConstantTestNode(new NonConstantTestNode(5));
+        RootTestNode rootNode = new RootTestNode(descriptor, "compilationConstant", result);
+        try {
+            compileHelper("compilationConstant", rootNode, new Object[0]);
+            Assert.fail("Expected bailout exception because expression is not compilation constant");
+        } catch (BailoutException e) {
+            // Bailout exception expected.
+        }
+    }
+
+    @Test
+    public void compilationConstantTest() {
+        FrameDescriptor descriptor = new FrameDescriptor();
+        CompilationConstantTestNode result = new CompilationConstantTestNode(new ConstantTestNode(5));
+        RootTestNode rootNode = new RootTestNode(descriptor, "compilationConstant", result);
+        compileHelper("compilationConstant", rootNode, new Object[0]);
+    }
+}
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/BlockTestNode.java	Fri Feb 20 01:15:31 2015 +0100
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/BlockTestNode.java	Fri Feb 20 13:58:56 2015 +0100
@@ -30,7 +30,7 @@
 
     @Children private final AbstractTestNode[] statements;
 
-    public BlockTestNode(AbstractTestNode[] statements) {
+    public BlockTestNode(AbstractTestNode... statements) {
         this.statements = statements;
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/NonConstantTestNode.java	Fri Feb 20 13:58:56 2015 +0100
@@ -0,0 +1,39 @@
+/*
+ * 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.frame.*;
+
+public class NonConstantTestNode extends AbstractTestNode {
+
+    private int value;
+
+    public NonConstantTestNode(int value) {
+        this.value = value;
+    }
+
+    @Override
+    public int execute(VirtualFrame frame) {
+        return value;
+    }
+}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Fri Feb 20 01:15:31 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Fri Feb 20 13:58:56 2015 +0100
@@ -151,6 +151,7 @@
             CompilationResult compilationResult = compileMethodHelper(graph, compilable.toString(), graphBuilderSuite, compilable.getSpeculationLog(), compilable);
             compilationNotify.notifyCompilationSuccess(compilable, graph, compilationResult);
         } catch (Throwable t) {
+            System.out.println("compilation failed!?");
             compilationNotify.notifyCompilationFailed(compilable, graph, t);
             throw t;
         }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/TraceCompilationFailureListener.java	Fri Feb 20 01:15:31 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/TraceCompilationFailureListener.java	Fri Feb 20 13:58:56 2015 +0100
@@ -25,6 +25,7 @@
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.truffle.*;
 
@@ -39,7 +40,7 @@
 
     @Override
     public void notifyCompilationFailed(OptimizedCallTarget target, StructuredGraph graph, Throwable t) {
-        if (isPermanentBailout(t)) {
+        if (isPermanentBailout(t) || GraalOptions.PrintBailout.getValue()) {
             Map<String, Object> properties = new LinkedHashMap<>();
             properties.put("Reason", t.toString());
             log(0, "opt fail", target.toString(), properties);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/CompilationConstantNode.java	Fri Feb 20 01:15:31 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * 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.nodes.asserts;
-
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.nodeinfo.*;
-import com.oracle.graal.nodes.*;
-
-@NodeInfo
-public final class CompilationConstantNode extends NeverPartOfCompilationNode implements Canonicalizable {
-
-    public static final NodeClass<CompilationConstantNode> TYPE = NodeClass.get(CompilationConstantNode.class);
-
-    public CompilationConstantNode(Invoke invoke) {
-        super(TYPE, invoke, "The value could not be reduced to a compile time constant.");
-        assert arguments.size() == 1;
-    }
-
-    @Override
-    public Node canonical(CanonicalizerTool tool) {
-        if (arguments.get(0).isConstant()) {
-            return arguments.get(0);
-        }
-        return this;
-    }
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java	Fri Feb 20 01:15:31 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java	Fri Feb 20 13:58:56 2015 +0100
@@ -22,29 +22,25 @@
  */
 package com.oracle.graal.truffle.nodes.asserts;
 
+import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.util.*;
-import com.oracle.graal.replacements.nodes.*;
 
 @NodeInfo
-public class NeverPartOfCompilationNode extends MacroStateSplitNode implements IterableNodeType {
+public final class NeverPartOfCompilationNode extends FixedWithNextNode implements IterableNodeType {
 
     public static final NodeClass<NeverPartOfCompilationNode> TYPE = NodeClass.get(NeverPartOfCompilationNode.class);
     protected final String message;
 
-    public NeverPartOfCompilationNode(Invoke invoke) {
-        this(TYPE, invoke, "This code path should never be part of a compilation.");
-    }
-
-    protected NeverPartOfCompilationNode(NodeClass<? extends NeverPartOfCompilationNode> c, Invoke invoke, String message) {
-        super(c, invoke);
+    public NeverPartOfCompilationNode(String message) {
+        super(TYPE, StampFactory.forVoid());
         this.message = message;
     }
 
-    public final String getMessage() {
-        return message + " " + arguments.toString();
+    public String getMessage() {
+        return message;
     }
 
     public static void verifyNotFoundIn(final StructuredGraph graph) {
@@ -53,4 +49,7 @@
             throw GraphUtil.approxSourceException(neverPartOfCompilationNode, exception);
         }
     }
+
+    @NodeIntrinsic
+    public static native void apply(@ConstantNodeParameter String message);
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java	Fri Feb 20 01:15:31 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java	Fri Feb 20 13:58:56 2015 +0100
@@ -30,14 +30,14 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.replacements.nodes.*;
 import com.oracle.graal.truffle.nodes.*;
-import com.oracle.graal.truffle.nodes.asserts.*;
 
 /**
  * Macro node for CompilerDirectives#unsafeGetInt*.
  */
 @NodeInfo
-public final class CustomizedUnsafeLoadMacroNode extends NeverPartOfCompilationNode implements Canonicalizable {
+public final class CustomizedUnsafeLoadMacroNode extends MacroStateSplitNode implements Canonicalizable {
     public static final NodeClass<CustomizedUnsafeLoadMacroNode> TYPE = NodeClass.get(CustomizedUnsafeLoadMacroNode.class);
 
     private static final int ARGUMENT_COUNT = 4;
@@ -47,7 +47,7 @@
     private static final int LOCATION_ARGUMENT_INDEX = 3;
 
     public CustomizedUnsafeLoadMacroNode(Invoke invoke) {
-        super(TYPE, invoke, "The location argument could not be resolved to a constant.");
+        super(TYPE, invoke);
         assert arguments.size() == ARGUMENT_COUNT;
     }
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java	Fri Feb 20 01:15:31 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java	Fri Feb 20 13:58:56 2015 +0100
@@ -28,14 +28,14 @@
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.replacements.nodes.*;
 import com.oracle.graal.truffle.nodes.*;
-import com.oracle.graal.truffle.nodes.asserts.*;
 
 /**
  * Macro node for method CompilerDirectives#unsafePut*.
  */
 @NodeInfo
-public final class CustomizedUnsafeStoreMacroNode extends NeverPartOfCompilationNode implements Canonicalizable, StateSplit {
+public final class CustomizedUnsafeStoreMacroNode extends MacroStateSplitNode implements Canonicalizable, StateSplit {
     public static final NodeClass<CustomizedUnsafeStoreMacroNode> TYPE = NodeClass.get(CustomizedUnsafeStoreMacroNode.class);
     private static final int ARGUMENT_COUNT = 4;
     private static final int OBJECT_ARGUMENT_INDEX = 0;
@@ -44,7 +44,7 @@
     private static final int LOCATION_ARGUMENT_INDEX = 3;
 
     public CustomizedUnsafeStoreMacroNode(Invoke invoke) {
-        super(TYPE, invoke, "The location argument could not be resolved to a constant.");
+        super(TYPE, invoke);
         assert arguments.size() == ARGUMENT_COUNT;
     }
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java	Fri Feb 20 01:15:31 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java	Fri Feb 20 13:58:56 2015 +0100
@@ -31,13 +31,13 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.util.*;
-import com.oracle.graal.truffle.nodes.asserts.*;
+import com.oracle.graal.replacements.nodes.*;
 
 /**
  * Macro node for method CompilerDirectives#unsafeCast.
  */
 @NodeInfo
-public final class UnsafeTypeCastMacroNode extends NeverPartOfCompilationNode implements Simplifiable {
+public final class UnsafeTypeCastMacroNode extends MacroStateSplitNode implements Simplifiable {
 
     public static final NodeClass<UnsafeTypeCastMacroNode> TYPE = NodeClass.get(UnsafeTypeCastMacroNode.class);
     private static final int OBJECT_ARGUMENT_INDEX = 0;
@@ -47,7 +47,7 @@
     private static final int ARGUMENT_COUNT = 4;
 
     public UnsafeTypeCastMacroNode(Invoke invoke) {
-        super(TYPE, invoke, "The class of the unsafe cast could not be reduced to a compile time constant.");
+        super(TYPE, invoke);
         assert arguments.size() == ARGUMENT_COUNT;
     }
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerAssertsSubstitutions.java	Fri Feb 20 01:15:31 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerAssertsSubstitutions.java	Fri Feb 20 13:58:56 2015 +0100
@@ -23,43 +23,15 @@
 package com.oracle.graal.truffle.substitutions;
 
 import com.oracle.graal.api.replacements.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.truffle.nodes.asserts.*;
 import com.oracle.truffle.api.*;
 
 @ClassSubstitution(CompilerAsserts.class)
 public class CompilerAssertsSubstitutions {
 
-    @MacroSubstitution(macro = NeverPartOfCompilationNode.class, isStatic = true)
-    public static native void neverPartOfCompilation();
-
-    @MacroSubstitution(macro = NeverPartOfCompilationNode.class, isStatic = true)
-    public static native void neverPartOfCompilation(String message);
-
-    @MacroSubstitution(macro = CompilationConstantNode.class, isStatic = true)
-    public static native boolean compilationConstant(boolean value);
-
-    @MacroSubstitution(macro = CompilationConstantNode.class, isStatic = true)
-    public static native byte compilationConstant(byte value);
-
-    @MacroSubstitution(macro = CompilationConstantNode.class, isStatic = true)
-    public static native char compilationConstant(char value);
+    @MethodSubstitution
+    public static void neverPartOfCompilation(@SuppressWarnings("unused") String message) {
+        NeverPartOfCompilationNode.apply("Never part of compilation");
+    }
 
-    @MacroSubstitution(macro = CompilationConstantNode.class, isStatic = true)
-    public static native short compilationConstant(short value);
-
-    @MacroSubstitution(macro = CompilationConstantNode.class, isStatic = true)
-    public static native int compilationConstant(int value);
-
-    @MacroSubstitution(macro = CompilationConstantNode.class, isStatic = true)
-    public static native long compilationConstant(long value);
-
-    @MacroSubstitution(macro = CompilationConstantNode.class, isStatic = true)
-    public static native float compilationConstant(float value);
-
-    @MacroSubstitution(macro = CompilationConstantNode.class, isStatic = true)
-    public static native double compilationConstant(double value);
-
-    @MacroSubstitution(macro = CompilationConstantNode.class, isStatic = true)
-    public static native Object compilationConstant(Object value);
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java	Fri Feb 20 01:15:31 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java	Fri Feb 20 13:58:56 2015 +0100
@@ -26,7 +26,6 @@
 
 import java.util.concurrent.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.calc.*;
@@ -78,7 +77,7 @@
                         builder.getAssumptions().record(new AssumptionValidAssumption(assumption));
                     }
                 } else {
-                    throw new BailoutException("assumption could not be reduced to a constant");
+                    throw builder.bailout("assumption could not be reduced to a constant");
                 }
                 return true;
             }
@@ -170,9 +169,9 @@
         r.register1("bailout", String.class, new InvocationPlugin() {
             public boolean apply(GraphBuilderContext builder, ValueNode message) {
                 if (message.isConstant()) {
-                    throw new BailoutException(message.asConstant().toValueString());
+                    throw builder.bailout(message.asConstant().toValueString());
                 }
-                throw new BailoutException("bailout (message is not compile-time constant, so no additional information is available)");
+                throw builder.bailout("bailout (message is not compile-time constant, so no additional information is available)");
             }
         });
         r.register1("isCompilationConstant", Object.class, new InvocationPlugin() {
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerAsserts.java	Fri Feb 20 01:15:31 2015 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerAsserts.java	Fri Feb 20 13:58:56 2015 +0100
@@ -32,7 +32,6 @@
  *
  */
 public class CompilerAsserts {
-
     /**
      * Assertion that this code position should never be reached during compilation. It can be used
      * for exceptional code paths or rare code paths that should never be included in a compilation
@@ -40,98 +39,29 @@
      * directive.
      */
     public static void neverPartOfCompilation() {
-    }
-
-    public static void neverPartOfCompilation(@SuppressWarnings("unused") String message) {
-    }
-
-    /**
-     * Assertion that the corresponding value is reduced to a constant during compilation.
-     *
-     * @param value the value that must be constant during compilation
-     * @return the value given as parameter
-     */
-    public static boolean compilationConstant(boolean value) {
-        return value;
+        neverPartOfCompilation("");
     }
 
     /**
-     * Assertion that the corresponding value is reduced to a constant during compilation.
+     * Assertion that this code position should never be reached during compilation. It can be used
+     * for exceptional code paths or rare code paths that should never be included in a compilation
+     * unit. See {@link CompilerDirectives#transferToInterpreter()} for the corresponding compiler
+     * directive.
      *
-     * @param value the value that must be constant during compilation
-     * @return the value given as parameter
+     * @param message text associated with the bailout exception
      */
-    public static byte compilationConstant(byte value) {
-        return value;
-    }
-
-    /**
-     * Assertion that the corresponding value is reduced to a constant during compilation.
-     *
-     * @param value the value that must be constant during compilation
-     * @return the value given as parameter
-     */
-    public static char compilationConstant(char value) {
-        return value;
+    public static void neverPartOfCompilation(String message) {
+        CompilerDirectives.bailout(message);
     }
 
     /**
      * Assertion that the corresponding value is reduced to a constant during compilation.
      *
      * @param value the value that must be constant during compilation
-     * @return the value given as parameter
      */
-    public static short compilationConstant(short value) {
-        return value;
-    }
-
-    /**
-     * Assertion that the corresponding value is reduced to a constant during compilation.
-     *
-     * @param value the value that must be constant during compilation
-     * @return the value given as parameter
-     */
-    public static int compilationConstant(int value) {
-        return value;
-    }
-
-    /**
-     * Assertion that the corresponding value is reduced to a constant during compilation.
-     *
-     * @param value the value that must be constant during compilation
-     * @return the value given as parameter
-     */
-    public static long compilationConstant(long value) {
-        return value;
-    }
-
-    /**
-     * Assertion that the corresponding value is reduced to a constant during compilation.
-     *
-     * @param value the value that must be constant during compilation
-     * @return the value given as parameter
-     */
-    public static float compilationConstant(float value) {
-        return value;
-    }
-
-    /**
-     * Assertion that the corresponding value is reduced to a constant during compilation.
-     *
-     * @param value the value that must be constant during compilation
-     * @return the value given as parameter
-     */
-    public static double compilationConstant(double value) {
-        return value;
-    }
-
-    /**
-     * Assertion that the corresponding value is reduced to a constant during compilation.
-     *
-     * @param value the value that must be constant during compilation
-     * @return the value given as parameter
-     */
-    public static Object compilationConstant(Object value) {
-        return value;
+    public static <T> void compilationConstant(Object value) {
+        if (!CompilerDirectives.isCompilationConstant(value)) {
+            neverPartOfCompilation("Value is not compilation constant");
+        }
     }
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Fri Feb 20 01:15:31 2015 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Fri Feb 20 13:58:56 2015 +0100
@@ -80,33 +80,20 @@
     /**
      * Returns a boolean indicating whether or not a given value is seen as constant in optimized
      * code. If this method is called in the interpreter this method will always return
-     * <code>false</code>. This API may be used in combination with {@link #inCompiledCode()} to
-     * implement compilation constant assertions in the following way:
-     *
-     * <pre>
-     * <code>
-     * void assertCompilationConstant(Object value) {
-     *   if (inCompiledCode()) {
-     *     if (!isCompilationConstant(value)) {
-     *       throw new AssertionError("Given value is not constant");
-     *     }
-     *   }
-     * }
-     * </code>
-     * </pre>
+     * <code>true</code>.
      *
      * Note that optimizations that a compiler will apply to code that is conditional on
      * <code>isCompilationConstant</code> may be limited. For this reason
      * <code>isCompilationConstant</code> is not recommended for use to select between alternate
      * implementations of functionality depending on whether a value is constant. Instead, it is
-     * intended for use as a diagnostic mechanism, such as illustrated above.
+     * intended for use as a diagnostic mechanism.
      *
      * @param value
      * @return {@code true} when given value is seen as compilation constant, {@code false} if not
      *         compilation constant.
      */
     public static boolean isCompilationConstant(Object value) {
-        return false;
+        return CompilerDirectives.inInterpreter();
     }
 
     /**