changeset 11321:77bf4af4cc94

Merge.
author Christian Humer <christian.humer@gmail.com>
date Fri, 16 Aug 2013 17:55:25 +0200
parents 80de3bbfa8b9 (current diff) 602a25aade24 (diff)
children 07814c3b5dba
files graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/CompilationConstantNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/FrameAccessNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/FrameGetNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/FrameSetNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerAddExactNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerAddExactSplitNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerExactArithmeticNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerExactArithmeticSplitNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerMulExactNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerMulExactSplitNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerSubExactNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerSubExactSplitNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/MaterializeFrameNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/NeverInlineMacroNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/NeverPartOfCompilationNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/NewFrameNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/UnsafeCastMacroNode.java
diffstat 59 files changed, 1810 insertions(+), 1366 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java	Fri Aug 16 14:00:17 2013 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java	Fri Aug 16 17:55:25 2013 +0200
@@ -87,7 +87,8 @@
     TriState getExceptionSeen(int bci);
 
     /**
-     * Returns information if null was ever seen for the given BCI.
+     * Returns information if null was ever seen for the given BCI. This information is collected
+     * for the aastore, checkcast and instanceof bytecodes.
      * 
      * @return {@link TriState#TRUE} if null was seen for the instruction, {@link TriState#FALSE} if
      *         null was NOT seen, and {@link TriState#UNKNOWN} if this information was not recorded.
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Fri Aug 16 14:00:17 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Fri Aug 16 17:55:25 2013 +0200
@@ -363,11 +363,13 @@
 
     protected Result executeActualCheckDeopt(Method method, Set<DeoptimizationReason> shouldNotDeopt, Object receiver, Object... args) {
         Map<DeoptimizationReason, Integer> deoptCounts = new EnumMap<>(DeoptimizationReason.class);
-        ProfilingInfo profile = runtime.lookupJavaMethod(method).getProfilingInfo();
+        ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(method);
+        ProfilingInfo profile = javaMethod.getProfilingInfo();
         for (DeoptimizationReason reason : shouldNotDeopt) {
             deoptCounts.put(reason, profile.getDeoptimizationCount(reason));
         }
         Result actual = executeActual(method, receiver, args);
+        profile = javaMethod.getProfilingInfo(); // profile can change after execution
         for (DeoptimizationReason reason : shouldNotDeopt) {
             Assert.assertEquals((int) deoptCounts.get(reason), profile.getDeoptimizationCount(reason));
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Fri Aug 16 14:00:17 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Fri Aug 16 17:55:25 2013 +0200
@@ -722,8 +722,8 @@
                                 value = allocations[commit.getVirtualObjects().indexOf(value)];
                             }
                             if (!(value.isConstant() && value.asConstant().isDefaultForKind())) {
-                                WriteNode write = new WriteNode(newObject, value, createFieldLocation(graph, (HotSpotResolvedJavaField) virtualInstance.field(i)), BarrierType.NONE,
-                                                virtualInstance.field(i).getKind() == Kind.Object);
+                                WriteNode write = new WriteNode(newObject, value, createFieldLocation(graph, (HotSpotResolvedJavaField) virtualInstance.field(i)),
+                                                virtualInstance.field(i).getKind() == Kind.Object ? BarrierType.IMPRECISE : BarrierType.NONE, virtualInstance.field(i).getKind() == Kind.Object);
 
                                 graph.addBeforeFixed(commit, graph.add(write));
                             }
@@ -740,8 +740,8 @@
                                 value = allocations[indexOf];
                             }
                             if (!(value.isConstant() && value.asConstant().isDefaultForKind())) {
-                                WriteNode write = new WriteNode(newObject, value, createArrayLocation(graph, element.getKind(), ConstantNode.forInt(i, graph)), BarrierType.NONE,
-                                                value.kind() == Kind.Object);
+                                WriteNode write = new WriteNode(newObject, value, createArrayLocation(graph, element.getKind(), ConstantNode.forInt(i, graph)),
+                                                value.kind() == Kind.Object ? BarrierType.PRECISE : BarrierType.NONE, value.kind() == Kind.Object);
                                 graph.addBeforeFixed(commit, graph.add(write));
                             }
                         }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Fri Aug 16 14:00:17 2013 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Fri Aug 16 17:55:25 2013 +0200
@@ -812,7 +812,7 @@
         if (type instanceof ResolvedJavaType) {
             ResolvedJavaType resolvedType = (ResolvedJavaType) type;
             InstanceOfNode instanceOfNode = new InstanceOfNode((ResolvedJavaType) type, object, getProfileForTypeCheck(resolvedType));
-            frameState.ipush(append(new ConditionalNode(currentGraph.unique(instanceOfNode), ConstantNode.forInt(1, currentGraph), ConstantNode.forInt(0, currentGraph))));
+            frameState.ipush(append(new ConditionalNode(currentGraph.unique(instanceOfNode))));
         } else {
             handleUnresolvedInstanceOf(type, object);
         }
@@ -1137,9 +1137,12 @@
         if (graphBuilderConfig.eagerResolving()) {
             returnType = returnType.resolve(targetMethod.getDeclaringClass());
         }
-        if (invokeKind != InvokeKind.Static && invokeKind != InvokeKind.Special) {
-            JavaTypeProfile profile = profilingInfo.getTypeProfile(bci());
-            args[0] = TypeProfileProxyNode.create(args[0], profile);
+        if (invokeKind != InvokeKind.Static) {
+            emitExplicitExceptions(args[0], null);
+            if (invokeKind != InvokeKind.Special) {
+                JavaTypeProfile profile = profilingInfo.getTypeProfile(bci());
+                args[0] = TypeProfileProxyNode.create(args[0], profile);
+            }
         }
         MethodCallTargetNode callTarget = currentGraph.add(new MethodCallTargetNode(invokeKind, targetMethod, args, returnType));
         createInvokeNode(callTarget, resultType);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ConditionalEliminiation01.java	Fri Aug 16 17:55:25 2013 +0200
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2011, 2012, 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.jtt.optimize;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.junit.*;
+
+import com.oracle.graal.test.*;
+import com.oracle.graal.jtt.*;
+
+@SuppressWarnings("unused")
+public class ConditionalEliminiation01 extends JTTTest {
+
+    private static int x;
+    private static Object o = new Object();
+
+    private static class A {
+
+        public A(int y) {
+            this.y = y;
+        }
+
+        int y;
+    }
+
+    @Override
+    protected void before(Method method) {
+        super.before(method);
+        x = 0;
+    }
+
+    public int test(A a) {
+        if (o == null) {
+            return -1;
+        }
+        if (a == null) {
+            return -2;
+        }
+        if (o == null) {
+            return -3;
+        }
+        x = 3;
+        return a.y + x;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        runTest("test", new A(5));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        runTest("test", new Object[]{null});
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ConditionalEliminiation02.java	Fri Aug 16 17:55:25 2013 +0200
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2011, 2012, 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.jtt.optimize;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.junit.*;
+
+import com.oracle.graal.test.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.jtt.*;
+
+@SuppressWarnings("unused")
+public class ConditionalEliminiation02 extends JTTTest {
+
+    private static Object o = null;
+
+    private static class A {
+
+        public A(int y) {
+            this.y = y;
+        }
+
+        int y;
+    }
+
+    public int test(A a, boolean isNull, boolean isVeryNull) {
+        if (o == null) {
+            if (!isNull) {
+                if (o == null) {
+                    return a.y;
+                }
+            }
+            if (!isVeryNull) {
+                if (o == null) {
+                    return a.y;
+                }
+            }
+        }
+        return -1;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        runTest(EnumSet.of(DeoptimizationReason.NullCheckException), "test", new A(5), false, false);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        runTest(EnumSet.of(DeoptimizationReason.NullCheckException), "test", new Object[]{null, true, true});
+    }
+
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java	Fri Aug 16 14:00:17 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java	Fri Aug 16 17:55:25 2013 +0200
@@ -42,6 +42,10 @@
         return condition;
     }
 
+    public ConditionalNode(LogicNode condition) {
+        this(condition, ConstantNode.forInt(1, condition.graph()), ConstantNode.forInt(0, condition.graph()));
+    }
+
     public ConditionalNode(LogicNode condition, ValueNode trueValue, ValueNode falseValue) {
         super(trueValue.kind(), trueValue, falseValue);
         assert trueValue.kind() == falseValue.kind();
@@ -104,11 +108,11 @@
     }
 
     private ConditionalNode(Condition condition, ValueNode x, ValueNode y) {
-        this(createCompareNode(condition, x, y), ConstantNode.forInt(1, x.graph()), ConstantNode.forInt(0, x.graph()));
+        this(createCompareNode(condition, x, y));
     }
 
     private ConditionalNode(ValueNode type, ValueNode object) {
-        this(type.graph().add(new InstanceOfDynamicNode(type, object)), ConstantNode.forInt(1, type.graph()), ConstantNode.forInt(0, type.graph()));
+        this(type.graph().add(new InstanceOfDynamicNode(type, object)));
     }
 
     @NodeIntrinsic
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java	Fri Aug 16 14:00:17 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java	Fri Aug 16 17:55:25 2013 +0200
@@ -32,12 +32,21 @@
  */
 public class UnsafeCastNode extends PiNode implements Canonicalizable, LIRLowerable {
 
+    private final Object customType;
+
     public UnsafeCastNode(ValueNode object, Stamp stamp) {
         super(object, stamp);
+        customType = null;
     }
 
     public UnsafeCastNode(ValueNode object, Stamp stamp, GuardingNode anchor) {
         super(object, stamp, anchor);
+        customType = null;
+    }
+
+    public UnsafeCastNode(ValueNode object, Stamp stamp, GuardingNode anchor, Object customType) {
+        super(object, stamp, anchor);
+        this.customType = customType;
     }
 
     public UnsafeCastNode(ValueNode object, Stamp stamp, ValueNode anchor) {
@@ -48,6 +57,10 @@
         this(object, toType.getKind() == Kind.Object ? StampFactory.object(toType, exactType, nonNull || ObjectStamp.isObjectNonNull(object.stamp())) : StampFactory.forKind(toType.getKind()));
     }
 
+    public Object getCustomType() {
+        return customType;
+    }
+
     @Override
     public boolean inferStamp() {
         if (stamp() == StampFactory.forNodeIntrinsic()) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Fri Aug 16 14:00:17 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Fri Aug 16 17:55:25 2013 +0200
@@ -33,7 +33,7 @@
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.java.MethodCallTargetNode.*;
+import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
@@ -547,6 +547,10 @@
                 }
 
                 if (replacement != null) {
+                    if (replacementAnchor instanceof GuardNode) {
+                        ValueAnchorNode anchor = graph.add(new ValueAnchorNode(replacementAnchor));
+                        graph.addBeforeFixed(ifNode, anchor);
+                    }
                     for (Node n : survivingSuccessor.usages().snapshot()) {
                         if (n instanceof GuardNode || n instanceof ProxyNode) {
                             // Keep wired to the begin node.
@@ -555,7 +559,6 @@
                                 // Cannot simplify this IfNode as there is no anchor.
                                 return;
                             }
-
                             // Rewire to the replacement anchor.
                             n.replaceFirstInput(survivingSuccessor, replacementAnchor);
                         }
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Fri Aug 16 14:00:17 2013 +0200
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Fri Aug 16 17:55:25 2013 +0200
@@ -100,7 +100,7 @@
             compilable.call(null, arguments);
         } while (compilable.inline());
 
-        StructuredGraph graph = Debug.scope("Truffle", new DebugDumpScope("Truffle: " + compilable), new Callable<StructuredGraph>() {
+        StructuredGraph graph = Debug.scope("TruffleCompilation", new DebugDumpScope("TruffleCompilation: " + compilable), new Callable<StructuredGraph>() {
 
             @Override
             public StructuredGraph call() {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Fri Aug 16 14:00:17 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Fri Aug 16 17:55:25 2013 +0200
@@ -47,8 +47,9 @@
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.common.CanonicalizerPhase.CustomCanonicalizer;
 import com.oracle.graal.phases.tiers.*;
-import com.oracle.graal.truffle.nodes.*;
-import com.oracle.graal.truffle.nodes.NewFrameNode.VirtualOnlyInstanceNode;
+import com.oracle.graal.truffle.nodes.asserts.*;
+import com.oracle.graal.truffle.nodes.frame.*;
+import com.oracle.graal.truffle.nodes.frame.NewFrameNode.VirtualOnlyInstanceNode;
 import com.oracle.graal.truffle.phases.*;
 import com.oracle.graal.truffle.printer.*;
 import com.oracle.graal.truffle.printer.method.*;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/CompilationConstantNode.java	Fri Aug 16 14:00:17 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +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;
-
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-
-public class CompilationConstantNode extends NeverPartOfCompilationNode implements Canonicalizable {
-
-    public CompilationConstantNode(Invoke invoke) {
-        super(invoke, "The value could not be reduced to a compile time constant.");
-        assert arguments.size() == 1;
-    }
-
-    @Override
-    public ValueNode 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/FrameAccessNode.java	Fri Aug 16 14:00:17 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,163 +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;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.truffle.*;
-import com.oracle.truffle.api.frame.*;
-
-/**
- * Base node class for the intrinsic nodes for read and write access to a Truffle frame.
- */
-public abstract class FrameAccessNode extends FixedWithNextNode implements Simplifiable {
-
-    @Input private ValueNode frame;
-    @Input private ValueNode slot;
-    protected final ResolvedJavaField field;
-    protected final Kind slotKind;
-
-    public FrameAccessNode(Stamp stamp, Kind slotKind, ValueNode frame, ValueNode slot, ResolvedJavaField field) {
-        super(stamp);
-        this.slotKind = slotKind;
-        this.frame = frame;
-        this.slot = slot;
-        this.field = field;
-    }
-
-    public ValueNode getFrame() {
-        return frame;
-    }
-
-    public ValueNode getSlot() {
-        return slot;
-    }
-
-    public Kind getSlotKind() {
-        return slotKind;
-    }
-
-    protected int getSlotIndex() {
-        return getConstantFrameSlot().getIndex();
-    }
-
-    protected boolean isConstantFrameSlot() {
-        return slot.isConstant() && !slot.isNullConstant();
-    }
-
-    protected FrameSlot getConstantFrameSlot() {
-        assert isConstantFrameSlot() : slot;
-        return (FrameSlot) slot.asConstant().asObject();
-    }
-
-    protected final void insertDeoptimization(VirtualizerTool tool) {
-        LogicNode contradiction = LogicConstantNode.contradiction(graph());
-        FixedGuardNode fixedGuard = new FixedGuardNode(contradiction, DeoptimizationReason.UnreachedCode, DeoptimizationAction.InvalidateReprofile);
-        tool.addNode(fixedGuard);
-    }
-
-    @Override
-    public String toString(Verbosity verbosity) {
-        if (verbosity == Verbosity.Name) {
-            return super.toString(verbosity) + getSlotKind().name() + (isConstantFrameSlot() ? " " + getConstantFrameSlot() : "");
-        } else {
-            return super.toString(verbosity);
-        }
-    }
-
-    protected final ValueNode getSlotOffset(int scale, MetaAccessProvider metaAccessProvider) {
-        if (isConstantFrameSlot()) {
-            return ConstantNode.forInt(getSlotIndex() * scale, graph());
-        } else {
-            LoadFieldNode loadFrameSlotIndex = graph().add(new LoadFieldNode(getSlot(), metaAccessProvider.lookupJavaField(getFrameSlotIndexField())));
-            graph().addBeforeFixed(this, loadFrameSlotIndex);
-            return scale == 1 ? loadFrameSlotIndex : IntegerArithmeticNode.mul(loadFrameSlotIndex, ConstantNode.forInt(scale, graph()));
-        }
-    }
-
-    private static Field getFrameSlotIndexField() {
-        try {
-            return FrameSlotImpl.class.getDeclaredField("index");
-        } catch (NoSuchFieldException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    protected final boolean isValidAccessKind() {
-        if (getSlotKind() == Kind.Byte) {
-            // tag access
-            return true;
-        }
-
-        return getSlotKind() == getGraalKind(getConstantFrameSlot().getKind());
-    }
-
-    private static Kind getGraalKind(FrameSlotKind kind) {
-        switch (kind) {
-            case Object:
-                return Kind.Object;
-            case Long:
-                return Kind.Long;
-            case Int:
-                return Kind.Int;
-            case Double:
-                return Kind.Double;
-            case Float:
-                return Kind.Float;
-            case Boolean:
-                return Kind.Boolean;
-            case Illegal:
-            default:
-                return Kind.Illegal;
-        }
-    }
-
-    @Override
-    public final void simplify(SimplifierTool tool) {
-        if (isConstantFrameSlot()) {
-            if (!isValidAccessKind()) {
-                tool.deleteBranch(this.next());
-                this.replaceAndDelete(graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.UnreachedCode)));
-            } else {
-                tool.assumptions().record(new AssumptionValidAssumption((OptimizedAssumption) getConstantFrameSlot().getFrameDescriptor().getVersion()));
-            }
-        }
-    }
-
-    @Override
-    public Map<Object, Object> getDebugProperties(Map<Object, Object> map) {
-        Map<Object, Object> properties = super.getDebugProperties(map);
-        if (isConstantFrameSlot()) {
-            properties.put("frameSlot", getConstantFrameSlot().toString());
-        }
-        return properties;
-    }
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/FrameGetNode.java	Fri Aug 16 14:00:17 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +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;
-
-import sun.misc.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.Node.IterableNodeType;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.nodes.virtual.*;
-import com.oracle.graal.truffle.*;
-import com.oracle.truffle.api.frame.*;
-
-/**
- * Intrinsic node for read access to a Truffle frame.
- */
-@NodeInfo(nameTemplate = "FrameGet{p#slotKind/s}{p#frameSlot/s}")
-public class FrameGetNode extends FrameAccessNode implements IterableNodeType, Virtualizable, Lowerable {
-
-    public FrameGetNode(Kind kind, ValueNode frame, ValueNode slot, ResolvedJavaField field) {
-        super(StampFactory.forKind(kind), kind, frame, slot, field);
-    }
-
-    @Override
-    public void virtualize(VirtualizerTool tool) {
-        if (!isConstantFrameSlot()) {
-            return;
-        }
-        assert isValidAccessKind();
-        State virtualFrame = tool.getObjectState(getFrame());
-        if (virtualFrame == null || virtualFrame.getState() != EscapeState.Virtual) {
-            return;
-        }
-        assert virtualFrame.getVirtualObject().type() == NewFrameNode.FRAME_TYPE : virtualFrame;
-        VirtualInstanceNode virtualFrameObject = (VirtualInstanceNode) virtualFrame.getVirtualObject();
-        int arrayFieldIndex = virtualFrameObject.fieldIndex(field);
-        State virtualArray = tool.getObjectState(virtualFrame.getEntry(arrayFieldIndex));
-        assert virtualArray != null;
-        ValueNode result = virtualArray.getEntry(getSlotIndex());
-        State virtualResult = tool.getObjectState(result);
-        if (virtualResult != null) {
-            tool.replaceWithVirtual(virtualResult.getVirtualObject());
-        } else {
-            tool.replaceWithValue(result);
-        }
-    }
-
-    @Override
-    public void lower(LoweringTool tool, LoweringType loweringType) {
-        assert !(getFrame() instanceof NewFrameNode);
-        StructuredGraph structuredGraph = graph();
-
-        LoadFieldNode loadFieldNode = graph().add(new LoadFieldNode(getFrame(), field));
-        structuredGraph.addBeforeFixed(this, loadFieldNode);
-        FixedWithNextNode loadNode;
-        if (!getSlotKind().isPrimitive()) {
-            ValueNode slotIndex = getSlotOffset(1, tool.getRuntime());
-            loadNode = graph().add(new LoadIndexedNode(loadFieldNode, slotIndex, Kind.Object));
-        } else if (getSlotKind() == Kind.Byte) {
-            ValueNode slotIndex = getSlotOffset(1, tool.getRuntime());
-            loadNode = graph().add(new LoadIndexedNode(loadFieldNode, slotIndex, Kind.Byte));
-        } else {
-            ValueNode slotOffset = getSlotOffset(Unsafe.ARRAY_LONG_INDEX_SCALE, tool.getRuntime());
-            loadNode = graph().add(new UnsafeLoadNode(loadFieldNode, Unsafe.ARRAY_LONG_BASE_OFFSET, slotOffset, getSlotKind()));
-        }
-        structuredGraph.replaceFixedWithFixed(this, loadNode);
-    }
-
-    @NodeIntrinsic
-    public static native <T> T get(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, @ConstantNodeParameter ResolvedJavaField field);
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/FrameSetNode.java	Fri Aug 16 14:00:17 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,112 +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;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.Node.IterableNodeType;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.nodes.virtual.*;
-import com.oracle.graal.truffle.*;
-import com.oracle.truffle.api.frame.*;
-
-/**
- * Intrinsic node for write access to a Truffle frame.
- */
-@NodeInfo(nameTemplate = "FrameSet{p#slotKind/s}{p#frameSlot/s}")
-public class FrameSetNode extends FrameAccessNode implements IterableNodeType, Virtualizable, Lowerable {
-
-    @Input private ValueNode value;
-
-    public FrameSetNode(Kind kind, ValueNode frame, ValueNode frameSlot, ValueNode value, ResolvedJavaField field) {
-        super(StampFactory.forVoid(), kind, frame, frameSlot, field);
-        this.value = value;
-    }
-
-    public ValueNode getValue() {
-        return value;
-    }
-
-    @Override
-    public void virtualize(VirtualizerTool tool) {
-        if (!isConstantFrameSlot()) {
-            return;
-        }
-        assert isValidAccessKind();
-        State virtualFrame = tool.getObjectState(getFrame());
-        if (virtualFrame == null || virtualFrame.getState() != EscapeState.Virtual) {
-            return;
-        }
-        assert virtualFrame.getVirtualObject().type() == NewFrameNode.FRAME_TYPE : virtualFrame;
-        VirtualInstanceNode virtualFrameObject = (VirtualInstanceNode) virtualFrame.getVirtualObject();
-        int arrayFieldIndex = virtualFrameObject.fieldIndex(field);
-        State virtualArray = tool.getObjectState(virtualFrame.getEntry(arrayFieldIndex));
-        assert virtualArray != null;
-        ValueNode storedValue = value;
-        tool.setVirtualEntry(virtualArray, getSlotIndex(), storedValue);
-        tool.delete();
-    }
-
-    @Override
-    public void lower(LoweringTool tool, LoweringType loweringType) {
-        assert !(getFrame() instanceof NewFrameNode);
-        StructuredGraph structuredGraph = graph();
-
-        LoadFieldNode loadFieldNode = graph().add(new LoadFieldNode(getFrame(), field));
-        structuredGraph.addBeforeFixed(this, loadFieldNode);
-        FixedWithNextNode storeNode;
-        ValueNode slotIndex = getSlotOffset(1, tool.getRuntime());
-        if (!getSlotKind().isPrimitive()) {
-            storeNode = graph().add(new StoreIndexedNode(loadFieldNode, slotIndex, Kind.Object, value));
-        } else if (getSlotKind() == Kind.Byte) {
-            storeNode = graph().add(new StoreIndexedNode(loadFieldNode, slotIndex, Kind.Byte, value));
-        } else {
-            storeNode = graph().add(new StoreIndexedNode(loadFieldNode, slotIndex, Kind.Long, value));
-        }
-        structuredGraph.replaceFixedWithFixed(this, storeNode);
-    }
-
-    @NodeIntrinsic
-    public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, Object value, @ConstantNodeParameter ResolvedJavaField field);
-
-    @NodeIntrinsic
-    public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, byte value, @ConstantNodeParameter ResolvedJavaField field);
-
-    @NodeIntrinsic
-    public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, boolean value, @ConstantNodeParameter ResolvedJavaField field);
-
-    @NodeIntrinsic
-    public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, int value, @ConstantNodeParameter ResolvedJavaField field);
-
-    @NodeIntrinsic
-    public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, long value, @ConstantNodeParameter ResolvedJavaField field);
-
-    @NodeIntrinsic
-    public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, double value, @ConstantNodeParameter ResolvedJavaField field);
-
-    @NodeIntrinsic
-    public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, float value, @ConstantNodeParameter ResolvedJavaField field);
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerAddExactNode.java	Fri Aug 16 14:00:17 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +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;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-import com.oracle.truffle.api.*;
-
-/**
- * Node representing an exact integer addition that will throw an {@link ArithmeticException} in
- * case the addition would overflow the 32 bit range.
- */
-public class IntegerAddExactNode extends IntegerAddNode implements Canonicalizable, IntegerExactArithmeticNode {
-
-    public IntegerAddExactNode(ValueNode x, ValueNode y) {
-        super(x.kind(), x, y);
-        assert x.kind() == y.kind() && (x.kind() == Kind.Int || x.kind() == Kind.Long);
-    }
-
-    @Override
-    public boolean inferStamp() {
-        // TODO Should probably use a specialised version which understands that it can't overflow
-        return updateStamp(StampTool.add(x().stamp(), y().stamp()));
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        if (x().isConstant() && !y().isConstant()) {
-            return graph().unique(new IntegerAddExactNode(y(), x()));
-        }
-        if (x().isConstant()) {
-            try {
-                if (kind() == Kind.Int) {
-                    return ConstantNode.forInt(ExactMath.addExact(x().asConstant().asInt(), y().asConstant().asInt()), graph());
-                } else {
-                    assert kind() == Kind.Long;
-                    return ConstantNode.forLong(ExactMath.addExact(x().asConstant().asLong(), y().asConstant().asLong()), graph());
-                }
-            } catch (ArithmeticException ex) {
-                // The operation will result in an overflow exception, so do not canonicalize.
-            }
-        } else if (y().isConstant()) {
-            long c = y().asConstant().asLong();
-            if (c == 0) {
-                return x();
-            }
-        }
-        return this;
-    }
-
-    @Override
-    public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) {
-        return graph().add(new IntegerAddExactSplitNode(stamp(), x(), y(), next, deopt));
-    }
-
-    @Override
-    public void lower(LoweringTool tool, LoweringType loweringType) {
-        IntegerExactArithmeticSplitNode.lower(tool, this);
-    }
-
-    @NodeIntrinsic
-    public static native int addExact(int a, int b);
-
-    @NodeIntrinsic
-    public static native long addExact(long a, long b);
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerAddExactSplitNode.java	Fri Aug 16 14:00:17 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +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;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-
-public class IntegerAddExactSplitNode extends IntegerExactArithmeticSplitNode {
-
-    public IntegerAddExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) {
-        super(stamp, x, y, next, overflowSuccessor);
-    }
-
-    @Override
-    protected Value generateArithmetic(LIRGeneratorTool gen) {
-        return gen.emitAdd(gen.operand(getX()), gen.operand(getY()));
-    }
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerExactArithmeticNode.java	Fri Aug 16 14:00:17 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +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;
-
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-
-interface IntegerExactArithmeticNode extends Lowerable {
-
-    IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt);
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerExactArithmeticSplitNode.java	Fri Aug 16 14:00:17 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +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;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.gen.*;
-import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-
-public abstract class IntegerExactArithmeticSplitNode extends ControlSplitNode implements LIRGenLowerable {
-
-    @Successor private AbstractBeginNode overflowSuccessor;
-    @Successor private AbstractBeginNode next;
-    @Input private ValueNode x;
-    @Input private ValueNode y;
-
-    public IntegerExactArithmeticSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) {
-        super(stamp);
-        this.x = x;
-        this.y = y;
-        this.overflowSuccessor = overflowSuccessor;
-        this.next = next;
-    }
-
-    @Override
-    public double probability(AbstractBeginNode successor) {
-        return successor == next ? 1 : 0;
-    }
-
-    @Override
-    public void setProbability(AbstractBeginNode successor, double value) {
-        assert probability(successor) == value;
-    }
-
-    public AbstractBeginNode getNext() {
-        return next;
-    }
-
-    public AbstractBeginNode getOverflowSuccessor() {
-        return overflowSuccessor;
-    }
-
-    public ValueNode getX() {
-        return x;
-    }
-
-    public ValueNode getY() {
-        return y;
-    }
-
-    @Override
-    public void generate(LIRGenerator generator) {
-        generator.setResult(this, generateArithmetic(generator));
-        generator.emitOverflowCheckBranch(generator.getLIRBlock(getNext()), generator.getLIRBlock(getOverflowSuccessor()));
-    }
-
-    protected abstract Value generateArithmetic(LIRGeneratorTool generator);
-
-    static void lower(LoweringTool tool, IntegerExactArithmeticNode node) {
-        FloatingNode floatingNode = (FloatingNode) node;
-        FixedWithNextNode previous = tool.lastFixedNode();
-        FixedNode next = previous.next();
-        previous.setNext(null);
-        DeoptimizeNode deopt = floatingNode.graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.ArithmeticException));
-        BeginNode normalBegin = floatingNode.graph().add(new BeginNode());
-        normalBegin.setNext(next);
-        IntegerExactArithmeticSplitNode split = node.createSplit(normalBegin, BeginNode.begin(deopt));
-        previous.setNext(split);
-        floatingNode.replaceAndDelete(split);
-    }
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerMulExactNode.java	Fri Aug 16 14:00:17 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +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;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.truffle.api.*;
-
-/**
- * Node representing an exact integer multiplication that will throw an {@link ArithmeticException}
- * in case the addition would overflow the 32 bit range.
- */
-public class IntegerMulExactNode extends IntegerMulNode implements Canonicalizable, IntegerExactArithmeticNode {
-
-    public IntegerMulExactNode(ValueNode x, ValueNode y) {
-        super(x.kind(), x, y);
-        assert x.kind() == y.kind() && (x.kind() == Kind.Int || x.kind() == Kind.Long);
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        if (x().isConstant() && !y().isConstant()) {
-            return graph().unique(new IntegerMulExactNode(y(), x()));
-        }
-        if (x().isConstant()) {
-            try {
-                if (kind() == Kind.Int) {
-                    return ConstantNode.forInt(ExactMath.multiplyExact(x().asConstant().asInt(), y().asConstant().asInt()), graph());
-                } else {
-                    assert kind() == Kind.Long;
-                    return ConstantNode.forLong(ExactMath.multiplyExact(x().asConstant().asLong(), y().asConstant().asLong()), graph());
-                }
-            } catch (ArithmeticException ex) {
-                // The operation will result in an overflow exception, so do not canonicalize.
-            }
-        } else if (y().isConstant()) {
-            long c = y().asConstant().asLong();
-            if (c == 1) {
-                return x();
-            }
-            if (c == 0) {
-                return ConstantNode.defaultForKind(kind(), graph());
-            }
-        }
-        return this;
-    }
-
-    @Override
-    public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) {
-        return graph().add(new IntegerMulExactSplitNode(stamp(), x(), y(), next, deopt));
-    }
-
-    @Override
-    public void lower(LoweringTool tool, LoweringType loweringType) {
-        IntegerExactArithmeticSplitNode.lower(tool, this);
-    }
-
-    @NodeIntrinsic
-    public static native int multiplyExact(int a, int b);
-
-    @NodeIntrinsic
-    public static native long multiplyExact(long a, long b);
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerMulExactSplitNode.java	Fri Aug 16 14:00:17 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +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;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-
-public class IntegerMulExactSplitNode extends IntegerExactArithmeticSplitNode {
-
-    public IntegerMulExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) {
-        super(stamp, x, y, next, overflowSuccessor);
-    }
-
-    @Override
-    protected Value generateArithmetic(LIRGeneratorTool gen) {
-        return gen.emitMul(gen.operand(getX()), gen.operand(getY()));
-    }
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerSubExactNode.java	Fri Aug 16 14:00:17 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +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;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-import com.oracle.truffle.api.*;
-
-/**
- * Node representing an exact integer substraction that will throw an {@link ArithmeticException} in
- * case the addition would overflow the 32 bit range.
- */
-public class IntegerSubExactNode extends IntegerSubNode implements Canonicalizable, IntegerExactArithmeticNode {
-
-    public IntegerSubExactNode(ValueNode x, ValueNode y) {
-        super(x.kind(), x, y);
-        assert x.kind() == y.kind() && (x.kind() == Kind.Int || x.kind() == Kind.Long);
-    }
-
-    @Override
-    public boolean inferStamp() {
-        // TODO Should probably use a specialised version which understands that it can't overflow
-        return updateStamp(StampTool.sub(x().stamp(), y().stamp()));
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        if (x() == y()) {
-            return ConstantNode.forIntegerKind(kind(), 0, graph());
-        }
-        if (x().isConstant() && y().isConstant()) {
-            try {
-                if (kind() == Kind.Int) {
-                    return ConstantNode.forInt(ExactMath.subtractExact(x().asConstant().asInt(), y().asConstant().asInt()), graph());
-                } else {
-                    assert kind() == Kind.Long;
-                    return ConstantNode.forLong(ExactMath.subtractExact(x().asConstant().asLong(), y().asConstant().asLong()), graph());
-                }
-            } catch (ArithmeticException ex) {
-                // The operation will result in an overflow exception, so do not canonicalize.
-            }
-        } else if (y().isConstant()) {
-            long c = y().asConstant().asLong();
-            if (c == 0) {
-                return x();
-            }
-        }
-        return this;
-    }
-
-    @Override
-    public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) {
-        return graph().add(new IntegerSubExactSplitNode(stamp(), x(), y(), next, deopt));
-    }
-
-    @Override
-    public void lower(LoweringTool tool, LoweringType loweringType) {
-        IntegerExactArithmeticSplitNode.lower(tool, this);
-    }
-
-    @NodeIntrinsic
-    public static native int subtractExact(int a, int b);
-
-    @NodeIntrinsic
-    public static native long subtractExact(long a, long b);
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerSubExactSplitNode.java	Fri Aug 16 14:00:17 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +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;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-
-public class IntegerSubExactSplitNode extends IntegerExactArithmeticSplitNode {
-
-    public IntegerSubExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) {
-        super(stamp, x, y, next, overflowSuccessor);
-    }
-
-    @Override
-    protected Value generateArithmetic(LIRGeneratorTool gen) {
-        return gen.emitSub(gen.operand(getX()), gen.operand(getY()));
-    }
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/MaterializeFrameNode.java	Fri Aug 16 14:00:17 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +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;
-
-import com.oracle.graal.graph.Node.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.truffle.*;
-
-/**
- * Intrinsic node for materializing a Truffle frame.
- */
-@NodeInfo(nameTemplate = "MaterializeFrame{p#frame/s}")
-public class MaterializeFrameNode extends FixedWithNextNode implements IterableNodeType {
-
-    @Input private ValueNode frame;
-
-    public MaterializeFrameNode(ValueNode frame) {
-        super(frame.stamp());
-        this.frame = frame;
-    }
-
-    public ValueNode getFrame() {
-        return frame;
-    }
-
-    @NodeIntrinsic
-    public static native <T> T materialize(FrameWithoutBoxing frame);
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/NeverInlineMacroNode.java	Fri Aug 16 14:00:17 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +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;
-
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.replacements.nodes.*;
-
-public class NeverInlineMacroNode extends MacroNode implements com.oracle.graal.graph.Node.IterableNodeType {
-
-    public NeverInlineMacroNode(Invoke invoke) {
-        super(invoke);
-    }
-
-    @Override
-    public void lower(LoweringTool tool, LoweringType loweringType) {
-        InvokeNode invoke = createInvoke();
-        graph().replaceFixedWithFixed(this, invoke);
-        invoke.setUseForInlining(false);
-    }
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/NeverPartOfCompilationNode.java	Fri Aug 16 14:00:17 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +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;
-
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.replacements.nodes.*;
-
-public class NeverPartOfCompilationNode extends MacroNode implements com.oracle.graal.graph.Node.IterableNodeType {
-
-    private final String message;
-
-    public NeverPartOfCompilationNode(Invoke invoke) {
-        this(invoke, "This code path should never be part of a compilation.");
-    }
-
-    public NeverPartOfCompilationNode(Invoke invoke, String message) {
-        super(invoke);
-        this.message = message;
-    }
-
-    public final String getMessage() {
-        return message;
-    }
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/NewFrameNode.java	Fri Aug 16 14:00:17 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,218 +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;
-
-import java.util.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.Node.IterableNodeType;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.nodes.util.*;
-import com.oracle.graal.nodes.virtual.*;
-import com.oracle.graal.truffle.*;
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-
-/**
- * Intrinsic node representing the call for creating a frame in the {@link OptimizedCallTarget}
- * class.
- */
-public class NewFrameNode extends FixedWithNextNode implements IterableNodeType, VirtualizableAllocation, Canonicalizable {
-
-    static final ResolvedJavaType FRAME_TYPE = Graal.getRequiredCapability(MetaAccessProvider.class).lookupJavaType(FrameWithoutBoxing.class);
-
-    @Input private ValueNode descriptor;
-    @Input private ValueNode caller;
-    @Input private ValueNode arguments;
-
-    public NewFrameNode(Stamp stamp, ValueNode descriptor, ValueNode caller, ValueNode arguments) {
-        super(stamp);
-        this.descriptor = descriptor;
-        this.caller = caller;
-        this.arguments = arguments;
-    }
-
-    public NewFrameNode(ValueNode descriptor, ValueNode caller, ValueNode arguments) {
-        this(StampFactory.declaredNonNull(FRAME_TYPE), descriptor, caller, arguments);
-    }
-
-    public ValueNode getDescriptor() {
-        return descriptor;
-    }
-
-    public ValueNode getCaller() {
-        return caller;
-    }
-
-    public ValueNode getArguments() {
-        return arguments;
-    }
-
-    private FrameDescriptor getConstantFrameDescriptor() {
-        assert descriptor.isConstant() && !descriptor.isNullConstant();
-        return (FrameDescriptor) descriptor.asConstant().asObject();
-    }
-
-    private int getFrameSize() {
-        return getConstantFrameDescriptor().getSize();
-    }
-
-    private static ResolvedJavaField findField(ResolvedJavaField[] fields, String fieldName) {
-        for (ResolvedJavaField field : fields) {
-            if (field.getName().equals(fieldName)) {
-                return field;
-            }
-        }
-        throw new RuntimeException("Frame field not found: " + fieldName);
-    }
-
-    public static class VirtualOnlyInstanceNode extends VirtualInstanceNode implements Node.IterableNodeType {
-
-        private boolean allowMaterialization;
-
-        public VirtualOnlyInstanceNode(ResolvedJavaType type, ResolvedJavaField[] fields) {
-            super(type, fields);
-        }
-
-        @Override
-        public ValueNode getMaterializedRepresentation(FixedNode fixed, ValueNode[] entries, int[] locks) {
-            if (allowMaterialization) {
-                return super.getMaterializedRepresentation(fixed, entries, locks);
-            }
-            return getMaterializedRepresentationHelper(this, fixed);
-        }
-
-        public void setAllowMaterialization(boolean b) {
-            this.allowMaterialization = b;
-        }
-    }
-
-    public static ValueNode getMaterializedRepresentationHelper(VirtualObjectNode virtualNode, FixedNode fixed) {
-        if (fixed instanceof MaterializeFrameNode || fixed instanceof AbstractEndNode) {
-            // We need to conservatively assume that a materialization of a virtual frame can also
-            // happen at a merge point.
-            return new AllocatedObjectNode(virtualNode);
-        }
-        String escapeReason;
-        if (fixed instanceof StoreFieldNode) {
-            escapeReason = "Must not store virtual frame object into a field.";
-        } else if (fixed instanceof Invoke) {
-            escapeReason = "Must not pass virtual frame object into an invoke that cannot be inlined.";
-        } else {
-            escapeReason = "Must not let virtual frame object escape at node " + fixed + ".";
-        }
-
-        Throwable exception = new GraalInternalError(escapeReason +
-                        " Insert a call to VirtualFrame.materialize() to convert the instance to a materialized frame object (source position of following stack trace is approximate)");
-        throw GraphUtil.approxSourceException(fixed, exception);
-    }
-
-    @Override
-    public void virtualize(VirtualizerTool tool) {
-        int frameSize = getFrameSize();
-
-        ResolvedJavaType frameType = stamp().javaType(tool.getMetaAccessProvider());
-        ResolvedJavaField[] frameFields = frameType.getInstanceFields(true);
-
-        ResolvedJavaField descriptorField = findField(frameFields, "descriptor");
-        ResolvedJavaField callerField = findField(frameFields, "caller");
-        ResolvedJavaField argumentsField = findField(frameFields, "arguments");
-        ResolvedJavaField localsField = findField(frameFields, "locals");
-        ResolvedJavaField primitiveLocalsField = findField(frameFields, "primitiveLocals");
-        ResolvedJavaField tagsField = findField(frameFields, "tags");
-
-        VirtualObjectNode virtualFrame = new VirtualOnlyInstanceNode(frameType, frameFields);
-        VirtualObjectNode virtualFrameObjectArray = new VirtualArrayNode((ResolvedJavaType) localsField.getType().getComponentType(), frameSize);
-        VirtualObjectNode virtualFramePrimitiveArray = new VirtualArrayNode((ResolvedJavaType) primitiveLocalsField.getType().getComponentType(), frameSize);
-        VirtualObjectNode virtualFrameTagArray = new VirtualArrayNode((ResolvedJavaType) tagsField.getType().getComponentType(), frameSize);
-
-        ValueNode[] objectArrayEntryState = new ValueNode[frameSize];
-        ValueNode[] primitiveArrayEntryState = new ValueNode[frameSize];
-        ValueNode[] tagArrayEntryState = new ValueNode[frameSize];
-
-        if (frameSize > 0) {
-            FrameDescriptor frameDescriptor = getConstantFrameDescriptor();
-            ConstantNode objectDefault = ConstantNode.forObject(frameDescriptor.getTypeConversion().getDefaultValue(), tool.getMetaAccessProvider(), graph());
-            ConstantNode tagDefault = ConstantNode.forByte((byte) 0, graph());
-            for (int i = 0; i < frameSize; i++) {
-                objectArrayEntryState[i] = objectDefault;
-                primitiveArrayEntryState[i] = initialValue(frameDescriptor.getSlots().get(i).getKind());
-                tagArrayEntryState[i] = tagDefault;
-            }
-            tool.getAssumptions().record(new AssumptionValidAssumption((OptimizedAssumption) frameDescriptor.getVersion()));
-        }
-
-        tool.createVirtualObject(virtualFrameObjectArray, objectArrayEntryState, null);
-        tool.createVirtualObject(virtualFramePrimitiveArray, primitiveArrayEntryState, null);
-        tool.createVirtualObject(virtualFrameTagArray, tagArrayEntryState, null);
-
-        assert frameFields.length == 6;
-        ValueNode[] frameEntryState = new ValueNode[frameFields.length];
-        List<ResolvedJavaField> frameFieldList = Arrays.asList(frameFields);
-        frameEntryState[frameFieldList.indexOf(descriptorField)] = getDescriptor();
-        frameEntryState[frameFieldList.indexOf(callerField)] = getCaller();
-        frameEntryState[frameFieldList.indexOf(argumentsField)] = getArguments();
-        frameEntryState[frameFieldList.indexOf(localsField)] = virtualFrameObjectArray;
-        frameEntryState[frameFieldList.indexOf(primitiveLocalsField)] = virtualFramePrimitiveArray;
-        frameEntryState[frameFieldList.indexOf(tagsField)] = virtualFrameTagArray;
-        tool.createVirtualObject(virtualFrame, frameEntryState, null);
-        tool.replaceWithVirtual(virtualFrame);
-    }
-
-    private ValueNode initialValue(FrameSlotKind kind) {
-        Kind graalKind = Kind.Long;
-        switch (kind) {
-            case Int:
-                graalKind = Kind.Int;
-                break;
-            case Double:
-                graalKind = Kind.Double;
-                break;
-            case Float:
-                graalKind = Kind.Float;
-                break;
-            case Boolean:
-                graalKind = Kind.Boolean;
-                break;
-        }
-
-        return ConstantNode.defaultForKind(graalKind, graph());
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        if (usages().isEmpty()) {
-            return null;
-        } else {
-            return this;
-        }
-    }
-
-    @NodeIntrinsic
-    public static native FrameWithoutBoxing allocate(FrameDescriptor descriptor, PackedFrame caller, Arguments args);
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/UnsafeCastMacroNode.java	Fri Aug 16 14:00:17 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +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;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-
-public class UnsafeCastMacroNode extends NeverPartOfCompilationNode implements Canonicalizable {
-
-    public UnsafeCastMacroNode(Invoke invoke) {
-        super(invoke, "The class of the unsafe cast could not be reduced to a compile time constant.");
-        assert arguments.size() == 2;
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        if (arguments.get(1).isConstant()) {
-            Class c = (Class) arguments.get(1).asConstant().asObject();
-            ResolvedJavaType lookupJavaType = tool.runtime().lookupJavaType(c);
-            Stamp s = StampFactory.declaredNonNull(lookupJavaType);
-            ValueAnchorNode valueAnchorNode = graph().add(new ValueAnchorNode());
-            UnsafeCastNode unsafeCast = graph().unique(new UnsafeCastNode(arguments.get(0), s, (GuardingNode) valueAnchorNode));
-            this.replaceAtUsages(unsafeCast);
-            return valueAnchorNode;
-        }
-        return this;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java	Fri Aug 16 17:55:25 2013 +0200
@@ -0,0 +1,89 @@
+/*
+ * 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.arithmetic;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.truffle.api.*;
+
+/**
+ * Node representing an exact integer addition that will throw an {@link ArithmeticException} in
+ * case the addition would overflow the 32 bit range.
+ */
+public class IntegerAddExactNode extends IntegerAddNode implements Canonicalizable, IntegerExactArithmeticNode {
+
+    public IntegerAddExactNode(ValueNode x, ValueNode y) {
+        super(x.kind(), x, y);
+        assert x.kind() == y.kind() && (x.kind() == Kind.Int || x.kind() == Kind.Long);
+    }
+
+    @Override
+    public boolean inferStamp() {
+        // TODO Should probably use a specialised version which understands that it can't overflow
+        return updateStamp(StampTool.add(x().stamp(), y().stamp()));
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x().isConstant() && !y().isConstant()) {
+            return graph().unique(new IntegerAddExactNode(y(), x()));
+        }
+        if (x().isConstant()) {
+            try {
+                if (kind() == Kind.Int) {
+                    return ConstantNode.forInt(ExactMath.addExact(x().asConstant().asInt(), y().asConstant().asInt()), graph());
+                } else {
+                    assert kind() == Kind.Long;
+                    return ConstantNode.forLong(ExactMath.addExact(x().asConstant().asLong(), y().asConstant().asLong()), graph());
+                }
+            } catch (ArithmeticException ex) {
+                // The operation will result in an overflow exception, so do not canonicalize.
+            }
+        } else if (y().isConstant()) {
+            long c = y().asConstant().asLong();
+            if (c == 0) {
+                return x();
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) {
+        return graph().add(new IntegerAddExactSplitNode(stamp(), x(), y(), next, deopt));
+    }
+
+    @Override
+    public void lower(LoweringTool tool, LoweringType loweringType) {
+        IntegerExactArithmeticSplitNode.lower(tool, this);
+    }
+
+    @NodeIntrinsic
+    public static native int addExact(int a, int b);
+
+    @NodeIntrinsic
+    public static native long addExact(long a, long b);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactSplitNode.java	Fri Aug 16 17:55:25 2013 +0200
@@ -0,0 +1,40 @@
+/*
+ * 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.arithmetic;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+public class IntegerAddExactSplitNode extends IntegerExactArithmeticSplitNode {
+
+    public IntegerAddExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) {
+        super(stamp, x, y, next, overflowSuccessor);
+    }
+
+    @Override
+    protected Value generateArithmetic(LIRGeneratorTool gen) {
+        return gen.emitAdd(gen.operand(getX()), gen.operand(getY()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticNode.java	Fri Aug 16 17:55:25 2013 +0200
@@ -0,0 +1,31 @@
+/*
+ * 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.arithmetic;
+
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+
+interface IntegerExactArithmeticNode extends Lowerable {
+
+    IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java	Fri Aug 16 17:55:25 2013 +0200
@@ -0,0 +1,98 @@
+/*
+ * 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.arithmetic;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.spi.Lowerable.*;
+import com.oracle.graal.nodes.type.*;
+
+public abstract class IntegerExactArithmeticSplitNode extends ControlSplitNode implements LIRGenLowerable {
+
+    @Successor private AbstractBeginNode overflowSuccessor;
+    @Successor private AbstractBeginNode next;
+    @Input private ValueNode x;
+    @Input private ValueNode y;
+
+    public IntegerExactArithmeticSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) {
+        super(stamp);
+        this.x = x;
+        this.y = y;
+        this.overflowSuccessor = overflowSuccessor;
+        this.next = next;
+    }
+
+    @Override
+    public double probability(AbstractBeginNode successor) {
+        return successor == next ? 1 : 0;
+    }
+
+    @Override
+    public void setProbability(AbstractBeginNode successor, double value) {
+        assert probability(successor) == value;
+    }
+
+    public AbstractBeginNode getNext() {
+        return next;
+    }
+
+    public AbstractBeginNode getOverflowSuccessor() {
+        return overflowSuccessor;
+    }
+
+    public ValueNode getX() {
+        return x;
+    }
+
+    public ValueNode getY() {
+        return y;
+    }
+
+    @Override
+    public void generate(LIRGenerator generator) {
+        generator.setResult(this, generateArithmetic(generator));
+        generator.emitOverflowCheckBranch(generator.getLIRBlock(getNext()), generator.getLIRBlock(getOverflowSuccessor()));
+    }
+
+    protected abstract Value generateArithmetic(LIRGeneratorTool generator);
+
+    static void lower(LoweringTool tool, IntegerExactArithmeticNode node) {
+        if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) {
+            FloatingNode floatingNode = (FloatingNode) node;
+            FixedWithNextNode previous = tool.lastFixedNode();
+            FixedNode next = previous.next();
+            previous.setNext(null);
+            DeoptimizeNode deopt = floatingNode.graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.ArithmeticException));
+            BeginNode normalBegin = floatingNode.graph().add(new BeginNode());
+            normalBegin.setNext(next);
+            IntegerExactArithmeticSplitNode split = node.createSplit(normalBegin, BeginNode.begin(deopt));
+            previous.setNext(split);
+            floatingNode.replaceAndDelete(split);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java	Fri Aug 16 17:55:25 2013 +0200
@@ -0,0 +1,85 @@
+/*
+ * 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.arithmetic;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.truffle.api.*;
+
+/**
+ * Node representing an exact integer multiplication that will throw an {@link ArithmeticException}
+ * in case the addition would overflow the 32 bit range.
+ */
+public class IntegerMulExactNode extends IntegerMulNode implements Canonicalizable, IntegerExactArithmeticNode {
+
+    public IntegerMulExactNode(ValueNode x, ValueNode y) {
+        super(x.kind(), x, y);
+        assert x.kind() == y.kind() && (x.kind() == Kind.Int || x.kind() == Kind.Long);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x().isConstant() && !y().isConstant()) {
+            return graph().unique(new IntegerMulExactNode(y(), x()));
+        }
+        if (x().isConstant()) {
+            try {
+                if (kind() == Kind.Int) {
+                    return ConstantNode.forInt(ExactMath.multiplyExact(x().asConstant().asInt(), y().asConstant().asInt()), graph());
+                } else {
+                    assert kind() == Kind.Long;
+                    return ConstantNode.forLong(ExactMath.multiplyExact(x().asConstant().asLong(), y().asConstant().asLong()), graph());
+                }
+            } catch (ArithmeticException ex) {
+                // The operation will result in an overflow exception, so do not canonicalize.
+            }
+        } else if (y().isConstant()) {
+            long c = y().asConstant().asLong();
+            if (c == 1) {
+                return x();
+            }
+            if (c == 0) {
+                return ConstantNode.defaultForKind(kind(), graph());
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) {
+        return graph().add(new IntegerMulExactSplitNode(stamp(), x(), y(), next, deopt));
+    }
+
+    @Override
+    public void lower(LoweringTool tool, LoweringType loweringType) {
+        IntegerExactArithmeticSplitNode.lower(tool, this);
+    }
+
+    @NodeIntrinsic
+    public static native int multiplyExact(int a, int b);
+
+    @NodeIntrinsic
+    public static native long multiplyExact(long a, long b);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactSplitNode.java	Fri Aug 16 17:55:25 2013 +0200
@@ -0,0 +1,40 @@
+/*
+ * 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.arithmetic;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+public class IntegerMulExactSplitNode extends IntegerExactArithmeticSplitNode {
+
+    public IntegerMulExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) {
+        super(stamp, x, y, next, overflowSuccessor);
+    }
+
+    @Override
+    protected Value generateArithmetic(LIRGeneratorTool gen) {
+        return gen.emitMul(gen.operand(getX()), gen.operand(getY()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java	Fri Aug 16 17:55:25 2013 +0200
@@ -0,0 +1,89 @@
+/*
+ * 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.arithmetic;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.truffle.api.*;
+
+/**
+ * Node representing an exact integer substraction that will throw an {@link ArithmeticException} in
+ * case the addition would overflow the 32 bit range.
+ */
+public class IntegerSubExactNode extends IntegerSubNode implements Canonicalizable, IntegerExactArithmeticNode {
+
+    public IntegerSubExactNode(ValueNode x, ValueNode y) {
+        super(x.kind(), x, y);
+        assert x.kind() == y.kind() && (x.kind() == Kind.Int || x.kind() == Kind.Long);
+    }
+
+    @Override
+    public boolean inferStamp() {
+        // TODO Should probably use a specialised version which understands that it can't overflow
+        return updateStamp(StampTool.sub(x().stamp(), y().stamp()));
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x() == y()) {
+            return ConstantNode.forIntegerKind(kind(), 0, graph());
+        }
+        if (x().isConstant() && y().isConstant()) {
+            try {
+                if (kind() == Kind.Int) {
+                    return ConstantNode.forInt(ExactMath.subtractExact(x().asConstant().asInt(), y().asConstant().asInt()), graph());
+                } else {
+                    assert kind() == Kind.Long;
+                    return ConstantNode.forLong(ExactMath.subtractExact(x().asConstant().asLong(), y().asConstant().asLong()), graph());
+                }
+            } catch (ArithmeticException ex) {
+                // The operation will result in an overflow exception, so do not canonicalize.
+            }
+        } else if (y().isConstant()) {
+            long c = y().asConstant().asLong();
+            if (c == 0) {
+                return x();
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) {
+        return graph().add(new IntegerSubExactSplitNode(stamp(), x(), y(), next, deopt));
+    }
+
+    @Override
+    public void lower(LoweringTool tool, LoweringType loweringType) {
+        IntegerExactArithmeticSplitNode.lower(tool, this);
+    }
+
+    @NodeIntrinsic
+    public static native int subtractExact(int a, int b);
+
+    @NodeIntrinsic
+    public static native long subtractExact(long a, long b);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactSplitNode.java	Fri Aug 16 17:55:25 2013 +0200
@@ -0,0 +1,40 @@
+/*
+ * 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.arithmetic;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+public class IntegerSubExactSplitNode extends IntegerExactArithmeticSplitNode {
+
+    public IntegerSubExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) {
+        super(stamp, x, y, next, overflowSuccessor);
+    }
+
+    @Override
+    protected Value generateArithmetic(LIRGeneratorTool gen) {
+        return gen.emitSub(gen.operand(getX()), gen.operand(getY()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/CompilationConstantNode.java	Fri Aug 16 17:55:25 2013 +0200
@@ -0,0 +1,42 @@
+/*
+ * 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.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+
+public class CompilationConstantNode extends NeverPartOfCompilationNode implements Canonicalizable {
+
+    public CompilationConstantNode(Invoke invoke) {
+        super(invoke, "The value could not be reduced to a compile time constant.");
+        assert arguments.size() == 1;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (arguments.get(0).isConstant()) {
+            return arguments.get(0);
+        }
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverInlineMacroNode.java	Fri Aug 16 17:55:25 2013 +0200
@@ -0,0 +1,41 @@
+/*
+ * 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.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.replacements.nodes.*;
+
+public class NeverInlineMacroNode extends MacroNode implements com.oracle.graal.graph.Node.IterableNodeType {
+
+    public NeverInlineMacroNode(Invoke invoke) {
+        super(invoke);
+    }
+
+    @Override
+    public void lower(LoweringTool tool, LoweringType loweringType) {
+        InvokeNode invoke = createInvoke();
+        graph().replaceFixedWithFixed(this, invoke);
+        invoke.setUseForInlining(false);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java	Fri Aug 16 17:55:25 2013 +0200
@@ -0,0 +1,44 @@
+/*
+ * 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.nodes.*;
+import com.oracle.graal.replacements.nodes.*;
+
+public class NeverPartOfCompilationNode extends MacroNode implements com.oracle.graal.graph.Node.IterableNodeType {
+
+    private final String message;
+
+    public NeverPartOfCompilationNode(Invoke invoke) {
+        this(invoke, "This code path should never be part of a compilation.");
+    }
+
+    public NeverPartOfCompilationNode(Invoke invoke, String message) {
+        super(invoke);
+        this.message = message;
+    }
+
+    public final String getMessage() {
+        return message;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameAccessNode.java	Fri Aug 16 17:55:25 2013 +0200
@@ -0,0 +1,164 @@
+/*
+ * 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.frame;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.truffle.*;
+import com.oracle.graal.truffle.nodes.*;
+import com.oracle.truffle.api.frame.*;
+
+/**
+ * Base node class for the intrinsic nodes for read and write access to a Truffle frame.
+ */
+public abstract class FrameAccessNode extends FixedWithNextNode implements Simplifiable {
+
+    @Input private ValueNode frame;
+    @Input private ValueNode slot;
+    protected final ResolvedJavaField field;
+    protected final Kind slotKind;
+
+    public FrameAccessNode(Stamp stamp, Kind slotKind, ValueNode frame, ValueNode slot, ResolvedJavaField field) {
+        super(stamp);
+        this.slotKind = slotKind;
+        this.frame = frame;
+        this.slot = slot;
+        this.field = field;
+    }
+
+    public ValueNode getFrame() {
+        return frame;
+    }
+
+    public ValueNode getSlot() {
+        return slot;
+    }
+
+    public Kind getSlotKind() {
+        return slotKind;
+    }
+
+    protected int getSlotIndex() {
+        return getConstantFrameSlot().getIndex();
+    }
+
+    protected boolean isConstantFrameSlot() {
+        return slot.isConstant() && !slot.isNullConstant();
+    }
+
+    protected FrameSlot getConstantFrameSlot() {
+        assert isConstantFrameSlot() : slot;
+        return (FrameSlot) slot.asConstant().asObject();
+    }
+
+    protected final void insertDeoptimization(VirtualizerTool tool) {
+        LogicNode contradiction = LogicConstantNode.contradiction(graph());
+        FixedGuardNode fixedGuard = new FixedGuardNode(contradiction, DeoptimizationReason.UnreachedCode, DeoptimizationAction.InvalidateReprofile);
+        tool.addNode(fixedGuard);
+    }
+
+    @Override
+    public String toString(Verbosity verbosity) {
+        if (verbosity == Verbosity.Name) {
+            return super.toString(verbosity) + getSlotKind().name() + (isConstantFrameSlot() ? " " + getConstantFrameSlot() : "");
+        } else {
+            return super.toString(verbosity);
+        }
+    }
+
+    protected final ValueNode getSlotOffset(int scale, MetaAccessProvider metaAccessProvider) {
+        if (isConstantFrameSlot()) {
+            return ConstantNode.forInt(getSlotIndex() * scale, graph());
+        } else {
+            LoadFieldNode loadFrameSlotIndex = graph().add(new LoadFieldNode(getSlot(), metaAccessProvider.lookupJavaField(getFrameSlotIndexField())));
+            graph().addBeforeFixed(this, loadFrameSlotIndex);
+            return scale == 1 ? loadFrameSlotIndex : IntegerArithmeticNode.mul(loadFrameSlotIndex, ConstantNode.forInt(scale, graph()));
+        }
+    }
+
+    private static Field getFrameSlotIndexField() {
+        try {
+            return FrameSlotImpl.class.getDeclaredField("index");
+        } catch (NoSuchFieldException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    protected final boolean isValidAccessKind() {
+        if (getSlotKind() == Kind.Byte) {
+            // tag access
+            return true;
+        }
+
+        return getSlotKind() == getGraalKind(getConstantFrameSlot().getKind());
+    }
+
+    private static Kind getGraalKind(FrameSlotKind kind) {
+        switch (kind) {
+            case Object:
+                return Kind.Object;
+            case Long:
+                return Kind.Long;
+            case Int:
+                return Kind.Int;
+            case Double:
+                return Kind.Double;
+            case Float:
+                return Kind.Float;
+            case Boolean:
+                return Kind.Boolean;
+            case Illegal:
+            default:
+                return Kind.Illegal;
+        }
+    }
+
+    @Override
+    public final void simplify(SimplifierTool tool) {
+        if (isConstantFrameSlot()) {
+            if (!isValidAccessKind()) {
+                tool.deleteBranch(this.next());
+                this.replaceAndDelete(graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.UnreachedCode)));
+            } else {
+                tool.assumptions().record(new AssumptionValidAssumption((OptimizedAssumption) getConstantFrameSlot().getFrameDescriptor().getVersion()));
+            }
+        }
+    }
+
+    @Override
+    public Map<Object, Object> getDebugProperties(Map<Object, Object> map) {
+        Map<Object, Object> properties = super.getDebugProperties(map);
+        if (isConstantFrameSlot()) {
+            properties.put("frameSlot", getConstantFrameSlot().toString());
+        }
+        return properties;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameGetNode.java	Fri Aug 16 17:55:25 2013 +0200
@@ -0,0 +1,96 @@
+/*
+ * 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.frame;
+
+import sun.misc.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.Node.IterableNodeType;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.nodes.virtual.*;
+import com.oracle.graal.truffle.*;
+import com.oracle.truffle.api.frame.*;
+
+/**
+ * Intrinsic node for read access to a Truffle frame.
+ */
+@NodeInfo(nameTemplate = "FrameGet{p#slotKind/s}{p#frameSlot/s}")
+public class FrameGetNode extends FrameAccessNode implements IterableNodeType, Virtualizable, Lowerable {
+
+    public FrameGetNode(Kind kind, ValueNode frame, ValueNode slot, ResolvedJavaField field) {
+        super(StampFactory.forKind(kind), kind, frame, slot, field);
+    }
+
+    @Override
+    public void virtualize(VirtualizerTool tool) {
+        if (!isConstantFrameSlot()) {
+            return;
+        }
+        assert isValidAccessKind();
+        State virtualFrame = tool.getObjectState(getFrame());
+        if (virtualFrame == null || virtualFrame.getState() != EscapeState.Virtual) {
+            return;
+        }
+        assert virtualFrame.getVirtualObject().type() == NewFrameNode.FRAME_TYPE : virtualFrame;
+        VirtualInstanceNode virtualFrameObject = (VirtualInstanceNode) virtualFrame.getVirtualObject();
+        int arrayFieldIndex = virtualFrameObject.fieldIndex(field);
+        State virtualArray = tool.getObjectState(virtualFrame.getEntry(arrayFieldIndex));
+        assert virtualArray != null;
+        ValueNode result = virtualArray.getEntry(getSlotIndex());
+        State virtualResult = tool.getObjectState(result);
+        if (virtualResult != null) {
+            tool.replaceWithVirtual(virtualResult.getVirtualObject());
+        } else {
+            tool.replaceWithValue(result);
+        }
+    }
+
+    @Override
+    public void lower(LoweringTool tool, LoweringType loweringType) {
+        assert !(getFrame() instanceof NewFrameNode);
+        StructuredGraph structuredGraph = graph();
+
+        LoadFieldNode loadFieldNode = graph().add(new LoadFieldNode(getFrame(), field));
+        structuredGraph.addBeforeFixed(this, loadFieldNode);
+        FixedWithNextNode loadNode;
+        if (!getSlotKind().isPrimitive()) {
+            ValueNode slotIndex = getSlotOffset(1, tool.getRuntime());
+            loadNode = graph().add(new LoadIndexedNode(loadFieldNode, slotIndex, Kind.Object));
+        } else if (getSlotKind() == Kind.Byte) {
+            ValueNode slotIndex = getSlotOffset(1, tool.getRuntime());
+            loadNode = graph().add(new LoadIndexedNode(loadFieldNode, slotIndex, Kind.Byte));
+        } else {
+            ValueNode slotOffset = getSlotOffset(Unsafe.ARRAY_LONG_INDEX_SCALE, tool.getRuntime());
+            loadNode = graph().add(new UnsafeLoadNode(loadFieldNode, Unsafe.ARRAY_LONG_BASE_OFFSET, slotOffset, getSlotKind()));
+        }
+        structuredGraph.replaceFixedWithFixed(this, loadNode);
+    }
+
+    @NodeIntrinsic
+    public static native <T> T get(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, @ConstantNodeParameter ResolvedJavaField field);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameSetNode.java	Fri Aug 16 17:55:25 2013 +0200
@@ -0,0 +1,112 @@
+/*
+ * 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.frame;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.Node.IterableNodeType;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.nodes.virtual.*;
+import com.oracle.graal.truffle.*;
+import com.oracle.truffle.api.frame.*;
+
+/**
+ * Intrinsic node for write access to a Truffle frame.
+ */
+@NodeInfo(nameTemplate = "FrameSet{p#slotKind/s}{p#frameSlot/s}")
+public class FrameSetNode extends FrameAccessNode implements IterableNodeType, Virtualizable, Lowerable {
+
+    @Input private ValueNode value;
+
+    public FrameSetNode(Kind kind, ValueNode frame, ValueNode frameSlot, ValueNode value, ResolvedJavaField field) {
+        super(StampFactory.forVoid(), kind, frame, frameSlot, field);
+        this.value = value;
+    }
+
+    public ValueNode getValue() {
+        return value;
+    }
+
+    @Override
+    public void virtualize(VirtualizerTool tool) {
+        if (!isConstantFrameSlot()) {
+            return;
+        }
+        assert isValidAccessKind();
+        State virtualFrame = tool.getObjectState(getFrame());
+        if (virtualFrame == null || virtualFrame.getState() != EscapeState.Virtual) {
+            return;
+        }
+        assert virtualFrame.getVirtualObject().type() == NewFrameNode.FRAME_TYPE : virtualFrame;
+        VirtualInstanceNode virtualFrameObject = (VirtualInstanceNode) virtualFrame.getVirtualObject();
+        int arrayFieldIndex = virtualFrameObject.fieldIndex(field);
+        State virtualArray = tool.getObjectState(virtualFrame.getEntry(arrayFieldIndex));
+        assert virtualArray != null;
+        ValueNode storedValue = value;
+        tool.setVirtualEntry(virtualArray, getSlotIndex(), storedValue);
+        tool.delete();
+    }
+
+    @Override
+    public void lower(LoweringTool tool, LoweringType loweringType) {
+        assert !(getFrame() instanceof NewFrameNode);
+        StructuredGraph structuredGraph = graph();
+
+        LoadFieldNode loadFieldNode = graph().add(new LoadFieldNode(getFrame(), field));
+        structuredGraph.addBeforeFixed(this, loadFieldNode);
+        FixedWithNextNode storeNode;
+        ValueNode slotIndex = getSlotOffset(1, tool.getRuntime());
+        if (!getSlotKind().isPrimitive()) {
+            storeNode = graph().add(new StoreIndexedNode(loadFieldNode, slotIndex, Kind.Object, value));
+        } else if (getSlotKind() == Kind.Byte) {
+            storeNode = graph().add(new StoreIndexedNode(loadFieldNode, slotIndex, Kind.Byte, value));
+        } else {
+            storeNode = graph().add(new StoreIndexedNode(loadFieldNode, slotIndex, Kind.Long, value));
+        }
+        structuredGraph.replaceFixedWithFixed(this, storeNode);
+    }
+
+    @NodeIntrinsic
+    public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, Object value, @ConstantNodeParameter ResolvedJavaField field);
+
+    @NodeIntrinsic
+    public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, byte value, @ConstantNodeParameter ResolvedJavaField field);
+
+    @NodeIntrinsic
+    public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, boolean value, @ConstantNodeParameter ResolvedJavaField field);
+
+    @NodeIntrinsic
+    public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, int value, @ConstantNodeParameter ResolvedJavaField field);
+
+    @NodeIntrinsic
+    public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, long value, @ConstantNodeParameter ResolvedJavaField field);
+
+    @NodeIntrinsic
+    public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, double value, @ConstantNodeParameter ResolvedJavaField field);
+
+    @NodeIntrinsic
+    public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, float value, @ConstantNodeParameter ResolvedJavaField field);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/MaterializeFrameNode.java	Fri Aug 16 17:55:25 2013 +0200
@@ -0,0 +1,49 @@
+/*
+ * 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.frame;
+
+import com.oracle.graal.graph.Node.IterableNodeType;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.truffle.*;
+
+/**
+ * Intrinsic node for materializing a Truffle frame.
+ */
+@NodeInfo(nameTemplate = "MaterializeFrame{p#frame/s}")
+public class MaterializeFrameNode extends FixedWithNextNode implements IterableNodeType {
+
+    @Input private ValueNode frame;
+
+    public MaterializeFrameNode(ValueNode frame) {
+        super(frame.stamp());
+        this.frame = frame;
+    }
+
+    public ValueNode getFrame() {
+        return frame;
+    }
+
+    @NodeIntrinsic
+    public static native <T> T materialize(FrameWithoutBoxing frame);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java	Fri Aug 16 17:55:25 2013 +0200
@@ -0,0 +1,219 @@
+/*
+ * 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.frame;
+
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.Node.IterableNodeType;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.nodes.util.*;
+import com.oracle.graal.nodes.virtual.*;
+import com.oracle.graal.truffle.*;
+import com.oracle.graal.truffle.nodes.*;
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.frame.*;
+
+/**
+ * Intrinsic node representing the call for creating a frame in the {@link OptimizedCallTarget}
+ * class.
+ */
+public class NewFrameNode extends FixedWithNextNode implements IterableNodeType, VirtualizableAllocation, Canonicalizable {
+
+    static final ResolvedJavaType FRAME_TYPE = Graal.getRequiredCapability(MetaAccessProvider.class).lookupJavaType(FrameWithoutBoxing.class);
+
+    @Input private ValueNode descriptor;
+    @Input private ValueNode caller;
+    @Input private ValueNode arguments;
+
+    public NewFrameNode(Stamp stamp, ValueNode descriptor, ValueNode caller, ValueNode arguments) {
+        super(stamp);
+        this.descriptor = descriptor;
+        this.caller = caller;
+        this.arguments = arguments;
+    }
+
+    public NewFrameNode(ValueNode descriptor, ValueNode caller, ValueNode arguments) {
+        this(StampFactory.declaredNonNull(FRAME_TYPE), descriptor, caller, arguments);
+    }
+
+    public ValueNode getDescriptor() {
+        return descriptor;
+    }
+
+    public ValueNode getCaller() {
+        return caller;
+    }
+
+    public ValueNode getArguments() {
+        return arguments;
+    }
+
+    private FrameDescriptor getConstantFrameDescriptor() {
+        assert descriptor.isConstant() && !descriptor.isNullConstant();
+        return (FrameDescriptor) descriptor.asConstant().asObject();
+    }
+
+    private int getFrameSize() {
+        return getConstantFrameDescriptor().getSize();
+    }
+
+    private static ResolvedJavaField findField(ResolvedJavaField[] fields, String fieldName) {
+        for (ResolvedJavaField field : fields) {
+            if (field.getName().equals(fieldName)) {
+                return field;
+            }
+        }
+        throw new RuntimeException("Frame field not found: " + fieldName);
+    }
+
+    public static class VirtualOnlyInstanceNode extends VirtualInstanceNode implements Node.IterableNodeType {
+
+        private boolean allowMaterialization;
+
+        public VirtualOnlyInstanceNode(ResolvedJavaType type, ResolvedJavaField[] fields) {
+            super(type, fields);
+        }
+
+        @Override
+        public ValueNode getMaterializedRepresentation(FixedNode fixed, ValueNode[] entries, int[] locks) {
+            if (allowMaterialization) {
+                return super.getMaterializedRepresentation(fixed, entries, locks);
+            }
+            return getMaterializedRepresentationHelper(this, fixed);
+        }
+
+        public void setAllowMaterialization(boolean b) {
+            this.allowMaterialization = b;
+        }
+    }
+
+    public static ValueNode getMaterializedRepresentationHelper(VirtualObjectNode virtualNode, FixedNode fixed) {
+        if (fixed instanceof MaterializeFrameNode || fixed instanceof AbstractEndNode) {
+            // We need to conservatively assume that a materialization of a virtual frame can also
+            // happen at a merge point.
+            return new AllocatedObjectNode(virtualNode);
+        }
+        String escapeReason;
+        if (fixed instanceof StoreFieldNode) {
+            escapeReason = "Must not store virtual frame object into a field.";
+        } else if (fixed instanceof Invoke) {
+            escapeReason = "Must not pass virtual frame object into an invoke that cannot be inlined.";
+        } else {
+            escapeReason = "Must not let virtual frame object escape at node " + fixed + ".";
+        }
+
+        Throwable exception = new GraalInternalError(escapeReason +
+                        " Insert a call to VirtualFrame.materialize() to convert the instance to a materialized frame object (source position of following stack trace is approximate)");
+        throw GraphUtil.approxSourceException(fixed, exception);
+    }
+
+    @Override
+    public void virtualize(VirtualizerTool tool) {
+        int frameSize = getFrameSize();
+
+        ResolvedJavaType frameType = stamp().javaType(tool.getMetaAccessProvider());
+        ResolvedJavaField[] frameFields = frameType.getInstanceFields(true);
+
+        ResolvedJavaField descriptorField = findField(frameFields, "descriptor");
+        ResolvedJavaField callerField = findField(frameFields, "caller");
+        ResolvedJavaField argumentsField = findField(frameFields, "arguments");
+        ResolvedJavaField localsField = findField(frameFields, "locals");
+        ResolvedJavaField primitiveLocalsField = findField(frameFields, "primitiveLocals");
+        ResolvedJavaField tagsField = findField(frameFields, "tags");
+
+        VirtualObjectNode virtualFrame = new VirtualOnlyInstanceNode(frameType, frameFields);
+        VirtualObjectNode virtualFrameObjectArray = new VirtualArrayNode((ResolvedJavaType) localsField.getType().getComponentType(), frameSize);
+        VirtualObjectNode virtualFramePrimitiveArray = new VirtualArrayNode((ResolvedJavaType) primitiveLocalsField.getType().getComponentType(), frameSize);
+        VirtualObjectNode virtualFrameTagArray = new VirtualArrayNode((ResolvedJavaType) tagsField.getType().getComponentType(), frameSize);
+
+        ValueNode[] objectArrayEntryState = new ValueNode[frameSize];
+        ValueNode[] primitiveArrayEntryState = new ValueNode[frameSize];
+        ValueNode[] tagArrayEntryState = new ValueNode[frameSize];
+
+        if (frameSize > 0) {
+            FrameDescriptor frameDescriptor = getConstantFrameDescriptor();
+            ConstantNode objectDefault = ConstantNode.forObject(frameDescriptor.getTypeConversion().getDefaultValue(), tool.getMetaAccessProvider(), graph());
+            ConstantNode tagDefault = ConstantNode.forByte((byte) 0, graph());
+            for (int i = 0; i < frameSize; i++) {
+                objectArrayEntryState[i] = objectDefault;
+                primitiveArrayEntryState[i] = initialValue(frameDescriptor.getSlots().get(i).getKind());
+                tagArrayEntryState[i] = tagDefault;
+            }
+            tool.getAssumptions().record(new AssumptionValidAssumption((OptimizedAssumption) frameDescriptor.getVersion()));
+        }
+
+        tool.createVirtualObject(virtualFrameObjectArray, objectArrayEntryState, null);
+        tool.createVirtualObject(virtualFramePrimitiveArray, primitiveArrayEntryState, null);
+        tool.createVirtualObject(virtualFrameTagArray, tagArrayEntryState, null);
+
+        assert frameFields.length == 6;
+        ValueNode[] frameEntryState = new ValueNode[frameFields.length];
+        List<ResolvedJavaField> frameFieldList = Arrays.asList(frameFields);
+        frameEntryState[frameFieldList.indexOf(descriptorField)] = getDescriptor();
+        frameEntryState[frameFieldList.indexOf(callerField)] = getCaller();
+        frameEntryState[frameFieldList.indexOf(argumentsField)] = getArguments();
+        frameEntryState[frameFieldList.indexOf(localsField)] = virtualFrameObjectArray;
+        frameEntryState[frameFieldList.indexOf(primitiveLocalsField)] = virtualFramePrimitiveArray;
+        frameEntryState[frameFieldList.indexOf(tagsField)] = virtualFrameTagArray;
+        tool.createVirtualObject(virtualFrame, frameEntryState, null);
+        tool.replaceWithVirtual(virtualFrame);
+    }
+
+    private ValueNode initialValue(FrameSlotKind kind) {
+        Kind graalKind = Kind.Long;
+        switch (kind) {
+            case Int:
+                graalKind = Kind.Int;
+                break;
+            case Double:
+                graalKind = Kind.Double;
+                break;
+            case Float:
+                graalKind = Kind.Float;
+                break;
+            case Boolean:
+                graalKind = Kind.Boolean;
+                break;
+        }
+
+        return ConstantNode.defaultForKind(graalKind, graph());
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (usages().isEmpty()) {
+            return null;
+        } else {
+            return this;
+        }
+    }
+
+    @NodeIntrinsic
+    public static native FrameWithoutBoxing allocate(FrameDescriptor descriptor, PackedFrame caller, Arguments args);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomTypeCheckMacroNode.java	Fri Aug 16 17:55:25 2013 +0200
@@ -0,0 +1,57 @@
+/*
+ * 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.typesystem;
+
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.truffle.nodes.asserts.*;
+import com.oracle.truffle.api.*;
+
+/**
+ * Macro node for method {@link CompilerDirectives#customTypeCheck(boolean, Object, Object)}.
+ */
+public class CustomTypeCheckMacroNode extends NeverPartOfCompilationNode implements Canonicalizable {
+
+    private static final int ARGUMENT_COUNT = 3;
+    private static final int CONDITION_ARGUMENT_INDEX = 0;
+    private static final int OBJECT_ARGUMENT_INDEX = 1;
+    private static final int CUSTOM_TYPE_ARGUMENT_INDEX = 2;
+
+    public CustomTypeCheckMacroNode(Invoke invoke) {
+        super(invoke, "The custom type parameter could not be reduced to a compile time constant.");
+        assert arguments.size() == ARGUMENT_COUNT;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        ValueNode customTypeArgument = arguments.get(CUSTOM_TYPE_ARGUMENT_INDEX);
+        if (customTypeArgument.isConstant()) {
+            Object typeToken = customTypeArgument.asConstant().asObject();
+            ValueNode conditionArgument = arguments.get(CONDITION_ARGUMENT_INDEX);
+            ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX);
+            return graph().unique(new ConditionalNode(graph().unique(new CustomTypeCheckNode(conditionArgument, objectArgument, typeToken))));
+        }
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomTypeCheckNode.java	Fri Aug 16 17:55:25 2013 +0200
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2012, 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.typesystem;
+
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
+
+public final class CustomTypeCheckNode extends LogicNode implements Lowerable, com.oracle.graal.graph.Node.IterableNodeType {
+
+    @Input private ValueNode condition;
+    @Input private ValueNode object;
+    private final Object customType;
+
+    public CustomTypeCheckNode(ValueNode condition, ValueNode object, Object customType) {
+        this.condition = condition;
+        this.object = object;
+        this.customType = customType;
+    }
+
+    public ValueNode getObject() {
+        return object;
+    }
+
+    public ValueNode getCondition() {
+        return condition;
+    }
+
+    public Object getCustomType() {
+        return customType;
+    }
+
+    public void lower(LoweringTool tool, LoweringType loweringType) {
+        if (loweringType == LoweringType.BEFORE_GUARDS) {
+            this.replaceAtUsages(graph().unique(new IntegerEqualsNode(condition, ConstantNode.forInt(1, graph()))));
+            this.safeDelete();
+        }
+    }
+
+    @Override
+    public LogicNode canonical(CanonicalizerTool tool) {
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/TypeCastMacroNode.java	Fri Aug 16 17:55:25 2013 +0200
@@ -0,0 +1,66 @@
+/*
+ * 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.typesystem;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.truffle.nodes.asserts.*;
+import com.oracle.truffle.api.*;
+
+/**
+ * Macro node for method {@link CompilerDirectives#unsafeCast(Object, Class)} and
+ * {@link CompilerDirectives#unsafeCast(Object, Class, Object)}.
+ */
+public class TypeCastMacroNode extends NeverPartOfCompilationNode implements Canonicalizable {
+
+    private static final int ARGUMENT_COUNT = 3;
+    private static final int OBJECT_ARGUMENT_INDEX = 0;
+    private static final int CLASS_ARGUMENT_INDEX = 1;
+    private static final int CUSTOM_TYPE_ARGUMENT_INDEX = 2;
+
+    public TypeCastMacroNode(Invoke invoke) {
+        super(invoke, "The class of the unsafe cast could not be reduced to a compile time constant.");
+        assert arguments.size() == ARGUMENT_COUNT;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        ValueNode classArgument = arguments.get(CLASS_ARGUMENT_INDEX);
+        ValueNode customTypeArgument = arguments.get(CUSTOM_TYPE_ARGUMENT_INDEX);
+        if (classArgument.isConstant() && customTypeArgument.isConstant()) {
+            Class c = (Class) classArgument.asConstant().asObject();
+            ResolvedJavaType lookupJavaType = tool.runtime().lookupJavaType(c);
+            Stamp s = StampFactory.declaredNonNull(lookupJavaType);
+            ValueAnchorNode valueAnchorNode = graph().add(new ValueAnchorNode());
+            ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX);
+            Object customType = customTypeArgument.asConstant().asObject();
+            UnsafeCastNode unsafeCast = graph().unique(new UnsafeCastNode(objectArgument, s, valueAnchorNode, customType));
+            this.replaceAtUsages(unsafeCast);
+            return valueAnchorNode;
+        }
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeCustomizationMacroNode.java	Fri Aug 16 17:55:25 2013 +0200
@@ -0,0 +1,57 @@
+/*
+ * 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.typesystem;
+
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.truffle.nodes.asserts.*;
+import com.oracle.truffle.api.*;
+
+/**
+ * Macro node for method {@link CompilerDirectives#unsafeCustomization(Object, Object, Object)}.
+ */
+public class UnsafeCustomizationMacroNode extends NeverPartOfCompilationNode implements Canonicalizable {
+
+    private static final int ARGUMENT_COUNT = 3;
+    private static final int RECEIVER_ARGUMENT_INDEX = 0;
+    private static final int CUSTOM_TYPE_ARGUMENT_INDEX = 1;
+    private static final int LOCATION_IDENTITY_ARGUMENT_INDEX = 2;
+
+    public UnsafeCustomizationMacroNode(Invoke invoke) {
+        super(invoke, "The custom type parameter and/or the location identity could not be reduced to a compile time constant.");
+        assert arguments.size() == ARGUMENT_COUNT;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        ValueNode customTypeArgument = this.arguments.get(CUSTOM_TYPE_ARGUMENT_INDEX);
+        ValueNode locationIdentityArgument = this.arguments.get(LOCATION_IDENTITY_ARGUMENT_INDEX);
+        if (customTypeArgument.isConstant() && locationIdentityArgument.isConstant()) {
+            Object customType = customTypeArgument.asConstant().asObject();
+            Object locationIdentity = locationIdentityArgument.asConstant().asObject();
+            ValueNode receiverArgument = this.arguments.get(RECEIVER_ARGUMENT_INDEX);
+            return graph().unique(new UnsafeCustomizationNode(receiverArgument, customType, locationIdentity));
+        }
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeCustomizationNode.java	Fri Aug 16 17:55:25 2013 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012, 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.typesystem;
+
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+public final class UnsafeCustomizationNode extends FloatingNode implements LIRLowerable, com.oracle.graal.graph.Node.IterableNodeType {
+
+    @Input private ValueNode receiver;
+    private final Object customType;
+    private final Object locationIdentity;
+
+    public UnsafeCustomizationNode(ValueNode receiver, Object customType, Object locationIdentity) {
+        super(StampFactory.object());
+        this.receiver = receiver;
+        this.customType = customType;
+        this.locationIdentity = locationIdentity;
+    }
+
+    public ValueNode getReceiver() {
+        return receiver;
+    }
+
+    public Object getCustomType() {
+        return customType;
+    }
+
+    public Object getLocationIdentity() {
+        return locationIdentity;
+    }
+
+    public void generate(LIRGeneratorTool generator) {
+        generator.setResult(this, generator.operand(receiver));
+    }
+}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/VerifyFrameDoesNotEscapePhase.java	Fri Aug 16 14:00:17 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/VerifyFrameDoesNotEscapePhase.java	Fri Aug 16 17:55:25 2013 +0200
@@ -27,7 +27,7 @@
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
-import com.oracle.graal.truffle.nodes.*;
+import com.oracle.graal.truffle.nodes.frame.*;
 
 /**
  * Compiler phase for verifying that the Truffle virtual frame does not escape and can therefore be
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/VerifyNoIntrinsicsLeftPhase.java	Fri Aug 16 14:00:17 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/VerifyNoIntrinsicsLeftPhase.java	Fri Aug 16 17:55:25 2013 +0200
@@ -27,7 +27,7 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.truffle.*;
-import com.oracle.graal.truffle.nodes.*;
+import com.oracle.graal.truffle.nodes.frame.*;
 
 /**
  * Verification phase for checking that no frame intrinsic nodes introduced by the
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerAssertsSubstitutions.java	Fri Aug 16 14:00:17 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerAssertsSubstitutions.java	Fri Aug 16 17:55:25 2013 +0200
@@ -24,7 +24,7 @@
 
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.truffle.nodes.*;
+import com.oracle.graal.truffle.nodes.asserts.*;
 import com.oracle.truffle.api.*;
 
 @ClassSubstitution(CompilerAsserts.class)
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java	Fri Aug 16 14:00:17 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java	Fri Aug 16 17:55:25 2013 +0200
@@ -31,6 +31,7 @@
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.truffle.nodes.*;
+import com.oracle.graal.truffle.nodes.typesystem.*;
 import com.oracle.truffle.api.*;
 
 @ClassSubstitution(CompilerDirectives.class)
@@ -63,6 +64,12 @@
     @MacroSubstitution(macro = BailoutNode.class, isStatic = true)
     public static native void bailout(String reason);
 
-    @MacroSubstitution(macro = UnsafeCastMacroNode.class, isStatic = true)
-    public static native Object unsafeCast(Object value, Class clazz);
+    @MacroSubstitution(macro = TypeCastMacroNode.class, isStatic = true)
+    public static native Object unsafeCast(Object value, Class clazz, Object customType);
+
+    @MacroSubstitution(macro = CustomTypeCheckMacroNode.class, isStatic = true)
+    public static native boolean customTypeCheck(boolean condition, Object value, Object customType);
+
+    @MacroSubstitution(macro = UnsafeCustomizationMacroNode.class, isStatic = true)
+    public static native Object unsafeCustomization(Object receiver, Object customType, Object locationIdentity);
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/DefaultCallTargetSubstitutions.java	Fri Aug 16 14:00:17 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/DefaultCallTargetSubstitutions.java	Fri Aug 16 17:55:25 2013 +0200
@@ -24,7 +24,7 @@
 
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.truffle.nodes.*;
+import com.oracle.graal.truffle.nodes.asserts.*;
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.impl.*;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/ExactMathSubstitutions.java	Fri Aug 16 14:00:17 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/ExactMathSubstitutions.java	Fri Aug 16 17:55:25 2013 +0200
@@ -23,7 +23,7 @@
 package com.oracle.graal.truffle.substitutions;
 
 import com.oracle.graal.api.replacements.*;
-import com.oracle.graal.truffle.nodes.*;
+import com.oracle.graal.truffle.nodes.arithmetic.*;
 import com.oracle.truffle.api.*;
 
 /**
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/FrameWithoutBoxingSubstitutions.java	Fri Aug 16 14:00:17 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/FrameWithoutBoxingSubstitutions.java	Fri Aug 16 17:55:25 2013 +0200
@@ -28,7 +28,7 @@
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.truffle.*;
-import com.oracle.graal.truffle.nodes.*;
+import com.oracle.graal.truffle.nodes.frame.*;
 import com.oracle.truffle.api.frame.*;
 
 @ClassSubstitution(FrameWithoutBoxing.class)
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java	Fri Aug 16 14:00:17 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java	Fri Aug 16 17:55:25 2013 +0200
@@ -25,7 +25,8 @@
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.truffle.*;
-import com.oracle.graal.truffle.nodes.*;
+import com.oracle.graal.truffle.nodes.asserts.*;
+import com.oracle.graal.truffle.nodes.frame.*;
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.frame.*;
 
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Fri Aug 16 14:00:17 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Fri Aug 16 17:55:25 2013 +0200
@@ -145,10 +145,9 @@
      * @param clazz the specified type of the value
      * @return the value
      */
-    @SuppressWarnings("unchecked")
     @Unsafe
     public static <T> T unsafeCast(Object value, Class<T> clazz) {
-        return (T) value;
+        return unsafeCast(value, clazz, null);
     }
 
     /**
@@ -172,28 +171,30 @@
      * @param customType the custom type that if present on a value makes this unsafe cast safe
      * @return the value
      */
+    @SuppressWarnings("unchecked")
     @Unsafe
     public static <T> T unsafeCast(Object value, Class<T> clazz, Object customType) {
-        return unsafeCast(value, clazz);
+        return (T) value;
     }
 
     /**
-     * Proxies a sun.misc.Unsafe instance into an instance that adds a custom location identity on
-     * its accesses. This means that the accesses on these kind of location identities can only
-     * alias among themselves. It also allows to specify a custom type for the receiver values of
-     * follow-up unsafe accesses. Both the custom type and the location identity must evaluate to a
-     * constant. Furthermore, you should use the new sun.misc.Unsafe instance immediately for one
-     * read or write access via a sun.misc.Unsafe method and not store it anywhere.
+     * Proxies an object instance into an instance that adds a custom location identity on its
+     * accesses via sun.misc.Unsafe. This means that the accesses on these kind of location
+     * identities can only alias among themselves. It also allows to specify a custom type for the
+     * receiver values of follow-up unsafe accesses. Both the custom type and the location identity
+     * must evaluate to a constant. Furthermore, you should use the proxied receiver object
+     * immediately for one read or write access via a sun.misc.Unsafe method and not store it
+     * anywhere.
      * 
-     * @param unsafe the instance of sun.misc.Unsafe
+     * @param receiver the object that is accessed via sun.misc.Unsafe
      * @param customType the expected type of the receiver object of follow-up unsafe accesses
      * @param locationIdentity the location identity token that can be used for improved global
      *            value numbering or null
      * @return the accessed value
      */
     @Unsafe
-    public static sun.misc.Unsafe unsafeCustomization(sun.misc.Unsafe unsafe, Object customType, Object locationIdentity) {
-        return unsafe;
+    public static Object unsafeCustomization(Object receiver, Object customType, Object locationIdentity) {
+        return receiver;
     }
 
     /**
--- a/mxtool/mx.py	Fri Aug 16 14:00:17 2013 +0200
+++ b/mxtool/mx.py	Fri Aug 16 17:55:25 2013 +0200
@@ -3326,9 +3326,9 @@
     Presents a command line interface for selecting one or more (if allowMultiple is true) items.
     
     """
-    if len(items) == 0:
-        return []
-    elif len(items) > 1:
+    if len(items) <= 1:
+        return items
+    else:
         if allowMultiple:
             log('[0] <all>')
         for i in range(0, len(items)):