changeset 11312:f0c8303cf88e

Restructure Truffle API node intrinsics and introduce new intrinsics for type system modelling.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Fri, 16 Aug 2013 01:09:03 +0200
parents c08d8fd6aa19
children b7bfa2353056
files Test.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java 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 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactSplitNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactSplitNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactSplitNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/CompilationConstantNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverInlineMacroNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameAccessNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameGetNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameSetNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/MaterializeFrameNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomTypeCheckMacroNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomTypeCheckNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/TypeCastMacroNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeCustomizationMacroNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeCustomizationNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/VerifyFrameDoesNotEscapePhase.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/VerifyNoIntrinsicsLeftPhase.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerAssertsSubstitutions.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/DefaultCallTargetSubstitutions.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/ExactMathSubstitutions.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/FrameWithoutBoxingSubstitutions.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java
diffstat 51 files changed, 1653 insertions(+), 1351 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Test.java	Fri Aug 16 01:09:03 2013 +0200
@@ -0,0 +1,30 @@
+public class Test {
+   public static void main(String[] args) {
+      Test t = new Test();
+      Test2 t2 = new Test2();
+      for (int i = 0; i < 5000; ++i) {
+	      test2(t2);
+      }
+      for (int i = 0; i < 100000; ++i) {
+	      test(t);
+      }
+   }
+
+   public static int test(Object t) {
+      if (t instanceof Test) {
+          test2(t);
+      }
+      return 3;
+   }
+
+   public static int test2(Object t) {
+         if (t instanceof Test) {
+             return 1;
+         }
+         return 2;
+   }
+}
+
+
+class Test2 extends Test {
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java	Fri Aug 16 00:29:30 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java	Fri Aug 16 01:09:03 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.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Fri Aug 16 00:29:30 2013 +0200
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Fri Aug 16 01:09:03 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 00:29:30 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Fri Aug 16 01:09:03 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 00:29:30 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 00:29:30 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 00:29:30 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 00:29:30 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 00:29:30 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 00:29:30 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 00:29:30 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 00:29:30 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +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) {
-        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);
-        }
-    }
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerMulExactNode.java	Fri Aug 16 00:29:30 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 00:29:30 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 00:29:30 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 00:29:30 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 00:29:30 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 00:29:30 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 00:29:30 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 00:29:30 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 00:29:30 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 01:09:03 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 01:09:03 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 01:09:03 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 01:09:03 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 01:09:03 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 01:09:03 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 01:09:03 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 01:09:03 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 01:09:03 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 01:09:03 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 01:09:03 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 01:09:03 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 01:09:03 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 01:09:03 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 01:09:03 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 01:09:03 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 01:09:03 2013 +0200
@@ -0,0 +1,56 @@
+/*
+ * 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#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 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 01:09:03 2013 +0200
@@ -0,0 +1,60 @@
+/*
+ * 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 FloatingNode implements Lowerable {
+
+    @Input private ValueNode condition;
+    @Input private ValueNode object;
+    private final Object customType;
+
+    public CustomTypeCheckNode(ValueNode condition, ValueNode object, Object customType) {
+        super(condition.stamp());
+        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(condition);
+            this.safeDelete();
+        }
+    }
+}
--- /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 01:09:03 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 01:09:03 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 01:09:03 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 {
+
+    @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 00:29:30 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/VerifyFrameDoesNotEscapePhase.java	Fri Aug 16 01:09:03 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 00:29:30 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/VerifyNoIntrinsicsLeftPhase.java	Fri Aug 16 01:09:03 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 00:29:30 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerAssertsSubstitutions.java	Fri Aug 16 01:09:03 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 00:29:30 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java	Fri Aug 16 01:09:03 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 00:29:30 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/DefaultCallTargetSubstitutions.java	Fri Aug 16 01:09:03 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 00:29:30 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/ExactMathSubstitutions.java	Fri Aug 16 01:09:03 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 00:29:30 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/FrameWithoutBoxingSubstitutions.java	Fri Aug 16 01:09:03 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 00:29:30 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java	Fri Aug 16 01:09:03 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 00:29:30 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Fri Aug 16 01:09:03 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;
     }
 
     /**