changeset 8426:182753fdaa7f

Merge.
author Christian Humer <christian.humer@gmail.com>
date Thu, 21 Mar 2013 13:13:07 +0100
parents fbf25ec7aa5e (current diff) ba659864f935 (diff)
children 18e2856d1993
files graal/com.oracle.graal.compiler.amd64.test/src/com/oracle/graal/compiler/amd64/test/AMD64FrameOmissionTest.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/HotSpotAMD64LIRGenerator.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotSnippetInstaller.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/AESCryptSubstitutions.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopyNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CheckCastSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CipherBlockChainingSubstitutions.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ClassSubstitutions.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/InstanceOfSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/MonitorSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectCloneNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectCloneSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectSubstitutions.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/SystemSubstitutions.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ThreadSubstitutions.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/TypeCheckSnippetUtils.java graal/com.oracle.graal.snippets.amd64/src/com/oracle/graal/snippets/amd64/AMD64ConvertSnippets.java graal/com.oracle.graal.snippets.test/overview.html graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/CheckCastTest.java graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/InstanceOfDynamicTest.java graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/InstanceOfTest.java graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/IntrinsificationTest.java graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/InvokeTest.java graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/MonitorTest.java graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/NewArrayTest.java graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/NewInstanceTest.java graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/NewMultiArrayTest.java graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/PointerTest.java graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/TypeCheckTest.java graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/WordTest.java graal/com.oracle.graal.snippets/overview.html graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/ClassSubstitution.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/DoubleSubstitutions.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/FloatSubstitutions.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/GraalIntrinsics.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/InstanceOfSnippetsTemplates.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/IntegerSubstitutions.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/JavacBug.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Log.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/LongSubstitutions.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/MathSubstitutionsX86.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/NodeClassSubstitutions.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetCounter.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetFrameStateCleanupPhase.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationVerificationPhase.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetProvider.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetsInterface.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/UnsafeSubstitutions.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/UnsignedMathSubstitutions.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitCountNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanForwardNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanReverseNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BranchProbabilityNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/DirectObjectStoreNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/DirectReadNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/DirectStoreNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/ExplodeLoopNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/LoadSnippetVarargParameterNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/MacroNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/MathIntrinsicNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/ReadRegisterNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/ReverseBytesNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/WriteRegisterNode.java
diffstat 210 files changed, 12529 insertions(+), 12147 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.amd64.test/src/com/oracle/graal/compiler/amd64/test/AMD64FrameOmissionTest.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +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.compiler.amd64.test;
-
-import static com.oracle.graal.amd64.AMD64.*;
-
-import java.lang.reflect.*;
-
-import org.junit.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.compiler.test.*;
-import com.oracle.graal.phases.*;
-
-/**
- * Ensures that frame omission works in cases where it is expected to.
- */
-public class AMD64FrameOmissionTest extends GraalCompilerTest {
-
-    interface CodeGenerator {
-
-        void generateCode(AMD64Assembler asm);
-    }
-
-    public static void test1snippet() {
-        return;
-    }
-
-    @Test
-    public void test1() {
-        testHelper("test1snippet", new CodeGenerator() {
-
-            @Override
-            public void generateCode(AMD64Assembler asm) {
-                asm.ret(0);
-            }
-        });
-    }
-
-    public static int test2snippet(int x) {
-        return x + 5;
-    }
-
-    @Test
-    public void test2() {
-        testHelper("test2snippet", new CodeGenerator() {
-
-            @Override
-            public void generateCode(AMD64Assembler asm) {
-                asm.addl(rsi, 5);
-                asm.movl(rax, rsi);
-                asm.ret(0);
-            }
-        });
-    }
-
-    public static double test3snippet(double x) {
-        return 42.0D / x;
-    }
-
-    @Test
-    public void test3() {
-        testHelper("test3snippet", new CodeGenerator() {
-
-            @Override
-            public void generateCode(AMD64Assembler asm) {
-                asm.movsd(xmm1, new AMD64Address(rip, -40));
-                asm.divsd(xmm1, xmm0);
-                asm.movapd(xmm0, xmm1);
-                asm.ret(0);
-            }
-        });
-    }
-
-    private void testHelper(String name, CodeGenerator gen) {
-        Method method = getMethod(name);
-        ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(method);
-        InstalledCode installedCode = getCode(javaMethod, parse(method));
-
-        CodeCacheProvider codeCache = Graal.getRequiredCapability(CodeCacheProvider.class);
-        TargetDescription target = codeCache.getTarget();
-        RegisterConfig registerConfig = codeCache.lookupRegisterConfig();
-        AMD64Assembler asm = new AMD64Assembler(target, registerConfig);
-
-        gen.generateCode(asm);
-        for (int i = 0; i < GraalOptions.MethodEndBreakpointGuards; ++i) {
-            asm.int3();
-        }
-        while ((asm.codeBuffer.position() % 8) != 0) {
-            asm.hlt();
-        }
-
-        byte[] expectedCode = asm.codeBuffer.close(true);
-        byte[] actualCode = installedCode.getCode();
-
-        Assert.assertArrayEquals(expectedCode, actualCode);
-    }
-}
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Thu Mar 21 13:13:07 2013 +0100
@@ -369,6 +369,14 @@
     }
 
     @Override
+    public void emitNullCheck(ValueNode v) {
+        assert v.kind() == Kind.Object;
+        Variable obj = newVariable(Kind.Object);
+        emitMove(obj, operand(v));
+        append(new AMD64Move.NullCheckOp(obj, state()));
+    }
+
+    @Override
     public Variable emitNegate(Value inputVal) {
         AllocatableValue input = asAllocatable(inputVal);
         Variable result = newVariable(input.getKind());
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Thu Mar 21 13:13:07 2013 +0100
@@ -472,4 +472,9 @@
         // TODO Auto-generated method stub
 
     }
+
+    @Override
+    public void emitNullCheck(ValueNode v) {
+        throw new InternalError("NYI");
+    }
 }
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Thu Mar 21 13:13:07 2013 +0100
@@ -365,7 +365,13 @@
 
     @Override
     public void emitUnwind(Value operand) {
-        // TODO Auto-generated method stub
+        // SPARC: Auto-generated method stub
+
+    }
+
+    @Override
+    public void emitNullCheck(ValueNode v) {
+        // SPARC: Auto-generated method stub
 
     }
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Thu Mar 21 13:13:07 2013 +0100
@@ -1073,7 +1073,11 @@
     }
 
     private static boolean optimizeMethodArgument(Value value) {
-        return isStackSlot(value) && asStackSlot(value).isInCallerFrame() && (GraalOptions.IncomingMethodArgumentsGCSafe || value.getKind() != Kind.Object);
+        /*
+         * Object method arguments that are passed on the stack are currently not optimized because
+         * this requires that the runtime visits method arguments during stack walking.
+         */
+        return isStackSlot(value) && asStackSlot(value).isInCallerFrame() && value.getKind() != Kind.Object;
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.amd64.test/src/com/oracle/graal/hotspot/amd64/test/AMD64HotSpotFrameOmissionTest.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,116 @@
+/*
+ * 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.hotspot.amd64.test;
+
+import static com.oracle.graal.amd64.AMD64.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.junit.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.compiler.test.*;
+
+/**
+ * Ensures that frame omission works in cases where it is expected to.
+ */
+public class AMD64HotSpotFrameOmissionTest extends GraalCompilerTest {
+
+    interface CodeGenerator {
+
+        void generateCode(AMD64Assembler asm);
+    }
+
+    public static void test1snippet() {
+        return;
+    }
+
+    @Test
+    public void test1() {
+        testHelper("test1snippet", new CodeGenerator() {
+
+            @Override
+            public void generateCode(AMD64Assembler asm) {
+                asm.ret(0);
+            }
+        });
+    }
+
+    public static int test2snippet(int x) {
+        return x + 5;
+    }
+
+    @Test
+    public void test2() {
+        testHelper("test2snippet", new CodeGenerator() {
+
+            @Override
+            public void generateCode(AMD64Assembler asm) {
+                asm.addl(rsi, 5);
+                asm.movl(rax, rsi);
+                asm.ret(0);
+            }
+        });
+    }
+
+    public static long test3snippet(long x) {
+        return 1 + x;
+    }
+
+    @Test
+    public void test3() {
+        testHelper("test3snippet", new CodeGenerator() {
+
+            @Override
+            public void generateCode(AMD64Assembler asm) {
+                asm.addq(rsi, 1);
+                asm.movq(rax, rsi);
+                asm.ret(0);
+            }
+        });
+    }
+
+    private void testHelper(String name, CodeGenerator gen) {
+        Method method = getMethod(name);
+        ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(method);
+        InstalledCode installedCode = getCode(javaMethod, parse(method));
+
+        CodeCacheProvider codeCache = Graal.getRequiredCapability(CodeCacheProvider.class);
+        TargetDescription target = codeCache.getTarget();
+        RegisterConfig registerConfig = codeCache.lookupRegisterConfig();
+        AMD64Assembler asm = new AMD64Assembler(target, registerConfig);
+
+        gen.generateCode(asm);
+        byte[] expectedCode = asm.codeBuffer.close(true);
+
+        // Only compare up to expectedCode.length bytes to ignore
+        // padding instructions adding during code installation
+        byte[] actualCode = Arrays.copyOf(installedCode.getCode(), expectedCode.length);
+
+        Assert.assertArrayEquals(expectedCode, actualCode);
+    }
+}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Thu Mar 21 13:13:07 2013 +0100
@@ -64,7 +64,7 @@
 
     @Override
     public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, ResolvedJavaMethod method, LIR lir) {
-        return new HotSpotAMD64LIRGenerator(graph, runtime(), target, frameMap, method, lir);
+        return new AMD64HotSpotLIRGenerator(graph, runtime(), target, frameMap, method, lir);
     }
 
     /**
@@ -141,7 +141,7 @@
         // - has no callee-saved registers
         // - has no incoming arguments passed on the stack
         // - has no instructions with debug info
-        HotSpotAMD64LIRGenerator gen = (HotSpotAMD64LIRGenerator) lirGen;
+        AMD64HotSpotLIRGenerator gen = (AMD64HotSpotLIRGenerator) lirGen;
         FrameMap frameMap = gen.frameMap;
         LIR lir = gen.lir;
         boolean omitFrame = CanOmitFrame && !frameMap.frameNeedsAllocating() && !lir.hasArgInCallerFrame();
@@ -203,11 +203,5 @@
             asm.bind(unverifiedStub);
             AMD64Call.directJmp(tasm, asm, runtime().lookupRuntimeCall(IC_MISS_HANDLER));
         }
-
-        for (int i = 0; i < GraalOptions.MethodEndBreakpointGuards; ++i) {
-            asm.int3();
-        }
-
     }
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.amd64;
+
+import static com.oracle.graal.amd64.AMD64.*;
+import static com.oracle.graal.api.code.CallingConvention.Type.*;
+import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.hotspot.amd64.AMD64HotSpotUnwindOp.*;
+
+import java.util.*;
+
+import com.oracle.graal.amd64.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.*;
+import com.oracle.graal.asm.amd64.AMD64Address.*;
+import com.oracle.graal.compiler.amd64.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.hotspot.stubs.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.StandardOp.*;
+import com.oracle.graal.lir.amd64.*;
+import com.oracle.graal.lir.amd64.AMD64Move.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.cfg.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.java.MethodCallTargetNode.*;
+
+/**
+ * LIR generator specialized for AMD64 HotSpot.
+ */
+final class AMD64HotSpotLIRGenerator extends AMD64LIRGenerator implements HotSpotLIRGenerator {
+
+    private HotSpotRuntime runtime() {
+        return (HotSpotRuntime) runtime;
+    }
+
+    AMD64HotSpotLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, ResolvedJavaMethod method, LIR lir) {
+        super(graph, runtime, target, frameMap, method, lir);
+    }
+
+    /**
+     * The slot reserved for storing the original return address when a frame is marked for
+     * deoptimization. The return address slot in the callee is overwritten with the address of a
+     * deoptimization stub.
+     */
+    StackSlot deoptimizationRescueSlot;
+
+    /**
+     * The position at which the instruction for saving RBP should be inserted.
+     */
+    Block saveRbpBlock;
+    int saveRbpIndex;
+
+    /**
+     * The slot reserved for saving RBP.
+     */
+    StackSlot rbpSlot;
+
+    /**
+     * List of epilogue operations that need to restore RBP.
+     */
+    List<AMD64HotSpotEpilogueOp> epilogueOps = new ArrayList<>(2);
+
+    @Override
+    protected void emitPrologue() {
+
+        CallingConvention incomingArguments = createCallingConvention();
+
+        RegisterValue rbpParam = rbp.asValue(Kind.Long);
+        Value[] params = new Value[incomingArguments.getArgumentCount() + 1];
+        for (int i = 0; i < params.length - 1; i++) {
+            params[i] = toStackKind(incomingArguments.getArgument(i));
+            if (isStackSlot(params[i])) {
+                StackSlot slot = ValueUtil.asStackSlot(params[i]);
+                if (slot.isInCallerFrame() && !lir.hasArgInCallerFrame()) {
+                    lir.setHasArgInCallerFrame();
+                }
+            }
+        }
+        params[params.length - 1] = rbpParam;
+
+        ParametersOp paramsOp = new ParametersOp(params);
+        append(paramsOp);
+        saveRbpBlock = currentBlock;
+        saveRbpIndex = lir.lir(saveRbpBlock).size();
+        append(paramsOp); // placeholder
+        rbpSlot = frameMap.allocateSpillSlot(Kind.Long);
+        assert rbpSlot.getRawOffset() == -16 : rbpSlot.getRawOffset();
+
+        for (LocalNode local : graph.getNodes(LocalNode.class)) {
+            Value param = params[local.index()];
+            assert param.getKind() == local.kind().getStackKind();
+            setResult(local, emitMove(param));
+        }
+    }
+
+    @Override
+    protected void emitReturn(Value input) {
+        AMD64HotSpotReturnOp op = new AMD64HotSpotReturnOp(input);
+        epilogueOps.add(op);
+        append(op);
+    }
+
+    @Override
+    protected boolean needOnlyOopMaps() {
+        // Stubs only need oop maps
+        return runtime().asStub(method) != null;
+    }
+
+    @Override
+    protected CallingConvention createCallingConvention() {
+        Stub stub = runtime().asStub(method);
+        if (stub != null) {
+            return stub.getLinkage().getCallingConvention();
+        }
+
+        if (graph.getEntryBCI() == StructuredGraph.INVOCATION_ENTRY_BCI) {
+            return super.createCallingConvention();
+        } else {
+            return frameMap.registerConfig.getCallingConvention(JavaCallee, method.getSignature().getReturnType(null), new JavaType[]{runtime.lookupJavaType(long.class)}, target, false);
+        }
+    }
+
+    @Override
+    public void visitSafepointNode(SafepointNode i) {
+        LIRFrameState info = state();
+        append(new AMD64SafepointOp(info, runtime().config, this));
+    }
+
+    @Override
+    public void visitExceptionObject(ExceptionObjectNode x) {
+        HotSpotVMConfig config = runtime().config;
+        RegisterValue thread = runtime().threadRegister().asValue();
+        Value exception = emitLoad(Kind.Object, thread, config.threadExceptionOopOffset, Value.ILLEGAL, 0, false);
+        emitStore(Kind.Object, thread, config.threadExceptionOopOffset, Value.ILLEGAL, 0, Constant.NULL_OBJECT, false);
+        emitStore(Kind.Long, thread, config.threadExceptionPcOffset, Value.ILLEGAL, 0, Constant.LONG_0, false);
+        setResult(x, exception);
+    }
+
+    @SuppressWarnings("hiding")
+    @Override
+    public void visitDirectCompareAndSwap(DirectCompareAndSwapNode x) {
+        Kind kind = x.newValue().kind();
+        assert kind == x.expectedValue().kind();
+
+        Value expected = loadNonConst(operand(x.expectedValue()));
+        Variable newVal = load(operand(x.newValue()));
+
+        int disp = 0;
+        AMD64AddressValue address;
+        Value index = operand(x.offset());
+        if (ValueUtil.isConstant(index) && NumUtil.isInt(ValueUtil.asConstant(index).asLong() + disp)) {
+            assert !runtime.needsDataPatch(asConstant(index));
+            disp += (int) ValueUtil.asConstant(index).asLong();
+            address = new AMD64AddressValue(kind, load(operand(x.object())), disp);
+        } else {
+            address = new AMD64AddressValue(kind, load(operand(x.object())), load(index), Scale.Times1, disp);
+        }
+
+        RegisterValue rax = AMD64.rax.asValue(kind);
+        emitMove(rax, expected);
+        append(new CompareAndSwapOp(rax, address, rax, newVal));
+
+        Variable result = newVariable(x.kind());
+        emitMove(result, rax);
+        setResult(x, result);
+    }
+
+    @Override
+    public void emitTailcall(Value[] args, Value address) {
+        append(new AMD64TailcallOp(args, address));
+
+    }
+
+    @Override
+    protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
+        InvokeKind invokeKind = ((HotSpotDirectCallTargetNode) callTarget).invokeKind();
+        if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) {
+            append(new AMD64HotspotDirectVirtualCallOp(callTarget.target(), result, parameters, temps, callState, invokeKind));
+        } else {
+            assert invokeKind == InvokeKind.Static || invokeKind == InvokeKind.Special;
+            HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) callTarget.target();
+            Constant metaspaceMethod = resolvedMethod.getMetaspaceMethodConstant();
+            append(new AMD64HotspotDirectStaticCallOp(callTarget.target(), result, parameters, temps, callState, invokeKind, metaspaceMethod));
+        }
+    }
+
+    @Override
+    protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
+        Value metaspaceMethod = AMD64.rbx.asValue();
+        emitMove(metaspaceMethod, operand(((HotSpotIndirectCallTargetNode) callTarget).metaspaceMethod()));
+        Value targetAddress = AMD64.rax.asValue();
+        emitMove(targetAddress, operand(callTarget.computedAddress()));
+        append(new AMD64IndirectCallOp(callTarget.target(), result, parameters, temps, metaspaceMethod, targetAddress, callState));
+    }
+
+    @Override
+    public void emitUnwind(Value exception) {
+        RegisterValue exceptionParameter = EXCEPTION.asValue();
+        emitMove(exceptionParameter, exception);
+        AMD64HotSpotUnwindOp op = new AMD64HotSpotUnwindOp(exceptionParameter);
+        epilogueOps.add(op);
+        append(op);
+    }
+
+    @Override
+    public void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason) {
+        append(new AMD64DeoptimizeOp(action, reason, state()));
+    }
+
+    @Override
+    public void beforeRegisterAllocation() {
+        assert rbpSlot != null;
+        RegisterValue rbpParam = rbp.asValue(Kind.Long);
+        AllocatableValue savedRbp;
+        LIRInstruction saveRbp;
+        if (lir.hasDebugInfo()) {
+            savedRbp = rbpSlot;
+            deoptimizationRescueSlot = frameMap.allocateSpillSlot(Kind.Long);
+        } else {
+            frameMap.freeSpillSlot(rbpSlot);
+            savedRbp = newVariable(Kind.Long);
+        }
+
+        for (AMD64HotSpotEpilogueOp op : epilogueOps) {
+            op.savedRbp = savedRbp;
+        }
+
+        saveRbp = new MoveFromRegOp(savedRbp, rbpParam);
+        lir.lir(saveRbpBlock).set(saveRbpIndex, saveRbp);
+    }
+}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Thu Mar 21 13:13:07 2013 +0100
@@ -37,10 +37,10 @@
 import static com.oracle.graal.hotspot.nodes.ThreadIsInterruptedStubCall.*;
 import static com.oracle.graal.hotspot.nodes.VMErrorNode.*;
 import static com.oracle.graal.hotspot.nodes.VerifyOopStubCall.*;
-import static com.oracle.graal.hotspot.snippets.AESCryptSubstitutions.DecryptBlockStubCall.*;
-import static com.oracle.graal.hotspot.snippets.AESCryptSubstitutions.EncryptBlockStubCall.*;
-import static com.oracle.graal.hotspot.snippets.CipherBlockChainingSubstitutions.DecryptAESCryptStubCall.*;
-import static com.oracle.graal.hotspot.snippets.CipherBlockChainingSubstitutions.EncryptAESCryptStubCall.*;
+import static com.oracle.graal.hotspot.replacements.AESCryptSubstitutions.DecryptBlockStubCall.*;
+import static com.oracle.graal.hotspot.replacements.AESCryptSubstitutions.EncryptBlockStubCall.*;
+import static com.oracle.graal.hotspot.replacements.CipherBlockChainingSubstitutions.DecryptAESCryptStubCall.*;
+import static com.oracle.graal.hotspot.replacements.CipherBlockChainingSubstitutions.EncryptAESCryptStubCall.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
@@ -50,8 +50,8 @@
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.snippets.*;
-import com.oracle.graal.snippets.amd64.*;
+import com.oracle.graal.replacements.*;
+import com.oracle.graal.replacements.amd64.*;
 
 public class AMD64HotSpotRuntime extends HotSpotRuntime {
 
@@ -196,10 +196,10 @@
     private AMD64ConvertSnippets.Templates convertSnippets;
 
     @Override
-    public void installSnippets(Backend backend, SnippetInstaller installer, Assumptions assumptions) {
+    public void installReplacements(Backend backend, ReplacementsInstaller installer, Assumptions assumptions) {
         installer.installSnippets(AMD64ConvertSnippets.class);
         convertSnippets = new AMD64ConvertSnippets.Templates(this, assumptions, graalRuntime.getTarget());
-        super.installSnippets(backend, installer, assumptions);
+        super.installReplacements(backend, installer, assumptions);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/HotSpotAMD64LIRGenerator.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,255 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.amd64;
-
-import static com.oracle.graal.amd64.AMD64.*;
-import static com.oracle.graal.api.code.CallingConvention.Type.*;
-import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.hotspot.amd64.AMD64HotSpotUnwindOp.*;
-
-import java.util.*;
-
-import com.oracle.graal.amd64.*;
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.*;
-import com.oracle.graal.asm.amd64.AMD64Address.*;
-import com.oracle.graal.compiler.amd64.*;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.hotspot.nodes.*;
-import com.oracle.graal.hotspot.stubs.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.*;
-import com.oracle.graal.lir.amd64.*;
-import com.oracle.graal.lir.amd64.AMD64Move.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.cfg.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.java.MethodCallTargetNode.*;
-
-/**
- * LIR generator specialized for AMD64 HotSpot.
- */
-final class HotSpotAMD64LIRGenerator extends AMD64LIRGenerator implements HotSpotLIRGenerator {
-
-    private HotSpotRuntime runtime() {
-        return (HotSpotRuntime) runtime;
-    }
-
-    HotSpotAMD64LIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, ResolvedJavaMethod method, LIR lir) {
-        super(graph, runtime, target, frameMap, method, lir);
-    }
-
-    /**
-     * The slot reserved for storing the original return address when a frame is marked for
-     * deoptimization. The return address slot in the callee is overwritten with the address of a
-     * deoptimization stub.
-     */
-    StackSlot deoptimizationRescueSlot;
-
-    /**
-     * The position at which the instruction for saving RBP should be inserted.
-     */
-    Block saveRbpBlock;
-    int saveRbpIndex;
-
-    /**
-     * The slot reserved for saving RBP.
-     */
-    StackSlot rbpSlot;
-
-    /**
-     * List of epilogue operations that need to restore RBP.
-     */
-    List<AMD64HotSpotEpilogueOp> epilogueOps = new ArrayList<>(2);
-
-    @Override
-    protected void emitPrologue() {
-
-        CallingConvention incomingArguments = createCallingConvention();
-
-        RegisterValue rbpParam = rbp.asValue(Kind.Long);
-        Value[] params = new Value[incomingArguments.getArgumentCount() + 1];
-        for (int i = 0; i < params.length - 1; i++) {
-            params[i] = toStackKind(incomingArguments.getArgument(i));
-            if (isStackSlot(params[i])) {
-                StackSlot slot = ValueUtil.asStackSlot(params[i]);
-                if (slot.isInCallerFrame() && !lir.hasArgInCallerFrame()) {
-                    lir.setHasArgInCallerFrame();
-                }
-            }
-        }
-        params[params.length - 1] = rbpParam;
-
-        ParametersOp paramsOp = new ParametersOp(params);
-        append(paramsOp);
-        saveRbpBlock = currentBlock;
-        saveRbpIndex = lir.lir(saveRbpBlock).size();
-        append(paramsOp); // placeholder
-        rbpSlot = frameMap.allocateSpillSlot(Kind.Long);
-        assert rbpSlot.getRawOffset() == -16 : rbpSlot.getRawOffset();
-
-        for (LocalNode local : graph.getNodes(LocalNode.class)) {
-            Value param = params[local.index()];
-            assert param.getKind() == local.kind().getStackKind();
-            setResult(local, emitMove(param));
-        }
-    }
-
-    @Override
-    protected void emitReturn(Value input) {
-        AMD64HotSpotReturnOp op = new AMD64HotSpotReturnOp(input);
-        epilogueOps.add(op);
-        append(op);
-    }
-
-    @Override
-    protected boolean needOnlyOopMaps() {
-        // Stubs only need oop maps
-        return runtime().asStub(method) != null;
-    }
-
-    @Override
-    protected CallingConvention createCallingConvention() {
-        Stub stub = runtime().asStub(method);
-        if (stub != null) {
-            return stub.getLinkage().getCallingConvention();
-        }
-
-        if (graph.getEntryBCI() == StructuredGraph.INVOCATION_ENTRY_BCI) {
-            return super.createCallingConvention();
-        } else {
-            return frameMap.registerConfig.getCallingConvention(JavaCallee, method.getSignature().getReturnType(null), new JavaType[]{runtime.lookupJavaType(long.class)}, target, false);
-        }
-    }
-
-    @Override
-    public void visitSafepointNode(SafepointNode i) {
-        LIRFrameState info = state();
-        append(new AMD64SafepointOp(info, runtime().config, this));
-    }
-
-    @Override
-    public void visitExceptionObject(ExceptionObjectNode x) {
-        HotSpotVMConfig config = runtime().config;
-        RegisterValue thread = runtime().threadRegister().asValue();
-        Value exception = emitLoad(Kind.Object, thread, config.threadExceptionOopOffset, Value.ILLEGAL, 0, false);
-        emitStore(Kind.Object, thread, config.threadExceptionOopOffset, Value.ILLEGAL, 0, Constant.NULL_OBJECT, false);
-        emitStore(Kind.Long, thread, config.threadExceptionPcOffset, Value.ILLEGAL, 0, Constant.LONG_0, false);
-        setResult(x, exception);
-    }
-
-    @SuppressWarnings("hiding")
-    @Override
-    public void visitDirectCompareAndSwap(DirectCompareAndSwapNode x) {
-        Kind kind = x.newValue().kind();
-        assert kind == x.expectedValue().kind();
-
-        Value expected = loadNonConst(operand(x.expectedValue()));
-        Variable newVal = load(operand(x.newValue()));
-
-        int disp = 0;
-        AMD64AddressValue address;
-        Value index = operand(x.offset());
-        if (ValueUtil.isConstant(index) && NumUtil.isInt(ValueUtil.asConstant(index).asLong() + disp)) {
-            assert !runtime.needsDataPatch(asConstant(index));
-            disp += (int) ValueUtil.asConstant(index).asLong();
-            address = new AMD64AddressValue(kind, load(operand(x.object())), disp);
-        } else {
-            address = new AMD64AddressValue(kind, load(operand(x.object())), load(index), Scale.Times1, disp);
-        }
-
-        RegisterValue rax = AMD64.rax.asValue(kind);
-        emitMove(rax, expected);
-        append(new CompareAndSwapOp(rax, address, rax, newVal));
-
-        Variable result = newVariable(x.kind());
-        emitMove(result, rax);
-        setResult(x, result);
-    }
-
-    @Override
-    public void emitTailcall(Value[] args, Value address) {
-        append(new AMD64TailcallOp(args, address));
-
-    }
-
-    @Override
-    protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
-        InvokeKind invokeKind = ((HotSpotDirectCallTargetNode) callTarget).invokeKind();
-        if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) {
-            append(new AMD64HotspotDirectVirtualCallOp(callTarget.target(), result, parameters, temps, callState, invokeKind));
-        } else {
-            assert invokeKind == InvokeKind.Static || invokeKind == InvokeKind.Special;
-            HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) callTarget.target();
-            Constant metaspaceMethod = resolvedMethod.getMetaspaceMethodConstant();
-            append(new AMD64HotspotDirectStaticCallOp(callTarget.target(), result, parameters, temps, callState, invokeKind, metaspaceMethod));
-        }
-    }
-
-    @Override
-    protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
-        Value metaspaceMethod = AMD64.rbx.asValue();
-        emitMove(metaspaceMethod, operand(((HotSpotIndirectCallTargetNode) callTarget).metaspaceMethod()));
-        Value targetAddress = AMD64.rax.asValue();
-        emitMove(targetAddress, operand(callTarget.computedAddress()));
-        append(new AMD64IndirectCallOp(callTarget.target(), result, parameters, temps, metaspaceMethod, targetAddress, callState));
-    }
-
-    @Override
-    public void emitUnwind(Value exception) {
-        RegisterValue exceptionParameter = EXCEPTION.asValue();
-        emitMove(exceptionParameter, exception);
-        AMD64HotSpotUnwindOp op = new AMD64HotSpotUnwindOp(exceptionParameter);
-        epilogueOps.add(op);
-        append(op);
-    }
-
-    @Override
-    public void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason) {
-        append(new AMD64DeoptimizeOp(action, reason, state()));
-    }
-
-    @Override
-    public void beforeRegisterAllocation() {
-        assert rbpSlot != null;
-        RegisterValue rbpParam = rbp.asValue(Kind.Long);
-        AllocatableValue savedRbp;
-        LIRInstruction saveRbp;
-        if (lir.hasDebugInfo()) {
-            savedRbp = rbpSlot;
-            deoptimizationRescueSlot = frameMap.allocateSpillSlot(Kind.Long);
-        } else {
-            frameMap.freeSpillSlot(rbpSlot);
-            savedRbp = newVariable(Kind.Long);
-        }
-
-        for (AMD64HotSpotEpilogueOp op : epilogueOps) {
-            op.savedRbp = savedRbp;
-        }
-
-        saveRbp = new MoveFromRegOp(savedRbp, rbpParam);
-        lir.lir(saveRbpBlock).set(saveRbpIndex, saveRbp);
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Thu Mar 21 13:13:07 2013 +0100
@@ -142,7 +142,7 @@
                         if (graph == null || entryBCI != INVOCATION_ENTRY_BCI) {
                             graph = new StructuredGraph(method, entryBCI);
                         } else {
-                            // Compiling an intrinsic graph - must clone the graph
+                            // Compiling method substitution - must clone the graph
                             graph = graph.copy();
                         }
                         InlinedBytecodes.add(method.getCodeSize());
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Thu Mar 21 13:13:07 2013 +0100
@@ -36,7 +36,6 @@
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.*;
-import com.oracle.graal.snippets.*;
 
 /**
  * Singleton class holding the instance of the {@link GraalRuntime}.
@@ -251,7 +250,7 @@
     @SuppressWarnings("unchecked")
     @Override
     public <T> T getCapability(Class<T> clazz) {
-        if (clazz == GraalCodeCacheProvider.class || clazz == CodeCacheProvider.class || clazz == MetaAccessProvider.class || clazz == SnippetProvider.class) {
+        if (clazz == GraalCodeCacheProvider.class || clazz == CodeCacheProvider.class || clazz == MetaAccessProvider.class) {
             return (T) getRuntime();
         }
         if (clazz == DisassemblerProvider.class || clazz == BytecodeDisassemblerProvider.class) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsInstaller.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,63 @@
+/*
+ * 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.hotspot;
+
+import java.lang.reflect.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.replacements.*;
+import com.oracle.graal.replacements.*;
+
+/**
+ * Filters certain method substitutions based on whether there is underlying hardware support for them.
+ */
+public class HotSpotReplacementsInstaller extends ReplacementsInstaller {
+
+    private final HotSpotVMConfig config;
+
+    public HotSpotReplacementsInstaller(HotSpotRuntime runtime, Assumptions assumptions, TargetDescription target) {
+        super(runtime, assumptions, target);
+        this.config = runtime.config;
+    }
+
+    @Override
+    protected void installMethodSubstitution(Member originalMethod, Method substituteMethod) {
+        if (substituteMethod.getDeclaringClass() == IntegerSubstitutions.class || substituteMethod.getDeclaringClass() == LongSubstitutions.class) {
+            if (substituteMethod.getName().equals("bitCount")) {
+                if (!config.usePopCountInstruction) {
+                    return;
+                }
+            }
+        } else if (substituteMethod.getDeclaringClass() == AESCryptSubstitutions.class || substituteMethod.getDeclaringClass() == CipherBlockChainingSubstitutions.class) {
+            if (!config.useAESIntrinsics) {
+                return;
+            }
+            assert config.aescryptEncryptBlockStub != 0L;
+            assert config.aescryptDecryptBlockStub != 0L;
+            assert config.cipherBlockChainingEncryptAESCryptStub != 0L;
+            assert config.cipherBlockChainingDecryptAESCryptStub != 0L;
+        }
+        super.installMethodSubstitution(originalMethod, substituteMethod);
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotSnippetInstaller.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +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.hotspot;
-
-import java.lang.reflect.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.hotspot.snippets.*;
-import com.oracle.graal.snippets.*;
-
-/**
- * Filters certain intrinsifications based on whether there is underlying hardware support for them.
- */
-public class HotSpotSnippetInstaller extends SnippetInstaller {
-
-    private final HotSpotVMConfig config;
-
-    public HotSpotSnippetInstaller(HotSpotRuntime runtime, Assumptions assumptions, TargetDescription target) {
-        super(runtime, assumptions, target);
-        this.config = runtime.config;
-    }
-
-    @Override
-    protected void installMethodSubstitution(Member originalMethod, Method substituteMethod) {
-        if (substituteMethod.getDeclaringClass() == IntegerSubstitutions.class || substituteMethod.getDeclaringClass() == LongSubstitutions.class) {
-            if (substituteMethod.getName().equals("bitCount")) {
-                if (!config.usePopCountInstruction) {
-                    return;
-                }
-            }
-        } else if (substituteMethod.getDeclaringClass() == AESCryptSubstitutions.class || substituteMethod.getDeclaringClass() == CipherBlockChainingSubstitutions.class) {
-            if (!config.useAESIntrinsics) {
-                return;
-            }
-            assert config.aescryptEncryptBlockStub != 0L;
-            assert config.aescryptDecryptBlockStub != 0L;
-            assert config.cipherBlockChainingEncryptAESCryptStub != 0L;
-            assert config.cipherBlockChainingDecryptAESCryptStub != 0L;
-        }
-        super.installMethodSubstitution(originalMethod, substituteMethod);
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Thu Mar 21 13:13:07 2013 +0100
@@ -47,7 +47,7 @@
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
 import com.oracle.graal.printer.*;
-import com.oracle.graal.snippets.*;
+import com.oracle.graal.replacements.*;
 
 /**
  * Exits from the HotSpot VM into Java code.
@@ -136,7 +136,7 @@
 
         if (GraalOptions.Debug) {
             Debug.enable();
-            if (GraalOptions.DebugSnippets) {
+            if (GraalOptions.DebugReplacements) {
                 DebugEnvironment.initialize(log);
             }
         }
@@ -144,23 +144,23 @@
         // Install intrinsics.
         final HotSpotRuntime runtime = graalRuntime.getCapability(HotSpotRuntime.class);
         if (GraalOptions.Intrinsify) {
-            Debug.scope("InstallSnippets", new Object[]{new DebugDumpScope("InstallSnippets")}, new Runnable() {
+            Debug.scope("InstallReplacements", new Object[]{new DebugDumpScope("InstallReplacements")}, new Runnable() {
 
                 @Override
                 public void run() {
-                    // Snippets cannot have speculative optimizations since they have to be valid
-                    // for the entire run of the VM.
+                    // Replacements cannot have speculative optimizations since they have
+                    // to be valid for the entire run of the VM.
                     Assumptions assumptions = new Assumptions(false);
-                    SnippetInstaller installer = new HotSpotSnippetInstaller(runtime, assumptions, runtime.getGraalRuntime().getTarget());
+                    ReplacementsInstaller installer = new HotSpotReplacementsInstaller(runtime, assumptions, runtime.getGraalRuntime().getTarget());
                     GraalIntrinsics.installIntrinsics(installer);
-                    runtime.installSnippets(graalRuntime.getBackend(), installer, assumptions);
+                    runtime.installReplacements(graalRuntime.getBackend(), installer, assumptions);
                 }
             });
 
         }
 
-        if (GraalOptions.DebugSnippets) {
-            phaseTransition("snippets");
+        if (GraalOptions.DebugReplacements) {
+            phaseTransition("replacements");
         }
 
         // Create compilation queue.
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Thu Mar 21 13:13:07 2013 +0100
@@ -29,7 +29,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.phases.*;
-import com.oracle.graal.snippets.*;
+import com.oracle.graal.replacements.*;
 
 /**
  * Represents a field in a HotSpot type.
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Thu Mar 21 13:13:07 2013 +0100
@@ -30,11 +30,11 @@
 import static com.oracle.graal.api.meta.Value.*;
 import static com.oracle.graal.graph.UnsafeAccess.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
-import static com.oracle.graal.hotspot.snippets.SystemSubstitutions.*;
+import static com.oracle.graal.hotspot.replacements.SystemSubstitutions.*;
 import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*;
 import static com.oracle.graal.nodes.java.RegisterFinalizerNode.*;
-import static com.oracle.graal.snippets.Log.*;
-import static com.oracle.graal.snippets.MathSubstitutionsX86.*;
+import static com.oracle.graal.replacements.Log.*;
+import static com.oracle.graal.replacements.MathSubstitutionsX86.*;
 
 import java.lang.reflect.*;
 import java.util.*;
@@ -57,7 +57,7 @@
 import com.oracle.graal.hotspot.bridge.CompilerToVM.CodeInstallResult;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.hotspot.phases.*;
-import com.oracle.graal.hotspot.snippets.*;
+import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.nodes.*;
@@ -69,13 +69,13 @@
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.printer.*;
-import com.oracle.graal.snippets.*;
+import com.oracle.graal.replacements.*;
 import com.oracle.graal.word.*;
 
 /**
  * HotSpot implementation of {@link GraalCodeCacheProvider}.
  */
-public abstract class HotSpotRuntime implements GraalCodeCacheProvider, SnippetProvider, DisassemblerProvider, BytecodeDisassemblerProvider {
+public abstract class HotSpotRuntime implements GraalCodeCacheProvider, DisassemblerProvider, BytecodeDisassemblerProvider {
 
     public final HotSpotVMConfig config;
 
@@ -319,7 +319,7 @@
 
     protected abstract RegisterConfig createRegisterConfig(boolean globalStubConfig);
 
-    public void installSnippets(Backend backend, SnippetInstaller installer, Assumptions assumptions) {
+    public void installReplacements(Backend backend, ReplacementsInstaller installer, Assumptions assumptions) {
         if (GraalOptions.IntrinsifyObjectMethods) {
             installer.installSubstitutions(ObjectSubstitutions.class);
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -52,8 +52,8 @@
     }
 
     @Override
-    public Object getLocationIdentity() {
-        return LocationNode.ANY_LOCATION;
+    public Object[] getLocationIdentities() {
+        return new Object[]{LocationNode.ANY_LOCATION};
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -70,8 +70,8 @@
     }
 
     @Override
-    public Object getLocationIdentity() {
-        return locationIdentity;
+    public Object[] getLocationIdentities() {
+        return new Object[]{locationIdentity};
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EndLockScopeNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EndLockScopeNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -44,8 +44,8 @@
     }
 
     @Override
-    public Object getLocationIdentity() {
-        return LocationNode.ANY_LOCATION;
+    public Object[] getLocationIdentities() {
+        return new Object[]{LocationNode.ANY_LOCATION};
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -31,7 +31,7 @@
 import com.oracle.graal.lir.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.snippets.*;
+import com.oracle.graal.replacements.*;
 
 /**
  * Causes the VM to exit with a description of the current Java location and an optional
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.replacements;
+
+import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*;
+import sun.misc.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.replacements.*;
+import com.oracle.graal.replacements.ClassSubstitution.*;
+import com.oracle.graal.word.*;
+
+/**
+ * Substitutions for {@code com.sun.crypto.provider.AESCrypt} methods.
+ */
+@ClassSubstitution(className = "com.sun.crypto.provider.AESCrypt", optional = true)
+public class AESCryptSubstitutions {
+
+    static final long kOffset;
+    static final Class<?> AESCryptClass;
+
+    static {
+        try {
+            // Need to use launcher class path as com.sun.crypto.provider.AESCrypt
+            // is normally not on the boot class path
+            ClassLoader cl = Launcher.getLauncher().getClassLoader();
+            AESCryptClass = Class.forName("com.sun.crypto.provider.AESCrypt", true, cl);
+            kOffset = UnsafeAccess.unsafe.objectFieldOffset(AESCryptClass.getDeclaredField("K"));
+        } catch (Exception ex) {
+            throw new GraalInternalError(ex);
+        }
+    }
+
+    @MethodSubstitution(isStatic = false)
+    static void encryptBlock(Object rcvr, byte[] in, int inOffset, byte[] out, int outOffset) {
+        crypt(rcvr, in, inOffset, out, outOffset, true);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    static void decryptBlock(Object rcvr, byte[] in, int inOffset, byte[] out, int outOffset) {
+        crypt(rcvr, in, inOffset, out, outOffset, false);
+    }
+
+    private static void crypt(Object rcvr, byte[] in, int inOffset, byte[] out, int outOffset, boolean encrypt) {
+        Word kAddr = Word.fromObject(rcvr).readWord(Word.unsigned(kOffset), UNKNOWN_LOCATION).add(arrayBaseOffset(Kind.Byte));
+        Word inAddr = Word.unsigned(GetObjectAddressNode.get(in) + arrayBaseOffset(Kind.Byte) + inOffset);
+        Word outAddr = Word.unsigned(GetObjectAddressNode.get(out) + arrayBaseOffset(Kind.Byte) + outOffset);
+        if (encrypt) {
+            EncryptBlockStubCall.call(inAddr, outAddr, kAddr);
+        } else {
+            DecryptBlockStubCall.call(inAddr, outAddr, kAddr);
+        }
+    }
+
+    abstract static class CryptBlockStubCall extends FixedWithNextNode implements LIRGenLowerable {
+
+        @Input private final ValueNode in;
+        @Input private final ValueNode out;
+        @Input private final ValueNode key;
+
+        private final Descriptor descriptor;
+
+        public CryptBlockStubCall(ValueNode in, ValueNode out, ValueNode key, Descriptor descriptor) {
+            super(StampFactory.forVoid());
+            this.in = in;
+            this.out = out;
+            this.key = key;
+            this.descriptor = descriptor;
+        }
+
+        @Override
+        public void generate(LIRGenerator gen) {
+            RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(descriptor);
+            gen.emitCall(stub, stub.getCallingConvention(), false, gen.operand(in), gen.operand(out), gen.operand(key));
+        }
+    }
+
+    public static class EncryptBlockStubCall extends CryptBlockStubCall {
+
+        public static final Descriptor ENCRYPT_BLOCK = new Descriptor("encrypt_block", false, void.class, Word.class, Word.class, Word.class);
+
+        public EncryptBlockStubCall(ValueNode in, ValueNode out, ValueNode key) {
+            super(in, out, key, ENCRYPT_BLOCK);
+        }
+
+        @NodeIntrinsic
+        public static native void call(Word in, Word out, Word key);
+    }
+
+    public static class DecryptBlockStubCall extends CryptBlockStubCall {
+
+        public static final Descriptor DECRYPT_BLOCK = new Descriptor("decrypt_block", false, void.class, Word.class, Word.class, Word.class);
+
+        public DecryptBlockStubCall(ValueNode in, ValueNode out, ValueNode key) {
+            super(in, out, key, DECRYPT_BLOCK);
+        }
+
+        @NodeIntrinsic
+        public static native void call(Word in, Word out, Word key);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,172 @@
+/*
+ * 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.hotspot.replacements;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.Node.IterableNodeType;
+import com.oracle.graal.loop.phases.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.virtual.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.common.*;
+import com.oracle.graal.replacements.nodes.*;
+
+public class ArrayCopyNode extends MacroNode implements Virtualizable, IterableNodeType, Lowerable {
+
+    public ArrayCopyNode(Invoke invoke) {
+        super(invoke);
+    }
+
+    private ValueNode getSource() {
+        return arguments.get(0);
+    }
+
+    private ValueNode getSourcePosition() {
+        return arguments.get(1);
+    }
+
+    private ValueNode getDestination() {
+        return arguments.get(2);
+    }
+
+    private ValueNode getDestinationPosition() {
+        return arguments.get(3);
+    }
+
+    private ValueNode getLength() {
+        return arguments.get(4);
+    }
+
+    private StructuredGraph selectSnippet(LoweringTool tool) {
+        ResolvedJavaType srcType = getSource().objectStamp().type();
+        ResolvedJavaType destType = getDestination().objectStamp().type();
+
+        if (srcType == null || !srcType.isArray() || destType == null || !destType.isArray()) {
+            return null;
+        }
+        if (!destType.getComponentType().isAssignableFrom(srcType.getComponentType()) || !getDestination().objectStamp().isExactType()) {
+            return null;
+        }
+        Kind componentKind = srcType.getComponentType().getKind();
+        ResolvedJavaMethod snippetMethod = tool.getRuntime().lookupJavaMethod(ArrayCopySnippets.getSnippetForKind(componentKind));
+        return (StructuredGraph) snippetMethod.getCompilerStorage().get(Graph.class);
+    }
+
+    private static void unrollFixedLengthLoop(StructuredGraph snippetGraph, int length, LoweringTool tool) {
+        LocalNode lengthLocal = snippetGraph.getLocal(4);
+        if (lengthLocal != null) {
+            snippetGraph.replaceFloating(lengthLocal, ConstantNode.forInt(length, snippetGraph));
+        }
+        // the canonicalization before loop unrolling is needed to propagate the length into
+        // additions, etc.
+        new CanonicalizerPhase(tool.getRuntime(), tool.assumptions()).apply(snippetGraph);
+        new LoopFullUnrollPhase(tool.getRuntime(), tool.assumptions()).apply(snippetGraph);
+        new CanonicalizerPhase(tool.getRuntime(), tool.assumptions()).apply(snippetGraph);
+    }
+
+    private static void replaceSnippetInvokes(StructuredGraph snippetGraph, ResolvedJavaMethod targetMethod, int bci) {
+        for (InvokeNode invoke : snippetGraph.getNodes(InvokeNode.class)) {
+            if (invoke.methodCallTarget().targetMethod() != targetMethod) {
+                throw new GraalInternalError("unexpected invoke in arraycopy snippet");
+            }
+            if (invoke.stateAfter().bci == FrameState.INVALID_FRAMESTATE_BCI) {
+                InvokeNode newInvoke = snippetGraph.add(new InvokeNode(invoke.methodCallTarget(), bci));
+                newInvoke.setStateAfter(snippetGraph.add(new FrameState(FrameState.AFTER_BCI)));
+                snippetGraph.replaceFixedWithFixed(invoke, newInvoke);
+            } else {
+                assert invoke.stateAfter().bci == FrameState.AFTER_BCI : invoke;
+            }
+        }
+    }
+
+    @Override
+    protected StructuredGraph getSnippetGraph(LoweringTool tool) {
+        if (!GraalOptions.IntrinsifyArrayCopy) {
+            return null;
+        }
+
+        StructuredGraph snippetGraph = selectSnippet(tool);
+        if (snippetGraph == null) {
+            ResolvedJavaMethod snippetMethod = tool.getRuntime().lookupJavaMethod(ArrayCopySnippets.genericArraycopySnippet);
+            snippetGraph = ((StructuredGraph) snippetMethod.getCompilerStorage().get(Graph.class)).copy();
+            assert snippetGraph != null : "ArrayCopySnippets should be installed";
+
+            replaceSnippetInvokes(snippetGraph, getTargetMethod(), getBci());
+        } else {
+            assert snippetGraph != null : "ArrayCopySnippets should be installed";
+
+            if (getLength().isConstant()) {
+                snippetGraph = snippetGraph.copy();
+                unrollFixedLengthLoop(snippetGraph, getLength().asConstant().asInt(), tool);
+            }
+        }
+        return snippetGraph;
+    }
+
+    private static boolean checkBounds(int position, int length, VirtualObjectNode virtualObject) {
+        return position >= 0 && position + length <= virtualObject.entryCount();
+    }
+
+    private static boolean checkEntryTypes(int srcPos, int length, State srcState, ResolvedJavaType destComponentType) {
+        if (destComponentType.getKind() == Kind.Object) {
+            for (int i = 0; i < length; i++) {
+                if (!destComponentType.isAssignableFrom(srcState.getEntry(srcPos + i).objectStamp().type())) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public void virtualize(VirtualizerTool tool) {
+        if (getSourcePosition().isConstant() && getDestinationPosition().isConstant() && getLength().isConstant()) {
+            int srcPos = getSourcePosition().asConstant().asInt();
+            int destPos = getDestinationPosition().asConstant().asInt();
+            int length = getLength().asConstant().asInt();
+            State srcState = tool.getObjectState(getSource());
+            State destState = tool.getObjectState(getDestination());
+
+            if (srcState != null && srcState.getState() == EscapeState.Virtual && destState != null && destState.getState() == EscapeState.Virtual) {
+                VirtualObjectNode srcVirtual = srcState.getVirtualObject();
+                VirtualObjectNode destVirtual = destState.getVirtualObject();
+                if (length < 0 || !checkBounds(srcPos, length, srcVirtual) || !checkBounds(destPos, length, destVirtual)) {
+                    return;
+                }
+                if (!checkEntryTypes(srcPos, length, srcState, destVirtual.type().getComponentType())) {
+                    return;
+                }
+                for (int i = 0; i < length; i++) {
+                    tool.setVirtualEntry(destState, destPos + i, srcState.getEntry(srcPos + i));
+                }
+                tool.delete();
+                if (Debug.isLogEnabled()) {
+                    Debug.log("virtualized arraycopyf(%s, %d, %s, %d, %d)", getSource(), srcPos, getDestination(), destPos, length);
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,359 @@
+/*
+ * Copyright (c) 2011, 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.hotspot.replacements;
+
+import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*;
+import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.replacements.*;
+import com.oracle.graal.replacements.Snippet.*;
+import com.oracle.graal.replacements.nodes.*;
+import com.oracle.graal.word.*;
+
+@SuppressWarnings("unused")
+public class ArrayCopySnippets implements Snippets {
+
+    private static final EnumMap<Kind, Method> arraycopyMethods = new EnumMap<>(Kind.class);
+    public static final Method genericArraycopySnippet;
+
+    private static void addArraycopySnippetMethod(Kind kind, Class<?> arrayClass) throws NoSuchMethodException {
+        arraycopyMethods.put(kind, ArrayCopySnippets.class.getDeclaredMethod("arraycopy", arrayClass, int.class, arrayClass, int.class, int.class));
+    }
+
+    static {
+        try {
+            addArraycopySnippetMethod(Kind.Byte, byte[].class);
+            addArraycopySnippetMethod(Kind.Boolean, boolean[].class);
+            addArraycopySnippetMethod(Kind.Char, char[].class);
+            addArraycopySnippetMethod(Kind.Short, short[].class);
+            addArraycopySnippetMethod(Kind.Int, int[].class);
+            addArraycopySnippetMethod(Kind.Long, long[].class);
+            addArraycopySnippetMethod(Kind.Float, float[].class);
+            addArraycopySnippetMethod(Kind.Double, double[].class);
+            addArraycopySnippetMethod(Kind.Object, Object[].class);
+            genericArraycopySnippet = ArrayCopySnippets.class.getDeclaredMethod("arraycopy", Object.class, int.class, Object.class, int.class, int.class);
+        } catch (SecurityException | NoSuchMethodException e) {
+            throw new GraalInternalError(e);
+        }
+    }
+
+    public static Method getSnippetForKind(Kind kind) {
+        return arraycopyMethods.get(kind);
+    }
+
+    private static final Kind VECTOR_KIND = Kind.Long;
+    private static final long VECTOR_SIZE = arrayIndexScale(Kind.Long);
+
+    public static void vectorizedCopy(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter("baseKind") Kind baseKind) {
+        checkNonNull(src);
+        checkNonNull(dest);
+        checkLimits(src, srcPos, dest, destPos, length);
+        int header = arrayBaseOffset(baseKind);
+        int elementSize = arrayIndexScale(baseKind);
+        long byteLength = (long) length * elementSize;
+        long nonVectorBytes = byteLength % VECTOR_SIZE;
+        long srcOffset = (long) srcPos * elementSize;
+        long destOffset = (long) destPos * elementSize;
+        if (src == dest && srcPos < destPos) { // bad aliased case
+            probability(NOT_FREQUENT_PROBABILITY);
+            for (long i = byteLength - elementSize; i >= byteLength - nonVectorBytes; i -= elementSize) {
+                UnsafeStoreNode.store(dest, header, i + destOffset, UnsafeLoadNode.load(src, header, i + srcOffset, baseKind), baseKind);
+            }
+            long vectorLength = byteLength - nonVectorBytes;
+            for (long i = vectorLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) {
+                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
+            }
+        } else {
+            for (long i = 0; i < nonVectorBytes; i += elementSize) {
+                UnsafeStoreNode.store(dest, header, i + destOffset, UnsafeLoadNode.load(src, header, i + srcOffset, baseKind), baseKind);
+            }
+            for (long i = nonVectorBytes; i < byteLength; i += VECTOR_SIZE) {
+                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
+            }
+        }
+    }
+
+    public static void checkNonNull(Object obj) {
+        if (obj == null) {
+            probability(DEOPT_PATH_PROBABILITY);
+            checkNPECounter.inc();
+            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
+        }
+    }
+
+    public static int checkArrayType(Word hub) {
+        int layoutHelper = readLayoutHelper(hub);
+        if (layoutHelper >= 0) {
+            probability(DEOPT_PATH_PROBABILITY);
+            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
+        }
+        return layoutHelper;
+    }
+
+    public static void checkLimits(Object src, int srcPos, Object dest, int destPos, int length) {
+        if (srcPos < 0) {
+            probability(DEOPT_PATH_PROBABILITY);
+            checkAIOOBECounter.inc();
+            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
+        }
+        if (destPos < 0) {
+            probability(DEOPT_PATH_PROBABILITY);
+            checkAIOOBECounter.inc();
+            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
+        }
+        if (length < 0) {
+            probability(DEOPT_PATH_PROBABILITY);
+            checkAIOOBECounter.inc();
+            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
+        }
+        if (srcPos + length > ArrayLengthNode.arrayLength(src)) {
+            probability(DEOPT_PATH_PROBABILITY);
+            checkAIOOBECounter.inc();
+            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
+        }
+        if (destPos + length > ArrayLengthNode.arrayLength(dest)) {
+            probability(DEOPT_PATH_PROBABILITY);
+            checkAIOOBECounter.inc();
+            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
+        }
+        checkSuccessCounter.inc();
+    }
+
+    @Snippet
+    public static void arraycopy(byte[] src, int srcPos, byte[] dest, int destPos, int length) {
+        byteCounter.inc();
+        vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Byte);
+    }
+
+    @Snippet
+    public static void arraycopy(boolean[] src, int srcPos, boolean[] dest, int destPos, int length) {
+        booleanCounter.inc();
+        vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Byte);
+    }
+
+    @Snippet
+    public static void arraycopy(char[] src, int srcPos, char[] dest, int destPos, int length) {
+        charCounter.inc();
+        vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Char);
+    }
+
+    @Snippet
+    public static void arraycopy(short[] src, int srcPos, short[] dest, int destPos, int length) {
+        shortCounter.inc();
+        vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Short);
+    }
+
+    @Snippet
+    public static void arraycopy(int[] src, int srcPos, int[] dest, int destPos, int length) {
+        intCounter.inc();
+        vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Int);
+    }
+
+    @Snippet
+    public static void arraycopy(float[] src, int srcPos, float[] dest, int destPos, int length) {
+        floatCounter.inc();
+        vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Float);
+    }
+
+    @Snippet
+    public static void arraycopy(long[] src, int srcPos, long[] dest, int destPos, int length) {
+        longCounter.inc();
+        checkNonNull(src);
+        checkNonNull(dest);
+        checkLimits(src, srcPos, dest, destPos, length);
+        Kind baseKind = Kind.Long;
+        int header = arrayBaseOffset(baseKind);
+        long byteLength = (long) length * arrayIndexScale(baseKind);
+        long srcOffset = (long) srcPos * arrayIndexScale(baseKind);
+        long destOffset = (long) destPos * arrayIndexScale(baseKind);
+        if (src == dest && srcPos < destPos) { // bad aliased case
+            for (long i = byteLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) {
+                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
+            }
+        } else {
+            for (long i = 0; i < byteLength; i += VECTOR_SIZE) {
+                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
+            }
+        }
+    }
+
+    @Snippet
+    public static void arraycopy(double[] src, int srcPos, double[] dest, int destPos, int length) {
+        doubleCounter.inc();
+        checkNonNull(src);
+        checkNonNull(dest);
+        checkLimits(src, srcPos, dest, destPos, length);
+        Kind baseKind = Kind.Double;
+        int header = arrayBaseOffset(baseKind);
+        long byteLength = (long) length * arrayIndexScale(baseKind);
+        long srcOffset = (long) srcPos * arrayIndexScale(baseKind);
+        long destOffset = (long) destPos * arrayIndexScale(baseKind);
+        if (src == dest && srcPos < destPos) { // bad aliased case
+            for (long i = byteLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) {
+                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
+            }
+        } else {
+            for (long i = 0; i < byteLength; i += VECTOR_SIZE) {
+                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
+            }
+        }
+    }
+
+    // Does NOT perform store checks
+    @Snippet
+    public static void arraycopy(Object[] src, int srcPos, Object[] dest, int destPos, int length) {
+        objectCounter.inc();
+        checkNonNull(src);
+        checkNonNull(dest);
+        checkLimits(src, srcPos, dest, destPos, length);
+        final int scale = arrayIndexScale(Kind.Object);
+        int header = arrayBaseOffset(Kind.Object);
+        if (src == dest && srcPos < destPos) { // bad aliased case
+            long start = (long) (length - 1) * scale;
+            for (long i = start; i >= 0; i -= scale) {
+                Object a = UnsafeLoadNode.load(src, header, i + (long) srcPos * scale, Kind.Object);
+                DirectObjectStoreNode.storeObject(dest, header, i + (long) destPos * scale, a);
+            }
+        } else {
+            long end = (long) length * scale;
+            for (long i = 0; i < end; i += scale) {
+                Object a = UnsafeLoadNode.load(src, header, i + (long) srcPos * scale, Kind.Object);
+                DirectObjectStoreNode.storeObject(dest, header, i + (long) destPos * scale, a);
+            }
+        }
+        if (length > 0) {
+            int cardShift = cardTableShift();
+            long cardStart = cardTableStart();
+            long dstAddr = GetObjectAddressNode.get(dest);
+            long start = (dstAddr + header + (long) destPos * scale) >>> cardShift;
+            long end = (dstAddr + header + ((long) destPos + length - 1) * scale) >>> cardShift;
+            long count = end - start + 1;
+            while (count-- > 0) {
+                DirectStoreNode.store((start + cardStart) + count, false, Kind.Boolean);
+            }
+        }
+    }
+
+    @Snippet
+    public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) {
+
+        // loading the hubs also checks for nullness
+        Word srcHub = loadHub(src);
+        Word destHub = loadHub(dest);
+
+        int layoutHelper = checkArrayType(srcHub);
+        if (srcHub.equal(destHub) && src != dest) {
+            probability(FAST_PATH_PROBABILITY);
+
+            checkLimits(src, srcPos, dest, destPos, length);
+
+            arraycopyInnerloop(src, srcPos, dest, destPos, length, layoutHelper);
+        } else {
+            genericObjectCallCounter.inc();
+            System.arraycopy(src, srcPos, dest, destPos, length);
+        }
+    }
+
+    public static void arraycopyInnerloop(Object src, int srcPos, Object dest, int destPos, int length, int layoutHelper) {
+        int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask();
+        int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift()) & layoutHelperHeaderSizeMask();
+
+        Word memory = (Word) Word.fromObject(src);
+
+        Word srcOffset = (Word) Word.fromObject(src).add(headerSize).add(srcPos << log2ElementSize);
+        Word destOffset = (Word) Word.fromObject(dest).add(headerSize).add(destPos << log2ElementSize);
+        Word destStart = destOffset;
+        long sizeInBytes = ((long) length) << log2ElementSize;
+        Word destEnd = destOffset.add(Word.unsigned(length).shiftLeft(log2ElementSize));
+
+        int nonVectorBytes = (int) (sizeInBytes % VECTOR_SIZE);
+        Word destNonVectorEnd = destStart.add(nonVectorBytes);
+
+        while (destOffset.belowThan(destNonVectorEnd)) {
+            destOffset.writeByte(0, srcOffset.readByte(0, UNKNOWN_LOCATION), ANY_LOCATION);
+            destOffset = destOffset.add(1);
+            srcOffset = srcOffset.add(1);
+        }
+        while (destOffset.belowThan(destEnd)) {
+            destOffset.writeWord(0, srcOffset.readWord(0, UNKNOWN_LOCATION), ANY_LOCATION);
+            destOffset = destOffset.add(wordSize());
+            srcOffset = srcOffset.add(wordSize());
+        }
+
+        if ((layoutHelper & layoutHelperElementTypePrimitiveInPlace()) != 0) {
+            genericPrimitiveCallCounter.inc();
+
+        } else {
+            probability(LIKELY_PROBABILITY);
+            genericObjectExactCallCounter.inc();
+
+            if (length > 0) {
+                int cardShift = cardTableShift();
+                long cardStart = cardTableStart();
+                Word destCardOffset = destStart.unsignedShiftRight(cardShift).add(Word.unsigned(cardStart));
+                Word destCardEnd = destEnd.subtract(1).unsignedShiftRight(cardShift).add(Word.unsigned(cardStart));
+                while (destCardOffset.belowOrEqual(destCardEnd)) {
+                    DirectStoreNode.store(destCardOffset.rawValue(), false, Kind.Boolean);
+                    destCardOffset = destCardOffset.add(1);
+                }
+            }
+        }
+    }
+
+    private static final SnippetCounter.Group checkCounters = GraalOptions.SnippetCounters ? new SnippetCounter.Group("System.arraycopy checkInputs") : null;
+    private static final SnippetCounter checkSuccessCounter = new SnippetCounter(checkCounters, "checkSuccess", "checkSuccess");
+    private static final SnippetCounter checkNPECounter = new SnippetCounter(checkCounters, "checkNPE", "checkNPE");
+    private static final SnippetCounter checkAIOOBECounter = new SnippetCounter(checkCounters, "checkAIOOBE", "checkAIOOBE");
+
+    private static final SnippetCounter.Group counters = GraalOptions.SnippetCounters ? new SnippetCounter.Group("System.arraycopy") : null;
+    private static final SnippetCounter byteCounter = new SnippetCounter(counters, "byte[]", "arraycopy for byte[] arrays");
+    private static final SnippetCounter charCounter = new SnippetCounter(counters, "char[]", "arraycopy for char[] arrays");
+    private static final SnippetCounter shortCounter = new SnippetCounter(counters, "short[]", "arraycopy for short[] arrays");
+    private static final SnippetCounter intCounter = new SnippetCounter(counters, "int[]", "arraycopy for int[] arrays");
+    private static final SnippetCounter booleanCounter = new SnippetCounter(counters, "boolean[]", "arraycopy for boolean[] arrays");
+    private static final SnippetCounter longCounter = new SnippetCounter(counters, "long[]", "arraycopy for long[] arrays");
+    private static final SnippetCounter objectCounter = new SnippetCounter(counters, "Object[]", "arraycopy for Object[] arrays");
+    private static final SnippetCounter floatCounter = new SnippetCounter(counters, "float[]", "arraycopy for float[] arrays");
+    private static final SnippetCounter doubleCounter = new SnippetCounter(counters, "double[]", "arraycopy for double[] arrays");
+    private static final SnippetCounter genericPrimitiveCallCounter = new SnippetCounter(counters, "genericPrimitive", "generic arraycopy snippet for primitive arrays");
+    private static final SnippetCounter genericObjectExactCallCounter = new SnippetCounter(counters, "genericObjectExact", "generic arraycopy snippet for special object arrays");
+    private static final SnippetCounter genericObjectCallCounter = new SnippetCounter(counters, "genericObject", "call to the generic, native arraycopy method");
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.replacements;
+
+import static com.oracle.graal.api.code.DeoptimizationAction.*;
+import static com.oracle.graal.api.meta.DeoptimizationReason.*;
+import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*;
+import static com.oracle.graal.hotspot.replacements.TypeCheckSnippetUtils.*;
+import static com.oracle.graal.nodes.extended.UnsafeCastNode.*;
+import static com.oracle.graal.replacements.SnippetTemplate.*;
+import static com.oracle.graal.replacements.SnippetTemplate.Arguments.*;
+import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.Node.NodeIntrinsic;
+import com.oracle.graal.hotspot.meta.*;
+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.phases.*;
+import com.oracle.graal.replacements.*;
+import com.oracle.graal.replacements.Snippet.*;
+import com.oracle.graal.replacements.nodes.*;
+import com.oracle.graal.word.*;
+
+/**
+ * Snippets used for implementing the type test of a checkcast instruction.
+ * 
+ * The type tests implemented are described in the paper <a
+ * href="http://dl.acm.org/citation.cfm?id=583821"> Fast subtype checking in the HotSpot JVM</a> by
+ * Cliff Click and John Rose.
+ */
+public class CheckCastSnippets implements Snippets {
+
+    @NodeIntrinsic(BreakpointNode.class)
+    static native void bkpt(Object object, Word hub, Word objectHub);
+
+    // @formatter:off
+
+    /**
+     * Type test used when the type being tested against is a final type.
+     */
+    @Snippet
+    public static Object checkcastExact(
+                    @Parameter("object") Object object,
+                    @Parameter("exactHub") Word exactHub,
+                    @ConstantParameter("checkNull") boolean checkNull) {
+        if (checkNull && object == null) {
+            probability(NOT_FREQUENT_PROBABILITY);
+            isNull.inc();
+        } else {
+            Word objectHub = loadHub(object);
+            if (objectHub.notEqual(exactHub)) {
+                probability(DEOPT_PATH_PROBABILITY);
+                exactMiss.inc();
+                //bkpt(object, exactHub, objectHub);
+                DeoptimizeNode.deopt(InvalidateReprofile, ClassCastException);
+            }
+            exactHit.inc();
+        }
+        return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic());
+    }
+
+    /**
+     * Type test used when the type being tested against is a restricted primary type.
+     *
+     * This test ignores use of hints altogether as the display-based type check only
+     * involves one extra load where the second load should hit the same cache line as the
+     * first.
+     */
+    @Snippet
+    public static Object checkcastPrimary(
+                    @Parameter("hub") Word hub,
+                    @Parameter("object") Object object,
+                    @ConstantParameter("checkNull") boolean checkNull,
+                    @ConstantParameter("superCheckOffset") int superCheckOffset) {
+        if (checkNull && object == null) {
+            probability(NOT_FREQUENT_PROBABILITY);
+            isNull.inc();
+        } else {
+            Word objectHub = loadHub(object);
+            if (objectHub.readWord(superCheckOffset, FINAL_LOCATION).notEqual(hub)) {
+                probability(DEOPT_PATH_PROBABILITY);
+                displayMiss.inc();
+                DeoptimizeNode.deopt(InvalidateReprofile, ClassCastException);
+            }
+            displayHit.inc();
+        }
+        return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic());
+    }
+
+    /**
+     * Type test used when the type being tested against is a restricted secondary type.
+     */
+    @Snippet
+    public static Object checkcastSecondary(
+                    @Parameter("hub") Word hub,
+                    @Parameter("object") Object object,
+                    @VarargsParameter("hints") Word[] hints,
+                    @ConstantParameter("checkNull") boolean checkNull) {
+        if (checkNull && object == null) {
+            probability(NOT_FREQUENT_PROBABILITY);
+            isNull.inc();
+        } else {
+            Word objectHub = loadHub(object);
+            // if we get an exact match: succeed immediately
+            ExplodeLoopNode.explodeLoop();
+            for (int i = 0; i < hints.length; i++) {
+                Word hintHub = hints[i];
+                if (hintHub.equal(objectHub)) {
+                    hintsHit.inc();
+                    return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic());
+                }
+            }
+            if (!checkSecondarySubType(hub, objectHub)) {
+                DeoptimizeNode.deopt(InvalidateReprofile, ClassCastException);
+            }
+        }
+        return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic());
+    }
+
+    /**
+     * Type test used when the type being tested against is not known at compile time (e.g. the type test
+     * in an object array store check).
+     */
+    @Snippet
+    public static Object checkcastDynamic(
+                    @Parameter("hub") Word hub,
+                    @Parameter("object") Object object,
+                    @ConstantParameter("checkNull") boolean checkNull) {
+        if (checkNull && object == null) {
+            probability(NOT_FREQUENT_PROBABILITY);
+            isNull.inc();
+        } else {
+            Word objectHub = loadHub(object);
+            if (!checkUnknownSubType(hub, objectHub)) {
+                DeoptimizeNode.deopt(InvalidateReprofile, ClassCastException);
+            }
+        }
+        return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic());
+    }
+
+    // @formatter:on
+
+    public static class Templates extends AbstractTemplates<CheckCastSnippets> {
+
+        private final ResolvedJavaMethod exact;
+        private final ResolvedJavaMethod primary;
+        private final ResolvedJavaMethod secondary;
+        private final ResolvedJavaMethod dynamic;
+
+        public Templates(CodeCacheProvider runtime, Assumptions assumptions, TargetDescription target) {
+            super(runtime, assumptions, target, CheckCastSnippets.class);
+            exact = snippet("checkcastExact", Object.class, Word.class, boolean.class);
+            primary = snippet("checkcastPrimary", Word.class, Object.class, boolean.class, int.class);
+            secondary = snippet("checkcastSecondary", Word.class, Object.class, Word[].class, boolean.class);
+            dynamic = snippet("checkcastDynamic", Word.class, Object.class, boolean.class);
+        }
+
+        /**
+         * Lowers a checkcast node.
+         */
+        public void lower(CheckCastNode checkcast, LoweringTool tool) {
+            StructuredGraph graph = (StructuredGraph) checkcast.graph();
+            ValueNode object = checkcast.object();
+            final HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) checkcast.type();
+            TypeCheckHints hintInfo = new TypeCheckHints(checkcast.type(), checkcast.profile(), tool.assumptions(), GraalOptions.CheckcastMinHintHitProbability, GraalOptions.CheckcastMaxHints);
+            ValueNode hub = ConstantNode.forConstant(type.klass(), runtime, checkcast.graph());
+            boolean checkNull = !object.stamp().nonNull();
+            Arguments arguments;
+            Key key;
+
+            assert type != null;
+            if (hintInfo.exact) {
+                ConstantNode[] hints = createHints(hintInfo, runtime, graph);
+                assert hints.length == 1;
+                key = new Key(exact).add("checkNull", checkNull);
+                arguments = arguments("object", object).add("exactHub", hints[0]);
+            } else if (type.isPrimaryType()) {
+                key = new Key(primary).add("checkNull", checkNull).add("superCheckOffset", type.superCheckOffset());
+                arguments = arguments("hub", hub).add("object", object);
+            } else {
+                ConstantNode[] hints = createHints(hintInfo, runtime, graph);
+                key = new Key(secondary).add("hints", Varargs.vargargs(new Word[hints.length], StampFactory.forKind(wordKind()))).add("checkNull", checkNull);
+                arguments = arguments("hub", hub).add("object", object).add("hints", hints);
+            }
+
+            SnippetTemplate template = cache.get(key, assumptions);
+            Debug.log("Lowering checkcast in %s: node=%s, template=%s, arguments=%s", graph, checkcast, template, arguments);
+            template.instantiate(runtime, checkcast, DEFAULT_REPLACER, arguments);
+        }
+
+        /**
+         * Lowers a dynamic checkcast node.
+         */
+        public void lower(CheckCastDynamicNode checkcast) {
+            StructuredGraph graph = (StructuredGraph) checkcast.graph();
+            ValueNode hub = checkcast.type();
+            ValueNode object = checkcast.object();
+            boolean checkNull = !object.stamp().nonNull();
+
+            Key key = new Key(dynamic).add("checkNull", checkNull);
+            Arguments arguments = arguments("hub", hub).add("object", object);
+
+            SnippetTemplate template = cache.get(key, assumptions);
+            Debug.log("Lowering dynamic checkcast in %s: node=%s, template=%s, arguments=%s", graph, checkcast, template, arguments);
+            template.instantiate(runtime, checkcast, DEFAULT_REPLACER, arguments);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.replacements;
+
+import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*;
+import sun.misc.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.replacements.*;
+import com.oracle.graal.replacements.ClassSubstitution.*;
+import com.oracle.graal.replacements.Snippet.*;
+import com.oracle.graal.word.*;
+
+/**
+ * Substitutions for {@code com.sun.crypto.provider.CipherBlockChaining} methods.
+ */
+@ClassSubstitution(className = "com.sun.crypto.provider.CipherBlockChaining", optional = true)
+public class CipherBlockChainingSubstitutions {
+
+    private static final long embeddedCipherOffset;
+    private static final long rOffset;
+    static {
+        try {
+            // Need to use launcher class path as com.sun.crypto.provider.AESCrypt
+            // is normally not on the boot class path
+            ClassLoader cl = Launcher.getLauncher().getClassLoader();
+            embeddedCipherOffset = UnsafeAccess.unsafe.objectFieldOffset(Class.forName("com.sun.crypto.provider.FeedbackCipher", true, cl).getDeclaredField("embeddedCipher"));
+            rOffset = UnsafeAccess.unsafe.objectFieldOffset(Class.forName("com.sun.crypto.provider.CipherBlockChaining", true, cl).getDeclaredField("r"));
+        } catch (Exception ex) {
+            throw new GraalInternalError(ex);
+        }
+    }
+
+    @Fold
+    private static Class getAESCryptClass() {
+        return AESCryptSubstitutions.AESCryptClass;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    static void encrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) {
+        Object embeddedCipher = Word.fromObject(rcvr).readObject(Word.unsigned(embeddedCipherOffset), UNKNOWN_LOCATION);
+        if (getAESCryptClass().isInstance(embeddedCipher)) {
+            crypt(rcvr, in, inOffset, inLength, out, outOffset, embeddedCipher, true);
+        } else {
+            encrypt(rcvr, in, inOffset, inLength, out, outOffset);
+        }
+    }
+
+    private static void crypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset, Object embeddedCipher, boolean encrypt) {
+        Word kAddr = Word.fromObject(embeddedCipher).readWord(Word.unsigned(AESCryptSubstitutions.kOffset), UNKNOWN_LOCATION).add(arrayBaseOffset(Kind.Byte));
+        Word rAddr = Word.unsigned(GetObjectAddressNode.get(rcvr)).readWord(Word.unsigned(rOffset), UNKNOWN_LOCATION).add(arrayBaseOffset(Kind.Byte));
+        Word inAddr = Word.unsigned(GetObjectAddressNode.get(in) + arrayBaseOffset(Kind.Byte) + inOffset);
+        Word outAddr = Word.unsigned(GetObjectAddressNode.get(out) + arrayBaseOffset(Kind.Byte) + outOffset);
+        if (encrypt) {
+            EncryptAESCryptStubCall.call(inAddr, outAddr, kAddr, rAddr, inLength);
+        } else {
+            DecryptAESCryptStubCall.call(inAddr, outAddr, kAddr, rAddr, inLength);
+        }
+
+    }
+
+    @MethodSubstitution(isStatic = false)
+    static void decrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) {
+        Object embeddedCipher = Word.fromObject(rcvr).readObject(Word.unsigned(embeddedCipherOffset), UNKNOWN_LOCATION);
+        if (in != out && getAESCryptClass().isInstance(embeddedCipher)) {
+            crypt(rcvr, in, inOffset, inLength, out, outOffset, embeddedCipher, false);
+        } else {
+            decrypt(rcvr, in, inOffset, inLength, out, outOffset);
+        }
+    }
+
+    abstract static class AESCryptStubCall extends FixedWithNextNode implements LIRGenLowerable {
+
+        @Input private final ValueNode in;
+        @Input private final ValueNode out;
+        @Input private final ValueNode key;
+        @Input private final ValueNode r;
+        @Input private final ValueNode inLength;
+
+        private final Descriptor descriptor;
+
+        public AESCryptStubCall(ValueNode in, ValueNode out, ValueNode key, ValueNode r, ValueNode inLength, Descriptor descriptor) {
+            super(StampFactory.forVoid());
+            this.in = in;
+            this.out = out;
+            this.key = key;
+            this.r = r;
+            this.inLength = inLength;
+            this.descriptor = descriptor;
+        }
+
+        @Override
+        public void generate(LIRGenerator gen) {
+            RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(descriptor);
+            gen.emitCall(stub, stub.getCallingConvention(), false, gen.operand(in), gen.operand(out), gen.operand(key), gen.operand(r), gen.operand(inLength));
+        }
+    }
+
+    public static class EncryptAESCryptStubCall extends AESCryptStubCall {
+
+        public static final Descriptor ENCRYPT = new Descriptor("encrypt", false, void.class, Word.class, Word.class, Word.class, Word.class, int.class);
+
+        public EncryptAESCryptStubCall(ValueNode in, ValueNode out, ValueNode key, ValueNode r, ValueNode inLength) {
+            super(in, out, key, r, inLength, ENCRYPT);
+        }
+
+        @NodeIntrinsic
+        public static native void call(Word in, Word out, Word key, Word r, int inLength);
+    }
+
+    public static class DecryptAESCryptStubCall extends AESCryptStubCall {
+
+        public static final Descriptor DECRYPT = new Descriptor("decrypt", false, void.class, Word.class, Word.class, Word.class, Word.class, int.class);
+
+        public DecryptAESCryptStubCall(ValueNode in, ValueNode out, ValueNode key, ValueNode r, ValueNode inLength) {
+            super(in, out, key, r, inLength, DECRYPT);
+        }
+
+        @NodeIntrinsic
+        public static native void call(Word in, Word out, Word key, Word r, int inLength);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassSubstitutions.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.replacements;
+
+import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*;
+import static com.oracle.graal.nodes.extended.UnsafeCastNode.*;
+
+import java.lang.reflect.*;
+
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.replacements.*;
+import com.oracle.graal.replacements.ClassSubstitution.*;
+import com.oracle.graal.word.*;
+
+/**
+ * Substitutions for {@link java.lang.Class} methods.
+ */
+@ClassSubstitution(java.lang.Class.class)
+public class ClassSubstitutions {
+
+    @MethodSubstitution(isStatic = false)
+    public static int getModifiers(final Class<?> thisObj) {
+        Word klass = loadWordFromObject(thisObj, klassOffset());
+        if (klass.equal(0)) {
+            // Class for primitive type
+            return Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC;
+        } else {
+            return klass.readInt(klassModifierFlagsOffset(), FINAL_LOCATION);
+        }
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static boolean isInterface(final Class<?> thisObj) {
+        Word klass = loadWordFromObject(thisObj, klassOffset());
+        if (klass.equal(0)) {
+            return false;
+        } else {
+            int accessFlags = klass.readInt(klassAccessFlagsOffset(), FINAL_LOCATION);
+            return (accessFlags & Modifier.INTERFACE) != 0;
+        }
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static boolean isArray(final Class<?> thisObj) {
+        Word klass = loadWordFromObject(thisObj, klassOffset());
+        if (klass.equal(0)) {
+            return false;
+        } else {
+            return (readLayoutHelper(klass) & arrayKlassLayoutHelperIdentifier()) != 0;
+        }
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static boolean isPrimitive(final Class<?> thisObj) {
+        Word klass = loadWordFromObject(thisObj, klassOffset());
+        return klass.equal(0);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static Class<?> getSuperclass(final Class<?> thisObj) {
+        Word klass = loadWordFromObject(thisObj, klassOffset());
+        if (klass.notEqual(0)) {
+            int accessFlags = klass.readInt(klassAccessFlagsOffset(), FINAL_LOCATION);
+            if ((accessFlags & Modifier.INTERFACE) == 0) {
+                if ((readLayoutHelper(klass) & arrayKlassLayoutHelperIdentifier()) != 0) {
+                    return Object.class;
+                } else {
+                    Word superKlass = klass.readWord(klassSuperKlassOffset(), FINAL_LOCATION);
+                    if (superKlass.equal(0)) {
+                        return null;
+                    } else {
+                        return unsafeCast(superKlass.readObject(classMirrorOffset(), FINAL_LOCATION), Class.class, true, true);
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static Class<?> getComponentType(final Class<?> thisObj) {
+        Word klass = loadWordFromObject(thisObj, klassOffset());
+        if (klass.notEqual(0)) {
+            if ((readLayoutHelper(klass) & arrayKlassLayoutHelperIdentifier()) != 0) {
+                return unsafeCast(klass.readObject(arrayKlassComponentMirrorOffset(), FINAL_LOCATION), Class.class, true, true);
+            }
+        }
+        return null;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static boolean isInstance(final Class<?> thisObj, Object obj) {
+        return !isPrimitive(thisObj) && ConditionalNode.materializeIsInstance(thisObj, obj);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSnippetUtils.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,550 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.replacements;
+
+import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*;
+import sun.misc.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.Node.ConstantNodeParameter;
+import com.oracle.graal.graph.Node.NodeIntrinsic;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.replacements.Snippet.*;
+import com.oracle.graal.replacements.nodes.*;
+import com.oracle.graal.word.*;
+
+//JaCoCo Exclude
+
+/**
+ * A collection of methods used in HotSpot snippets and substitutions.
+ */
+public class HotSpotSnippetUtils {
+
+    public static final Object ANY_LOCATION = LocationNode.ANY_LOCATION;
+    public static final Object UNKNOWN_LOCATION = LocationNode.UNKNOWN_LOCATION;
+    public static final Object FINAL_LOCATION = LocationNode.FINAL_LOCATION;
+
+    public static HotSpotVMConfig config() {
+        return HotSpotGraalRuntime.getInstance().getConfig();
+    }
+
+    @Fold
+    public static boolean verifyOops() {
+        return config().verifyOops;
+    }
+
+    public static final Object TLAB_TOP_LOCATION = LocationNode.createLocation("TlabTop");
+
+    @Fold
+    public static int threadTlabTopOffset() {
+        return config().threadTlabTopOffset;
+    }
+
+    public static final Object TLAB_END_LOCATION = LocationNode.createLocation("TlabEnd");
+
+    @Fold
+    private static int threadTlabEndOffset() {
+        return config().threadTlabEndOffset;
+    }
+
+    public static final Object TLAB_START_LOCATION = LocationNode.createLocation("TlabStart");
+
+    @Fold
+    private static int threadTlabStartOffset() {
+        return config().threadTlabStartOffset;
+    }
+
+    public static Word readTlabTop(Word thread) {
+        return thread.readWord(threadTlabTopOffset(), TLAB_TOP_LOCATION);
+    }
+
+    public static Word readTlabEnd(Word thread) {
+        return thread.readWord(threadTlabEndOffset(), TLAB_END_LOCATION);
+    }
+
+    public static Word readTlabStart(Word thread) {
+        return thread.readWord(threadTlabStartOffset(), TLAB_START_LOCATION);
+    }
+
+    public static void writeTlabTop(Word thread, Word top) {
+        thread.writeWord(threadTlabTopOffset(), top, TLAB_TOP_LOCATION);
+    }
+
+    public static void initializeTlab(Word thread, Word start, Word end) {
+        thread.writeWord(threadTlabStartOffset(), start, TLAB_START_LOCATION);
+        thread.writeWord(threadTlabTopOffset(), start, TLAB_TOP_LOCATION);
+        thread.writeWord(threadTlabEndOffset(), end, TLAB_END_LOCATION);
+    }
+
+    @Fold
+    public static int threadObjectOffset() {
+        return config().threadObjectOffset;
+    }
+
+    @Fold
+    public static int osThreadOffset() {
+        return config().osThreadOffset;
+    }
+
+    @Fold
+    public static int osThreadInterruptedOffset() {
+        return config().osThreadInterruptedOffset;
+    }
+
+    @Fold
+    public static Kind wordKind() {
+        return HotSpotGraalRuntime.getInstance().getTarget().wordKind;
+    }
+
+    @Fold
+    public static Register threadRegister() {
+        return HotSpotGraalRuntime.getInstance().getRuntime().threadRegister();
+    }
+
+    @Fold
+    public static Register stackPointerRegister() {
+        return HotSpotGraalRuntime.getInstance().getRuntime().stackPointerRegister();
+    }
+
+    @Fold
+    public static int wordSize() {
+        return HotSpotGraalRuntime.getInstance().getTarget().wordSize;
+    }
+
+    @Fold
+    public static int pageSize() {
+        return Unsafe.getUnsafe().pageSize();
+    }
+
+    public static final Object PROTOTYPE_MARK_WORD_LOCATION = LocationNode.createLocation("PrototypeMarkWord");
+
+    @Fold
+    public static int prototypeMarkWordOffset() {
+        return config().prototypeMarkWordOffset;
+    }
+
+    @Fold
+    public static long arrayPrototypeMarkWord() {
+        return config().arrayPrototypeMarkWord;
+    }
+
+    @Fold
+    public static int klassAccessFlagsOffset() {
+        return config().klassAccessFlagsOffset;
+    }
+
+    @Fold
+    private static int klassLayoutHelperOffset() {
+        return config().klassLayoutHelperOffset;
+    }
+
+    public static int readLayoutHelper(Word hub) {
+        return hub.readInt(klassLayoutHelperOffset(), FINAL_LOCATION);
+    }
+
+    @Fold
+    public static int arrayKlassLayoutHelperIdentifier() {
+        return config().arrayKlassLayoutHelperIdentifier;
+    }
+
+    @Fold
+    public static int arrayKlassComponentMirrorOffset() {
+        return config().arrayKlassComponentMirrorOffset;
+    }
+
+    @Fold
+    public static int klassSuperKlassOffset() {
+        return config().klassSuperKlassOffset;
+    }
+
+    public static final Object MARK_WORD_LOCATION = LocationNode.createLocation("MarkWord");
+
+    @Fold
+    public static int markOffset() {
+        return config().markOffset;
+    }
+
+    public static final Object HUB_LOCATION = LocationNode.createLocation("Hub");
+
+    @Fold
+    private static int hubOffset() {
+        return config().hubOffset;
+    }
+
+    public static void initializeObjectHeader(Word memory, Word markWord, Word hub) {
+        memory.writeWord(markOffset(), markWord, MARK_WORD_LOCATION);
+        memory.writeWord(hubOffset(), hub, HUB_LOCATION);
+    }
+
+    @Fold
+    public static int unlockedMask() {
+        return config().unlockedMask;
+    }
+
+    /**
+     * Mask for a biasable, locked or unlocked mark word.
+     * 
+     * <pre>
+     * +----------------------------------+-+-+
+     * |                                 1|1|1|
+     * +----------------------------------+-+-+
+     * </pre>
+     * 
+     */
+    @Fold
+    public static int biasedLockMaskInPlace() {
+        return config().biasedLockMaskInPlace;
+    }
+
+    @Fold
+    public static int epochMaskInPlace() {
+        return config().epochMaskInPlace;
+    }
+
+    /**
+     * Pattern for a biasable, unlocked mark word.
+     * 
+     * <pre>
+     * +----------------------------------+-+-+
+     * |                                 1|0|1|
+     * +----------------------------------+-+-+
+     * </pre>
+     * 
+     */
+    @Fold
+    public static int biasedLockPattern() {
+        return config().biasedLockPattern;
+    }
+
+    @Fold
+    public static int ageMaskInPlace() {
+        return config().ageMaskInPlace;
+    }
+
+    @Fold
+    public static int metaspaceArrayLengthOffset() {
+        return config().metaspaceArrayLengthOffset;
+    }
+
+    @Fold
+    public static int metaspaceArrayBaseOffset() {
+        return config().metaspaceArrayBaseOffset;
+    }
+
+    @Fold
+    public static int arrayLengthOffset() {
+        return config().arrayLengthOffset;
+    }
+
+    @Fold
+    public static int arrayBaseOffset(Kind elementKind) {
+        return HotSpotRuntime.getArrayBaseOffset(elementKind);
+    }
+
+    @Fold
+    public static int arrayIndexScale(Kind elementKind) {
+        return HotSpotRuntime.getArrayIndexScale(elementKind);
+    }
+
+    @Fold
+    public static int cardTableShift() {
+        return config().cardtableShift;
+    }
+
+    @Fold
+    public static long cardTableStart() {
+        return config().cardtableStartAddress;
+    }
+
+    @Fold
+    public static int superCheckOffsetOffset() {
+        return config().superCheckOffsetOffset;
+    }
+
+    public static final Object SECONDARY_SUPER_CACHE_LOCATION = LocationNode.createLocation("SecondarySuperCache");
+
+    @Fold
+    public static int secondarySuperCacheOffset() {
+        return config().secondarySuperCacheOffset;
+    }
+
+    public static final Object SECONDARY_SUPERS_LOCATION = LocationNode.createLocation("SecondarySupers");
+
+    @Fold
+    public static int secondarySupersOffset() {
+        return config().secondarySupersOffset;
+    }
+
+    public static final Object DISPLACED_MARK_WORD_LOCATION = LocationNode.createLocation("DisplacedMarkWord");
+
+    @Fold
+    public static int lockDisplacedMarkOffset() {
+        return config().basicLockDisplacedHeaderOffset;
+    }
+
+    @Fold
+    public static boolean useBiasedLocking() {
+        return config().useBiasedLocking;
+    }
+
+    @Fold
+    static int uninitializedIdentityHashCodeValue() {
+        return config().uninitializedIdentityHashCodeValue;
+    }
+
+    @Fold
+    static int identityHashCodeShift() {
+        return config().identityHashCodeShift;
+    }
+
+    /**
+     * Loads the hub from a object, null checking it first.
+     */
+    public static Word loadHub(Object object) {
+        return loadHubIntrinsic(object, wordKind());
+    }
+
+    public static Object verifyOop(Object object) {
+        if (verifyOops()) {
+            VerifyOopStubCall.call(object);
+        }
+        return object;
+    }
+
+    /**
+     * Gets the value of the stack pointer register as a Word.
+     */
+    public static Word stackPointer() {
+        return HotSpotSnippetUtils.registerAsWord(stackPointerRegister(), true, false);
+    }
+
+    /**
+     * Gets the value of the thread register as a Word.
+     */
+    public static Word thread() {
+        return HotSpotSnippetUtils.registerAsWord(threadRegister(), true, false);
+    }
+
+    public static Word loadWordFromObject(Object object, int offset) {
+        return loadWordFromObjectIntrinsic(object, 0, offset, wordKind());
+    }
+
+    @NodeIntrinsic(value = ReadRegisterNode.class, setStampFromReturnType = true)
+    public static native Word registerAsWord(@ConstantNodeParameter Register register, @ConstantNodeParameter boolean directUse, @ConstantNodeParameter boolean incoming);
+
+    @NodeIntrinsic(value = UnsafeLoadNode.class, setStampFromReturnType = true)
+    private static native Word loadWordFromObjectIntrinsic(Object object, @ConstantNodeParameter int displacement, long offset, @ConstantNodeParameter Kind wordKind);
+
+    @NodeIntrinsic(value = LoadHubNode.class, setStampFromReturnType = true)
+    static native Word loadHubIntrinsic(Object object, @ConstantNodeParameter Kind word);
+
+    @Fold
+    public static int log2WordSize() {
+        return CodeUtil.log2(wordSize());
+    }
+
+    public static final Object CLASS_STATE_LOCATION = LocationNode.createLocation("ClassState");
+
+    @Fold
+    public static int klassStateOffset() {
+        return config().klassStateOffset;
+    }
+
+    @Fold
+    public static int klassStateFullyInitialized() {
+        return config().klassStateFullyInitialized;
+    }
+
+    @Fold
+    public static int klassModifierFlagsOffset() {
+        return config().klassModifierFlagsOffset;
+    }
+
+    @Fold
+    public static int klassOffset() {
+        return config().klassOffset;
+    }
+
+    @Fold
+    public static int classMirrorOffset() {
+        return config().classMirrorOffset;
+    }
+
+    @Fold
+    public static int klassInstanceSizeOffset() {
+        return config().klassInstanceSizeOffset;
+    }
+
+    public static final Object HEAP_TOP_LOCATION = LocationNode.createLocation("HeapTop");
+
+    @Fold
+    public static long heapTopAddress() {
+        return config().heapTopAddress;
+    }
+
+    public static final Object HEAP_END_LOCATION = LocationNode.createLocation("HeapEnd");
+
+    @Fold
+    public static long heapEndAddress() {
+        return config().heapEndAddress;
+    }
+
+    @Fold
+    public static long tlabIntArrayMarkWord() {
+        return config().tlabIntArrayMarkWord;
+    }
+
+    @Fold
+    public static boolean inlineContiguousAllocationSupported() {
+        return config().inlineContiguousAllocationSupported;
+    }
+
+    @Fold
+    public static int tlabAlignmentReserveInHeapWords() {
+        return config().tlabAlignmentReserve;
+    }
+
+    public static final Object TLAB_SIZE_LOCATION = LocationNode.createLocation("TlabSize");
+
+    @Fold
+    public static int threadTlabSizeOffset() {
+        return config().threadTlabSizeOffset;
+    }
+
+    public static final Object TLAB_THREAD_ALLOCATED_BYTES_LOCATION = LocationNode.createLocation("TlabThreadAllocatedBytes");
+
+    @Fold
+    public static int threadAllocatedBytesOffset() {
+        return config().threadAllocatedBytesOffset;
+    }
+
+    public static final Object TLAB_REFILL_WASTE_LIMIT_LOCATION = LocationNode.createLocation("RefillWasteLimit");
+
+    @Fold
+    public static int tlabRefillWasteLimitOffset() {
+        return config().tlabRefillWasteLimitOffset;
+    }
+
+    public static final Object TLAB_NOF_REFILLS_LOCATION = LocationNode.createLocation("TlabNOfRefills");
+
+    @Fold
+    public static int tlabNumberOfRefillsOffset() {
+        return config().tlabNumberOfRefillsOffset;
+    }
+
+    public static final Object TLAB_FAST_REFILL_WASTE_LOCATION = LocationNode.createLocation("TlabFastRefillWaste");
+
+    @Fold
+    public static int tlabFastRefillWasteOffset() {
+        return config().tlabFastRefillWasteOffset;
+    }
+
+    public static final Object TLAB_SLOW_ALLOCATIONS_LOCATION = LocationNode.createLocation("TlabSlowAllocations");
+
+    @Fold
+    public static int tlabSlowAllocationsOffset() {
+        return config().tlabSlowAllocationsOffset;
+    }
+
+    @Fold
+    public static int tlabRefillWasteIncrement() {
+        return config().tlabRefillWasteIncrement;
+    }
+
+    @Fold
+    public static boolean tlabStats() {
+        return config().tlabStats;
+    }
+
+    @Fold
+    public static int layoutHelperOffset() {
+        return config().layoutHelperOffset;
+    }
+
+    @Fold
+    public static int layoutHelperHeaderSizeShift() {
+        return config().layoutHelperHeaderSizeShift;
+    }
+
+    @Fold
+    public static int layoutHelperHeaderSizeMask() {
+        return config().layoutHelperHeaderSizeMask;
+    }
+
+    @Fold
+    public static int layoutHelperLog2ElementSizeShift() {
+        return config().layoutHelperLog2ElementSizeShift;
+    }
+
+    @Fold
+    public static int layoutHelperLog2ElementSizeMask() {
+        return config().layoutHelperLog2ElementSizeMask;
+    }
+
+    @Fold
+    public static int layoutHelperElementTypeShift() {
+        return config().layoutHelperElementTypeShift;
+    }
+
+    @Fold
+    public static int layoutHelperElementTypeMask() {
+        return config().layoutHelperElementTypeMask;
+    }
+
+    @Fold
+    public static int layoutHelperElementTypePrimitiveInPlace() {
+        return config().layoutHelperElementTypePrimitiveInPlace;
+    }
+
+    static {
+        assert arrayIndexScale(Kind.Byte) == 1;
+        assert arrayIndexScale(Kind.Boolean) == 1;
+        assert arrayIndexScale(Kind.Char) == 2;
+        assert arrayIndexScale(Kind.Short) == 2;
+        assert arrayIndexScale(Kind.Int) == 4;
+        assert arrayIndexScale(Kind.Long) == 8;
+        assert arrayIndexScale(Kind.Float) == 4;
+        assert arrayIndexScale(Kind.Double) == 8;
+    }
+
+    static int computeHashCode(Object x) {
+        Word mark = loadWordFromObject(x, markOffset());
+
+        // this code is independent from biased locking (although it does not look that way)
+        final Word biasedLock = mark.and(biasedLockMaskInPlace());
+        if (biasedLock.equal(Word.unsigned(unlockedMask()))) {
+            probability(FAST_PATH_PROBABILITY);
+            int hash = (int) mark.unsignedShiftRight(identityHashCodeShift()).rawValue();
+            if (hash != uninitializedIdentityHashCodeValue()) {
+                probability(FAST_PATH_PROBABILITY);
+                return hash;
+            }
+        }
+
+        return IdentityHashCodeStubCall.call(x);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.replacements;
+
+import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*;
+import static com.oracle.graal.hotspot.replacements.TypeCheckSnippetUtils.*;
+import static com.oracle.graal.replacements.SnippetTemplate.Arguments.*;
+import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.meta.*;
+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.phases.*;
+import com.oracle.graal.replacements.*;
+import com.oracle.graal.replacements.Snippet.*;
+import com.oracle.graal.replacements.SnippetTemplate.*;
+import com.oracle.graal.replacements.nodes.*;
+import com.oracle.graal.word.*;
+
+/**
+ * Snippets used for implementing the type test of an instanceof instruction. Since instanceof is a
+ * floating node, it is lowered separately for each of its usages.
+ * 
+ * The type tests implemented are described in the paper <a
+ * href="http://dl.acm.org/citation.cfm?id=583821"> Fast subtype checking in the HotSpot JVM</a> by
+ * Cliff Click and John Rose.
+ */
+public class InstanceOfSnippets implements Snippets {
+
+    // @formatter:off
+
+    /**
+     * A test against a final type.
+     */
+    @Snippet
+    public static Object instanceofExact(
+                    @Parameter("object") Object object,
+                    @Parameter("exactHub") Word exactHub,
+                    @Parameter("trueValue") Object trueValue,
+                    @Parameter("falseValue") Object falseValue,
+                    @ConstantParameter("checkNull") boolean checkNull) {
+        if (checkNull && object == null) {
+            probability(NOT_FREQUENT_PROBABILITY);
+            isNull.inc();
+            return falseValue;
+        }
+        Word objectHub = loadHub(object);
+        if (objectHub.notEqual(exactHub)) {
+            probability(LIKELY_PROBABILITY);
+            exactMiss.inc();
+            return falseValue;
+        }
+        exactHit.inc();
+        return trueValue;
+    }
+
+    /**
+     * A test against a primary type.
+     */
+    @Snippet
+    public static Object instanceofPrimary(
+                    @Parameter("hub") Word hub,
+                    @Parameter("object") Object object,
+                    @Parameter("trueValue") Object trueValue,
+                    @Parameter("falseValue") Object falseValue,
+                    @ConstantParameter("checkNull") boolean checkNull,
+                    @ConstantParameter("superCheckOffset") int superCheckOffset) {
+        if (checkNull && object == null) {
+            probability(NOT_FREQUENT_PROBABILITY);
+            isNull.inc();
+            return falseValue;
+        }
+        Word objectHub = loadHub(object);
+        if (objectHub.readWord(superCheckOffset, FINAL_LOCATION).notEqual(hub)) {
+            probability(NOT_LIKELY_PROBABILITY);
+            displayMiss.inc();
+            return falseValue;
+        }
+        displayHit.inc();
+        return trueValue;
+    }
+
+    /**
+     * A test against a restricted secondary type type.
+     */
+    @Snippet
+    public static Object instanceofSecondary(
+                    @Parameter("hub") Word hub,
+                    @Parameter("object") Object object,
+                    @Parameter("trueValue") Object trueValue,
+                    @Parameter("falseValue") Object falseValue,
+                    @VarargsParameter("hints") Word[] hints,
+                    @ConstantParameter("checkNull") boolean checkNull) {
+        if (checkNull && object == null) {
+            probability(NOT_FREQUENT_PROBABILITY);
+            isNull.inc();
+            return falseValue;
+        }
+        Word objectHub = loadHub(object);
+        // if we get an exact match: succeed immediately
+        ExplodeLoopNode.explodeLoop();
+        for (int i = 0; i < hints.length; i++) {
+            Word hintHub = hints[i];
+            if (hintHub.equal(objectHub)) {
+                probability(NOT_FREQUENT_PROBABILITY);
+                hintsHit.inc();
+                return trueValue;
+            }
+        }
+        if (!checkSecondarySubType(hub, objectHub)) {
+            return falseValue;
+        }
+        return trueValue;
+    }
+
+    /**
+     * Type test used when the type being tested against is not known at compile time.
+     */
+    @Snippet
+    public static Object instanceofDynamic(
+                    @Parameter("mirror") Class mirror,
+                    @Parameter("object") Object object,
+                    @Parameter("trueValue") Object trueValue,
+                    @Parameter("falseValue") Object falseValue,
+                    @ConstantParameter("checkNull") boolean checkNull) {
+        if (checkNull && object == null) {
+            probability(NOT_FREQUENT_PROBABILITY);
+            isNull.inc();
+            return falseValue;
+        }
+
+        Word hub = loadWordFromObject(mirror, klassOffset());
+        Word objectHub = loadHub(object);
+        if (!checkUnknownSubType(hub, objectHub)) {
+            return falseValue;
+        }
+        return trueValue;
+    }
+
+    // @formatter:on
+
+    public static class Templates extends InstanceOfSnippetsTemplates<InstanceOfSnippets> {
+
+        private final ResolvedJavaMethod instanceofExact;
+        private final ResolvedJavaMethod instanceofPrimary;
+        private final ResolvedJavaMethod instanceofSecondary;
+        private final ResolvedJavaMethod instanceofDynamic;
+
+        public Templates(CodeCacheProvider runtime, Assumptions assumptions, TargetDescription target) {
+            super(runtime, assumptions, target, InstanceOfSnippets.class);
+            instanceofExact = snippet("instanceofExact", Object.class, Word.class, Object.class, Object.class, boolean.class);
+            instanceofPrimary = snippet("instanceofPrimary", Word.class, Object.class, Object.class, Object.class, boolean.class, int.class);
+            instanceofSecondary = snippet("instanceofSecondary", Word.class, Object.class, Object.class, Object.class, Word[].class, boolean.class);
+            instanceofDynamic = snippet("instanceofDynamic", Class.class, Object.class, Object.class, Object.class, boolean.class);
+        }
+
+        @Override
+        protected KeyAndArguments getKeyAndArguments(InstanceOfUsageReplacer replacer, LoweringTool tool) {
+            if (replacer.instanceOf instanceof InstanceOfNode) {
+                InstanceOfNode instanceOf = (InstanceOfNode) replacer.instanceOf;
+                ValueNode trueValue = replacer.trueValue;
+                ValueNode falseValue = replacer.falseValue;
+                ValueNode object = instanceOf.object();
+                TypeCheckHints hintInfo = new TypeCheckHints(instanceOf.type(), instanceOf.profile(), tool.assumptions(), GraalOptions.InstanceOfMinHintHitProbability, GraalOptions.InstanceOfMaxHints);
+                final HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) instanceOf.type();
+                ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, instanceOf.graph());
+                boolean checkNull = !object.stamp().nonNull();
+                Arguments arguments;
+                Key key;
+                if (hintInfo.exact) {
+                    ConstantNode[] hints = createHints(hintInfo, runtime, hub.graph());
+                    assert hints.length == 1;
+                    key = new Key(instanceofExact).add("checkNull", checkNull);
+                    arguments = arguments("object", object).add("exactHub", hints[0]).add("trueValue", trueValue).add("falseValue", falseValue);
+                } else if (type.isPrimaryType()) {
+                    key = new Key(instanceofPrimary).add("checkNull", checkNull).add("superCheckOffset", type.superCheckOffset());
+                    arguments = arguments("hub", hub).add("object", object).add("trueValue", trueValue).add("falseValue", falseValue);
+                } else {
+                    ConstantNode[] hints = createHints(hintInfo, runtime, hub.graph());
+                    key = new Key(instanceofSecondary).add("hints", Varargs.vargargs(new Word[hints.length], StampFactory.forKind(wordKind()))).add("checkNull", checkNull);
+                    arguments = arguments("hub", hub).add("object", object).add("hints", hints).add("trueValue", trueValue).add("falseValue", falseValue);
+                }
+                return new KeyAndArguments(key, arguments);
+            } else {
+                assert replacer.instanceOf instanceof InstanceOfDynamicNode;
+                InstanceOfDynamicNode instanceOf = (InstanceOfDynamicNode) replacer.instanceOf;
+                ValueNode trueValue = replacer.trueValue;
+                ValueNode falseValue = replacer.falseValue;
+                ValueNode object = instanceOf.object();
+                ValueNode mirror = instanceOf.mirror();
+                boolean checkNull = !object.stamp().nonNull();
+                Key key = new Key(instanceofDynamic).add("checkNull", checkNull);
+                Arguments arguments = arguments("mirror", mirror).add("object", object).add("trueValue", trueValue).add("falseValue", falseValue);
+                return new KeyAndArguments(key, arguments);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,544 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.replacements;
+
+import static com.oracle.graal.hotspot.nodes.BeginLockScopeNode.*;
+import static com.oracle.graal.hotspot.nodes.DirectCompareAndSwapNode.*;
+import static com.oracle.graal.hotspot.nodes.EndLockScopeNode.*;
+import static com.oracle.graal.hotspot.nodes.VMErrorNode.*;
+import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*;
+import static com.oracle.graal.replacements.SnippetTemplate.*;
+import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*;
+
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.Node.NodeIntrinsic;
+import com.oracle.graal.graph.iterators.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.common.*;
+import com.oracle.graal.replacements.*;
+import com.oracle.graal.replacements.Snippet.*;
+import com.oracle.graal.word.*;
+
+/**
+ * Snippets used for implementing the monitorenter and monitorexit instructions.
+ * 
+ * The locking algorithm used is described in the paper <a
+ * href="http://dl.acm.org/citation.cfm?id=1167515.1167496"> Eliminating synchronization-related
+ * atomic operations with biased locking and bulk rebiasing</a> by Kenneth Russell and David
+ * Detlefs.
+ */
+public class MonitorSnippets implements Snippets {
+
+    /**
+     * Monitor operations on objects whose type contains this substring will be traced.
+     */
+    private static final String TRACE_TYPE_FILTER = System.getProperty("graal.monitors.trace.typeFilter");
+
+    /**
+     * Monitor operations in methods whose fully qualified name contains this substring will be
+     * traced.
+     */
+    private static final String TRACE_METHOD_FILTER = System.getProperty("graal.monitors.trace.methodFilter");
+
+    public static final boolean CHECK_BALANCED_MONITORS = Boolean.getBoolean("graal.monitors.checkBalanced");
+
+    @Snippet
+    public static void monitorenter(@Parameter("object") Object object, @ConstantParameter("checkNull") boolean checkNull, @ConstantParameter("trace") boolean trace) {
+        verifyOop(object);
+
+        if (checkNull && object == null) {
+            DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException);
+        }
+
+        // Load the mark word - this includes a null-check on object
+        final Word mark = loadWordFromObject(object, markOffset());
+
+        final Word lock = beginLockScope(false);
+
+        trace(trace, "           object: 0x%016lx\n", Word.fromObject(object));
+        trace(trace, "             lock: 0x%016lx\n", lock);
+        trace(trace, "             mark: 0x%016lx\n", mark);
+
+        incCounter();
+
+        if (useBiasedLocking()) {
+            // See whether the lock is currently biased toward our thread and
+            // whether the epoch is still valid.
+            // Note that the runtime guarantees sufficient alignment of JavaThread
+            // pointers to allow age to be placed into low bits.
+            final Word biasableLockBits = mark.and(biasedLockMaskInPlace());
+
+            // First check to see whether biasing is enabled for this object
+            if (biasableLockBits.notEqual(Word.unsigned(biasedLockPattern()))) {
+                // Biasing not enabled -> fall through to lightweight locking
+            } else {
+                probability(FREQUENT_PROBABILITY);
+                // The bias pattern is present in the object's mark word. Need to check
+                // whether the bias owner and the epoch are both still current.
+                Word hub = loadHub(object);
+                final Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION);
+                final Word thread = thread();
+                final Word tmp = prototypeMarkWord.or(thread).xor(mark).and(~ageMaskInPlace());
+                trace(trace, "prototypeMarkWord: 0x%016lx\n", prototypeMarkWord);
+                trace(trace, "           thread: 0x%016lx\n", thread);
+                trace(trace, "              tmp: 0x%016lx\n", tmp);
+                if (tmp.equal(0)) {
+                    // Object is already biased to current thread -> done
+                    probability(FREQUENT_PROBABILITY);
+                    traceObject(trace, "+lock{bias:existing}", object);
+                    return;
+                }
+
+                // At this point we know that the mark word has the bias pattern and
+                // that we are not the bias owner in the current epoch. We need to
+                // figure out more details about the state of the mark word in order to
+                // know what operations can be legally performed on the object's
+                // mark word.
+
+                // If the low three bits in the xor result aren't clear, that means
+                // the prototype header is no longer biasable and we have to revoke
+                // the bias on this object.
+                if (tmp.and(biasedLockMaskInPlace()).equal(0)) {
+                    probability(FREQUENT_PROBABILITY);
+                    // Biasing is still enabled for object's type. See whether the
+                    // epoch of the current bias is still valid, meaning that the epoch
+                    // bits of the mark word are equal to the epoch bits of the
+                    // prototype mark word. (Note that the prototype mark word's epoch bits
+                    // only change at a safepoint.) If not, attempt to rebias the object
+                    // toward the current thread. Note that we must be absolutely sure
+                    // that the current epoch is invalid in order to do this because
+                    // otherwise the manipulations it performs on the mark word are
+                    // illegal.
+                    if (tmp.and(epochMaskInPlace()).equal(0)) {
+                        probability(FREQUENT_PROBABILITY);
+                        // The epoch of the current bias is still valid but we know nothing
+                        // about the owner; it might be set or it might be clear. Try to
+                        // acquire the bias of the object using an atomic operation. If this
+                        // fails we will go in to the runtime to revoke the object's bias.
+                        // Note that we first construct the presumed unbiased header so we
+                        // don't accidentally blow away another thread's valid bias.
+                        Word unbiasedMark = mark.and(biasedLockMaskInPlace() | ageMaskInPlace() | epochMaskInPlace());
+                        Word biasedMark = unbiasedMark.or(thread);
+                        trace(trace, "     unbiasedMark: 0x%016lx\n", unbiasedMark);
+                        trace(trace, "       biasedMark: 0x%016lx\n", biasedMark);
+                        if (compareAndSwap(object, markOffset(), unbiasedMark, biasedMark, MARK_WORD_LOCATION).equal(unbiasedMark)) {
+                            // Object is now biased to current thread -> done
+                            traceObject(trace, "+lock{bias:acquired}", object);
+                            return;
+                        }
+                        // If the biasing toward our thread failed, this means that another thread
+                        // owns the bias and we need to revoke that bias. The revocation will occur
+                        // in the interpreter runtime.
+                        probability(DEOPT_PATH_PROBABILITY);
+                        traceObject(trace, "+lock{stub:revoke}", object);
+                        MonitorEnterStubCall.call(object, lock);
+                        return;
+                    } else {
+                        // At this point we know the epoch has expired, meaning that the
+                        // current bias owner, if any, is actually invalid. Under these
+                        // circumstances _only_, are we allowed to use the current mark word
+                        // value as the comparison value when doing the CAS to acquire the
+                        // bias in the current epoch. In other words, we allow transfer of
+                        // the bias from one thread to another directly in this situation.
+                        Word biasedMark = prototypeMarkWord.or(thread);
+                        trace(trace, "       biasedMark: 0x%016lx\n", biasedMark);
+                        if (compareAndSwap(object, markOffset(), mark, biasedMark, MARK_WORD_LOCATION).equal(mark)) {
+                            // Object is now biased to current thread -> done
+                            traceObject(trace, "+lock{bias:transfer}", object);
+                            return;
+                        }
+                        // If the biasing toward our thread failed, then another thread
+                        // succeeded in biasing it toward itself and we need to revoke that
+                        // bias. The revocation will occur in the runtime in the slow case.
+                        probability(DEOPT_PATH_PROBABILITY);
+                        traceObject(trace, "+lock{stub:epoch-expired}", object);
+                        MonitorEnterStubCall.call(object, lock);
+                        return;
+                    }
+                } else {
+                    // The prototype mark word doesn't have the bias bit set any
+                    // more, indicating that objects of this data type are not supposed
+                    // to be biased any more. We are going to try to reset the mark of
+                    // this object to the prototype value and fall through to the
+                    // CAS-based locking scheme. Note that if our CAS fails, it means
+                    // that another thread raced us for the privilege of revoking the
+                    // bias of this particular object, so it's okay to continue in the
+                    // normal locking code.
+                    Word result = compareAndSwap(object, markOffset(), mark, prototypeMarkWord, MARK_WORD_LOCATION);
+
+                    // Fall through to the normal CAS-based lock, because no matter what
+                    // the result of the above CAS, some thread must have succeeded in
+                    // removing the bias bit from the object's header.
+
+                    if (ENABLE_BREAKPOINT) {
+                        bkpt(object, mark, tmp, result);
+                    }
+                }
+            }
+        }
+
+        // Create the unlocked mark word pattern
+        Word unlockedMark = mark.or(unlockedMask());
+        trace(trace, "     unlockedMark: 0x%016lx\n", unlockedMark);
+
+        // Copy this unlocked mark word into the lock slot on the stack
+        lock.writeWord(lockDisplacedMarkOffset(), unlockedMark, DISPLACED_MARK_WORD_LOCATION);
+
+        // Test if the object's mark word is unlocked, and if so, store the
+        // (address of) the lock slot into the object's mark word.
+        Word currentMark = compareAndSwap(object, markOffset(), unlockedMark, lock, MARK_WORD_LOCATION);
+        if (currentMark.notEqual(unlockedMark)) {
+            trace(trace, "      currentMark: 0x%016lx\n", currentMark);
+            // The mark word in the object header was not the same.
+            // Either the object is locked by another thread or is already locked
+            // by the current thread. The latter is true if the mark word
+            // is a stack pointer into the current thread's stack, i.e.:
+            //
+            // 1) (currentMark & aligned_mask) == 0
+            // 2) rsp <= currentMark
+            // 3) currentMark <= rsp + page_size
+            //
+            // These 3 tests can be done by evaluating the following expression:
+            //
+            // (currentMark - rsp) & (aligned_mask - page_size)
+            //
+            // assuming both the stack pointer and page_size have their least
+            // significant 2 bits cleared and page_size is a power of 2
+            final Word alignedMask = Word.unsigned(wordSize() - 1);
+            final Word stackPointer = stackPointer();
+            if (currentMark.subtract(stackPointer).and(alignedMask.subtract(pageSize())).notEqual(0)) {
+                // Most likely not a recursive lock, go into a slow runtime call
+                probability(DEOPT_PATH_PROBABILITY);
+                traceObject(trace, "+lock{stub:failed-cas}", object);
+                MonitorEnterStubCall.call(object, lock);
+                return;
+            } else {
+                // Recursively locked => write 0 to the lock slot
+                lock.writeWord(lockDisplacedMarkOffset(), Word.zero(), DISPLACED_MARK_WORD_LOCATION);
+                traceObject(trace, "+lock{recursive}", object);
+            }
+        } else {
+            traceObject(trace, "+lock{cas}", object);
+        }
+    }
+
+    @Snippet
+    public static void monitorenterEliminated() {
+        incCounter();
+        beginLockScope(true);
+    }
+
+    /**
+     * Calls straight out to the monitorenter stub.
+     */
+    @Snippet
+    public static void monitorenterStub(@Parameter("object") Object object, @ConstantParameter("checkNull") boolean checkNull, @ConstantParameter("trace") boolean trace) {
+        verifyOop(object);
+        incCounter();
+        if (checkNull && object == null) {
+            DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException);
+        }
+        // BeginLockScope nodes do not read from object so a use of object
+        // cannot float about the null check above
+        final Word lock = beginLockScope(false);
+        traceObject(trace, "+lock{stub}", object);
+        MonitorEnterStubCall.call(object, lock);
+    }
+
+    @Snippet
+    public static void monitorexit(@Parameter("object") Object object, @ConstantParameter("trace") boolean trace) {
+        trace(trace, "           object: 0x%016lx\n", Word.fromObject(object));
+        if (useBiasedLocking()) {
+            // Check for biased locking unlock case, which is a no-op
+            // Note: we do not have to check the thread ID for two reasons.
+            // First, the interpreter checks for IllegalMonitorStateException at
+            // a higher level. Second, if the bias was revoked while we held the
+            // lock, the object could not be rebiased toward another thread, so
+            // the bias bit would be clear.
+            final Word mark = loadWordFromObject(object, markOffset());
+            trace(trace, "             mark: 0x%016lx\n", mark);
+            if (mark.and(biasedLockMaskInPlace()).equal(Word.unsigned(biasedLockPattern()))) {
+                probability(FREQUENT_PROBABILITY);
+                endLockScope();
+                decCounter();
+                traceObject(trace, "-lock{bias}", object);
+                return;
+            }
+        }
+
+        final Word lock = CurrentLockNode.currentLock();
+
+        // Load displaced mark
+        final Word displacedMark = lock.readWord(lockDisplacedMarkOffset(), DISPLACED_MARK_WORD_LOCATION);
+        trace(trace, "    displacedMark: 0x%016lx\n", displacedMark);
+
+        if (displacedMark.equal(0)) {
+            // Recursive locking => done
+            traceObject(trace, "-lock{recursive}", object);
+        } else {
+            verifyOop(object);
+            // Test if object's mark word is pointing to the displaced mark word, and if so, restore
+            // the displaced mark in the object - if the object's mark word is not pointing to
+            // the displaced mark word, do unlocking via runtime call.
+            if (DirectCompareAndSwapNode.compareAndSwap(object, markOffset(), lock, displacedMark, MARK_WORD_LOCATION).notEqual(lock)) {
+                // The object's mark word was not pointing to the displaced header,
+                // we do unlocking via runtime call.
+                probability(DEOPT_PATH_PROBABILITY);
+                traceObject(trace, "-lock{stub}", object);
+                MonitorExitStubCall.call(object);
+            } else {
+                traceObject(trace, "-lock{cas}", object);
+            }
+        }
+        endLockScope();
+        decCounter();
+    }
+
+    /**
+     * Calls straight out to the monitorexit stub.
+     */
+    @Snippet
+    public static void monitorexitStub(@Parameter("object") Object object, @ConstantParameter("trace") boolean trace) {
+        verifyOop(object);
+        traceObject(trace, "-lock{stub}", object);
+        MonitorExitStubCall.call(object);
+        endLockScope();
+        decCounter();
+    }
+
+    @Snippet
+    public static void monitorexitEliminated() {
+        endLockScope();
+        decCounter();
+    }
+
+    private static void traceObject(boolean enabled, String action, Object object) {
+        if (enabled) {
+            Log.print(action);
+            Log.print(' ');
+            Log.printlnObject(object);
+        }
+    }
+
+    private static void trace(boolean enabled, String format, WordBase value) {
+        if (enabled) {
+            Log.printf(format, value.rawValue());
+        }
+    }
+
+    /**
+     * Leaving the breakpoint code in to provide an example of how to use the {@link BreakpointNode}
+     * intrinsic.
+     */
+    private static final boolean ENABLE_BREAKPOINT = false;
+
+    private static final Object MONITOR_COUNTER_LOCATION = LocationNode.createLocation("MonitorCounter");
+
+    @NodeIntrinsic(BreakpointNode.class)
+    static native void bkpt(Object object, Word mark, Word tmp, Word value);
+
+    private static void incCounter() {
+        if (CHECK_BALANCED_MONITORS) {
+            final Word counter = MonitorCounterNode.counter();
+            final int count = counter.readInt(0, MONITOR_COUNTER_LOCATION);
+            counter.writeInt(0, count + 1, MONITOR_COUNTER_LOCATION);
+        }
+    }
+
+    private static void decCounter() {
+        if (CHECK_BALANCED_MONITORS) {
+            final Word counter = MonitorCounterNode.counter();
+            final int count = counter.readInt(0, MONITOR_COUNTER_LOCATION);
+            counter.writeInt(0, count - 1, MONITOR_COUNTER_LOCATION);
+        }
+    }
+
+    @Snippet
+    private static void initCounter() {
+        final Word counter = MonitorCounterNode.counter();
+        counter.writeInt(0, 0, MONITOR_COUNTER_LOCATION);
+    }
+
+    @Snippet
+    private static void checkCounter(String errMsg) {
+        final Word counter = MonitorCounterNode.counter();
+        final int count = counter.readInt(0, MONITOR_COUNTER_LOCATION);
+        if (count != 0) {
+            vmError(errMsg, count);
+        }
+    }
+
+    public static class Templates extends AbstractTemplates<MonitorSnippets> {
+
+        private final ResolvedJavaMethod monitorenter;
+        private final ResolvedJavaMethod monitorexit;
+        private final ResolvedJavaMethod monitorenterStub;
+        private final ResolvedJavaMethod monitorexitStub;
+        private final ResolvedJavaMethod monitorenterEliminated;
+        private final ResolvedJavaMethod monitorexitEliminated;
+        private final ResolvedJavaMethod initCounter;
+        private final ResolvedJavaMethod checkCounter;
+        private final boolean useFastLocking;
+
+        public Templates(CodeCacheProvider runtime, Assumptions assumptions, TargetDescription target, boolean useFastLocking) {
+            super(runtime, assumptions, target, MonitorSnippets.class);
+            monitorenter = snippet("monitorenter", Object.class, boolean.class, boolean.class);
+            monitorexit = snippet("monitorexit", Object.class, boolean.class);
+            monitorenterStub = snippet("monitorenterStub", Object.class, boolean.class, boolean.class);
+            monitorexitStub = snippet("monitorexitStub", Object.class, boolean.class);
+            monitorenterEliminated = snippet("monitorenterEliminated");
+            monitorexitEliminated = snippet("monitorexitEliminated");
+            initCounter = snippet("initCounter");
+            checkCounter = snippet("checkCounter", String.class);
+            this.useFastLocking = useFastLocking;
+        }
+
+        public void lower(MonitorEnterNode monitorenterNode, @SuppressWarnings("unused") LoweringTool tool) {
+            StructuredGraph graph = (StructuredGraph) monitorenterNode.graph();
+
+            checkBalancedMonitors(graph);
+
+            FrameState stateAfter = monitorenterNode.stateAfter();
+            boolean eliminated = monitorenterNode.eliminated();
+            ResolvedJavaMethod method = eliminated ? monitorenterEliminated : useFastLocking ? monitorenter : monitorenterStub;
+            boolean checkNull = !monitorenterNode.object().stamp().nonNull();
+            Key key = new Key(method);
+            if (method != monitorenterEliminated) {
+                key.add("checkNull", checkNull);
+            }
+            if (!eliminated) {
+                key.add("trace", isTracingEnabledForType(monitorenterNode.object()) || isTracingEnabledForMethod(stateAfter.method()) || isTracingEnabledForMethod(graph.method()));
+            }
+
+            Arguments arguments = new Arguments();
+            if (!eliminated) {
+                arguments.add("object", monitorenterNode.object());
+            }
+            SnippetTemplate template = cache.get(key, assumptions);
+            Map<Node, Node> nodes = template.instantiate(runtime, monitorenterNode, DEFAULT_REPLACER, arguments);
+            for (Node n : nodes.values()) {
+                if (n instanceof BeginLockScopeNode) {
+                    BeginLockScopeNode begin = (BeginLockScopeNode) n;
+                    begin.setStateAfter(stateAfter);
+                }
+            }
+        }
+
+        public void lower(MonitorExitNode monitorexitNode, @SuppressWarnings("unused") LoweringTool tool) {
+            StructuredGraph graph = (StructuredGraph) monitorexitNode.graph();
+            FrameState stateAfter = monitorexitNode.stateAfter();
+            boolean eliminated = monitorexitNode.eliminated();
+            ResolvedJavaMethod method = eliminated ? monitorexitEliminated : useFastLocking ? monitorexit : monitorexitStub;
+            Key key = new Key(method);
+            if (!eliminated) {
+                key.add("trace", isTracingEnabledForType(monitorexitNode.object()) || isTracingEnabledForMethod(stateAfter.method()) || isTracingEnabledForMethod(graph.method()));
+            }
+            Arguments arguments = new Arguments();
+            if (!eliminated) {
+                arguments.add("object", monitorexitNode.object());
+            }
+            SnippetTemplate template = cache.get(key, assumptions);
+            Map<Node, Node> nodes = template.instantiate(runtime, monitorexitNode, DEFAULT_REPLACER, arguments);
+            for (Node n : nodes.values()) {
+                if (n instanceof EndLockScopeNode) {
+                    EndLockScopeNode end = (EndLockScopeNode) n;
+                    end.setStateAfter(stateAfter);
+                }
+            }
+        }
+
+        static boolean isTracingEnabledForType(ValueNode object) {
+            ResolvedJavaType type = object.objectStamp().type();
+            if (TRACE_TYPE_FILTER == null) {
+                return false;
+            } else {
+                if (TRACE_TYPE_FILTER.length() == 0) {
+                    return true;
+                }
+                if (type == null) {
+                    return false;
+                }
+                return (type.getName().contains(TRACE_TYPE_FILTER));
+            }
+        }
+
+        static boolean isTracingEnabledForMethod(ResolvedJavaMethod method) {
+            if (TRACE_METHOD_FILTER == null) {
+                return false;
+            } else {
+                if (TRACE_METHOD_FILTER.length() == 0) {
+                    return true;
+                }
+                if (method == null) {
+                    return false;
+                }
+                return (MetaUtil.format("%H.%n", method).contains(TRACE_METHOD_FILTER));
+            }
+        }
+
+        /**
+         * If balanced monitor checking is enabled then nodes are inserted at the start and all
+         * return points of the graph to initialize and check the monitor counter respectively.
+         */
+        private void checkBalancedMonitors(StructuredGraph graph) {
+            if (CHECK_BALANCED_MONITORS) {
+                NodeIterable<MonitorCounterNode> nodes = graph.getNodes().filter(MonitorCounterNode.class);
+                if (nodes.isEmpty()) {
+                    // Only insert the nodes if this is the first monitorenter being lowered.
+                    JavaType returnType = initCounter.getSignature().getReturnType(initCounter.getDeclaringClass());
+                    MethodCallTargetNode callTarget = graph.add(new MethodCallTargetNode(InvokeKind.Static, initCounter, new ValueNode[0], returnType));
+                    InvokeNode invoke = graph.add(new InvokeNode(callTarget, 0));
+                    invoke.setStateAfter(graph.start().stateAfter());
+                    graph.addAfterFixed(graph.start(), invoke);
+                    StructuredGraph inlineeGraph = (StructuredGraph) initCounter.getCompilerStorage().get(Graph.class);
+                    InliningUtil.inline(invoke, inlineeGraph, false);
+
+                    List<ReturnNode> rets = graph.getNodes().filter(ReturnNode.class).snapshot();
+                    for (ReturnNode ret : rets) {
+                        returnType = checkCounter.getSignature().getReturnType(checkCounter.getDeclaringClass());
+                        Object msg = ((HotSpotRuntime) runtime).registerGCRoot("unbalanced monitors in " + MetaUtil.format("%H.%n(%p)", graph.method()) + ", count = %d");
+                        ConstantNode errMsg = ConstantNode.forObject(msg, runtime, graph);
+                        callTarget = graph.add(new MethodCallTargetNode(InvokeKind.Static, checkCounter, new ValueNode[]{errMsg}, returnType));
+                        invoke = graph.add(new InvokeNode(callTarget, 0));
+                        List<ValueNode> stack = Collections.emptyList();
+                        FrameState stateAfter = new FrameState(graph.method(), FrameState.AFTER_BCI, new ValueNode[0], stack, new ValueNode[0], false, false);
+                        invoke.setStateAfter(graph.add(stateAfter));
+                        graph.addBeforeFixed(ret, invoke);
+                        inlineeGraph = (StructuredGraph) checkCounter.getCompilerStorage().get(Graph.class);
+                        InliningUtil.inline(invoke, inlineeGraph, false);
+                    }
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,386 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.replacements;
+
+import static com.oracle.graal.api.code.UnsignedMath.*;
+import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*;
+import static com.oracle.graal.nodes.extended.UnsafeArrayCastNode.*;
+import static com.oracle.graal.nodes.extended.UnsafeCastNode.*;
+import static com.oracle.graal.replacements.Snippet.Varargs.*;
+import static com.oracle.graal.replacements.SnippetTemplate.*;
+import static com.oracle.graal.replacements.SnippetTemplate.Arguments.*;
+import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*;
+import static com.oracle.graal.replacements.nodes.ExplodeLoopNode.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.nodes.*;
+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.phases.*;
+import com.oracle.graal.replacements.*;
+import com.oracle.graal.replacements.Snippet.*;
+import com.oracle.graal.replacements.nodes.*;
+import com.oracle.graal.word.*;
+
+/**
+ * Snippets used for implementing NEW, ANEWARRAY and NEWARRAY.
+ */
+public class NewObjectSnippets implements Snippets {
+
+    // @formatter:off
+
+    @Snippet
+    public static Word allocate(@Parameter("size") int size) {
+        Word thread = thread();
+        Word top = readTlabTop(thread);
+        Word end = readTlabEnd(thread);
+        Word newTop = top.add(size);
+        // this check might lead to problems if the TLAB is within 16GB of the address space end (checked in c++ code)
+        if (newTop.belowOrEqual(end)) {
+            probability(FAST_PATH_PROBABILITY);
+            writeTlabTop(thread, newTop);
+            return top;
+        }
+        return Word.zero();
+    }
+
+    @Snippet
+    public static Object initializeObject(
+                    @Parameter("memory") Word memory,
+                    @Parameter("hub") Word hub,
+                    @Parameter("prototypeMarkWord") Word prototypeMarkWord,
+                    @ConstantParameter("size") int size,
+                    @ConstantParameter("fillContents") boolean fillContents,
+                    @ConstantParameter("locked") boolean locked) {
+
+        Object result;
+        if (memory.equal(0)) {
+            new_stub.inc();
+            result = NewInstanceStubCall.call(hub);
+        } else {
+            probability(FAST_PATH_PROBABILITY);
+            if (locked) {
+                formatObject(hub, size, memory, thread().or(biasedLockPattern()), fillContents);
+            } else {
+                formatObject(hub, size, memory, prototypeMarkWord, fillContents);
+            }
+            result = memory.toObject();
+        }
+        return unsafeCast(verifyOop(result), StampFactory.forNodeIntrinsic());
+    }
+
+    @Snippet
+    public static Object initializeArray(
+                    @Parameter("memory") Word memory,
+                    @Parameter("hub") Word hub,
+                    @Parameter("length") int length,
+                    @Parameter("allocationSize") int allocationSize,
+                    @Parameter("prototypeMarkWord") Word prototypeMarkWord,
+                    @ConstantParameter("headerSize") int headerSize,
+                    @ConstantParameter("fillContents") boolean fillContents,
+                    @ConstantParameter("locked") boolean locked) {
+        if (locked) {
+            return initializeArray(memory, hub, length, allocationSize, thread().or(biasedLockPattern()), headerSize, fillContents);
+        } else {
+            return initializeArray(memory, hub, length, allocationSize, prototypeMarkWord, headerSize, fillContents);
+        }
+    }
+
+    private static Object initializeArray(Word memory, Word hub, int length, int allocationSize, Word prototypeMarkWord, int headerSize, boolean fillContents) {
+        Object result;
+        if (memory.equal(0)) {
+            newarray_stub.inc();
+            result = NewArrayStubCall.call(hub, length);
+        } else {
+            probability(FAST_PATH_PROBABILITY);
+            newarray_loopInit.inc();
+            formatArray(hub, allocationSize, length, headerSize, memory, prototypeMarkWord, fillContents);
+            result = memory.toObject();
+        }
+        return unsafeArrayCast(verifyOop(result), length, StampFactory.forNodeIntrinsic());
+    }
+
+    /**
+     * Maximum array length for which fast path allocation is used.
+     */
+    public static final int MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH = 0x00FFFFFF;
+
+    @Snippet
+    public static Object allocateArrayAndInitialize(
+                    @Parameter("length") int length,
+                    @ConstantParameter("alignment") int alignment,
+                    @ConstantParameter("headerSize") int headerSize,
+                    @ConstantParameter("log2ElementSize") int log2ElementSize,
+                    @ConstantParameter("type") ResolvedJavaType type) {
+        if (!belowThan(length, MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH)) {
+            probability(DEOPT_PATH_PROBABILITY);
+            // This handles both negative array sizes and very large array sizes
+            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
+        }
+        int allocationSize = computeArrayAllocationSize(length, alignment, headerSize, log2ElementSize);
+        Word memory = TLABAllocateNode.allocateVariableSize(allocationSize);
+        return InitializeArrayNode.initialize(memory, length, allocationSize, type, true, false);
+    }
+
+    /**
+     * Computes the size of the memory chunk allocated for an array. This size accounts for the array
+     * header size, boy size and any padding after the last element to satisfy object alignment requirements.
+     *
+     * @param length the number of elements in the array
+     * @param alignment the object alignment requirement
+     * @param headerSize the size of the array header
+     * @param log2ElementSize log2 of the size of an element in the array
+     */
+    public static int computeArrayAllocationSize(int length, int alignment, int headerSize, int log2ElementSize) {
+        int size = (length << log2ElementSize) + headerSize + (alignment - 1);
+        int mask = ~(alignment - 1);
+        return size & mask;
+    }
+
+    /**
+     * Calls the runtime stub for implementing MULTIANEWARRAY.
+     */
+    @Snippet
+    public static Object newmultiarray(
+                    @Parameter("hub") Word hub,
+                    @ConstantParameter("rank") int rank,
+                    @VarargsParameter("dimensions") int[] dimensions) {
+        Word dims = DimensionsNode.allocaDimsArray(rank);
+        ExplodeLoopNode.explodeLoop();
+        for (int i = 0; i < rank; i++) {
+            dims.writeInt(i * 4, dimensions[i], ANY_LOCATION);
+        }
+        return NewMultiArrayStubCall.call(hub, rank, dims);
+    }
+
+    /**
+     * Maximum size of an object whose body is initialized by a sequence of
+     * zero-stores to its fields. Larger objects have their bodies initialized
+     * in a loop.
+     */
+    private static final int MAX_UNROLLED_OBJECT_ZEROING_SIZE = 10 * wordSize();
+
+    /**
+     * Formats some allocated memory with an object header zeroes out the rest.
+     */
+    private static void formatObject(Word hub, int size, Word memory, Word compileTimePrototypeMarkWord, boolean fillContents) {
+        Word prototypeMarkWord = useBiasedLocking() ? hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION) : compileTimePrototypeMarkWord;
+        initializeObjectHeader(memory, prototypeMarkWord, hub);
+        if (fillContents) {
+            if (size <= MAX_UNROLLED_OBJECT_ZEROING_SIZE) {
+                new_seqInit.inc();
+                explodeLoop();
+                for (int offset = 2 * wordSize(); offset < size; offset += wordSize()) {
+                    memory.writeWord(offset, Word.zero(), ANY_LOCATION);
+                }
+            } else {
+                new_loopInit.inc();
+                for (int offset = 2 * wordSize(); offset < size; offset += wordSize()) {
+                    memory.writeWord(offset, Word.zero(), ANY_LOCATION);
+                }
+            }
+        }
+    }
+
+    /**
+     * Formats some allocated memory with an object header zeroes out the rest.
+     */
+    public static void formatArray(Word hub, int allocationSize, int length, int headerSize, Word memory, Word prototypeMarkWord, boolean fillContents) {
+        memory.writeInt(arrayLengthOffset(), length, ANY_LOCATION);
+        // store hub last as the concurrent garbage collectors assume length is valid if hub field is not null
+        initializeObjectHeader(memory, prototypeMarkWord, hub);
+        if (fillContents) {
+            for (int offset = headerSize; offset < allocationSize; offset += wordSize()) {
+                memory.writeWord(offset, Word.zero(), ANY_LOCATION);
+            }
+        }
+    }
+
+    // @formatter:on
+
+    public static class Templates extends AbstractTemplates<NewObjectSnippets> {
+
+        private final ResolvedJavaMethod allocate;
+        private final ResolvedJavaMethod initializeObject;
+        private final ResolvedJavaMethod initializeArray;
+        private final ResolvedJavaMethod allocateArrayAndInitialize;
+        private final ResolvedJavaMethod newmultiarray;
+        private final TargetDescription target;
+        private final boolean useTLAB;
+
+        public Templates(CodeCacheProvider runtime, Assumptions assumptions, TargetDescription target, boolean useTLAB) {
+            super(runtime, assumptions, target, NewObjectSnippets.class);
+            this.target = target;
+            this.useTLAB = useTLAB;
+            allocate = snippet("allocate", int.class);
+            initializeObject = snippet("initializeObject", Word.class, Word.class, Word.class, int.class, boolean.class, boolean.class);
+            initializeArray = snippet("initializeArray", Word.class, Word.class, int.class, int.class, Word.class, int.class, boolean.class, boolean.class);
+            allocateArrayAndInitialize = snippet("allocateArrayAndInitialize", int.class, int.class, int.class, int.class, ResolvedJavaType.class);
+            newmultiarray = snippet("newmultiarray", Word.class, int.class, int[].class);
+        }
+
+        /**
+         * Lowers a {@link NewInstanceNode}.
+         */
+        @SuppressWarnings("unused")
+        public void lower(NewInstanceNode newInstanceNode, LoweringTool tool) {
+            StructuredGraph graph = (StructuredGraph) newInstanceNode.graph();
+            HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) newInstanceNode.instanceClass();
+            ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, graph);
+            int size = instanceSize(type);
+
+            ValueNode memory;
+            if (!useTLAB) {
+                memory = ConstantNode.defaultForKind(target.wordKind, graph);
+            } else {
+                ConstantNode sizeNode = ConstantNode.forInt(size, graph);
+                TLABAllocateNode tlabAllocateNode = graph.add(new TLABAllocateNode(sizeNode));
+                graph.addBeforeFixed(newInstanceNode, tlabAllocateNode);
+                memory = tlabAllocateNode;
+            }
+            InitializeObjectNode initializeNode = graph.add(new InitializeObjectNode(memory, type, newInstanceNode.fillContents(), newInstanceNode.locked()));
+            graph.replaceFixedWithFixed(newInstanceNode, initializeNode);
+        }
+
+        /**
+         * Lowers a {@link NewArrayNode}.
+         */
+        @SuppressWarnings("unused")
+        public void lower(NewArrayNode newArrayNode, LoweringTool tool) {
+            StructuredGraph graph = (StructuredGraph) newArrayNode.graph();
+            ValueNode lengthNode = newArrayNode.length();
+            TLABAllocateNode tlabAllocateNode;
+            ResolvedJavaType elementType = newArrayNode.elementType();
+            ResolvedJavaType arrayType = elementType.getArrayClass();
+            Kind elementKind = elementType.getKind();
+            final int alignment = target.wordSize;
+            final int headerSize = HotSpotRuntime.getArrayBaseOffset(elementKind);
+            final Integer length = lengthNode.isConstant() ? Integer.valueOf(lengthNode.asConstant().asInt()) : null;
+            int log2ElementSize = CodeUtil.log2(target.sizeInBytes(elementKind));
+            if (!useTLAB) {
+                ConstantNode zero = ConstantNode.defaultForKind(target.wordKind, graph);
+                // value for 'size' doesn't matter as it isn't used since a stub call will be made
+                // anyway
+                // for both allocation and initialization - it just needs to be non-null
+                ConstantNode size = ConstantNode.forInt(-1, graph);
+                InitializeArrayNode initializeNode = graph.add(new InitializeArrayNode(zero, lengthNode, size, arrayType, newArrayNode.fillContents(), newArrayNode.locked()));
+                graph.replaceFixedWithFixed(newArrayNode, initializeNode);
+            } else if (length != null && belowThan(length, MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH)) {
+                // Calculate aligned size
+                int size = computeArrayAllocationSize(length, alignment, headerSize, log2ElementSize);
+                ConstantNode sizeNode = ConstantNode.forInt(size, graph);
+                tlabAllocateNode = graph.add(new TLABAllocateNode(sizeNode));
+                graph.addBeforeFixed(newArrayNode, tlabAllocateNode);
+                InitializeArrayNode initializeNode = graph.add(new InitializeArrayNode(tlabAllocateNode, lengthNode, sizeNode, arrayType, newArrayNode.fillContents(), newArrayNode.locked()));
+                graph.replaceFixedWithFixed(newArrayNode, initializeNode);
+            } else {
+                Key key = new Key(allocateArrayAndInitialize).add("alignment", alignment).add("headerSize", headerSize).add("log2ElementSize", log2ElementSize).add("type", arrayType);
+                Arguments arguments = new Arguments().add("length", lengthNode);
+                SnippetTemplate template = cache.get(key, assumptions);
+                Debug.log("Lowering allocateArrayAndInitialize in %s: node=%s, template=%s, arguments=%s", graph, newArrayNode, template, arguments);
+                template.instantiate(runtime, newArrayNode, DEFAULT_REPLACER, arguments);
+            }
+        }
+
+        @SuppressWarnings("unused")
+        public void lower(TLABAllocateNode tlabAllocateNode, LoweringTool tool) {
+            StructuredGraph graph = (StructuredGraph) tlabAllocateNode.graph();
+            ValueNode size = tlabAllocateNode.size();
+            Key key = new Key(allocate);
+            Arguments arguments = arguments("size", size);
+            SnippetTemplate template = cache.get(key, assumptions);
+            Debug.log("Lowering fastAllocate in %s: node=%s, template=%s, arguments=%s", graph, tlabAllocateNode, template, arguments);
+            template.instantiate(runtime, tlabAllocateNode, DEFAULT_REPLACER, arguments);
+        }
+
+        @SuppressWarnings("unused")
+        public void lower(InitializeObjectNode initializeNode, LoweringTool tool) {
+            StructuredGraph graph = (StructuredGraph) initializeNode.graph();
+            HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) initializeNode.type();
+            assert !type.isArray();
+            ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, graph);
+            int size = instanceSize(type);
+            Key key = new Key(initializeObject).add("size", size).add("fillContents", initializeNode.fillContents()).add("locked", initializeNode.locked());
+            ValueNode memory = initializeNode.memory();
+            Arguments arguments = arguments("memory", memory).add("hub", hub).add("prototypeMarkWord", type.prototypeMarkWord());
+            SnippetTemplate template = cache.get(key, assumptions);
+            Debug.log("Lowering initializeObject in %s: node=%s, template=%s, arguments=%s", graph, initializeNode, template, arguments);
+            template.instantiate(runtime, initializeNode, DEFAULT_REPLACER, arguments);
+        }
+
+        @SuppressWarnings("unused")
+        public void lower(InitializeArrayNode initializeNode, LoweringTool tool) {
+            StructuredGraph graph = (StructuredGraph) initializeNode.graph();
+            HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) initializeNode.type();
+            ResolvedJavaType elementType = type.getComponentType();
+            assert elementType != null;
+            ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, graph);
+            Kind elementKind = elementType.getKind();
+            final int headerSize = HotSpotRuntime.getArrayBaseOffset(elementKind);
+            Key key = new Key(initializeArray).add("headerSize", headerSize).add("fillContents", initializeNode.fillContents()).add("locked", initializeNode.locked());
+            ValueNode memory = initializeNode.memory();
+            Arguments arguments = arguments("memory", memory).add("hub", hub).add("prototypeMarkWord", type.prototypeMarkWord()).add("allocationSize", initializeNode.allocationSize()).add("length",
+                            initializeNode.length());
+            SnippetTemplate template = cache.get(key, assumptions);
+            Debug.log("Lowering initializeArray in %s: node=%s, template=%s, arguments=%s", graph, initializeNode, template, arguments);
+            template.instantiate(runtime, initializeNode, DEFAULT_REPLACER, arguments);
+        }
+
+        @SuppressWarnings("unused")
+        public void lower(NewMultiArrayNode newmultiarrayNode, LoweringTool tool) {
+            StructuredGraph graph = (StructuredGraph) newmultiarrayNode.graph();
+            int rank = newmultiarrayNode.dimensionCount();
+            ValueNode[] dims = new ValueNode[rank];
+            for (int i = 0; i < newmultiarrayNode.dimensionCount(); i++) {
+                dims[i] = newmultiarrayNode.dimension(i);
+            }
+            HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) newmultiarrayNode.type();
+            ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, graph);
+            Key key = new Key(newmultiarray).add("dimensions", vargargs(new int[rank], StampFactory.forKind(Kind.Int))).add("rank", rank);
+            Arguments arguments = arguments("dimensions", dims).add("hub", hub);
+            SnippetTemplate template = cache.get(key, assumptions);
+            template.instantiate(runtime, newmultiarrayNode, DEFAULT_REPLACER, arguments);
+        }
+
+        private static int instanceSize(HotSpotResolvedObjectType type) {
+            int size = type.instanceSize();
+            assert (size % wordSize()) == 0;
+            assert size >= 0;
+            return size;
+        }
+    }
+
+    private static final SnippetCounter.Group countersNew = GraalOptions.SnippetCounters ? new SnippetCounter.Group("NewInstance") : null;
+    private static final SnippetCounter new_seqInit = new SnippetCounter(countersNew, "tlabSeqInit", "TLAB alloc with unrolled zeroing");
+    private static final SnippetCounter new_loopInit = new SnippetCounter(countersNew, "tlabLoopInit", "TLAB alloc with zeroing in a loop");
+    private static final SnippetCounter new_stub = new SnippetCounter(countersNew, "stub", "alloc and zeroing via stub");
+
+    private static final SnippetCounter.Group countersNewArray = GraalOptions.SnippetCounters ? new SnippetCounter.Group("NewArray") : null;
+    private static final SnippetCounter newarray_loopInit = new SnippetCounter(countersNewArray, "tlabLoopInit", "TLAB alloc with zeroing in a loop");
+    private static final SnippetCounter newarray_stub = new SnippetCounter(countersNewArray, "stub", "alloc and zeroing via stub");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,152 @@
+/*
+ * 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.hotspot.replacements;
+
+import java.lang.reflect.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+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.phases.*;
+import com.oracle.graal.replacements.nodes.*;
+
+public class ObjectCloneNode extends MacroNode implements VirtualizableAllocation, ArrayLengthProvider {
+
+    public ObjectCloneNode(Invoke invoke) {
+        super(invoke);
+    }
+
+    @Override
+    public boolean inferStamp() {
+        return updateStamp(getObject().stamp());
+    }
+
+    private ValueNode getObject() {
+        return arguments.get(0);
+    }
+
+    @Override
+    protected StructuredGraph getSnippetGraph(LoweringTool tool) {
+        if (!GraalOptions.IntrinsifyObjectClone) {
+            return null;
+        }
+
+        ResolvedJavaType type = getObject().objectStamp().type();
+        Method method;
+        /*
+         * The first condition tests if the parameter is an array, the second condition tests if the
+         * parameter can be an array. Otherwise, the parameter is known to be a non-array object.
+         */
+        if (type.isArray()) {
+            method = ObjectCloneSnippets.arrayCloneMethod;
+        } else if (type == null || type.isAssignableFrom(tool.getRuntime().lookupJavaType(Object[].class))) {
+            method = ObjectCloneSnippets.genericCloneMethod;
+        } else {
+            method = ObjectCloneSnippets.instanceCloneMethod;
+        }
+        ResolvedJavaMethod snippetMethod = tool.getRuntime().lookupJavaMethod(method);
+        StructuredGraph snippetGraph = (StructuredGraph) snippetMethod.getCompilerStorage().get(Graph.class);
+
+        assert snippetGraph != null : "ObjectCloneSnippets should be installed";
+        return snippetGraph;
+    }
+
+    private static boolean isCloneableType(ResolvedJavaType type, MetaAccessProvider metaAccess) {
+        return metaAccess.lookupJavaType(Cloneable.class).isAssignableFrom(type);
+    }
+
+    private static ResolvedJavaType getConcreteType(ObjectStamp stamp, Assumptions assumptions) {
+        if (stamp.isExactType() || stamp.type() == null) {
+            return stamp.type();
+        } else {
+            ResolvedJavaType type = stamp.type().findUniqueConcreteSubtype();
+            if (type != null) {
+                assumptions.recordConcreteSubtype(stamp.type(), type);
+            }
+            return type;
+        }
+    }
+
+    @Override
+    public void virtualize(VirtualizerTool tool) {
+        State originalState = tool.getObjectState(getObject());
+        if (originalState != null && originalState.getState() == EscapeState.Virtual) {
+            VirtualObjectNode originalVirtual = originalState.getVirtualObject();
+            if (isCloneableType(originalVirtual.type(), tool.getMetaAccessProvider())) {
+                ValueNode[] newEntryState = new ValueNode[originalVirtual.entryCount()];
+                for (int i = 0; i < newEntryState.length; i++) {
+                    newEntryState[i] = originalState.getEntry(i);
+                }
+                VirtualObjectNode newVirtual = originalVirtual.duplicate();
+                tool.createVirtualObject(newVirtual, newEntryState, 0);
+                tool.replaceWithVirtual(newVirtual);
+            }
+        } else {
+            ValueNode obj;
+            if (originalState != null) {
+                obj = originalState.getMaterializedValue();
+            } else {
+                obj = tool.getReplacedValue(getObject());
+            }
+            ResolvedJavaType type = getConcreteType(obj.objectStamp(), tool.getAssumptions());
+            if (isCloneableType(type, tool.getMetaAccessProvider())) {
+                if (!type.isArray()) {
+                    VirtualInstanceNode newVirtual = new VirtualInstanceNode(type);
+                    ResolvedJavaField[] fields = newVirtual.getFields();
+
+                    ValueNode[] state = new ValueNode[fields.length];
+                    final LoadFieldNode[] loads = new LoadFieldNode[fields.length];
+                    for (int i = 0; i < fields.length; i++) {
+                        state[i] = loads[i] = graph().add(new LoadFieldNode(obj, fields[i]));
+                    }
+
+                    final StructuredGraph structuredGraph = (StructuredGraph) graph();
+                    tool.customAction(new Runnable() {
+
+                        public void run() {
+                            for (LoadFieldNode load : loads) {
+                                structuredGraph.addBeforeFixed(ObjectCloneNode.this, load);
+                            }
+                        }
+                    });
+                    tool.createVirtualObject(newVirtual, state, 0);
+                    tool.replaceWithVirtual(newVirtual);
+                }
+            }
+        }
+    }
+
+    @Override
+    public ValueNode length() {
+        if (getObject() instanceof ArrayLengthProvider) {
+            return ((ArrayLengthProvider) getObject()).length();
+        } else {
+            return null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2011, 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.hotspot.replacements;
+
+import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*;
+import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*;
+
+import java.lang.reflect.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.replacements.*;
+import com.oracle.graal.word.*;
+
+public class ObjectCloneSnippets implements Snippets {
+
+    public static final Method instanceCloneMethod = getCloneMethod("instanceClone");
+    public static final Method arrayCloneMethod = getCloneMethod("arrayClone");
+    public static final Method genericCloneMethod = getCloneMethod("genericClone");
+
+    private static Method getCloneMethod(String name) {
+        try {
+            return ObjectCloneSnippets.class.getDeclaredMethod(name, Object.class);
+        } catch (SecurityException | NoSuchMethodException e) {
+            throw new GraalInternalError(e);
+        }
+    }
+
+    private static Object instanceClone(Object src, Word hub, int layoutHelper) {
+        int instanceSize = layoutHelper;
+        Pointer memory = NewObjectSnippets.allocate(instanceSize);
+        Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION);
+        Object result = NewObjectSnippets.initializeObject((Word) memory, hub, prototypeMarkWord, instanceSize, false, false);
+
+        memory = Word.fromObject(result);
+        for (int offset = 2 * wordSize(); offset < instanceSize; offset += wordSize()) {
+            memory.writeWord(offset, Word.fromObject(src).readWord(offset, UNKNOWN_LOCATION), ANY_LOCATION);
+        }
+
+        return result;
+    }
+
+    private static Object arrayClone(Object src, Word hub, int layoutHelper) {
+        int arrayLength = ArrayLengthNode.arrayLength(src);
+        int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask();
+        int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift()) & layoutHelperHeaderSizeMask();
+        int sizeInBytes = NewObjectSnippets.computeArrayAllocationSize(arrayLength, wordSize(), headerSize, log2ElementSize);
+
+        Pointer memory = NewObjectSnippets.allocate(sizeInBytes);
+        Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION);
+        Object result = NewObjectSnippets.initializeArray((Word) memory, hub, arrayLength, sizeInBytes, prototypeMarkWord, headerSize, false, false);
+
+        memory = Word.fromObject(result);
+        for (int offset = headerSize; offset < sizeInBytes; offset += wordSize()) {
+            memory.writeWord(offset, Word.fromObject(src).readWord(offset, UNKNOWN_LOCATION), ANY_LOCATION);
+        }
+        return result;
+    }
+
+    private static Word getAndCheckHub(Object src) {
+        Word hub = loadHub(src);
+        if (!(src instanceof Cloneable)) {
+            probability(DEOPT_PATH_PROBABILITY);
+            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
+        }
+        return hub;
+    }
+
+    @Snippet
+    public static Object instanceClone(Object src) {
+        instanceCloneCounter.inc();
+        Word hub = getAndCheckHub(src);
+        return instanceClone(src, hub, hub.readInt(layoutHelperOffset(), FINAL_LOCATION));
+    }
+
+    @Snippet
+    public static Object arrayClone(Object src) {
+        arrayCloneCounter.inc();
+        Word hub = getAndCheckHub(src);
+        int layoutHelper = hub.readInt(layoutHelperOffset(), FINAL_LOCATION);
+        return arrayClone(src, hub, layoutHelper);
+    }
+
+    @Snippet
+    public static Object genericClone(Object src) {
+        genericCloneCounter.inc();
+        Word hub = getAndCheckHub(src);
+        int layoutHelper = hub.readInt(layoutHelperOffset(), FINAL_LOCATION);
+        if (layoutHelper < 0) {
+            probability(LIKELY_PROBABILITY);
+            genericArrayCloneCounter.inc();
+            return arrayClone(src, hub, layoutHelper);
+        } else {
+            genericInstanceCloneCounter.inc();
+            return instanceClone(src, hub, layoutHelper);
+        }
+    }
+
+    private static final SnippetCounter.Group cloneCounters = GraalOptions.SnippetCounters ? new SnippetCounter.Group("Object.clone") : null;
+    private static final SnippetCounter instanceCloneCounter = new SnippetCounter(cloneCounters, "instanceClone", "clone snippet for instances");
+    private static final SnippetCounter arrayCloneCounter = new SnippetCounter(cloneCounters, "arrayClone", "clone snippet for arrays");
+    private static final SnippetCounter genericCloneCounter = new SnippetCounter(cloneCounters, "genericClone", "clone snippet for arrays and instances");
+
+    private static final SnippetCounter.Group genericCloneCounters = GraalOptions.SnippetCounters ? new SnippetCounter.Group("Object.clone generic snippet") : null;
+    private static final SnippetCounter genericInstanceCloneCounter = new SnippetCounter(genericCloneCounters, "genericInstanceClone", "generic clone implementation took instance path");
+    private static final SnippetCounter genericArrayCloneCounter = new SnippetCounter(genericCloneCounters, "genericArrayClone", "generic clone implementation took array path");
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectSubstitutions.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.replacements;
+
+import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*;
+import static com.oracle.graal.nodes.extended.UnsafeCastNode.*;
+
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.replacements.*;
+import com.oracle.graal.replacements.ClassSubstitution.*;
+import com.oracle.graal.word.*;
+
+/**
+ * Substitutions for {@link java.lang.Object} methods.
+ */
+@ClassSubstitution(java.lang.Object.class)
+public class ObjectSubstitutions {
+
+    @MethodSubstitution(isStatic = false)
+    public static Class<?> getClass(final Object thisObj) {
+        Word hub = loadHub(thisObj);
+        return unsafeCast(hub.readObject(Word.signed(classMirrorOffset()), LocationNode.FINAL_LOCATION), Class.class, true, true);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static int hashCode(final Object thisObj) {
+        return computeHashCode(thisObj);
+    }
+
+    @MacroSubstitution(macro = ObjectCloneNode.class, isStatic = false)
+    public static native Object clone(Object obj);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemSubstitutions.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2011, 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.hotspot.replacements;
+
+import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*;
+import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*;
+
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
+import com.oracle.graal.graph.Node.ConstantNodeParameter;
+import com.oracle.graal.graph.Node.NodeIntrinsic;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.replacements.*;
+import com.oracle.graal.replacements.ClassSubstitution.*;
+
+/**
+ * Substitutions for {@link java.lang.System} methods.
+ */
+@ClassSubstitution(java.lang.System.class)
+public class SystemSubstitutions {
+
+    public static final Descriptor JAVA_TIME_MILLIS = new Descriptor("javaTimeMillis", false, long.class);
+    public static final Descriptor JAVA_TIME_NANOS = new Descriptor("javaTimeNanos", false, long.class);
+
+    @MacroSubstitution(macro = ArrayCopyNode.class)
+    public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
+
+    @MethodSubstitution
+    public static long currentTimeMillis() {
+        return callLong(JAVA_TIME_MILLIS);
+    }
+
+    @MethodSubstitution
+    public static long nanoTime() {
+        return callLong(JAVA_TIME_NANOS);
+    }
+
+    @MethodSubstitution
+    public static int identityHashCode(Object x) {
+        if (x == null) {
+            probability(NOT_FREQUENT_PROBABILITY);
+            return 0;
+        }
+
+        return computeHashCode(x);
+    }
+
+    @NodeIntrinsic(value = RuntimeCallNode.class, setStampFromReturnType = true)
+    public static native long callLong(@ConstantNodeParameter Descriptor descriptor);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ThreadSubstitutions.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.replacements;
+
+import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*;
+
+import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.replacements.*;
+import com.oracle.graal.replacements.ClassSubstitution.*;
+import com.oracle.graal.word.*;
+
+/**
+ * Substitutions for {@link java.lang.Thread} methods.
+ */
+@ClassSubstitution(java.lang.Thread.class)
+public class ThreadSubstitutions {
+
+    @MethodSubstitution
+    public static Thread currentThread() {
+        return CurrentThread.get();
+    }
+
+    @MethodSubstitution(isStatic = false)
+    private static boolean isInterrupted(final Thread thisObject, boolean clearInterrupted) {
+        Word rawThread = HotSpotCurrentRawThreadNode.get();
+        Thread thread = (Thread) rawThread.readObject(threadObjectOffset(), FINAL_LOCATION);
+        if (thisObject == thread) {
+            Word osThread = rawThread.readWord(osThreadOffset(), FINAL_LOCATION);
+            boolean interrupted = osThread.readInt(osThreadInterruptedOffset(), UNKNOWN_LOCATION) != 0;
+            if (!interrupted || !clearInterrupted) {
+                return interrupted;
+            }
+        }
+
+        return ThreadIsInterruptedStubCall.call(thisObject, clearInterrupted) != 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,125 @@
+/*
+ * 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.hotspot.replacements;
+
+import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*;
+import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.replacements.*;
+import com.oracle.graal.word.*;
+
+/**
+ * Utilities and common code paths used by the type check snippets.
+ */
+public class TypeCheckSnippetUtils {
+
+    public static final Object TYPE_DISPLAY_LOCATION = LocationNode.createLocation("TypeDisplay");
+
+    static boolean checkSecondarySubType(Word t, Word s) {
+        // if (S.cache == T) return true
+        if (s.readWord(secondarySuperCacheOffset(), SECONDARY_SUPER_CACHE_LOCATION).equal(t)) {
+            cacheHit.inc();
+            return true;
+        }
+
+        return checkSelfAndSupers(t, s);
+    }
+
+    static boolean checkUnknownSubType(Word t, Word s) {
+        // int off = T.offset
+        int superCheckOffset = t.readInt(superCheckOffsetOffset(), FINAL_LOCATION);
+        boolean primary = superCheckOffset != secondarySuperCacheOffset();
+
+        // if (T = S[off]) return true
+        if (s.readWord(superCheckOffset, TYPE_DISPLAY_LOCATION).equal(t)) {
+            if (primary) {
+                cacheHit.inc();
+            } else {
+                displayHit.inc();
+            }
+            return true;
+        }
+
+        // if (off != &cache) return false
+        if (primary) {
+            displayMiss.inc();
+            return false;
+        }
+
+        return checkSelfAndSupers(t, s);
+    }
+
+    private static boolean checkSelfAndSupers(Word t, Word s) {
+        // if (T == S) return true
+        if (s.equal(t)) {
+            T_equals_S.inc();
+            return true;
+        }
+
+        // if (S.scan_s_s_array(T)) { S.cache = T; return true; }
+        Word secondarySupers = s.readWord(secondarySupersOffset(), SECONDARY_SUPERS_LOCATION);
+        int length = secondarySupers.readInt(metaspaceArrayLengthOffset(), FINAL_LOCATION);
+        for (int i = 0; i < length; i++) {
+            if (t.equal(loadSecondarySupersElement(secondarySupers, i))) {
+                probability(NOT_LIKELY_PROBABILITY);
+                s.writeWord(secondarySuperCacheOffset(), t, SECONDARY_SUPER_CACHE_LOCATION);
+                secondariesHit.inc();
+                return true;
+            }
+        }
+        secondariesMiss.inc();
+        return false;
+    }
+
+    static ConstantNode[] createHints(TypeCheckHints hints, MetaAccessProvider runtime, Graph graph) {
+        ConstantNode[] hintHubs = new ConstantNode[hints.types.length];
+        for (int i = 0; i < hintHubs.length; i++) {
+            hintHubs[i] = ConstantNode.forConstant(((HotSpotResolvedObjectType) hints.types[i]).klass(), runtime, graph);
+        }
+        return hintHubs;
+    }
+
+    static Word loadSecondarySupersElement(Word metaspaceArray, int index) {
+        return metaspaceArray.readWord(metaspaceArrayBaseOffset() + index * wordSize(), FINAL_LOCATION);
+    }
+
+    private static final SnippetCounter.Group counters = GraalOptions.SnippetCounters ? new SnippetCounter.Group("TypeCheck") : null;
+    static final SnippetCounter hintsHit = new SnippetCounter(counters, "hintsHit", "hit a hint type");
+    static final SnippetCounter exactHit = new SnippetCounter(counters, "exactHit", "exact type test succeeded");
+    static final SnippetCounter exactMiss = new SnippetCounter(counters, "exactMiss", "exact type test failed");
+    static final SnippetCounter isNull = new SnippetCounter(counters, "isNull", "object tested was null");
+    static final SnippetCounter cacheHit = new SnippetCounter(counters, "cacheHit", "secondary type cache hit");
+    static final SnippetCounter secondariesHit = new SnippetCounter(counters, "secondariesHit", "secondaries scan succeeded");
+    static final SnippetCounter secondariesMiss = new SnippetCounter(counters, "secondariesMiss", "secondaries scan failed");
+    static final SnippetCounter displayHit = new SnippetCounter(counters, "displayHit", "primary type test succeeded");
+    static final SnippetCounter displayMiss = new SnippetCounter(counters, "displayMiss", "primary type test failed");
+    static final SnippetCounter T_equals_S = new SnippetCounter(counters, "T_equals_S", "object type was equal to secondary type");
+
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/AESCryptSubstitutions.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.snippets;
-
-import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
-import sun.misc.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.gen.*;
-import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.hotspot.nodes.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.snippets.*;
-import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution;
-import com.oracle.graal.word.*;
-
-/**
- * Substitutions for {@code com.sun.crypto.provider.AESCrypt} methods.
- */
-@ClassSubstitution(className = "com.sun.crypto.provider.AESCrypt")
-public class AESCryptSubstitutions {
-
-    static final long kOffset;
-    static final Class<?> AESCryptClass;
-
-    static {
-        try {
-            // Need to use launcher class path as com.sun.crypto.provider.AESCrypt
-            // is normally not on the boot class path
-            ClassLoader cl = Launcher.getLauncher().getClassLoader();
-            AESCryptClass = Class.forName("com.sun.crypto.provider.AESCrypt", true, cl);
-            kOffset = UnsafeAccess.unsafe.objectFieldOffset(AESCryptClass.getDeclaredField("K"));
-        } catch (Exception ex) {
-            throw new GraalInternalError(ex);
-        }
-    }
-
-    @MethodSubstitution(isStatic = false)
-    static void encryptBlock(Object rcvr, byte[] in, int inOffset, byte[] out, int outOffset) {
-        crypt(rcvr, in, inOffset, out, outOffset, true);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    static void decryptBlock(Object rcvr, byte[] in, int inOffset, byte[] out, int outOffset) {
-        crypt(rcvr, in, inOffset, out, outOffset, false);
-    }
-
-    private static void crypt(Object rcvr, byte[] in, int inOffset, byte[] out, int outOffset, boolean encrypt) {
-        Word kAddr = Word.fromObject(rcvr).readWord(Word.unsigned(kOffset), UNKNOWN_LOCATION).add(arrayBaseOffset(Kind.Byte));
-        Word inAddr = Word.unsigned(GetObjectAddressNode.get(in) + arrayBaseOffset(Kind.Byte) + inOffset);
-        Word outAddr = Word.unsigned(GetObjectAddressNode.get(out) + arrayBaseOffset(Kind.Byte) + outOffset);
-        if (encrypt) {
-            EncryptBlockStubCall.call(inAddr, outAddr, kAddr);
-        } else {
-            DecryptBlockStubCall.call(inAddr, outAddr, kAddr);
-        }
-    }
-
-    abstract static class CryptBlockStubCall extends FixedWithNextNode implements LIRGenLowerable {
-
-        @Input private final ValueNode in;
-        @Input private final ValueNode out;
-        @Input private final ValueNode key;
-
-        private final Descriptor descriptor;
-
-        public CryptBlockStubCall(ValueNode in, ValueNode out, ValueNode key, Descriptor descriptor) {
-            super(StampFactory.forVoid());
-            this.in = in;
-            this.out = out;
-            this.key = key;
-            this.descriptor = descriptor;
-        }
-
-        @Override
-        public void generate(LIRGenerator gen) {
-            RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(descriptor);
-            gen.emitCall(stub, stub.getCallingConvention(), false, gen.operand(in), gen.operand(out), gen.operand(key));
-        }
-    }
-
-    public static class EncryptBlockStubCall extends CryptBlockStubCall {
-
-        public static final Descriptor ENCRYPT_BLOCK = new Descriptor("encrypt_block", false, void.class, Word.class, Word.class, Word.class);
-
-        public EncryptBlockStubCall(ValueNode in, ValueNode out, ValueNode key) {
-            super(in, out, key, ENCRYPT_BLOCK);
-        }
-
-        @NodeIntrinsic
-        public static native void call(Word in, Word out, Word key);
-    }
-
-    public static class DecryptBlockStubCall extends CryptBlockStubCall {
-
-        public static final Descriptor DECRYPT_BLOCK = new Descriptor("decrypt_block", false, void.class, Word.class, Word.class, Word.class);
-
-        public DecryptBlockStubCall(ValueNode in, ValueNode out, ValueNode key) {
-            super(in, out, key, DECRYPT_BLOCK);
-        }
-
-        @NodeIntrinsic
-        public static native void call(Word in, Word out, Word key);
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopyNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,172 +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.hotspot.snippets;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.debug.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.Node.IterableNodeType;
-import com.oracle.graal.loop.phases.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.virtual.*;
-import com.oracle.graal.phases.*;
-import com.oracle.graal.phases.common.*;
-import com.oracle.graal.snippets.nodes.*;
-
-public class ArrayCopyNode extends MacroNode implements Virtualizable, IterableNodeType, Lowerable {
-
-    public ArrayCopyNode(Invoke invoke) {
-        super(invoke);
-    }
-
-    private ValueNode getSource() {
-        return arguments.get(0);
-    }
-
-    private ValueNode getSourcePosition() {
-        return arguments.get(1);
-    }
-
-    private ValueNode getDestination() {
-        return arguments.get(2);
-    }
-
-    private ValueNode getDestinationPosition() {
-        return arguments.get(3);
-    }
-
-    private ValueNode getLength() {
-        return arguments.get(4);
-    }
-
-    private StructuredGraph selectSnippet(LoweringTool tool) {
-        ResolvedJavaType srcType = getSource().objectStamp().type();
-        ResolvedJavaType destType = getDestination().objectStamp().type();
-
-        if (srcType == null || !srcType.isArray() || destType == null || !destType.isArray()) {
-            return null;
-        }
-        if (!destType.getComponentType().isAssignableFrom(srcType.getComponentType()) || !getDestination().objectStamp().isExactType()) {
-            return null;
-        }
-        Kind componentKind = srcType.getComponentType().getKind();
-        ResolvedJavaMethod snippetMethod = tool.getRuntime().lookupJavaMethod(ArrayCopySnippets.getSnippetForKind(componentKind));
-        return (StructuredGraph) snippetMethod.getCompilerStorage().get(Graph.class);
-    }
-
-    private static void unrollFixedLengthLoop(StructuredGraph snippetGraph, int length, LoweringTool tool) {
-        LocalNode lengthLocal = snippetGraph.getLocal(4);
-        if (lengthLocal != null) {
-            snippetGraph.replaceFloating(lengthLocal, ConstantNode.forInt(length, snippetGraph));
-        }
-        // the canonicalization before loop unrolling is needed to propagate the length into
-        // additions, etc.
-        new CanonicalizerPhase(tool.getRuntime(), tool.assumptions()).apply(snippetGraph);
-        new LoopFullUnrollPhase(tool.getRuntime(), tool.assumptions()).apply(snippetGraph);
-        new CanonicalizerPhase(tool.getRuntime(), tool.assumptions()).apply(snippetGraph);
-    }
-
-    private static void replaceSnippetInvokes(StructuredGraph snippetGraph, ResolvedJavaMethod targetMethod, int bci) {
-        for (InvokeNode invoke : snippetGraph.getNodes(InvokeNode.class)) {
-            if (invoke.methodCallTarget().targetMethod() != targetMethod) {
-                throw new GraalInternalError("unexpected invoke in arraycopy snippet");
-            }
-            if (invoke.stateAfter().bci == FrameState.INVALID_FRAMESTATE_BCI) {
-                InvokeNode newInvoke = snippetGraph.add(new InvokeNode(invoke.methodCallTarget(), bci));
-                newInvoke.setStateAfter(snippetGraph.add(new FrameState(FrameState.AFTER_BCI)));
-                snippetGraph.replaceFixedWithFixed(invoke, newInvoke);
-            } else {
-                assert invoke.stateAfter().bci == FrameState.AFTER_BCI : invoke;
-            }
-        }
-    }
-
-    @Override
-    protected StructuredGraph getSnippetGraph(LoweringTool tool) {
-        if (!GraalOptions.IntrinsifyArrayCopy) {
-            return null;
-        }
-
-        StructuredGraph snippetGraph = selectSnippet(tool);
-        if (snippetGraph == null) {
-            ResolvedJavaMethod snippetMethod = tool.getRuntime().lookupJavaMethod(ArrayCopySnippets.genericArraycopySnippet);
-            snippetGraph = ((StructuredGraph) snippetMethod.getCompilerStorage().get(Graph.class)).copy();
-            assert snippetGraph != null : "ArrayCopySnippets should be installed";
-
-            replaceSnippetInvokes(snippetGraph, getTargetMethod(), getBci());
-        } else {
-            assert snippetGraph != null : "ArrayCopySnippets should be installed";
-
-            if (getLength().isConstant()) {
-                snippetGraph = snippetGraph.copy();
-                unrollFixedLengthLoop(snippetGraph, getLength().asConstant().asInt(), tool);
-            }
-        }
-        return snippetGraph;
-    }
-
-    private static boolean checkBounds(int position, int length, VirtualObjectNode virtualObject) {
-        return position >= 0 && position + length <= virtualObject.entryCount();
-    }
-
-    private static boolean checkEntryTypes(int srcPos, int length, State srcState, ResolvedJavaType destComponentType) {
-        if (destComponentType.getKind() == Kind.Object) {
-            for (int i = 0; i < length; i++) {
-                if (!destComponentType.isAssignableFrom(srcState.getEntry(srcPos + i).objectStamp().type())) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public void virtualize(VirtualizerTool tool) {
-        if (getSourcePosition().isConstant() && getDestinationPosition().isConstant() && getLength().isConstant()) {
-            int srcPos = getSourcePosition().asConstant().asInt();
-            int destPos = getDestinationPosition().asConstant().asInt();
-            int length = getLength().asConstant().asInt();
-            State srcState = tool.getObjectState(getSource());
-            State destState = tool.getObjectState(getDestination());
-
-            if (srcState != null && srcState.getState() == EscapeState.Virtual && destState != null && destState.getState() == EscapeState.Virtual) {
-                VirtualObjectNode srcVirtual = srcState.getVirtualObject();
-                VirtualObjectNode destVirtual = destState.getVirtualObject();
-                if (length < 0 || !checkBounds(srcPos, length, srcVirtual) || !checkBounds(destPos, length, destVirtual)) {
-                    return;
-                }
-                if (!checkEntryTypes(srcPos, length, srcState, destVirtual.type().getComponentType())) {
-                    return;
-                }
-                for (int i = 0; i < length; i++) {
-                    tool.setVirtualEntry(destState, destPos + i, srcState.getEntry(srcPos + i));
-                }
-                tool.delete();
-                if (Debug.isLogEnabled()) {
-                    Debug.log("virtualized arraycopyf(%s, %d, %s, %d, %d)", getSource(), srcPos, getDestination(), destPos, length);
-                }
-            }
-        }
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,359 +0,0 @@
-/*
- * Copyright (c) 2011, 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.hotspot.snippets;
-
-import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
-import static com.oracle.graal.snippets.nodes.BranchProbabilityNode.*;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.hotspot.nodes.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.phases.*;
-import com.oracle.graal.snippets.*;
-import com.oracle.graal.snippets.Snippet.ConstantParameter;
-import com.oracle.graal.snippets.nodes.*;
-import com.oracle.graal.word.*;
-
-@SuppressWarnings("unused")
-public class ArrayCopySnippets implements SnippetsInterface {
-
-    private static final EnumMap<Kind, Method> arraycopyMethods = new EnumMap<>(Kind.class);
-    public static final Method genericArraycopySnippet;
-
-    private static void addArraycopySnippetMethod(Kind kind, Class<?> arrayClass) throws NoSuchMethodException {
-        arraycopyMethods.put(kind, ArrayCopySnippets.class.getDeclaredMethod("arraycopy", arrayClass, int.class, arrayClass, int.class, int.class));
-    }
-
-    static {
-        try {
-            addArraycopySnippetMethod(Kind.Byte, byte[].class);
-            addArraycopySnippetMethod(Kind.Boolean, boolean[].class);
-            addArraycopySnippetMethod(Kind.Char, char[].class);
-            addArraycopySnippetMethod(Kind.Short, short[].class);
-            addArraycopySnippetMethod(Kind.Int, int[].class);
-            addArraycopySnippetMethod(Kind.Long, long[].class);
-            addArraycopySnippetMethod(Kind.Float, float[].class);
-            addArraycopySnippetMethod(Kind.Double, double[].class);
-            addArraycopySnippetMethod(Kind.Object, Object[].class);
-            genericArraycopySnippet = ArrayCopySnippets.class.getDeclaredMethod("arraycopy", Object.class, int.class, Object.class, int.class, int.class);
-        } catch (SecurityException | NoSuchMethodException e) {
-            throw new GraalInternalError(e);
-        }
-    }
-
-    public static Method getSnippetForKind(Kind kind) {
-        return arraycopyMethods.get(kind);
-    }
-
-    private static final Kind VECTOR_KIND = Kind.Long;
-    private static final long VECTOR_SIZE = arrayIndexScale(Kind.Long);
-
-    public static void vectorizedCopy(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter("baseKind") Kind baseKind) {
-        checkNonNull(src);
-        checkNonNull(dest);
-        checkLimits(src, srcPos, dest, destPos, length);
-        int header = arrayBaseOffset(baseKind);
-        int elementSize = arrayIndexScale(baseKind);
-        long byteLength = (long) length * elementSize;
-        long nonVectorBytes = byteLength % VECTOR_SIZE;
-        long srcOffset = (long) srcPos * elementSize;
-        long destOffset = (long) destPos * elementSize;
-        if (src == dest && srcPos < destPos) { // bad aliased case
-            probability(NOT_FREQUENT_PROBABILITY);
-            for (long i = byteLength - elementSize; i >= byteLength - nonVectorBytes; i -= elementSize) {
-                UnsafeStoreNode.store(dest, header, i + destOffset, UnsafeLoadNode.load(src, header, i + srcOffset, baseKind), baseKind);
-            }
-            long vectorLength = byteLength - nonVectorBytes;
-            for (long i = vectorLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) {
-                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
-                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
-            }
-        } else {
-            for (long i = 0; i < nonVectorBytes; i += elementSize) {
-                UnsafeStoreNode.store(dest, header, i + destOffset, UnsafeLoadNode.load(src, header, i + srcOffset, baseKind), baseKind);
-            }
-            for (long i = nonVectorBytes; i < byteLength; i += VECTOR_SIZE) {
-                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
-                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
-            }
-        }
-    }
-
-    public static void checkNonNull(Object obj) {
-        if (obj == null) {
-            probability(DEOPT_PATH_PROBABILITY);
-            checkNPECounter.inc();
-            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
-        }
-    }
-
-    public static int checkArrayType(Word hub) {
-        int layoutHelper = readLayoutHelper(hub);
-        if (layoutHelper >= 0) {
-            probability(DEOPT_PATH_PROBABILITY);
-            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
-        }
-        return layoutHelper;
-    }
-
-    public static void checkLimits(Object src, int srcPos, Object dest, int destPos, int length) {
-        if (srcPos < 0) {
-            probability(DEOPT_PATH_PROBABILITY);
-            checkAIOOBECounter.inc();
-            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
-        }
-        if (destPos < 0) {
-            probability(DEOPT_PATH_PROBABILITY);
-            checkAIOOBECounter.inc();
-            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
-        }
-        if (length < 0) {
-            probability(DEOPT_PATH_PROBABILITY);
-            checkAIOOBECounter.inc();
-            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
-        }
-        if (srcPos + length > ArrayLengthNode.arrayLength(src)) {
-            probability(DEOPT_PATH_PROBABILITY);
-            checkAIOOBECounter.inc();
-            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
-        }
-        if (destPos + length > ArrayLengthNode.arrayLength(dest)) {
-            probability(DEOPT_PATH_PROBABILITY);
-            checkAIOOBECounter.inc();
-            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
-        }
-        checkSuccessCounter.inc();
-    }
-
-    @Snippet
-    public static void arraycopy(byte[] src, int srcPos, byte[] dest, int destPos, int length) {
-        byteCounter.inc();
-        vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Byte);
-    }
-
-    @Snippet
-    public static void arraycopy(boolean[] src, int srcPos, boolean[] dest, int destPos, int length) {
-        booleanCounter.inc();
-        vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Byte);
-    }
-
-    @Snippet
-    public static void arraycopy(char[] src, int srcPos, char[] dest, int destPos, int length) {
-        charCounter.inc();
-        vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Char);
-    }
-
-    @Snippet
-    public static void arraycopy(short[] src, int srcPos, short[] dest, int destPos, int length) {
-        shortCounter.inc();
-        vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Short);
-    }
-
-    @Snippet
-    public static void arraycopy(int[] src, int srcPos, int[] dest, int destPos, int length) {
-        intCounter.inc();
-        vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Int);
-    }
-
-    @Snippet
-    public static void arraycopy(float[] src, int srcPos, float[] dest, int destPos, int length) {
-        floatCounter.inc();
-        vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Float);
-    }
-
-    @Snippet
-    public static void arraycopy(long[] src, int srcPos, long[] dest, int destPos, int length) {
-        longCounter.inc();
-        checkNonNull(src);
-        checkNonNull(dest);
-        checkLimits(src, srcPos, dest, destPos, length);
-        Kind baseKind = Kind.Long;
-        int header = arrayBaseOffset(baseKind);
-        long byteLength = (long) length * arrayIndexScale(baseKind);
-        long srcOffset = (long) srcPos * arrayIndexScale(baseKind);
-        long destOffset = (long) destPos * arrayIndexScale(baseKind);
-        if (src == dest && srcPos < destPos) { // bad aliased case
-            for (long i = byteLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) {
-                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
-                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
-            }
-        } else {
-            for (long i = 0; i < byteLength; i += VECTOR_SIZE) {
-                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
-                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
-            }
-        }
-    }
-
-    @Snippet
-    public static void arraycopy(double[] src, int srcPos, double[] dest, int destPos, int length) {
-        doubleCounter.inc();
-        checkNonNull(src);
-        checkNonNull(dest);
-        checkLimits(src, srcPos, dest, destPos, length);
-        Kind baseKind = Kind.Double;
-        int header = arrayBaseOffset(baseKind);
-        long byteLength = (long) length * arrayIndexScale(baseKind);
-        long srcOffset = (long) srcPos * arrayIndexScale(baseKind);
-        long destOffset = (long) destPos * arrayIndexScale(baseKind);
-        if (src == dest && srcPos < destPos) { // bad aliased case
-            for (long i = byteLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) {
-                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
-                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
-            }
-        } else {
-            for (long i = 0; i < byteLength; i += VECTOR_SIZE) {
-                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
-                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
-            }
-        }
-    }
-
-    // Does NOT perform store checks
-    @Snippet
-    public static void arraycopy(Object[] src, int srcPos, Object[] dest, int destPos, int length) {
-        objectCounter.inc();
-        checkNonNull(src);
-        checkNonNull(dest);
-        checkLimits(src, srcPos, dest, destPos, length);
-        final int scale = arrayIndexScale(Kind.Object);
-        int header = arrayBaseOffset(Kind.Object);
-        if (src == dest && srcPos < destPos) { // bad aliased case
-            long start = (long) (length - 1) * scale;
-            for (long i = start; i >= 0; i -= scale) {
-                Object a = UnsafeLoadNode.load(src, header, i + (long) srcPos * scale, Kind.Object);
-                DirectObjectStoreNode.storeObject(dest, header, i + (long) destPos * scale, a);
-            }
-        } else {
-            long end = (long) length * scale;
-            for (long i = 0; i < end; i += scale) {
-                Object a = UnsafeLoadNode.load(src, header, i + (long) srcPos * scale, Kind.Object);
-                DirectObjectStoreNode.storeObject(dest, header, i + (long) destPos * scale, a);
-            }
-        }
-        if (length > 0) {
-            int cardShift = cardTableShift();
-            long cardStart = cardTableStart();
-            long dstAddr = GetObjectAddressNode.get(dest);
-            long start = (dstAddr + header + (long) destPos * scale) >>> cardShift;
-            long end = (dstAddr + header + ((long) destPos + length - 1) * scale) >>> cardShift;
-            long count = end - start + 1;
-            while (count-- > 0) {
-                DirectStoreNode.store((start + cardStart) + count, false, Kind.Boolean);
-            }
-        }
-    }
-
-    @Snippet
-    public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) {
-
-        // loading the hubs also checks for nullness
-        Word srcHub = loadHub(src);
-        Word destHub = loadHub(dest);
-
-        int layoutHelper = checkArrayType(srcHub);
-        if (srcHub.equal(destHub) && src != dest) {
-            probability(FAST_PATH_PROBABILITY);
-
-            checkLimits(src, srcPos, dest, destPos, length);
-
-            arraycopyInnerloop(src, srcPos, dest, destPos, length, layoutHelper);
-        } else {
-            genericObjectCallCounter.inc();
-            System.arraycopy(src, srcPos, dest, destPos, length);
-        }
-    }
-
-    public static void arraycopyInnerloop(Object src, int srcPos, Object dest, int destPos, int length, int layoutHelper) {
-        int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask();
-        int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift()) & layoutHelperHeaderSizeMask();
-
-        Word memory = (Word) Word.fromObject(src);
-
-        Word srcOffset = (Word) Word.fromObject(src).add(headerSize).add(srcPos << log2ElementSize);
-        Word destOffset = (Word) Word.fromObject(dest).add(headerSize).add(destPos << log2ElementSize);
-        Word destStart = destOffset;
-        long sizeInBytes = ((long) length) << log2ElementSize;
-        Word destEnd = destOffset.add(Word.unsigned(length).shiftLeft(log2ElementSize));
-
-        int nonVectorBytes = (int) (sizeInBytes % VECTOR_SIZE);
-        Word destNonVectorEnd = destStart.add(nonVectorBytes);
-
-        while (destOffset.belowThan(destNonVectorEnd)) {
-            destOffset.writeByte(0, srcOffset.readByte(0, UNKNOWN_LOCATION), ANY_LOCATION);
-            destOffset = destOffset.add(1);
-            srcOffset = srcOffset.add(1);
-        }
-        while (destOffset.belowThan(destEnd)) {
-            destOffset.writeWord(0, srcOffset.readWord(0, UNKNOWN_LOCATION), ANY_LOCATION);
-            destOffset = destOffset.add(wordSize());
-            srcOffset = srcOffset.add(wordSize());
-        }
-
-        if ((layoutHelper & layoutHelperElementTypePrimitiveInPlace()) != 0) {
-            genericPrimitiveCallCounter.inc();
-
-        } else {
-            probability(LIKELY_PROBABILITY);
-            genericObjectExactCallCounter.inc();
-
-            if (length > 0) {
-                int cardShift = cardTableShift();
-                long cardStart = cardTableStart();
-                Word destCardOffset = destStart.unsignedShiftRight(cardShift).add(Word.unsigned(cardStart));
-                Word destCardEnd = destEnd.subtract(1).unsignedShiftRight(cardShift).add(Word.unsigned(cardStart));
-                while (destCardOffset.belowOrEqual(destCardEnd)) {
-                    DirectStoreNode.store(destCardOffset.rawValue(), false, Kind.Boolean);
-                    destCardOffset = destCardOffset.add(1);
-                }
-            }
-        }
-    }
-
-    private static final SnippetCounter.Group checkCounters = GraalOptions.SnippetCounters ? new SnippetCounter.Group("System.arraycopy checkInputs") : null;
-    private static final SnippetCounter checkSuccessCounter = new SnippetCounter(checkCounters, "checkSuccess", "checkSuccess");
-    private static final SnippetCounter checkNPECounter = new SnippetCounter(checkCounters, "checkNPE", "checkNPE");
-    private static final SnippetCounter checkAIOOBECounter = new SnippetCounter(checkCounters, "checkAIOOBE", "checkAIOOBE");
-
-    private static final SnippetCounter.Group counters = GraalOptions.SnippetCounters ? new SnippetCounter.Group("System.arraycopy") : null;
-    private static final SnippetCounter byteCounter = new SnippetCounter(counters, "byte[]", "arraycopy for byte[] arrays");
-    private static final SnippetCounter charCounter = new SnippetCounter(counters, "char[]", "arraycopy for char[] arrays");
-    private static final SnippetCounter shortCounter = new SnippetCounter(counters, "short[]", "arraycopy for short[] arrays");
-    private static final SnippetCounter intCounter = new SnippetCounter(counters, "int[]", "arraycopy for int[] arrays");
-    private static final SnippetCounter booleanCounter = new SnippetCounter(counters, "boolean[]", "arraycopy for boolean[] arrays");
-    private static final SnippetCounter longCounter = new SnippetCounter(counters, "long[]", "arraycopy for long[] arrays");
-    private static final SnippetCounter objectCounter = new SnippetCounter(counters, "Object[]", "arraycopy for Object[] arrays");
-    private static final SnippetCounter floatCounter = new SnippetCounter(counters, "float[]", "arraycopy for float[] arrays");
-    private static final SnippetCounter doubleCounter = new SnippetCounter(counters, "double[]", "arraycopy for double[] arrays");
-    private static final SnippetCounter genericPrimitiveCallCounter = new SnippetCounter(counters, "genericPrimitive", "generic arraycopy snippet for primitive arrays");
-    private static final SnippetCounter genericObjectExactCallCounter = new SnippetCounter(counters, "genericObjectExact", "generic arraycopy snippet for special object arrays");
-    private static final SnippetCounter genericObjectCallCounter = new SnippetCounter(counters, "genericObject", "call to the generic, native arraycopy method");
-
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CheckCastSnippets.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,239 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.snippets;
-
-import static com.oracle.graal.api.code.DeoptimizationAction.*;
-import static com.oracle.graal.api.meta.DeoptimizationReason.*;
-import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
-import static com.oracle.graal.hotspot.snippets.TypeCheckSnippetUtils.*;
-import static com.oracle.graal.nodes.extended.UnsafeCastNode.*;
-import static com.oracle.graal.snippets.SnippetTemplate.*;
-import static com.oracle.graal.snippets.SnippetTemplate.Arguments.*;
-import static com.oracle.graal.snippets.nodes.BranchProbabilityNode.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.debug.*;
-import com.oracle.graal.graph.Node.NodeIntrinsic;
-import com.oracle.graal.hotspot.meta.*;
-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.phases.*;
-import com.oracle.graal.snippets.*;
-import com.oracle.graal.snippets.Snippet.ConstantParameter;
-import com.oracle.graal.snippets.Snippet.Parameter;
-import com.oracle.graal.snippets.Snippet.Varargs;
-import com.oracle.graal.snippets.Snippet.VarargsParameter;
-import com.oracle.graal.snippets.SnippetTemplate.AbstractTemplates;
-import com.oracle.graal.snippets.SnippetTemplate.Arguments;
-import com.oracle.graal.snippets.SnippetTemplate.Key;
-import com.oracle.graal.snippets.nodes.*;
-import com.oracle.graal.word.*;
-
-/**
- * Snippets used for implementing the type test of a checkcast instruction.
- * 
- * The type tests implemented are described in the paper <a
- * href="http://dl.acm.org/citation.cfm?id=583821"> Fast subtype checking in the HotSpot JVM</a> by
- * Cliff Click and John Rose.
- */
-public class CheckCastSnippets implements SnippetsInterface {
-
-    @NodeIntrinsic(BreakpointNode.class)
-    static native void bkpt(Object object, Word hub, Word objectHub);
-
-    // @formatter:off
-
-    /**
-     * Type test used when the type being tested against is a final type.
-     */
-    @Snippet
-    public static Object checkcastExact(
-                    @Parameter("object") Object object,
-                    @Parameter("exactHub") Word exactHub,
-                    @ConstantParameter("checkNull") boolean checkNull) {
-        if (checkNull && object == null) {
-            probability(NOT_FREQUENT_PROBABILITY);
-            isNull.inc();
-        } else {
-            Word objectHub = loadHub(object);
-            if (objectHub.notEqual(exactHub)) {
-                probability(DEOPT_PATH_PROBABILITY);
-                exactMiss.inc();
-                //bkpt(object, exactHub, objectHub);
-                DeoptimizeNode.deopt(InvalidateReprofile, ClassCastException);
-            }
-            exactHit.inc();
-        }
-        return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic());
-    }
-
-    /**
-     * Type test used when the type being tested against is a restricted primary type.
-     *
-     * This test ignores use of hints altogether as the display-based type check only
-     * involves one extra load where the second load should hit the same cache line as the
-     * first.
-     */
-    @Snippet
-    public static Object checkcastPrimary(
-                    @Parameter("hub") Word hub,
-                    @Parameter("object") Object object,
-                    @ConstantParameter("checkNull") boolean checkNull,
-                    @ConstantParameter("superCheckOffset") int superCheckOffset) {
-        if (checkNull && object == null) {
-            probability(NOT_FREQUENT_PROBABILITY);
-            isNull.inc();
-        } else {
-            Word objectHub = loadHub(object);
-            if (objectHub.readWord(superCheckOffset, FINAL_LOCATION).notEqual(hub)) {
-                probability(DEOPT_PATH_PROBABILITY);
-                displayMiss.inc();
-                DeoptimizeNode.deopt(InvalidateReprofile, ClassCastException);
-            }
-            displayHit.inc();
-        }
-        return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic());
-    }
-
-    /**
-     * Type test used when the type being tested against is a restricted secondary type.
-     */
-    @Snippet
-    public static Object checkcastSecondary(
-                    @Parameter("hub") Word hub,
-                    @Parameter("object") Object object,
-                    @VarargsParameter("hints") Word[] hints,
-                    @ConstantParameter("checkNull") boolean checkNull) {
-        if (checkNull && object == null) {
-            probability(NOT_FREQUENT_PROBABILITY);
-            isNull.inc();
-        } else {
-            Word objectHub = loadHub(object);
-            // if we get an exact match: succeed immediately
-            ExplodeLoopNode.explodeLoop();
-            for (int i = 0; i < hints.length; i++) {
-                Word hintHub = hints[i];
-                if (hintHub.equal(objectHub)) {
-                    hintsHit.inc();
-                    return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic());
-                }
-            }
-            if (!checkSecondarySubType(hub, objectHub)) {
-                DeoptimizeNode.deopt(InvalidateReprofile, ClassCastException);
-            }
-        }
-        return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic());
-    }
-
-    /**
-     * Type test used when the type being tested against is not known at compile time (e.g. the type test
-     * in an object array store check).
-     */
-    @Snippet
-    public static Object checkcastDynamic(
-                    @Parameter("hub") Word hub,
-                    @Parameter("object") Object object,
-                    @ConstantParameter("checkNull") boolean checkNull) {
-        if (checkNull && object == null) {
-            probability(NOT_FREQUENT_PROBABILITY);
-            isNull.inc();
-        } else {
-            Word objectHub = loadHub(object);
-            if (!checkUnknownSubType(hub, objectHub)) {
-                DeoptimizeNode.deopt(InvalidateReprofile, ClassCastException);
-            }
-        }
-        return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic());
-    }
-
-    // @formatter:on
-
-    public static class Templates extends AbstractTemplates<CheckCastSnippets> {
-
-        private final ResolvedJavaMethod exact;
-        private final ResolvedJavaMethod primary;
-        private final ResolvedJavaMethod secondary;
-        private final ResolvedJavaMethod dynamic;
-
-        public Templates(CodeCacheProvider runtime, Assumptions assumptions, TargetDescription target) {
-            super(runtime, assumptions, target, CheckCastSnippets.class);
-            exact = snippet("checkcastExact", Object.class, Word.class, boolean.class);
-            primary = snippet("checkcastPrimary", Word.class, Object.class, boolean.class, int.class);
-            secondary = snippet("checkcastSecondary", Word.class, Object.class, Word[].class, boolean.class);
-            dynamic = snippet("checkcastDynamic", Word.class, Object.class, boolean.class);
-        }
-
-        /**
-         * Lowers a checkcast node.
-         */
-        public void lower(CheckCastNode checkcast, LoweringTool tool) {
-            StructuredGraph graph = (StructuredGraph) checkcast.graph();
-            ValueNode object = checkcast.object();
-            final HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) checkcast.type();
-            TypeCheckHints hintInfo = new TypeCheckHints(checkcast.type(), checkcast.profile(), tool.assumptions(), GraalOptions.CheckcastMinHintHitProbability, GraalOptions.CheckcastMaxHints);
-            ValueNode hub = ConstantNode.forConstant(type.klass(), runtime, checkcast.graph());
-            boolean checkNull = !object.stamp().nonNull();
-            Arguments arguments;
-            Key key;
-
-            assert type != null;
-            if (hintInfo.exact) {
-                ConstantNode[] hints = createHints(hintInfo, runtime, graph);
-                assert hints.length == 1;
-                key = new Key(exact).add("checkNull", checkNull);
-                arguments = arguments("object", object).add("exactHub", hints[0]);
-            } else if (type.isPrimaryType()) {
-                key = new Key(primary).add("checkNull", checkNull).add("superCheckOffset", type.superCheckOffset());
-                arguments = arguments("hub", hub).add("object", object);
-            } else {
-                ConstantNode[] hints = createHints(hintInfo, runtime, graph);
-                key = new Key(secondary).add("hints", Varargs.vargargs(new Word[hints.length], StampFactory.forKind(wordKind()))).add("checkNull", checkNull);
-                arguments = arguments("hub", hub).add("object", object).add("hints", hints);
-            }
-
-            SnippetTemplate template = cache.get(key, assumptions);
-            Debug.log("Lowering checkcast in %s: node=%s, template=%s, arguments=%s", graph, checkcast, template, arguments);
-            template.instantiate(runtime, checkcast, DEFAULT_REPLACER, arguments);
-        }
-
-        /**
-         * Lowers a dynamic checkcast node.
-         */
-        public void lower(CheckCastDynamicNode checkcast) {
-            StructuredGraph graph = (StructuredGraph) checkcast.graph();
-            ValueNode hub = checkcast.type();
-            ValueNode object = checkcast.object();
-            boolean checkNull = !object.stamp().nonNull();
-
-            Key key = new Key(dynamic).add("checkNull", checkNull);
-            Arguments arguments = arguments("hub", hub).add("object", object);
-
-            SnippetTemplate template = cache.get(key, assumptions);
-            Debug.log("Lowering dynamic checkcast in %s: node=%s, template=%s, arguments=%s", graph, checkcast, template, arguments);
-            template.instantiate(runtime, checkcast, DEFAULT_REPLACER, arguments);
-        }
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CipherBlockChainingSubstitutions.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.snippets;
-
-import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
-import sun.misc.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.gen.*;
-import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.hotspot.nodes.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.snippets.*;
-import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution;
-import com.oracle.graal.snippets.Snippet.Fold;
-import com.oracle.graal.word.*;
-
-/**
- * Substitutions for {@code com.sun.crypto.provider.CipherBlockChaining} methods.
- */
-@ClassSubstitution(className = "com.sun.crypto.provider.CipherBlockChaining")
-public class CipherBlockChainingSubstitutions {
-
-    private static final long embeddedCipherOffset;
-    private static final long rOffset;
-    static {
-        try {
-            // Need to use launcher class path as com.sun.crypto.provider.AESCrypt
-            // is normally not on the boot class path
-            ClassLoader cl = Launcher.getLauncher().getClassLoader();
-            embeddedCipherOffset = UnsafeAccess.unsafe.objectFieldOffset(Class.forName("com.sun.crypto.provider.FeedbackCipher", true, cl).getDeclaredField("embeddedCipher"));
-            rOffset = UnsafeAccess.unsafe.objectFieldOffset(Class.forName("com.sun.crypto.provider.CipherBlockChaining", true, cl).getDeclaredField("r"));
-        } catch (Exception ex) {
-            throw new GraalInternalError(ex);
-        }
-    }
-
-    @Fold
-    private static Class getAESCryptClass() {
-        return AESCryptSubstitutions.AESCryptClass;
-    }
-
-    @MethodSubstitution(isStatic = false)
-    static void encrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) {
-        Object embeddedCipher = Word.fromObject(rcvr).readObject(Word.unsigned(embeddedCipherOffset), UNKNOWN_LOCATION);
-        if (getAESCryptClass().isInstance(embeddedCipher)) {
-            crypt(rcvr, in, inOffset, inLength, out, outOffset, embeddedCipher, true);
-        } else {
-            encrypt(rcvr, in, inOffset, inLength, out, outOffset);
-        }
-    }
-
-    private static void crypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset, Object embeddedCipher, boolean encrypt) {
-        Word kAddr = Word.fromObject(embeddedCipher).readWord(Word.unsigned(AESCryptSubstitutions.kOffset), UNKNOWN_LOCATION).add(arrayBaseOffset(Kind.Byte));
-        Word rAddr = Word.unsigned(GetObjectAddressNode.get(rcvr)).readWord(Word.unsigned(rOffset), UNKNOWN_LOCATION).add(arrayBaseOffset(Kind.Byte));
-        Word inAddr = Word.unsigned(GetObjectAddressNode.get(in) + arrayBaseOffset(Kind.Byte) + inOffset);
-        Word outAddr = Word.unsigned(GetObjectAddressNode.get(out) + arrayBaseOffset(Kind.Byte) + outOffset);
-        if (encrypt) {
-            EncryptAESCryptStubCall.call(inAddr, outAddr, kAddr, rAddr, inLength);
-        } else {
-            DecryptAESCryptStubCall.call(inAddr, outAddr, kAddr, rAddr, inLength);
-        }
-
-    }
-
-    @MethodSubstitution(isStatic = false)
-    static void decrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) {
-        Object embeddedCipher = Word.fromObject(rcvr).readObject(Word.unsigned(embeddedCipherOffset), UNKNOWN_LOCATION);
-        if (in != out && getAESCryptClass().isInstance(embeddedCipher)) {
-            crypt(rcvr, in, inOffset, inLength, out, outOffset, embeddedCipher, false);
-        } else {
-            decrypt(rcvr, in, inOffset, inLength, out, outOffset);
-        }
-    }
-
-    abstract static class AESCryptStubCall extends FixedWithNextNode implements LIRGenLowerable {
-
-        @Input private final ValueNode in;
-        @Input private final ValueNode out;
-        @Input private final ValueNode key;
-        @Input private final ValueNode r;
-        @Input private final ValueNode inLength;
-
-        private final Descriptor descriptor;
-
-        public AESCryptStubCall(ValueNode in, ValueNode out, ValueNode key, ValueNode r, ValueNode inLength, Descriptor descriptor) {
-            super(StampFactory.forVoid());
-            this.in = in;
-            this.out = out;
-            this.key = key;
-            this.r = r;
-            this.inLength = inLength;
-            this.descriptor = descriptor;
-        }
-
-        @Override
-        public void generate(LIRGenerator gen) {
-            RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(descriptor);
-            gen.emitCall(stub, stub.getCallingConvention(), false, gen.operand(in), gen.operand(out), gen.operand(key), gen.operand(r), gen.operand(inLength));
-        }
-    }
-
-    public static class EncryptAESCryptStubCall extends AESCryptStubCall {
-
-        public static final Descriptor ENCRYPT = new Descriptor("encrypt", false, void.class, Word.class, Word.class, Word.class, Word.class, int.class);
-
-        public EncryptAESCryptStubCall(ValueNode in, ValueNode out, ValueNode key, ValueNode r, ValueNode inLength) {
-            super(in, out, key, r, inLength, ENCRYPT);
-        }
-
-        @NodeIntrinsic
-        public static native void call(Word in, Word out, Word key, Word r, int inLength);
-    }
-
-    public static class DecryptAESCryptStubCall extends AESCryptStubCall {
-
-        public static final Descriptor DECRYPT = new Descriptor("decrypt", false, void.class, Word.class, Word.class, Word.class, Word.class, int.class);
-
-        public DecryptAESCryptStubCall(ValueNode in, ValueNode out, ValueNode key, ValueNode r, ValueNode inLength) {
-            super(in, out, key, r, inLength, DECRYPT);
-        }
-
-        @NodeIntrinsic
-        public static native void call(Word in, Word out, Word key, Word r, int inLength);
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ClassSubstitutions.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.snippets;
-
-import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
-import static com.oracle.graal.nodes.extended.UnsafeCastNode.*;
-
-import java.lang.reflect.*;
-
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.snippets.*;
-import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution;
-import com.oracle.graal.word.*;
-
-/**
- * Substitutions for {@link java.lang.Class} methods.
- */
-@ClassSubstitution(java.lang.Class.class)
-public class ClassSubstitutions {
-
-    @MethodSubstitution(isStatic = false)
-    public static int getModifiers(final Class<?> thisObj) {
-        Word klass = loadWordFromObject(thisObj, klassOffset());
-        if (klass.equal(0)) {
-            // Class for primitive type
-            return Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC;
-        } else {
-            return klass.readInt(klassModifierFlagsOffset(), FINAL_LOCATION);
-        }
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static boolean isInterface(final Class<?> thisObj) {
-        Word klass = loadWordFromObject(thisObj, klassOffset());
-        if (klass.equal(0)) {
-            return false;
-        } else {
-            int accessFlags = klass.readInt(klassAccessFlagsOffset(), FINAL_LOCATION);
-            return (accessFlags & Modifier.INTERFACE) != 0;
-        }
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static boolean isArray(final Class<?> thisObj) {
-        Word klass = loadWordFromObject(thisObj, klassOffset());
-        if (klass.equal(0)) {
-            return false;
-        } else {
-            return (readLayoutHelper(klass) & arrayKlassLayoutHelperIdentifier()) != 0;
-        }
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static boolean isPrimitive(final Class<?> thisObj) {
-        Word klass = loadWordFromObject(thisObj, klassOffset());
-        return klass.equal(0);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static Class<?> getSuperclass(final Class<?> thisObj) {
-        Word klass = loadWordFromObject(thisObj, klassOffset());
-        if (klass.notEqual(0)) {
-            int accessFlags = klass.readInt(klassAccessFlagsOffset(), FINAL_LOCATION);
-            if ((accessFlags & Modifier.INTERFACE) == 0) {
-                if ((readLayoutHelper(klass) & arrayKlassLayoutHelperIdentifier()) != 0) {
-                    return Object.class;
-                } else {
-                    Word superKlass = klass.readWord(klassSuperKlassOffset(), FINAL_LOCATION);
-                    if (superKlass.equal(0)) {
-                        return null;
-                    } else {
-                        return unsafeCast(superKlass.readObject(classMirrorOffset(), FINAL_LOCATION), Class.class, true, true);
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static Class<?> getComponentType(final Class<?> thisObj) {
-        Word klass = loadWordFromObject(thisObj, klassOffset());
-        if (klass.notEqual(0)) {
-            if ((readLayoutHelper(klass) & arrayKlassLayoutHelperIdentifier()) != 0) {
-                return unsafeCast(klass.readObject(arrayKlassComponentMirrorOffset(), FINAL_LOCATION), Class.class, true, true);
-            }
-        }
-        return null;
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static boolean isInstance(final Class<?> thisObj, Object obj) {
-        return !isPrimitive(thisObj) && ConditionalNode.materializeIsInstance(thisObj, obj);
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,550 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.snippets;
-
-import static com.oracle.graal.snippets.nodes.BranchProbabilityNode.*;
-import sun.misc.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.Node.ConstantNodeParameter;
-import com.oracle.graal.graph.Node.NodeIntrinsic;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.hotspot.nodes.*;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.snippets.Snippet.Fold;
-import com.oracle.graal.snippets.nodes.*;
-import com.oracle.graal.word.*;
-
-//JaCoCo Exclude
-
-/**
- * A collection of methods used in HotSpot snippets and substitutions.
- */
-public class HotSpotSnippetUtils {
-
-    public static final Object ANY_LOCATION = LocationNode.ANY_LOCATION;
-    public static final Object UNKNOWN_LOCATION = LocationNode.UNKNOWN_LOCATION;
-    public static final Object FINAL_LOCATION = LocationNode.FINAL_LOCATION;
-
-    public static HotSpotVMConfig config() {
-        return HotSpotGraalRuntime.getInstance().getConfig();
-    }
-
-    @Fold
-    public static boolean verifyOops() {
-        return config().verifyOops;
-    }
-
-    public static final Object TLAB_TOP_LOCATION = LocationNode.createLocation("TlabTop");
-
-    @Fold
-    public static int threadTlabTopOffset() {
-        return config().threadTlabTopOffset;
-    }
-
-    public static final Object TLAB_END_LOCATION = LocationNode.createLocation("TlabEnd");
-
-    @Fold
-    private static int threadTlabEndOffset() {
-        return config().threadTlabEndOffset;
-    }
-
-    public static final Object TLAB_START_LOCATION = LocationNode.createLocation("TlabStart");
-
-    @Fold
-    private static int threadTlabStartOffset() {
-        return config().threadTlabStartOffset;
-    }
-
-    public static Word readTlabTop(Word thread) {
-        return thread.readWord(threadTlabTopOffset(), TLAB_TOP_LOCATION);
-    }
-
-    public static Word readTlabEnd(Word thread) {
-        return thread.readWord(threadTlabEndOffset(), TLAB_END_LOCATION);
-    }
-
-    public static Word readTlabStart(Word thread) {
-        return thread.readWord(threadTlabStartOffset(), TLAB_START_LOCATION);
-    }
-
-    public static void writeTlabTop(Word thread, Word top) {
-        thread.writeWord(threadTlabTopOffset(), top, TLAB_TOP_LOCATION);
-    }
-
-    public static void initializeTlab(Word thread, Word start, Word end) {
-        thread.writeWord(threadTlabStartOffset(), start, TLAB_START_LOCATION);
-        thread.writeWord(threadTlabTopOffset(), start, TLAB_TOP_LOCATION);
-        thread.writeWord(threadTlabEndOffset(), end, TLAB_END_LOCATION);
-    }
-
-    @Fold
-    public static int threadObjectOffset() {
-        return config().threadObjectOffset;
-    }
-
-    @Fold
-    public static int osThreadOffset() {
-        return config().osThreadOffset;
-    }
-
-    @Fold
-    public static int osThreadInterruptedOffset() {
-        return config().osThreadInterruptedOffset;
-    }
-
-    @Fold
-    public static Kind wordKind() {
-        return HotSpotGraalRuntime.getInstance().getTarget().wordKind;
-    }
-
-    @Fold
-    public static Register threadRegister() {
-        return HotSpotGraalRuntime.getInstance().getRuntime().threadRegister();
-    }
-
-    @Fold
-    public static Register stackPointerRegister() {
-        return HotSpotGraalRuntime.getInstance().getRuntime().stackPointerRegister();
-    }
-
-    @Fold
-    public static int wordSize() {
-        return HotSpotGraalRuntime.getInstance().getTarget().wordSize;
-    }
-
-    @Fold
-    public static int pageSize() {
-        return Unsafe.getUnsafe().pageSize();
-    }
-
-    public static final Object PROTOTYPE_MARK_WORD_LOCATION = LocationNode.createLocation("PrototypeMarkWord");
-
-    @Fold
-    public static int prototypeMarkWordOffset() {
-        return config().prototypeMarkWordOffset;
-    }
-
-    @Fold
-    public static long arrayPrototypeMarkWord() {
-        return config().arrayPrototypeMarkWord;
-    }
-
-    @Fold
-    public static int klassAccessFlagsOffset() {
-        return config().klassAccessFlagsOffset;
-    }
-
-    @Fold
-    private static int klassLayoutHelperOffset() {
-        return config().klassLayoutHelperOffset;
-    }
-
-    public static int readLayoutHelper(Word hub) {
-        return hub.readInt(klassLayoutHelperOffset(), FINAL_LOCATION);
-    }
-
-    @Fold
-    public static int arrayKlassLayoutHelperIdentifier() {
-        return config().arrayKlassLayoutHelperIdentifier;
-    }
-
-    @Fold
-    public static int arrayKlassComponentMirrorOffset() {
-        return config().arrayKlassComponentMirrorOffset;
-    }
-
-    @Fold
-    public static int klassSuperKlassOffset() {
-        return config().klassSuperKlassOffset;
-    }
-
-    public static final Object MARK_WORD_LOCATION = LocationNode.createLocation("MarkWord");
-
-    @Fold
-    public static int markOffset() {
-        return config().markOffset;
-    }
-
-    public static final Object HUB_LOCATION = LocationNode.createLocation("Hub");
-
-    @Fold
-    private static int hubOffset() {
-        return config().hubOffset;
-    }
-
-    public static void initializeObjectHeader(Word memory, Word markWord, Word hub) {
-        memory.writeWord(markOffset(), markWord, MARK_WORD_LOCATION);
-        memory.writeWord(hubOffset(), hub, HUB_LOCATION);
-    }
-
-    @Fold
-    public static int unlockedMask() {
-        return config().unlockedMask;
-    }
-
-    /**
-     * Mask for a biasable, locked or unlocked mark word.
-     * 
-     * <pre>
-     * +----------------------------------+-+-+
-     * |                                 1|1|1|
-     * +----------------------------------+-+-+
-     * </pre>
-     * 
-     */
-    @Fold
-    public static int biasedLockMaskInPlace() {
-        return config().biasedLockMaskInPlace;
-    }
-
-    @Fold
-    public static int epochMaskInPlace() {
-        return config().epochMaskInPlace;
-    }
-
-    /**
-     * Pattern for a biasable, unlocked mark word.
-     * 
-     * <pre>
-     * +----------------------------------+-+-+
-     * |                                 1|0|1|
-     * +----------------------------------+-+-+
-     * </pre>
-     * 
-     */
-    @Fold
-    public static int biasedLockPattern() {
-        return config().biasedLockPattern;
-    }
-
-    @Fold
-    public static int ageMaskInPlace() {
-        return config().ageMaskInPlace;
-    }
-
-    @Fold
-    public static int metaspaceArrayLengthOffset() {
-        return config().metaspaceArrayLengthOffset;
-    }
-
-    @Fold
-    public static int metaspaceArrayBaseOffset() {
-        return config().metaspaceArrayBaseOffset;
-    }
-
-    @Fold
-    public static int arrayLengthOffset() {
-        return config().arrayLengthOffset;
-    }
-
-    @Fold
-    public static int arrayBaseOffset(Kind elementKind) {
-        return HotSpotRuntime.getArrayBaseOffset(elementKind);
-    }
-
-    @Fold
-    public static int arrayIndexScale(Kind elementKind) {
-        return HotSpotRuntime.getArrayIndexScale(elementKind);
-    }
-
-    @Fold
-    public static int cardTableShift() {
-        return config().cardtableShift;
-    }
-
-    @Fold
-    public static long cardTableStart() {
-        return config().cardtableStartAddress;
-    }
-
-    @Fold
-    public static int superCheckOffsetOffset() {
-        return config().superCheckOffsetOffset;
-    }
-
-    public static final Object SECONDARY_SUPER_CACHE_LOCATION = LocationNode.createLocation("SecondarySuperCache");
-
-    @Fold
-    public static int secondarySuperCacheOffset() {
-        return config().secondarySuperCacheOffset;
-    }
-
-    public static final Object SECONDARY_SUPERS_LOCATION = LocationNode.createLocation("SecondarySupers");
-
-    @Fold
-    public static int secondarySupersOffset() {
-        return config().secondarySupersOffset;
-    }
-
-    public static final Object DISPLACED_MARK_WORD_LOCATION = LocationNode.createLocation("DisplacedMarkWord");
-
-    @Fold
-    public static int lockDisplacedMarkOffset() {
-        return config().basicLockDisplacedHeaderOffset;
-    }
-
-    @Fold
-    public static boolean useBiasedLocking() {
-        return config().useBiasedLocking;
-    }
-
-    @Fold
-    static int uninitializedIdentityHashCodeValue() {
-        return config().uninitializedIdentityHashCodeValue;
-    }
-
-    @Fold
-    static int identityHashCodeShift() {
-        return config().identityHashCodeShift;
-    }
-
-    /**
-     * Loads the hub from a object, null checking it first.
-     */
-    public static Word loadHub(Object object) {
-        return loadHubIntrinsic(object, wordKind());
-    }
-
-    public static Object verifyOop(Object object) {
-        if (verifyOops()) {
-            VerifyOopStubCall.call(object);
-        }
-        return object;
-    }
-
-    /**
-     * Gets the value of the stack pointer register as a Word.
-     */
-    public static Word stackPointer() {
-        return HotSpotSnippetUtils.registerAsWord(stackPointerRegister(), true, false);
-    }
-
-    /**
-     * Gets the value of the thread register as a Word.
-     */
-    public static Word thread() {
-        return HotSpotSnippetUtils.registerAsWord(threadRegister(), true, false);
-    }
-
-    public static Word loadWordFromObject(Object object, int offset) {
-        return loadWordFromObjectIntrinsic(object, 0, offset, wordKind());
-    }
-
-    @NodeIntrinsic(value = ReadRegisterNode.class, setStampFromReturnType = true)
-    public static native Word registerAsWord(@ConstantNodeParameter Register register, @ConstantNodeParameter boolean directUse, @ConstantNodeParameter boolean incoming);
-
-    @NodeIntrinsic(value = UnsafeLoadNode.class, setStampFromReturnType = true)
-    private static native Word loadWordFromObjectIntrinsic(Object object, @ConstantNodeParameter int displacement, long offset, @ConstantNodeParameter Kind wordKind);
-
-    @NodeIntrinsic(value = LoadHubNode.class, setStampFromReturnType = true)
-    static native Word loadHubIntrinsic(Object object, @ConstantNodeParameter Kind word);
-
-    @Fold
-    public static int log2WordSize() {
-        return CodeUtil.log2(wordSize());
-    }
-
-    public static final Object CLASS_STATE_LOCATION = LocationNode.createLocation("ClassState");
-
-    @Fold
-    public static int klassStateOffset() {
-        return config().klassStateOffset;
-    }
-
-    @Fold
-    public static int klassStateFullyInitialized() {
-        return config().klassStateFullyInitialized;
-    }
-
-    @Fold
-    public static int klassModifierFlagsOffset() {
-        return config().klassModifierFlagsOffset;
-    }
-
-    @Fold
-    public static int klassOffset() {
-        return config().klassOffset;
-    }
-
-    @Fold
-    public static int classMirrorOffset() {
-        return config().classMirrorOffset;
-    }
-
-    @Fold
-    public static int klassInstanceSizeOffset() {
-        return config().klassInstanceSizeOffset;
-    }
-
-    public static final Object HEAP_TOP_LOCATION = LocationNode.createLocation("HeapTop");
-
-    @Fold
-    public static long heapTopAddress() {
-        return config().heapTopAddress;
-    }
-
-    public static final Object HEAP_END_LOCATION = LocationNode.createLocation("HeapEnd");
-
-    @Fold
-    public static long heapEndAddress() {
-        return config().heapEndAddress;
-    }
-
-    @Fold
-    public static long tlabIntArrayMarkWord() {
-        return config().tlabIntArrayMarkWord;
-    }
-
-    @Fold
-    public static boolean inlineContiguousAllocationSupported() {
-        return config().inlineContiguousAllocationSupported;
-    }
-
-    @Fold
-    public static int tlabAlignmentReserveInHeapWords() {
-        return config().tlabAlignmentReserve;
-    }
-
-    public static final Object TLAB_SIZE_LOCATION = LocationNode.createLocation("TlabSize");
-
-    @Fold
-    public static int threadTlabSizeOffset() {
-        return config().threadTlabSizeOffset;
-    }
-
-    public static final Object TLAB_THREAD_ALLOCATED_BYTES_LOCATION = LocationNode.createLocation("TlabThreadAllocatedBytes");
-
-    @Fold
-    public static int threadAllocatedBytesOffset() {
-        return config().threadAllocatedBytesOffset;
-    }
-
-    public static final Object TLAB_REFILL_WASTE_LIMIT_LOCATION = LocationNode.createLocation("RefillWasteLimit");
-
-    @Fold
-    public static int tlabRefillWasteLimitOffset() {
-        return config().tlabRefillWasteLimitOffset;
-    }
-
-    public static final Object TLAB_NOF_REFILLS_LOCATION = LocationNode.createLocation("TlabNOfRefills");
-
-    @Fold
-    public static int tlabNumberOfRefillsOffset() {
-        return config().tlabNumberOfRefillsOffset;
-    }
-
-    public static final Object TLAB_FAST_REFILL_WASTE_LOCATION = LocationNode.createLocation("TlabFastRefillWaste");
-
-    @Fold
-    public static int tlabFastRefillWasteOffset() {
-        return config().tlabFastRefillWasteOffset;
-    }
-
-    public static final Object TLAB_SLOW_ALLOCATIONS_LOCATION = LocationNode.createLocation("TlabSlowAllocations");
-
-    @Fold
-    public static int tlabSlowAllocationsOffset() {
-        return config().tlabSlowAllocationsOffset;
-    }
-
-    @Fold
-    public static int tlabRefillWasteIncrement() {
-        return config().tlabRefillWasteIncrement;
-    }
-
-    @Fold
-    public static boolean tlabStats() {
-        return config().tlabStats;
-    }
-
-    @Fold
-    public static int layoutHelperOffset() {
-        return config().layoutHelperOffset;
-    }
-
-    @Fold
-    public static int layoutHelperHeaderSizeShift() {
-        return config().layoutHelperHeaderSizeShift;
-    }
-
-    @Fold
-    public static int layoutHelperHeaderSizeMask() {
-        return config().layoutHelperHeaderSizeMask;
-    }
-
-    @Fold
-    public static int layoutHelperLog2ElementSizeShift() {
-        return config().layoutHelperLog2ElementSizeShift;
-    }
-
-    @Fold
-    public static int layoutHelperLog2ElementSizeMask() {
-        return config().layoutHelperLog2ElementSizeMask;
-    }
-
-    @Fold
-    public static int layoutHelperElementTypeShift() {
-        return config().layoutHelperElementTypeShift;
-    }
-
-    @Fold
-    public static int layoutHelperElementTypeMask() {
-        return config().layoutHelperElementTypeMask;
-    }
-
-    @Fold
-    public static int layoutHelperElementTypePrimitiveInPlace() {
-        return config().layoutHelperElementTypePrimitiveInPlace;
-    }
-
-    static {
-        assert arrayIndexScale(Kind.Byte) == 1;
-        assert arrayIndexScale(Kind.Boolean) == 1;
-        assert arrayIndexScale(Kind.Char) == 2;
-        assert arrayIndexScale(Kind.Short) == 2;
-        assert arrayIndexScale(Kind.Int) == 4;
-        assert arrayIndexScale(Kind.Long) == 8;
-        assert arrayIndexScale(Kind.Float) == 4;
-        assert arrayIndexScale(Kind.Double) == 8;
-    }
-
-    static int computeHashCode(Object x) {
-        Word mark = loadWordFromObject(x, markOffset());
-
-        // this code is independent from biased locking (although it does not look that way)
-        final Word biasedLock = mark.and(biasedLockMaskInPlace());
-        if (biasedLock.equal(Word.unsigned(unlockedMask()))) {
-            probability(FAST_PATH_PROBABILITY);
-            int hash = (int) mark.unsignedShiftRight(identityHashCodeShift()).rawValue();
-            if (hash != uninitializedIdentityHashCodeValue()) {
-                probability(FAST_PATH_PROBABILITY);
-                return hash;
-            }
-        }
-
-        return IdentityHashCodeStubCall.call(x);
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/InstanceOfSnippets.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,226 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.snippets;
-
-import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
-import static com.oracle.graal.hotspot.snippets.TypeCheckSnippetUtils.*;
-import static com.oracle.graal.snippets.SnippetTemplate.Arguments.*;
-import static com.oracle.graal.snippets.nodes.BranchProbabilityNode.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.hotspot.meta.*;
-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.phases.*;
-import com.oracle.graal.snippets.*;
-import com.oracle.graal.snippets.Snippet.ConstantParameter;
-import com.oracle.graal.snippets.Snippet.Parameter;
-import com.oracle.graal.snippets.Snippet.Varargs;
-import com.oracle.graal.snippets.Snippet.VarargsParameter;
-import com.oracle.graal.snippets.SnippetTemplate.Arguments;
-import com.oracle.graal.snippets.SnippetTemplate.Key;
-import com.oracle.graal.snippets.nodes.*;
-import com.oracle.graal.word.*;
-
-/**
- * Snippets used for implementing the type test of an instanceof instruction. Since instanceof is a
- * floating node, it is lowered separately for each of its usages.
- * 
- * The type tests implemented are described in the paper <a
- * href="http://dl.acm.org/citation.cfm?id=583821"> Fast subtype checking in the HotSpot JVM</a> by
- * Cliff Click and John Rose.
- */
-public class InstanceOfSnippets implements SnippetsInterface {
-
-    // @formatter:off
-
-    /**
-     * A test against a final type.
-     */
-    @Snippet
-    public static Object instanceofExact(
-                    @Parameter("object") Object object,
-                    @Parameter("exactHub") Word exactHub,
-                    @Parameter("trueValue") Object trueValue,
-                    @Parameter("falseValue") Object falseValue,
-                    @ConstantParameter("checkNull") boolean checkNull) {
-        if (checkNull && object == null) {
-            probability(NOT_FREQUENT_PROBABILITY);
-            isNull.inc();
-            return falseValue;
-        }
-        Word objectHub = loadHub(object);
-        if (objectHub.notEqual(exactHub)) {
-            probability(LIKELY_PROBABILITY);
-            exactMiss.inc();
-            return falseValue;
-        }
-        exactHit.inc();
-        return trueValue;
-    }
-
-    /**
-     * A test against a primary type.
-     */
-    @Snippet
-    public static Object instanceofPrimary(
-                    @Parameter("hub") Word hub,
-                    @Parameter("object") Object object,
-                    @Parameter("trueValue") Object trueValue,
-                    @Parameter("falseValue") Object falseValue,
-                    @ConstantParameter("checkNull") boolean checkNull,
-                    @ConstantParameter("superCheckOffset") int superCheckOffset) {
-        if (checkNull && object == null) {
-            probability(NOT_FREQUENT_PROBABILITY);
-            isNull.inc();
-            return falseValue;
-        }
-        Word objectHub = loadHub(object);
-        if (objectHub.readWord(superCheckOffset, FINAL_LOCATION).notEqual(hub)) {
-            probability(NOT_LIKELY_PROBABILITY);
-            displayMiss.inc();
-            return falseValue;
-        }
-        displayHit.inc();
-        return trueValue;
-    }
-
-    /**
-     * A test against a restricted secondary type type.
-     */
-    @Snippet
-    public static Object instanceofSecondary(
-                    @Parameter("hub") Word hub,
-                    @Parameter("object") Object object,
-                    @Parameter("trueValue") Object trueValue,
-                    @Parameter("falseValue") Object falseValue,
-                    @VarargsParameter("hints") Word[] hints,
-                    @ConstantParameter("checkNull") boolean checkNull) {
-        if (checkNull && object == null) {
-            probability(NOT_FREQUENT_PROBABILITY);
-            isNull.inc();
-            return falseValue;
-        }
-        Word objectHub = loadHub(object);
-        // if we get an exact match: succeed immediately
-        ExplodeLoopNode.explodeLoop();
-        for (int i = 0; i < hints.length; i++) {
-            Word hintHub = hints[i];
-            if (hintHub.equal(objectHub)) {
-                probability(NOT_FREQUENT_PROBABILITY);
-                hintsHit.inc();
-                return trueValue;
-            }
-        }
-        if (!checkSecondarySubType(hub, objectHub)) {
-            return falseValue;
-        }
-        return trueValue;
-    }
-
-    /**
-     * Type test used when the type being tested against is not known at compile time.
-     */
-    @Snippet
-    public static Object instanceofDynamic(
-                    @Parameter("mirror") Class mirror,
-                    @Parameter("object") Object object,
-                    @Parameter("trueValue") Object trueValue,
-                    @Parameter("falseValue") Object falseValue,
-                    @ConstantParameter("checkNull") boolean checkNull) {
-        if (checkNull && object == null) {
-            probability(NOT_FREQUENT_PROBABILITY);
-            isNull.inc();
-            return falseValue;
-        }
-
-        Word hub = loadWordFromObject(mirror, klassOffset());
-        Word objectHub = loadHub(object);
-        if (!checkUnknownSubType(hub, objectHub)) {
-            return falseValue;
-        }
-        return trueValue;
-    }
-
-    // @formatter:on
-
-    public static class Templates extends InstanceOfSnippetsTemplates<InstanceOfSnippets> {
-
-        private final ResolvedJavaMethod instanceofExact;
-        private final ResolvedJavaMethod instanceofPrimary;
-        private final ResolvedJavaMethod instanceofSecondary;
-        private final ResolvedJavaMethod instanceofDynamic;
-
-        public Templates(CodeCacheProvider runtime, Assumptions assumptions, TargetDescription target) {
-            super(runtime, assumptions, target, InstanceOfSnippets.class);
-            instanceofExact = snippet("instanceofExact", Object.class, Word.class, Object.class, Object.class, boolean.class);
-            instanceofPrimary = snippet("instanceofPrimary", Word.class, Object.class, Object.class, Object.class, boolean.class, int.class);
-            instanceofSecondary = snippet("instanceofSecondary", Word.class, Object.class, Object.class, Object.class, Word[].class, boolean.class);
-            instanceofDynamic = snippet("instanceofDynamic", Class.class, Object.class, Object.class, Object.class, boolean.class);
-        }
-
-        @Override
-        protected KeyAndArguments getKeyAndArguments(InstanceOfUsageReplacer replacer, LoweringTool tool) {
-            if (replacer.instanceOf instanceof InstanceOfNode) {
-                InstanceOfNode instanceOf = (InstanceOfNode) replacer.instanceOf;
-                ValueNode trueValue = replacer.trueValue;
-                ValueNode falseValue = replacer.falseValue;
-                ValueNode object = instanceOf.object();
-                TypeCheckHints hintInfo = new TypeCheckHints(instanceOf.type(), instanceOf.profile(), tool.assumptions(), GraalOptions.InstanceOfMinHintHitProbability, GraalOptions.InstanceOfMaxHints);
-                final HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) instanceOf.type();
-                ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, instanceOf.graph());
-                boolean checkNull = !object.stamp().nonNull();
-                Arguments arguments;
-                Key key;
-                if (hintInfo.exact) {
-                    ConstantNode[] hints = createHints(hintInfo, runtime, hub.graph());
-                    assert hints.length == 1;
-                    key = new Key(instanceofExact).add("checkNull", checkNull);
-                    arguments = arguments("object", object).add("exactHub", hints[0]).add("trueValue", trueValue).add("falseValue", falseValue);
-                } else if (type.isPrimaryType()) {
-                    key = new Key(instanceofPrimary).add("checkNull", checkNull).add("superCheckOffset", type.superCheckOffset());
-                    arguments = arguments("hub", hub).add("object", object).add("trueValue", trueValue).add("falseValue", falseValue);
-                } else {
-                    ConstantNode[] hints = createHints(hintInfo, runtime, hub.graph());
-                    key = new Key(instanceofSecondary).add("hints", Varargs.vargargs(new Word[hints.length], StampFactory.forKind(wordKind()))).add("checkNull", checkNull);
-                    arguments = arguments("hub", hub).add("object", object).add("hints", hints).add("trueValue", trueValue).add("falseValue", falseValue);
-                }
-                return new KeyAndArguments(key, arguments);
-            } else {
-                assert replacer.instanceOf instanceof InstanceOfDynamicNode;
-                InstanceOfDynamicNode instanceOf = (InstanceOfDynamicNode) replacer.instanceOf;
-                ValueNode trueValue = replacer.trueValue;
-                ValueNode falseValue = replacer.falseValue;
-                ValueNode object = instanceOf.object();
-                ValueNode mirror = instanceOf.mirror();
-                boolean checkNull = !object.stamp().nonNull();
-                Key key = new Key(instanceofDynamic).add("checkNull", checkNull);
-                Arguments arguments = arguments("mirror", mirror).add("object", object).add("trueValue", trueValue).add("falseValue", falseValue);
-                return new KeyAndArguments(key, arguments);
-            }
-        }
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/MonitorSnippets.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,548 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.snippets;
-
-import static com.oracle.graal.hotspot.nodes.BeginLockScopeNode.*;
-import static com.oracle.graal.hotspot.nodes.DirectCompareAndSwapNode.*;
-import static com.oracle.graal.hotspot.nodes.EndLockScopeNode.*;
-import static com.oracle.graal.hotspot.nodes.VMErrorNode.*;
-import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
-import static com.oracle.graal.snippets.SnippetTemplate.*;
-import static com.oracle.graal.snippets.nodes.BranchProbabilityNode.*;
-
-import java.util.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.Node.NodeIntrinsic;
-import com.oracle.graal.graph.iterators.*;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.hotspot.nodes.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.phases.common.*;
-import com.oracle.graal.snippets.*;
-import com.oracle.graal.snippets.Snippet.ConstantParameter;
-import com.oracle.graal.snippets.Snippet.Parameter;
-import com.oracle.graal.snippets.SnippetTemplate.AbstractTemplates;
-import com.oracle.graal.snippets.SnippetTemplate.Arguments;
-import com.oracle.graal.snippets.SnippetTemplate.Key;
-import com.oracle.graal.word.*;
-
-/**
- * Snippets used for implementing the monitorenter and monitorexit instructions.
- * 
- * The locking algorithm used is described in the paper <a
- * href="http://dl.acm.org/citation.cfm?id=1167515.1167496"> Eliminating synchronization-related
- * atomic operations with biased locking and bulk rebiasing</a> by Kenneth Russell and David
- * Detlefs.
- */
-public class MonitorSnippets implements SnippetsInterface {
-
-    /**
-     * Monitor operations on objects whose type contains this substring will be traced.
-     */
-    private static final String TRACE_TYPE_FILTER = System.getProperty("graal.monitors.trace.typeFilter");
-
-    /**
-     * Monitor operations in methods whose fully qualified name contains this substring will be
-     * traced.
-     */
-    private static final String TRACE_METHOD_FILTER = System.getProperty("graal.monitors.trace.methodFilter");
-
-    public static final boolean CHECK_BALANCED_MONITORS = Boolean.getBoolean("graal.monitors.checkBalanced");
-
-    @Snippet
-    public static void monitorenter(@Parameter("object") Object object, @ConstantParameter("checkNull") boolean checkNull, @ConstantParameter("trace") boolean trace) {
-        verifyOop(object);
-
-        if (checkNull && object == null) {
-            DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException);
-        }
-
-        // Load the mark word - this includes a null-check on object
-        final Word mark = loadWordFromObject(object, markOffset());
-
-        final Word lock = beginLockScope(false);
-
-        trace(trace, "           object: 0x%016lx\n", Word.fromObject(object));
-        trace(trace, "             lock: 0x%016lx\n", lock);
-        trace(trace, "             mark: 0x%016lx\n", mark);
-
-        incCounter();
-
-        if (useBiasedLocking()) {
-            // See whether the lock is currently biased toward our thread and
-            // whether the epoch is still valid.
-            // Note that the runtime guarantees sufficient alignment of JavaThread
-            // pointers to allow age to be placed into low bits.
-            final Word biasableLockBits = mark.and(biasedLockMaskInPlace());
-
-            // First check to see whether biasing is enabled for this object
-            if (biasableLockBits.notEqual(Word.unsigned(biasedLockPattern()))) {
-                // Biasing not enabled -> fall through to lightweight locking
-            } else {
-                probability(FREQUENT_PROBABILITY);
-                // The bias pattern is present in the object's mark word. Need to check
-                // whether the bias owner and the epoch are both still current.
-                Word hub = loadHub(object);
-                final Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION);
-                final Word thread = thread();
-                final Word tmp = prototypeMarkWord.or(thread).xor(mark).and(~ageMaskInPlace());
-                trace(trace, "prototypeMarkWord: 0x%016lx\n", prototypeMarkWord);
-                trace(trace, "           thread: 0x%016lx\n", thread);
-                trace(trace, "              tmp: 0x%016lx\n", tmp);
-                if (tmp.equal(0)) {
-                    // Object is already biased to current thread -> done
-                    probability(FREQUENT_PROBABILITY);
-                    traceObject(trace, "+lock{bias:existing}", object);
-                    return;
-                }
-
-                // At this point we know that the mark word has the bias pattern and
-                // that we are not the bias owner in the current epoch. We need to
-                // figure out more details about the state of the mark word in order to
-                // know what operations can be legally performed on the object's
-                // mark word.
-
-                // If the low three bits in the xor result aren't clear, that means
-                // the prototype header is no longer biasable and we have to revoke
-                // the bias on this object.
-                if (tmp.and(biasedLockMaskInPlace()).equal(0)) {
-                    probability(FREQUENT_PROBABILITY);
-                    // Biasing is still enabled for object's type. See whether the
-                    // epoch of the current bias is still valid, meaning that the epoch
-                    // bits of the mark word are equal to the epoch bits of the
-                    // prototype mark word. (Note that the prototype mark word's epoch bits
-                    // only change at a safepoint.) If not, attempt to rebias the object
-                    // toward the current thread. Note that we must be absolutely sure
-                    // that the current epoch is invalid in order to do this because
-                    // otherwise the manipulations it performs on the mark word are
-                    // illegal.
-                    if (tmp.and(epochMaskInPlace()).equal(0)) {
-                        probability(FREQUENT_PROBABILITY);
-                        // The epoch of the current bias is still valid but we know nothing
-                        // about the owner; it might be set or it might be clear. Try to
-                        // acquire the bias of the object using an atomic operation. If this
-                        // fails we will go in to the runtime to revoke the object's bias.
-                        // Note that we first construct the presumed unbiased header so we
-                        // don't accidentally blow away another thread's valid bias.
-                        Word unbiasedMark = mark.and(biasedLockMaskInPlace() | ageMaskInPlace() | epochMaskInPlace());
-                        Word biasedMark = unbiasedMark.or(thread);
-                        trace(trace, "     unbiasedMark: 0x%016lx\n", unbiasedMark);
-                        trace(trace, "       biasedMark: 0x%016lx\n", biasedMark);
-                        if (compareAndSwap(object, markOffset(), unbiasedMark, biasedMark, MARK_WORD_LOCATION).equal(unbiasedMark)) {
-                            // Object is now biased to current thread -> done
-                            traceObject(trace, "+lock{bias:acquired}", object);
-                            return;
-                        }
-                        // If the biasing toward our thread failed, this means that another thread
-                        // owns the bias and we need to revoke that bias. The revocation will occur
-                        // in the interpreter runtime.
-                        probability(DEOPT_PATH_PROBABILITY);
-                        traceObject(trace, "+lock{stub:revoke}", object);
-                        MonitorEnterStubCall.call(object, lock);
-                        return;
-                    } else {
-                        // At this point we know the epoch has expired, meaning that the
-                        // current bias owner, if any, is actually invalid. Under these
-                        // circumstances _only_, are we allowed to use the current mark word
-                        // value as the comparison value when doing the CAS to acquire the
-                        // bias in the current epoch. In other words, we allow transfer of
-                        // the bias from one thread to another directly in this situation.
-                        Word biasedMark = prototypeMarkWord.or(thread);
-                        trace(trace, "       biasedMark: 0x%016lx\n", biasedMark);
-                        if (compareAndSwap(object, markOffset(), mark, biasedMark, MARK_WORD_LOCATION).equal(mark)) {
-                            // Object is now biased to current thread -> done
-                            traceObject(trace, "+lock{bias:transfer}", object);
-                            return;
-                        }
-                        // If the biasing toward our thread failed, then another thread
-                        // succeeded in biasing it toward itself and we need to revoke that
-                        // bias. The revocation will occur in the runtime in the slow case.
-                        probability(DEOPT_PATH_PROBABILITY);
-                        traceObject(trace, "+lock{stub:epoch-expired}", object);
-                        MonitorEnterStubCall.call(object, lock);
-                        return;
-                    }
-                } else {
-                    // The prototype mark word doesn't have the bias bit set any
-                    // more, indicating that objects of this data type are not supposed
-                    // to be biased any more. We are going to try to reset the mark of
-                    // this object to the prototype value and fall through to the
-                    // CAS-based locking scheme. Note that if our CAS fails, it means
-                    // that another thread raced us for the privilege of revoking the
-                    // bias of this particular object, so it's okay to continue in the
-                    // normal locking code.
-                    Word result = compareAndSwap(object, markOffset(), mark, prototypeMarkWord, MARK_WORD_LOCATION);
-
-                    // Fall through to the normal CAS-based lock, because no matter what
-                    // the result of the above CAS, some thread must have succeeded in
-                    // removing the bias bit from the object's header.
-
-                    if (ENABLE_BREAKPOINT) {
-                        bkpt(object, mark, tmp, result);
-                    }
-                }
-            }
-        }
-
-        // Create the unlocked mark word pattern
-        Word unlockedMark = mark.or(unlockedMask());
-        trace(trace, "     unlockedMark: 0x%016lx\n", unlockedMark);
-
-        // Copy this unlocked mark word into the lock slot on the stack
-        lock.writeWord(lockDisplacedMarkOffset(), unlockedMark, DISPLACED_MARK_WORD_LOCATION);
-
-        // Test if the object's mark word is unlocked, and if so, store the
-        // (address of) the lock slot into the object's mark word.
-        Word currentMark = compareAndSwap(object, markOffset(), unlockedMark, lock, MARK_WORD_LOCATION);
-        if (currentMark.notEqual(unlockedMark)) {
-            trace(trace, "      currentMark: 0x%016lx\n", currentMark);
-            // The mark word in the object header was not the same.
-            // Either the object is locked by another thread or is already locked
-            // by the current thread. The latter is true if the mark word
-            // is a stack pointer into the current thread's stack, i.e.:
-            //
-            // 1) (currentMark & aligned_mask) == 0
-            // 2) rsp <= currentMark
-            // 3) currentMark <= rsp + page_size
-            //
-            // These 3 tests can be done by evaluating the following expression:
-            //
-            // (currentMark - rsp) & (aligned_mask - page_size)
-            //
-            // assuming both the stack pointer and page_size have their least
-            // significant 2 bits cleared and page_size is a power of 2
-            final Word alignedMask = Word.unsigned(wordSize() - 1);
-            final Word stackPointer = stackPointer();
-            if (currentMark.subtract(stackPointer).and(alignedMask.subtract(pageSize())).notEqual(0)) {
-                // Most likely not a recursive lock, go into a slow runtime call
-                probability(DEOPT_PATH_PROBABILITY);
-                traceObject(trace, "+lock{stub:failed-cas}", object);
-                MonitorEnterStubCall.call(object, lock);
-                return;
-            } else {
-                // Recursively locked => write 0 to the lock slot
-                lock.writeWord(lockDisplacedMarkOffset(), Word.zero(), DISPLACED_MARK_WORD_LOCATION);
-                traceObject(trace, "+lock{recursive}", object);
-            }
-        } else {
-            traceObject(trace, "+lock{cas}", object);
-        }
-    }
-
-    @Snippet
-    public static void monitorenterEliminated() {
-        incCounter();
-        beginLockScope(true);
-    }
-
-    /**
-     * Calls straight out to the monitorenter stub.
-     */
-    @Snippet
-    public static void monitorenterStub(@Parameter("object") Object object, @ConstantParameter("checkNull") boolean checkNull, @ConstantParameter("trace") boolean trace) {
-        verifyOop(object);
-        incCounter();
-        if (checkNull && object == null) {
-            DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException);
-        }
-        // BeginLockScope nodes do not read from object so a use of object
-        // cannot float about the null check above
-        final Word lock = beginLockScope(false);
-        traceObject(trace, "+lock{stub}", object);
-        MonitorEnterStubCall.call(object, lock);
-    }
-
-    @Snippet
-    public static void monitorexit(@Parameter("object") Object object, @ConstantParameter("trace") boolean trace) {
-        trace(trace, "           object: 0x%016lx\n", Word.fromObject(object));
-        if (useBiasedLocking()) {
-            // Check for biased locking unlock case, which is a no-op
-            // Note: we do not have to check the thread ID for two reasons.
-            // First, the interpreter checks for IllegalMonitorStateException at
-            // a higher level. Second, if the bias was revoked while we held the
-            // lock, the object could not be rebiased toward another thread, so
-            // the bias bit would be clear.
-            final Word mark = loadWordFromObject(object, markOffset());
-            trace(trace, "             mark: 0x%016lx\n", mark);
-            if (mark.and(biasedLockMaskInPlace()).equal(Word.unsigned(biasedLockPattern()))) {
-                probability(FREQUENT_PROBABILITY);
-                endLockScope();
-                decCounter();
-                traceObject(trace, "-lock{bias}", object);
-                return;
-            }
-        }
-
-        final Word lock = CurrentLockNode.currentLock();
-
-        // Load displaced mark
-        final Word displacedMark = lock.readWord(lockDisplacedMarkOffset(), DISPLACED_MARK_WORD_LOCATION);
-        trace(trace, "    displacedMark: 0x%016lx\n", displacedMark);
-
-        if (displacedMark.equal(0)) {
-            // Recursive locking => done
-            traceObject(trace, "-lock{recursive}", object);
-        } else {
-            verifyOop(object);
-            // Test if object's mark word is pointing to the displaced mark word, and if so, restore
-            // the displaced mark in the object - if the object's mark word is not pointing to
-            // the displaced mark word, do unlocking via runtime call.
-            if (DirectCompareAndSwapNode.compareAndSwap(object, markOffset(), lock, displacedMark, MARK_WORD_LOCATION).notEqual(lock)) {
-                // The object's mark word was not pointing to the displaced header,
-                // we do unlocking via runtime call.
-                probability(DEOPT_PATH_PROBABILITY);
-                traceObject(trace, "-lock{stub}", object);
-                MonitorExitStubCall.call(object);
-            } else {
-                traceObject(trace, "-lock{cas}", object);
-            }
-        }
-        endLockScope();
-        decCounter();
-    }
-
-    /**
-     * Calls straight out to the monitorexit stub.
-     */
-    @Snippet
-    public static void monitorexitStub(@Parameter("object") Object object, @ConstantParameter("trace") boolean trace) {
-        verifyOop(object);
-        traceObject(trace, "-lock{stub}", object);
-        MonitorExitStubCall.call(object);
-        endLockScope();
-        decCounter();
-    }
-
-    @Snippet
-    public static void monitorexitEliminated() {
-        endLockScope();
-        decCounter();
-    }
-
-    private static void traceObject(boolean enabled, String action, Object object) {
-        if (enabled) {
-            Log.print(action);
-            Log.print(' ');
-            Log.printlnObject(object);
-        }
-    }
-
-    private static void trace(boolean enabled, String format, WordBase value) {
-        if (enabled) {
-            Log.printf(format, value.rawValue());
-        }
-    }
-
-    /**
-     * Leaving the breakpoint code in to provide an example of how to use the {@link BreakpointNode}
-     * intrinsic.
-     */
-    private static final boolean ENABLE_BREAKPOINT = false;
-
-    private static final Object MONITOR_COUNTER_LOCATION = LocationNode.createLocation("MonitorCounter");
-
-    @NodeIntrinsic(BreakpointNode.class)
-    static native void bkpt(Object object, Word mark, Word tmp, Word value);
-
-    private static void incCounter() {
-        if (CHECK_BALANCED_MONITORS) {
-            final Word counter = MonitorCounterNode.counter();
-            final int count = counter.readInt(0, MONITOR_COUNTER_LOCATION);
-            counter.writeInt(0, count + 1, MONITOR_COUNTER_LOCATION);
-        }
-    }
-
-    private static void decCounter() {
-        if (CHECK_BALANCED_MONITORS) {
-            final Word counter = MonitorCounterNode.counter();
-            final int count = counter.readInt(0, MONITOR_COUNTER_LOCATION);
-            counter.writeInt(0, count - 1, MONITOR_COUNTER_LOCATION);
-        }
-    }
-
-    @Snippet
-    private static void initCounter() {
-        final Word counter = MonitorCounterNode.counter();
-        counter.writeInt(0, 0, MONITOR_COUNTER_LOCATION);
-    }
-
-    @Snippet
-    private static void checkCounter(String errMsg) {
-        final Word counter = MonitorCounterNode.counter();
-        final int count = counter.readInt(0, MONITOR_COUNTER_LOCATION);
-        if (count != 0) {
-            vmError(errMsg, count);
-        }
-    }
-
-    public static class Templates extends AbstractTemplates<MonitorSnippets> {
-
-        private final ResolvedJavaMethod monitorenter;
-        private final ResolvedJavaMethod monitorexit;
-        private final ResolvedJavaMethod monitorenterStub;
-        private final ResolvedJavaMethod monitorexitStub;
-        private final ResolvedJavaMethod monitorenterEliminated;
-        private final ResolvedJavaMethod monitorexitEliminated;
-        private final ResolvedJavaMethod initCounter;
-        private final ResolvedJavaMethod checkCounter;
-        private final boolean useFastLocking;
-
-        public Templates(CodeCacheProvider runtime, Assumptions assumptions, TargetDescription target, boolean useFastLocking) {
-            super(runtime, assumptions, target, MonitorSnippets.class);
-            monitorenter = snippet("monitorenter", Object.class, boolean.class, boolean.class);
-            monitorexit = snippet("monitorexit", Object.class, boolean.class);
-            monitorenterStub = snippet("monitorenterStub", Object.class, boolean.class, boolean.class);
-            monitorexitStub = snippet("monitorexitStub", Object.class, boolean.class);
-            monitorenterEliminated = snippet("monitorenterEliminated");
-            monitorexitEliminated = snippet("monitorexitEliminated");
-            initCounter = snippet("initCounter");
-            checkCounter = snippet("checkCounter", String.class);
-            this.useFastLocking = useFastLocking;
-        }
-
-        public void lower(MonitorEnterNode monitorenterNode, @SuppressWarnings("unused") LoweringTool tool) {
-            StructuredGraph graph = (StructuredGraph) monitorenterNode.graph();
-
-            checkBalancedMonitors(graph);
-
-            FrameState stateAfter = monitorenterNode.stateAfter();
-            boolean eliminated = monitorenterNode.eliminated();
-            ResolvedJavaMethod method = eliminated ? monitorenterEliminated : useFastLocking ? monitorenter : monitorenterStub;
-            boolean checkNull = !monitorenterNode.object().stamp().nonNull();
-            Key key = new Key(method);
-            if (method != monitorenterEliminated) {
-                key.add("checkNull", checkNull);
-            }
-            if (!eliminated) {
-                key.add("trace", isTracingEnabledForType(monitorenterNode.object()) || isTracingEnabledForMethod(stateAfter.method()) || isTracingEnabledForMethod(graph.method()));
-            }
-
-            Arguments arguments = new Arguments();
-            if (!eliminated) {
-                arguments.add("object", monitorenterNode.object());
-            }
-            SnippetTemplate template = cache.get(key, assumptions);
-            Map<Node, Node> nodes = template.instantiate(runtime, monitorenterNode, DEFAULT_REPLACER, arguments);
-            for (Node n : nodes.values()) {
-                if (n instanceof BeginLockScopeNode) {
-                    BeginLockScopeNode begin = (BeginLockScopeNode) n;
-                    begin.setStateAfter(stateAfter);
-                }
-            }
-        }
-
-        public void lower(MonitorExitNode monitorexitNode, @SuppressWarnings("unused") LoweringTool tool) {
-            StructuredGraph graph = (StructuredGraph) monitorexitNode.graph();
-            FrameState stateAfter = monitorexitNode.stateAfter();
-            boolean eliminated = monitorexitNode.eliminated();
-            ResolvedJavaMethod method = eliminated ? monitorexitEliminated : useFastLocking ? monitorexit : monitorexitStub;
-            Key key = new Key(method);
-            if (!eliminated) {
-                key.add("trace", isTracingEnabledForType(monitorexitNode.object()) || isTracingEnabledForMethod(stateAfter.method()) || isTracingEnabledForMethod(graph.method()));
-            }
-            Arguments arguments = new Arguments();
-            if (!eliminated) {
-                arguments.add("object", monitorexitNode.object());
-            }
-            SnippetTemplate template = cache.get(key, assumptions);
-            Map<Node, Node> nodes = template.instantiate(runtime, monitorexitNode, DEFAULT_REPLACER, arguments);
-            for (Node n : nodes.values()) {
-                if (n instanceof EndLockScopeNode) {
-                    EndLockScopeNode end = (EndLockScopeNode) n;
-                    end.setStateAfter(stateAfter);
-                }
-            }
-        }
-
-        static boolean isTracingEnabledForType(ValueNode object) {
-            ResolvedJavaType type = object.objectStamp().type();
-            if (TRACE_TYPE_FILTER == null) {
-                return false;
-            } else {
-                if (TRACE_TYPE_FILTER.length() == 0) {
-                    return true;
-                }
-                if (type == null) {
-                    return false;
-                }
-                return (type.getName().contains(TRACE_TYPE_FILTER));
-            }
-        }
-
-        static boolean isTracingEnabledForMethod(ResolvedJavaMethod method) {
-            if (TRACE_METHOD_FILTER == null) {
-                return false;
-            } else {
-                if (TRACE_METHOD_FILTER.length() == 0) {
-                    return true;
-                }
-                if (method == null) {
-                    return false;
-                }
-                return (MetaUtil.format("%H.%n", method).contains(TRACE_METHOD_FILTER));
-            }
-        }
-
-        /**
-         * If balanced monitor checking is enabled then nodes are inserted at the start and all
-         * return points of the graph to initialize and check the monitor counter respectively.
-         */
-        private void checkBalancedMonitors(StructuredGraph graph) {
-            if (CHECK_BALANCED_MONITORS) {
-                NodeIterable<MonitorCounterNode> nodes = graph.getNodes().filter(MonitorCounterNode.class);
-                if (nodes.isEmpty()) {
-                    // Only insert the nodes if this is the first monitorenter being lowered.
-                    JavaType returnType = initCounter.getSignature().getReturnType(initCounter.getDeclaringClass());
-                    MethodCallTargetNode callTarget = graph.add(new MethodCallTargetNode(InvokeKind.Static, initCounter, new ValueNode[0], returnType));
-                    InvokeNode invoke = graph.add(new InvokeNode(callTarget, 0));
-                    invoke.setStateAfter(graph.start().stateAfter());
-                    graph.addAfterFixed(graph.start(), invoke);
-                    StructuredGraph inlineeGraph = (StructuredGraph) initCounter.getCompilerStorage().get(Graph.class);
-                    InliningUtil.inline(invoke, inlineeGraph, false);
-
-                    List<ReturnNode> rets = graph.getNodes().filter(ReturnNode.class).snapshot();
-                    for (ReturnNode ret : rets) {
-                        returnType = checkCounter.getSignature().getReturnType(checkCounter.getDeclaringClass());
-                        Object msg = ((HotSpotRuntime) runtime).registerGCRoot("unbalanced monitors in " + MetaUtil.format("%H.%n(%p)", graph.method()) + ", count = %d");
-                        ConstantNode errMsg = ConstantNode.forObject(msg, runtime, graph);
-                        callTarget = graph.add(new MethodCallTargetNode(InvokeKind.Static, checkCounter, new ValueNode[]{errMsg}, returnType));
-                        invoke = graph.add(new InvokeNode(callTarget, 0));
-                        List<ValueNode> stack = Collections.emptyList();
-                        FrameState stateAfter = new FrameState(graph.method(), FrameState.AFTER_BCI, new ValueNode[0], stack, new ValueNode[0], false, false);
-                        invoke.setStateAfter(graph.add(stateAfter));
-                        graph.addBeforeFixed(ret, invoke);
-                        inlineeGraph = (StructuredGraph) checkCounter.getCompilerStorage().get(Graph.class);
-                        InliningUtil.inline(invoke, inlineeGraph, false);
-                    }
-                }
-            }
-        }
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,391 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.snippets;
-
-import static com.oracle.graal.api.code.UnsignedMath.*;
-import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
-import static com.oracle.graal.nodes.extended.UnsafeArrayCastNode.*;
-import static com.oracle.graal.nodes.extended.UnsafeCastNode.*;
-import static com.oracle.graal.snippets.Snippet.Varargs.*;
-import static com.oracle.graal.snippets.SnippetTemplate.*;
-import static com.oracle.graal.snippets.SnippetTemplate.Arguments.*;
-import static com.oracle.graal.snippets.nodes.BranchProbabilityNode.*;
-import static com.oracle.graal.snippets.nodes.ExplodeLoopNode.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.debug.*;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.hotspot.nodes.*;
-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.phases.*;
-import com.oracle.graal.snippets.*;
-import com.oracle.graal.snippets.Snippet.ConstantParameter;
-import com.oracle.graal.snippets.Snippet.Parameter;
-import com.oracle.graal.snippets.Snippet.VarargsParameter;
-import com.oracle.graal.snippets.SnippetTemplate.AbstractTemplates;
-import com.oracle.graal.snippets.SnippetTemplate.Arguments;
-import com.oracle.graal.snippets.SnippetTemplate.Key;
-import com.oracle.graal.snippets.nodes.*;
-import com.oracle.graal.word.*;
-
-/**
- * Snippets used for implementing NEW, ANEWARRAY and NEWARRAY.
- */
-public class NewObjectSnippets implements SnippetsInterface {
-
-    // @formatter:off
-
-    @Snippet
-    public static Word allocate(@Parameter("size") int size) {
-        Word thread = thread();
-        Word top = readTlabTop(thread);
-        Word end = readTlabEnd(thread);
-        Word newTop = top.add(size);
-        // this check might lead to problems if the TLAB is within 16GB of the address space end (checked in c++ code)
-        if (newTop.belowOrEqual(end)) {
-            probability(FAST_PATH_PROBABILITY);
-            writeTlabTop(thread, newTop);
-            return top;
-        }
-        return Word.zero();
-    }
-
-    @Snippet
-    public static Object initializeObject(
-                    @Parameter("memory") Word memory,
-                    @Parameter("hub") Word hub,
-                    @Parameter("prototypeMarkWord") Word prototypeMarkWord,
-                    @ConstantParameter("size") int size,
-                    @ConstantParameter("fillContents") boolean fillContents,
-                    @ConstantParameter("locked") boolean locked) {
-
-        Object result;
-        if (memory.equal(0)) {
-            new_stub.inc();
-            result = NewInstanceStubCall.call(hub);
-        } else {
-            probability(FAST_PATH_PROBABILITY);
-            if (locked) {
-                formatObject(hub, size, memory, thread().or(biasedLockPattern()), fillContents);
-            } else {
-                formatObject(hub, size, memory, prototypeMarkWord, fillContents);
-            }
-            result = memory.toObject();
-        }
-        return unsafeCast(verifyOop(result), StampFactory.forNodeIntrinsic());
-    }
-
-    @Snippet
-    public static Object initializeArray(
-                    @Parameter("memory") Word memory,
-                    @Parameter("hub") Word hub,
-                    @Parameter("length") int length,
-                    @Parameter("allocationSize") int allocationSize,
-                    @Parameter("prototypeMarkWord") Word prototypeMarkWord,
-                    @ConstantParameter("headerSize") int headerSize,
-                    @ConstantParameter("fillContents") boolean fillContents,
-                    @ConstantParameter("locked") boolean locked) {
-        if (locked) {
-            return initializeArray(memory, hub, length, allocationSize, thread().or(biasedLockPattern()), headerSize, fillContents);
-        } else {
-            return initializeArray(memory, hub, length, allocationSize, prototypeMarkWord, headerSize, fillContents);
-        }
-    }
-
-    private static Object initializeArray(Word memory, Word hub, int length, int allocationSize, Word prototypeMarkWord, int headerSize, boolean fillContents) {
-        Object result;
-        if (memory.equal(0)) {
-            newarray_stub.inc();
-            result = NewArrayStubCall.call(hub, length);
-        } else {
-            probability(FAST_PATH_PROBABILITY);
-            newarray_loopInit.inc();
-            formatArray(hub, allocationSize, length, headerSize, memory, prototypeMarkWord, fillContents);
-            result = memory.toObject();
-        }
-        return unsafeArrayCast(verifyOop(result), length, StampFactory.forNodeIntrinsic());
-    }
-
-    /**
-     * Maximum array length for which fast path allocation is used.
-     */
-    public static final int MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH = 0x00FFFFFF;
-
-    @Snippet
-    public static Object allocateArrayAndInitialize(
-                    @Parameter("length") int length,
-                    @ConstantParameter("alignment") int alignment,
-                    @ConstantParameter("headerSize") int headerSize,
-                    @ConstantParameter("log2ElementSize") int log2ElementSize,
-                    @ConstantParameter("type") ResolvedJavaType type) {
-        if (!belowThan(length, MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH)) {
-            probability(DEOPT_PATH_PROBABILITY);
-            // This handles both negative array sizes and very large array sizes
-            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
-        }
-        int allocationSize = computeArrayAllocationSize(length, alignment, headerSize, log2ElementSize);
-        Word memory = TLABAllocateNode.allocateVariableSize(allocationSize);
-        return InitializeArrayNode.initialize(memory, length, allocationSize, type, true, false);
-    }
-
-    /**
-     * Computes the size of the memory chunk allocated for an array. This size accounts for the array
-     * header size, boy size and any padding after the last element to satisfy object alignment requirements.
-     *
-     * @param length the number of elements in the array
-     * @param alignment the object alignment requirement
-     * @param headerSize the size of the array header
-     * @param log2ElementSize log2 of the size of an element in the array
-     */
-    public static int computeArrayAllocationSize(int length, int alignment, int headerSize, int log2ElementSize) {
-        int size = (length << log2ElementSize) + headerSize + (alignment - 1);
-        int mask = ~(alignment - 1);
-        return size & mask;
-    }
-
-    /**
-     * Calls the runtime stub for implementing MULTIANEWARRAY.
-     */
-    @Snippet
-    public static Object newmultiarray(
-                    @Parameter("hub") Word hub,
-                    @ConstantParameter("rank") int rank,
-                    @VarargsParameter("dimensions") int[] dimensions) {
-        Word dims = DimensionsNode.allocaDimsArray(rank);
-        ExplodeLoopNode.explodeLoop();
-        for (int i = 0; i < rank; i++) {
-            dims.writeInt(i * 4, dimensions[i], ANY_LOCATION);
-        }
-        return NewMultiArrayStubCall.call(hub, rank, dims);
-    }
-
-    /**
-     * Maximum size of an object whose body is initialized by a sequence of
-     * zero-stores to its fields. Larger objects have their bodies initialized
-     * in a loop.
-     */
-    private static final int MAX_UNROLLED_OBJECT_ZEROING_SIZE = 10 * wordSize();
-
-    /**
-     * Formats some allocated memory with an object header zeroes out the rest.
-     */
-    private static void formatObject(Word hub, int size, Word memory, Word compileTimePrototypeMarkWord, boolean fillContents) {
-        Word prototypeMarkWord = useBiasedLocking() ? hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION) : compileTimePrototypeMarkWord;
-        initializeObjectHeader(memory, prototypeMarkWord, hub);
-        if (fillContents) {
-            if (size <= MAX_UNROLLED_OBJECT_ZEROING_SIZE) {
-                new_seqInit.inc();
-                explodeLoop();
-                for (int offset = 2 * wordSize(); offset < size; offset += wordSize()) {
-                    memory.writeWord(offset, Word.zero(), ANY_LOCATION);
-                }
-            } else {
-                new_loopInit.inc();
-                for (int offset = 2 * wordSize(); offset < size; offset += wordSize()) {
-                    memory.writeWord(offset, Word.zero(), ANY_LOCATION);
-                }
-            }
-        }
-    }
-
-    /**
-     * Formats some allocated memory with an object header zeroes out the rest.
-     */
-    public static void formatArray(Word hub, int allocationSize, int length, int headerSize, Word memory, Word prototypeMarkWord, boolean fillContents) {
-        memory.writeInt(arrayLengthOffset(), length, ANY_LOCATION);
-        // store hub last as the concurrent garbage collectors assume length is valid if hub field is not null
-        initializeObjectHeader(memory, prototypeMarkWord, hub);
-        if (fillContents) {
-            for (int offset = headerSize; offset < allocationSize; offset += wordSize()) {
-                memory.writeWord(offset, Word.zero(), ANY_LOCATION);
-            }
-        }
-    }
-
-    // @formatter:on
-
-    public static class Templates extends AbstractTemplates<NewObjectSnippets> {
-
-        private final ResolvedJavaMethod allocate;
-        private final ResolvedJavaMethod initializeObject;
-        private final ResolvedJavaMethod initializeArray;
-        private final ResolvedJavaMethod allocateArrayAndInitialize;
-        private final ResolvedJavaMethod newmultiarray;
-        private final TargetDescription target;
-        private final boolean useTLAB;
-
-        public Templates(CodeCacheProvider runtime, Assumptions assumptions, TargetDescription target, boolean useTLAB) {
-            super(runtime, assumptions, target, NewObjectSnippets.class);
-            this.target = target;
-            this.useTLAB = useTLAB;
-            allocate = snippet("allocate", int.class);
-            initializeObject = snippet("initializeObject", Word.class, Word.class, Word.class, int.class, boolean.class, boolean.class);
-            initializeArray = snippet("initializeArray", Word.class, Word.class, int.class, int.class, Word.class, int.class, boolean.class, boolean.class);
-            allocateArrayAndInitialize = snippet("allocateArrayAndInitialize", int.class, int.class, int.class, int.class, ResolvedJavaType.class);
-            newmultiarray = snippet("newmultiarray", Word.class, int.class, int[].class);
-        }
-
-        /**
-         * Lowers a {@link NewInstanceNode}.
-         */
-        @SuppressWarnings("unused")
-        public void lower(NewInstanceNode newInstanceNode, LoweringTool tool) {
-            StructuredGraph graph = (StructuredGraph) newInstanceNode.graph();
-            HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) newInstanceNode.instanceClass();
-            ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, graph);
-            int size = instanceSize(type);
-
-            ValueNode memory;
-            if (!useTLAB) {
-                memory = ConstantNode.defaultForKind(target.wordKind, graph);
-            } else {
-                ConstantNode sizeNode = ConstantNode.forInt(size, graph);
-                TLABAllocateNode tlabAllocateNode = graph.add(new TLABAllocateNode(sizeNode));
-                graph.addBeforeFixed(newInstanceNode, tlabAllocateNode);
-                memory = tlabAllocateNode;
-            }
-            InitializeObjectNode initializeNode = graph.add(new InitializeObjectNode(memory, type, newInstanceNode.fillContents(), newInstanceNode.locked()));
-            graph.replaceFixedWithFixed(newInstanceNode, initializeNode);
-        }
-
-        /**
-         * Lowers a {@link NewArrayNode}.
-         */
-        @SuppressWarnings("unused")
-        public void lower(NewArrayNode newArrayNode, LoweringTool tool) {
-            StructuredGraph graph = (StructuredGraph) newArrayNode.graph();
-            ValueNode lengthNode = newArrayNode.length();
-            TLABAllocateNode tlabAllocateNode;
-            ResolvedJavaType elementType = newArrayNode.elementType();
-            ResolvedJavaType arrayType = elementType.getArrayClass();
-            Kind elementKind = elementType.getKind();
-            final int alignment = target.wordSize;
-            final int headerSize = HotSpotRuntime.getArrayBaseOffset(elementKind);
-            final Integer length = lengthNode.isConstant() ? Integer.valueOf(lengthNode.asConstant().asInt()) : null;
-            int log2ElementSize = CodeUtil.log2(target.sizeInBytes(elementKind));
-            if (!useTLAB) {
-                ConstantNode zero = ConstantNode.defaultForKind(target.wordKind, graph);
-                // value for 'size' doesn't matter as it isn't used since a stub call will be made
-                // anyway
-                // for both allocation and initialization - it just needs to be non-null
-                ConstantNode size = ConstantNode.forInt(-1, graph);
-                InitializeArrayNode initializeNode = graph.add(new InitializeArrayNode(zero, lengthNode, size, arrayType, newArrayNode.fillContents(), newArrayNode.locked()));
-                graph.replaceFixedWithFixed(newArrayNode, initializeNode);
-            } else if (length != null && belowThan(length, MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH)) {
-                // Calculate aligned size
-                int size = computeArrayAllocationSize(length, alignment, headerSize, log2ElementSize);
-                ConstantNode sizeNode = ConstantNode.forInt(size, graph);
-                tlabAllocateNode = graph.add(new TLABAllocateNode(sizeNode));
-                graph.addBeforeFixed(newArrayNode, tlabAllocateNode);
-                InitializeArrayNode initializeNode = graph.add(new InitializeArrayNode(tlabAllocateNode, lengthNode, sizeNode, arrayType, newArrayNode.fillContents(), newArrayNode.locked()));
-                graph.replaceFixedWithFixed(newArrayNode, initializeNode);
-            } else {
-                Key key = new Key(allocateArrayAndInitialize).add("alignment", alignment).add("headerSize", headerSize).add("log2ElementSize", log2ElementSize).add("type", arrayType);
-                Arguments arguments = new Arguments().add("length", lengthNode);
-                SnippetTemplate template = cache.get(key, assumptions);
-                Debug.log("Lowering allocateArrayAndInitialize in %s: node=%s, template=%s, arguments=%s", graph, newArrayNode, template, arguments);
-                template.instantiate(runtime, newArrayNode, DEFAULT_REPLACER, arguments);
-            }
-        }
-
-        @SuppressWarnings("unused")
-        public void lower(TLABAllocateNode tlabAllocateNode, LoweringTool tool) {
-            StructuredGraph graph = (StructuredGraph) tlabAllocateNode.graph();
-            ValueNode size = tlabAllocateNode.size();
-            Key key = new Key(allocate);
-            Arguments arguments = arguments("size", size);
-            SnippetTemplate template = cache.get(key, assumptions);
-            Debug.log("Lowering fastAllocate in %s: node=%s, template=%s, arguments=%s", graph, tlabAllocateNode, template, arguments);
-            template.instantiate(runtime, tlabAllocateNode, DEFAULT_REPLACER, arguments);
-        }
-
-        @SuppressWarnings("unused")
-        public void lower(InitializeObjectNode initializeNode, LoweringTool tool) {
-            StructuredGraph graph = (StructuredGraph) initializeNode.graph();
-            HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) initializeNode.type();
-            assert !type.isArray();
-            ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, graph);
-            int size = instanceSize(type);
-            Key key = new Key(initializeObject).add("size", size).add("fillContents", initializeNode.fillContents()).add("locked", initializeNode.locked());
-            ValueNode memory = initializeNode.memory();
-            Arguments arguments = arguments("memory", memory).add("hub", hub).add("prototypeMarkWord", type.prototypeMarkWord());
-            SnippetTemplate template = cache.get(key, assumptions);
-            Debug.log("Lowering initializeObject in %s: node=%s, template=%s, arguments=%s", graph, initializeNode, template, arguments);
-            template.instantiate(runtime, initializeNode, DEFAULT_REPLACER, arguments);
-        }
-
-        @SuppressWarnings("unused")
-        public void lower(InitializeArrayNode initializeNode, LoweringTool tool) {
-            StructuredGraph graph = (StructuredGraph) initializeNode.graph();
-            HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) initializeNode.type();
-            ResolvedJavaType elementType = type.getComponentType();
-            assert elementType != null;
-            ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, graph);
-            Kind elementKind = elementType.getKind();
-            final int headerSize = HotSpotRuntime.getArrayBaseOffset(elementKind);
-            Key key = new Key(initializeArray).add("headerSize", headerSize).add("fillContents", initializeNode.fillContents()).add("locked", initializeNode.locked());
-            ValueNode memory = initializeNode.memory();
-            Arguments arguments = arguments("memory", memory).add("hub", hub).add("prototypeMarkWord", type.prototypeMarkWord()).add("allocationSize", initializeNode.allocationSize()).add("length",
-                            initializeNode.length());
-            SnippetTemplate template = cache.get(key, assumptions);
-            Debug.log("Lowering initializeArray in %s: node=%s, template=%s, arguments=%s", graph, initializeNode, template, arguments);
-            template.instantiate(runtime, initializeNode, DEFAULT_REPLACER, arguments);
-        }
-
-        @SuppressWarnings("unused")
-        public void lower(NewMultiArrayNode newmultiarrayNode, LoweringTool tool) {
-            StructuredGraph graph = (StructuredGraph) newmultiarrayNode.graph();
-            int rank = newmultiarrayNode.dimensionCount();
-            ValueNode[] dims = new ValueNode[rank];
-            for (int i = 0; i < newmultiarrayNode.dimensionCount(); i++) {
-                dims[i] = newmultiarrayNode.dimension(i);
-            }
-            HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) newmultiarrayNode.type();
-            ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, graph);
-            Key key = new Key(newmultiarray).add("dimensions", vargargs(new int[rank], StampFactory.forKind(Kind.Int))).add("rank", rank);
-            Arguments arguments = arguments("dimensions", dims).add("hub", hub);
-            SnippetTemplate template = cache.get(key, assumptions);
-            template.instantiate(runtime, newmultiarrayNode, DEFAULT_REPLACER, arguments);
-        }
-
-        private static int instanceSize(HotSpotResolvedObjectType type) {
-            int size = type.instanceSize();
-            assert (size % wordSize()) == 0;
-            assert size >= 0;
-            return size;
-        }
-    }
-
-    private static final SnippetCounter.Group countersNew = GraalOptions.SnippetCounters ? new SnippetCounter.Group("NewInstance") : null;
-    private static final SnippetCounter new_seqInit = new SnippetCounter(countersNew, "tlabSeqInit", "TLAB alloc with unrolled zeroing");
-    private static final SnippetCounter new_loopInit = new SnippetCounter(countersNew, "tlabLoopInit", "TLAB alloc with zeroing in a loop");
-    private static final SnippetCounter new_stub = new SnippetCounter(countersNew, "stub", "alloc and zeroing via stub");
-
-    private static final SnippetCounter.Group countersNewArray = GraalOptions.SnippetCounters ? new SnippetCounter.Group("NewArray") : null;
-    private static final SnippetCounter newarray_loopInit = new SnippetCounter(countersNewArray, "tlabLoopInit", "TLAB alloc with zeroing in a loop");
-    private static final SnippetCounter newarray_stub = new SnippetCounter(countersNewArray, "stub", "alloc and zeroing via stub");
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectCloneNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,151 +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.hotspot.snippets;
-
-import java.lang.reflect.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-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.phases.*;
-import com.oracle.graal.snippets.nodes.*;
-
-public class ObjectCloneNode extends MacroNode implements VirtualizableAllocation, ArrayLengthProvider {
-
-    public ObjectCloneNode(Invoke invoke) {
-        super(invoke);
-    }
-
-    @Override
-    public boolean inferStamp() {
-        return updateStamp(getObject().stamp());
-    }
-
-    private ValueNode getObject() {
-        return arguments.get(0);
-    }
-
-    @Override
-    protected StructuredGraph getSnippetGraph(LoweringTool tool) {
-        if (!GraalOptions.IntrinsifyObjectClone) {
-            return null;
-        }
-
-        ResolvedJavaType type = getObject().objectStamp().type();
-        Method method;
-        /*
-         * The first condition tests if the parameter is an array, the second condition tests if the
-         * parameter can be an array. Otherwise, the parameter is known to be a non-array object.
-         */
-        if (type.isArray()) {
-            method = ObjectCloneSnippets.arrayCloneMethod;
-        } else if (type == null || type.isAssignableFrom(tool.getRuntime().lookupJavaType(Object[].class))) {
-            method = ObjectCloneSnippets.genericCloneMethod;
-        } else {
-            method = ObjectCloneSnippets.instanceCloneMethod;
-        }
-        ResolvedJavaMethod snippetMethod = tool.getRuntime().lookupJavaMethod(method);
-        StructuredGraph snippetGraph = (StructuredGraph) snippetMethod.getCompilerStorage().get(Graph.class);
-
-        assert snippetGraph != null : "ObjectCloneSnippets should be installed";
-        return snippetGraph;
-    }
-
-    private static boolean isCloneableType(ResolvedJavaType type, MetaAccessProvider metaAccess) {
-        return metaAccess.lookupJavaType(Cloneable.class).isAssignableFrom(type);
-    }
-
-    private static ResolvedJavaType getConcreteType(ObjectStamp stamp, Assumptions assumptions) {
-        if (stamp.isExactType() || stamp.type() == null) {
-            return stamp.type();
-        } else {
-            ResolvedJavaType type = stamp.type().findUniqueConcreteSubtype();
-            if (type != null) {
-                assumptions.recordConcreteSubtype(stamp.type(), type);
-            }
-            return type;
-        }
-    }
-
-    @Override
-    public void virtualize(VirtualizerTool tool) {
-        State originalState = tool.getObjectState(getObject());
-        if (originalState != null && originalState.getState() == EscapeState.Virtual) {
-            VirtualObjectNode originalVirtual = originalState.getVirtualObject();
-            if (isCloneableType(originalVirtual.type(), tool.getMetaAccessProvider())) {
-                ValueNode[] newEntryState = new ValueNode[originalVirtual.entryCount()];
-                for (int i = 0; i < newEntryState.length; i++) {
-                    newEntryState[i] = originalState.getEntry(i);
-                }
-                VirtualObjectNode newVirtual = originalVirtual.duplicate();
-                tool.createVirtualObject(newVirtual, newEntryState, 0);
-                tool.replaceWithVirtual(newVirtual);
-            }
-        } else {
-            ValueNode obj;
-            if (originalState != null) {
-                obj = originalState.getMaterializedValue();
-            } else {
-                obj = tool.getReplacedValue(getObject());
-            }
-            ResolvedJavaType type = getConcreteType(obj.objectStamp(), tool.getAssumptions());
-            if (isCloneableType(type, tool.getMetaAccessProvider())) {
-                if (!type.isArray()) {
-                    ResolvedJavaField[] fields = type.getInstanceFields(true);
-                    ValueNode[] state = new ValueNode[fields.length];
-                    final LoadFieldNode[] loads = new LoadFieldNode[fields.length];
-                    for (int i = 0; i < fields.length; i++) {
-                        state[i] = loads[i] = graph().add(new LoadFieldNode(obj, fields[i]));
-                    }
-
-                    VirtualObjectNode newVirtual = new VirtualInstanceNode(type, fields);
-                    final StructuredGraph structuredGraph = (StructuredGraph) graph();
-                    tool.customAction(new Runnable() {
-
-                        public void run() {
-                            for (LoadFieldNode load : loads) {
-                                structuredGraph.addBeforeFixed(ObjectCloneNode.this, load);
-                            }
-                        }
-                    });
-                    tool.createVirtualObject(newVirtual, state, 0);
-                    tool.replaceWithVirtual(newVirtual);
-                }
-            }
-        }
-    }
-
-    @Override
-    public ValueNode length() {
-        if (getObject() instanceof ArrayLengthProvider) {
-            return ((ArrayLengthProvider) getObject()).length();
-        } else {
-            return null;
-        }
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectCloneSnippets.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +0,0 @@
-/*
- * Copyright (c) 2011, 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.hotspot.snippets;
-
-import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
-import static com.oracle.graal.snippets.nodes.BranchProbabilityNode.*;
-
-import java.lang.reflect.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.phases.*;
-import com.oracle.graal.snippets.*;
-import com.oracle.graal.word.*;
-
-public class ObjectCloneSnippets implements SnippetsInterface {
-
-    public static final Method instanceCloneMethod = getCloneMethod("instanceClone");
-    public static final Method arrayCloneMethod = getCloneMethod("arrayClone");
-    public static final Method genericCloneMethod = getCloneMethod("genericClone");
-
-    private static Method getCloneMethod(String name) {
-        try {
-            return ObjectCloneSnippets.class.getDeclaredMethod(name, Object.class);
-        } catch (SecurityException | NoSuchMethodException e) {
-            throw new GraalInternalError(e);
-        }
-    }
-
-    private static Object instanceClone(Object src, Word hub, int layoutHelper) {
-        int instanceSize = layoutHelper;
-        Pointer memory = NewObjectSnippets.allocate(instanceSize);
-        Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION);
-        Object result = NewObjectSnippets.initializeObject((Word) memory, hub, prototypeMarkWord, instanceSize, false, false);
-
-        memory = Word.fromObject(result);
-        for (int offset = 2 * wordSize(); offset < instanceSize; offset += wordSize()) {
-            memory.writeWord(offset, Word.fromObject(src).readWord(offset, UNKNOWN_LOCATION), ANY_LOCATION);
-        }
-
-        return result;
-    }
-
-    private static Object arrayClone(Object src, Word hub, int layoutHelper) {
-        int arrayLength = ArrayLengthNode.arrayLength(src);
-        int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask();
-        int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift()) & layoutHelperHeaderSizeMask();
-        int sizeInBytes = NewObjectSnippets.computeArrayAllocationSize(arrayLength, wordSize(), headerSize, log2ElementSize);
-
-        Pointer memory = NewObjectSnippets.allocate(sizeInBytes);
-        Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION);
-        Object result = NewObjectSnippets.initializeArray((Word) memory, hub, arrayLength, sizeInBytes, prototypeMarkWord, headerSize, false, false);
-
-        memory = Word.fromObject(result);
-        for (int offset = headerSize; offset < sizeInBytes; offset += wordSize()) {
-            memory.writeWord(offset, Word.fromObject(src).readWord(offset, UNKNOWN_LOCATION), ANY_LOCATION);
-        }
-        return result;
-    }
-
-    private static Word getAndCheckHub(Object src) {
-        Word hub = loadHub(src);
-        if (!(src instanceof Cloneable)) {
-            probability(DEOPT_PATH_PROBABILITY);
-            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
-        }
-        return hub;
-    }
-
-    @Snippet
-    public static Object instanceClone(Object src) {
-        instanceCloneCounter.inc();
-        Word hub = getAndCheckHub(src);
-        return instanceClone(src, hub, hub.readInt(layoutHelperOffset(), FINAL_LOCATION));
-    }
-
-    @Snippet
-    public static Object arrayClone(Object src) {
-        arrayCloneCounter.inc();
-        Word hub = getAndCheckHub(src);
-        int layoutHelper = hub.readInt(layoutHelperOffset(), FINAL_LOCATION);
-        return arrayClone(src, hub, layoutHelper);
-    }
-
-    @Snippet
-    public static Object genericClone(Object src) {
-        genericCloneCounter.inc();
-        Word hub = getAndCheckHub(src);
-        int layoutHelper = hub.readInt(layoutHelperOffset(), FINAL_LOCATION);
-        if (layoutHelper < 0) {
-            probability(LIKELY_PROBABILITY);
-            genericArrayCloneCounter.inc();
-            return arrayClone(src, hub, layoutHelper);
-        } else {
-            genericInstanceCloneCounter.inc();
-            return instanceClone(src, hub, layoutHelper);
-        }
-    }
-
-    private static final SnippetCounter.Group cloneCounters = GraalOptions.SnippetCounters ? new SnippetCounter.Group("Object.clone") : null;
-    private static final SnippetCounter instanceCloneCounter = new SnippetCounter(cloneCounters, "instanceClone", "clone snippet for instances");
-    private static final SnippetCounter arrayCloneCounter = new SnippetCounter(cloneCounters, "arrayClone", "clone snippet for arrays");
-    private static final SnippetCounter genericCloneCounter = new SnippetCounter(cloneCounters, "genericClone", "clone snippet for arrays and instances");
-
-    private static final SnippetCounter.Group genericCloneCounters = GraalOptions.SnippetCounters ? new SnippetCounter.Group("Object.clone generic snippet") : null;
-    private static final SnippetCounter genericInstanceCloneCounter = new SnippetCounter(genericCloneCounters, "genericInstanceClone", "generic clone implementation took instance path");
-    private static final SnippetCounter genericArrayCloneCounter = new SnippetCounter(genericCloneCounters, "genericArrayClone", "generic clone implementation took array path");
-
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectSubstitutions.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.snippets;
-
-import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
-import static com.oracle.graal.nodes.extended.UnsafeCastNode.*;
-
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.snippets.*;
-import com.oracle.graal.snippets.ClassSubstitution.MacroSubstitution;
-import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution;
-import com.oracle.graal.word.*;
-
-/**
- * Substitutions for {@link java.lang.Object} methods.
- */
-@ClassSubstitution(java.lang.Object.class)
-public class ObjectSubstitutions {
-
-    @MethodSubstitution(isStatic = false)
-    public static Class<?> getClass(final Object thisObj) {
-        Word hub = loadHub(thisObj);
-        return unsafeCast(hub.readObject(Word.signed(classMirrorOffset()), LocationNode.FINAL_LOCATION), Class.class, true, true);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static int hashCode(final Object thisObj) {
-        return computeHashCode(thisObj);
-    }
-
-    @MacroSubstitution(macro = ObjectCloneNode.class, isStatic = false)
-    public static native Object clone(Object obj);
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/SystemSubstitutions.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2011, 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.hotspot.snippets;
-
-import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
-import static com.oracle.graal.snippets.nodes.BranchProbabilityNode.*;
-
-import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
-import com.oracle.graal.graph.Node.ConstantNodeParameter;
-import com.oracle.graal.graph.Node.NodeIntrinsic;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.snippets.*;
-import com.oracle.graal.snippets.ClassSubstitution.MacroSubstitution;
-import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution;
-
-/**
- * Substitutions for {@link java.lang.System} methods.
- */
-@ClassSubstitution(java.lang.System.class)
-public class SystemSubstitutions {
-
-    public static final Descriptor JAVA_TIME_MILLIS = new Descriptor("javaTimeMillis", false, long.class);
-    public static final Descriptor JAVA_TIME_NANOS = new Descriptor("javaTimeNanos", false, long.class);
-
-    @MacroSubstitution(macro = ArrayCopyNode.class)
-    public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
-
-    @MethodSubstitution
-    public static long currentTimeMillis() {
-        return callLong(JAVA_TIME_MILLIS);
-    }
-
-    @MethodSubstitution
-    public static long nanoTime() {
-        return callLong(JAVA_TIME_NANOS);
-    }
-
-    @MethodSubstitution
-    public static int identityHashCode(Object x) {
-        if (x == null) {
-            probability(NOT_FREQUENT_PROBABILITY);
-            return 0;
-        }
-
-        return computeHashCode(x);
-    }
-
-    @NodeIntrinsic(value = RuntimeCallNode.class, setStampFromReturnType = true)
-    public static native long callLong(@ConstantNodeParameter Descriptor descriptor);
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ThreadSubstitutions.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.snippets;
-
-import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
-
-import com.oracle.graal.hotspot.nodes.*;
-import com.oracle.graal.snippets.*;
-import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution;
-import com.oracle.graal.word.*;
-
-/**
- * Substitutions for {@link java.lang.Thread} methods.
- */
-@ClassSubstitution(java.lang.Thread.class)
-public class ThreadSubstitutions {
-
-    @MethodSubstitution
-    public static Thread currentThread() {
-        return CurrentThread.get();
-    }
-
-    @MethodSubstitution(isStatic = false)
-    private static boolean isInterrupted(final Thread thisObject, boolean clearInterrupted) {
-        Word rawThread = HotSpotCurrentRawThreadNode.get();
-        Thread thread = (Thread) rawThread.readObject(threadObjectOffset(), FINAL_LOCATION);
-        if (thisObject == thread) {
-            Word osThread = rawThread.readWord(osThreadOffset(), FINAL_LOCATION);
-            boolean interrupted = osThread.readInt(osThreadInterruptedOffset(), UNKNOWN_LOCATION) != 0;
-            if (!interrupted || !clearInterrupted) {
-                return interrupted;
-            }
-        }
-
-        return ThreadIsInterruptedStubCall.call(thisObject, clearInterrupted) != 0;
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/TypeCheckSnippetUtils.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,125 +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.hotspot.snippets;
-
-import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
-import static com.oracle.graal.snippets.nodes.BranchProbabilityNode.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.phases.*;
-import com.oracle.graal.snippets.*;
-import com.oracle.graal.word.*;
-
-/**
- * Utilities and common code paths used by the type check snippets.
- */
-public class TypeCheckSnippetUtils {
-
-    public static final Object TYPE_DISPLAY_LOCATION = LocationNode.createLocation("TypeDisplay");
-
-    static boolean checkSecondarySubType(Word t, Word s) {
-        // if (S.cache == T) return true
-        if (s.readWord(secondarySuperCacheOffset(), SECONDARY_SUPER_CACHE_LOCATION).equal(t)) {
-            cacheHit.inc();
-            return true;
-        }
-
-        return checkSelfAndSupers(t, s);
-    }
-
-    static boolean checkUnknownSubType(Word t, Word s) {
-        // int off = T.offset
-        int superCheckOffset = t.readInt(superCheckOffsetOffset(), FINAL_LOCATION);
-        boolean primary = superCheckOffset != secondarySuperCacheOffset();
-
-        // if (T = S[off]) return true
-        if (s.readWord(superCheckOffset, TYPE_DISPLAY_LOCATION).equal(t)) {
-            if (primary) {
-                cacheHit.inc();
-            } else {
-                displayHit.inc();
-            }
-            return true;
-        }
-
-        // if (off != &cache) return false
-        if (primary) {
-            displayMiss.inc();
-            return false;
-        }
-
-        return checkSelfAndSupers(t, s);
-    }
-
-    private static boolean checkSelfAndSupers(Word t, Word s) {
-        // if (T == S) return true
-        if (s.equal(t)) {
-            T_equals_S.inc();
-            return true;
-        }
-
-        // if (S.scan_s_s_array(T)) { S.cache = T; return true; }
-        Word secondarySupers = s.readWord(secondarySupersOffset(), SECONDARY_SUPERS_LOCATION);
-        int length = secondarySupers.readInt(metaspaceArrayLengthOffset(), FINAL_LOCATION);
-        for (int i = 0; i < length; i++) {
-            if (t.equal(loadSecondarySupersElement(secondarySupers, i))) {
-                probability(NOT_LIKELY_PROBABILITY);
-                s.writeWord(secondarySuperCacheOffset(), t, SECONDARY_SUPER_CACHE_LOCATION);
-                secondariesHit.inc();
-                return true;
-            }
-        }
-        secondariesMiss.inc();
-        return false;
-    }
-
-    static ConstantNode[] createHints(TypeCheckHints hints, MetaAccessProvider runtime, Graph graph) {
-        ConstantNode[] hintHubs = new ConstantNode[hints.types.length];
-        for (int i = 0; i < hintHubs.length; i++) {
-            hintHubs[i] = ConstantNode.forConstant(((HotSpotResolvedObjectType) hints.types[i]).klass(), runtime, graph);
-        }
-        return hintHubs;
-    }
-
-    static Word loadSecondarySupersElement(Word metaspaceArray, int index) {
-        return metaspaceArray.readWord(metaspaceArrayBaseOffset() + index * wordSize(), FINAL_LOCATION);
-    }
-
-    private static final SnippetCounter.Group counters = GraalOptions.SnippetCounters ? new SnippetCounter.Group("TypeCheck") : null;
-    static final SnippetCounter hintsHit = new SnippetCounter(counters, "hintsHit", "hit a hint type");
-    static final SnippetCounter exactHit = new SnippetCounter(counters, "exactHit", "exact type test succeeded");
-    static final SnippetCounter exactMiss = new SnippetCounter(counters, "exactMiss", "exact type test failed");
-    static final SnippetCounter isNull = new SnippetCounter(counters, "isNull", "object tested was null");
-    static final SnippetCounter cacheHit = new SnippetCounter(counters, "cacheHit", "secondary type cache hit");
-    static final SnippetCounter secondariesHit = new SnippetCounter(counters, "secondariesHit", "secondaries scan succeeded");
-    static final SnippetCounter secondariesMiss = new SnippetCounter(counters, "secondariesMiss", "secondaries scan failed");
-    static final SnippetCounter displayHit = new SnippetCounter(counters, "displayHit", "primary type test succeeded");
-    static final SnippetCounter displayMiss = new SnippetCounter(counters, "displayMiss", "primary type test failed");
-    static final SnippetCounter T_equals_S = new SnippetCounter(counters, "T_equals_S", "object type was equal to secondary type");
-
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Thu Mar 21 13:13:07 2013 +0100
@@ -22,19 +22,18 @@
  */
 package com.oracle.graal.hotspot.stubs;
 
-import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
-import static com.oracle.graal.hotspot.snippets.NewObjectSnippets.*;
+import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*;
+import static com.oracle.graal.hotspot.replacements.NewObjectSnippets.*;
 import static com.oracle.graal.hotspot.stubs.NewInstanceStub.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
-import com.oracle.graal.hotspot.snippets.*;
-import com.oracle.graal.snippets.*;
-import com.oracle.graal.snippets.Snippet.ConstantParameter;
-import com.oracle.graal.snippets.Snippet.Parameter;
-import com.oracle.graal.snippets.SnippetTemplate.Key;
+import com.oracle.graal.hotspot.replacements.*;
+import com.oracle.graal.replacements.*;
+import com.oracle.graal.replacements.Snippet.*;
+import com.oracle.graal.replacements.SnippetTemplate.*;
 import com.oracle.graal.word.*;
 
 /**
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Thu Mar 21 13:13:07 2013 +0100
@@ -24,19 +24,17 @@
 
 import static com.oracle.graal.hotspot.nodes.DirectCompareAndSwapNode.*;
 import static com.oracle.graal.hotspot.nodes.NewInstanceStubCall.*;
-import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
-import static com.oracle.graal.hotspot.snippets.NewObjectSnippets.*;
+import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*;
+import static com.oracle.graal.hotspot.replacements.NewObjectSnippets.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
-import com.oracle.graal.hotspot.snippets.*;
-import com.oracle.graal.snippets.*;
-import com.oracle.graal.snippets.Snippet.ConstantParameter;
-import com.oracle.graal.snippets.Snippet.Fold;
-import com.oracle.graal.snippets.Snippet.Parameter;
-import com.oracle.graal.snippets.SnippetTemplate.Key;
+import com.oracle.graal.hotspot.replacements.*;
+import com.oracle.graal.replacements.*;
+import com.oracle.graal.replacements.Snippet.*;
+import com.oracle.graal.replacements.SnippetTemplate.*;
 import com.oracle.graal.word.*;
 
 /**
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Thu Mar 21 13:13:07 2013 +0100
@@ -40,19 +40,18 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
-import com.oracle.graal.snippets.*;
-import com.oracle.graal.snippets.Snippet.ConstantParameter;
-import com.oracle.graal.snippets.SnippetTemplate.AbstractTemplates;
-import com.oracle.graal.snippets.SnippetTemplate.Key;
+import com.oracle.graal.replacements.*;
+import com.oracle.graal.replacements.Snippet.*;
+import com.oracle.graal.replacements.SnippetTemplate.*;
 
 /**
  * Base class for implementing some low level code providing the out-of-line slow path for a
  * snippet. A concrete stub is defined a subclass of this class.
  * <p>
  * Implementation detail: The stub classes re-use some of the functionality for {@link Snippet}s
- * purely for convenience (e.g., can re-use the {@link SnippetInstaller}).
+ * purely for convenience (e.g., can re-use the {@link ReplacementsInstaller}).
  */
-public abstract class Stub extends AbstractTemplates implements SnippetsInterface {
+public abstract class Stub extends AbstractTemplates implements Snippets {
 
     /**
      * The method implementing the stub.
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Thu Mar 21 13:13:07 2013 +0100
@@ -1552,10 +1552,10 @@
 
     private void createUnwind() {
         assert frameState.stackSize() == 1 : frameState;
-        synchronizedEpilogue(FrameState.AFTER_EXCEPTION_BCI);
         ValueNode exception = frameState.apop();
         FixedGuardNode guard = currentGraph.add(new FixedGuardNode(currentGraph.unique(new IsNullNode(exception)), NullCheckException, InvalidateReprofile, true));
         append(guard);
+        synchronizedEpilogue(FrameState.AFTER_EXCEPTION_BCI);
         UnwindNode unwindNode = currentGraph.add(new UnwindNode(exception));
         append(unwindNode);
     }
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/System_identityHashCode01.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/System_identityHashCode01.java	Thu Mar 21 13:13:07 2013 +0100
@@ -22,8 +22,9 @@
  */
 package com.oracle.graal.jtt.lang;
 
+import org.junit.*;
+
 import com.oracle.graal.jtt.*;
-import org.junit.*;
 
 /*
  */
@@ -47,6 +48,9 @@
         if (i == 2) {
             return hash2 == System.identityHashCode(object2);
         }
+        if (i == 3) {
+            return 0 == System.identityHashCode(null);
+        }
         return false;
     }
 
@@ -70,4 +74,8 @@
         runTest("test", 3);
     }
 
+    @Test
+    public void run4() throws Throwable {
+        runTest("test", 4);
+    }
 }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Thu Mar 21 13:13:07 2013 +0100
@@ -297,7 +297,7 @@
 
     public static class NullCheckOp extends AMD64LIRInstruction {
 
-        @Use protected AllocatableValue input;
+        @Use({REG}) protected AllocatableValue input;
         @State protected LIRFrameState state;
 
         public NullCheckOp(Variable input, LIRFrameState state) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSinkNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2011, 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.nodes;
+
+import com.oracle.graal.nodes.type.*;
+
+public abstract class ControlSinkNode extends FixedNode {
+
+    public ControlSinkNode(Stamp stamp) {
+        super(stamp);
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -29,7 +29,7 @@
 import com.oracle.graal.nodes.type.*;
 
 @NodeInfo(shortName = "Deopt", nameTemplate = "Deopt {p#reason/s}")
-public class DeoptimizeNode extends FixedNode implements Node.IterableNodeType, LIRLowerable {
+public class DeoptimizeNode extends ControlSinkNode implements Node.IterableNodeType, LIRLowerable {
 
     private final DeoptimizationAction action;
     private final DeoptimizationReason reason;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -109,8 +109,8 @@
     }
 
     @Override
-    public Object getLocationIdentity() {
-        return LocationNode.ANY_LOCATION;
+    public Object[] getLocationIdentities() {
+        return new Object[]{LocationNode.ANY_LOCATION};
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -162,8 +162,8 @@
     }
 
     @Override
-    public Object getLocationIdentity() {
-        return LocationNode.ANY_LOCATION;
+    public Object[] getLocationIdentities() {
+        return new Object[]{LocationNode.ANY_LOCATION};
     }
 
     public FrameState stateDuring() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ReturnNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ReturnNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -26,7 +26,7 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
-public final class ReturnNode extends FixedNode implements LIRLowerable, Node.IterableNodeType {
+public final class ReturnNode extends ControlSinkNode implements LIRLowerable, Node.IterableNodeType {
 
     @Input private ValueNode result;
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StartNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StartNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -30,7 +30,7 @@
 public class StartNode extends BeginStateSplitNode implements MemoryCheckpoint {
 
     @Override
-    public Object getLocationIdentity() {
-        return LocationNode.ANY_LOCATION;
+    public Object[] getLocationIdentities() {
+        return new Object[]{LocationNode.ANY_LOCATION};
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnwindNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnwindNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -31,7 +31,7 @@
  * Unwind takes an exception object, destroys the current stack frame and passes the exception
  * object to the system's exception dispatch code.
  */
-public final class UnwindNode extends FixedNode implements Lowerable, LIRLowerable, Node.IterableNodeType {
+public final class UnwindNode extends ControlSinkNode implements Lowerable, LIRLowerable, Node.IterableNodeType {
 
     @Input private ValueNode exception;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/DynamicCounterNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,120 @@
+/*
+ * 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.nodes.debug;
+
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+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.*;
+
+/**
+ * This node can be used to add a counter to the code that will estimate the dynamic number of calls
+ * by adding an increment to the compiled code. This should of course only be used for
+ * debugging/testing purposes, and is not 100% accurate (because of concurrency issues while
+ * accessing the counters).
+ * 
+ * A unique counter will be created for each unique String passed to the constructor.
+ */
+public class DynamicCounterNode extends FixedWithNextNode implements Lowerable {
+
+    private static final int MAX_COUNTERS = 10 * 1024;
+    private static final long[] COUNTERS = new long[MAX_COUNTERS];
+    private static final HashMap<String, Integer> INDEXES = new HashMap<>();
+    private final String name;
+    private final boolean addContext;
+
+    public DynamicCounterNode(String name, boolean addContext) {
+        super(StampFactory.forVoid());
+        this.name = name;
+        this.addContext = addContext;
+    }
+
+    private static synchronized int getIndex(String name) {
+        Integer index = INDEXES.get(name);
+        if (index == null) {
+            index = INDEXES.size();
+            if (index == 0) {
+                Runtime.getRuntime().addShutdownHook(new Thread() {
+
+                    @Override
+                    public void run() {
+                        dump();
+                    }
+                });
+            }
+            INDEXES.put(name, index);
+            if (index >= MAX_COUNTERS) {
+                throw new GraalInternalError("too many dynamic counters");
+            }
+            return index;
+        } else {
+            return index;
+        }
+    }
+
+    private static synchronized void dump() {
+        TreeMap<Long, String> sorted = new TreeMap<>();
+
+        long sum = 0;
+        for (int i = 0; i < MAX_COUNTERS; i++) {
+            sum += COUNTERS[i];
+        }
+        int cnt = 0;
+        for (Map.Entry<String, Integer> entry : INDEXES.entrySet()) {
+            sorted.put(COUNTERS[entry.getValue()] * MAX_COUNTERS + cnt++, entry.getKey());
+        }
+
+        for (Map.Entry<Long, String> entry : sorted.entrySet()) {
+            System.out.println((entry.getKey() / MAX_COUNTERS) + ": " + entry.getValue());
+        }
+        System.out.println(sum + ": total");
+
+    }
+
+    @Override
+    public void lower(LoweringTool tool) {
+        int index = addContext ? getIndex(name + " @ " + MetaUtil.format("%h.%n", ((StructuredGraph) graph()).method())) : getIndex(name);
+
+        StructuredGraph graph = (StructuredGraph) graph();
+        ConstantNode arrayConstant = ConstantNode.forObject(COUNTERS, tool.getRuntime(), graph);
+        ConstantNode indexConstant = ConstantNode.forInt(index, graph);
+        LoadIndexedNode load = graph.add(new LoadIndexedNode(arrayConstant, indexConstant, Kind.Long));
+        IntegerAddNode add = graph.add(new IntegerAddNode(Kind.Long, load, ConstantNode.forLong(1, graph)));
+        StoreIndexedNode store = graph.add(new StoreIndexedNode(arrayConstant, indexConstant, Kind.Long, add));
+
+        graph.addBeforeFixed(this, load);
+        graph.addBeforeFixed(this, store);
+        graph.removeFixed(this);
+    }
+
+    public static void createCounter(String name, FixedNode before, boolean addContext) {
+        StructuredGraph graph = (StructuredGraph) before.graph();
+        DynamicCounterNode counter = graph.add(new DynamicCounterNode(name, addContext));
+        graph.addBeforeFixed(before, counter);
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/Access.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/Access.java	Thu Mar 21 13:13:07 2013 +0100
@@ -29,7 +29,7 @@
 
     ValueNode object();
 
-    LocationNode location();
+    LocationNode nullCheckLocation();
 
     void setNullCheck(boolean check);
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AccessNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AccessNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -30,7 +30,8 @@
 
 /**
  * Accesses a value at an memory address specified by an {@linkplain #object object} and a
- * {@linkplain #location() location}. The access does not include a null check on the object.
+ * {@linkplain #nullCheckLocation() location}. The access does not include a null check on the
+ * object.
  */
 public abstract class AccessNode extends FixedWithNextNode implements Access {
 
@@ -46,6 +47,10 @@
         return (LocationNode) location;
     }
 
+    public LocationNode nullCheckLocation() {
+        return (LocationNode) location;
+    }
+
     public boolean getNullCheck() {
         return nullCheck;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -43,6 +43,10 @@
         return location;
     }
 
+    public LocationNode nullCheckLocation() {
+        return location;
+    }
+
     public boolean getNullCheck() {
         return nullCheck;
     }
@@ -73,4 +77,6 @@
     public Node node() {
         return this;
     }
+
+    public abstract Access asFixedNode();
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -58,6 +58,11 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
-        return ReadNode.canonicalizeRead(this, tool);
+        return ReadNode.canonicalizeRead(this, location(), object(), tool);
+    }
+
+    @Override
+    public Access asFixedNode() {
+        return graph().add(new ReadNode(object(), nullCheckLocation(), stamp(), dependencies()));
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -43,8 +43,8 @@
     }
 
     @Override
-    public Object getLocationIdentity() {
-        return LocationNode.ANY_LOCATION;
+    public Object[] getLocationIdentities() {
+        return new Object[]{LocationNode.ANY_LOCATION};
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryCheckpoint.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryCheckpoint.java	Thu Mar 21 13:13:07 2013 +0100
@@ -26,8 +26,8 @@
 
 /**
  * This interface marks is used for subclasses of {@link FixedNode} that kill a set of memory
- * locations represented by a location identity (i.e. change a value at one or more locations that
- * belong to this location identity).
+ * locations represented by location identities (i.e. change a value at one or more locations that
+ * belong to these location identities).
  */
 public interface MemoryCheckpoint {
 
@@ -35,8 +35,8 @@
      * This method is used to determine which set of memory locations is killed by this node.
      * Returning the special value {@link LocationNode#ANY_LOCATION} will kill all memory locations.
      * 
-     * @return the identity of the location killed by this node.
+     * @return the identities of all locations killed by this node.
      */
-    Object getLocationIdentity();
+    Object[] getLocationIdentities();
 
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/NullCheckNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,46 @@
+/*
+ * 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.nodes.extended;
+
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+public class NullCheckNode extends FixedWithNextNode implements LIRLowerable {
+
+    @Input public ValueNode object;
+
+    public NullCheckNode(ValueNode object) {
+        super(StampFactory.dependency());
+        this.object = object;
+    }
+
+    public ValueNode getObject() {
+        return object;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool generator) {
+        generator.emitNullCheck(object);
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -62,35 +62,35 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
-        return canonicalizeRead(this, tool);
+        return canonicalizeRead(this, location(), object(), tool);
     }
 
-    public static ValueNode canonicalizeRead(Access read, CanonicalizerTool tool) {
+    public static ValueNode canonicalizeRead(ValueNode read, LocationNode location, ValueNode object, CanonicalizerTool tool) {
         MetaAccessProvider runtime = tool.runtime();
-        if (runtime != null && read.object() != null && read.object().isConstant()) {
-            if (read.location().locationIdentity() == LocationNode.FINAL_LOCATION && read.location().getClass() == LocationNode.class) {
-                long displacement = read.location().displacement();
-                Kind kind = read.location().getValueKind();
-                if (read.object().kind() == Kind.Object) {
-                    Object base = read.object().asConstant().asObject();
+        if (runtime != null && object != null && object.isConstant()) {
+            if (location.locationIdentity() == LocationNode.FINAL_LOCATION && location.getClass() == LocationNode.class) {
+                long displacement = location.displacement();
+                Kind kind = location.getValueKind();
+                if (object.kind() == Kind.Object) {
+                    Object base = object.asConstant().asObject();
                     if (base != null) {
                         Constant constant = tool.runtime().readUnsafeConstant(kind, base, displacement);
                         if (constant != null) {
-                            return ConstantNode.forConstant(constant, runtime, read.node().graph());
+                            return ConstantNode.forConstant(constant, runtime, read.graph());
                         }
                     }
-                } else if (read.object().kind() == Kind.Long || read.object().kind().getStackKind() == Kind.Int) {
-                    long base = read.object().asConstant().asLong();
+                } else if (object.kind() == Kind.Long || object.kind().getStackKind() == Kind.Int) {
+                    long base = object.asConstant().asLong();
                     if (base != 0L) {
                         Constant constant = tool.runtime().readUnsafeConstant(kind, null, base + displacement);
                         if (constant != null) {
-                            return ConstantNode.forConstant(constant, runtime, read.node().graph());
+                            return ConstantNode.forConstant(constant, runtime, read.graph());
                         }
                     }
                 }
             }
         }
-        return (ValueNode) read;
+        return read;
     }
 
     /**
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/RuntimeCallNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/RuntimeCallNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -49,8 +49,8 @@
     }
 
     @Override
-    public Object getLocationIdentity() {
-        return LocationNode.ANY_LOCATION;
+    public Object[] getLocationIdentities() {
+        return new Object[]{LocationNode.ANY_LOCATION};
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -72,8 +72,8 @@
     }
 
     @Override
-    public Object getLocationIdentity() {
-        return LocationNode.ANY_LOCATION;
+    public Object[] getLocationIdentities() {
+        return new Object[]{LocationNode.ANY_LOCATION};
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteMemoryCheckpointNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteMemoryCheckpointNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -37,8 +37,8 @@
     }
 
     @Override
-    public Object getLocationIdentity() {
-        return LocationNode.ANY_LOCATION;
+    public Object[] getLocationIdentities() {
+        return new Object[]{LocationNode.ANY_LOCATION};
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -66,7 +66,7 @@
     public static native void writeMemory(Object object, Object value, Object location);
 
     @Override
-    public Object getLocationIdentity() {
-        return location().locationIdentity();
+    public Object[] getLocationIdentities() {
+        return new Object[]{location().locationIdentity()};
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -71,8 +71,8 @@
     }
 
     @Override
-    public Object getLocationIdentity() {
-        return LocationNode.ANY_LOCATION;
+    public Object[] getLocationIdentities() {
+        return new Object[]{LocationNode.ANY_LOCATION};
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -42,8 +42,8 @@
     }
 
     @Override
-    public Object getLocationIdentity() {
-        return LocationNode.ANY_LOCATION;
+    public Object[] getLocationIdentities() {
+        return new Object[]{LocationNode.ANY_LOCATION};
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -41,8 +41,8 @@
     }
 
     @Override
-    public Object getLocationIdentity() {
-        return LocationNode.ANY_LOCATION;
+    public Object[] getLocationIdentities() {
+        return new Object[]{LocationNode.ANY_LOCATION};
     }
 
     public void lower(LoweringTool tool) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -42,8 +42,8 @@
     }
 
     @Override
-    public Object getLocationIdentity() {
-        return LocationNode.ANY_LOCATION;
+    public Object[] getLocationIdentities() {
+        return new Object[]{LocationNode.ANY_LOCATION};
     }
 
     public void lower(LoweringTool tool) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -95,12 +95,12 @@
     public void virtualize(VirtualizerTool tool) {
         if (instanceClass != null) {
             assert !instanceClass().isArray();
-            ResolvedJavaField[] fields = instanceClass().getInstanceFields(true);
+            VirtualInstanceNode virtualObject = new VirtualInstanceNode(instanceClass());
+            ResolvedJavaField[] fields = virtualObject.getFields();
             ValueNode[] state = new ValueNode[fields.length];
             for (int i = 0; i < state.length; i++) {
                 state[i] = ConstantNode.defaultForKind(fields[i].getType().getKind(), graph());
             }
-            VirtualObjectNode virtualObject = new VirtualInstanceNode(instanceClass(), fields);
             tool.createVirtualObject(virtualObject, state, 0);
             tool.replaceWithVirtual(virtualObject);
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -32,7 +32,7 @@
  * This node is used to perform the finalizer registration at the end of the java.lang.Object
  * constructor.
  */
-public final class RegisterFinalizerNode extends AbstractStateSplit implements StateSplit, Canonicalizable, LIRLowerable {
+public final class RegisterFinalizerNode extends AbstractStateSplit implements StateSplit, Canonicalizable, LIRLowerable, Virtualizable {
 
     public static final Descriptor REGISTER_FINALIZER = new Descriptor("registerFinalizer", true, void.class, Object.class);
 
@@ -74,4 +74,12 @@
 
         return this;
     }
+
+    @Override
+    public void virtualize(VirtualizerTool tool) {
+        State state = tool.getObjectState(object);
+        if (state != null && !state.getVirtualObject().type().hasFinalizer()) {
+            tool.delete();
+        }
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java	Thu Mar 21 13:13:07 2013 +0100
@@ -99,6 +99,8 @@
 
     public abstract void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason);
 
+    public abstract void emitNullCheck(ValueNode v);
+
     public abstract Value emitCall(RuntimeCallTarget callTarget, CallingConvention cc, boolean canTrap, Value... args);
 
     public abstract void emitIf(IfNode i);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.nodes.virtual;
 
-import java.util.*;
-
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 
@@ -32,21 +30,10 @@
 
     private final ResolvedJavaType type;
     private final ResolvedJavaField[] fields;
-    private final HashMap<ResolvedJavaField, Integer> fieldMap;
 
-    public VirtualInstanceNode(ResolvedJavaType type, ResolvedJavaField[] fields) {
+    public VirtualInstanceNode(ResolvedJavaType type) {
         this.type = type;
-        this.fields = fields;
-        fieldMap = new HashMap<>();
-        for (int i = 0; i < fields.length; i++) {
-            fieldMap.put(fields[i], i);
-        }
-    }
-
-    private VirtualInstanceNode(ResolvedJavaType type, ResolvedJavaField[] fields, HashMap<ResolvedJavaField, Integer> fieldMap) {
-        this.type = type;
-        this.fields = fields;
-        this.fieldMap = fieldMap;
+        this.fields = type.getInstanceFields(true);
     }
 
     @Override
@@ -63,6 +50,10 @@
         return fields[index];
     }
 
+    public ResolvedJavaField[] getFields() {
+        return fields;
+    }
+
     @Override
     public String toString(Verbosity verbosity) {
         if (verbosity == Verbosity.Name) {
@@ -78,8 +69,13 @@
     }
 
     public int fieldIndex(ResolvedJavaField field) {
-        Integer index = fieldMap.get(field);
-        return index == null ? -1 : index;
+        // on average fields.length == ~6, so a linear search is fast enough
+        for (int i = 0; i < fields.length; i++) {
+            if (fields[i] == field) {
+                return i;
+            }
+        }
+        return -1;
     }
 
     @Override
@@ -95,6 +91,6 @@
 
     @Override
     public VirtualInstanceNode duplicate() {
-        return new VirtualInstanceNode(type, fields, fieldMap);
+        return new VirtualInstanceNode(type);
     }
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Thu Mar 21 13:13:07 2013 +0100
@@ -299,8 +299,18 @@
 
         public ConditionalElimination(FixedNode start, State initialState) {
             super(start, initialState);
-            this.trueConstant = LogicConstantNode.tautology(graph);
-            this.falseConstant = LogicConstantNode.contradiction(graph);
+            trueConstant = LogicConstantNode.tautology(graph);
+            falseConstant = LogicConstantNode.contradiction(graph);
+        }
+
+        @Override
+        public void finished() {
+            if (trueConstant.usages().isEmpty()) {
+                graph.removeFloating(trueConstant);
+            }
+            if (falseConstant.usages().isEmpty()) {
+                graph.removeFloating(falseConstant);
+            }
         }
 
         private void registerCondition(boolean isTrue, LogicNode condition, ValueNode anchor) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java	Thu Mar 21 13:13:07 2013 +0100
@@ -28,6 +28,7 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
 
 public class ConvertDeoptimizeToGuardPhase extends Phase {
@@ -50,6 +51,7 @@
         }
 
         for (DeoptimizeNode d : graph.getNodes(DeoptimizeNode.class)) {
+            assert d.isAlive();
             visitDeoptBegin(findBeginNode(d), d, graph);
         }
 
@@ -60,42 +62,53 @@
         if (deoptBegin instanceof MergeNode) {
             MergeNode mergeNode = (MergeNode) deoptBegin;
             Debug.log("Visiting %s followed by %s", mergeNode, deopt);
-            List<EndNode> ends = mergeNode.forwardEnds().snapshot();
-            for (EndNode end : ends) {
-                if (!end.isDeleted()) {
-                    BeginNode beginNode = findBeginNode(end);
-                    if (!(beginNode instanceof MergeNode)) {
-                        visitDeoptBegin(beginNode, deopt, graph);
-                    }
-                }
+            List<BeginNode> begins = new ArrayList<>();
+            for (EndNode end : mergeNode.forwardEnds()) {
+                BeginNode newBeginNode = findBeginNode(end);
+                assert !begins.contains(newBeginNode);
+                begins.add(newBeginNode);
             }
-            if (mergeNode.isDeleted()) {
-                if (!deopt.isDeleted()) {
-                    Debug.log("Merge deleted, deopt moved to %s", findBeginNode(deopt));
-                    visitDeoptBegin(findBeginNode(deopt), deopt, graph);
-                }
+            for (BeginNode begin : begins) {
+                assert !begin.isDeleted();
+                visitDeoptBegin(begin, deopt, graph);
             }
+            assert mergeNode.isDeleted();
+            return;
         } else if (deoptBegin.predecessor() instanceof IfNode) {
             IfNode ifNode = (IfNode) deoptBegin.predecessor();
             BeginNode otherBegin = ifNode.trueSuccessor();
             LogicNode conditionNode = ifNode.condition();
-            if (conditionNode instanceof InstanceOfNode || conditionNode instanceof InstanceOfDynamicNode) {
+            if (!(conditionNode instanceof InstanceOfNode) && !(conditionNode instanceof InstanceOfDynamicNode)) {
                 // TODO The lowering currently does not support a FixedGuard as the usage of an
                 // InstanceOfNode. Relax this restriction.
+                FixedGuardNode guard = graph.add(new FixedGuardNode(conditionNode, deopt.reason(), deopt.action(), deoptBegin == ifNode.trueSuccessor()));
+                FixedWithNextNode pred = (FixedWithNextNode) ifNode.predecessor();
+                if (deoptBegin == ifNode.trueSuccessor()) {
+                    graph.removeSplitPropagate(ifNode, ifNode.falseSuccessor());
+                } else {
+                    graph.removeSplitPropagate(ifNode, ifNode.trueSuccessor());
+                }
+                Debug.log("Converting %s on %-5s branch of %s to guard for remaining branch %s.", deopt, deoptBegin == ifNode.trueSuccessor() ? "true" : "false", ifNode, otherBegin);
+                FixedNode next = pred.next();
+                pred.setNext(guard);
+                guard.setNext(next);
                 return;
             }
-            FixedGuardNode guard = graph.add(new FixedGuardNode(conditionNode, deopt.reason(), deopt.action(), deoptBegin == ifNode.trueSuccessor()));
-            FixedWithNextNode pred = (FixedWithNextNode) ifNode.predecessor();
-            if (deoptBegin == ifNode.trueSuccessor()) {
-                graph.removeSplitPropagate(ifNode, ifNode.falseSuccessor());
-            } else {
-                graph.removeSplitPropagate(ifNode, ifNode.trueSuccessor());
-            }
-            Debug.log("Converting %s on %-5s branch of %s to guard for remaining branch %s.", deopt, deoptBegin == ifNode.trueSuccessor() ? "true" : "false", ifNode, otherBegin);
-            FixedNode next = pred.next();
-            pred.setNext(guard);
-            guard.setNext(next);
-            Debug.dump(graph, "After introducing fixed guard %s", guard);
+        }
+
+        // We could not convert the control split - at least cut off control flow after the split.
+        FixedWithNextNode deoptPred = deoptBegin;
+        FixedNode next = deoptPred.next();
+        if (next instanceof ExceptionObjectNode) {
+            deoptPred = (FixedWithNextNode) next;
+            next = deoptPred.next();
+        }
+
+        if (next != deopt) {
+            DeoptimizeNode newDeoptNode = (DeoptimizeNode) deopt.clone(graph);
+            deoptPred.setNext(newDeoptNode);
+            assert deoptPred == newDeoptNode.predecessor();
+            GraphUtil.killCFG(next);
         }
     }
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java	Thu Mar 21 13:13:07 2013 +0100
@@ -84,7 +84,9 @@
         @Override
         protected void processNode(FixedNode node, Set<Object> currentState) {
             if (node instanceof MemoryCheckpoint) {
-                currentState.add(((MemoryCheckpoint) node).getLocationIdentity());
+                for (Object identity : ((MemoryCheckpoint) node).getLocationIdentities()) {
+                    currentState.add(identity);
+                }
             }
         }
 
@@ -132,10 +134,12 @@
         }
 
         private void processCheckpoint(MemoryCheckpoint checkpoint, MemoryMap state) {
-            if (checkpoint.getLocationIdentity() == LocationNode.ANY_LOCATION) {
-                state.lastMemorySnapshot.clear();
+            for (Object identity : checkpoint.getLocationIdentities()) {
+                if (identity == LocationNode.ANY_LOCATION) {
+                    state.lastMemorySnapshot.clear();
+                }
+                state.lastMemorySnapshot.put(identity, (ValueNode) checkpoint);
             }
-            state.lastMemorySnapshot.put(checkpoint.getLocationIdentity(), (ValueNode) checkpoint);
         }
 
         private void processRead(ReadNode readNode, MemoryMap state) {
@@ -200,7 +204,21 @@
 
         @Override
         protected MemoryMap afterSplit(BeginNode node, MemoryMap oldState) {
-            return new MemoryMap(oldState);
+            MemoryMap result = new MemoryMap(oldState);
+            if (node.predecessor() instanceof InvokeWithExceptionNode) {
+                /*
+                 * InvokeWithException cannot be the lastLocationAccess for a FloatingReadNode.
+                 * Since it is both the invoke and a control flow split, the scheduler cannot
+                 * schedule anything immediately the invoke. It can only schedule in the normal or
+                 * exceptional successor - and we have to tell the scheduler here which side it
+                 * needs to choose by putting in the location identity on both successors.
+                 */
+                InvokeWithExceptionNode checkpoint = (InvokeWithExceptionNode) node.predecessor();
+                for (Object identity : checkpoint.getLocationIdentities()) {
+                    result.lastMemorySnapshot.put(identity, node);
+                }
+            }
+            return result;
         }
 
         @Override
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Thu Mar 21 13:13:07 2013 +0100
@@ -37,114 +37,60 @@
 
 public class GuardLoweringPhase extends Phase {
 
-    private TargetDescription target;
+    private abstract static class ScheduledNodeIterator {
 
-    public GuardLoweringPhase(TargetDescription target) {
-        this.target = target;
-    }
+        private FixedWithNextNode lastFixed;
+        private FixedWithNextNode reconnect;
+        private ListIterator<ScheduledNode> iterator;
 
-    @Override
-    protected void run(StructuredGraph graph) {
-        SchedulePhase schedule = new SchedulePhase();
-        schedule.apply(graph);
+        public void processNodes(List<ScheduledNode> nodes, FixedWithNextNode begin) {
+            assert begin != null;
+            lastFixed = begin;
+            reconnect = null;
+            iterator = nodes.listIterator();
+            while (iterator.hasNext()) {
+                Node node = iterator.next();
+                if (!node.isAlive()) {
+                    continue;
+                }
+                if (reconnect != null && node instanceof FixedNode) {
+                    reconnect.setNext((FixedNode) node);
+                    reconnect = null;
+                }
+                if (node instanceof FixedWithNextNode) {
+                    lastFixed = (FixedWithNextNode) node;
+                }
+                processNode(node);
+            }
+        }
 
-        for (Block block : schedule.getCFG().getBlocks()) {
-            processBlock(block, schedule, graph, target);
+        protected void insert(FixedNode start, FixedWithNextNode end) {
+            this.lastFixed.setNext(start);
+            this.lastFixed = end;
+            this.reconnect = end;
         }
+
+        protected void replaceCurrent(FixedWithNextNode newNode) {
+            Node current = iterator.previous();
+            iterator.next(); // needed because of the previous() call
+            current.replaceAndDelete(newNode);
+            insert(newNode, newNode);
+            iterator.set(newNode);
+        }
+
+        protected abstract void processNode(Node node);
     }
 
-    private static void processBlock(Block block, SchedulePhase schedule, StructuredGraph graph, TargetDescription target) {
-        List<ScheduledNode> nodes = schedule.nodesFor(block);
-        if (GraalOptions.OptImplicitNullChecks && target.implicitNullCheckLimit > 0) {
-            useImplicitNullChecks(block.getBeginNode(), nodes, graph, target);
-        }
-        FixedWithNextNode lastFixed = block.getBeginNode();
-        BeginNode lastFastPath = null;
-        for (Node node : nodes) {
-            if (!node.isAlive()) {
-                continue;
-            }
-            if (lastFastPath != null && node instanceof FixedNode) {
-                lastFastPath.setNext((FixedNode) node);
-                lastFastPath = null;
-            }
-            if (node instanceof FixedWithNextNode) {
-                lastFixed = (FixedWithNextNode) node;
-            } else if (node instanceof GuardNode) {
-                GuardNode guard = (GuardNode) node;
-                BeginNode fastPath = graph.add(new BeginNode());
-                BeginNode trueSuccessor;
-                BeginNode falseSuccessor;
-                DeoptimizeNode deopt = graph.add(new DeoptimizeNode(guard.action(), guard.reason()));
-                BeginNode deoptBranch = BeginNode.begin(deopt);
-                Loop loop = block.getLoop();
-                while (loop != null) {
-                    LoopExitNode exit = graph.add(new LoopExitNode(loop.loopBegin()));
-                    graph.addBeforeFixed(deopt, exit);
-                    loop = loop.parent;
-                }
-                if (guard.negated()) {
-                    trueSuccessor = deoptBranch;
-                    falseSuccessor = fastPath;
-                } else {
-                    trueSuccessor = fastPath;
-                    falseSuccessor = deoptBranch;
-                }
-                IfNode ifNode = graph.add(new IfNode(guard.condition(), trueSuccessor, falseSuccessor, trueSuccessor == fastPath ? 1 : 0));
-                guard.replaceAndDelete(fastPath);
-                lastFixed.setNext(ifNode);
-                lastFixed = fastPath;
-                lastFastPath = fastPath;
-            }
-        }
-    }
+    private class UseImplicitNullChecks extends ScheduledNodeIterator {
+
+        private final IdentityHashMap<ValueNode, GuardNode> nullGuarded = new IdentityHashMap<>();
 
-    private static void useImplicitNullChecks(BeginNode begin, List<ScheduledNode> nodes, StructuredGraph graph, TargetDescription target) {
-        ListIterator<ScheduledNode> iterator = nodes.listIterator();
-        IdentityHashMap<ValueNode, GuardNode> nullGuarded = new IdentityHashMap<>();
-        FixedWithNextNode lastFixed = begin;
-        FixedWithNextNode reconnect = null;
-        while (iterator.hasNext()) {
-            Node node = iterator.next();
-
-            if (reconnect != null && node instanceof FixedNode) {
-                reconnect.setNext((FixedNode) node);
-                reconnect = null;
-            }
-            if (node instanceof FixedWithNextNode) {
-                lastFixed = (FixedWithNextNode) node;
-            }
-
+        @Override
+        protected void processNode(Node node) {
             if (node instanceof GuardNode) {
-                GuardNode guard = (GuardNode) node;
-                if (guard.negated() && guard.condition() instanceof IsNullNode) {
-                    ValueNode obj = ((IsNullNode) guard.condition()).object();
-                    nullGuarded.put(obj, guard);
-                }
+                processGuard(node);
             } else if (node instanceof Access) {
-                Access access = (Access) node;
-                GuardNode guard = nullGuarded.get(access.object());
-                if (guard != null && isImplicitNullCheck(access.location(), target)) {
-                    NodeInputList<ValueNode> dependencies = ((ValueNode) access).dependencies();
-                    dependencies.remove(guard);
-                    if (access instanceof FloatingReadNode) {
-                        ReadNode read = graph.add(new ReadNode(access.object(), access.location(), ((FloatingReadNode) access).stamp(), dependencies));
-                        node.replaceAndDelete(read);
-                        access = read;
-                        lastFixed.setNext(read);
-                        lastFixed = read;
-                        reconnect = read;
-                        iterator.set(read);
-                    }
-                    assert access instanceof AccessNode;
-                    access.setNullCheck(true);
-                    LogicNode condition = guard.condition();
-                    guard.replaceAndDelete(access.node());
-                    if (condition.usages().isEmpty()) {
-                        GraphUtil.killWithUnusedFloatingInputs(condition);
-                    }
-                    nullGuarded.remove(access.object());
-                }
+                processAccess((Access) node);
             }
             if (node instanceof StateSplit && ((StateSplit) node).stateAfter() != null) {
                 nullGuarded.clear();
@@ -159,9 +105,119 @@
                 }
             }
         }
+
+        private void processAccess(Access access) {
+            GuardNode guard = nullGuarded.get(access.object());
+            if (guard != null && isImplicitNullCheck(access.nullCheckLocation())) {
+                NodeInputList<ValueNode> dependencies = ((ValueNode) access).dependencies();
+                dependencies.remove(guard);
+                Access fixedAccess = access;
+                if (access instanceof FloatingAccessNode) {
+                    fixedAccess = ((FloatingAccessNode) access).asFixedNode();
+                    replaceCurrent((FixedWithNextNode) fixedAccess.node());
+                }
+                assert fixedAccess instanceof FixedNode;
+                fixedAccess.setNullCheck(true);
+                LogicNode condition = guard.condition();
+                guard.replaceAndDelete(fixedAccess.node());
+                if (condition.usages().isEmpty()) {
+                    GraphUtil.killWithUnusedFloatingInputs(condition);
+                }
+                nullGuarded.remove(fixedAccess.object());
+            }
+        }
+
+        private void processGuard(Node node) {
+            GuardNode guard = (GuardNode) node;
+            if (guard.negated() && guard.condition() instanceof IsNullNode) {
+                ValueNode obj = ((IsNullNode) guard.condition()).object();
+                nullGuarded.put(obj, guard);
+            }
+        }
     }
 
-    private static boolean isImplicitNullCheck(LocationNode location, TargetDescription target) {
+    private class LowerGuards extends ScheduledNodeIterator {
+
+        private final Block block;
+
+        public LowerGuards(Block block) {
+            this.block = block;
+        }
+
+        @Override
+        protected void processNode(Node node) {
+            if (node instanceof GuardNode) {
+                GuardNode guard = (GuardNode) node;
+                if (guard.negated() && guard.condition() instanceof IsNullNode) {
+                    lowerToNullCheck(guard);
+                } else {
+                    lowerToIf(guard);
+                }
+            }
+        }
+
+        private void lowerToIf(GuardNode guard) {
+            StructuredGraph graph = (StructuredGraph) guard.graph();
+            BeginNode fastPath = graph.add(new BeginNode());
+            DeoptimizeNode deopt = graph.add(new DeoptimizeNode(guard.action(), guard.reason()));
+            BeginNode deoptBranch = BeginNode.begin(deopt);
+            BeginNode trueSuccessor;
+            BeginNode falseSuccessor;
+            insertLoopExits(deopt);
+            if (guard.negated()) {
+                trueSuccessor = deoptBranch;
+                falseSuccessor = fastPath;
+            } else {
+                trueSuccessor = fastPath;
+                falseSuccessor = deoptBranch;
+            }
+            IfNode ifNode = graph.add(new IfNode(guard.condition(), trueSuccessor, falseSuccessor, trueSuccessor == fastPath ? 1 : 0));
+            guard.replaceAndDelete(fastPath);
+            insert(ifNode, fastPath);
+        }
+
+        private void lowerToNullCheck(GuardNode guard) {
+            IsNullNode isNull = (IsNullNode) guard.condition();
+            NullCheckNode nullCheck = guard.graph().add(new NullCheckNode(isNull.object()));
+            replaceCurrent(nullCheck);
+        }
+
+        private void insertLoopExits(DeoptimizeNode deopt) {
+            Loop loop = block.getLoop();
+            StructuredGraph graph = (StructuredGraph) deopt.graph();
+            while (loop != null) {
+                LoopExitNode exit = graph.add(new LoopExitNode(loop.loopBegin()));
+                graph.addBeforeFixed(deopt, exit);
+                loop = loop.parent;
+            }
+        }
+    }
+
+    private TargetDescription target;
+
+    public GuardLoweringPhase(TargetDescription target) {
+        this.target = target;
+    }
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        SchedulePhase schedule = new SchedulePhase();
+        schedule.apply(graph);
+
+        for (Block block : schedule.getCFG().getBlocks()) {
+            processBlock(block, schedule);
+        }
+    }
+
+    private void processBlock(Block block, SchedulePhase schedule) {
+        List<ScheduledNode> nodes = schedule.nodesFor(block);
+        if (GraalOptions.OptImplicitNullChecks && target.implicitNullCheckLimit > 0) {
+            new UseImplicitNullChecks().processNodes(nodes, block.getBeginNode());
+        }
+        new LowerGuards(block).processNodes(nodes, block.getBeginNode());
+    }
+
+    private boolean isImplicitNullCheck(LocationNode location) {
         return !(location instanceof IndexedLocationNode) && location.displacement() < target.implicitNullCheckLimit;
     }
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Thu Mar 21 13:13:07 2013 +0100
@@ -443,11 +443,7 @@
                     queueSuccessors(current);
                 } else if (current instanceof EndNode) {
                     queueMerge((EndNode) current);
-                } else if (current instanceof DeoptimizeNode) {
-                    // nothing todo
-                } else if (current instanceof ReturnNode) {
-                    // nothing todo
-                } else if (current instanceof UnwindNode) {
+                } else if (current instanceof ControlSinkNode) {
                     // nothing todo
                 } else if (current instanceof ControlSplitNode) {
                     queueSuccessors(current);
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Thu Mar 21 13:13:07 2013 +0100
@@ -105,7 +105,6 @@
     public static int     LoopUnswitchUncertaintyBoost       = 5;
 
     // debugging settings
-    public static int     MethodEndBreakpointGuards          = 2;
     public static boolean ZapStackOnMethodEntry              = ____;
     public static boolean DeoptALot                          = ____;
     public static boolean VerifyPhases                       = true;
@@ -114,7 +113,7 @@
 
     // Debug settings:
     public static boolean Debug                              = true;
-    public static boolean DebugSnippets                      = false;
+    public static boolean DebugReplacements                      = false;
     public static boolean PerThreadDebugValues               = ____;
     public static boolean SummarizeDebugValues               = ____;
     public static boolean SummarizePerPhase                  = ____;
@@ -212,12 +211,6 @@
     public static boolean IntrinsifyAESMethods               = true;
 
     /**
-     * Method arguments that are passed on the stack can be optimized by the register allocator to avoid spilling 
-     * and reloading. However, this requires that the runtime visits method arguments during stack walking.  
-     */
-    public static boolean IncomingMethodArgumentsGCSafe      = true;
-
-    /**
      * Counts the various paths taken through snippets.
      */
     public static boolean SnippetCounters = false;
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/PostOrderNodeIterator.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/PostOrderNodeIterator.java	Thu Mar 21 13:13:07 2013 +0100
@@ -89,14 +89,8 @@
                 end((EndNode) current);
                 queueMerge((EndNode) current);
                 current = nextQueuedNode();
-            } else if (current instanceof DeoptimizeNode) {
-                deoptimize((DeoptimizeNode) current);
-                current = nextQueuedNode();
-            } else if (current instanceof ReturnNode) {
-                returnNode((ReturnNode) current);
-                current = nextQueuedNode();
-            } else if (current instanceof UnwindNode) {
-                unwind((UnwindNode) current);
+            } else if (current instanceof ControlSinkNode) {
+                node(current);
                 current = nextQueuedNode();
             } else if (current instanceof ControlSplitNode) {
                 Set<Node> successors = controlSplit((ControlSplitNode) current);
@@ -106,6 +100,7 @@
                 assert false : current;
             }
         } while (current != null);
+        finished();
     }
 
     private void queueSuccessors(FixedNode x, Set<Node> successors) {
@@ -216,24 +211,16 @@
         node(loopEnd);
     }
 
-    protected void deoptimize(DeoptimizeNode deoptimize) {
-        node(deoptimize);
-    }
-
     protected Set<Node> controlSplit(ControlSplitNode controlSplit) {
         node(controlSplit);
         return null;
     }
 
-    protected void returnNode(ReturnNode returnNode) {
-        node(returnNode);
-    }
-
     protected void invoke(Invoke invoke) {
         node(invoke.node());
     }
 
-    protected void unwind(UnwindNode unwind) {
-        node(unwind);
+    protected void finished() {
+        // nothing to do
     }
 }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ScopedPostOrderNodeIterator.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ScopedPostOrderNodeIterator.java	Thu Mar 21 13:13:07 2013 +0100
@@ -73,11 +73,7 @@
                 queueSuccessors(current);
             } else if (current instanceof EndNode) {
                 queueMerge((EndNode) current);
-            } else if (current instanceof DeoptimizeNode) {
-                // nothing todo
-            } else if (current instanceof ReturnNode) {
-                // nothing todo
-            } else if (current instanceof UnwindNode) {
+            } else if (current instanceof ControlSinkNode) {
                 // nothing todo
             } else if (current instanceof ControlSplitNode) {
                 queueSuccessors(current);
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Thu Mar 21 13:13:07 2013 +0100
@@ -64,12 +64,13 @@
                 if (node instanceof FloatingReadNode) {
                     currentState.add((FloatingReadNode) node);
                 } else if (node instanceof MemoryCheckpoint) {
-                    Object identity = ((MemoryCheckpoint) node).getLocationIdentity();
-                    for (Iterator<FloatingReadNode> iter = currentState.iterator(); iter.hasNext();) {
-                        FloatingReadNode read = iter.next();
-                        FixedNode fixed = (FixedNode) node;
-                        if (identity == LocationNode.ANY_LOCATION || read.location().locationIdentity() == identity) {
-                            addPhantomReference(read, fixed);
+                    for (Object identity : ((MemoryCheckpoint) node).getLocationIdentities()) {
+                        for (Iterator<FloatingReadNode> iter = currentState.iterator(); iter.hasNext();) {
+                            FloatingReadNode read = iter.next();
+                            FixedNode fixed = (FixedNode) node;
+                            if (identity == LocationNode.ANY_LOCATION || read.location().locationIdentity() == identity) {
+                                addPhantomReference(read, fixed);
+                            }
                         }
                     }
                 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,193 @@
+/*
+ * 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.replacements.amd64;
+
+import static com.oracle.graal.replacements.SnippetTemplate.*;
+import static com.oracle.graal.replacements.SnippetTemplate.Arguments.*;
+import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.calc.ConvertNode.Op;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.replacements.*;
+import com.oracle.graal.replacements.Snippet.*;
+
+/**
+ * Snippets used for conversion operations on AMD64 where the AMD64 instruction used does not match
+ * the semantics of the JVM specification.
+ */
+public class AMD64ConvertSnippets implements Snippets {
+
+    /**
+     * Converts a float to an int.
+     * <p>
+     * This snippet accounts for the semantics of the x64 CVTTSS2SI instruction used to do the
+     * conversion. If the float value is a NaN, infinity or if the result of the conversion is
+     * larger than {@link Integer#MAX_VALUE} then CVTTSS2SI returns {@link Integer#MIN_VALUE} and
+     * extra tests are required on the float value to return the correct int value.
+     * 
+     * @param input the float being converted
+     * @param result the result produced by the CVTTSS2SI instruction
+     */
+    @Snippet
+    public static int f2i(@Parameter("input") float input, @Parameter("result") int result) {
+        if (result == Integer.MIN_VALUE) {
+            probability(NOT_FREQUENT_PROBABILITY);
+            if (Float.isNaN(input)) {
+                // input is NaN -> return 0
+                return 0;
+            } else if (input > 0.0f) {
+                // input is > 0 -> return max int
+                return Integer.MAX_VALUE;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Converts a float to a long.
+     * <p>
+     * This snippet accounts for the semantics of the x64 CVTTSS2SI instruction used to do the
+     * conversion. If the float value is a NaN or infinity then CVTTSS2SI returns
+     * {@link Long#MIN_VALUE} and extra tests are required on the float value to return the correct
+     * long value.
+     * 
+     * @param input the float being converted
+     * @param result the result produced by the CVTTSS2SI instruction
+     */
+    @Snippet
+    public static long f2l(@Parameter("input") float input, @Parameter("result") long result) {
+        if (result == Long.MIN_VALUE) {
+            probability(NOT_FREQUENT_PROBABILITY);
+            if (Float.isNaN(input)) {
+                // input is NaN -> return 0
+                return 0;
+            } else if (input > 0.0f) {
+                // input is > 0 -> return max int
+                return Long.MAX_VALUE;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Converts a double to an int.
+     * <p>
+     * This snippet accounts for the semantics of the x64 CVTTSD2SI instruction used to do the
+     * conversion. If the double value is a NaN, infinity or if the result of the conversion is
+     * larger than {@link Integer#MAX_VALUE} then CVTTSD2SI returns {@link Integer#MIN_VALUE} and
+     * extra tests are required on the double value to return the correct int value.
+     * 
+     * @param input the double being converted
+     * @param result the result produced by the CVTTSS2SI instruction
+     */
+    @Snippet
+    public static int d2i(@Parameter("input") double input, @Parameter("result") int result) {
+        if (result == Integer.MIN_VALUE) {
+            probability(NOT_FREQUENT_PROBABILITY);
+            if (Double.isNaN(input)) {
+                // input is NaN -> return 0
+                return 0;
+            } else if (input > 0.0d) {
+                // input is positive -> return maxInt
+                return Integer.MAX_VALUE;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Converts a double to a long.
+     * <p>
+     * This snippet accounts for the semantics of the x64 CVTTSD2SI instruction used to do the
+     * conversion. If the double value is a NaN, infinity or if the result of the conversion is
+     * larger than {@link Long#MAX_VALUE} then CVTTSD2SI returns {@link Long#MIN_VALUE} and extra
+     * tests are required on the double value to return the correct long value.
+     * 
+     * @param input the double being converted
+     * @param result the result produced by the CVTTSS2SI instruction
+     */
+    @Snippet
+    public static long d2l(@Parameter("input") double input, @Parameter("result") long result) {
+        if (result == Long.MIN_VALUE) {
+            probability(NOT_FREQUENT_PROBABILITY);
+            if (Double.isNaN(input)) {
+                // input is NaN -> return 0
+                return 0;
+            } else if (input > 0.0d) {
+                // input is positive -> return maxInt
+                return Long.MAX_VALUE;
+            }
+        }
+        return result;
+    }
+
+    public static class Templates extends AbstractTemplates<AMD64ConvertSnippets> {
+
+        private final ResolvedJavaMethod f2i;
+        private final ResolvedJavaMethod f2l;
+        private final ResolvedJavaMethod d2i;
+        private final ResolvedJavaMethod d2l;
+
+        public Templates(CodeCacheProvider runtime, Assumptions assumptions, TargetDescription target) {
+            super(runtime, assumptions, target, AMD64ConvertSnippets.class);
+            f2i = snippet("f2i", float.class, int.class);
+            f2l = snippet("f2l", float.class, long.class);
+            d2i = snippet("d2i", double.class, int.class);
+            d2l = snippet("d2l", double.class, long.class);
+        }
+
+        public void lower(ConvertNode convert, LoweringTool tool) {
+            if (convert.opcode == Op.F2I) {
+                lower0(convert, tool, f2i);
+            } else if (convert.opcode == Op.F2L) {
+                lower0(convert, tool, f2l);
+            } else if (convert.opcode == Op.D2I) {
+                lower0(convert, tool, d2i);
+            } else if (convert.opcode == Op.D2L) {
+                lower0(convert, tool, d2l);
+            }
+        }
+
+        private void lower0(ConvertNode convert, LoweringTool tool, ResolvedJavaMethod snippet) {
+            StructuredGraph graph = (StructuredGraph) convert.graph();
+
+            // Insert a unique placeholder node in place of the Convert node so that the
+            // Convert node can be used as an input to the snippet. All usage of the
+            // Convert node are replaced by the placeholder which in turn is replaced by the
+            // snippet.
+
+            LocalNode replacee = graph.add(new LocalNode(Integer.MAX_VALUE, convert.stamp()));
+            convert.replaceAtUsages(replacee);
+            Key key = new Key(snippet);
+            Arguments arguments = arguments("input", convert.value()).add("result", convert);
+            SnippetTemplate template = cache.get(key, assumptions);
+            Debug.log("Lowering %s in %s: node=%s, template=%s, arguments=%s", convert.opcode, graph, convert, template, arguments);
+            template.instantiate(runtime, replacee, DEFAULT_REPLACER, tool, arguments);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements.test/overview.html	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+This code is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 2 only, as
+published by the Free Software Foundation.  Oracle designates this
+particular file as subject to the "Classpath" exception as provided
+by Oracle in the LICENSE file that accompanied this code.
+
+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.
+-->
+
+</head>
+<body>
+
+Documentation for the <code>com.oracle.graal.snippets.test</code> project.
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/CheckCastTest.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2011, 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.replacements;
+
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.test.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+
+/**
+ * Tests the implementation of checkcast, allowing profiling information to be manually specified.
+ */
+public class CheckCastTest extends TypeCheckTest {
+
+    @Override
+    protected void replaceProfile(StructuredGraph graph, JavaTypeProfile profile) {
+        CheckCastNode ccn = graph.getNodes(CheckCastNode.class).first();
+        if (ccn != null) {
+            CheckCastNode ccnNew = graph.add(new CheckCastNode(ccn.type(), ccn.object(), profile));
+            graph.replaceFixedWithFixed(ccn, ccnNew);
+        }
+    }
+
+    @LongTest
+    public void test1() {
+        test("asNumber", profile(), 111);
+        test("asNumber", profile(Integer.class), 111);
+        test("asNumber", profile(Long.class, Short.class), 111);
+        test("asNumberExt", profile(), 111);
+        test("asNumberExt", profile(Integer.class), 111);
+        test("asNumberExt", profile(Long.class, Short.class), 111);
+    }
+
+    @LongTest
+    public void test2() {
+        test("asString", profile(), "111");
+        test("asString", profile(String.class), "111");
+        test("asString", profile(String.class), "111");
+
+        final String nullString = null;
+        test("asString", profile(), nullString);
+        test("asString", profile(String.class), nullString);
+        test("asString", profile(String.class), nullString);
+
+        test("asStringExt", profile(), "111");
+        test("asStringExt", profile(String.class), "111");
+        test("asStringExt", profile(String.class), "111");
+    }
+
+    @LongTest
+    public void test3() {
+        test("asNumber", profile(), "111");
+    }
+
+    @LongTest
+    public void test4() {
+        test("asString", profile(String.class), 111);
+    }
+
+    @LongTest
+    public void test5() {
+        test("asNumberExt", profile(), "111");
+    }
+
+    @LongTest
+    public void test6() {
+        test("asStringExt", profile(String.class), 111);
+    }
+
+    @LongTest
+    public void test7() {
+        Throwable throwable = new Exception();
+        test("asThrowable", profile(), throwable);
+        test("asThrowable", profile(Throwable.class), throwable);
+        test("asThrowable", profile(Exception.class, Error.class), throwable);
+    }
+
+    @LongTest
+    public void test8() {
+        test("arrayStore", new Object[100], "111");
+    }
+
+    @LongTest
+    public void test8_1() {
+        test("arrayFill", new Object[100], "111");
+    }
+
+    public static Number asNumber(Object o) {
+        return (Number) o;
+    }
+
+    public static String asString(Object o) {
+        return (String) o;
+    }
+
+    public static Throwable asThrowable(Object o) {
+        return (Throwable) o;
+    }
+
+    public static ValueNode asValueNode(Object o) {
+        return (ValueNode) o;
+    }
+
+    public static Number asNumberExt(Object o) {
+        Number n = (Number) o;
+        return n.intValue() + 10;
+    }
+
+    public static String asStringExt(Object o) {
+        String s = (String) o;
+        return "#" + s;
+    }
+
+    public static Object[] arrayStore(Object[] arr, Object value) {
+        arr[15] = value;
+        return arr;
+    }
+
+    public static Object[] arrayFill(Object[] arr, Object value) {
+        for (int i = 0; i < arr.length; i++) {
+            arr[i] = value;
+        }
+        return arr;
+    }
+
+    static class Depth1 implements Cloneable {
+    }
+
+    static class Depth2 extends Depth1 {
+    }
+
+    static class Depth3 extends Depth2 {
+    }
+
+    static class Depth4 extends Depth3 {
+    }
+
+    static class Depth5 extends Depth4 {
+    }
+
+    static class Depth6 extends Depth5 {
+    }
+
+    static class Depth7 extends Depth6 {
+    }
+
+    static class Depth8 extends Depth7 {
+    }
+
+    static class Depth9 extends Depth8 {
+    }
+
+    static class Depth10 extends Depth9 {
+    }
+
+    static class Depth11 extends Depth10 {
+    }
+
+    static class Depth12 extends Depth11 {
+    }
+
+    static class Depth13 extends Depth12 {
+    }
+
+    static class Depth14 extends Depth12 {
+    }
+
+    public static Depth12 asDepth12(Object o) {
+        return (Depth12) o;
+    }
+
+    public static Depth12[][] asDepth12Arr(Object o) {
+        return (Depth12[][]) o;
+    }
+
+    public static Cloneable asCloneable(Object o) {
+        return (Cloneable) o;
+    }
+
+    @LongTest
+    public void test9() {
+        Object o = new Depth13();
+        test("asDepth12", profile(), o);
+        test("asDepth12", profile(Depth13.class), o);
+        test("asDepth12", profile(Depth13.class, Depth14.class), o);
+    }
+
+    @LongTest
+    public void test10() {
+        Object o = new Depth13[3][];
+        test("asDepth12Arr", o);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/InstanceOfDynamicTest.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2011, 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.replacements;
+
+import com.oracle.graal.test.*;
+import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.nodes.java.*;
+
+/**
+ * Tests for {@link InstanceOfDynamicNode}.
+ */
+public class InstanceOfDynamicTest extends GraalCompilerTest {
+
+    public static int id(int value) {
+        return value;
+    }
+
+    @LongTest
+    public void test100() {
+        final Object nul = null;
+        test("isStringDynamic", nul);
+        test("isStringDynamic", "object");
+        test("isStringDynamic", Object.class);
+    }
+
+    @LongTest
+    public void test101() {
+        final Object nul = null;
+        test("isStringIntDynamic", nul);
+        test("isStringIntDynamic", "object");
+        test("isStringIntDynamic", Object.class);
+    }
+
+    @LongTest
+    public void test103() {
+        test("isInstanceDynamic", String.class, null);
+        test("isInstanceDynamic", String.class, "object");
+        test("isInstanceDynamic", String.class, Object.class);
+        test("isInstanceDynamic", int.class, null);
+        test("isInstanceDynamic", int.class, "Object");
+        test("isInstanceDynamic", int.class, Object.class);
+    }
+
+    @LongTest
+    public void test104() {
+        test("isInstanceIntDynamic", String.class, null);
+        test("isInstanceIntDynamic", String.class, "object");
+        test("isInstanceIntDynamic", String.class, Object.class);
+        test("isInstanceIntDynamic", int.class, null);
+        test("isInstanceIntDynamic", int.class, "Object");
+        test("isInstanceIntDynamic", int.class, Object.class);
+    }
+
+    public static boolean isStringDynamic(Object o) {
+        return String.class.isInstance(o);
+    }
+
+    public static int isStringIntDynamic(Object o) {
+        if (String.class.isInstance(o)) {
+            return o.toString().length();
+        }
+        return o.getClass().getName().length();
+    }
+
+    public static boolean isInstanceDynamic(Class c, Object o) {
+        return c.isInstance(o);
+    }
+
+    public static int isInstanceIntDynamic(Class c, Object o) {
+        if (c.isInstance(o)) {
+            return o.toString().length();
+        }
+        return o.getClass().getName().length();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/InstanceOfTest.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,398 @@
+/*
+ * Copyright (c) 2011, 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.replacements;
+
+import java.util.*;
+
+
+import com.oracle.graal.api.code.CompilationResult.Call;
+import com.oracle.graal.api.code.CompilationResult.Mark;
+import com.oracle.graal.api.code.CompilationResult.Site;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.test.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.common.*;
+import com.oracle.graal.replacements.CheckCastTest.*;
+
+/**
+ * Tests the implementation of instanceof, allowing profiling information to be manually specified.
+ */
+public class InstanceOfTest extends TypeCheckTest {
+
+    @Override
+    protected void editPhasePlan(ResolvedJavaMethod method, StructuredGraph graph, PhasePlan phasePlan) {
+        phasePlan.disablePhase(InliningPhase.class);
+    }
+
+    @Override
+    protected void replaceProfile(StructuredGraph graph, JavaTypeProfile profile) {
+        InstanceOfNode ion = graph.getNodes().filter(InstanceOfNode.class).first();
+        if (ion != null) {
+            InstanceOfNode ionNew = graph.add(new InstanceOfNode(ion.type(), ion.object(), profile));
+            graph.replaceFloating(ion, ionNew);
+        }
+    }
+
+    @LongTest
+    public void test1() {
+        test("isString", profile(), "object");
+        test("isString", profile(String.class), "object");
+
+        test("isString", profile(), Object.class);
+        test("isString", profile(String.class), Object.class);
+    }
+
+    @LongTest
+    public void test2() {
+        test("isStringInt", profile(), "object");
+        test("isStringInt", profile(String.class), "object");
+
+        test("isStringInt", profile(), Object.class);
+        test("isStringInt", profile(String.class), Object.class);
+    }
+
+    @LongTest
+    public void test2_1() {
+        test("isStringIntComplex", profile(), "object");
+        test("isStringIntComplex", profile(String.class), "object");
+
+        test("isStringIntComplex", profile(), Object.class);
+        test("isStringIntComplex", profile(String.class), Object.class);
+    }
+
+    @LongTest
+    public void test3() {
+        Throwable throwable = new Exception();
+        test("isThrowable", profile(), throwable);
+        test("isThrowable", profile(Throwable.class), throwable);
+        test("isThrowable", profile(Exception.class, Error.class), throwable);
+
+        test("isThrowable", profile(), Object.class);
+        test("isThrowable", profile(Throwable.class), Object.class);
+        test("isThrowable", profile(Exception.class, Error.class), Object.class);
+    }
+
+    @LongTest
+    public void test3_1() {
+        onlyFirstIsException(new Exception(), new Error());
+        test("onlyFirstIsException", profile(), new Exception(), new Error());
+        test("onlyFirstIsException", profile(), new Error(), new Exception());
+        test("onlyFirstIsException", profile(), new Exception(), new Exception());
+        test("onlyFirstIsException", profile(), new Error(), new Error());
+    }
+
+    @LongTest
+    public void test4() {
+        Throwable throwable = new Exception();
+        test("isThrowableInt", profile(), throwable);
+        test("isThrowableInt", profile(Throwable.class), throwable);
+        test("isThrowableInt", profile(Exception.class, Error.class), throwable);
+
+        test("isThrowableInt", profile(), Object.class);
+        test("isThrowableInt", profile(Throwable.class), Object.class);
+        test("isThrowableInt", profile(Exception.class, Error.class), Object.class);
+    }
+
+    @LongTest
+    public void test5() {
+        Map map = new HashMap<>();
+        test("isMap", profile(), map);
+        test("isMap", profile(HashMap.class), map);
+        test("isMap", profile(TreeMap.class, HashMap.class), map);
+
+        test("isMap", profile(), Object.class);
+        test("isMap", profile(HashMap.class), Object.class);
+        test("isMap", profile(TreeMap.class, HashMap.class), Object.class);
+    }
+
+    @LongTest
+    public void test6() {
+        Map map = new HashMap<>();
+        test("isMapInt", profile(), map);
+        test("isMapInt", profile(HashMap.class), map);
+        test("isMapInt", profile(TreeMap.class, HashMap.class), map);
+
+        test("isMapInt", profile(), Object.class);
+        test("isMapInt", profile(HashMap.class), Object.class);
+        test("isMapInt", profile(TreeMap.class, HashMap.class), Object.class);
+    }
+
+    @LongTest
+    public void test7() {
+        Object o = new Depth13();
+        test("isDepth12", profile(), o);
+        test("isDepth12", profile(Depth13.class), o);
+        test("isDepth12", profile(Depth13.class, Depth14.class), o);
+
+        o = "not a depth";
+        test("isDepth12", profile(), o);
+        test("isDepth12", profile(Depth13.class), o);
+        test("isDepth12", profile(Depth13.class, Depth14.class), o);
+    }
+
+    @LongTest
+    public void test8() {
+        Object o = new Depth13();
+        test("isDepth12Int", profile(), o);
+        test("isDepth12Int", profile(Depth13.class), o);
+        test("isDepth12Int", profile(Depth13.class, Depth14.class), o);
+
+        o = "not a depth";
+        test("isDepth12Int", profile(), o);
+        test("isDepth12Int", profile(Depth13.class), o);
+        test("isDepth12Int", profile(Depth13.class, Depth14.class), o);
+    }
+
+    public static boolean isString(Object o) {
+        return o instanceof String;
+    }
+
+    public static int isStringInt(Object o) {
+        if (o instanceof String) {
+            return id(1);
+        }
+        return id(0);
+    }
+
+    public static int isStringIntComplex(Object o) {
+        if (o instanceof String || o instanceof Integer) {
+            return id(o instanceof String ? 1 : 0);
+        }
+        return id(0);
+    }
+
+    public static int id(int value) {
+        return value;
+    }
+
+    public static boolean isThrowable(Object o) {
+        return ((Throwable) o) instanceof Exception;
+    }
+
+    public static int onlyFirstIsException(Throwable t1, Throwable t2) {
+        if (t1 instanceof Exception ^ t2 instanceof Exception) {
+            return t1 instanceof Exception ? 1 : -1;
+        }
+        return -1;
+    }
+
+    public static int isThrowableInt(Object o) {
+        int result = o instanceof Throwable ? 4 : 5;
+        if (o instanceof Throwable) {
+            return id(4);
+        }
+        return result;
+    }
+
+    public static boolean isMap(Object o) {
+        return o instanceof Map;
+    }
+
+    public static int isMapInt(Object o) {
+        if (o instanceof Map) {
+            return id(1);
+        }
+        return id(0);
+    }
+
+    public static boolean isDepth12(Object o) {
+        return o instanceof Depth12;
+    }
+
+    public static int isDepth12Int(Object o) {
+        if (o instanceof Depth12) {
+            return id(0);
+        }
+        return id(0);
+    }
+
+    abstract static class MySite {
+
+        final int offset;
+
+        MySite(int offset) {
+            this.offset = offset;
+        }
+    }
+
+    static class MyMark extends MySite {
+
+        MyMark(int offset) {
+            super(offset);
+        }
+    }
+
+    abstract static class MySafepoint extends MySite {
+
+        MySafepoint(int offset) {
+            super(offset);
+        }
+    }
+
+    static class MyCall extends MySafepoint {
+
+        MyCall(int offset) {
+            super(offset);
+        }
+    }
+
+    @LongTest
+    public void test9() {
+        MyCall callAt63 = new MyCall(63);
+        MyMark markAt63 = new MyMark(63);
+        test("compareMySites", callAt63, callAt63);
+        test("compareMySites", callAt63, markAt63);
+        test("compareMySites", markAt63, callAt63);
+        test("compareMySites", markAt63, markAt63);
+    }
+
+    public static int compareMySites(MySite s1, MySite s2) {
+        if (s1.offset == s2.offset && (s1 instanceof MyMark ^ s2 instanceof MyMark)) {
+            return s1 instanceof MyMark ? -1 : 1;
+        }
+        return s1.offset - s2.offset;
+    }
+
+    @LongTest
+    public void test10() {
+        Mark[] noMarks = {};
+        Call callAt63 = new Call(null, 63, 5, true, null);
+        Mark markAt63 = new Mark(63, "1", noMarks);
+        test("compareSites", callAt63, callAt63);
+        test("compareSites", callAt63, markAt63);
+        test("compareSites", markAt63, callAt63);
+        test("compareSites", markAt63, markAt63);
+    }
+
+    public static int compareSites(Site s1, Site s2) {
+        if (s1.pcOffset == s2.pcOffset && (s1 instanceof Mark ^ s2 instanceof Mark)) {
+            return s1 instanceof Mark ? -1 : 1;
+        }
+        return s1.pcOffset - s2.pcOffset;
+    }
+
+    /**
+     * This test exists to show the kind of pattern that is be optimizable by
+     * {@code removeIntermediateMaterialization()} in {@link IfNode}.
+     * <p>
+     * The test exists in this source file as the transformation was originally motivated by the
+     * need to remove use of special JumpNodes in the {@code InstanceOfSnippets}.
+     */
+    @LongTest
+    public void test_removeIntermediateMaterialization() {
+        List<String> list = Arrays.asList("1", "2", "3", "4");
+        test("removeIntermediateMaterialization", profile(), list, "2", "yes", "no");
+        test("removeIntermediateMaterialization", profile(), list, null, "yes", "no");
+        test("removeIntermediateMaterialization", profile(), null, "2", "yes", "no");
+    }
+
+    public static String removeIntermediateMaterialization(List<Object> list, Object e, String a, String b) {
+        boolean test;
+        if (list == null || e == null) {
+            test = false;
+        } else {
+            test = false;
+            for (Object i : list) {
+                if (i.equals(e)) {
+                    test = true;
+                    break;
+                }
+            }
+        }
+        if (test) {
+            return a;
+        }
+        return b;
+    }
+
+    abstract static class A {
+    }
+
+    static class B extends A {
+    }
+
+    static class C extends B {
+    }
+
+    abstract static class D extends C {
+    }
+
+    public static boolean isArrayOfA(Object o) {
+        return o instanceof A[];
+    }
+
+    public static boolean isArrayOfB(Object o) {
+        return o instanceof B[];
+    }
+
+    public static boolean isArrayOfC(Object o) {
+        return o instanceof C[];
+    }
+
+    public static boolean isArrayOfD(Object o) {
+        return o instanceof D[];
+    }
+
+    @LongTest
+    public void testArray() {
+        Object aArray = new A[10];
+        test("isArrayOfA", aArray);
+
+        Object bArray = new B[10];
+        test("isArrayOfA", aArray);
+        test("isArrayOfA", bArray);
+        test("isArrayOfB", aArray);
+        test("isArrayOfB", bArray);
+
+        Object cArray = new C[10];
+        test("isArrayOfA", aArray);
+        test("isArrayOfA", bArray);
+        test("isArrayOfA", cArray);
+        test("isArrayOfB", aArray);
+        test("isArrayOfB", bArray);
+        test("isArrayOfB", cArray);
+        test("isArrayOfC", aArray);
+        test("isArrayOfC", bArray);
+        test("isArrayOfC", cArray);
+
+        Object dArray = new D[10];
+        test("isArrayOfA", aArray);
+        test("isArrayOfA", bArray);
+        test("isArrayOfA", cArray);
+        test("isArrayOfA", dArray);
+        test("isArrayOfB", aArray);
+        test("isArrayOfB", bArray);
+        test("isArrayOfB", cArray);
+        test("isArrayOfB", dArray);
+        test("isArrayOfC", aArray);
+        test("isArrayOfC", bArray);
+        test("isArrayOfC", cArray);
+        test("isArrayOfC", dArray);
+        test("isArrayOfD", aArray);
+        test("isArrayOfD", bArray);
+        test("isArrayOfD", cArray);
+        test("isArrayOfD", dArray);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/InvokeTest.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2011, 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.replacements;
+
+import org.junit.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.common.*;
+
+/**
+ * Tests the implementation of the snippets for lowering the INVOKE* instructions.
+ */
+public class InvokeTest extends GraalCompilerTest {
+
+    @Override
+    protected void editPhasePlan(ResolvedJavaMethod method, StructuredGraph graph, PhasePlan phasePlan) {
+        phasePlan.disablePhase(InliningPhase.class);
+    }
+
+    public interface I {
+
+        String virtualMethod(String s);
+    }
+
+    public static class A implements I {
+
+        final String name = "A";
+
+        public String virtualMethod(String s) {
+            return name + s;
+        }
+    }
+
+    @SuppressWarnings("static-method")
+    private String privateMethod(String s) {
+        return s;
+    }
+
+    @Test
+    public void test1() {
+        test("invokestatic", "a string");
+        test("invokespecialConstructor", "a string");
+        test("invokespecial", this, "a string");
+        test("invokevirtual", new A(), "a string");
+        test("invokevirtual2", new A(), "a string");
+        test("invokeinterface", new A(), "a string");
+        Object[] args = {null};
+        test("invokestatic", args);
+        test("invokespecialConstructor", args);
+        test("invokespecial", null, null);
+        test("invokevirtual", null, null);
+        test("invokevirtual2", null, null);
+        test("invokeinterface", null, null);
+    }
+
+    public static String invokestatic(String s) {
+        return staticMethod(s);
+    }
+
+    public static String staticMethod(String s) {
+        return s;
+    }
+
+    public static String invokespecialConstructor(String s) {
+        return new A().virtualMethod(s);
+    }
+
+    public static String invokespecial(InvokeTest a, String s) {
+        return a.privateMethod(s);
+    }
+
+    public static String invokevirtual(A a, String s) {
+        return a.virtualMethod(s);
+    }
+
+    public static String invokevirtual2(A a, String s) {
+        a.virtualMethod(s);
+        return a.virtualMethod(s);
+    }
+
+    public static String invokeinterface(I i, String s) {
+        return i.virtualMethod(s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/MethodSubstitutionTest.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,462 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.replacements;
+
+import static org.junit.Assert.*;
+
+import java.util.concurrent.*;
+
+import org.junit.*;
+
+import sun.misc.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.common.*;
+import com.oracle.graal.replacements.ClassSubstitution.*;
+import com.oracle.graal.replacements.nodes.*;
+
+/**
+ * Tests if {@link MethodSubstitution}s are inlined correctly. Most test cases only assert that
+ * there are no remaining invocations in the graph. This is sufficient if the method that is being
+ * substituted is a native method. For Java methods, additional checks are necessary.
+ */
+public class MethodSubstitutionTest extends GraalCompilerTest {
+
+    @Test
+    public void testObjectSubstitutions() {
+        test("getClass_");
+        test("objectHashCode");
+    }
+
+    @SuppressWarnings("all")
+    public static boolean getClass_(Object obj, Class<?> clazz) {
+        return obj.getClass() == clazz;
+    }
+
+    @SuppressWarnings("all")
+    public static int objectHashCode(TestClassA obj) {
+        return obj.hashCode();
+    }
+
+    @Test
+    public void testClassSubstitutions() {
+        test("getModifiers");
+        test("isInstance");
+        test("isInterface");
+        test("isArray");
+        test("isPrimitive");
+        test("getSuperClass");
+        test("getComponentType");
+    }
+
+    @SuppressWarnings("all")
+    public static int getModifiers(Class<?> clazz) {
+        return clazz.getModifiers();
+    }
+
+    @SuppressWarnings("all")
+    public static boolean isInstance(Class<?> clazz) {
+        return clazz.isInstance(Number.class);
+    }
+
+    @SuppressWarnings("all")
+    public static boolean isInterface(Class<?> clazz) {
+        return clazz.isInterface();
+    }
+
+    @SuppressWarnings("all")
+    public static boolean isArray(Class<?> clazz) {
+        return clazz.isArray();
+    }
+
+    @SuppressWarnings("all")
+    public static boolean isPrimitive(Class<?> clazz) {
+        return clazz.isPrimitive();
+    }
+
+    @SuppressWarnings("all")
+    public static Class<?> getSuperClass(Class<?> clazz) {
+        return clazz.getSuperclass();
+    }
+
+    @SuppressWarnings("all")
+    public static Class<?> getComponentType(Class<?> clazz) {
+        return clazz.getComponentType();
+    }
+
+    @Test
+    public void testThreadSubstitutions() {
+        test("currentThread");
+        test("threadIsInterrupted");
+        test("threadInterrupted");
+    }
+
+    @SuppressWarnings("all")
+    public static Thread currentThread() {
+        return Thread.currentThread();
+    }
+
+    @SuppressWarnings("all")
+    public static boolean threadIsInterrupted(Thread thread) {
+        return thread.isInterrupted();
+    }
+
+    @SuppressWarnings("all")
+    public static boolean threadInterrupted() {
+        return Thread.interrupted();
+    }
+
+    @Test
+    public void testSystemSubstitutions() {
+        test("systemTime");
+        test("systemIdentityHashCode");
+    }
+
+    @SuppressWarnings("all")
+    public static long systemTime() {
+        return System.currentTimeMillis() + System.nanoTime();
+    }
+
+    @SuppressWarnings("all")
+    public static int systemIdentityHashCode(Object obj) {
+        return System.identityHashCode(obj);
+    }
+
+    @Test
+    public void testUnsafeSubstitutions() {
+        test("unsafeCompareAndSwapInt");
+        test("unsafeCompareAndSwapLong");
+        test("unsafeCompareAndSwapObject");
+
+        test("unsafeGetBoolean");
+        test("unsafeGetByte");
+        test("unsafeGetShort");
+        test("unsafeGetChar");
+        test("unsafeGetInt");
+        test("unsafeGetFloat");
+        test("unsafeGetDouble");
+        test("unsafeGetObject");
+
+        test("unsafePutBoolean");
+        test("unsafePutByte");
+        test("unsafePutShort");
+        test("unsafePutChar");
+        test("unsafePutInt");
+        test("unsafePutFloat");
+        test("unsafePutDouble");
+        test("unsafePutObject");
+
+        test("unsafeDirectMemoryRead");
+        test("unsafeDirectMemoryWrite");
+    }
+
+    @SuppressWarnings("all")
+    public static boolean unsafeCompareAndSwapInt(Unsafe unsafe, Object obj, long offset) {
+        return unsafe.compareAndSwapInt(obj, offset, 0, 1);
+    }
+
+    @SuppressWarnings("all")
+    public static boolean unsafeCompareAndSwapLong(Unsafe unsafe, Object obj, long offset) {
+        return unsafe.compareAndSwapLong(obj, offset, 0, 1);
+    }
+
+    @SuppressWarnings("all")
+    public static boolean unsafeCompareAndSwapObject(Unsafe unsafe, Object obj, long offset) {
+        return unsafe.compareAndSwapObject(obj, offset, null, new Object());
+    }
+
+    @SuppressWarnings("all")
+    public static boolean unsafeGetBoolean(Unsafe unsafe, Object obj, long offset) {
+        return unsafe.getBoolean(obj, offset) && unsafe.getBooleanVolatile(obj, offset);
+    }
+
+    @SuppressWarnings("all")
+    public static int unsafeGetByte(Unsafe unsafe, Object obj, long offset) {
+        return unsafe.getByte(obj, offset) + unsafe.getByteVolatile(obj, offset);
+    }
+
+    @SuppressWarnings("all")
+    public static int unsafeGetShort(Unsafe unsafe, Object obj, long offset) {
+        return unsafe.getShort(obj, offset) + unsafe.getShortVolatile(obj, offset);
+    }
+
+    @SuppressWarnings("all")
+    public static int unsafeGetChar(Unsafe unsafe, Object obj, long offset) {
+        return unsafe.getChar(obj, offset) + unsafe.getCharVolatile(obj, offset);
+    }
+
+    @SuppressWarnings("all")
+    public static int unsafeGetInt(Unsafe unsafe, Object obj, long offset) {
+        return unsafe.getInt(obj, offset) + unsafe.getIntVolatile(obj, offset);
+    }
+
+    @SuppressWarnings("all")
+    public static long unsafeGetLong(Unsafe unsafe, Object obj, long offset) {
+        return unsafe.getLong(obj, offset) + unsafe.getLongVolatile(obj, offset);
+    }
+
+    @SuppressWarnings("all")
+    public static float unsafeGetFloat(Unsafe unsafe, Object obj, long offset) {
+        return unsafe.getFloat(obj, offset) + unsafe.getFloatVolatile(obj, offset);
+    }
+
+    @SuppressWarnings("all")
+    public static double unsafeGetDouble(Unsafe unsafe, Object obj, long offset) {
+        return unsafe.getDouble(obj, offset) + unsafe.getDoubleVolatile(obj, offset);
+    }
+
+    @SuppressWarnings("all")
+    public static boolean unsafeGetObject(Unsafe unsafe, Object obj, long offset) {
+        return unsafe.getObject(obj, offset) == unsafe.getObjectVolatile(obj, offset);
+    }
+
+    @SuppressWarnings("all")
+    public static void unsafePutBoolean(Unsafe unsafe, Object obj, long offset, boolean value) {
+        unsafe.putBoolean(obj, offset, value);
+        unsafe.putBooleanVolatile(obj, offset, value);
+    }
+
+    @SuppressWarnings("all")
+    public static void unsafePutByte(Unsafe unsafe, Object obj, long offset, byte value) {
+        unsafe.putByte(obj, offset, value);
+        unsafe.putByteVolatile(obj, offset, value);
+    }
+
+    @SuppressWarnings("all")
+    public static void unsafePutShort(Unsafe unsafe, Object obj, long offset, short value) {
+        unsafe.putShort(obj, offset, value);
+        unsafe.putShortVolatile(obj, offset, value);
+    }
+
+    @SuppressWarnings("all")
+    public static void unsafePutChar(Unsafe unsafe, Object obj, long offset, char value) {
+        unsafe.putChar(obj, offset, value);
+        unsafe.putCharVolatile(obj, offset, value);
+    }
+
+    @SuppressWarnings("all")
+    public static void unsafePutInt(Unsafe unsafe, Object obj, long offset, int value) {
+        unsafe.putInt(obj, offset, value);
+        unsafe.putIntVolatile(obj, offset, value);
+        unsafe.putOrderedInt(obj, offset, value);
+    }
+
+    @SuppressWarnings("all")
+    public static void unsafePutLong(Unsafe unsafe, Object obj, long offset, long value) {
+        unsafe.putLong(obj, offset, value);
+        unsafe.putLongVolatile(obj, offset, value);
+        unsafe.putOrderedLong(obj, offset, value);
+    }
+
+    @SuppressWarnings("all")
+    public static void unsafePutFloat(Unsafe unsafe, Object obj, long offset, float value) {
+        unsafe.putFloat(obj, offset, value);
+        unsafe.putFloatVolatile(obj, offset, value);
+    }
+
+    @SuppressWarnings("all")
+    public static void unsafePutDouble(Unsafe unsafe, Object obj, long offset, double value) {
+        unsafe.putDouble(obj, offset, value);
+        unsafe.putDoubleVolatile(obj, offset, value);
+    }
+
+    @SuppressWarnings("all")
+    public static void unsafePutObject(Unsafe unsafe, Object obj, long offset, Object value) {
+        unsafe.putObject(obj, offset, value);
+        unsafe.putObjectVolatile(obj, offset, value);
+        unsafe.putOrderedObject(obj, offset, value);
+    }
+
+    @SuppressWarnings("all")
+    public static double unsafeDirectMemoryRead(Unsafe unsafe, long address) {
+        // Unsafe.getBoolean(long) and Unsafe.getObject(long) do not exist
+        return unsafe.getByte(address) + unsafe.getShort(address) + unsafe.getChar(address) + unsafe.getInt(address) + unsafe.getLong(address) + unsafe.getFloat(address) + unsafe.getDouble(address);
+    }
+
+    @SuppressWarnings("all")
+    public static void unsafeDirectMemoryWrite(Unsafe unsafe, long address, byte value) {
+        // Unsafe.putBoolean(long) and Unsafe.putObject(long) do not exist
+        unsafe.putByte(address, value);
+        unsafe.putShort(address, value);
+        unsafe.putChar(address, (char) value);
+        unsafe.putInt(address, value);
+        unsafe.putLong(address, value);
+        unsafe.putFloat(address, value);
+        unsafe.putDouble(address, value);
+    }
+
+    @Test
+    public void testMathSubstitutions() {
+        assertInGraph(assertNotInGraph(test("mathAbs"), IfNode.class), MathIntrinsicNode.class);     // Java
+        test("math");
+    }
+
+    @SuppressWarnings("all")
+    public static double mathAbs(double value) {
+        return Math.abs(value);
+    }
+
+    @SuppressWarnings("all")
+    public static double math(double value) {
+        return Math.sqrt(value) + Math.log(value) + Math.log10(value) + Math.sin(value) + Math.cos(value) + Math.tan(value);
+        // Math.exp(value) +
+        // Math.pow(value, 13);
+    }
+
+    @Test
+    public void testIntegerSubstitutions() {
+        assertInGraph(test("integerReverseBytes"), ReverseBytesNode.class);              // Java
+        assertInGraph(test("integerNumberOfLeadingZeros"), BitScanReverseNode.class);    // Java
+        assertInGraph(test("integerNumberOfTrailingZeros"), BitScanForwardNode.class);   // Java
+        assertInGraph(test("integerBitCount"), BitCountNode.class);                      // Java
+    }
+
+    @SuppressWarnings("all")
+    public static int integerReverseBytes(int value) {
+        return Integer.reverseBytes(value);
+    }
+
+    @SuppressWarnings("all")
+    public static int integerNumberOfLeadingZeros(int value) {
+        return Integer.numberOfLeadingZeros(value);
+    }
+
+    @SuppressWarnings("all")
+    public static int integerNumberOfTrailingZeros(int value) {
+        return Integer.numberOfTrailingZeros(value);
+    }
+
+    @SuppressWarnings("all")
+    public static int integerBitCount(int value) {
+        return Integer.bitCount(value);
+    }
+
+    @Test
+    public void testLongSubstitutions() {
+        assertInGraph(test("longReverseBytes"), ReverseBytesNode.class);              // Java
+        assertInGraph(test("longNumberOfLeadingZeros"), BitScanReverseNode.class);    // Java
+        assertInGraph(test("longNumberOfTrailingZeros"), BitScanForwardNode.class);   // Java
+        assertInGraph(test("longBitCount"), BitCountNode.class);                      // Java
+    }
+
+    @SuppressWarnings("all")
+    public static long longReverseBytes(long value) {
+        return Long.reverseBytes(value);
+    }
+
+    @SuppressWarnings("all")
+    public static long longNumberOfLeadingZeros(long value) {
+        return Long.numberOfLeadingZeros(value);
+    }
+
+    @SuppressWarnings("all")
+    public static long longNumberOfTrailingZeros(long value) {
+        return Long.numberOfTrailingZeros(value);
+    }
+
+    @SuppressWarnings("all")
+    public static int longBitCount(long value) {
+        return Long.bitCount(value);
+    }
+
+    @Test
+    public void testFloatSubstitutions() {
+        assertInGraph(test("floatToIntBits"), ConvertNode.class); // Java
+        test("intBitsToFloat");
+    }
+
+    @SuppressWarnings("all")
+    public static int floatToIntBits(float value) {
+        return Float.floatToIntBits(value);
+    }
+
+    @SuppressWarnings("all")
+    public static float intBitsToFloat(int value) {
+        return Float.intBitsToFloat(value);
+    }
+
+    @Test
+    public void testDoubleSubstitutions() {
+        assertInGraph(test("doubleToLongBits"), ConvertNode.class); // Java
+        test("longBitsToDouble");
+    }
+
+    @SuppressWarnings("all")
+    public static long doubleToLongBits(double value) {
+        return Double.doubleToLongBits(value);
+    }
+
+    @SuppressWarnings("all")
+    public static double longBitsToDouble(long value) {
+        return Double.longBitsToDouble(value);
+    }
+
+    private StructuredGraph test(final String snippet) {
+        return Debug.scope("MethodSubstitutionTest", runtime.lookupJavaMethod(getMethod(snippet)), new Callable<StructuredGraph>() {
+
+            @Override
+            public StructuredGraph call() {
+                StructuredGraph graph = parse(snippet);
+                PhasePlan phasePlan = getDefaultPhasePlan();
+                Assumptions assumptions = new Assumptions(true);
+                new ComputeProbabilityPhase().apply(graph);
+                Debug.dump(graph, "Graph");
+                new InliningPhase(runtime(), null, assumptions, null, phasePlan, OptimisticOptimizations.ALL).apply(graph);
+                Debug.dump(graph, "Graph");
+                new CanonicalizerPhase(runtime(), assumptions).apply(graph);
+                new DeadCodeEliminationPhase().apply(graph);
+
+                assertNotInGraph(graph, Invoke.class);
+                return graph;
+            }
+        });
+    }
+
+    private static StructuredGraph assertNotInGraph(StructuredGraph graph, Class<?> clazz) {
+        for (Node node : graph.getNodes()) {
+            if (clazz.isInstance(node)) {
+                fail(node.toString());
+            }
+        }
+        return graph;
+    }
+
+    private static StructuredGraph assertInGraph(StructuredGraph graph, Class<?> clazz) {
+        for (Node node : graph.getNodes()) {
+            if (clazz.isInstance(node)) {
+                return graph;
+            }
+        }
+        fail("Graph does not contain a node of class " + clazz.getName());
+        return graph;
+    }
+
+    private static class TestClassA {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/MonitorTest.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.replacements;
+
+import org.junit.*;
+
+import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.virtual.phases.ea.*;
+
+public class MonitorTest extends GraalCompilerTest {
+
+    @Test
+    public void test0() {
+        test("lockObjectSimple", new Object(), new Object());
+        test("lockObjectSimple", new Object(), null);
+    }
+
+    @Test
+    public void test0_1() {
+        test("lockThisSimple", "test1", new Object());
+        test("lockThisSimple", "test1", null);
+    }
+
+    @Test
+    public void test0_2() {
+        test("lockObjectSimple", null, "test1");
+    }
+
+    @Test
+    public void test1_1() {
+        test("lockObject", new Object(), "test1", new String[1]);
+    }
+
+    @Test
+    public void test1_2() {
+        test("lockObject", null, "test1_1", new String[1]);
+    }
+
+    @Test
+    public void test2() {
+        test("lockThis", "test2", new String[1]);
+    }
+
+    /**
+     * Tests monitor operations on {@link PartialEscapeAnalysisPhase virtual objects}.
+     */
+    @Test
+    public void test3() {
+        test("lockLocalObject", "test3", new String[1]);
+    }
+
+    /**
+     * Tests recursive locking of objects which should be biasable.
+     */
+    @Test
+    public void test4() {
+        Chars src = new Chars("1234567890".toCharArray());
+        Chars dst = new Chars(src.data.length);
+        test("copyObj", src, dst, 100);
+    }
+
+    /**
+     * Tests recursive locking of objects which do not appear to be biasable.
+     */
+    @Test
+    public void test5() {
+        char[] src = "1234567890".toCharArray();
+        char[] dst = new char[src.length];
+        test("copyArr", src, dst, 100);
+    }
+
+    /**
+     * Extends {@link #test4()} with contention.
+     */
+    @Test
+    public void test6() {
+        Chars src = new Chars("1234567890".toCharArray());
+        Chars dst = new Chars(src.data.length);
+        int n = Runtime.getRuntime().availableProcessors();
+        testN(n, "copyObj", src, dst, 100);
+    }
+
+    /**
+     * Extends {@link #test5()} with contention.
+     */
+    @Test
+    public void test7() {
+        char[] src = "1234567890".toCharArray();
+        char[] dst = new char[src.length];
+        int n = Runtime.getRuntime().availableProcessors();
+        testN(n, "copyArr", src, dst, 100);
+    }
+
+    private static String setAndGet(String[] box, String value) {
+        synchronized (box) {
+            box[0] = null;
+        }
+
+        // Do a GC while a object is locked (by the caller)
+        System.gc();
+
+        synchronized (box) {
+            box[0] = value;
+        }
+        return box[0];
+    }
+
+    public static Object lockObjectSimple(Object o, Object value) {
+        synchronized (o) {
+            value.hashCode();
+            return value;
+        }
+    }
+
+    public String lockThisSimple(String value, Object o) {
+        synchronized (this) {
+            synchronized (value) {
+                o.hashCode();
+                return value;
+            }
+        }
+    }
+
+    public static String lockObject(Object o, String value, String[] box) {
+        synchronized (o) {
+            return setAndGet(box, value);
+        }
+    }
+
+    public String lockThis(String value, String[] box) {
+        synchronized (this) {
+            return setAndGet(box, value);
+        }
+    }
+
+    public static String lockLocalObject(String value, String[] box) {
+        Object o = new Object();
+        synchronized (o) {
+            return setAndGet(box, value);
+        }
+    }
+
+    static class Chars {
+
+        final char[] data;
+
+        public Chars(int size) {
+            this.data = new char[size];
+        }
+
+        public Chars(char[] data) {
+            this.data = data;
+        }
+    }
+
+    public static String copyObj(Chars src, Chars dst, int n) {
+        System.out.println(Thread.currentThread().getName() + " reps=" + n + ", src.length=" + src.data.length);
+        int total = 0;
+        for (int j = 0; j < n; j++) {
+            for (int i = 0; i < src.data.length; i++) {
+                synchronized (src) {
+                    synchronized (dst) {
+                        synchronized (src) {
+                            synchronized (dst) {
+                                dst.data[i] = src.data[i];
+                                total++;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        System.out.println(Thread.currentThread().getName() + " total " + total);
+        return new String(dst.data);
+    }
+
+    public static String copyArr(char[] src, char[] dst, int n) {
+        System.out.println(Thread.currentThread().getName() + " reps=" + n + ", src.length=" + src.length);
+        int total = 0;
+        for (int j = 0; j < n; j++) {
+            for (int i = 0; i < src.length; i++) {
+                synchronized (src) {
+                    synchronized (dst) {
+                        synchronized (src) {
+                            synchronized (dst) {
+                                dst[i] = src[i];
+                                total++;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        System.out.println(Thread.currentThread().getName() + " total " + total);
+        return new String(dst);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/NewArrayTest.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2011, 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.replacements;
+
+import org.junit.*;
+
+import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.test.*;
+
+/**
+ * Tests the implementation of {@code [A]NEWARRAY}.
+ */
+public class NewArrayTest extends GraalCompilerTest {
+
+    @Override
+    protected void assertEquals(Object expected, Object actual) {
+        Assert.assertTrue(expected != null);
+        Assert.assertTrue(actual != null);
+        super.assertEquals(expected.getClass(), actual.getClass());
+        if (expected instanceof int[]) {
+            Assert.assertArrayEquals((int[]) expected, (int[]) actual);
+        } else if (expected instanceof byte[]) {
+            Assert.assertArrayEquals((byte[]) expected, (byte[]) actual);
+        } else if (expected instanceof char[]) {
+            Assert.assertArrayEquals((char[]) expected, (char[]) actual);
+        } else if (expected instanceof short[]) {
+            Assert.assertArrayEquals((short[]) expected, (short[]) actual);
+        } else if (expected instanceof float[]) {
+            Assert.assertArrayEquals((float[]) expected, (float[]) actual, 0.0f);
+        } else if (expected instanceof long[]) {
+            Assert.assertArrayEquals((long[]) expected, (long[]) actual);
+        } else if (expected instanceof double[]) {
+            Assert.assertArrayEquals((double[]) expected, (double[]) actual, 0.0d);
+        } else if (expected instanceof Object[]) {
+            Assert.assertArrayEquals((Object[]) expected, (Object[]) actual);
+        } else {
+            Assert.fail("non-array value encountered: " + expected);
+        }
+    }
+
+    @LongTest
+    public void test1() {
+        for (String type : new String[]{"Byte", "Char", "Short", "Int", "Float", "Long", "Double", "String"}) {
+            test("new" + type + "Array7");
+            test("new" + type + "ArrayMinus7");
+            test("new" + type + "Array", 7);
+            test("new" + type + "Array", -7);
+            test("new" + type + "Array", Integer.MAX_VALUE);
+            test("new" + type + "Array", Integer.MIN_VALUE);
+        }
+    }
+
+    public static Object newCharArray7() {
+        return new char[7];
+    }
+
+    public static Object newCharArrayMinus7() {
+        return new char[-7];
+    }
+
+    public static Object newCharArray(int length) {
+        return new char[length];
+    }
+
+    public static Object newShortArray7() {
+        return new short[7];
+    }
+
+    public static Object newShortArrayMinus7() {
+        return new short[-7];
+    }
+
+    public static Object newShortArray(int length) {
+        return new short[length];
+    }
+
+    public static Object newFloatArray7() {
+        return new float[7];
+    }
+
+    public static Object newFloatArrayMinus7() {
+        return new float[-7];
+    }
+
+    public static Object newFloatArray(int length) {
+        return new float[length];
+    }
+
+    public static Object newLongArray7() {
+        return new long[7];
+    }
+
+    public static Object newLongArrayMinus7() {
+        return new long[-7];
+    }
+
+    public static Object newLongArray(int length) {
+        return new long[length];
+    }
+
+    public static Object newDoubleArray7() {
+        return new double[7];
+    }
+
+    public static Object newDoubleArrayMinus7() {
+        return new double[-7];
+    }
+
+    public static Object newDoubleArray(int length) {
+        return new double[length];
+    }
+
+    public static Object newIntArray7() {
+        return new int[7];
+    }
+
+    public static Object newIntArrayMinus7() {
+        return new int[-7];
+    }
+
+    public static Object newIntArray(int length) {
+        return new int[length];
+    }
+
+    public static Object newByteArray7() {
+        return new byte[7];
+    }
+
+    public static Object newByteArrayMinus7() {
+        return new byte[-7];
+    }
+
+    public static Object newByteArray(int length) {
+        return new byte[length];
+    }
+
+    public static Object newStringArray7() {
+        return new String[7];
+    }
+
+    public static Object newStringArrayMinus7() {
+        return new String[-7];
+    }
+
+    public static Object newStringArray(int length) {
+        return new String[length];
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/NewInstanceTest.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2011, 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.replacements;
+
+import java.util.*;
+
+import org.junit.*;
+
+import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.test.*;
+
+/**
+ * Tests the implementation of {@code NEW}.
+ */
+public class NewInstanceTest extends GraalCompilerTest {
+
+    @Override
+    protected void assertEquals(Object expected, Object actual) {
+        Assert.assertTrue(expected != null);
+        Assert.assertTrue(actual != null);
+        super.assertEquals(expected.getClass(), actual.getClass());
+
+        if (expected instanceof Object[]) {
+            Assert.assertTrue(actual instanceof Object[]);
+            Object[] eArr = (Object[]) expected;
+            Object[] aArr = (Object[]) actual;
+            Assert.assertTrue(eArr.length == aArr.length);
+            for (int i = 0; i < eArr.length; i++) {
+                assertEquals(eArr[i], aArr[i]);
+            }
+        } else if (expected.getClass() != Object.class) {
+            try {
+                expected.getClass().getDeclaredMethod("equals", Object.class);
+                super.assertEquals(expected, actual);
+            } catch (Exception e) {
+            }
+        }
+    }
+
+    @LongTest
+    public void test1() {
+        test("newObject");
+    }
+
+    @LongTest
+    public void test2() {
+        test("newObjectTwice");
+    }
+
+    public static Object newObject() {
+        return new Object();
+    }
+
+    @LongTest
+    public void test3() {
+        test("newObjectLoop", 100);
+    }
+
+    @LongTest
+    public void test4() {
+        test("newBigObject");
+    }
+
+    @LongTest
+    public void test5() {
+        test("newSomeObject");
+    }
+
+    @LongTest
+    public void test6() {
+        test("newEmptyString");
+    }
+
+    @LongTest
+    public void test7() {
+        test("newString", "value");
+    }
+
+    @LongTest
+    public void test8() {
+        test("newHashMap", 31);
+    }
+
+    @LongTest
+    public void test9() {
+        test("newRegression", true);
+    }
+
+    public static Object[] newObjectTwice() {
+        Object[] res = {new Object(), new Object()};
+        return res;
+    }
+
+    public static Object[] newObjectLoop(int n) {
+        Object[] res = new Object[n];
+        for (int i = 0; i < n; i++) {
+            res[i] = new Object();
+        }
+        return res;
+    }
+
+    public static BigObject newBigObject() {
+        return new BigObject();
+    }
+
+    public static SomeObject newSomeObject() {
+        return new SomeObject();
+    }
+
+    public static String newEmptyString() {
+        return new String();
+    }
+
+    public static String newString(String value) {
+        return new String(value);
+    }
+
+    public static HashMap newHashMap(int initialCapacity) {
+        return new HashMap(initialCapacity);
+    }
+
+    static class SomeObject {
+
+        String name = "o1";
+        HashMap<String, Object> map = new HashMap<>();
+
+        public SomeObject() {
+            map.put(name, this.getClass());
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof SomeObject) {
+                SomeObject so = (SomeObject) obj;
+                return so.name.equals(name) && so.map.equals(map);
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return name.hashCode();
+        }
+    }
+
+    static class BigObject {
+
+        Object f01;
+        Object f02;
+        Object f03;
+        Object f04;
+        Object f05;
+        Object f06;
+        Object f07;
+        Object f08;
+        Object f09;
+        Object f10;
+        Object f12;
+        Object f13;
+        Object f14;
+        Object f15;
+        Object f16;
+        Object f17;
+        Object f18;
+        Object f19;
+        Object f20;
+        Object f21;
+        Object f22;
+        Object f23;
+        Object f24;
+        Object f25;
+        Object f26;
+        Object f27;
+        Object f28;
+        Object f29;
+        Object f30;
+        Object f31;
+        Object f32;
+        Object f33;
+        Object f34;
+        Object f35;
+        Object f36;
+        Object f37;
+        Object f38;
+        Object f39;
+        Object f40;
+        Object f41;
+        Object f42;
+        Object f43;
+        Object f44;
+        Object f45;
+    }
+
+    /**
+     * Tests that an earlier bug does not occur. The issue was that the loading of the TLAB 'top'
+     * and 'end' values was being GVN'ed from each branch of the 'if' statement. This meant that the
+     * allocated B object in the true branch overwrote the allocated array. The cause is that
+     * RegisterNode was a floating node and the reads from it were UnsafeLoads which are also
+     * floating. The fix was to make RegisterNode a fixed node (which it should have been in the
+     * first place).
+     */
+    public static Object newRegression(boolean condition) {
+        Object result;
+        if (condition) {
+            Object[] arr = {0, 1, 2, 3, 4, 5};
+            result = new B();
+            for (int i = 0; i < arr.length; ++i) {
+                // If the bug exists, the values of arr will now be deadbeef values
+                // and the virtual dispatch will cause a segfault. This can result in
+                // either a VM crash or a spurious NullPointerException.
+                if (arr[i].equals(Integer.valueOf(i))) {
+                    return false;
+                }
+            }
+        } else {
+            result = new B();
+        }
+        return result;
+    }
+
+    static class B {
+
+        long f1 = 0xdeadbeefdeadbe01L;
+        long f2 = 0xdeadbeefdeadbe02L;
+        long f3 = 0xdeadbeefdeadbe03L;
+        long f4 = 0xdeadbeefdeadbe04L;
+        long f5 = 0xdeadbeefdeadbe05L;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/NewMultiArrayTest.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.replacements;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.test.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+
+/**
+ * Tests the lowering of the MULTIANEWARRAY instruction.
+ */
+public class NewMultiArrayTest extends GraalCompilerTest {
+
+    private static int rank(ResolvedJavaType type) {
+        String name = type.getName();
+        int dims = 0;
+        while (dims < name.length() && name.charAt(dims) == '[') {
+            dims++;
+        }
+        return dims;
+    }
+
+    @Override
+    protected InstalledCode getCode(final ResolvedJavaMethod method, final StructuredGraph graph) {
+        boolean forceCompile = false;
+        if (bottomType != null) {
+            List<NewMultiArrayNode> snapshot = graph.getNodes().filter(NewMultiArrayNode.class).snapshot();
+            assert snapshot != null;
+            assert snapshot.size() == 1;
+
+            NewMultiArrayNode node = snapshot.get(0);
+            assert rank(arrayType) == dimensions.length;
+            int rank = dimensions.length;
+            ValueNode[] dimensionNodes = new ValueNode[rank];
+            for (int i = 0; i < rank; i++) {
+                dimensionNodes[i] = graph.unique(ConstantNode.forInt(dimensions[i], graph));
+            }
+
+            NewMultiArrayNode repl = graph.add(new NewMultiArrayNode(arrayType, dimensionNodes));
+            graph.replaceFixedWithFixed(node, repl);
+            forceCompile = true;
+        }
+        return super.getCode(method, graph, forceCompile);
+    }
+
+    @Override
+    protected Object referenceInvoke(Method method, Object receiver, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+        if (bottomType != null) {
+            try {
+                return Array.newInstance(bottomClass, dimensions);
+            } catch (Exception e) {
+                throw new InvocationTargetException(e);
+            }
+        }
+        return super.referenceInvoke(method, receiver, args);
+    }
+
+    ResolvedJavaType arrayType;
+    ResolvedJavaType bottomType;
+    Class bottomClass;
+    int[] dimensions;
+
+    @LongTest
+    public void test1() {
+        for (Class clazz : new Class[]{byte.class, char.class, short.class, int.class, float.class, long.class, double.class, String.class}) {
+            bottomClass = clazz;
+            bottomType = runtime.lookupJavaType(clazz);
+            arrayType = bottomType;
+            for (int rank : new int[]{1, 2, 10, 50, 100, 200, 254, 255}) {
+                while (rank(arrayType) != rank) {
+                    arrayType = arrayType.getArrayClass();
+                }
+
+                dimensions = new int[rank];
+                for (int i = 0; i < rank; i++) {
+                    dimensions[i] = 1;
+                }
+
+                test("newMultiArray");
+            }
+        }
+        bottomType = null;
+        arrayType = null;
+    }
+
+    public static Object newMultiArray() {
+        // This is merely a template - the NewMultiArrayNode is replaced in getCode() above.
+        // This also means we need a separate test for correct handling of negative dimensions
+        // as deoptimization won't do what we want for a graph modified to be different from the
+        // source bytecode.
+        return new Object[10][9][8];
+    }
+
+    @LongTest
+    public void test2() {
+        test("newMultiArrayException");
+    }
+
+    public static Object newMultiArrayException() {
+        return new Object[10][9][-8];
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/PointerTest.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,399 @@
+/*
+ * 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.replacements;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.replacements.Snippet.*;
+import com.oracle.graal.word.*;
+
+/**
+ * Tests for the {@link Pointer} read and write operations.
+ */
+public class PointerTest extends GraalCompilerTest implements Snippets {
+
+    private static final Object ID = new Object();
+    private static final Kind[] KINDS = new Kind[]{Kind.Byte, Kind.Char, Kind.Short, Kind.Int, Kind.Long, Kind.Float, Kind.Double, Kind.Object};
+    private final TargetDescription target;
+    private final ReplacementsInstaller installer;
+
+    public PointerTest() {
+        target = Graal.getRequiredCapability(CodeCacheProvider.class).getTarget();
+        installer = new ReplacementsInstaller(runtime, new Assumptions(false), target);
+    }
+
+    private static final ThreadLocal<SnippetInliningPolicy> inliningPolicy = new ThreadLocal<>();
+
+    @Override
+    protected StructuredGraph parse(Method m) {
+        ResolvedJavaMethod resolvedMethod = runtime.lookupJavaMethod(m);
+        return installer.makeGraph(resolvedMethod, inliningPolicy.get());
+    }
+
+    @Test
+    public void test_read1() {
+        for (Kind kind : KINDS) {
+            assertRead(parse("read" + kind.name() + "1"), kind, false, ID);
+        }
+    }
+
+    @Test
+    public void test_read2() {
+        for (Kind kind : KINDS) {
+            assertRead(parse("read" + kind.name() + "2"), kind, true, ID);
+        }
+    }
+
+    @Test
+    public void test_read3() {
+        for (Kind kind : KINDS) {
+            assertRead(parse("read" + kind.name() + "3"), kind, false, LocationNode.UNKNOWN_LOCATION);
+        }
+    }
+
+    @Test
+    public void test_write1() {
+        for (Kind kind : KINDS) {
+            assertWrite(parse("write" + kind.name() + "1"), kind, false, ID);
+        }
+    }
+
+    @Test
+    public void test_write2() {
+        for (Kind kind : KINDS) {
+            assertWrite(parse("write" + kind.name() + "2"), kind, true, ID);
+        }
+    }
+
+    @Test
+    public void test_write3() {
+        for (Kind kind : KINDS) {
+            assertWrite(parse("write" + kind.name() + "3"), kind, false, LocationNode.ANY_LOCATION);
+        }
+    }
+
+    private void assertRead(StructuredGraph graph, Kind kind, boolean indexConvert, Object locationIdentity) {
+        ReadNode read = (ReadNode) graph.start().next();
+        Assert.assertEquals(kind.getStackKind(), read.kind());
+
+        UnsafeCastNode cast = (UnsafeCastNode) read.object();
+        Assert.assertEquals(graph.getLocal(0), cast.object());
+        Assert.assertEquals(target.wordKind, cast.kind());
+
+        IndexedLocationNode location = (IndexedLocationNode) read.location();
+        Assert.assertEquals(kind, location.getValueKind());
+        Assert.assertEquals(locationIdentity, location.locationIdentity());
+        Assert.assertEquals(1, location.indexScaling());
+
+        if (indexConvert) {
+            ConvertNode convert = (ConvertNode) location.index();
+            Assert.assertEquals(ConvertNode.Op.I2L, convert.opcode);
+            Assert.assertEquals(graph.getLocal(1), convert.value());
+        } else {
+            Assert.assertEquals(graph.getLocal(1), location.index());
+        }
+
+        ReturnNode ret = (ReturnNode) read.next();
+        Assert.assertEquals(read, ret.result());
+    }
+
+    private void assertWrite(StructuredGraph graph, Kind kind, boolean indexConvert, Object locationIdentity) {
+        WriteNode write = (WriteNode) graph.start().next();
+        Assert.assertEquals(graph.getLocal(2), write.value());
+        Assert.assertEquals(Kind.Void, write.kind());
+        Assert.assertEquals(FrameState.INVALID_FRAMESTATE_BCI, write.stateAfter().bci);
+
+        UnsafeCastNode cast = (UnsafeCastNode) write.object();
+        Assert.assertEquals(graph.getLocal(0), cast.object());
+        Assert.assertEquals(target.wordKind, cast.kind());
+
+        IndexedLocationNode location = (IndexedLocationNode) write.location();
+        Assert.assertEquals(kind, location.getValueKind());
+        Assert.assertEquals(locationIdentity, location.locationIdentity());
+        Assert.assertEquals(1, location.indexScaling());
+
+        if (indexConvert) {
+            ConvertNode convert = (ConvertNode) location.index();
+            Assert.assertEquals(ConvertNode.Op.I2L, convert.opcode);
+            Assert.assertEquals(graph.getLocal(1), convert.value());
+        } else {
+            Assert.assertEquals(graph.getLocal(1), location.index());
+        }
+
+        AbstractStateSplit stateSplit = (AbstractStateSplit) write.next();
+        Assert.assertEquals(FrameState.AFTER_BCI, stateSplit.stateAfter().bci);
+
+        ReturnNode ret = (ReturnNode) stateSplit.next();
+        Assert.assertEquals(null, ret.result());
+    }
+
+    @Snippet
+    public static byte readByte1(Object o, int offset) {
+        return Word.fromObject(o).readByte(offset, ID);
+    }
+
+    @Snippet
+    public static byte readByte2(Object o, int offset) {
+        return Word.fromObject(o).readByte(Word.signed(offset), ID);
+    }
+
+    @Snippet
+    public static byte readByte3(Object o, int offset) {
+        return Word.fromObject(o).readByte(offset);
+    }
+
+    @Snippet
+    public static void writeByte1(Object o, int offset, byte value) {
+        Word.fromObject(o).writeByte(offset, value, ID);
+    }
+
+    @Snippet
+    public static void writeByte2(Object o, int offset, byte value) {
+        Word.fromObject(o).writeByte(Word.signed(offset), value, ID);
+    }
+
+    @Snippet
+    public static void writeByte3(Object o, int offset, byte value) {
+        Word.fromObject(o).writeByte(offset, value);
+    }
+
+    @Snippet
+    public static char readChar1(Object o, int offset) {
+        return Word.fromObject(o).readChar(offset, ID);
+    }
+
+    @Snippet
+    public static char readChar2(Object o, int offset) {
+        return Word.fromObject(o).readChar(Word.signed(offset), ID);
+    }
+
+    @Snippet
+    public static char readChar3(Object o, int offset) {
+        return Word.fromObject(o).readChar(offset);
+    }
+
+    @Snippet
+    public static void writeChar1(Object o, int offset, char value) {
+        Word.fromObject(o).writeChar(offset, value, ID);
+    }
+
+    @Snippet
+    public static void writeChar2(Object o, int offset, char value) {
+        Word.fromObject(o).writeChar(Word.signed(offset), value, ID);
+    }
+
+    @Snippet
+    public static void writeChar3(Object o, int offset, char value) {
+        Word.fromObject(o).writeChar(offset, value);
+    }
+
+    @Snippet
+    public static short readShort1(Object o, int offset) {
+        return Word.fromObject(o).readShort(offset, ID);
+    }
+
+    @Snippet
+    public static short readShort2(Object o, int offset) {
+        return Word.fromObject(o).readShort(Word.signed(offset), ID);
+    }
+
+    @Snippet
+    public static short readShort3(Object o, int offset) {
+        return Word.fromObject(o).readShort(offset);
+    }
+
+    @Snippet
+    public static void writeShort1(Object o, int offset, short value) {
+        Word.fromObject(o).writeShort(offset, value, ID);
+    }
+
+    @Snippet
+    public static void writeShort2(Object o, int offset, short value) {
+        Word.fromObject(o).writeShort(Word.signed(offset), value, ID);
+    }
+
+    @Snippet
+    public static void writeShort3(Object o, int offset, short value) {
+        Word.fromObject(o).writeShort(offset, value);
+    }
+
+    @Snippet
+    public static int readInt1(Object o, int offset) {
+        return Word.fromObject(o).readInt(offset, ID);
+    }
+
+    @Snippet
+    public static int readInt2(Object o, int offset) {
+        return Word.fromObject(o).readInt(Word.signed(offset), ID);
+    }
+
+    @Snippet
+    public static int readInt3(Object o, int offset) {
+        return Word.fromObject(o).readInt(offset);
+    }
+
+    @Snippet
+    public static void writeInt1(Object o, int offset, int value) {
+        Word.fromObject(o).writeInt(offset, value, ID);
+    }
+
+    @Snippet
+    public static void writeInt2(Object o, int offset, int value) {
+        Word.fromObject(o).writeInt(Word.signed(offset), value, ID);
+    }
+
+    @Snippet
+    public static void writeInt3(Object o, int offset, int value) {
+        Word.fromObject(o).writeInt(offset, value);
+    }
+
+    @Snippet
+    public static long readLong1(Object o, int offset) {
+        return Word.fromObject(o).readLong(offset, ID);
+    }
+
+    @Snippet
+    public static long readLong2(Object o, int offset) {
+        return Word.fromObject(o).readLong(Word.signed(offset), ID);
+    }
+
+    @Snippet
+    public static long readLong3(Object o, int offset) {
+        return Word.fromObject(o).readLong(offset);
+    }
+
+    @Snippet
+    public static void writeLong1(Object o, int offset, long value) {
+        Word.fromObject(o).writeLong(offset, value, ID);
+    }
+
+    @Snippet
+    public static void writeLong2(Object o, int offset, long value) {
+        Word.fromObject(o).writeLong(Word.signed(offset), value, ID);
+    }
+
+    @Snippet
+    public static void writeLong3(Object o, int offset, long value) {
+        Word.fromObject(o).writeLong(offset, value);
+    }
+
+    @Snippet
+    public static float readFloat1(Object o, int offset) {
+        return Word.fromObject(o).readFloat(offset, ID);
+    }
+
+    @Snippet
+    public static float readFloat2(Object o, int offset) {
+        return Word.fromObject(o).readFloat(Word.signed(offset), ID);
+    }
+
+    @Snippet
+    public static float readFloat3(Object o, int offset) {
+        return Word.fromObject(o).readFloat(offset);
+    }
+
+    @Snippet
+    public static void writeFloat1(Object o, int offset, float value) {
+        Word.fromObject(o).writeFloat(offset, value, ID);
+    }
+
+    @Snippet
+    public static void writeFloat2(Object o, int offset, float value) {
+        Word.fromObject(o).writeFloat(Word.signed(offset), value, ID);
+    }
+
+    @Snippet
+    public static void writeFloat3(Object o, int offset, float value) {
+        Word.fromObject(o).writeFloat(offset, value);
+    }
+
+    @Snippet
+    public static double readDouble1(Object o, int offset) {
+        return Word.fromObject(o).readDouble(offset, ID);
+    }
+
+    @Snippet
+    public static double readDouble2(Object o, int offset) {
+        return Word.fromObject(o).readDouble(Word.signed(offset), ID);
+    }
+
+    @Snippet
+    public static double readDouble3(Object o, int offset) {
+        return Word.fromObject(o).readDouble(offset);
+    }
+
+    @Snippet
+    public static void writeDouble1(Object o, int offset, double value) {
+        Word.fromObject(o).writeDouble(offset, value, ID);
+    }
+
+    @Snippet
+    public static void writeDouble2(Object o, int offset, double value) {
+        Word.fromObject(o).writeDouble(Word.signed(offset), value, ID);
+    }
+
+    @Snippet
+    public static void writeDouble3(Object o, int offset, double value) {
+        Word.fromObject(o).writeDouble(offset, value);
+    }
+
+    @Snippet
+    public static Object readObject1(Object o, int offset) {
+        return Word.fromObject(o).readObject(offset, ID);
+    }
+
+    @Snippet
+    public static Object readObject2(Object o, int offset) {
+        return Word.fromObject(o).readObject(Word.signed(offset), ID);
+    }
+
+    @Snippet
+    public static Object readObject3(Object o, int offset) {
+        return Word.fromObject(o).readObject(offset);
+    }
+
+    @Snippet
+    public static void writeObject1(Object o, int offset, Object value) {
+        Word.fromObject(o).writeObject(offset, value, ID);
+    }
+
+    @Snippet
+    public static void writeObject2(Object o, int offset, Object value) {
+        Word.fromObject(o).writeObject(Word.signed(offset), value, ID);
+    }
+
+    @Snippet
+    public static void writeObject3(Object o, int offset, Object value) {
+        Word.fromObject(o).writeObject(offset, value);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/TypeCheckTest.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2011, 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.replacements;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType;
+import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.nodes.*;
+
+/**
+ * Base class for checkcast and instanceof test classes.
+ */
+public abstract class TypeCheckTest extends GraalCompilerTest {
+
+    protected abstract void replaceProfile(StructuredGraph graph, JavaTypeProfile profile);
+
+    protected JavaTypeProfile currentProfile;
+
+    @Override
+    protected InstalledCode getCode(final ResolvedJavaMethod method, final StructuredGraph graph) {
+        boolean forceCompile = false;
+        if (currentProfile != null) {
+            replaceProfile(graph, currentProfile);
+            forceCompile = true;
+        }
+        return super.getCode(method, graph, forceCompile);
+    }
+
+    protected JavaTypeProfile profile(Class... types) {
+        if (types.length == 0) {
+            return null;
+        }
+        ProfiledType[] ptypes = new ProfiledType[types.length];
+        for (int i = 0; i < types.length; i++) {
+            ptypes[i] = new ProfiledType(runtime.lookupJavaType(types[i]), 1.0D / types.length);
+        }
+        return new JavaTypeProfile(0.0D, ptypes);
+    }
+
+    protected void test(String name, JavaTypeProfile profile, Object... args) {
+        assert currentProfile == null;
+        currentProfile = profile;
+        try {
+            super.test(name, args);
+        } finally {
+            currentProfile = null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/WordTest.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2011, 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.replacements;
+
+import java.lang.reflect.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.test.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.replacements.Snippet.*;
+import com.oracle.graal.word.*;
+
+/**
+ * Tests for the {@link Word} type.
+ */
+public class WordTest extends GraalCompilerTest implements Snippets {
+
+    private final ReplacementsInstaller installer;
+
+    public WordTest() {
+        TargetDescription target = Graal.getRequiredCapability(CodeCacheProvider.class).getTarget();
+        installer = new ReplacementsInstaller(runtime, new Assumptions(false), target);
+    }
+
+    private static final ThreadLocal<SnippetInliningPolicy> inliningPolicy = new ThreadLocal<>();
+
+    @Override
+    protected StructuredGraph parse(Method m) {
+        ResolvedJavaMethod resolvedMethod = runtime.lookupJavaMethod(m);
+        return installer.makeGraph(resolvedMethod, inliningPolicy.get());
+    }
+
+    @LongTest
+    public void construction() {
+        long[] words = new long[]{Long.MIN_VALUE, Long.MIN_VALUE + 1, -1L, 0L, 1L, Long.MAX_VALUE - 1, Long.MAX_VALUE, Integer.MAX_VALUE - 1L, Integer.MAX_VALUE, Integer.MAX_VALUE + 1L,
+                        Integer.MIN_VALUE - 1L, Integer.MIN_VALUE, Integer.MIN_VALUE + 1L};
+        for (long word : words) {
+            test("unsigned_long", word);
+            test("unsigned_int", (int) word);
+            test("signed_long", word);
+            test("signed_int", (int) word);
+        }
+    }
+
+    @LongTest
+    public void test_arithmetic() {
+        long[] words = new long[]{Long.MIN_VALUE, Long.MIN_VALUE + 1, -1L, 0L, 1L, Long.MAX_VALUE - 1, Long.MAX_VALUE, Integer.MAX_VALUE - 1L, Integer.MAX_VALUE, Integer.MAX_VALUE + 1L,
+                        Integer.MIN_VALUE - 1L, Integer.MIN_VALUE, Integer.MIN_VALUE + 1L};
+        for (long word : words) {
+            test("unsigned_not", word);
+            test("signed_not", word);
+            for (long addend : words) {
+                test("unsigned_plus_int", word, (int) addend);
+                test("unsigned_minus_int", word, (int) addend);
+                test("unsigned_plus_int", word, -((int) addend));
+                test("unsigned_minus_int", word, -((int) addend));
+                test("unsigned_plus_long", word, addend);
+                test("unsigned_minus_long", word, addend);
+                test("unsigned_plus_long", word, -addend);
+                test("unsigned_minus_long", word, -addend);
+                test("signed_plus_int", word, (int) addend);
+                test("signed_minus_int", word, (int) addend);
+                test("signed_plus_int", word, -((int) addend));
+                test("signed_minus_int", word, -((int) addend));
+                test("signed_plus_long", word, addend);
+                test("signed_minus_long", word, addend);
+                test("signed_plus_long", word, -addend);
+                test("signed_minus_long", word, -addend);
+
+                test("and_int", word, (int) addend);
+                test("or_int", word, (int) addend);
+                test("and_int", word, -((int) addend));
+                test("or_int", word, -((int) addend));
+                test("and_long", word, addend);
+                test("or_long", word, addend);
+                test("and_long", word, -addend);
+                test("or_long", word, -addend);
+            }
+        }
+    }
+
+    @LongTest
+    public void test_compare() {
+        long[] words = new long[]{Long.MIN_VALUE, Long.MIN_VALUE + 1, -1L, 0L, 1L, Long.MAX_VALUE - 1, Long.MAX_VALUE};
+        for (long word1 : words) {
+            for (long word2 : words) {
+                for (String method : new String[]{"aboveOrEqual", "above", "belowOrEqual", "below"}) {
+                    test(method, word1, word2);
+                    test(method, word2, word1);
+                }
+            }
+        }
+    }
+
+    @Snippet
+    public static long unsigned_long(long word) {
+        return Word.unsigned(word).rawValue();
+    }
+
+    @Snippet
+    public static long unsigned_int(int word) {
+        return Word.unsigned(word).rawValue();
+    }
+
+    @Snippet
+    public static long signed_long(long word) {
+        return Word.signed(word).rawValue();
+    }
+
+    @Snippet
+    public static long signed_int(int word) {
+        return Word.signed(word).rawValue();
+    }
+
+    @Snippet
+    public static long unsigned_plus_int(long word, int addend) {
+        return Word.unsigned(word).add(addend).rawValue();
+    }
+
+    @Snippet
+    public static long unsigned_minus_int(long word, int addend) {
+        return Word.unsigned(word).subtract(addend).rawValue();
+    }
+
+    @Snippet
+    public static long unsigned_plus_long(long word, long addend) {
+        return Word.unsigned(word).add(Word.unsigned(addend)).rawValue();
+    }
+
+    @Snippet
+    public static long unsigned_minus_long(long word, long addend) {
+        return Word.unsigned(word).subtract(Word.unsigned(addend)).rawValue();
+    }
+
+    @Snippet
+    public static long signed_plus_int(long word, int addend) {
+        return Word.signed(word).add(addend).rawValue();
+    }
+
+    @Snippet
+    public static long signed_minus_int(long word, int addend) {
+        return Word.signed(word).subtract(addend).rawValue();
+    }
+
+    @Snippet
+    public static long signed_plus_long(long word, long addend) {
+        return Word.signed(word).add(Word.signed(addend)).rawValue();
+    }
+
+    @Snippet
+    public static long signed_minus_long(long word, long addend) {
+        return Word.signed(word).subtract(Word.signed(addend)).rawValue();
+    }
+
+    @Snippet
+    public static long signed_not(long word) {
+        return Word.signed(word).not().rawValue();
+    }
+
+    @Snippet
+    public static long unsigned_not(long word) {
+        return Word.unsigned(word).not().rawValue();
+    }
+
+    @Snippet
+    public static boolean aboveOrEqual(long word1, long word2) {
+        return Word.unsigned(word1).aboveOrEqual(Word.unsigned(word2));
+    }
+
+    @Snippet
+    public static boolean above(long word1, long word2) {
+        return Word.unsigned(word1).aboveThan(Word.unsigned(word2));
+    }
+
+    @Snippet
+    public static boolean belowOrEqual(long word1, long word2) {
+        return Word.unsigned(word1).belowOrEqual(Word.unsigned(word2));
+    }
+
+    @Snippet
+    public static boolean below(long word1, long word2) {
+        return Word.unsigned(word1).belowThan(Word.unsigned(word2));
+    }
+
+    @Snippet
+    public static long and_int(long word, int addend) {
+        return Word.unsigned(word).and(addend).rawValue();
+    }
+
+    @Snippet
+    public static long or_int(long word, int addend) {
+        return Word.unsigned(word).or(addend).rawValue();
+    }
+
+    @Snippet
+    public static long and_long(long word, long addend) {
+        return Word.unsigned(word).and(Word.unsigned(addend)).rawValue();
+    }
+
+    @Snippet
+    public static long or_long(long word, long addend) {
+        return Word.unsigned(word).or(Word.unsigned(addend)).rawValue();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/overview.html	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+This code is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 2 only, as
+published by the Free Software Foundation.  Oracle designates this
+particular file as subject to the "Classpath" exception as provided
+by Oracle in the LICENSE file that accompanied this code.
+
+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.
+-->
+
+</head>
+<body>
+
+Documentation for the <code>com.oracle.graal.snippets</code> project.
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ClassSubstitution.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2011, 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.replacements;
+
+import java.lang.annotation.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.replacements.nodes.*;
+
+/**
+ * Denotes a class that substitutes methods of another specified class. The substitute methods are
+ * exactly those annotated by {@link MethodSubstitution}.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface ClassSubstitution {
+
+    /**
+     * Specifies the original class.
+     * <p>
+     * If the default value is specified for this element, then a non-default value must be given
+     * for the {@link #className()} element.
+     */
+    Class<?> value() default ClassSubstitution.class;
+
+    /**
+     * Specifies the original class.
+     * <p>
+     * This method is provided for cases where the original class is not accessible (according to
+     * Java language access control rules).
+     * <p>
+     * If the default value is specified for this element, then a non-default value must be given
+     * for the {@link #value()} element.
+     */
+    String className() default "";
+
+    /**
+     * Determines if the substitutions are for classes that may not be part of the runtime.
+     * Substitutions for such classes are omitted if the original classes cannot be found.
+     */
+    boolean optional() default false;
+
+    /**
+     * Denotes a substitute method. A substitute method can call the original/substituted method by
+     * making a recursive call to itself.
+     */
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.METHOD)
+    public @interface MethodSubstitution {
+
+        /**
+         * Gets the name of the original method.
+         * <p>
+         * If the default value is specified for this element, then the name of the original method
+         * is same as the substitute method.
+         */
+        String value() default "";
+
+        /**
+         * Determines if the original method is static.
+         */
+        boolean isStatic() default true;
+
+        /**
+         * Gets the {@linkplain MetaUtil#signatureToMethodDescriptor signature} of the original
+         * method.
+         * <p>
+         * If the default value is specified for this element, then the signature of the original
+         * method is the same as the substitute method.
+         */
+        String signature() default "";
+    }
+
+    /**
+     * Denotes a macro substitute method. This replaces a method invocation with an instance of the
+     * specified node class.
+     * 
+     * A macro substitution can be combined with a normal substitution, so that the macro node can
+     * be replaced with the actual substitution code during lowering.
+     */
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.METHOD)
+    public @interface MacroSubstitution {
+
+        /**
+         * Gets the name of the substituted method.
+         * <p>
+         * If the default value is specified for this element, then the name of the substituted
+         * method is same as the substitute method.
+         */
+        String value() default "";
+
+        /**
+         * Determines if the substituted method is static.
+         */
+        boolean isStatic() default true;
+
+        /**
+         * Gets the {@linkplain MetaUtil#signatureToMethodDescriptor signature} of the substituted
+         * method.
+         * <p>
+         * If the default value is specified for this element, then the signature of the substituted
+         * method is the same as the substitute method.
+         */
+        String signature() default "";
+
+        /**
+         * The node class with which the method invocation should be replaced. It needs to be a
+         * subclass of {@link FixedWithNextNode}, and it is expected to provide a public constructor
+         * that takes an InvokeNode as a parameter. For most cases this class should subclass
+         * {@link MacroNode} and use its constructor.
+         */
+        Class<? extends FixedWithNextNode> macro();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DoubleSubstitutions.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2011, 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.replacements;
+
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.replacements.ClassSubstitution.*;
+
+/**
+ * Substitutions for {@link java.lang.Double} methods.
+ */
+@ClassSubstitution(java.lang.Double.class)
+public class DoubleSubstitutions {
+
+    private static final long NAN_RAW_LONG_BITS = Double.doubleToRawLongBits(Double.NaN);
+
+    @MethodSubstitution
+    public static long doubleToRawLongBits(double value) {
+        @JavacBug(id = 6995200)
+        Long result = ConvertNode.convert(ConvertNode.Op.MOV_D2L, value);
+        return result;
+    }
+
+    // TODO This method is not necessary, since the JDK method does exactly this
+    @MethodSubstitution
+    public static long doubleToLongBits(double value) {
+        if (value != value) {
+            return NAN_RAW_LONG_BITS;
+        } else {
+            return doubleToRawLongBits(value);
+        }
+    }
+
+    @MethodSubstitution
+    public static double longBitsToDouble(long bits) {
+        @JavacBug(id = 6995200)
+        Double result = ConvertNode.convert(ConvertNode.Op.MOV_L2D, bits);
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/FloatSubstitutions.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2011, 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.replacements;
+
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.replacements.ClassSubstitution.*;
+
+/**
+ * Substitutions for {@link java.lang.Float} methods.
+ */
+@ClassSubstitution(java.lang.Float.class)
+public class FloatSubstitutions {
+
+    private static final int NAN_RAW_INT_BITS = Float.floatToRawIntBits(Float.NaN);
+
+    @MethodSubstitution
+    public static int floatToRawIntBits(float value) {
+        @JavacBug(id = 6995200)
+        Integer result = ConvertNode.convert(ConvertNode.Op.MOV_F2I, value);
+        return result;
+    }
+
+    // TODO This method is not necessary, since the JDK method does exactly this
+    @MethodSubstitution
+    public static int floatToIntBits(float value) {
+        if (value != value) {
+            return NAN_RAW_INT_BITS;
+        } else {
+            return floatToRawIntBits(value);
+        }
+    }
+
+    @MethodSubstitution
+    public static float intBitsToFloat(int bits) {
+        @JavacBug(id = 6995200)
+        Float result = ConvertNode.convert(ConvertNode.Op.MOV_I2F, bits);
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalIntrinsics.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2011, 2011, 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.replacements;
+
+import com.oracle.graal.phases.*;
+
+/**
+ * Definition of the snippets that are VM-independent and can be intrinsified by Graal in any VM.
+ */
+public class GraalIntrinsics {
+
+    public static void installIntrinsics(ReplacementsInstaller installer) {
+        if (GraalOptions.Intrinsify) {
+            installer.installSubstitutions(MathSubstitutionsX86.class);
+            installer.installSubstitutions(DoubleSubstitutions.class);
+            installer.installSubstitutions(FloatSubstitutions.class);
+            installer.installSubstitutions(NodeClassSubstitutions.class);
+            installer.installSubstitutions(LongSubstitutions.class);
+            installer.installSubstitutions(IntegerSubstitutions.class);
+            installer.installSubstitutions(UnsignedMathSubstitutions.class);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.replacements;
+
+import static com.oracle.graal.nodes.calc.CompareNode.*;
+
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+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.util.*;
+import com.oracle.graal.replacements.SnippetTemplate.*;
+
+/**
+ * Helper class for lowering {@link InstanceOfNode}s with snippets. The majority of the complexity
+ * in such a lowering derives from the fact that {@link InstanceOfNode} is a floating node. A
+ * snippet used to lower an {@link InstanceOfNode} will almost always incorporate control flow and
+ * replacing a floating node with control flow is not trivial.
+ * <p>
+ * The mechanism implemented in this class ensures that the graph for an instanceof snippet is
+ * instantiated once per {@link InstanceOfNode} being lowered. The result produced is then re-used
+ * by all usages of the node. Additionally, if there is a single usage that is an {@link IfNode},
+ * the control flow in the snippet is connected directly to the true and false successors of the
+ * {@link IfNode}. This avoids materializing the instanceof test as a boolean which is then retested
+ * by the {@link IfNode}.
+ */
+public abstract class InstanceOfSnippetsTemplates<T extends Snippets> extends AbstractTemplates<T> {
+
+    public InstanceOfSnippetsTemplates(MetaAccessProvider runtime, Assumptions assumptions, TargetDescription target, Class<T> snippetsClass) {
+        super(runtime, assumptions, target, snippetsClass);
+    }
+
+    /**
+     * The key and arguments used to retrieve and instantiate an instanceof snippet template.
+     */
+    public static class KeyAndArguments {
+
+        public final Key key;
+        public final Arguments arguments;
+
+        public KeyAndArguments(Key key, Arguments arguments) {
+            this.key = key;
+            this.arguments = arguments;
+        }
+
+    }
+
+    /**
+     * Gets the key and arguments used to retrieve and instantiate an instanceof snippet template.
+     */
+    protected abstract KeyAndArguments getKeyAndArguments(InstanceOfUsageReplacer replacer, LoweringTool tool);
+
+    public void lower(FloatingNode instanceOf, LoweringTool tool) {
+        assert instanceOf instanceof InstanceOfNode || instanceOf instanceof InstanceOfDynamicNode;
+        List<Node> usages = instanceOf.usages().snapshot();
+        int nUsages = usages.size();
+
+        Instantiation instantiation = new Instantiation();
+        for (Node usage : usages) {
+            final StructuredGraph graph = (StructuredGraph) usage.graph();
+
+            InstanceOfUsageReplacer replacer = createReplacer(instanceOf, tool, nUsages, instantiation, usage, graph);
+
+            if (instantiation.isInitialized()) {
+                // No need to re-instantiate the snippet - just re-use its result
+                replacer.replaceUsingInstantiation();
+            } else {
+                KeyAndArguments keyAndArguments = getKeyAndArguments(replacer, tool);
+                SnippetTemplate template = cache.get(keyAndArguments.key, assumptions);
+                template.instantiate(runtime, instanceOf, replacer, tool, keyAndArguments.arguments);
+            }
+        }
+
+        assert instanceOf.usages().isEmpty();
+        if (!instanceOf.isDeleted()) {
+            GraphUtil.killWithUnusedFloatingInputs(instanceOf);
+        }
+    }
+
+    /**
+     * Gets the specific replacer object used to replace the usage of an instanceof node with the
+     * result of an instantiated instanceof snippet.
+     */
+    protected InstanceOfUsageReplacer createReplacer(FloatingNode instanceOf, LoweringTool tool, int nUsages, Instantiation instantiation, Node usage, final StructuredGraph graph) {
+        InstanceOfUsageReplacer replacer;
+        if (usage instanceof IfNode) {
+            replacer = new IfUsageReplacer(instantiation, ConstantNode.forInt(1, graph), ConstantNode.forInt(0, graph), instanceOf, (IfNode) usage, nUsages == 1, tool);
+        } else {
+            assert usage instanceof ConditionalNode : "unexpected usage of " + instanceOf + ": " + usage;
+            ConditionalNode c = (ConditionalNode) usage;
+            replacer = new ConditionalUsageReplacer(instantiation, c.trueValue(), c.falseValue(), instanceOf, c);
+        }
+        return replacer;
+    }
+
+    /**
+     * The result of an instantiating an instanceof snippet. This enables a snippet instantiation to
+     * be re-used which reduces compile time and produces better code.
+     */
+    public static final class Instantiation {
+
+        private PhiNode result;
+        private CompareNode condition;
+        private ValueNode trueValue;
+        private ValueNode falseValue;
+
+        /**
+         * Determines if the instantiation has occurred.
+         */
+        boolean isInitialized() {
+            return result != null;
+        }
+
+        void initialize(PhiNode phi, ValueNode t, ValueNode f) {
+            assert !isInitialized();
+            this.result = phi;
+            this.trueValue = t;
+            this.falseValue = f;
+        }
+
+        /**
+         * Gets the result of this instantiation as a condition.
+         * 
+         * @param testValue the returned condition is true if the result is equal to this value
+         */
+        CompareNode asCondition(ValueNode testValue) {
+            assert isInitialized();
+            if (condition == null || condition.y() != testValue) {
+                // Re-use previously generated condition if the trueValue for the test is the same
+                condition = createCompareNode(Condition.EQ, result, testValue);
+            }
+            return condition;
+        }
+
+        /**
+         * Gets the result of the instantiation as a materialized value.
+         * 
+         * @param t the true value for the materialization
+         * @param f the false value for the materialization
+         */
+        ValueNode asMaterialization(ValueNode t, ValueNode f) {
+            assert isInitialized();
+            if (t == this.trueValue && f == this.falseValue) {
+                // Can simply use the phi result if the same materialized values are expected.
+                return result;
+            } else {
+                return t.graph().unique(new ConditionalNode(asCondition(trueValue), t, f));
+            }
+        }
+    }
+
+    /**
+     * Replaces a usage of an {@link InstanceOfNode} or {@link InstanceOfDynamicNode}.
+     */
+    public abstract static class InstanceOfUsageReplacer implements UsageReplacer {
+
+        public final Instantiation instantiation;
+        public final FloatingNode instanceOf;
+        public final ValueNode trueValue;
+        public final ValueNode falseValue;
+
+        public InstanceOfUsageReplacer(Instantiation instantiation, FloatingNode instanceOf, ValueNode trueValue, ValueNode falseValue) {
+            assert instanceOf instanceof InstanceOfNode || instanceOf instanceof InstanceOfDynamicNode;
+            this.instantiation = instantiation;
+            this.instanceOf = instanceOf;
+            this.trueValue = trueValue;
+            this.falseValue = falseValue;
+        }
+
+        /**
+         * Does the replacement based on a previously snippet instantiation.
+         */
+        public abstract void replaceUsingInstantiation();
+    }
+
+    /**
+     * Replaces an {@link IfNode} usage of an {@link InstanceOfNode} or
+     * {@link InstanceOfDynamicNode}.
+     */
+    public static class IfUsageReplacer extends InstanceOfUsageReplacer {
+
+        private final boolean solitaryUsage;
+        private final IfNode usage;
+        private final boolean sameBlock;
+
+        public IfUsageReplacer(Instantiation instantiation, ValueNode trueValue, ValueNode falseValue, FloatingNode instanceOf, IfNode usage, boolean solitaryUsage, LoweringTool tool) {
+            super(instantiation, instanceOf, trueValue, falseValue);
+            this.sameBlock = tool.getBlockFor(usage) == tool.getBlockFor(instanceOf);
+            this.solitaryUsage = solitaryUsage;
+            this.usage = usage;
+        }
+
+        @Override
+        public void replaceUsingInstantiation() {
+            usage.replaceFirstInput(instanceOf, instantiation.asCondition(trueValue));
+        }
+
+        private boolean usageFollowsInstantiation() {
+            return instantiation.result != null && instantiation.result.merge().next() == usage;
+        }
+
+        @Override
+        public void replace(ValueNode oldNode, ValueNode newNode) {
+            assert newNode instanceof PhiNode;
+            assert oldNode == instanceOf;
+            if (sameBlock && solitaryUsage && usageFollowsInstantiation()) {
+                removeIntermediateMaterialization(newNode);
+            } else {
+                newNode.inferStamp();
+                instantiation.initialize((PhiNode) newNode, trueValue, falseValue);
+                usage.replaceFirstInput(oldNode, instantiation.asCondition(trueValue));
+            }
+        }
+
+        /**
+         * Directly wires the incoming edges of the merge at the end of the snippet to the outgoing
+         * edges of the IfNode that uses the materialized result.
+         */
+        private void removeIntermediateMaterialization(ValueNode newNode) {
+            IfNode ifNode = usage;
+            PhiNode phi = (PhiNode) newNode;
+            MergeNode merge = phi.merge();
+            assert merge.stateAfter() == null;
+
+            List<EndNode> mergePredecessors = merge.cfgPredecessors().snapshot();
+            assert phi.valueCount() == mergePredecessors.size();
+
+            List<EndNode> falseEnds = new ArrayList<>(mergePredecessors.size());
+            List<EndNode> trueEnds = new ArrayList<>(mergePredecessors.size());
+
+            int endIndex = 0;
+            for (EndNode end : mergePredecessors) {
+                ValueNode endValue = phi.valueAt(endIndex++);
+                if (endValue == trueValue) {
+                    trueEnds.add(end);
+                } else {
+                    assert endValue == falseValue;
+                    falseEnds.add(end);
+                }
+            }
+
+            BeginNode trueSuccessor = ifNode.trueSuccessor();
+            BeginNode falseSuccessor = ifNode.falseSuccessor();
+            ifNode.setTrueSuccessor(null);
+            ifNode.setFalseSuccessor(null);
+
+            connectEnds(merge, trueEnds, trueSuccessor);
+            connectEnds(merge, falseEnds, falseSuccessor);
+
+            GraphUtil.killCFG(merge);
+            GraphUtil.killCFG(ifNode);
+
+            assert !merge.isAlive() : merge;
+            assert !phi.isAlive() : phi;
+        }
+
+        private static void connectEnds(MergeNode merge, List<EndNode> ends, BeginNode successor) {
+            if (ends.size() == 0) {
+                // InstanceOf has been lowered to always true or always false - this successor is
+                // therefore unreachable.
+                GraphUtil.killCFG(successor);
+            } else if (ends.size() == 1) {
+                EndNode end = ends.get(0);
+                ((FixedWithNextNode) end.predecessor()).setNext(successor);
+                merge.removeEnd(end);
+                GraphUtil.killCFG(end);
+            } else {
+                assert ends.size() > 1;
+                MergeNode newMerge = merge.graph().add(new MergeNode());
+
+                for (EndNode end : ends) {
+                    newMerge.addForwardEnd(end);
+                }
+                newMerge.setNext(successor);
+            }
+        }
+    }
+
+    /**
+     * Replaces a {@link ConditionalNode} usage of an {@link InstanceOfNode} or
+     * {@link InstanceOfDynamicNode}.
+     */
+    public static class ConditionalUsageReplacer extends InstanceOfUsageReplacer {
+
+        public final ConditionalNode usage;
+
+        public ConditionalUsageReplacer(Instantiation instantiation, ValueNode trueValue, ValueNode falseValue, FloatingNode instanceOf, ConditionalNode usage) {
+            super(instantiation, instanceOf, trueValue, falseValue);
+            this.usage = usage;
+        }
+
+        @Override
+        public void replaceUsingInstantiation() {
+            ValueNode newValue = instantiation.asMaterialization(trueValue, falseValue);
+            usage.replaceAtUsages(newValue);
+            usage.clearInputs();
+            assert usage.usages().isEmpty();
+            GraphUtil.killWithUnusedFloatingInputs(usage);
+        }
+
+        @Override
+        public void replace(ValueNode oldNode, ValueNode newNode) {
+            assert newNode instanceof PhiNode;
+            assert oldNode == instanceOf;
+            newNode.inferStamp();
+            instantiation.initialize((PhiNode) newNode, trueValue, falseValue);
+            usage.replaceAtUsages(newNode);
+            usage.clearInputs();
+            assert usage.usages().isEmpty();
+            GraphUtil.killWithUnusedFloatingInputs(usage);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/IntegerSubstitutions.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.replacements;
+
+import com.oracle.graal.replacements.ClassSubstitution.*;
+import com.oracle.graal.replacements.nodes.*;
+
+@ClassSubstitution(Integer.class)
+public class IntegerSubstitutions {
+
+    @MethodSubstitution
+    public static int reverseBytes(int i) {
+        return ReverseBytesNode.reverse(i);
+    }
+
+    @MethodSubstitution
+    public static int numberOfLeadingZeros(int i) {
+        if (i == 0) {
+            return 32;
+        }
+        return 31 - BitScanReverseNode.scan(i);
+    }
+
+    @MethodSubstitution
+    public static int numberOfTrailingZeros(int i) {
+        if (i == 0) {
+            return 32;
+        }
+        return BitScanForwardNode.scan(i);
+    }
+
+    @MethodSubstitution
+    public static int bitCount(int i) {
+        return BitCountNode.bitCount(i);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/JavacBug.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2011, 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.replacements;
+
+/**
+ * Used to indicate that an otherwise strange looking code pattern is required to work around a bug
+ * in javac.
+ */
+public @interface JavacBug {
+
+    /**
+     * A description of the bug. Only really useful if there is no existing entry for the bug in the
+     * <a href="http://bugs.sun.com/bugdatabase/">Bug Database</a>.
+     */
+    String value() default "";
+
+    /**
+     * An identifier in the <a href="http://bugs.sun.com/bugdatabase/">Bug Database</a>.
+     */
+    int id() default 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/Log.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.replacements;
+
+import java.io.*;
+
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.Node.ConstantNodeParameter;
+import com.oracle.graal.graph.Node.NodeIntrinsic;
+import com.oracle.graal.nodes.extended.*;
+
+//JaCoCo Exclude
+
+/**
+ * Provides {@link PrintStream}-like logging facility. This should only be used in
+ * {@linkplain Snippet snippets}.
+ */
+public final class Log {
+
+    public static final Descriptor LOG_PRIMITIVE = new Descriptor("logPrimitive", false, void.class, int.class, long.class, boolean.class);
+    public static final Descriptor LOG_OBJECT = new Descriptor("logObject", false, void.class, Object.class, int.class);
+    public static final Descriptor LOG_PRINTF = new Descriptor("logPrintf", false, void.class, Object.class, long.class, long.class, long.class);
+
+    // Note: Must be kept in sync with constants in c1_Runtime1.hpp
+    private static final int LOG_OBJECT_NEWLINE = 0x01;
+    private static final int LOG_OBJECT_STRING = 0x02;
+    private static final int LOG_OBJECT_ADDRESS = 0x04;
+
+    @NodeIntrinsic(RuntimeCallNode.class)
+    private static native void log(@ConstantNodeParameter Descriptor logObject, Object object, int flags);
+
+    @NodeIntrinsic(RuntimeCallNode.class)
+    private static native void log(@ConstantNodeParameter Descriptor logPrimitive, int typeChar, long value, boolean newline);
+
+    @NodeIntrinsic(RuntimeCallNode.class)
+    private static native void printf(@ConstantNodeParameter Descriptor logPrintf, String format, long v1, long v2, long v3);
+
+    public static void print(boolean value) {
+        log(LOG_PRIMITIVE, Kind.Boolean.getTypeChar(), value ? 1L : 0L, false);
+    }
+
+    public static void print(byte value) {
+        log(LOG_PRIMITIVE, Kind.Byte.getTypeChar(), value, false);
+    }
+
+    public static void print(char value) {
+        log(LOG_PRIMITIVE, Kind.Char.getTypeChar(), value, false);
+    }
+
+    public static void print(short value) {
+        log(LOG_PRIMITIVE, Kind.Short.getTypeChar(), value, false);
+    }
+
+    public static void print(int value) {
+        log(LOG_PRIMITIVE, Kind.Int.getTypeChar(), value, false);
+    }
+
+    public static void print(long value) {
+        log(LOG_PRIMITIVE, Kind.Long.getTypeChar(), value, false);
+    }
+
+    /**
+     * Prints a formatted string to the log stream.
+     * 
+     * @param format a C style printf format value that can contain at most one conversion specifier
+     *            (i.e., a sequence of characters starting with '%').
+     * @param value the value associated with the conversion specifier
+     */
+    public static void printf(String format, long value) {
+        printf(LOG_PRINTF, format, value, 0L, 0L);
+    }
+
+    public static void printf(String format, long v1, long v2) {
+        printf(LOG_PRINTF, format, v1, v2, 0L);
+    }
+
+    public static void printf(String format, long v1, long v2, long v3) {
+        printf(LOG_PRINTF, format, v1, v2, v3);
+    }
+
+    public static void print(float value) {
+        if (Float.isNaN(value)) {
+            print("NaN");
+        } else if (value == Float.POSITIVE_INFINITY) {
+            print("Infinity");
+        } else if (value == Float.NEGATIVE_INFINITY) {
+            print("-Infinity");
+        } else {
+            log(LOG_PRIMITIVE, Kind.Float.getTypeChar(), Float.floatToRawIntBits(value), false);
+        }
+    }
+
+    public static void print(double value) {
+        if (Double.isNaN(value)) {
+            print("NaN");
+        } else if (value == Double.POSITIVE_INFINITY) {
+            print("Infinity");
+        } else if (value == Double.NEGATIVE_INFINITY) {
+            print("-Infinity");
+        } else {
+            log(LOG_PRIMITIVE, Kind.Double.getTypeChar(), Double.doubleToRawLongBits(value), false);
+        }
+    }
+
+    public static void print(String value) {
+        log(LOG_OBJECT, value, LOG_OBJECT_STRING);
+    }
+
+    public static void printAddress(Object o) {
+        log(LOG_OBJECT, o, LOG_OBJECT_ADDRESS);
+    }
+
+    public static void printObject(Object o) {
+        log(LOG_OBJECT, o, 0);
+    }
+
+    public static void println(boolean value) {
+        log(LOG_PRIMITIVE, Kind.Boolean.getTypeChar(), value ? 1L : 0L, true);
+    }
+
+    public static void println(byte value) {
+        log(LOG_PRIMITIVE, Kind.Byte.getTypeChar(), value, true);
+    }
+
+    public static void println(char value) {
+        log(LOG_PRIMITIVE, Kind.Char.getTypeChar(), value, true);
+    }
+
+    public static void println(short value) {
+        log(LOG_PRIMITIVE, Kind.Short.getTypeChar(), value, true);
+    }
+
+    public static void println(int value) {
+        log(LOG_PRIMITIVE, Kind.Int.getTypeChar(), value, true);
+    }
+
+    public static void println(long value) {
+        log(LOG_PRIMITIVE, Kind.Long.getTypeChar(), value, true);
+    }
+
+    public static void println(float value) {
+        if (Float.isNaN(value)) {
+            println("NaN");
+        } else if (value == Float.POSITIVE_INFINITY) {
+            println("Infinity");
+        } else if (value == Float.NEGATIVE_INFINITY) {
+            println("-Infinity");
+        } else {
+            log(LOG_PRIMITIVE, Kind.Float.getTypeChar(), Float.floatToRawIntBits(value), true);
+        }
+    }
+
+    public static void println(double value) {
+        if (Double.isNaN(value)) {
+            println("NaN");
+        } else if (value == Double.POSITIVE_INFINITY) {
+            println("Infinity");
+        } else if (value == Double.NEGATIVE_INFINITY) {
+            println("-Infinity");
+        } else {
+            log(LOG_PRIMITIVE, Kind.Double.getTypeChar(), Double.doubleToRawLongBits(value), true);
+        }
+    }
+
+    public static void println(String value) {
+        log(LOG_OBJECT, value, LOG_OBJECT_NEWLINE | LOG_OBJECT_STRING);
+    }
+
+    public static void printlnAddress(Object o) {
+        log(LOG_OBJECT, o, LOG_OBJECT_NEWLINE | LOG_OBJECT_ADDRESS);
+    }
+
+    public static void printlnObject(Object o) {
+        log(LOG_OBJECT, o, LOG_OBJECT_NEWLINE);
+    }
+
+    public static void println() {
+        println("");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/LongSubstitutions.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.replacements;
+
+import com.oracle.graal.replacements.ClassSubstitution.*;
+import com.oracle.graal.replacements.nodes.*;
+
+@ClassSubstitution(Long.class)
+public class LongSubstitutions {
+
+    @MethodSubstitution
+    public static long reverseBytes(long i) {
+        return ReverseBytesNode.reverse(i);
+    }
+
+    @MethodSubstitution
+    public static int numberOfLeadingZeros(long i) {
+        if (i == 0) {
+            return 64;
+        }
+        return 63 - BitScanReverseNode.scan(i);
+    }
+
+    @MethodSubstitution
+    public static int numberOfTrailingZeros(long i) {
+        if (i == 0) {
+            return 64;
+        }
+        return BitScanForwardNode.scan(i);
+    }
+
+    @MethodSubstitution
+    public static int bitCount(long i) {
+        return BitCountNode.bitCount(i);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/MathSubstitutionsX86.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2011, 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.replacements;
+
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
+import com.oracle.graal.graph.Node.ConstantNodeParameter;
+import com.oracle.graal.graph.Node.NodeIntrinsic;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.replacements.ClassSubstitution.*;
+import com.oracle.graal.replacements.nodes.*;
+import com.oracle.graal.replacements.nodes.MathIntrinsicNode.*;
+
+/**
+ * Substitutions for {@link java.lang.Math} methods.
+ */
+@ClassSubstitution(java.lang.Math.class)
+public class MathSubstitutionsX86 {
+
+    private static final double PI_4 = 0.7853981633974483;
+
+    @MethodSubstitution
+    public static double abs(double x) {
+        return MathIntrinsicNode.compute(x, Operation.ABS);
+    }
+
+    @MethodSubstitution
+    public static double sqrt(double x) {
+        return MathIntrinsicNode.compute(x, Operation.SQRT);
+    }
+
+    @MethodSubstitution
+    public static double log(double x) {
+        return MathIntrinsicNode.compute(x, Operation.LOG);
+    }
+
+    @MethodSubstitution
+    public static double log10(double x) {
+        return MathIntrinsicNode.compute(x, Operation.LOG10);
+    }
+
+    // NOTE on snippets below:
+    // Math.sin(), .cos() and .tan() guarantee a value within 1 ULP of the
+    // exact result, but x87 trigonometric FPU instructions are only that
+    // accurate within [-pi/4, pi/4]. Examine the passed value and provide
+    // a slow path for inputs outside of that interval.
+
+    @MethodSubstitution
+    public static double sin(double x) {
+        if (abs(x) < PI_4) {
+            return MathIntrinsicNode.compute(x, Operation.SIN);
+        } else {
+            return callDouble(ARITHMETIC_SIN, x);
+        }
+    }
+
+    @MethodSubstitution
+    public static double cos(double x) {
+        if (abs(x) < PI_4) {
+            return MathIntrinsicNode.compute(x, Operation.COS);
+        } else {
+            return callDouble(ARITHMETIC_COS, x);
+        }
+    }
+
+    @MethodSubstitution
+    public static double tan(double x) {
+        if (abs(x) < PI_4) {
+            return MathIntrinsicNode.compute(x, Operation.TAN);
+        } else {
+            return callDouble(ARITHMETIC_TAN, x);
+        }
+    }
+
+    public static final Descriptor ARITHMETIC_SIN = new Descriptor("arithmeticSin", false, double.class, double.class);
+    public static final Descriptor ARITHMETIC_COS = new Descriptor("arithmeticCos", false, double.class, double.class);
+    public static final Descriptor ARITHMETIC_TAN = new Descriptor("arithmeticTan", false, double.class, double.class);
+
+    @NodeIntrinsic(value = RuntimeCallNode.class, setStampFromReturnType = true)
+    public static native double callDouble(@ConstantNodeParameter Descriptor descriptor, double value);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2011, 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.replacements;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.replacements.ClassSubstitution.*;
+
+/**
+ * Substitutions for improving the performance of some critical methods in {@link NodeClass}
+ * methods. These substitutions improve the performance by forcing the relevant methods to be
+ * inlined (intrinsification being a special form of inlining) and removing a checked cast. The
+ * latter cannot be done directly in Java code as {@link UnsafeCastNode} is not available to the
+ * project containing {@link NodeClass}.
+ */
+@ClassSubstitution(NodeClass.class)
+public class NodeClassSubstitutions {
+
+    @MethodSubstitution
+    private static Node getNode(Node node, long offset) {
+        return UnsafeCastNode.unsafeCast(UnsafeLoadNode.load(node, 0, offset, Kind.Object), Node.class, false, false);
+    }
+
+    @MethodSubstitution
+    private static NodeList getNodeList(Node node, long offset) {
+        return UnsafeCastNode.unsafeCast(UnsafeLoadNode.load(node, 0, offset, Kind.Object), NodeList.class, false, false);
+    }
+
+    @MethodSubstitution
+    private static void putNode(Node node, long offset, Node value) {
+        UnsafeStoreNode.store(node, 0, offset, value, Kind.Object);
+    }
+
+    @MethodSubstitution
+    private static void putNodeList(Node node, long offset, NodeList value) {
+        UnsafeStoreNode.store(node, 0, offset, value, Kind.Object);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,397 @@
+/*
+ * Copyright (c) 2011, 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.replacements;
+
+import static com.oracle.graal.api.meta.MetaUtil.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.Node.ConstantNodeParameter;
+import com.oracle.graal.graph.Node.NodeIntrinsic;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.nodes.util.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.replacements.Snippet.*;
+
+/**
+ * Replaces calls to {@link NodeIntrinsic}s with nodes and calls to methods annotated with
+ * {@link Fold} with the result of invoking the annotated method via reflection.
+ */
+public class NodeIntrinsificationPhase extends Phase {
+
+    private final MetaAccessProvider runtime;
+    private final BoxingMethodPool pool;
+
+    public NodeIntrinsificationPhase(MetaAccessProvider runtime, BoxingMethodPool pool) {
+        this.runtime = runtime;
+        this.pool = pool;
+    }
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        for (Invoke i : graph.getInvokes()) {
+            if (i.callTarget() instanceof MethodCallTargetNode) {
+                tryIntrinsify(i);
+            }
+        }
+    }
+
+    public static Class<?>[] signatureToTypes(Signature signature, ResolvedJavaType accessingClass) {
+        int count = signature.getParameterCount(false);
+        Class<?>[] result = new Class<?>[count];
+        for (int i = 0; i < result.length; ++i) {
+            result[i] = getMirrorOrFail(signature.getParameterType(i, accessingClass).resolve(accessingClass), Thread.currentThread().getContextClassLoader());
+        }
+        return result;
+    }
+
+    private boolean tryIntrinsify(Invoke invoke) {
+        ResolvedJavaMethod target = invoke.methodCallTarget().targetMethod();
+        NodeIntrinsic intrinsic = target.getAnnotation(Node.NodeIntrinsic.class);
+        ResolvedJavaType declaringClass = target.getDeclaringClass();
+        if (intrinsic != null) {
+            assert target.getAnnotation(Fold.class) == null;
+
+            Class<?>[] parameterTypes = signatureToTypes(target.getSignature(), declaringClass);
+            ResolvedJavaType returnType = target.getSignature().getReturnType(declaringClass).resolve(declaringClass);
+
+            // Prepare the arguments for the reflective constructor call on the node class.
+            Object[] nodeConstructorArguments = prepareArguments(invoke, parameterTypes, target, false);
+            if (nodeConstructorArguments == null) {
+                return false;
+            }
+
+            // Create the new node instance.
+            Class<?> c = getNodeClass(target, intrinsic);
+            Node newInstance = createNodeInstance(c, parameterTypes, returnType, intrinsic.setStampFromReturnType(), nodeConstructorArguments);
+
+            // Replace the invoke with the new node.
+            invoke.node().graph().add(newInstance);
+            invoke.intrinsify(newInstance);
+
+            // Clean up checkcast instructions inserted by javac if the return type is generic.
+            cleanUpReturnCheckCast(newInstance);
+        } else if (target.getAnnotation(Fold.class) != null) {
+            Class<?>[] parameterTypes = signatureToTypes(target.getSignature(), declaringClass);
+
+            // Prepare the arguments for the reflective method call
+            Object[] arguments = prepareArguments(invoke, parameterTypes, target, true);
+            if (arguments == null) {
+                return false;
+            }
+            Object receiver = null;
+            if (!invoke.methodCallTarget().isStatic()) {
+                receiver = arguments[0];
+                arguments = Arrays.asList(arguments).subList(1, arguments.length).toArray();
+            }
+
+            // Call the method
+            Constant constant = callMethod(target.getSignature().getReturnKind(), getMirrorOrFail(declaringClass, Thread.currentThread().getContextClassLoader()), target.getName(), parameterTypes,
+                            receiver, arguments);
+
+            if (constant != null) {
+                // Replace the invoke with the result of the call
+                ConstantNode node = ConstantNode.forConstant(constant, runtime, invoke.node().graph());
+                invoke.intrinsify(node);
+
+                // Clean up checkcast instructions inserted by javac if the return type is generic.
+                cleanUpReturnCheckCast(node);
+            } else {
+                // Remove the invoke
+                invoke.intrinsify(null);
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Converts the arguments of an invoke node to object values suitable for use as the arguments
+     * to a reflective invocation of a Java constructor or method.
+     * 
+     * @param folding specifies if the invocation is for handling a {@link Fold} annotation
+     * @return the arguments for the reflective invocation or null if an argument of {@code invoke}
+     *         that is expected to be constant isn't
+     */
+    private Object[] prepareArguments(Invoke invoke, Class<?>[] parameterTypes, ResolvedJavaMethod target, boolean folding) {
+        NodeInputList<ValueNode> arguments = invoke.callTarget().arguments();
+        Object[] reflectionCallArguments = new Object[arguments.size()];
+        for (int i = 0; i < reflectionCallArguments.length; ++i) {
+            int parameterIndex = i;
+            if (!invoke.methodCallTarget().isStatic()) {
+                parameterIndex--;
+            }
+            ValueNode argument = tryBoxingElimination(parameterIndex, target, arguments.get(i));
+            if (folding || MetaUtil.getParameterAnnotation(ConstantNodeParameter.class, parameterIndex, target) != null) {
+                if (!(argument instanceof ConstantNode)) {
+                    return null;
+                }
+                ConstantNode constantNode = (ConstantNode) argument;
+                Constant constant = constantNode.asConstant();
+                Object o = constant.asBoxedValue();
+                if (o instanceof Class<?>) {
+                    reflectionCallArguments[i] = runtime.lookupJavaType((Class<?>) o);
+                    parameterTypes[i] = ResolvedJavaType.class;
+                } else {
+                    if (parameterTypes[i] == boolean.class) {
+                        reflectionCallArguments[i] = Boolean.valueOf(constant.asInt() != 0);
+                    } else if (parameterTypes[i] == byte.class) {
+                        reflectionCallArguments[i] = Byte.valueOf((byte) constant.asInt());
+                    } else if (parameterTypes[i] == short.class) {
+                        reflectionCallArguments[i] = Short.valueOf((short) constant.asInt());
+                    } else if (parameterTypes[i] == char.class) {
+                        reflectionCallArguments[i] = Character.valueOf((char) constant.asInt());
+                    } else {
+                        reflectionCallArguments[i] = o;
+                    }
+                }
+            } else {
+                reflectionCallArguments[i] = argument;
+                parameterTypes[i] = ValueNode.class;
+            }
+        }
+        return reflectionCallArguments;
+    }
+
+    private static Class<?> getNodeClass(ResolvedJavaMethod target, NodeIntrinsic intrinsic) {
+        Class<?> result = intrinsic.value();
+        if (result == NodeIntrinsic.class) {
+            return getMirrorOrFail(target.getDeclaringClass(), Thread.currentThread().getContextClassLoader());
+        }
+        assert Node.class.isAssignableFrom(result);
+        return result;
+    }
+
+    private ValueNode tryBoxingElimination(int parameterIndex, ResolvedJavaMethod target, ValueNode node) {
+        if (parameterIndex >= 0) {
+            Type type = target.getGenericParameterTypes()[parameterIndex];
+            if (type instanceof TypeVariable) {
+                TypeVariable typeVariable = (TypeVariable) type;
+                if (typeVariable.getBounds().length == 1) {
+                    Type boundType = typeVariable.getBounds()[0];
+                    if (boundType instanceof Class && ((Class) boundType).getSuperclass() == null) {
+                        // Unbound generic => try boxing elimination
+                        if (node.usages().count() == 2) {
+                            if (node instanceof Invoke) {
+                                Invoke invokeNode = (Invoke) node;
+                                MethodCallTargetNode callTarget = invokeNode.methodCallTarget();
+                                if (pool.isBoxingMethod(callTarget.targetMethod())) {
+                                    FrameState stateAfter = invokeNode.stateAfter();
+                                    assert stateAfter.usages().count() == 1;
+                                    invokeNode.node().replaceAtUsages(null);
+                                    ValueNode result = callTarget.arguments().get(0);
+                                    StructuredGraph graph = (StructuredGraph) node.graph();
+                                    if (invokeNode instanceof InvokeWithExceptionNode) {
+                                        // Destroy exception edge & clear stateAfter.
+                                        InvokeWithExceptionNode invokeWithExceptionNode = (InvokeWithExceptionNode) invokeNode;
+
+                                        invokeWithExceptionNode.killExceptionEdge();
+                                        graph.removeSplit(invokeWithExceptionNode, invokeWithExceptionNode.next());
+                                    } else {
+                                        graph.removeFixed((InvokeNode) invokeNode);
+                                    }
+                                    stateAfter.safeDelete();
+                                    GraphUtil.propagateKill(callTarget);
+                                    return result;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return node;
+    }
+
+    private static Class asBoxedType(Class type) {
+        if (!type.isPrimitive()) {
+            return type;
+        }
+
+        if (Boolean.TYPE == type) {
+            return Boolean.class;
+        }
+        if (Character.TYPE == type) {
+            return Character.class;
+        }
+        if (Byte.TYPE == type) {
+            return Byte.class;
+        }
+        if (Short.TYPE == type) {
+            return Short.class;
+        }
+        if (Integer.TYPE == type) {
+            return Integer.class;
+        }
+        if (Long.TYPE == type) {
+            return Long.class;
+        }
+        if (Float.TYPE == type) {
+            return Float.class;
+        }
+        assert Double.TYPE == type;
+        return Double.class;
+    }
+
+    static final int VARARGS = 0x00000080;
+
+    private static Node createNodeInstance(Class<?> nodeClass, Class<?>[] parameterTypes, ResolvedJavaType returnType, boolean setStampFromReturnType, Object[] nodeConstructorArguments) {
+        Object[] arguments = null;
+        Constructor<?> constructor = null;
+        nextConstructor: for (Constructor c : nodeClass.getDeclaredConstructors()) {
+            Class[] signature = c.getParameterTypes();
+            if ((c.getModifiers() & VARARGS) != 0) {
+                int fixedArgs = signature.length - 1;
+                if (parameterTypes.length < fixedArgs) {
+                    continue nextConstructor;
+                }
+
+                for (int i = 0; i < fixedArgs; i++) {
+                    if (!parameterTypes[i].equals(signature[i])) {
+                        continue nextConstructor;
+                    }
+                }
+
+                Class componentType = signature[fixedArgs].getComponentType();
+                assert componentType != null : "expected last parameter of varargs constructor " + c + " to be an array type";
+                Class boxedType = asBoxedType(componentType);
+                for (int i = fixedArgs; i < nodeConstructorArguments.length; i++) {
+                    if (!boxedType.isInstance(nodeConstructorArguments[i])) {
+                        continue nextConstructor;
+                    }
+                }
+
+                arguments = Arrays.copyOf(nodeConstructorArguments, fixedArgs + 1);
+                int varargsLength = nodeConstructorArguments.length - fixedArgs;
+                Object varargs = Array.newInstance(componentType, varargsLength);
+                for (int i = fixedArgs; i < nodeConstructorArguments.length; i++) {
+                    Array.set(varargs, i - fixedArgs, nodeConstructorArguments[i]);
+                }
+                arguments[fixedArgs] = varargs;
+                constructor = c;
+                break;
+            } else if (Arrays.equals(parameterTypes, signature)) {
+                arguments = nodeConstructorArguments;
+                constructor = c;
+                break;
+            }
+        }
+        if (constructor == null) {
+            throw new GraalInternalError("Could not find constructor in " + nodeClass + " compatible with signature " + Arrays.toString(parameterTypes));
+        }
+        constructor.setAccessible(true);
+        try {
+            ValueNode intrinsicNode = (ValueNode) constructor.newInstance(arguments);
+            if (setStampFromReturnType) {
+                if (returnType.getKind() == Kind.Object) {
+                    intrinsicNode.setStamp(StampFactory.declared(returnType));
+                } else {
+                    intrinsicNode.setStamp(StampFactory.forKind(returnType.getKind()));
+                }
+            }
+            return intrinsicNode;
+        } catch (Exception e) {
+            throw new RuntimeException(constructor + Arrays.toString(nodeConstructorArguments), e);
+        }
+    }
+
+    /**
+     * Calls a Java method via reflection.
+     */
+    private static Constant callMethod(Kind returnKind, Class<?> holder, String name, Class<?>[] parameterTypes, Object receiver, Object[] arguments) {
+        Method method;
+        try {
+            method = holder.getDeclaredMethod(name, parameterTypes);
+            method.setAccessible(true);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        try {
+            Object result = method.invoke(receiver, arguments);
+            if (result == null) {
+                return null;
+            }
+            return Constant.forBoxed(returnKind, result);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static String sourceLocation(Node n) {
+        String loc = GraphUtil.approxSourceLocation(n);
+        return loc == null ? "<unknown>" : loc;
+    }
+
+    public void cleanUpReturnCheckCast(Node newInstance) {
+        if (newInstance instanceof ValueNode && (((ValueNode) newInstance).kind() != Kind.Object || ((ValueNode) newInstance).stamp() == StampFactory.forNodeIntrinsic())) {
+            StructuredGraph graph = (StructuredGraph) newInstance.graph();
+            for (CheckCastNode checkCastNode : newInstance.usages().filter(CheckCastNode.class).snapshot()) {
+                for (ProxyNode vpn : checkCastNode.usages().filter(ProxyNode.class).snapshot()) {
+                    graph.replaceFloating(vpn, checkCastNode);
+                }
+                for (Node checkCastUsage : checkCastNode.usages().snapshot()) {
+                    if (checkCastUsage instanceof ValueAnchorNode) {
+                        ValueAnchorNode valueAnchorNode = (ValueAnchorNode) checkCastUsage;
+                        graph.removeFixed(valueAnchorNode);
+                    } else if (checkCastUsage instanceof MethodCallTargetNode) {
+                        MethodCallTargetNode checkCastCallTarget = (MethodCallTargetNode) checkCastUsage;
+                        if (pool.isUnboxingMethod(checkCastCallTarget.targetMethod())) {
+                            Invoke invokeNode = checkCastCallTarget.invoke();
+                            invokeNode.node().replaceAtUsages(newInstance);
+                            if (invokeNode instanceof InvokeWithExceptionNode) {
+                                // Destroy exception edge & clear stateAfter.
+                                InvokeWithExceptionNode invokeWithExceptionNode = (InvokeWithExceptionNode) invokeNode;
+
+                                invokeWithExceptionNode.killExceptionEdge();
+                                graph.removeSplit(invokeWithExceptionNode, invokeWithExceptionNode.next());
+                            } else {
+                                graph.removeFixed((InvokeNode) invokeNode);
+                            }
+                            checkCastCallTarget.safeDelete();
+                        } else {
+                            assert checkCastCallTarget.targetMethod().getAnnotation(NodeIntrinsic.class) != null : "checkcast at " + sourceLocation(checkCastNode) +
+                                            " not used by an unboxing method or node intrinsic, but by a call at " + sourceLocation(checkCastCallTarget.usages().first()) + " to " +
+                                            checkCastCallTarget.targetMethod();
+                            checkCastUsage.replaceFirstInput(checkCastNode, checkCastNode.object());
+                        }
+                    } else if (checkCastUsage instanceof FrameState) {
+                        checkCastUsage.replaceFirstInput(checkCastNode, null);
+                    } else if (checkCastUsage instanceof ReturnNode && checkCastNode.object().stamp() == StampFactory.forNodeIntrinsic()) {
+                        checkCastUsage.replaceFirstInput(checkCastNode, checkCastNode.object());
+                    } else {
+                        assert false : sourceLocation(checkCastUsage) + " has unexpected usage " + checkCastUsage + " of checkcast at " + sourceLocation(checkCastNode);
+                    }
+                }
+                FixedNode next = checkCastNode.next();
+                checkCastNode.setNext(null);
+                checkCastNode.replaceAtPredecessor(next);
+                GraphUtil.killCFG(checkCastNode);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationVerificationPhase.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2011, 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.replacements;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.Node.NodeIntrinsic;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.replacements.Snippet.*;
+
+/**
+ * Checks that a graph contains no calls to {@link NodeIntrinsic} or {@link Fold} methods.
+ */
+public class NodeIntrinsificationVerificationPhase extends Phase {
+
+    public static boolean verify(StructuredGraph graph) {
+        new NodeIntrinsificationVerificationPhase().apply(graph);
+        return true;
+    }
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        for (Invoke i : graph.getInvokes()) {
+            if (i.callTarget() instanceof MethodCallTargetNode) {
+                checkInvoke(i);
+            }
+        }
+    }
+
+    private static void checkInvoke(Invoke invoke) {
+        ResolvedJavaMethod target = invoke.methodCallTarget().targetMethod();
+        NodeIntrinsic intrinsic = target.getAnnotation(Node.NodeIntrinsic.class);
+        if (intrinsic != null) {
+            throw new GraalInternalError("Illegal call to node intrinsic in " + invoke.graph() + ": " + invoke);
+        } else if (target.getAnnotation(Fold.class) != null) {
+            throw new GraalInternalError("Illegal call to foldable method in " + invoke.graph() + ": " + invoke);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsInstaller.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,406 @@
+/*
+ * Copyright (c) 2011, 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.replacements;
+
+import static com.oracle.graal.api.meta.MetaUtil.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+import sun.misc.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.java.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.common.*;
+import com.oracle.graal.replacements.ClassSubstitution.*;
+import com.oracle.graal.replacements.Snippet.*;
+import com.oracle.graal.word.phases.*;
+
+/**
+ * Utility for managing the pre-processing and installation of replacements. Replacements are either
+ * {@linkplain Snippets snippets}, {@linkplain MethodSubstitution method substitutions} or
+ * {@link MacroSubstitution macro substitutions}.
+ */
+public class ReplacementsInstaller {
+
+    protected final MetaAccessProvider runtime;
+    protected final TargetDescription target;
+    protected final Assumptions assumptions;
+    protected final BoxingMethodPool pool;
+    private final Thread owner;
+
+    /**
+     * A graph cache used by this installer to avoid using the compiler storage for each method
+     * processed during snippet installation. Without this, all processed methods are to be
+     * determined as {@linkplain InliningUtil#canIntrinsify intrinsifiable}.
+     */
+    private final Map<ResolvedJavaMethod, StructuredGraph> graphCache;
+
+    public ReplacementsInstaller(MetaAccessProvider runtime, Assumptions assumptions, TargetDescription target) {
+        this.runtime = runtime;
+        this.target = target;
+        this.assumptions = assumptions;
+        this.pool = new BoxingMethodPool(runtime);
+        this.graphCache = new HashMap<>();
+        this.owner = Thread.currentThread();
+    }
+
+    /**
+     * Finds all the snippet methods in a given class, builds a graph for them and installs the
+     * graph with the key value of {@code Graph.class} in the
+     * {@linkplain ResolvedJavaMethod#getCompilerStorage() compiler storage} of each method.
+     */
+    public void installSnippets(Class<? extends Snippets> snippets) {
+        for (Method method : snippets.getDeclaredMethods()) {
+            if (method.getAnnotation(Snippet.class) != null) {
+                int modifiers = method.getModifiers();
+                if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) {
+                    throw new RuntimeException("Snippet must not be abstract or native");
+                }
+                ResolvedJavaMethod snippet = runtime.lookupJavaMethod(method);
+                assert snippet.getCompilerStorage().get(Graph.class) == null : method;
+                StructuredGraph graph = makeGraph(snippet, inliningPolicy(snippet));
+                // System.out.println("snippet: " + graph);
+                snippet.getCompilerStorage().put(Graph.class, graph);
+            }
+        }
+    }
+
+    /**
+     * Finds all the methods in a given class annotated with {@link MethodSubstitution} or
+     * {@link MacroSubstitution}. It builds graphs for the former and installs them in the
+     * {@linkplain ResolvedJavaMethod#getCompilerStorage() compiler storage} of the original (i.e.,
+     * substituted) method with a key of {@code Graph.class}. For the latter, the denoted
+     * {@linkplain MacroSubstitution#macro() macro} node type is install in the compiler storage
+     * with a key of {@code Node.class}.
+     */
+    public void installSubstitutions(Class<?> substitutions) {
+        assert owner == Thread.currentThread() : "substitution installation must be single threaded";
+        ClassSubstitution classSubstitution = substitutions.getAnnotation(ClassSubstitution.class);
+        assert classSubstitution != null;
+        assert !Snippets.class.isAssignableFrom(substitutions);
+        for (Method substituteMethod : substitutions.getDeclaredMethods()) {
+            MethodSubstitution methodSubstitution = substituteMethod.getAnnotation(MethodSubstitution.class);
+            MacroSubstitution macroSubstitution = substituteMethod.getAnnotation(MacroSubstitution.class);
+            if (methodSubstitution == null && macroSubstitution == null) {
+                continue;
+            }
+
+            int modifiers = substituteMethod.getModifiers();
+            if (!Modifier.isStatic(modifiers)) {
+                throw new RuntimeException("Substitution methods must be static: " + substituteMethod);
+            }
+
+            if (methodSubstitution != null) {
+                if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) {
+                    throw new RuntimeException("Substitution method must not be abstract or native: " + substituteMethod);
+                }
+                String originalName = originalName(substituteMethod, methodSubstitution.value());
+                Class[] originalParameters = originalParameters(substituteMethod, methodSubstitution.signature(), methodSubstitution.isStatic());
+                Member originalMethod = originalMethod(classSubstitution, originalName, originalParameters);
+                if (originalMethod != null) {
+                    installMethodSubstitution(originalMethod, substituteMethod);
+                }
+            }
+            if (macroSubstitution != null) {
+                String originalName = originalName(substituteMethod, macroSubstitution.value());
+                Class[] originalParameters = originalParameters(substituteMethod, macroSubstitution.signature(), macroSubstitution.isStatic());
+                Member originalMethod = originalMethod(classSubstitution, originalName, originalParameters);
+                if (originalMethod != null) {
+                    installMacroSubstitution(originalMethod, macroSubstitution.macro());
+                }
+            }
+        }
+    }
+
+    // These fields are used to detect calls from the substitute method to the original method.
+    ResolvedJavaMethod substitute;
+    ResolvedJavaMethod original;
+    boolean substituteCallsOriginal;
+
+    /**
+     * Installs a method substitution.
+     * 
+     * @param originalMethod a method or constructor being substituted
+     * @param substituteMethod the substitute method
+     */
+    protected void installMethodSubstitution(Member originalMethod, Method substituteMethod) {
+        substitute = runtime.lookupJavaMethod(substituteMethod);
+        if (originalMethod instanceof Method) {
+            original = runtime.lookupJavaMethod((Method) originalMethod);
+        } else {
+            original = runtime.lookupJavaConstructor((Constructor) originalMethod);
+        }
+        try {
+            Debug.log("substitution: " + MetaUtil.format("%H.%n(%p)", original) + " --> " + MetaUtil.format("%H.%n(%p)", substitute));
+            StructuredGraph graph = makeGraph(substitute, inliningPolicy(substitute));
+            Object oldValue = original.getCompilerStorage().put(Graph.class, graph);
+            assert oldValue == null;
+        } finally {
+            substitute = null;
+            original = null;
+            substituteCallsOriginal = false;
+        }
+    }
+
+    /**
+     * Installs a macro substitution.
+     * 
+     * @param originalMethod a method or constructor being substituted
+     * @param macro the substitute macro node class
+     */
+    protected void installMacroSubstitution(Member originalMethod, Class<? extends FixedWithNextNode> macro) {
+        ResolvedJavaMethod originalJavaMethod;
+        if (originalMethod instanceof Method) {
+            originalJavaMethod = runtime.lookupJavaMethod((Method) originalMethod);
+        } else {
+            originalJavaMethod = runtime.lookupJavaConstructor((Constructor) originalMethod);
+        }
+        Object oldValue = originalJavaMethod.getCompilerStorage().put(Node.class, macro);
+        assert oldValue == null;
+    }
+
+    private SnippetInliningPolicy inliningPolicy(ResolvedJavaMethod method) {
+        Class<? extends SnippetInliningPolicy> policyClass = SnippetInliningPolicy.class;
+        Snippet snippet = method.getAnnotation(Snippet.class);
+        if (snippet != null) {
+            policyClass = snippet.inlining();
+        }
+        if (policyClass == SnippetInliningPolicy.class) {
+            return new DefaultSnippetInliningPolicy(runtime, pool);
+        }
+        try {
+            return policyClass.getConstructor().newInstance();
+        } catch (Exception e) {
+            throw new GraalInternalError(e);
+        }
+    }
+
+    /**
+     * Does final processing of a snippet graph.
+     */
+    protected void finalizeGraph(ResolvedJavaMethod method, StructuredGraph graph) {
+        new NodeIntrinsificationPhase(runtime, pool).apply(graph);
+        assert SnippetTemplate.hasConstantParameter(method) || NodeIntrinsificationVerificationPhase.verify(graph);
+
+        new SnippetFrameStateCleanupPhase().apply(graph);
+        new DeadCodeEliminationPhase().apply(graph);
+
+        new InsertStateAfterPlaceholderPhase().apply(graph);
+    }
+
+    public StructuredGraph makeGraph(final ResolvedJavaMethod method, final SnippetInliningPolicy policy) {
+        return Debug.scope("BuildSnippetGraph", new Object[]{method}, new Callable<StructuredGraph>() {
+
+            @Override
+            public StructuredGraph call() throws Exception {
+                StructuredGraph graph = parseGraph(method, policy);
+
+                finalizeGraph(method, graph);
+
+                Debug.dump(graph, "%s: Final", method.getName());
+
+                return graph;
+            }
+        });
+    }
+
+    private StructuredGraph parseGraph(final ResolvedJavaMethod method, final SnippetInliningPolicy policy) {
+        StructuredGraph graph = graphCache.get(method);
+        if (graph == null) {
+            graph = buildGraph(method, policy == null ? inliningPolicy(method) : policy);
+            graphCache.put(method, graph);
+        }
+        return graph;
+    }
+
+    /**
+     * Builds the initial graph for a snippet.
+     */
+    protected StructuredGraph buildInitialGraph(final ResolvedJavaMethod method) {
+        final StructuredGraph graph = new StructuredGraph(method);
+        GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault();
+        GraphBuilderPhase graphBuilder = new GraphBuilderPhase(runtime, config, OptimisticOptimizations.NONE);
+        graphBuilder.apply(graph);
+
+        Debug.dump(graph, "%s: %s", method.getName(), GraphBuilderPhase.class.getSimpleName());
+
+        new WordTypeVerificationPhase(runtime, target.wordKind).apply(graph);
+        new NodeIntrinsificationPhase(runtime, pool).apply(graph);
+
+        return graph;
+    }
+
+    /**
+     * Called after a graph is inlined.
+     * 
+     * @param caller the graph into which {@code callee} was inlined
+     * @param callee the graph that was inlined into {@code caller}
+     */
+    protected void afterInline(StructuredGraph caller, StructuredGraph callee) {
+        if (GraalOptions.OptCanonicalizer) {
+            new WordTypeRewriterPhase(runtime, target.wordKind).apply(caller);
+            new CanonicalizerPhase(runtime, assumptions).apply(caller);
+        }
+    }
+
+    /**
+     * Called after all inlining for a given graph is complete.
+     */
+    protected void afterInlining(StructuredGraph graph) {
+        new NodeIntrinsificationPhase(runtime, pool).apply(graph);
+
+        new WordTypeRewriterPhase(runtime, target.wordKind).apply(graph);
+
+        new DeadCodeEliminationPhase().apply(graph);
+        if (GraalOptions.OptCanonicalizer) {
+            new CanonicalizerPhase(runtime, assumptions).apply(graph);
+        }
+    }
+
+    private StructuredGraph buildGraph(final ResolvedJavaMethod method, final SnippetInliningPolicy policy) {
+        assert !Modifier.isAbstract(method.getModifiers()) && !Modifier.isNative(method.getModifiers()) : method;
+        final StructuredGraph graph = buildInitialGraph(method);
+
+        for (Invoke invoke : graph.getInvokes()) {
+            MethodCallTargetNode callTarget = invoke.methodCallTarget();
+            ResolvedJavaMethod callee = callTarget.targetMethod();
+            if (callee == substitute) {
+                final StructuredGraph originalGraph = new StructuredGraph(original);
+                new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(originalGraph);
+                InliningUtil.inline(invoke, originalGraph, true);
+
+                Debug.dump(graph, "after inlining %s", callee);
+                afterInline(graph, originalGraph);
+                substituteCallsOriginal = true;
+            } else {
+                if ((callTarget.invokeKind() == InvokeKind.Static || callTarget.invokeKind() == InvokeKind.Special) && policy.shouldInline(callee, method)) {
+                    StructuredGraph targetGraph = parseGraph(callee, policy);
+                    InliningUtil.inline(invoke, targetGraph, true);
+                    Debug.dump(graph, "after inlining %s", callee);
+                    afterInline(graph, targetGraph);
+                }
+            }
+        }
+
+        afterInlining(graph);
+
+        for (LoopEndNode end : graph.getNodes(LoopEndNode.class)) {
+            end.disableSafepoint();
+        }
+
+        if (GraalOptions.ProbabilityAnalysis) {
+            new DeadCodeEliminationPhase().apply(graph);
+            new ComputeProbabilityPhase().apply(graph);
+        }
+        return graph;
+    }
+
+    private static String originalName(Method substituteMethod, String methodSubstitution) {
+        if (methodSubstitution.isEmpty()) {
+            return substituteMethod.getName();
+        } else {
+            return methodSubstitution;
+        }
+    }
+
+    /**
+     * Resolves a name to a class.
+     * 
+     * @param className the name of the class to resolve
+     * @param optional if true, resolution failure returns null
+     * @return the resolved class or null if resolution fails and {@code optional} is true
+     */
+    private static Class resolveType(String className, boolean optional) {
+        try {
+            // Need to use launcher class path to handle classes
+            // that are not on the boot class path
+            ClassLoader cl = Launcher.getLauncher().getClassLoader();
+            return Class.forName(className, false, cl);
+        } catch (ClassNotFoundException e) {
+            if (optional) {
+                return null;
+            }
+            throw new GraalInternalError("Could not resolve type " + className);
+        }
+    }
+
+    private static Class resolveType(JavaType type) {
+        JavaType base = type;
+        int dimensions = 0;
+        while (base.getComponentType() != null) {
+            base = base.getComponentType();
+            dimensions++;
+        }
+
+        Class baseClass = base.getKind() != Kind.Object ? base.getKind().toJavaClass() : resolveType(toJavaName(base), false);
+        return dimensions == 0 ? baseClass : Array.newInstance(baseClass, new int[dimensions]).getClass();
+    }
+
+    private Class[] originalParameters(Method substituteMethod, String methodSubstitution, boolean isStatic) {
+        Class[] parameters;
+        if (methodSubstitution.isEmpty()) {
+            parameters = substituteMethod.getParameterTypes();
+            if (!isStatic) {
+                assert parameters.length > 0 : "must be a static method with the 'this' object as its first parameter";
+                parameters = Arrays.copyOfRange(parameters, 1, parameters.length);
+            }
+        } else {
+            Signature signature = runtime.parseMethodDescriptor(methodSubstitution);
+            parameters = new Class[signature.getParameterCount(false)];
+            for (int i = 0; i < parameters.length; i++) {
+                parameters[i] = resolveType(signature.getParameterType(i, null));
+            }
+        }
+        return parameters;
+    }
+
+    private static Member originalMethod(ClassSubstitution classSubstitution, String name, Class[] parameters) {
+        Class<?> originalClass = classSubstitution.value();
+        if (originalClass == ClassSubstitution.class) {
+            originalClass = resolveType(classSubstitution.className(), classSubstitution.optional());
+            if (originalClass == null) {
+                // optional class was not found
+                return null;
+            }
+        }
+        try {
+            if (name.equals("<init>")) {
+                return originalClass.getDeclaredConstructor(parameters);
+            } else {
+                return originalClass.getDeclaredMethod(name, parameters);
+            }
+        } catch (NoSuchMethodException | SecurityException e) {
+            throw new GraalInternalError(e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/Snippet.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2011, 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.replacements;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.Node.NodeIntrinsic;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.replacements.nodes.*;
+import com.oracle.graal.word.*;
+
+/**
+ * A snippet is a Graal graph expressed as a Java source method. Snippets are used for lowering
+ * nodes that have runtime dependent semantics (e.g. the {@code CHECKCAST} bytecode).
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Snippet {
+
+    /**
+     * Specifies the class defining the inlining policy for this snippet. A
+     * {@linkplain DefaultSnippetInliningPolicy default} policy is used if none is supplied.
+     */
+    Class<? extends SnippetInliningPolicy> inlining() default SnippetInliningPolicy.class;
+
+    /**
+     * Guides inlining decisions used when installing a snippet.
+     */
+    public interface SnippetInliningPolicy {
+
+        /**
+         * Determines if {@code method} should be inlined into {@code caller}.
+         */
+        boolean shouldInline(ResolvedJavaMethod method, ResolvedJavaMethod caller);
+    }
+
+    /**
+     * The default inlining policy which inlines everything except for methods in any of the
+     * following categories.
+     * <ul>
+     * <li>{@linkplain Fold foldable} methods</li>
+     * <li>{@linkplain NodeIntrinsic node intrinsics}</li>
+     * <li>native methods</li>
+     * <li>constructors of {@link Throwable} classes</li>
+     * </ul>
+     */
+    public static class DefaultSnippetInliningPolicy implements SnippetInliningPolicy {
+
+        private final MetaAccessProvider metaAccess;
+        private final BoxingMethodPool pool;
+
+        public DefaultSnippetInliningPolicy(MetaAccessProvider metaAccess, BoxingMethodPool pool) {
+            this.metaAccess = metaAccess;
+            this.pool = pool;
+        }
+
+        @Override
+        public boolean shouldInline(ResolvedJavaMethod method, ResolvedJavaMethod caller) {
+            if (Modifier.isNative(method.getModifiers())) {
+                return false;
+            }
+            if (method.getAnnotation(Fold.class) != null) {
+                return false;
+            }
+            if (method.getAnnotation(NodeIntrinsic.class) != null) {
+                return false;
+            }
+            if (metaAccess.lookupJavaType(Throwable.class).isAssignableFrom(method.getDeclaringClass())) {
+                if (method.getName().equals("<init>")) {
+                    return false;
+                }
+            }
+            if (method.getAnnotation(Word.Operation.class) != null) {
+                return false;
+            }
+            if (pool.isSpecialMethod(method)) {
+                return false;
+            }
+            return true;
+        }
+    }
+
+    /**
+     * Annotates a method replaced by a compile-time constant. A (resolved) call to the annotated
+     * method is replaced with a constant obtained by calling the annotated method via reflection.
+     * 
+     * All arguments to such a method (including the receiver if applicable) must be compile-time
+     * constants.
+     */
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.METHOD)
+    public static @interface Fold {
+    }
+
+    /**
+     * Denotes a snippet parameter that will be bound during snippet template
+     * {@linkplain SnippetTemplate#instantiate instantiation}.
+     */
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.PARAMETER)
+    public @interface Parameter {
+
+        /**
+         * The name of this parameter.
+         */
+        String value();
+    }
+
+    /**
+     * Denotes a snippet parameter representing 0 or more arguments that will be bound during
+     * snippet template {@linkplain SnippetTemplate#instantiate instantiation}. During snippet
+     * template creation, its value must be an array whose length specifies the number of arguments
+     * (the contents of the array are ignored) bound to the parameter during
+     * {@linkplain SnippetTemplate#instantiate instantiation}.
+     * 
+     * Such a parameter must be used in a counted loop in the snippet preceded by a call to
+     * {@link ExplodeLoopNode#explodeLoop()}. The counted looped must be a standard iteration over
+     * all the loop's elements (i.e. {@code for (T e : arr) ... }).
+     */
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.PARAMETER)
+    public @interface VarargsParameter {
+
+        /**
+         * The name of this parameter.
+         */
+        String value();
+    }
+
+    /**
+     * Denotes a snippet parameter that will bound to a constant value during snippet template
+     * {@linkplain SnippetTemplate#instantiate instantiation}.
+     */
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.PARAMETER)
+    public @interface ConstantParameter {
+
+        /**
+         * The name of this constant.
+         */
+        String value();
+    }
+
+    /**
+     * Wrapper for the prototype value of a {@linkplain VarargsParameter varargs} parameter.
+     */
+    public static class Varargs {
+
+        private final Object args;
+        private final Class argType;
+        private final int length;
+        private final Stamp argStamp;
+
+        public static Varargs vargargs(Object array, Stamp argStamp) {
+            return new Varargs(array, argStamp);
+        }
+
+        public Varargs(Object array, Stamp argStamp) {
+            assert array != null;
+            this.argType = array.getClass().getComponentType();
+            this.argStamp = argStamp;
+            assert this.argType != null;
+            this.length = java.lang.reflect.Array.getLength(array);
+            this.args = array;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof Varargs) {
+                Varargs other = (Varargs) obj;
+                return other.argType == argType && other.length == length;
+            }
+            return false;
+        }
+
+        public Object getArray() {
+            return args;
+        }
+
+        public Stamp getArgStamp() {
+            return argStamp;
+        }
+
+        @Override
+        public int hashCode() {
+            return argType.hashCode() ^ length;
+        }
+
+        @Override
+        public String toString() {
+            return argType.getName() + "[" + length + "]";
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetCounter.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.replacements;
+
+//JaCoCo Exclude
+
+import static com.oracle.graal.graph.FieldIntrospection.*;
+
+import java.io.*;
+import java.util.*;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.replacements.Snippet.*;
+import com.oracle.graal.replacements.nodes.*;
+
+/**
+ * A counter that can be safely {@linkplain #inc() incremented} from within a snippet for gathering
+ * snippet specific metrics.
+ */
+public class SnippetCounter implements Comparable<SnippetCounter> {
+
+    /**
+     * A group of related counters.
+     */
+    public static class Group {
+
+        final String name;
+        final List<SnippetCounter> counters;
+
+        public Group(String name) {
+            this.name = name;
+            this.counters = new ArrayList<>();
+        }
+
+        @Override
+        public synchronized String toString() {
+            Collections.sort(counters);
+
+            long total = 0;
+            int maxNameLen = 0;
+            for (SnippetCounter c : counters) {
+                total += c.value;
+                maxNameLen = Math.max(c.name.length(), maxNameLen);
+            }
+
+            StringBuilder buf = new StringBuilder(String.format("Counters: %s%n", name));
+
+            for (SnippetCounter c : counters) {
+                double percent = total == 0D ? 0D : ((double) (c.value * 100)) / total;
+                buf.append(String.format("  %" + maxNameLen + "s: %5.2f%%%10d  // %s%n", c.name, percent, c.value, c.description));
+            }
+            return buf.toString();
+        }
+    }
+
+    /**
+     * Sorts counters in descending order of their {@linkplain #value() values}.
+     */
+    @Override
+    public int compareTo(SnippetCounter o) {
+        if (value > o.value) {
+            return -1;
+        } else if (o.value < value) {
+            return 1;
+        }
+        return 0;
+    }
+
+    private static final List<Group> groups = new ArrayList<>();
+
+    private final Group group;
+    private final int index;
+    private final String name;
+    private final String description;
+    private long value;
+
+    @Fold
+    private static int countOffset() {
+        try {
+            return (int) unsafe.objectFieldOffset(SnippetCounter.class.getDeclaredField("value"));
+        } catch (Exception e) {
+            throw new GraalInternalError(e);
+        }
+    }
+
+    /**
+     * Creates a counter.
+     * 
+     * @param group the group to which the counter belongs. If this is null, the newly created
+     *            counter is disabled and {@linkplain #inc() incrementing} is a no-op.
+     * @param name the name of the counter
+     * @param description a brief comment describing the metric represented by the counter
+     */
+    public SnippetCounter(Group group, String name, String description) {
+        this.group = group;
+        this.name = name;
+        this.description = description;
+        if (group != null) {
+            List<SnippetCounter> counters = group.counters;
+            this.index = counters.size();
+            counters.add(this);
+            if (index == 0) {
+                groups.add(group);
+            }
+        } else {
+            this.index = -1;
+        }
+    }
+
+    /**
+     * Increments the value of this counter. This method can be safely used in a snippet if it is
+     * invoked on a compile-time constant {@link SnippetCounter} object.
+     */
+    public void inc() {
+        if (group != null) {
+            DirectObjectStoreNode.storeLong(this, countOffset(), 0, value + 1);
+        }
+    }
+
+    /**
+     * Gets the value of this counter.
+     */
+    public long value() {
+        return value;
+    }
+
+    /**
+     * Prints all the counter groups to a given stream.
+     */
+    public static void printGroups(PrintStream out) {
+        for (Group group : groups) {
+            out.println(group);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetFrameStateCleanupPhase.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2011, 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.replacements;
+
+import java.util.*;
+
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.util.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.graph.*;
+import com.oracle.graal.phases.graph.ReentrantNodeIterator.LoopInfo;
+import com.oracle.graal.phases.graph.ReentrantNodeIterator.NodeIteratorClosure;
+
+/**
+ * Removes frame states from {@linkplain StateSplit#hasSideEffect() non-side-effecting} nodes in a
+ * snippet.
+ * 
+ * The frame states of side-effecting nodes are replaced with
+ * {@linkplain FrameState#INVALID_FRAMESTATE_BCI invalid} frame states. Loops that contain invalid
+ * frame states are also assigned an invalid frame state.
+ * 
+ * The invalid frame states ensure that no deoptimization to a snippet frame state will happen.
+ */
+public class SnippetFrameStateCleanupPhase extends Phase {
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        ReentrantNodeIterator.apply(new SnippetFrameStateCleanupClosure(), graph.start(), new CleanupState(false), null);
+    }
+
+    private static class CleanupState {
+
+        public boolean containsFrameState;
+
+        public CleanupState(boolean containsFrameState) {
+            this.containsFrameState = containsFrameState;
+        }
+    }
+
+    /**
+     * A proper (loop-aware) iteration over the graph is used to detect loops that contain invalid
+     * frame states, so that they can be marked with an invalid frame state.
+     */
+    private static class SnippetFrameStateCleanupClosure extends NodeIteratorClosure<CleanupState> {
+
+        @Override
+        protected void processNode(FixedNode node, CleanupState currentState) {
+            if (node instanceof StateSplit) {
+                StateSplit stateSplit = (StateSplit) node;
+                FrameState frameState = stateSplit.stateAfter();
+                if (frameState != null) {
+                    if (stateSplit.hasSideEffect()) {
+                        currentState.containsFrameState = true;
+                        stateSplit.setStateAfter(node.graph().add(new FrameState(FrameState.INVALID_FRAMESTATE_BCI)));
+                    } else {
+                        stateSplit.setStateAfter(null);
+                    }
+                    if (frameState.usages().isEmpty()) {
+                        GraphUtil.killWithUnusedFloatingInputs(frameState);
+                    }
+                }
+            }
+        }
+
+        @Override
+        protected CleanupState merge(MergeNode merge, List<CleanupState> states) {
+            for (CleanupState state : states) {
+                if (state.containsFrameState) {
+                    return new CleanupState(true);
+                }
+            }
+            return new CleanupState(false);
+        }
+
+        @Override
+        protected CleanupState afterSplit(BeginNode node, CleanupState oldState) {
+            return new CleanupState(oldState.containsFrameState);
+        }
+
+        @Override
+        protected Map<LoopExitNode, CleanupState> processLoop(LoopBeginNode loop, CleanupState initialState) {
+            LoopInfo<CleanupState> info = ReentrantNodeIterator.processLoop(this, loop, new CleanupState(false));
+            boolean containsFrameState = false;
+            for (CleanupState state : info.endStates.values()) {
+                containsFrameState |= state.containsFrameState;
+            }
+            if (containsFrameState) {
+                loop.setStateAfter(loop.graph().add(new FrameState(FrameState.INVALID_FRAMESTATE_BCI)));
+            }
+            if (containsFrameState || initialState.containsFrameState) {
+                for (CleanupState state : info.exitStates.values()) {
+                    state.containsFrameState = true;
+                }
+            }
+            return info.exitStates;
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,752 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.replacements;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.concurrent.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.loop.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+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.util.*;
+import com.oracle.graal.phases.common.*;
+import com.oracle.graal.replacements.Snippet.*;
+import com.oracle.graal.replacements.nodes.*;
+import com.oracle.graal.word.*;
+import com.oracle.graal.word.phases.*;
+
+/**
+ * A snippet template is a graph created by parsing a snippet method and then specialized by binding
+ * constants to the snippet's {@link ConstantParameter} parameters.
+ * 
+ * Snippet templates can be managed in a {@link Cache}.
+ */
+public class SnippetTemplate {
+
+    /**
+     * A snippet template key encapsulates the method from which a snippet was built and the
+     * arguments used to specialize the snippet.
+     * 
+     * @see Cache
+     */
+    public static class Key implements Iterable<Map.Entry<String, Object>> {
+
+        public final ResolvedJavaMethod method;
+        private final HashMap<String, Object> map = new HashMap<>();
+        private int hash;
+
+        public Key(ResolvedJavaMethod method) {
+            this.method = method;
+            this.hash = method.hashCode();
+        }
+
+        public Key add(String name, Object value) {
+            assert !map.containsKey(name);
+            map.put(name, value);
+            hash = hash ^ name.hashCode();
+            if (value != null) {
+                hash *= (value.hashCode() + 1);
+            }
+            return this;
+        }
+
+        public int length() {
+            return map.size();
+        }
+
+        public Object get(String name) {
+            return map.get(name);
+        }
+
+        @Override
+        public Iterator<Entry<String, Object>> iterator() {
+            return map.entrySet().iterator();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof Key) {
+                Key other = (Key) obj;
+                return other.method == method && other.map.equals(map);
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return hash;
+        }
+
+        @Override
+        public String toString() {
+            return MetaUtil.format("%h.%n", method) + map.toString();
+        }
+
+        public Set<String> names() {
+            return map.keySet();
+        }
+    }
+
+    /**
+     * Arguments used to instantiate a template.
+     */
+    public static class Arguments implements Iterable<Map.Entry<String, Object>> {
+
+        private final HashMap<String, Object> map = new HashMap<>();
+
+        public static Arguments arguments(String name, Object value) {
+            return new Arguments().add(name, value);
+        }
+
+        public Arguments add(String name, Object value) {
+            assert !map.containsKey(name);
+            map.put(name, value);
+            return this;
+        }
+
+        public int length() {
+            return map.size();
+        }
+
+        @Override
+        public Iterator<Entry<String, Object>> iterator() {
+            return map.entrySet().iterator();
+        }
+
+        @Override
+        public String toString() {
+            return map.toString();
+        }
+    }
+
+    /**
+     * A collection of snippet templates accessed by a {@link Key} instance.
+     */
+    public static class Cache {
+
+        private final ConcurrentHashMap<SnippetTemplate.Key, SnippetTemplate> templates = new ConcurrentHashMap<>();
+        private final MetaAccessProvider runtime;
+        private final TargetDescription target;
+
+        public Cache(MetaAccessProvider runtime, TargetDescription target) {
+            this.runtime = runtime;
+            this.target = target;
+        }
+
+        /**
+         * Gets a template for a given key, creating it first if necessary.
+         */
+        public SnippetTemplate get(final SnippetTemplate.Key key, final Assumptions assumptions) {
+            SnippetTemplate template = templates.get(key);
+            if (template == null) {
+                template = Debug.scope("SnippetSpecialization", key.method, new Callable<SnippetTemplate>() {
+
+                    @Override
+                    public SnippetTemplate call() throws Exception {
+                        return new SnippetTemplate(runtime, assumptions, target, key);
+                    }
+                });
+                // System.out.println(key + " -> " + template);
+                templates.put(key, template);
+            }
+            return template;
+        }
+    }
+
+    public abstract static class AbstractTemplates<T extends Snippets> {
+
+        protected final Cache cache;
+        protected final MetaAccessProvider runtime;
+        protected final Assumptions assumptions;
+        protected Class<?> snippetsClass;
+
+        public AbstractTemplates(MetaAccessProvider runtime, Assumptions assumptions, TargetDescription target, Class<T> snippetsClass) {
+            this.runtime = runtime;
+            this.assumptions = assumptions;
+            if (snippetsClass == null) {
+                assert this instanceof Snippets;
+                this.snippetsClass = getClass();
+            } else {
+                this.snippetsClass = snippetsClass;
+            }
+            this.cache = new Cache(runtime, target);
+        }
+
+        protected ResolvedJavaMethod snippet(String name, Class<?>... parameterTypes) {
+            try {
+                ResolvedJavaMethod snippet = runtime.lookupJavaMethod(snippetsClass.getDeclaredMethod(name, parameterTypes));
+                assert snippet.getAnnotation(Snippet.class) != null : "snippet is not annotated with @" + Snippet.class.getSimpleName();
+                return snippet;
+            } catch (NoSuchMethodException e) {
+                throw new GraalInternalError(e);
+            }
+        }
+    }
+
+    private static final Object UNUSED_PARAMETER = "DEAD PARAMETER";
+
+    /**
+     * Determines if any parameter of a given method is annotated with {@link ConstantParameter}.
+     */
+    public static boolean hasConstantParameter(ResolvedJavaMethod method) {
+        for (ConstantParameter p : MetaUtil.getParameterAnnotations(ConstantParameter.class, method)) {
+            if (p != null) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Creates a snippet template.
+     */
+    public SnippetTemplate(MetaAccessProvider runtime, Assumptions assumptions, TargetDescription target, SnippetTemplate.Key key) {
+        ResolvedJavaMethod method = key.method;
+        assert Modifier.isStatic(method.getModifiers()) : "snippet method must be static: " + method;
+        Signature signature = method.getSignature();
+
+        // Copy snippet graph, replacing constant parameters with given arguments
+        StructuredGraph snippetGraph = (StructuredGraph) method.getCompilerStorage().get(Graph.class);
+        StructuredGraph snippetCopy = new StructuredGraph(snippetGraph.name, snippetGraph.method());
+        IdentityHashMap<Node, Node> replacements = new IdentityHashMap<>();
+        replacements.put(snippetGraph.start(), snippetCopy.start());
+
+        int parameterCount = signature.getParameterCount(false);
+        assert checkTemplate(runtime, key, parameterCount, method, signature);
+
+        Parameter[] parameterAnnotations = new Parameter[parameterCount];
+        VarargsParameter[] varargsParameterAnnotations = new VarargsParameter[parameterCount];
+        ConstantNode[] placeholders = new ConstantNode[parameterCount];
+        for (int i = 0; i < parameterCount; i++) {
+            ConstantParameter c = MetaUtil.getParameterAnnotation(ConstantParameter.class, i, method);
+            if (c != null) {
+                String name = c.value();
+                Object arg = key.get(name);
+                Kind kind = signature.getParameterKind(i);
+                Constant constantArg;
+                if (arg instanceof Constant) {
+                    constantArg = (Constant) arg;
+                } else {
+                    constantArg = Constant.forBoxed(kind, arg);
+                }
+                replacements.put(snippetGraph.getLocal(i), ConstantNode.forConstant(constantArg, runtime, snippetCopy));
+            } else {
+                VarargsParameter vp = MetaUtil.getParameterAnnotation(VarargsParameter.class, i, method);
+                if (vp != null) {
+                    String name = vp.value();
+                    Varargs varargs = (Varargs) key.get(name);
+                    Object array = varargs.getArray();
+                    ConstantNode placeholder = ConstantNode.forObject(array, runtime, snippetCopy);
+                    replacements.put(snippetGraph.getLocal(i), placeholder);
+                    placeholders[i] = placeholder;
+                    varargsParameterAnnotations[i] = vp;
+                } else {
+                    parameterAnnotations[i] = MetaUtil.getParameterAnnotation(Parameter.class, i, method);
+                }
+            }
+        }
+        snippetCopy.addDuplicates(snippetGraph.getNodes(), replacements);
+
+        Debug.dump(snippetCopy, "Before specialization");
+        if (!replacements.isEmpty()) {
+            // Do deferred intrinsification of node intrinsics
+            new NodeIntrinsificationPhase(runtime, new BoxingMethodPool(runtime)).apply(snippetCopy);
+            new WordTypeRewriterPhase(runtime, target.wordKind).apply(snippetCopy);
+
+            new CanonicalizerPhase(runtime, assumptions, 0, null).apply(snippetCopy);
+        }
+        assert NodeIntrinsificationVerificationPhase.verify(snippetCopy);
+
+        // Gather the template parameters
+        parameters = new HashMap<>();
+        for (int i = 0; i < parameterCount; i++) {
+            VarargsParameter vp = varargsParameterAnnotations[i];
+            if (vp != null) {
+                assert snippetCopy.getLocal(i) == null;
+                Varargs varargs = (Varargs) key.get(vp.value());
+                Object array = varargs.getArray();
+                int length = Array.getLength(array);
+                LocalNode[] locals = new LocalNode[length];
+                Stamp stamp = varargs.getArgStamp();
+                for (int j = 0; j < length; j++) {
+                    assert (parameterCount & 0xFFFF) == parameterCount;
+                    int idx = i << 16 | j;
+                    LocalNode local = snippetCopy.unique(new LocalNode(idx, stamp));
+                    locals[j] = local;
+                }
+                parameters.put(vp.value(), locals);
+
+                ConstantNode placeholder = placeholders[i];
+                assert placeholder != null;
+                for (Node usage : placeholder.usages().snapshot()) {
+                    if (usage instanceof LoadIndexedNode) {
+                        LoadIndexedNode loadIndexed = (LoadIndexedNode) usage;
+                        Debug.dump(snippetCopy, "Before replacing %s", loadIndexed);
+                        LoadSnippetVarargParameterNode loadSnippetParameter = snippetCopy.add(new LoadSnippetVarargParameterNode(locals, loadIndexed.index(), loadIndexed.stamp()));
+                        snippetCopy.replaceFixedWithFixed(loadIndexed, loadSnippetParameter);
+                        Debug.dump(snippetCopy, "After replacing %s", loadIndexed);
+                    }
+                }
+            } else {
+                Parameter p = parameterAnnotations[i];
+                if (p != null) {
+                    LocalNode local = snippetCopy.getLocal(i);
+                    if (local == null) {
+                        // Parameter value was eliminated
+                        parameters.put(p.value(), UNUSED_PARAMETER);
+                    } else {
+                        parameters.put(p.value(), local);
+                    }
+                }
+            }
+        }
+
+        // Do any required loop explosion
+        boolean exploded = false;
+        do {
+            exploded = false;
+            ExplodeLoopNode explodeLoop = snippetCopy.getNodes().filter(ExplodeLoopNode.class).first();
+            if (explodeLoop != null) { // Earlier canonicalization may have removed the loop
+                                       // altogether
+                LoopBeginNode loopBegin = explodeLoop.findLoopBegin();
+                if (loopBegin != null) {
+                    LoopEx loop = new LoopsData(snippetCopy).loop(loopBegin);
+                    int mark = snippetCopy.getMark();
+                    LoopTransformations.fullUnroll(loop, runtime, null);
+                    new CanonicalizerPhase(runtime, assumptions, mark, null).apply(snippetCopy);
+                }
+                FixedNode explodeLoopNext = explodeLoop.next();
+                explodeLoop.clearSuccessors();
+                explodeLoop.replaceAtPredecessor(explodeLoopNext);
+                explodeLoop.replaceAtUsages(null);
+                GraphUtil.killCFG(explodeLoop);
+                exploded = true;
+            }
+        } while (exploded);
+
+        // Remove all frame states from inlined snippet graph. Snippets must be atomic (i.e. free
+        // of side-effects that prevent deoptimizing to a point before the snippet).
+        ArrayList<StateSplit> curSideEffectNodes = new ArrayList<>();
+        ArrayList<ValueNode> curStampNodes = new ArrayList<>();
+        for (Node node : snippetCopy.getNodes()) {
+            if (node instanceof ValueNode && ((ValueNode) node).stamp() == StampFactory.forNodeIntrinsic()) {
+                curStampNodes.add((ValueNode) node);
+            }
+            if (node instanceof StateSplit) {
+                StateSplit stateSplit = (StateSplit) node;
+                FrameState frameState = stateSplit.stateAfter();
+                if (stateSplit.hasSideEffect()) {
+                    curSideEffectNodes.add((StateSplit) node);
+                }
+                if (frameState != null) {
+                    stateSplit.setStateAfter(null);
+                }
+            }
+        }
+
+        new DeadCodeEliminationPhase().apply(snippetCopy);
+
+        assert checkAllVarargPlaceholdersAreDeleted(parameterCount, placeholders);
+
+        this.snippet = snippetCopy;
+        ReturnNode retNode = null;
+        StartNode entryPointNode = snippet.start();
+
+        new DeadCodeEliminationPhase().apply(snippetCopy);
+
+        nodes = new ArrayList<>(snippet.getNodeCount());
+        for (Node node : snippet.getNodes()) {
+            if (node == entryPointNode || node == entryPointNode.stateAfter()) {
+                // Do nothing.
+            } else {
+                nodes.add(node);
+                if (node instanceof ReturnNode) {
+                    retNode = (ReturnNode) node;
+                }
+            }
+        }
+
+        this.sideEffectNodes = curSideEffectNodes;
+        this.stampNodes = curStampNodes;
+        this.returnNode = retNode;
+    }
+
+    private static boolean checkAllVarargPlaceholdersAreDeleted(int parameterCount, ConstantNode[] placeholders) {
+        for (int i = 0; i < parameterCount; i++) {
+            if (placeholders[i] != null) {
+                assert placeholders[i].isDeleted() : placeholders[i];
+            }
+        }
+        return true;
+    }
+
+    private static boolean checkConstantArgument(MetaAccessProvider runtime, final ResolvedJavaMethod method, Signature signature, int i, String name, Object arg, Kind kind) {
+        ResolvedJavaType type = signature.getParameterType(i, method.getDeclaringClass()).resolve(method.getDeclaringClass());
+        if (runtime.lookupJavaType(WordBase.class).isAssignableFrom(type)) {
+            assert arg instanceof Constant : method + ": word constant parameters must be passed boxed in a Constant value: " + arg;
+            return true;
+        }
+        if (kind == Kind.Object) {
+            assert arg == null || type.isInstance(Constant.forObject(arg)) : method + ": wrong value type for " + name + ": expected " + type.getName() + ", got " + arg.getClass().getName();
+        } else {
+            assert arg != null && kind.toBoxedJavaClass() == arg.getClass() : method + ": wrong value kind for " + name + ": expected " + kind + ", got " +
+                            (arg == null ? "null" : arg.getClass().getSimpleName());
+        }
+        return true;
+    }
+
+    private static boolean checkVarargs(final ResolvedJavaMethod method, Signature signature, int i, String name, Varargs varargs) {
+        Object arg = varargs.getArray();
+        ResolvedJavaType type = (ResolvedJavaType) signature.getParameterType(i, method.getDeclaringClass());
+        assert type.isArray() : "varargs parameter must be an array type";
+        assert type.isInstance(Constant.forObject(arg)) : "value for " + name + " is not a " + MetaUtil.toJavaName(type) + " instance: " + arg;
+        return true;
+    }
+
+    /**
+     * The graph built from the snippet method.
+     */
+    private final StructuredGraph snippet;
+
+    /**
+     * The named parameters of this template that must be bound to values during instantiation. For
+     * a parameter that is still live after specialization, the value in this map is either a
+     * {@link LocalNode} instance or a {@link LocalNode} array. For an eliminated parameter, the
+     * value is identical to the key.
+     */
+    private final Map<String, Object> parameters;
+
+    /**
+     * The return node (if any) of the snippet.
+     */
+    private final ReturnNode returnNode;
+
+    /**
+     * Nodes that inherit the {@link StateSplit#stateAfter()} from the replacee during
+     * instantiation.
+     */
+    private final ArrayList<StateSplit> sideEffectNodes;
+
+    /**
+     * The nodes that inherit the {@link ValueNode#stamp()} from the replacee during instantiation.
+     */
+    private final ArrayList<ValueNode> stampNodes;
+
+    /**
+     * The nodes to be inlined when this specialization is instantiated.
+     */
+    private final ArrayList<Node> nodes;
+
+    /**
+     * Gets the instantiation-time bindings to this template's parameters.
+     * 
+     * @return the map that will be used to bind arguments to parameters when inlining this template
+     */
+    private IdentityHashMap<Node, Node> bind(StructuredGraph replaceeGraph, MetaAccessProvider runtime, SnippetTemplate.Arguments args) {
+        IdentityHashMap<Node, Node> replacements = new IdentityHashMap<>();
+        assert args.length() == parameters.size() : "number of args (" + args.length() + ") != number of parameters (" + parameters.size() + ")";
+        for (Map.Entry<String, Object> e : args) {
+            String name = e.getKey();
+            Object parameter = parameters.get(name);
+            assert parameter != null : this + " has no parameter named " + name;
+            Object argument = e.getValue();
+            if (parameter instanceof LocalNode) {
+                if (argument instanceof ValueNode) {
+                    replacements.put((LocalNode) parameter, (ValueNode) argument);
+                } else {
+                    Kind kind = ((LocalNode) parameter).kind();
+                    assert argument != null || kind == Kind.Object : this + " cannot accept null for non-object parameter named " + name;
+                    Constant constant = Constant.forBoxed(kind, argument);
+                    replacements.put((LocalNode) parameter, ConstantNode.forConstant(constant, runtime, replaceeGraph));
+                }
+            } else if (parameter instanceof LocalNode[]) {
+                LocalNode[] locals = (LocalNode[]) parameter;
+                int length = locals.length;
+                List list = null;
+                Object array = null;
+                if (argument instanceof List) {
+                    list = (List) argument;
+                    assert list.size() == length : length + " != " + list.size();
+                } else {
+                    array = argument;
+                    assert array != null && array.getClass().isArray();
+                    assert Array.getLength(array) == length : length + " != " + Array.getLength(array);
+                }
+
+                for (int j = 0; j < length; j++) {
+                    LocalNode local = locals[j];
+                    assert local != null;
+                    Object value = list != null ? list.get(j) : Array.get(array, j);
+                    if (value instanceof ValueNode) {
+                        replacements.put(local, (ValueNode) value);
+                    } else {
+                        Constant constant = Constant.forBoxed(local.kind(), value);
+                        ConstantNode element = ConstantNode.forConstant(constant, runtime, replaceeGraph);
+                        replacements.put(local, element);
+                    }
+                }
+            } else {
+                assert parameter == UNUSED_PARAMETER : "unexpected entry for parameter: " + name + " -> " + parameter;
+            }
+        }
+        return replacements;
+    }
+
+    /**
+     * Logic for replacing a snippet-lowered node at its usages with the return value of the
+     * snippet. An alternative to the {@linkplain SnippetTemplate#DEFAULT_REPLACER default}
+     * replacement logic can be used to handle mismatches between the stamp of the node being
+     * lowered and the stamp of the snippet's return value.
+     */
+    public interface UsageReplacer {
+
+        /**
+         * Replaces all usages of {@code oldNode} with direct or indirect usages of {@code newNode}.
+         */
+        void replace(ValueNode oldNode, ValueNode newNode);
+    }
+
+    /**
+     * Represents the default {@link UsageReplacer usage replacer} logic which simply delegates to
+     * {@link Node#replaceAtUsages(Node)}.
+     */
+    public static final UsageReplacer DEFAULT_REPLACER = new UsageReplacer() {
+
+        @Override
+        public void replace(ValueNode oldNode, ValueNode newNode) {
+            oldNode.replaceAtUsages(newNode);
+        }
+    };
+
+    /**
+     * Replaces a given fixed node with this specialized snippet.
+     * 
+     * @param runtime
+     * @param replacee the node that will be replaced
+     * @param replacer object that replaces the usages of {@code replacee}
+     * @param args the arguments to be bound to the flattened positional parameters of the snippet
+     * @return the map of duplicated nodes (original -> duplicate)
+     */
+    public Map<Node, Node> instantiate(MetaAccessProvider runtime, FixedNode replacee, UsageReplacer replacer, SnippetTemplate.Arguments args) {
+
+        // Inline the snippet nodes, replacing parameters with the given args in the process
+        String name = snippet.name == null ? "{copy}" : snippet.name + "{copy}";
+        StructuredGraph snippetCopy = new StructuredGraph(name, snippet.method());
+        StartNode entryPointNode = snippet.start();
+        FixedNode firstCFGNode = entryPointNode.next();
+        StructuredGraph replaceeGraph = (StructuredGraph) replacee.graph();
+        IdentityHashMap<Node, Node> replacements = bind(replaceeGraph, runtime, args);
+        Map<Node, Node> duplicates = replaceeGraph.addDuplicates(nodes, replacements);
+        Debug.dump(replaceeGraph, "After inlining snippet %s", snippetCopy.method());
+
+        // Re-wire the control flow graph around the replacee
+        FixedNode firstCFGNodeDuplicate = (FixedNode) duplicates.get(firstCFGNode);
+        replacee.replaceAtPredecessor(firstCFGNodeDuplicate);
+        FixedNode next = null;
+        if (replacee instanceof FixedWithNextNode) {
+            FixedWithNextNode fwn = (FixedWithNextNode) replacee;
+            next = fwn.next();
+            fwn.setNext(null);
+        }
+
+        if (replacee instanceof StateSplit) {
+            for (StateSplit sideEffectNode : sideEffectNodes) {
+                assert ((StateSplit) replacee).hasSideEffect();
+                Node sideEffectDup = duplicates.get(sideEffectNode);
+                ((StateSplit) sideEffectDup).setStateAfter(((StateSplit) replacee).stateAfter());
+            }
+        }
+        for (ValueNode stampNode : stampNodes) {
+            Node stampDup = duplicates.get(stampNode);
+            ((ValueNode) stampDup).setStamp(((ValueNode) replacee).stamp());
+        }
+
+        // Replace all usages of the replacee with the value returned by the snippet
+        ValueNode returnValue = null;
+        if (returnNode != null) {
+            if (returnNode.result() instanceof LocalNode) {
+                returnValue = (ValueNode) replacements.get(returnNode.result());
+            } else {
+                returnValue = (ValueNode) duplicates.get(returnNode.result());
+            }
+            assert returnValue != null || replacee.usages().isEmpty();
+            replacer.replace(replacee, returnValue);
+
+            Node returnDuplicate = duplicates.get(returnNode);
+            if (returnDuplicate.isAlive()) {
+                returnDuplicate.clearInputs();
+                returnDuplicate.replaceAndDelete(next);
+            }
+        }
+
+        // Remove the replacee from its graph
+        replacee.clearInputs();
+        replacee.replaceAtUsages(null);
+        GraphUtil.killCFG(replacee);
+
+        Debug.dump(replaceeGraph, "After lowering %s with %s", replacee, this);
+        return duplicates;
+    }
+
+    /**
+     * Gets a copy of the specialized graph.
+     */
+    public StructuredGraph copySpecializedGraph() {
+        return snippet.copy();
+    }
+
+    /**
+     * Replaces a given floating node with this specialized snippet.
+     * 
+     * @param runtime
+     * @param replacee the node that will be replaced
+     * @param replacer object that replaces the usages of {@code replacee}
+     * @param args the arguments to be bound to the flattened positional parameters of the snippet
+     */
+    public void instantiate(MetaAccessProvider runtime, FloatingNode replacee, UsageReplacer replacer, LoweringTool tool, SnippetTemplate.Arguments args) {
+
+        // Inline the snippet nodes, replacing parameters with the given args in the process
+        String name = snippet.name == null ? "{copy}" : snippet.name + "{copy}";
+        StructuredGraph snippetCopy = new StructuredGraph(name, snippet.method());
+        StartNode entryPointNode = snippet.start();
+        FixedNode firstCFGNode = entryPointNode.next();
+        StructuredGraph replaceeGraph = (StructuredGraph) replacee.graph();
+        IdentityHashMap<Node, Node> replacements = bind(replaceeGraph, runtime, args);
+        Map<Node, Node> duplicates = replaceeGraph.addDuplicates(nodes, replacements);
+        Debug.dump(replaceeGraph, "After inlining snippet %s", snippetCopy.method());
+
+        FixedWithNextNode lastFixedNode = tool.lastFixedNode();
+        assert lastFixedNode != null && lastFixedNode.isAlive() : replaceeGraph;
+        FixedNode next = lastFixedNode.next();
+        lastFixedNode.setNext(null);
+        FixedNode firstCFGNodeDuplicate = (FixedNode) duplicates.get(firstCFGNode);
+        replaceeGraph.addAfterFixed(lastFixedNode, firstCFGNodeDuplicate);
+
+        if (replacee instanceof StateSplit) {
+            for (StateSplit sideEffectNode : sideEffectNodes) {
+                assert ((StateSplit) replacee).hasSideEffect();
+                Node sideEffectDup = duplicates.get(sideEffectNode);
+                ((StateSplit) sideEffectDup).setStateAfter(((StateSplit) replacee).stateAfter());
+            }
+        }
+        for (ValueNode stampNode : stampNodes) {
+            Node stampDup = duplicates.get(stampNode);
+            ((ValueNode) stampDup).setStamp(((ValueNode) replacee).stamp());
+        }
+
+        // Replace all usages of the replacee with the value returned by the snippet
+        assert returnNode != null : replaceeGraph;
+        ValueNode returnValue = null;
+        if (returnNode.result() instanceof LocalNode) {
+            returnValue = (ValueNode) replacements.get(returnNode.result());
+        } else {
+            returnValue = (ValueNode) duplicates.get(returnNode.result());
+        }
+        assert returnValue != null || replacee.usages().isEmpty();
+        replacer.replace(replacee, returnValue);
+
+        tool.setLastFixedNode(null);
+        Node returnDuplicate = duplicates.get(returnNode);
+        if (returnDuplicate.isAlive()) {
+            returnDuplicate.clearInputs();
+            returnDuplicate.replaceAndDelete(next);
+            if (next != null && next.predecessor() instanceof FixedWithNextNode) {
+                tool.setLastFixedNode((FixedWithNextNode) next.predecessor());
+            }
+        }
+
+        Debug.dump(replaceeGraph, "After lowering %s with %s", replacee, this);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder buf = new StringBuilder(snippet.toString()).append('(');
+        String sep = "";
+        for (Map.Entry<String, Object> e : parameters.entrySet()) {
+            String name = e.getKey();
+            Object value = e.getValue();
+            buf.append(sep);
+            sep = ", ";
+            if (value == UNUSED_PARAMETER) {
+                buf.append("<unused> ").append(name);
+            } else if (value instanceof LocalNode) {
+                LocalNode local = (LocalNode) value;
+                buf.append(local.kind().getJavaName()).append(' ').append(name);
+            } else {
+                LocalNode[] locals = (LocalNode[]) value;
+                String kind = locals.length == 0 ? "?" : locals[0].kind().getJavaName();
+                buf.append(kind).append('[').append(locals.length).append("] ").append(name);
+            }
+        }
+        return buf.append(')').toString();
+    }
+
+    private static boolean checkTemplate(MetaAccessProvider runtime, SnippetTemplate.Key key, int parameterCount, ResolvedJavaMethod method, Signature signature) {
+        Set<String> expected = new HashSet<>();
+        for (int i = 0; i < parameterCount; i++) {
+            ConstantParameter c = MetaUtil.getParameterAnnotation(ConstantParameter.class, i, method);
+            VarargsParameter vp = MetaUtil.getParameterAnnotation(VarargsParameter.class, i, method);
+            Parameter p = MetaUtil.getParameterAnnotation(Parameter.class, i, method);
+            if (c != null) {
+                assert vp == null && p == null;
+                String name = c.value();
+                expected.add(name);
+                Kind kind = signature.getParameterKind(i);
+                assert key.names().contains(name) : "key for " + method + " is missing \"" + name + "\": " + key;
+                assert checkConstantArgument(runtime, method, signature, i, c.value(), key.get(name), kind);
+            } else if (vp != null) {
+                assert p == null;
+                String name = vp.value();
+                expected.add(name);
+                assert key.names().contains(name) : "key for " + method + " is missing \"" + name + "\": " + key;
+                assert key.get(name) instanceof Varargs;
+                Varargs varargs = (Varargs) key.get(name);
+                assert checkVarargs(method, signature, i, name, varargs);
+            } else {
+                assert p != null : method + ": parameter " + i + " must be annotated with exactly one of " + "@" + ConstantParameter.class.getSimpleName() + " or " + "@" +
+                                VarargsParameter.class.getSimpleName() + " or " + "@" + Parameter.class.getSimpleName();
+            }
+        }
+        if (!key.names().containsAll(expected)) {
+            expected.removeAll(key.names());
+            assert false : expected + " missing from key " + key;
+        }
+        if (!expected.containsAll(key.names())) {
+            Set<String> namesCopy = new HashSet<>(key.names());
+            namesCopy.removeAll(expected);
+            assert false : "parameter(s) " + namesCopy + " should be annotated with @" + ConstantParameter.class.getSimpleName() + " or @" + VarargsParameter.class.getSimpleName() + " in " +
+                            MetaUtil.format("%H.%n(%p)", method);
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/Snippets.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2011, 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.replacements;
+
+/**
+ * Marker interface for a class that defines one or more {@link Snippet}s.
+ */
+public interface Snippets {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsafeSubstitutions.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,383 @@
+/*
+ * Copyright (c) 2011, 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.replacements;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.replacements.ClassSubstitution.*;
+import com.oracle.graal.replacements.nodes.*;
+
+/**
+ * Substitutions for {@link sun.misc.Unsafe} methods.
+ */
+@ClassSubstitution(sun.misc.Unsafe.class)
+public class UnsafeSubstitutions {
+
+    @MethodSubstitution(isStatic = false)
+    public static boolean compareAndSwapObject(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, Object expected, Object x) {
+        return CompareAndSwapNode.compareAndSwap(o, 0, offset, expected, x);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static boolean compareAndSwapInt(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, int expected, int x) {
+        return CompareAndSwapNode.compareAndSwap(o, 0, offset, expected, x);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static boolean compareAndSwapLong(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, long expected, long x) {
+        return CompareAndSwapNode.compareAndSwap(o, 0, offset, expected, x);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static Object getObject(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
+        return UnsafeLoadNode.load(o, 0, offset, Kind.Object);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static Object getObjectVolatile(final Object thisObj, Object o, long offset) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        Object result = getObject(thisObj, o, offset);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putObject(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, Object x) {
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Object);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putObjectVolatile(final Object thisObj, Object o, long offset, Object x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putObject(thisObj, o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putOrderedObject(final Object thisObj, Object o, long offset, Object x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putObject(thisObj, o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static int getInt(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
+        Integer value = UnsafeLoadNode.load(o, 0, offset, Kind.Int);
+        return value;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static int getIntVolatile(final Object thisObj, Object o, long offset) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        int result = getInt(thisObj, o, offset);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putInt(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, int x) {
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Int);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putIntVolatile(final Object thisObj, Object o, long offset, int x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putInt(thisObj, o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putOrderedInt(final Object thisObj, Object o, long offset, int x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putInt(thisObj, o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static boolean getBoolean(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
+        @JavacBug(id = 6995200)
+        Boolean result = UnsafeLoadNode.load(o, 0, offset, Kind.Boolean);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static boolean getBooleanVolatile(final Object thisObj, Object o, long offset) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        boolean result = getBoolean(thisObj, o, offset);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putBoolean(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, boolean x) {
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Boolean);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putBooleanVolatile(final Object thisObj, Object o, long offset, boolean x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putBoolean(thisObj, o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static byte getByte(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
+        @JavacBug(id = 6995200)
+        Byte result = UnsafeLoadNode.load(o, 0, offset, Kind.Byte);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static byte getByteVolatile(final Object thisObj, Object o, long offset) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        byte result = getByte(thisObj, o, offset);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putByte(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, byte x) {
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Byte);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putByteVolatile(final Object thisObj, Object o, long offset, byte x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putByte(thisObj, o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static short getShort(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
+        @JavacBug(id = 6995200)
+        Short result = UnsafeLoadNode.load(o, 0, offset, Kind.Short);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static short getShortVolatile(final Object thisObj, Object o, long offset) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        short result = getShort(thisObj, o, offset);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putShort(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, short x) {
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Short);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putShortVolatile(final Object thisObj, Object o, long offset, short x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putShort(thisObj, o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static char getChar(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
+        @JavacBug(id = 6995200)
+        Character result = UnsafeLoadNode.load(o, 0, offset, Kind.Char);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static char getCharVolatile(final Object thisObj, Object o, long offset) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        char result = getChar(thisObj, o, offset);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putChar(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, char x) {
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Char);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putCharVolatile(final Object thisObj, Object o, long offset, char x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putChar(thisObj, o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static long getLong(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
+        @JavacBug(id = 6995200)
+        Long result = UnsafeLoadNode.load(o, 0, offset, Kind.Long);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static long getLongVolatile(final Object thisObj, Object o, long offset) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        long result = getLong(thisObj, o, offset);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putLong(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, long x) {
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Long);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putLongVolatile(final Object thisObj, Object o, long offset, long x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putLong(thisObj, o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putOrderedLong(final Object thisObj, Object o, long offset, long x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putLong(thisObj, o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static float getFloat(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
+        @JavacBug(id = 6995200)
+        Float result = UnsafeLoadNode.load(o, 0, offset, Kind.Float);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static float getFloatVolatile(final Object thisObj, Object o, long offset) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        float result = getFloat(thisObj, o, offset);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putFloat(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, float x) {
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Float);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putFloatVolatile(final Object thisObj, Object o, long offset, float x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putFloat(thisObj, o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static double getDouble(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
+        @JavacBug(id = 6995200)
+        Double result = UnsafeLoadNode.load(o, 0, offset, Kind.Double);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static double getDoubleVolatile(final Object thisObj, Object o, long offset) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        double result = getDouble(thisObj, o, offset);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putDouble(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, double x) {
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Double);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putDoubleVolatile(final Object thisObj, Object o, long offset, double x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putDouble(thisObj, o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putByte(@SuppressWarnings("unused") final Object thisObj, long address, byte value) {
+        DirectStoreNode.store(address, value, Kind.Byte);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putShort(@SuppressWarnings("unused") final Object thisObj, long address, short value) {
+        DirectStoreNode.store(address, value, Kind.Short);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putChar(@SuppressWarnings("unused") final Object thisObj, long address, char value) {
+        DirectStoreNode.store(address, value, Kind.Char);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putInt(@SuppressWarnings("unused") final Object thisObj, long address, int value) {
+        DirectStoreNode.store(address, value, Kind.Int);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putLong(@SuppressWarnings("unused") final Object thisObj, long address, long value) {
+        DirectStoreNode.store(address, value, Kind.Long);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putFloat(@SuppressWarnings("unused") final Object thisObj, long address, float value) {
+        DirectStoreNode.store(address, value, Kind.Float);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putDouble(@SuppressWarnings("unused") final Object thisObj, long address, double value) {
+        DirectStoreNode.store(address, value, Kind.Double);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static byte getByte(@SuppressWarnings("unused") final Object thisObj, long address) {
+        return DirectReadNode.read(address, Kind.Byte);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static short getShort(@SuppressWarnings("unused") final Object thisObj, long address) {
+        return DirectReadNode.read(address, Kind.Short);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static char getChar(@SuppressWarnings("unused") final Object thisObj, long address) {
+        return DirectReadNode.read(address, Kind.Char);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static int getInt(@SuppressWarnings("unused") final Object thisObj, long address) {
+        return DirectReadNode.read(address, Kind.Int);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static long getLong(@SuppressWarnings("unused") final Object thisObj, long address) {
+        return DirectReadNode.read(address, Kind.Long);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static float getFloat(@SuppressWarnings("unused") final Object thisObj, long address) {
+        return DirectReadNode.read(address, Kind.Float);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static double getDouble(@SuppressWarnings("unused") final Object thisObj, long address) {
+        return DirectReadNode.read(address, Kind.Double);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsignedMathSubstitutions.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2011, 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.replacements;
+
+import static com.oracle.graal.nodes.calc.ConditionalNode.*;
+import static com.oracle.graal.nodes.calc.Condition.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.replacements.ClassSubstitution.*;
+
+/**
+ * Substitutions for {@link UnsignedMath}.
+ */
+@ClassSubstitution(UnsignedMath.class)
+public class UnsignedMathSubstitutions {
+
+    @MethodSubstitution
+    public static boolean aboveThan(int a, int b) {
+        return materializeCondition(BT, b, a);
+    }
+
+    @MethodSubstitution
+    public static boolean aboveOrEqual(int a, int b) {
+        return !materializeCondition(BT, a, b);
+    }
+
+    /**
+     * Unsigned comparison belowThan for two numbers.
+     */
+    @MethodSubstitution
+    public static boolean belowThan(int a, int b) {
+        return materializeCondition(BT, a, b);
+    }
+
+    /**
+     * Unsigned comparison belowOrEqual for two numbers.
+     */
+    @MethodSubstitution
+    public static boolean belowOrEqual(int a, int b) {
+        return !materializeCondition(BT, b, a);
+    }
+
+    /**
+     * Unsigned comparison aboveThan for two numbers.
+     */
+    @MethodSubstitution
+    public static boolean aboveThan(long a, long b) {
+        return materializeCondition(BT, b, a);
+    }
+
+    /**
+     * Unsigned comparison aboveOrEqual for two numbers.
+     */
+    @MethodSubstitution
+    public static boolean aboveOrEqual(long a, long b) {
+        return !materializeCondition(BT, a, b);
+    }
+
+    /**
+     * Unsigned comparison belowThan for two numbers.
+     */
+    @MethodSubstitution
+    public static boolean belowThan(long a, long b) {
+        return materializeCondition(BT, a, b);
+    }
+
+    /**
+     * Unsigned comparison belowOrEqual for two numbers.
+     */
+    @MethodSubstitution
+    public static boolean belowOrEqual(long a, long b) {
+        return !materializeCondition(BT, b, a);
+    }
+
+    /**
+     * Unsigned division for two numbers.
+     */
+    @MethodSubstitution
+    public static int divide(int a, int b) {
+        return unsignedDivide(Kind.Int, a, b);
+    }
+
+    /**
+     * Unsigned remainder for two numbers.
+     */
+    @MethodSubstitution
+    public static int remainder(int a, int b) {
+        return unsignedRemainder(Kind.Int, a, b);
+    }
+
+    /**
+     * Unsigned division for two numbers.
+     */
+    @MethodSubstitution
+    public static long divide(long a, long b) {
+        return unsignedDivide(Kind.Long, a, b);
+    }
+
+    /**
+     * Unsigned remainder for two numbers.
+     */
+    @MethodSubstitution
+    public static long remainder(long a, long b) {
+        return unsignedRemainder(Kind.Long, a, b);
+    }
+
+    @NodeIntrinsic(UnsignedDivNode.class)
+    private static native int unsignedDivide(@ConstantNodeParameter Kind kind, int a, int b);
+
+    @NodeIntrinsic(UnsignedDivNode.class)
+    private static native long unsignedDivide(@ConstantNodeParameter Kind kind, long a, long b);
+
+    @NodeIntrinsic(UnsignedRemNode.class)
+    private static native int unsignedRemainder(@ConstantNodeParameter Kind kind, int a, int b);
+
+    @NodeIntrinsic(UnsignedRemNode.class)
+    private static native long unsignedRemainder(@ConstantNodeParameter Kind kind, long a, long b);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitCountNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.replacements.nodes;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+public class BitCountNode extends FloatingNode implements LIRGenLowerable, Canonicalizable {
+
+    @Input private ValueNode value;
+
+    public BitCountNode(ValueNode value) {
+        super(StampFactory.forInteger(Kind.Int, 0, value.kind().getBitCount()));
+        this.value = value;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (value.isConstant()) {
+            long v = value.asConstant().asLong();
+            if (value.kind().getStackKind() == Kind.Int) {
+                return ConstantNode.forInt(Integer.bitCount((int) v), graph());
+            } else if (value.kind() == Kind.Long) {
+                return ConstantNode.forInt(Long.bitCount(v), graph());
+            }
+        }
+        return this;
+    }
+
+    @NodeIntrinsic
+    public static native int bitCount(int v);
+
+    @NodeIntrinsic
+    public static native int bitCount(long v);
+
+    @Override
+    public void generate(LIRGenerator gen) {
+        Variable result = gen.newVariable(Kind.Int);
+        gen.emitBitCount(result, gen.operand(value));
+        gen.setResult(this, result);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.replacements.nodes;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+public class BitScanForwardNode extends FloatingNode implements LIRGenLowerable, Canonicalizable {
+
+    @Input private ValueNode value;
+
+    public BitScanForwardNode(ValueNode value) {
+        super(StampFactory.forInteger(Kind.Int, 0, value.kind().getBitCount()));
+        this.value = value;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (value.isConstant()) {
+            long v = value.asConstant().asLong();
+            if (value.kind().getStackKind() == Kind.Int) {
+                return ConstantNode.forInt(Integer.numberOfTrailingZeros((int) v), graph());
+            } else if (value.kind() == Kind.Long) {
+                return ConstantNode.forInt(Long.numberOfTrailingZeros(v), graph());
+            }
+        }
+        return this;
+    }
+
+    @NodeIntrinsic
+    public static native int scan(long v);
+
+    @Override
+    public void generate(LIRGenerator gen) {
+        Variable result = gen.newVariable(Kind.Int);
+        gen.emitBitScanForward(result, gen.operand(value));
+        gen.setResult(this, result);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.replacements.nodes;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+public class BitScanReverseNode extends FloatingNode implements LIRGenLowerable, Canonicalizable {
+
+    @Input private ValueNode value;
+
+    public BitScanReverseNode(ValueNode value) {
+        super(StampFactory.forInteger(Kind.Int, 0, value.kind().getBitCount()));
+        this.value = value;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (value.isConstant()) {
+            long v = value.asConstant().asLong();
+            if (value.kind().getStackKind() == Kind.Int) {
+                return ConstantNode.forInt(31 - Integer.numberOfLeadingZeros((int) v), graph());
+            } else if (value.kind() == Kind.Long) {
+                return ConstantNode.forInt(63 - Long.numberOfLeadingZeros(v), graph());
+            }
+        }
+        return this;
+    }
+
+    @NodeIntrinsic
+    public static native int scan(int v);
+
+    @NodeIntrinsic
+    public static native int scan(long v);
+
+    @Override
+    public void generate(LIRGenerator gen) {
+        Variable result = gen.newVariable(Kind.Int);
+        gen.emitBitScanReverse(result, gen.operand(value));
+        gen.setResult(this, result);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BranchProbabilityNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,81 @@
+/*
+ * 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.replacements.nodes;
+
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.nodes.util.*;
+
+/**
+ * Instances of this node class will look for a preceding if node and put the given probability into
+ * the if node's taken probability. Then the branch probability node will be removed. This node is
+ * intended primarily for snippets, so that they can define their fast and slow paths.
+ */
+public class BranchProbabilityNode extends FixedWithNextNode implements Simplifiable {
+
+    public static final double LIKELY_PROBABILITY = 0.6;
+    public static final double NOT_LIKELY_PROBABILITY = 1 - LIKELY_PROBABILITY;
+
+    public static final double FREQUENT_PROBABILITY = 0.9;
+    public static final double NOT_FREQUENT_PROBABILITY = 1 - FREQUENT_PROBABILITY;
+
+    public static final double FAST_PATH_PROBABILITY = 0.99;
+    public static final double SLOW_PATH_PROBABILITY = 1 - FAST_PATH_PROBABILITY;
+
+    public static final double NOT_DEOPT_PATH_PROBABILITY = 0.999;
+    public static final double DEOPT_PATH_PROBABILITY = 1 - NOT_DEOPT_PATH_PROBABILITY;
+
+    private final double probability;
+
+    public BranchProbabilityNode(double probability) {
+        super(StampFactory.forVoid());
+        assert probability >= 0 && probability <= 1;
+        this.probability = probability;
+    }
+
+    @Override
+    public void simplify(SimplifierTool tool) {
+        FixedNode current = this;
+        while (!(current instanceof BeginNode)) {
+            current = (FixedNode) current.predecessor();
+        }
+        BeginNode begin = (BeginNode) current;
+        assert begin.predecessor() instanceof IfNode : "explicit branch probability cannot follow a merge, only if nodes";
+        IfNode ifNode = (IfNode) begin.predecessor();
+        if (ifNode.trueSuccessor() == begin) {
+            ifNode.setTrueSuccessorProbability(probability);
+        } else {
+            ifNode.setTrueSuccessorProbability(1 - probability);
+        }
+
+        FixedNode next = next();
+        setNext(null);
+        ((FixedWithNextNode) predecessor()).setNext(next);
+        GraphUtil.killCFG(this);
+    }
+
+    @NodeIntrinsic
+    public static native void probability(@ConstantNodeParameter double probability);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.replacements.nodes;
+
+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.word.*;
+
+/**
+ * A special purpose store node that differs from {@link UnsafeStoreNode} in that it is not a
+ * {@link StateSplit} and does not include a write barrier.
+ */
+public class DirectObjectStoreNode extends FixedWithNextNode implements Lowerable {
+
+    @Input private ValueNode object;
+    @Input private ValueNode value;
+    @Input private ValueNode offset;
+    private final int displacement;
+
+    public DirectObjectStoreNode(ValueNode object, int displacement, ValueNode offset, ValueNode value) {
+        super(StampFactory.forVoid());
+        this.object = object;
+        this.value = value;
+        this.offset = offset;
+        this.displacement = displacement;
+    }
+
+    @NodeIntrinsic
+    public static native void storeObject(Object obj, @ConstantNodeParameter int displacement, long offset, Object value);
+
+    @NodeIntrinsic
+    public static native void storeLong(Object obj, @ConstantNodeParameter int displacement, long offset, long value);
+
+    @NodeIntrinsic
+    public static native void storeWord(Object obj, @ConstantNodeParameter int displacement, long offset, Word value);
+
+    @NodeIntrinsic
+    public static native void storeInt(Object obj, @ConstantNodeParameter int displacement, long offset, int value);
+
+    @Override
+    public void lower(LoweringTool tool) {
+        StructuredGraph graph = (StructuredGraph) this.graph();
+        IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, value.kind(), displacement, offset, graph, 1);
+        WriteNode write = graph.add(new WriteNode(object, value, location));
+        graph.replaceFixedWithFixed(this, write);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectReadNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.replacements.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.*;
+
+/**
+ * A special purpose store node that differs from {@link UnsafeStoreNode} in that it is not a
+ * {@link StateSplit} and takes a computed address instead of an object.
+ */
+public class DirectReadNode extends FixedWithNextNode implements LIRLowerable {
+
+    @Input private ValueNode address;
+    private final Kind readKind;
+
+    public DirectReadNode(ValueNode address, Kind readKind) {
+        super(StampFactory.forKind(readKind));
+        this.address = address;
+        this.readKind = readKind;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.setResult(this, gen.emitLoad(readKind, gen.operand(address), 0, Value.ILLEGAL, 0, false));
+    }
+
+    @NodeIntrinsic
+    public static native <T> T read(long address, @ConstantNodeParameter Kind kind);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectStoreNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.replacements.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.*;
+
+/**
+ * A special purpose store node that differs from {@link UnsafeStoreNode} in that it is not a
+ * {@link StateSplit} and takes a computed address instead of an object.
+ */
+public class DirectStoreNode extends FixedWithNextNode implements LIRLowerable {
+
+    @Input private ValueNode address;
+    @Input private ValueNode value;
+    private final Kind kind;
+
+    public DirectStoreNode(ValueNode address, ValueNode value, Kind kind) {
+        super(StampFactory.forVoid());
+        this.address = address;
+        this.value = value;
+        this.kind = kind;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        Value v = gen.operand(value);
+        gen.emitStore(kind, gen.operand(address), 0, Value.ILLEGAL, 0, v, false);
+    }
+
+    /*
+     * The kind of the store is provided explicitly in these intrinsics because it is not always
+     * possible to determine the kind from the given value during compilation (because stack kinds
+     * are used).
+     */
+
+    @NodeIntrinsic
+    public static native void store(long address, boolean value, @ConstantNodeParameter Kind kind);
+
+    @NodeIntrinsic
+    public static native void store(long address, byte value, @ConstantNodeParameter Kind kind);
+
+    @NodeIntrinsic
+    public static native void store(long address, short value, @ConstantNodeParameter Kind kind);
+
+    @NodeIntrinsic
+    public static native void store(long address, char value, @ConstantNodeParameter Kind kind);
+
+    @NodeIntrinsic
+    public static native void store(long address, int value, @ConstantNodeParameter Kind kind);
+
+    @NodeIntrinsic
+    public static native void store(long address, long value, @ConstantNodeParameter Kind kind);
+
+    @NodeIntrinsic
+    public static native void store(long address, float value, @ConstantNodeParameter Kind kind);
+
+    @NodeIntrinsic
+    public static native void store(long address, double value, @ConstantNodeParameter Kind kind);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ExplodeLoopNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.replacements.nodes;
+
+import java.util.*;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.replacements.Snippet.*;
+
+/**
+ * Placeholder node to denote to snippet preparation that the following loop must be completely
+ * unrolled.
+ * 
+ * @see VarargsParameter
+ */
+public final class ExplodeLoopNode extends FixedWithNextNode {
+
+    public ExplodeLoopNode() {
+        super(StampFactory.forVoid());
+    }
+
+    public LoopBeginNode findLoopBegin() {
+        Node next = next();
+        ArrayList<Node> succs = new ArrayList<>();
+        while (!(next instanceof LoopBeginNode)) {
+            assert next != null : "cannot find loop after " + this;
+            for (Node n : next.cfgSuccessors()) {
+                succs.add(n);
+            }
+            if (succs.size() == 1) {
+                next = succs.get(0);
+            } else {
+                return null;
+            }
+        }
+        return (LoopBeginNode) next;
+    }
+
+    /**
+     * A call to this method must be placed immediately prior to the loop that is to be exploded.
+     */
+    @NodeIntrinsic
+    public static native void explodeLoop();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/LoadSnippetVarargParameterNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2009, 2011, 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.replacements.nodes;
+
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.replacements.Snippet.*;
+
+/**
+ * Implements the semantics of {@link VarargsParameter}.
+ */
+public final class LoadSnippetVarargParameterNode extends FixedWithNextNode implements Canonicalizable {
+
+    @Input private ValueNode index;
+
+    private final LocalNode[] locals;
+
+    public LoadSnippetVarargParameterNode(LocalNode[] locals, ValueNode index, Stamp stamp) {
+        super(stamp);
+        this.index = index;
+        this.locals = locals;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (index.isConstant()) {
+            return locals[index.asConstant().asInt()];
+        }
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,88 @@
+/*
+ * 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.replacements.nodes;
+
+import java.lang.reflect.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.common.*;
+
+public class MacroNode extends AbstractStateSplit implements Lowerable {
+
+    @Input protected final NodeInputList<ValueNode> arguments;
+
+    private final int bci;
+    private final ResolvedJavaMethod targetMethod;
+    private final JavaType returnType;
+
+    protected MacroNode(Invoke invoke) {
+        super(invoke.node().stamp(), invoke.stateAfter());
+        this.arguments = new NodeInputList<>(this, invoke.methodCallTarget().arguments());
+        this.bci = invoke.bci();
+        this.targetMethod = invoke.methodCallTarget().targetMethod();
+        this.returnType = invoke.methodCallTarget().returnType();
+    }
+
+    public int getBci() {
+        return bci;
+    }
+
+    public ResolvedJavaMethod getTargetMethod() {
+        return targetMethod;
+    }
+
+    @SuppressWarnings("unused")
+    protected StructuredGraph getSnippetGraph(LoweringTool tool) {
+        return null;
+    }
+
+    @Override
+    public void lower(LoweringTool tool) {
+        StructuredGraph snippetGraph = getSnippetGraph(tool);
+
+        InvokeNode invoke = replaceWithInvoke();
+
+        if (snippetGraph != null) {
+            InliningUtil.inline(invoke, snippetGraph, false);
+        }
+    }
+
+    private InvokeNode replaceWithInvoke() {
+        InvokeNode invoke = createInvoke();
+        ((StructuredGraph) graph()).replaceFixedWithFixed(this, invoke);
+        return invoke;
+    }
+
+    protected InvokeNode createInvoke() {
+        InvokeKind invokeKind = Modifier.isStatic(targetMethod.getModifiers()) ? InvokeKind.Static : InvokeKind.Special;
+        MethodCallTargetNode callTarget = graph().add(new MethodCallTargetNode(invokeKind, targetMethod, arguments.toArray(new ValueNode[arguments.size()]), returnType));
+        InvokeNode invoke = graph().add(new InvokeNode(callTarget, bci));
+        invoke.setStateAfter(stateAfter());
+        return invoke;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.replacements.nodes;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+public class MathIntrinsicNode extends FloatingNode implements Canonicalizable, LIRGenLowerable {
+
+    @Input private ValueNode x;
+    private final Operation operation;
+
+    public enum Operation {
+        ABS, SQRT, LOG, LOG10, SIN, COS, TAN
+    }
+
+    public ValueNode x() {
+        return x;
+    }
+
+    public Operation operation() {
+        return operation;
+    }
+
+    public MathIntrinsicNode(ValueNode x, Operation op) {
+        super(StampFactory.forKind(x.kind()));
+        assert x.kind() == Kind.Double;
+        this.x = x;
+        this.operation = op;
+    }
+
+    @Override
+    public void generate(LIRGenerator gen) {
+        Variable input = gen.load(gen.operand(x()));
+        Variable result = gen.newVariable(kind());
+        switch (operation()) {
+            case ABS:
+                gen.emitMathAbs(result, input);
+                break;
+            case SQRT:
+                gen.emitMathSqrt(result, input);
+                break;
+            case LOG:
+                gen.emitMathLog(result, input, false);
+                break;
+            case LOG10:
+                gen.emitMathLog(result, input, true);
+                break;
+            case SIN:
+                gen.emitMathSin(result, input);
+                break;
+            case COS:
+                gen.emitMathCos(result, input);
+                break;
+            case TAN:
+                gen.emitMathTan(result, input);
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+        gen.setResult(this, result);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x().isConstant()) {
+            double value = x().asConstant().asDouble();
+            switch (operation()) {
+                case ABS:
+                    return ConstantNode.forDouble(Math.abs(value), graph());
+                case SQRT:
+                    return ConstantNode.forDouble(Math.sqrt(value), graph());
+                case LOG:
+                    return ConstantNode.forDouble(Math.log(value), graph());
+                case LOG10:
+                    return ConstantNode.forDouble(Math.log10(value), graph());
+                case SIN:
+                    return ConstantNode.forDouble(Math.sin(value), graph());
+                case COS:
+                    return ConstantNode.forDouble(Math.cos(value), graph());
+                case TAN:
+                    return ConstantNode.forDouble(Math.tan(value), graph());
+            }
+        }
+        return this;
+    }
+
+    @NodeIntrinsic
+    public static native double compute(double x, @ConstantNodeParameter Operation op);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReadRegisterNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,95 @@
+/*
+ * 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.replacements.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.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * Access the value of a specific register.
+ */
+@NodeInfo(nameTemplate = "ReadRegister %{p#register}")
+public final class ReadRegisterNode extends FixedWithNextNode implements LIRGenLowerable {
+
+    /**
+     * The fixed register to access.
+     */
+    private final Register register;
+
+    /**
+     * When true, subsequent uses of this node use the fixed register; when false, the value is
+     * moved into a new virtual register so that the fixed register is not seen by uses.
+     */
+    private final boolean directUse;
+
+    /**
+     * When true, this node is also an implicit definition of the value for the register allocator,
+     * i.e., the register is an implicit incoming value; when false, the register must be defined in
+     * the same method or must be an register excluded from register allocation.
+     */
+    private final boolean incoming;
+
+    public ReadRegisterNode(Register register, Kind kind, boolean directUse, boolean incoming) {
+        super(StampFactory.forKind(kind));
+        this.register = register;
+        this.directUse = directUse;
+        this.incoming = incoming;
+    }
+
+    /**
+     * Constructor to be used by node intrinsics where the stamp is inferred from the intrinsic
+     * definition.
+     */
+    public ReadRegisterNode(Register register, boolean directUse, boolean incoming) {
+        super(StampFactory.forNodeIntrinsic());
+        this.register = register;
+        this.directUse = directUse;
+        this.incoming = incoming;
+    }
+
+    @Override
+    public void generate(LIRGenerator generator) {
+        Value result = register.asValue(kind());
+        if (incoming) {
+            generator.emitIncomingValues(new Value[]{result});
+        }
+        if (!directUse) {
+            result = generator.emitMove(result);
+        }
+        generator.setResult(this, result);
+    }
+
+    @Override
+    public String toString(Verbosity verbosity) {
+        if (verbosity == Verbosity.Name) {
+            return super.toString(Verbosity.Name) + "%" + register;
+        } else {
+            return super.toString(verbosity);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReverseBytesNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.replacements.nodes;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+public class ReverseBytesNode extends FloatingNode implements LIRGenLowerable, Canonicalizable {
+
+    @Input private ValueNode value;
+
+    public ReverseBytesNode(ValueNode value) {
+        super(StampFactory.forKind(value.kind()));
+        assert kind().getStackKind() == Kind.Int || kind() == Kind.Long;
+        this.value = value;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (value.isConstant()) {
+            long v = value.asConstant().asLong();
+            if (kind().getStackKind() == Kind.Int) {
+                return ConstantNode.forInt(Integer.reverseBytes((int) v), graph());
+            } else if (kind() == Kind.Long) {
+                return ConstantNode.forLong(Long.reverseBytes(v), graph());
+            }
+        }
+        return this;
+    }
+
+    @NodeIntrinsic
+    public static native int reverse(int v);
+
+    @NodeIntrinsic
+    public static native long reverse(long v);
+
+    @Override
+    public void generate(LIRGenerator gen) {
+        Variable result = gen.newVariable(value.kind());
+        gen.emitByteSwap(result, gen.operand(value));
+        gen.setResult(this, result);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/WriteRegisterNode.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2013, 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.replacements.nodes;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * Changes the value of a specific register.
+ */
+@NodeInfo(nameTemplate = "WriteRegister %{p#register}")
+public final class WriteRegisterNode extends FixedWithNextNode implements LIRLowerable {
+
+    /**
+     * The fixed register to access.
+     */
+    private final Register register;
+
+    /**
+     * The new value assigned to the register.
+     */
+    @Input private ValueNode value;
+
+    public WriteRegisterNode(Register register, ValueNode value) {
+        super(StampFactory.forVoid());
+        this.register = register;
+        this.value = value;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool generator) {
+        Value val = generator.operand(value);
+        generator.emitMove(val, register.asValue(val.getKind()));
+    }
+
+    @Override
+    public String toString(Verbosity verbosity) {
+        if (verbosity == Verbosity.Name) {
+            return super.toString(Verbosity.Name) + "%" + register;
+        } else {
+            return super.toString(verbosity);
+        }
+    }
+}
--- a/graal/com.oracle.graal.snippets.amd64/src/com/oracle/graal/snippets/amd64/AMD64ConvertSnippets.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,196 +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.snippets.amd64;
-
-import static com.oracle.graal.snippets.SnippetTemplate.*;
-import static com.oracle.graal.snippets.SnippetTemplate.Arguments.*;
-import static com.oracle.graal.snippets.nodes.BranchProbabilityNode.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.debug.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.calc.ConvertNode.Op;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.snippets.*;
-import com.oracle.graal.snippets.Snippet.Parameter;
-import com.oracle.graal.snippets.SnippetTemplate.AbstractTemplates;
-import com.oracle.graal.snippets.SnippetTemplate.Arguments;
-import com.oracle.graal.snippets.SnippetTemplate.Key;
-
-/**
- * Snippets used for conversion operations on AMD64 where the AMD64 instruction used does not match
- * the semantics of the JVM specification.
- */
-public class AMD64ConvertSnippets implements SnippetsInterface {
-
-    /**
-     * Converts a float to an int.
-     * <p>
-     * This snippet accounts for the semantics of the x64 CVTTSS2SI instruction used to do the
-     * conversion. If the float value is a NaN, infinity or if the result of the conversion is
-     * larger than {@link Integer#MAX_VALUE} then CVTTSS2SI returns {@link Integer#MIN_VALUE} and
-     * extra tests are required on the float value to return the correct int value.
-     * 
-     * @param input the float being converted
-     * @param result the result produced by the CVTTSS2SI instruction
-     */
-    @Snippet
-    public static int f2i(@Parameter("input") float input, @Parameter("result") int result) {
-        if (result == Integer.MIN_VALUE) {
-            probability(NOT_FREQUENT_PROBABILITY);
-            if (Float.isNaN(input)) {
-                // input is NaN -> return 0
-                return 0;
-            } else if (input > 0.0f) {
-                // input is > 0 -> return max int
-                return Integer.MAX_VALUE;
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Converts a float to a long.
-     * <p>
-     * This snippet accounts for the semantics of the x64 CVTTSS2SI instruction used to do the
-     * conversion. If the float value is a NaN or infinity then CVTTSS2SI returns
-     * {@link Long#MIN_VALUE} and extra tests are required on the float value to return the correct
-     * long value.
-     * 
-     * @param input the float being converted
-     * @param result the result produced by the CVTTSS2SI instruction
-     */
-    @Snippet
-    public static long f2l(@Parameter("input") float input, @Parameter("result") long result) {
-        if (result == Long.MIN_VALUE) {
-            probability(NOT_FREQUENT_PROBABILITY);
-            if (Float.isNaN(input)) {
-                // input is NaN -> return 0
-                return 0;
-            } else if (input > 0.0f) {
-                // input is > 0 -> return max int
-                return Long.MAX_VALUE;
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Converts a double to an int.
-     * <p>
-     * This snippet accounts for the semantics of the x64 CVTTSD2SI instruction used to do the
-     * conversion. If the double value is a NaN, infinity or if the result of the conversion is
-     * larger than {@link Integer#MAX_VALUE} then CVTTSD2SI returns {@link Integer#MIN_VALUE} and
-     * extra tests are required on the double value to return the correct int value.
-     * 
-     * @param input the double being converted
-     * @param result the result produced by the CVTTSS2SI instruction
-     */
-    @Snippet
-    public static int d2i(@Parameter("input") double input, @Parameter("result") int result) {
-        if (result == Integer.MIN_VALUE) {
-            probability(NOT_FREQUENT_PROBABILITY);
-            if (Double.isNaN(input)) {
-                // input is NaN -> return 0
-                return 0;
-            } else if (input > 0.0d) {
-                // input is positive -> return maxInt
-                return Integer.MAX_VALUE;
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Converts a double to a long.
-     * <p>
-     * This snippet accounts for the semantics of the x64 CVTTSD2SI instruction used to do the
-     * conversion. If the double value is a NaN, infinity or if the result of the conversion is
-     * larger than {@link Long#MAX_VALUE} then CVTTSD2SI returns {@link Long#MIN_VALUE} and extra
-     * tests are required on the double value to return the correct long value.
-     * 
-     * @param input the double being converted
-     * @param result the result produced by the CVTTSS2SI instruction
-     */
-    @Snippet
-    public static long d2l(@Parameter("input") double input, @Parameter("result") long result) {
-        if (result == Long.MIN_VALUE) {
-            probability(NOT_FREQUENT_PROBABILITY);
-            if (Double.isNaN(input)) {
-                // input is NaN -> return 0
-                return 0;
-            } else if (input > 0.0d) {
-                // input is positive -> return maxInt
-                return Long.MAX_VALUE;
-            }
-        }
-        return result;
-    }
-
-    public static class Templates extends AbstractTemplates<AMD64ConvertSnippets> {
-
-        private final ResolvedJavaMethod f2i;
-        private final ResolvedJavaMethod f2l;
-        private final ResolvedJavaMethod d2i;
-        private final ResolvedJavaMethod d2l;
-
-        public Templates(CodeCacheProvider runtime, Assumptions assumptions, TargetDescription target) {
-            super(runtime, assumptions, target, AMD64ConvertSnippets.class);
-            f2i = snippet("f2i", float.class, int.class);
-            f2l = snippet("f2l", float.class, long.class);
-            d2i = snippet("d2i", double.class, int.class);
-            d2l = snippet("d2l", double.class, long.class);
-        }
-
-        public void lower(ConvertNode convert, LoweringTool tool) {
-            if (convert.opcode == Op.F2I) {
-                lower0(convert, tool, f2i);
-            } else if (convert.opcode == Op.F2L) {
-                lower0(convert, tool, f2l);
-            } else if (convert.opcode == Op.D2I) {
-                lower0(convert, tool, d2i);
-            } else if (convert.opcode == Op.D2L) {
-                lower0(convert, tool, d2l);
-            }
-        }
-
-        private void lower0(ConvertNode convert, LoweringTool tool, ResolvedJavaMethod snippet) {
-            StructuredGraph graph = (StructuredGraph) convert.graph();
-
-            // Insert a unique placeholder node in place of the Convert node so that the
-            // Convert node can be used as an input to the snippet. All usage of the
-            // Convert node are replaced by the placeholder which in turn is replaced by the
-            // snippet.
-
-            LocalNode replacee = graph.add(new LocalNode(Integer.MAX_VALUE, convert.stamp()));
-            convert.replaceAtUsages(replacee);
-            Key key = new Key(snippet);
-            Arguments arguments = arguments("input", convert.value()).add("result", convert);
-            SnippetTemplate template = cache.get(key, assumptions);
-            Debug.log("Lowering %s in %s: node=%s, template=%s, arguments=%s", convert.opcode, graph, convert, template, arguments);
-            template.instantiate(runtime, replacee, DEFAULT_REPLACER, tool, arguments);
-        }
-    }
-}
--- a/graal/com.oracle.graal.snippets.test/overview.html	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
-<head>
-<!--
-
-Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
-DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-
-This code is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License version 2 only, as
-published by the Free Software Foundation.  Oracle designates this
-particular file as subject to the "Classpath" exception as provided
-by Oracle in the LICENSE file that accompanied this code.
-
-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.
--->
-
-</head>
-<body>
-
-Documentation for the <code>com.oracle.graal.snippets.test</code> project.
-
-</body>
-</html>
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/CheckCastTest.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,214 +0,0 @@
-/*
- * Copyright (c) 2011, 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.snippets;
-
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.test.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.java.*;
-
-/**
- * Tests the implementation of checkcast, allowing profiling information to be manually specified.
- */
-public class CheckCastTest extends TypeCheckTest {
-
-    @Override
-    protected void replaceProfile(StructuredGraph graph, JavaTypeProfile profile) {
-        CheckCastNode ccn = graph.getNodes(CheckCastNode.class).first();
-        if (ccn != null) {
-            CheckCastNode ccnNew = graph.add(new CheckCastNode(ccn.type(), ccn.object(), profile));
-            graph.replaceFixedWithFixed(ccn, ccnNew);
-        }
-    }
-
-    @LongTest
-    public void test1() {
-        test("asNumber", profile(), 111);
-        test("asNumber", profile(Integer.class), 111);
-        test("asNumber", profile(Long.class, Short.class), 111);
-        test("asNumberExt", profile(), 111);
-        test("asNumberExt", profile(Integer.class), 111);
-        test("asNumberExt", profile(Long.class, Short.class), 111);
-    }
-
-    @LongTest
-    public void test2() {
-        test("asString", profile(), "111");
-        test("asString", profile(String.class), "111");
-        test("asString", profile(String.class), "111");
-
-        final String nullString = null;
-        test("asString", profile(), nullString);
-        test("asString", profile(String.class), nullString);
-        test("asString", profile(String.class), nullString);
-
-        test("asStringExt", profile(), "111");
-        test("asStringExt", profile(String.class), "111");
-        test("asStringExt", profile(String.class), "111");
-    }
-
-    @LongTest
-    public void test3() {
-        test("asNumber", profile(), "111");
-    }
-
-    @LongTest
-    public void test4() {
-        test("asString", profile(String.class), 111);
-    }
-
-    @LongTest
-    public void test5() {
-        test("asNumberExt", profile(), "111");
-    }
-
-    @LongTest
-    public void test6() {
-        test("asStringExt", profile(String.class), 111);
-    }
-
-    @LongTest
-    public void test7() {
-        Throwable throwable = new Exception();
-        test("asThrowable", profile(), throwable);
-        test("asThrowable", profile(Throwable.class), throwable);
-        test("asThrowable", profile(Exception.class, Error.class), throwable);
-    }
-
-    @LongTest
-    public void test8() {
-        test("arrayStore", new Object[100], "111");
-    }
-
-    @LongTest
-    public void test8_1() {
-        test("arrayFill", new Object[100], "111");
-    }
-
-    public static Number asNumber(Object o) {
-        return (Number) o;
-    }
-
-    public static String asString(Object o) {
-        return (String) o;
-    }
-
-    public static Throwable asThrowable(Object o) {
-        return (Throwable) o;
-    }
-
-    public static ValueNode asValueNode(Object o) {
-        return (ValueNode) o;
-    }
-
-    public static Number asNumberExt(Object o) {
-        Number n = (Number) o;
-        return n.intValue() + 10;
-    }
-
-    public static String asStringExt(Object o) {
-        String s = (String) o;
-        return "#" + s;
-    }
-
-    public static Object[] arrayStore(Object[] arr, Object value) {
-        arr[15] = value;
-        return arr;
-    }
-
-    public static Object[] arrayFill(Object[] arr, Object value) {
-        for (int i = 0; i < arr.length; i++) {
-            arr[i] = value;
-        }
-        return arr;
-    }
-
-    static class Depth1 implements Cloneable {
-    }
-
-    static class Depth2 extends Depth1 {
-    }
-
-    static class Depth3 extends Depth2 {
-    }
-
-    static class Depth4 extends Depth3 {
-    }
-
-    static class Depth5 extends Depth4 {
-    }
-
-    static class Depth6 extends Depth5 {
-    }
-
-    static class Depth7 extends Depth6 {
-    }
-
-    static class Depth8 extends Depth7 {
-    }
-
-    static class Depth9 extends Depth8 {
-    }
-
-    static class Depth10 extends Depth9 {
-    }
-
-    static class Depth11 extends Depth10 {
-    }
-
-    static class Depth12 extends Depth11 {
-    }
-
-    static class Depth13 extends Depth12 {
-    }
-
-    static class Depth14 extends Depth12 {
-    }
-
-    public static Depth12 asDepth12(Object o) {
-        return (Depth12) o;
-    }
-
-    public static Depth12[][] asDepth12Arr(Object o) {
-        return (Depth12[][]) o;
-    }
-
-    public static Cloneable asCloneable(Object o) {
-        return (Cloneable) o;
-    }
-
-    @LongTest
-    public void test9() {
-        Object o = new Depth13();
-        test("asDepth12", profile(), o);
-        test("asDepth12", profile(Depth13.class), o);
-        test("asDepth12", profile(Depth13.class, Depth14.class), o);
-    }
-
-    @LongTest
-    public void test10() {
-        Object o = new Depth13[3][];
-        test("asDepth12Arr", o);
-    }
-}
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/InstanceOfDynamicTest.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2011, 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.snippets;
-
-import com.oracle.graal.test.*;
-import com.oracle.graal.compiler.test.*;
-import com.oracle.graal.nodes.java.*;
-
-/**
- * Tests for {@link InstanceOfDynamicNode}.
- */
-public class InstanceOfDynamicTest extends GraalCompilerTest {
-
-    public static int id(int value) {
-        return value;
-    }
-
-    @LongTest
-    public void test100() {
-        final Object nul = null;
-        test("isStringDynamic", nul);
-        test("isStringDynamic", "object");
-        test("isStringDynamic", Object.class);
-    }
-
-    @LongTest
-    public void test101() {
-        final Object nul = null;
-        test("isStringIntDynamic", nul);
-        test("isStringIntDynamic", "object");
-        test("isStringIntDynamic", Object.class);
-    }
-
-    @LongTest
-    public void test103() {
-        test("isInstanceDynamic", String.class, null);
-        test("isInstanceDynamic", String.class, "object");
-        test("isInstanceDynamic", String.class, Object.class);
-        test("isInstanceDynamic", int.class, null);
-        test("isInstanceDynamic", int.class, "Object");
-        test("isInstanceDynamic", int.class, Object.class);
-    }
-
-    @LongTest
-    public void test104() {
-        test("isInstanceIntDynamic", String.class, null);
-        test("isInstanceIntDynamic", String.class, "object");
-        test("isInstanceIntDynamic", String.class, Object.class);
-        test("isInstanceIntDynamic", int.class, null);
-        test("isInstanceIntDynamic", int.class, "Object");
-        test("isInstanceIntDynamic", int.class, Object.class);
-    }
-
-    public static boolean isStringDynamic(Object o) {
-        return String.class.isInstance(o);
-    }
-
-    public static int isStringIntDynamic(Object o) {
-        if (String.class.isInstance(o)) {
-            return o.toString().length();
-        }
-        return o.getClass().getName().length();
-    }
-
-    public static boolean isInstanceDynamic(Class c, Object o) {
-        return c.isInstance(o);
-    }
-
-    public static int isInstanceIntDynamic(Class c, Object o) {
-        if (c.isInstance(o)) {
-            return o.toString().length();
-        }
-        return o.getClass().getName().length();
-    }
-}
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/InstanceOfTest.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,400 +0,0 @@
-/*
- * Copyright (c) 2011, 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.snippets;
-
-import java.util.*;
-
-
-import com.oracle.graal.api.code.CompilationResult.Call;
-import com.oracle.graal.api.code.CompilationResult.Mark;
-import com.oracle.graal.api.code.CompilationResult.Site;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.test.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.phases.*;
-import com.oracle.graal.phases.common.*;
-import com.oracle.graal.snippets.CheckCastTest.Depth12;
-import com.oracle.graal.snippets.CheckCastTest.Depth13;
-import com.oracle.graal.snippets.CheckCastTest.Depth14;
-
-/**
- * Tests the implementation of instanceof, allowing profiling information to be manually specified.
- */
-public class InstanceOfTest extends TypeCheckTest {
-
-    @Override
-    protected void editPhasePlan(ResolvedJavaMethod method, StructuredGraph graph, PhasePlan phasePlan) {
-        phasePlan.disablePhase(InliningPhase.class);
-    }
-
-    @Override
-    protected void replaceProfile(StructuredGraph graph, JavaTypeProfile profile) {
-        InstanceOfNode ion = graph.getNodes().filter(InstanceOfNode.class).first();
-        if (ion != null) {
-            InstanceOfNode ionNew = graph.add(new InstanceOfNode(ion.type(), ion.object(), profile));
-            graph.replaceFloating(ion, ionNew);
-        }
-    }
-
-    @LongTest
-    public void test1() {
-        test("isString", profile(), "object");
-        test("isString", profile(String.class), "object");
-
-        test("isString", profile(), Object.class);
-        test("isString", profile(String.class), Object.class);
-    }
-
-    @LongTest
-    public void test2() {
-        test("isStringInt", profile(), "object");
-        test("isStringInt", profile(String.class), "object");
-
-        test("isStringInt", profile(), Object.class);
-        test("isStringInt", profile(String.class), Object.class);
-    }
-
-    @LongTest
-    public void test2_1() {
-        test("isStringIntComplex", profile(), "object");
-        test("isStringIntComplex", profile(String.class), "object");
-
-        test("isStringIntComplex", profile(), Object.class);
-        test("isStringIntComplex", profile(String.class), Object.class);
-    }
-
-    @LongTest
-    public void test3() {
-        Throwable throwable = new Exception();
-        test("isThrowable", profile(), throwable);
-        test("isThrowable", profile(Throwable.class), throwable);
-        test("isThrowable", profile(Exception.class, Error.class), throwable);
-
-        test("isThrowable", profile(), Object.class);
-        test("isThrowable", profile(Throwable.class), Object.class);
-        test("isThrowable", profile(Exception.class, Error.class), Object.class);
-    }
-
-    @LongTest
-    public void test3_1() {
-        onlyFirstIsException(new Exception(), new Error());
-        test("onlyFirstIsException", profile(), new Exception(), new Error());
-        test("onlyFirstIsException", profile(), new Error(), new Exception());
-        test("onlyFirstIsException", profile(), new Exception(), new Exception());
-        test("onlyFirstIsException", profile(), new Error(), new Error());
-    }
-
-    @LongTest
-    public void test4() {
-        Throwable throwable = new Exception();
-        test("isThrowableInt", profile(), throwable);
-        test("isThrowableInt", profile(Throwable.class), throwable);
-        test("isThrowableInt", profile(Exception.class, Error.class), throwable);
-
-        test("isThrowableInt", profile(), Object.class);
-        test("isThrowableInt", profile(Throwable.class), Object.class);
-        test("isThrowableInt", profile(Exception.class, Error.class), Object.class);
-    }
-
-    @LongTest
-    public void test5() {
-        Map map = new HashMap<>();
-        test("isMap", profile(), map);
-        test("isMap", profile(HashMap.class), map);
-        test("isMap", profile(TreeMap.class, HashMap.class), map);
-
-        test("isMap", profile(), Object.class);
-        test("isMap", profile(HashMap.class), Object.class);
-        test("isMap", profile(TreeMap.class, HashMap.class), Object.class);
-    }
-
-    @LongTest
-    public void test6() {
-        Map map = new HashMap<>();
-        test("isMapInt", profile(), map);
-        test("isMapInt", profile(HashMap.class), map);
-        test("isMapInt", profile(TreeMap.class, HashMap.class), map);
-
-        test("isMapInt", profile(), Object.class);
-        test("isMapInt", profile(HashMap.class), Object.class);
-        test("isMapInt", profile(TreeMap.class, HashMap.class), Object.class);
-    }
-
-    @LongTest
-    public void test7() {
-        Object o = new Depth13();
-        test("isDepth12", profile(), o);
-        test("isDepth12", profile(Depth13.class), o);
-        test("isDepth12", profile(Depth13.class, Depth14.class), o);
-
-        o = "not a depth";
-        test("isDepth12", profile(), o);
-        test("isDepth12", profile(Depth13.class), o);
-        test("isDepth12", profile(Depth13.class, Depth14.class), o);
-    }
-
-    @LongTest
-    public void test8() {
-        Object o = new Depth13();
-        test("isDepth12Int", profile(), o);
-        test("isDepth12Int", profile(Depth13.class), o);
-        test("isDepth12Int", profile(Depth13.class, Depth14.class), o);
-
-        o = "not a depth";
-        test("isDepth12Int", profile(), o);
-        test("isDepth12Int", profile(Depth13.class), o);
-        test("isDepth12Int", profile(Depth13.class, Depth14.class), o);
-    }
-
-    public static boolean isString(Object o) {
-        return o instanceof String;
-    }
-
-    public static int isStringInt(Object o) {
-        if (o instanceof String) {
-            return id(1);
-        }
-        return id(0);
-    }
-
-    public static int isStringIntComplex(Object o) {
-        if (o instanceof String || o instanceof Integer) {
-            return id(o instanceof String ? 1 : 0);
-        }
-        return id(0);
-    }
-
-    public static int id(int value) {
-        return value;
-    }
-
-    public static boolean isThrowable(Object o) {
-        return ((Throwable) o) instanceof Exception;
-    }
-
-    public static int onlyFirstIsException(Throwable t1, Throwable t2) {
-        if (t1 instanceof Exception ^ t2 instanceof Exception) {
-            return t1 instanceof Exception ? 1 : -1;
-        }
-        return -1;
-    }
-
-    public static int isThrowableInt(Object o) {
-        int result = o instanceof Throwable ? 4 : 5;
-        if (o instanceof Throwable) {
-            return id(4);
-        }
-        return result;
-    }
-
-    public static boolean isMap(Object o) {
-        return o instanceof Map;
-    }
-
-    public static int isMapInt(Object o) {
-        if (o instanceof Map) {
-            return id(1);
-        }
-        return id(0);
-    }
-
-    public static boolean isDepth12(Object o) {
-        return o instanceof Depth12;
-    }
-
-    public static int isDepth12Int(Object o) {
-        if (o instanceof Depth12) {
-            return id(0);
-        }
-        return id(0);
-    }
-
-    abstract static class MySite {
-
-        final int offset;
-
-        MySite(int offset) {
-            this.offset = offset;
-        }
-    }
-
-    static class MyMark extends MySite {
-
-        MyMark(int offset) {
-            super(offset);
-        }
-    }
-
-    abstract static class MySafepoint extends MySite {
-
-        MySafepoint(int offset) {
-            super(offset);
-        }
-    }
-
-    static class MyCall extends MySafepoint {
-
-        MyCall(int offset) {
-            super(offset);
-        }
-    }
-
-    @LongTest
-    public void test9() {
-        MyCall callAt63 = new MyCall(63);
-        MyMark markAt63 = new MyMark(63);
-        test("compareMySites", callAt63, callAt63);
-        test("compareMySites", callAt63, markAt63);
-        test("compareMySites", markAt63, callAt63);
-        test("compareMySites", markAt63, markAt63);
-    }
-
-    public static int compareMySites(MySite s1, MySite s2) {
-        if (s1.offset == s2.offset && (s1 instanceof MyMark ^ s2 instanceof MyMark)) {
-            return s1 instanceof MyMark ? -1 : 1;
-        }
-        return s1.offset - s2.offset;
-    }
-
-    @LongTest
-    public void test10() {
-        Mark[] noMarks = {};
-        Call callAt63 = new Call(null, 63, 5, true, null);
-        Mark markAt63 = new Mark(63, "1", noMarks);
-        test("compareSites", callAt63, callAt63);
-        test("compareSites", callAt63, markAt63);
-        test("compareSites", markAt63, callAt63);
-        test("compareSites", markAt63, markAt63);
-    }
-
-    public static int compareSites(Site s1, Site s2) {
-        if (s1.pcOffset == s2.pcOffset && (s1 instanceof Mark ^ s2 instanceof Mark)) {
-            return s1 instanceof Mark ? -1 : 1;
-        }
-        return s1.pcOffset - s2.pcOffset;
-    }
-
-    /**
-     * This test exists to show the kind of pattern that is be optimizable by
-     * {@code removeIntermediateMaterialization()} in {@link IfNode}.
-     * <p>
-     * The test exists in this source file as the transformation was originally motivated by the
-     * need to remove use of special JumpNodes in the {@code InstanceOfSnippets}.
-     */
-    @LongTest
-    public void test_removeIntermediateMaterialization() {
-        List<String> list = Arrays.asList("1", "2", "3", "4");
-        test("removeIntermediateMaterialization", profile(), list, "2", "yes", "no");
-        test("removeIntermediateMaterialization", profile(), list, null, "yes", "no");
-        test("removeIntermediateMaterialization", profile(), null, "2", "yes", "no");
-    }
-
-    public static String removeIntermediateMaterialization(List<Object> list, Object e, String a, String b) {
-        boolean test;
-        if (list == null || e == null) {
-            test = false;
-        } else {
-            test = false;
-            for (Object i : list) {
-                if (i.equals(e)) {
-                    test = true;
-                    break;
-                }
-            }
-        }
-        if (test) {
-            return a;
-        }
-        return b;
-    }
-
-    abstract static class A {
-    }
-
-    static class B extends A {
-    }
-
-    static class C extends B {
-    }
-
-    abstract static class D extends C {
-    }
-
-    public static boolean isArrayOfA(Object o) {
-        return o instanceof A[];
-    }
-
-    public static boolean isArrayOfB(Object o) {
-        return o instanceof B[];
-    }
-
-    public static boolean isArrayOfC(Object o) {
-        return o instanceof C[];
-    }
-
-    public static boolean isArrayOfD(Object o) {
-        return o instanceof D[];
-    }
-
-    @LongTest
-    public void testArray() {
-        Object aArray = new A[10];
-        test("isArrayOfA", aArray);
-
-        Object bArray = new B[10];
-        test("isArrayOfA", aArray);
-        test("isArrayOfA", bArray);
-        test("isArrayOfB", aArray);
-        test("isArrayOfB", bArray);
-
-        Object cArray = new C[10];
-        test("isArrayOfA", aArray);
-        test("isArrayOfA", bArray);
-        test("isArrayOfA", cArray);
-        test("isArrayOfB", aArray);
-        test("isArrayOfB", bArray);
-        test("isArrayOfB", cArray);
-        test("isArrayOfC", aArray);
-        test("isArrayOfC", bArray);
-        test("isArrayOfC", cArray);
-
-        Object dArray = new D[10];
-        test("isArrayOfA", aArray);
-        test("isArrayOfA", bArray);
-        test("isArrayOfA", cArray);
-        test("isArrayOfA", dArray);
-        test("isArrayOfB", aArray);
-        test("isArrayOfB", bArray);
-        test("isArrayOfB", cArray);
-        test("isArrayOfB", dArray);
-        test("isArrayOfC", aArray);
-        test("isArrayOfC", bArray);
-        test("isArrayOfC", cArray);
-        test("isArrayOfC", dArray);
-        test("isArrayOfD", aArray);
-        test("isArrayOfD", bArray);
-        test("isArrayOfD", cArray);
-        test("isArrayOfD", dArray);
-    }
-}
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/IntrinsificationTest.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,461 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets;
-
-import static org.junit.Assert.*;
-
-import java.util.concurrent.*;
-
-import org.junit.*;
-
-import sun.misc.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.compiler.test.*;
-import com.oracle.graal.debug.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.phases.*;
-import com.oracle.graal.phases.common.*;
-import com.oracle.graal.snippets.nodes.*;
-
-/**
- * Tests if compiler intrinsics are inlined correctly. Most test cases only assert that there are no
- * remaining invocations in the graph. This is sufficient if the method that is being intrinsified
- * is a native method. For Java methods, additional checks are necessary.
- */
-public class IntrinsificationTest extends GraalCompilerTest {
-
-    @Test
-    public void testObjectIntrinsics() {
-        test("getClassSnippet");
-        test("objectHashCodeSnippet");
-    }
-
-    @SuppressWarnings("all")
-    public static boolean getClassSnippet(Object obj, Class<?> clazz) {
-        return obj.getClass() == clazz;
-    }
-
-    @SuppressWarnings("all")
-    public static int objectHashCodeSnippet(TestClassA obj) {
-        return obj.hashCode();
-    }
-
-    @Test
-    public void testClassIntrinsics() {
-        test("getModifiersSnippet");
-        test("isInstanceSnippet");
-        test("isInterfaceSnippet");
-        test("isArraySnippet");
-        test("isPrimitiveSnippet");
-        test("getSuperClassSnippet");
-        test("getComponentTypeSnippet");
-    }
-
-    @SuppressWarnings("all")
-    public static int getModifiersSnippet(Class<?> clazz) {
-        return clazz.getModifiers();
-    }
-
-    @SuppressWarnings("all")
-    public static boolean isInstanceSnippet(Class<?> clazz) {
-        return clazz.isInstance(Number.class);
-    }
-
-    @SuppressWarnings("all")
-    public static boolean isInterfaceSnippet(Class<?> clazz) {
-        return clazz.isInterface();
-    }
-
-    @SuppressWarnings("all")
-    public static boolean isArraySnippet(Class<?> clazz) {
-        return clazz.isArray();
-    }
-
-    @SuppressWarnings("all")
-    public static boolean isPrimitiveSnippet(Class<?> clazz) {
-        return clazz.isPrimitive();
-    }
-
-    @SuppressWarnings("all")
-    public static Class<?> getSuperClassSnippet(Class<?> clazz) {
-        return clazz.getSuperclass();
-    }
-
-    @SuppressWarnings("all")
-    public static Class<?> getComponentTypeSnippet(Class<?> clazz) {
-        return clazz.getComponentType();
-    }
-
-    @Test
-    public void testThreadIntrinsics() {
-        test("currentThreadSnippet");
-        test("threadIsInterruptedSnippet");
-        test("threadInterruptedSnippet");
-    }
-
-    @SuppressWarnings("all")
-    public static Thread currentThreadSnippet() {
-        return Thread.currentThread();
-    }
-
-    @SuppressWarnings("all")
-    public static boolean threadIsInterruptedSnippet(Thread thread) {
-        return thread.isInterrupted();
-    }
-
-    @SuppressWarnings("all")
-    public static boolean threadInterruptedSnippet() {
-        return Thread.interrupted();
-    }
-
-    @Test
-    public void testSystemIntrinsics() {
-        test("systemTimeSnippet");
-        test("systemIdentityHashCode");
-    }
-
-    @SuppressWarnings("all")
-    public static long systemTimeSnippet() {
-        return System.currentTimeMillis() + System.nanoTime();
-    }
-
-    @SuppressWarnings("all")
-    public static int systemIdentityHashCode(Object obj) {
-        return System.identityHashCode(obj);
-    }
-
-    @Test
-    public void testUnsafeIntrinsics() {
-        test("unsafeCompareAndSwapIntSnippet");
-        test("unsafeCompareAndSwapLongSnippet");
-        test("unsafeCompareAndSwapObjectSnippet");
-
-        test("unsafeGetBooleanSnippet");
-        test("unsafeGetByteSnippet");
-        test("unsafeGetShortSnippet");
-        test("unsafeGetCharSnippet");
-        test("unsafeGetIntSnippet");
-        test("unsafeGetFloatSnippet");
-        test("unsafeGetDoubleSnippet");
-        test("unsafeGetObjectSnippet");
-
-        test("unsafePutBooleanSnippet");
-        test("unsafePutByteSnippet");
-        test("unsafePutShortSnippet");
-        test("unsafePutCharSnippet");
-        test("unsafePutIntSnippet");
-        test("unsafePutFloatSnippet");
-        test("unsafePutDoubleSnippet");
-        test("unsafePutObjectSnippet");
-
-        test("unsafeDirectMemoryReadSnippet");
-        test("unsafeDirectMemoryWriteSnippet");
-    }
-
-    @SuppressWarnings("all")
-    public static boolean unsafeCompareAndSwapIntSnippet(Unsafe unsafe, Object obj, long offset) {
-        return unsafe.compareAndSwapInt(obj, offset, 0, 1);
-    }
-
-    @SuppressWarnings("all")
-    public static boolean unsafeCompareAndSwapLongSnippet(Unsafe unsafe, Object obj, long offset) {
-        return unsafe.compareAndSwapLong(obj, offset, 0, 1);
-    }
-
-    @SuppressWarnings("all")
-    public static boolean unsafeCompareAndSwapObjectSnippet(Unsafe unsafe, Object obj, long offset) {
-        return unsafe.compareAndSwapObject(obj, offset, null, new Object());
-    }
-
-    @SuppressWarnings("all")
-    public static boolean unsafeGetBooleanSnippet(Unsafe unsafe, Object obj, long offset) {
-        return unsafe.getBoolean(obj, offset) && unsafe.getBooleanVolatile(obj, offset);
-    }
-
-    @SuppressWarnings("all")
-    public static int unsafeGetByteSnippet(Unsafe unsafe, Object obj, long offset) {
-        return unsafe.getByte(obj, offset) + unsafe.getByteVolatile(obj, offset);
-    }
-
-    @SuppressWarnings("all")
-    public static int unsafeGetShortSnippet(Unsafe unsafe, Object obj, long offset) {
-        return unsafe.getShort(obj, offset) + unsafe.getShortVolatile(obj, offset);
-    }
-
-    @SuppressWarnings("all")
-    public static int unsafeGetCharSnippet(Unsafe unsafe, Object obj, long offset) {
-        return unsafe.getChar(obj, offset) + unsafe.getCharVolatile(obj, offset);
-    }
-
-    @SuppressWarnings("all")
-    public static int unsafeGetIntSnippet(Unsafe unsafe, Object obj, long offset) {
-        return unsafe.getInt(obj, offset) + unsafe.getIntVolatile(obj, offset);
-    }
-
-    @SuppressWarnings("all")
-    public static long unsafeGetLongSnippet(Unsafe unsafe, Object obj, long offset) {
-        return unsafe.getLong(obj, offset) + unsafe.getLongVolatile(obj, offset);
-    }
-
-    @SuppressWarnings("all")
-    public static float unsafeGetFloatSnippet(Unsafe unsafe, Object obj, long offset) {
-        return unsafe.getFloat(obj, offset) + unsafe.getFloatVolatile(obj, offset);
-    }
-
-    @SuppressWarnings("all")
-    public static double unsafeGetDoubleSnippet(Unsafe unsafe, Object obj, long offset) {
-        return unsafe.getDouble(obj, offset) + unsafe.getDoubleVolatile(obj, offset);
-    }
-
-    @SuppressWarnings("all")
-    public static boolean unsafeGetObjectSnippet(Unsafe unsafe, Object obj, long offset) {
-        return unsafe.getObject(obj, offset) == unsafe.getObjectVolatile(obj, offset);
-    }
-
-    @SuppressWarnings("all")
-    public static void unsafePutBooleanSnippet(Unsafe unsafe, Object obj, long offset, boolean value) {
-        unsafe.putBoolean(obj, offset, value);
-        unsafe.putBooleanVolatile(obj, offset, value);
-    }
-
-    @SuppressWarnings("all")
-    public static void unsafePutByteSnippet(Unsafe unsafe, Object obj, long offset, byte value) {
-        unsafe.putByte(obj, offset, value);
-        unsafe.putByteVolatile(obj, offset, value);
-    }
-
-    @SuppressWarnings("all")
-    public static void unsafePutShortSnippet(Unsafe unsafe, Object obj, long offset, short value) {
-        unsafe.putShort(obj, offset, value);
-        unsafe.putShortVolatile(obj, offset, value);
-    }
-
-    @SuppressWarnings("all")
-    public static void unsafePutCharSnippet(Unsafe unsafe, Object obj, long offset, char value) {
-        unsafe.putChar(obj, offset, value);
-        unsafe.putCharVolatile(obj, offset, value);
-    }
-
-    @SuppressWarnings("all")
-    public static void unsafePutIntSnippet(Unsafe unsafe, Object obj, long offset, int value) {
-        unsafe.putInt(obj, offset, value);
-        unsafe.putIntVolatile(obj, offset, value);
-        unsafe.putOrderedInt(obj, offset, value);
-    }
-
-    @SuppressWarnings("all")
-    public static void unsafePutLongSnippet(Unsafe unsafe, Object obj, long offset, long value) {
-        unsafe.putLong(obj, offset, value);
-        unsafe.putLongVolatile(obj, offset, value);
-        unsafe.putOrderedLong(obj, offset, value);
-    }
-
-    @SuppressWarnings("all")
-    public static void unsafePutFloatSnippet(Unsafe unsafe, Object obj, long offset, float value) {
-        unsafe.putFloat(obj, offset, value);
-        unsafe.putFloatVolatile(obj, offset, value);
-    }
-
-    @SuppressWarnings("all")
-    public static void unsafePutDoubleSnippet(Unsafe unsafe, Object obj, long offset, double value) {
-        unsafe.putDouble(obj, offset, value);
-        unsafe.putDoubleVolatile(obj, offset, value);
-    }
-
-    @SuppressWarnings("all")
-    public static void unsafePutObjectSnippet(Unsafe unsafe, Object obj, long offset, Object value) {
-        unsafe.putObject(obj, offset, value);
-        unsafe.putObjectVolatile(obj, offset, value);
-        unsafe.putOrderedObject(obj, offset, value);
-    }
-
-    @SuppressWarnings("all")
-    public static double unsafeDirectMemoryReadSnippet(Unsafe unsafe, long address) {
-        // Unsafe.getBoolean(long) and Unsafe.getObject(long) do not exist
-        return unsafe.getByte(address) + unsafe.getShort(address) + unsafe.getChar(address) + unsafe.getInt(address) + unsafe.getLong(address) + unsafe.getFloat(address) + unsafe.getDouble(address);
-    }
-
-    @SuppressWarnings("all")
-    public static void unsafeDirectMemoryWriteSnippet(Unsafe unsafe, long address, byte value) {
-        // Unsafe.putBoolean(long) and Unsafe.putObject(long) do not exist
-        unsafe.putByte(address, value);
-        unsafe.putShort(address, value);
-        unsafe.putChar(address, (char) value);
-        unsafe.putInt(address, value);
-        unsafe.putLong(address, value);
-        unsafe.putFloat(address, value);
-        unsafe.putDouble(address, value);
-    }
-
-    @Test
-    public void testMathIntrinsics() {
-        assertInGraph(assertNotInGraph(test("mathAbsSnippet"), IfNode.class), MathIntrinsicNode.class);     // Java
-        test("mathSnippet");
-    }
-
-    @SuppressWarnings("all")
-    public static double mathAbsSnippet(double value) {
-        return Math.abs(value);
-    }
-
-    @SuppressWarnings("all")
-    public static double mathSnippet(double value) {
-        return Math.sqrt(value) + Math.log(value) + Math.log10(value) + Math.sin(value) + Math.cos(value) + Math.tan(value);
-        // Math.exp(value) +
-        // Math.pow(value, 13);
-    }
-
-    @Test
-    public void testIntegerIntrinsics() {
-        assertInGraph(test("integerReverseBytesSnippet"), ReverseBytesNode.class);              // Java
-        assertInGraph(test("integerNumberOfLeadingZerosSnippet"), BitScanReverseNode.class);    // Java
-        assertInGraph(test("integerNumberOfTrailingZerosSnippet"), BitScanForwardNode.class);   // Java
-        assertInGraph(test("integerBitCountSnippet"), BitCountNode.class);                      // Java
-    }
-
-    @SuppressWarnings("all")
-    public static int integerReverseBytesSnippet(int value) {
-        return Integer.reverseBytes(value);
-    }
-
-    @SuppressWarnings("all")
-    public static int integerNumberOfLeadingZerosSnippet(int value) {
-        return Integer.numberOfLeadingZeros(value);
-    }
-
-    @SuppressWarnings("all")
-    public static int integerNumberOfTrailingZerosSnippet(int value) {
-        return Integer.numberOfTrailingZeros(value);
-    }
-
-    @SuppressWarnings("all")
-    public static int integerBitCountSnippet(int value) {
-        return Integer.bitCount(value);
-    }
-
-    @Test
-    public void testLongIntrinsics() {
-        assertInGraph(test("longReverseBytesSnippet"), ReverseBytesNode.class);              // Java
-        assertInGraph(test("longNumberOfLeadingZerosSnippet"), BitScanReverseNode.class);    // Java
-        assertInGraph(test("longNumberOfTrailingZerosSnippet"), BitScanForwardNode.class);   // Java
-        assertInGraph(test("longBitCountSnippet"), BitCountNode.class);                      // Java
-    }
-
-    @SuppressWarnings("all")
-    public static long longReverseBytesSnippet(long value) {
-        return Long.reverseBytes(value);
-    }
-
-    @SuppressWarnings("all")
-    public static long longNumberOfLeadingZerosSnippet(long value) {
-        return Long.numberOfLeadingZeros(value);
-    }
-
-    @SuppressWarnings("all")
-    public static long longNumberOfTrailingZerosSnippet(long value) {
-        return Long.numberOfTrailingZeros(value);
-    }
-
-    @SuppressWarnings("all")
-    public static int longBitCountSnippet(long value) {
-        return Long.bitCount(value);
-    }
-
-    @Test
-    public void testFloatIntrinsics() {
-        assertInGraph(test("floatToIntBitsSnippet"), ConvertNode.class); // Java
-        test("intBitsToFloatSnippet");
-    }
-
-    @SuppressWarnings("all")
-    public static int floatToIntBitsSnippet(float value) {
-        return Float.floatToIntBits(value);
-    }
-
-    @SuppressWarnings("all")
-    public static float intBitsToFloatSnippet(int value) {
-        return Float.intBitsToFloat(value);
-    }
-
-    @Test
-    public void testDoubleIntrinsics() {
-        assertInGraph(test("doubleToLongBitsSnippet"), ConvertNode.class); // Java
-        test("longBitsToDoubleSnippet");
-    }
-
-    @SuppressWarnings("all")
-    public static long doubleToLongBitsSnippet(double value) {
-        return Double.doubleToLongBits(value);
-    }
-
-    @SuppressWarnings("all")
-    public static double longBitsToDoubleSnippet(long value) {
-        return Double.longBitsToDouble(value);
-    }
-
-    private StructuredGraph test(final String snippet) {
-        return Debug.scope("IntrinsificationTest", runtime.lookupJavaMethod(getMethod(snippet)), new Callable<StructuredGraph>() {
-
-            @Override
-            public StructuredGraph call() {
-                StructuredGraph graph = parse(snippet);
-                PhasePlan phasePlan = getDefaultPhasePlan();
-                Assumptions assumptions = new Assumptions(true);
-                new ComputeProbabilityPhase().apply(graph);
-                Debug.dump(graph, "Graph");
-                new InliningPhase(runtime(), null, assumptions, null, phasePlan, OptimisticOptimizations.ALL).apply(graph);
-                Debug.dump(graph, "Graph");
-                new CanonicalizerPhase(runtime(), assumptions).apply(graph);
-                new DeadCodeEliminationPhase().apply(graph);
-
-                assertNotInGraph(graph, Invoke.class);
-                return graph;
-            }
-        });
-    }
-
-    private static StructuredGraph assertNotInGraph(StructuredGraph graph, Class<?> clazz) {
-        for (Node node : graph.getNodes()) {
-            if (clazz.isInstance(node)) {
-                fail(node.toString());
-            }
-        }
-        return graph;
-    }
-
-    private static StructuredGraph assertInGraph(StructuredGraph graph, Class<?> clazz) {
-        for (Node node : graph.getNodes()) {
-            if (clazz.isInstance(node)) {
-                return graph;
-            }
-        }
-        fail("Graph does not contain a node of class " + clazz.getName());
-        return graph;
-    }
-
-    private static class TestClassA {
-    }
-}
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/InvokeTest.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2011, 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.snippets;
-
-import org.junit.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.test.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.phases.*;
-import com.oracle.graal.phases.common.*;
-
-/**
- * Tests the implementation of the snippets for lowering the INVOKE* instructions.
- */
-public class InvokeTest extends GraalCompilerTest {
-
-    @Override
-    protected void editPhasePlan(ResolvedJavaMethod method, StructuredGraph graph, PhasePlan phasePlan) {
-        phasePlan.disablePhase(InliningPhase.class);
-    }
-
-    public interface I {
-
-        String virtualMethod(String s);
-    }
-
-    public static class A implements I {
-
-        final String name = "A";
-
-        public String virtualMethod(String s) {
-            return name + s;
-        }
-    }
-
-    @SuppressWarnings("static-method")
-    private String privateMethod(String s) {
-        return s;
-    }
-
-    @Test
-    public void test1() {
-        test("invokestatic", "a string");
-        test("invokespecialConstructor", "a string");
-        test("invokespecial", this, "a string");
-        test("invokevirtual", new A(), "a string");
-        test("invokevirtual2", new A(), "a string");
-        test("invokeinterface", new A(), "a string");
-        Object[] args = {null};
-        test("invokestatic", args);
-        test("invokespecialConstructor", args);
-        test("invokespecial", null, null);
-        test("invokevirtual", null, null);
-        test("invokevirtual2", null, null);
-        test("invokeinterface", null, null);
-    }
-
-    public static String invokestatic(String s) {
-        return staticMethod(s);
-    }
-
-    public static String staticMethod(String s) {
-        return s;
-    }
-
-    public static String invokespecialConstructor(String s) {
-        return new A().virtualMethod(s);
-    }
-
-    public static String invokespecial(InvokeTest a, String s) {
-        return a.privateMethod(s);
-    }
-
-    public static String invokevirtual(A a, String s) {
-        return a.virtualMethod(s);
-    }
-
-    public static String invokevirtual2(A a, String s) {
-        a.virtualMethod(s);
-        return a.virtualMethod(s);
-    }
-
-    public static String invokeinterface(I i, String s) {
-        return i.virtualMethod(s);
-    }
-}
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/MonitorTest.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,217 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets;
-
-import org.junit.*;
-
-import com.oracle.graal.compiler.test.*;
-import com.oracle.graal.virtual.phases.ea.*;
-
-public class MonitorTest extends GraalCompilerTest {
-
-    @Test
-    public void test0() {
-        test("lockObjectSimple", new Object(), new Object());
-        test("lockObjectSimple", new Object(), null);
-    }
-
-    @Test
-    public void test0_1() {
-        test("lockThisSimple", "test1", new Object());
-        test("lockThisSimple", "test1", null);
-    }
-
-    @Test
-    public void test0_2() {
-        test("lockObjectSimple", null, "test1");
-    }
-
-    @Test
-    public void test1_1() {
-        test("lockObject", new Object(), "test1", new String[1]);
-    }
-
-    @Test
-    public void test1_2() {
-        test("lockObject", null, "test1_1", new String[1]);
-    }
-
-    @Test
-    public void test2() {
-        test("lockThis", "test2", new String[1]);
-    }
-
-    /**
-     * Tests monitor operations on {@link PartialEscapeAnalysisPhase virtual objects}.
-     */
-    @Test
-    public void test3() {
-        test("lockLocalObject", "test3", new String[1]);
-    }
-
-    /**
-     * Tests recursive locking of objects which should be biasable.
-     */
-    @Test
-    public void test4() {
-        Chars src = new Chars("1234567890".toCharArray());
-        Chars dst = new Chars(src.data.length);
-        test("copyObj", src, dst, 100);
-    }
-
-    /**
-     * Tests recursive locking of objects which do not appear to be biasable.
-     */
-    @Test
-    public void test5() {
-        char[] src = "1234567890".toCharArray();
-        char[] dst = new char[src.length];
-        test("copyArr", src, dst, 100);
-    }
-
-    /**
-     * Extends {@link #test4()} with contention.
-     */
-    @Test
-    public void test6() {
-        Chars src = new Chars("1234567890".toCharArray());
-        Chars dst = new Chars(src.data.length);
-        int n = Runtime.getRuntime().availableProcessors();
-        testN(n, "copyObj", src, dst, 100);
-    }
-
-    /**
-     * Extends {@link #test5()} with contention.
-     */
-    @Test
-    public void test7() {
-        char[] src = "1234567890".toCharArray();
-        char[] dst = new char[src.length];
-        int n = Runtime.getRuntime().availableProcessors();
-        testN(n, "copyArr", src, dst, 100);
-    }
-
-    private static String setAndGet(String[] box, String value) {
-        synchronized (box) {
-            box[0] = null;
-        }
-
-        // Do a GC while a object is locked (by the caller)
-        System.gc();
-
-        synchronized (box) {
-            box[0] = value;
-        }
-        return box[0];
-    }
-
-    public static Object lockObjectSimple(Object o, Object value) {
-        synchronized (o) {
-            value.hashCode();
-            return value;
-        }
-    }
-
-    public String lockThisSimple(String value, Object o) {
-        synchronized (this) {
-            synchronized (value) {
-                o.hashCode();
-                return value;
-            }
-        }
-    }
-
-    public static String lockObject(Object o, String value, String[] box) {
-        synchronized (o) {
-            return setAndGet(box, value);
-        }
-    }
-
-    public String lockThis(String value, String[] box) {
-        synchronized (this) {
-            return setAndGet(box, value);
-        }
-    }
-
-    public static String lockLocalObject(String value, String[] box) {
-        Object o = new Object();
-        synchronized (o) {
-            return setAndGet(box, value);
-        }
-    }
-
-    static class Chars {
-
-        final char[] data;
-
-        public Chars(int size) {
-            this.data = new char[size];
-        }
-
-        public Chars(char[] data) {
-            this.data = data;
-        }
-    }
-
-    public static String copyObj(Chars src, Chars dst, int n) {
-        System.out.println(Thread.currentThread().getName() + " reps=" + n + ", src.length=" + src.data.length);
-        int total = 0;
-        for (int j = 0; j < n; j++) {
-            for (int i = 0; i < src.data.length; i++) {
-                synchronized (src) {
-                    synchronized (dst) {
-                        synchronized (src) {
-                            synchronized (dst) {
-                                dst.data[i] = src.data[i];
-                                total++;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        System.out.println(Thread.currentThread().getName() + " total " + total);
-        return new String(dst.data);
-    }
-
-    public static String copyArr(char[] src, char[] dst, int n) {
-        System.out.println(Thread.currentThread().getName() + " reps=" + n + ", src.length=" + src.length);
-        int total = 0;
-        for (int j = 0; j < n; j++) {
-            for (int i = 0; i < src.length; i++) {
-                synchronized (src) {
-                    synchronized (dst) {
-                        synchronized (src) {
-                            synchronized (dst) {
-                                dst[i] = src[i];
-                                total++;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        System.out.println(Thread.currentThread().getName() + " total " + total);
-        return new String(dst);
-    }
-}
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/NewArrayTest.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,168 +0,0 @@
-/*
- * Copyright (c) 2011, 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.snippets;
-
-import org.junit.*;
-
-import com.oracle.graal.compiler.test.*;
-import com.oracle.graal.test.*;
-
-/**
- * Tests the implementation of {@code [A]NEWARRAY}.
- */
-public class NewArrayTest extends GraalCompilerTest {
-
-    @Override
-    protected void assertEquals(Object expected, Object actual) {
-        Assert.assertTrue(expected != null);
-        Assert.assertTrue(actual != null);
-        super.assertEquals(expected.getClass(), actual.getClass());
-        if (expected instanceof int[]) {
-            Assert.assertArrayEquals((int[]) expected, (int[]) actual);
-        } else if (expected instanceof byte[]) {
-            Assert.assertArrayEquals((byte[]) expected, (byte[]) actual);
-        } else if (expected instanceof char[]) {
-            Assert.assertArrayEquals((char[]) expected, (char[]) actual);
-        } else if (expected instanceof short[]) {
-            Assert.assertArrayEquals((short[]) expected, (short[]) actual);
-        } else if (expected instanceof float[]) {
-            Assert.assertArrayEquals((float[]) expected, (float[]) actual, 0.0f);
-        } else if (expected instanceof long[]) {
-            Assert.assertArrayEquals((long[]) expected, (long[]) actual);
-        } else if (expected instanceof double[]) {
-            Assert.assertArrayEquals((double[]) expected, (double[]) actual, 0.0d);
-        } else if (expected instanceof Object[]) {
-            Assert.assertArrayEquals((Object[]) expected, (Object[]) actual);
-        } else {
-            Assert.fail("non-array value encountered: " + expected);
-        }
-    }
-
-    @LongTest
-    public void test1() {
-        for (String type : new String[]{"Byte", "Char", "Short", "Int", "Float", "Long", "Double", "String"}) {
-            test("new" + type + "Array7");
-            test("new" + type + "ArrayMinus7");
-            test("new" + type + "Array", 7);
-            test("new" + type + "Array", -7);
-            test("new" + type + "Array", Integer.MAX_VALUE);
-            test("new" + type + "Array", Integer.MIN_VALUE);
-        }
-    }
-
-    public static Object newCharArray7() {
-        return new char[7];
-    }
-
-    public static Object newCharArrayMinus7() {
-        return new char[-7];
-    }
-
-    public static Object newCharArray(int length) {
-        return new char[length];
-    }
-
-    public static Object newShortArray7() {
-        return new short[7];
-    }
-
-    public static Object newShortArrayMinus7() {
-        return new short[-7];
-    }
-
-    public static Object newShortArray(int length) {
-        return new short[length];
-    }
-
-    public static Object newFloatArray7() {
-        return new float[7];
-    }
-
-    public static Object newFloatArrayMinus7() {
-        return new float[-7];
-    }
-
-    public static Object newFloatArray(int length) {
-        return new float[length];
-    }
-
-    public static Object newLongArray7() {
-        return new long[7];
-    }
-
-    public static Object newLongArrayMinus7() {
-        return new long[-7];
-    }
-
-    public static Object newLongArray(int length) {
-        return new long[length];
-    }
-
-    public static Object newDoubleArray7() {
-        return new double[7];
-    }
-
-    public static Object newDoubleArrayMinus7() {
-        return new double[-7];
-    }
-
-    public static Object newDoubleArray(int length) {
-        return new double[length];
-    }
-
-    public static Object newIntArray7() {
-        return new int[7];
-    }
-
-    public static Object newIntArrayMinus7() {
-        return new int[-7];
-    }
-
-    public static Object newIntArray(int length) {
-        return new int[length];
-    }
-
-    public static Object newByteArray7() {
-        return new byte[7];
-    }
-
-    public static Object newByteArrayMinus7() {
-        return new byte[-7];
-    }
-
-    public static Object newByteArray(int length) {
-        return new byte[length];
-    }
-
-    public static Object newStringArray7() {
-        return new String[7];
-    }
-
-    public static Object newStringArrayMinus7() {
-        return new String[-7];
-    }
-
-    public static Object newStringArray(int length) {
-        return new String[length];
-    }
-}
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/NewInstanceTest.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,249 +0,0 @@
-/*
- * Copyright (c) 2011, 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.snippets;
-
-import java.util.*;
-
-import org.junit.*;
-
-import com.oracle.graal.compiler.test.*;
-import com.oracle.graal.test.*;
-
-/**
- * Tests the implementation of {@code NEW}.
- */
-public class NewInstanceTest extends GraalCompilerTest {
-
-    @Override
-    protected void assertEquals(Object expected, Object actual) {
-        Assert.assertTrue(expected != null);
-        Assert.assertTrue(actual != null);
-        super.assertEquals(expected.getClass(), actual.getClass());
-
-        if (expected instanceof Object[]) {
-            Assert.assertTrue(actual instanceof Object[]);
-            Object[] eArr = (Object[]) expected;
-            Object[] aArr = (Object[]) actual;
-            Assert.assertTrue(eArr.length == aArr.length);
-            for (int i = 0; i < eArr.length; i++) {
-                assertEquals(eArr[i], aArr[i]);
-            }
-        } else if (expected.getClass() != Object.class) {
-            try {
-                expected.getClass().getDeclaredMethod("equals", Object.class);
-                super.assertEquals(expected, actual);
-            } catch (Exception e) {
-            }
-        }
-    }
-
-    @LongTest
-    public void test1() {
-        test("newObject");
-    }
-
-    @LongTest
-    public void test2() {
-        test("newObjectTwice");
-    }
-
-    public static Object newObject() {
-        return new Object();
-    }
-
-    @LongTest
-    public void test3() {
-        test("newObjectLoop", 100);
-    }
-
-    @LongTest
-    public void test4() {
-        test("newBigObject");
-    }
-
-    @LongTest
-    public void test5() {
-        test("newSomeObject");
-    }
-
-    @LongTest
-    public void test6() {
-        test("newEmptyString");
-    }
-
-    @LongTest
-    public void test7() {
-        test("newString", "value");
-    }
-
-    @LongTest
-    public void test8() {
-        test("newHashMap", 31);
-    }
-
-    @LongTest
-    public void test9() {
-        test("newRegression", true);
-    }
-
-    public static Object[] newObjectTwice() {
-        Object[] res = {new Object(), new Object()};
-        return res;
-    }
-
-    public static Object[] newObjectLoop(int n) {
-        Object[] res = new Object[n];
-        for (int i = 0; i < n; i++) {
-            res[i] = new Object();
-        }
-        return res;
-    }
-
-    public static BigObject newBigObject() {
-        return new BigObject();
-    }
-
-    public static SomeObject newSomeObject() {
-        return new SomeObject();
-    }
-
-    public static String newEmptyString() {
-        return new String();
-    }
-
-    public static String newString(String value) {
-        return new String(value);
-    }
-
-    public static HashMap newHashMap(int initialCapacity) {
-        return new HashMap(initialCapacity);
-    }
-
-    static class SomeObject {
-
-        String name = "o1";
-        HashMap<String, Object> map = new HashMap<>();
-
-        public SomeObject() {
-            map.put(name, this.getClass());
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj instanceof SomeObject) {
-                SomeObject so = (SomeObject) obj;
-                return so.name.equals(name) && so.map.equals(map);
-            }
-            return false;
-        }
-
-        @Override
-        public int hashCode() {
-            return name.hashCode();
-        }
-    }
-
-    static class BigObject {
-
-        Object f01;
-        Object f02;
-        Object f03;
-        Object f04;
-        Object f05;
-        Object f06;
-        Object f07;
-        Object f08;
-        Object f09;
-        Object f10;
-        Object f12;
-        Object f13;
-        Object f14;
-        Object f15;
-        Object f16;
-        Object f17;
-        Object f18;
-        Object f19;
-        Object f20;
-        Object f21;
-        Object f22;
-        Object f23;
-        Object f24;
-        Object f25;
-        Object f26;
-        Object f27;
-        Object f28;
-        Object f29;
-        Object f30;
-        Object f31;
-        Object f32;
-        Object f33;
-        Object f34;
-        Object f35;
-        Object f36;
-        Object f37;
-        Object f38;
-        Object f39;
-        Object f40;
-        Object f41;
-        Object f42;
-        Object f43;
-        Object f44;
-        Object f45;
-    }
-
-    /**
-     * Tests that an earlier bug does not occur. The issue was that the loading of the TLAB 'top'
-     * and 'end' values was being GVN'ed from each branch of the 'if' statement. This meant that the
-     * allocated B object in the true branch overwrote the allocated array. The cause is that
-     * RegisterNode was a floating node and the reads from it were UnsafeLoads which are also
-     * floating. The fix was to make RegisterNode a fixed node (which it should have been in the
-     * first place).
-     */
-    public static Object newRegression(boolean condition) {
-        Object result;
-        if (condition) {
-            Object[] arr = {0, 1, 2, 3, 4, 5};
-            result = new B();
-            for (int i = 0; i < arr.length; ++i) {
-                // If the bug exists, the values of arr will now be deadbeef values
-                // and the virtual dispatch will cause a segfault. This can result in
-                // either a VM crash or a spurious NullPointerException.
-                if (arr[i].equals(Integer.valueOf(i))) {
-                    return false;
-                }
-            }
-        } else {
-            result = new B();
-        }
-        return result;
-    }
-
-    static class B {
-
-        long f1 = 0xdeadbeefdeadbe01L;
-        long f2 = 0xdeadbeefdeadbe02L;
-        long f3 = 0xdeadbeefdeadbe03L;
-        long f4 = 0xdeadbeefdeadbe04L;
-        long f5 = 0xdeadbeefdeadbe05L;
-    }
-}
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/NewMultiArrayTest.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.test.*;
-import com.oracle.graal.test.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.java.*;
-
-/**
- * Tests the lowering of the MULTIANEWARRAY instruction.
- */
-public class NewMultiArrayTest extends GraalCompilerTest {
-
-    private static int rank(ResolvedJavaType type) {
-        String name = type.getName();
-        int dims = 0;
-        while (dims < name.length() && name.charAt(dims) == '[') {
-            dims++;
-        }
-        return dims;
-    }
-
-    @Override
-    protected InstalledCode getCode(final ResolvedJavaMethod method, final StructuredGraph graph) {
-        boolean forceCompile = false;
-        if (bottomType != null) {
-            List<NewMultiArrayNode> snapshot = graph.getNodes().filter(NewMultiArrayNode.class).snapshot();
-            assert snapshot != null;
-            assert snapshot.size() == 1;
-
-            NewMultiArrayNode node = snapshot.get(0);
-            assert rank(arrayType) == dimensions.length;
-            int rank = dimensions.length;
-            ValueNode[] dimensionNodes = new ValueNode[rank];
-            for (int i = 0; i < rank; i++) {
-                dimensionNodes[i] = graph.unique(ConstantNode.forInt(dimensions[i], graph));
-            }
-
-            NewMultiArrayNode repl = graph.add(new NewMultiArrayNode(arrayType, dimensionNodes));
-            graph.replaceFixedWithFixed(node, repl);
-            forceCompile = true;
-        }
-        return super.getCode(method, graph, forceCompile);
-    }
-
-    @Override
-    protected Object referenceInvoke(Method method, Object receiver, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
-        if (bottomType != null) {
-            try {
-                return Array.newInstance(bottomClass, dimensions);
-            } catch (Exception e) {
-                throw new InvocationTargetException(e);
-            }
-        }
-        return super.referenceInvoke(method, receiver, args);
-    }
-
-    ResolvedJavaType arrayType;
-    ResolvedJavaType bottomType;
-    Class bottomClass;
-    int[] dimensions;
-
-    @LongTest
-    public void test1() {
-        for (Class clazz : new Class[]{byte.class, char.class, short.class, int.class, float.class, long.class, double.class, String.class}) {
-            bottomClass = clazz;
-            bottomType = runtime.lookupJavaType(clazz);
-            arrayType = bottomType;
-            for (int rank : new int[]{1, 2, 10, 50, 100, 200, 254, 255}) {
-                while (rank(arrayType) != rank) {
-                    arrayType = arrayType.getArrayClass();
-                }
-
-                dimensions = new int[rank];
-                for (int i = 0; i < rank; i++) {
-                    dimensions[i] = 1;
-                }
-
-                test("newMultiArray");
-            }
-        }
-        bottomType = null;
-        arrayType = null;
-    }
-
-    public static Object newMultiArray() {
-        // This is merely a template - the NewMultiArrayNode is replaced in getCode() above.
-        // This also means we need a separate test for correct handling of negative dimensions
-        // as deoptimization won't do what we want for a graph modified to be different from the
-        // source bytecode.
-        return new Object[10][9][8];
-    }
-
-    @LongTest
-    public void test2() {
-        test("newMultiArrayException");
-    }
-
-    public static Object newMultiArrayException() {
-        return new Object[10][9][-8];
-    }
-}
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/PointerTest.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,399 +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.snippets;
-
-import java.lang.reflect.*;
-
-import org.junit.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.compiler.test.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.snippets.Snippet.SnippetInliningPolicy;
-import com.oracle.graal.word.*;
-
-/**
- * Tests for the {@link Pointer} read and write operations.
- */
-public class PointerTest extends GraalCompilerTest implements SnippetsInterface {
-
-    private static final Object ID = new Object();
-    private static final Kind[] KINDS = new Kind[]{Kind.Byte, Kind.Char, Kind.Short, Kind.Int, Kind.Long, Kind.Float, Kind.Double, Kind.Object};
-    private final TargetDescription target;
-    private final SnippetInstaller installer;
-
-    public PointerTest() {
-        target = Graal.getRequiredCapability(CodeCacheProvider.class).getTarget();
-        installer = new SnippetInstaller(runtime, new Assumptions(false), target);
-    }
-
-    private static final ThreadLocal<SnippetInliningPolicy> inliningPolicy = new ThreadLocal<>();
-
-    @Override
-    protected StructuredGraph parse(Method m) {
-        ResolvedJavaMethod resolvedMethod = runtime.lookupJavaMethod(m);
-        return installer.makeGraph(resolvedMethod, inliningPolicy.get());
-    }
-
-    @Test
-    public void test_read1() {
-        for (Kind kind : KINDS) {
-            assertRead(parse("read" + kind.name() + "1"), kind, false, ID);
-        }
-    }
-
-    @Test
-    public void test_read2() {
-        for (Kind kind : KINDS) {
-            assertRead(parse("read" + kind.name() + "2"), kind, true, ID);
-        }
-    }
-
-    @Test
-    public void test_read3() {
-        for (Kind kind : KINDS) {
-            assertRead(parse("read" + kind.name() + "3"), kind, false, LocationNode.UNKNOWN_LOCATION);
-        }
-    }
-
-    @Test
-    public void test_write1() {
-        for (Kind kind : KINDS) {
-            assertWrite(parse("write" + kind.name() + "1"), kind, false, ID);
-        }
-    }
-
-    @Test
-    public void test_write2() {
-        for (Kind kind : KINDS) {
-            assertWrite(parse("write" + kind.name() + "2"), kind, true, ID);
-        }
-    }
-
-    @Test
-    public void test_write3() {
-        for (Kind kind : KINDS) {
-            assertWrite(parse("write" + kind.name() + "3"), kind, false, LocationNode.ANY_LOCATION);
-        }
-    }
-
-    private void assertRead(StructuredGraph graph, Kind kind, boolean indexConvert, Object locationIdentity) {
-        ReadNode read = (ReadNode) graph.start().next();
-        Assert.assertEquals(kind.getStackKind(), read.kind());
-
-        UnsafeCastNode cast = (UnsafeCastNode) read.object();
-        Assert.assertEquals(graph.getLocal(0), cast.object());
-        Assert.assertEquals(target.wordKind, cast.kind());
-
-        IndexedLocationNode location = (IndexedLocationNode) read.location();
-        Assert.assertEquals(kind, location.getValueKind());
-        Assert.assertEquals(locationIdentity, location.locationIdentity());
-        Assert.assertEquals(1, location.indexScaling());
-
-        if (indexConvert) {
-            ConvertNode convert = (ConvertNode) location.index();
-            Assert.assertEquals(ConvertNode.Op.I2L, convert.opcode);
-            Assert.assertEquals(graph.getLocal(1), convert.value());
-        } else {
-            Assert.assertEquals(graph.getLocal(1), location.index());
-        }
-
-        ReturnNode ret = (ReturnNode) read.next();
-        Assert.assertEquals(read, ret.result());
-    }
-
-    private void assertWrite(StructuredGraph graph, Kind kind, boolean indexConvert, Object locationIdentity) {
-        WriteNode write = (WriteNode) graph.start().next();
-        Assert.assertEquals(graph.getLocal(2), write.value());
-        Assert.assertEquals(Kind.Void, write.kind());
-        Assert.assertEquals(FrameState.INVALID_FRAMESTATE_BCI, write.stateAfter().bci);
-
-        UnsafeCastNode cast = (UnsafeCastNode) write.object();
-        Assert.assertEquals(graph.getLocal(0), cast.object());
-        Assert.assertEquals(target.wordKind, cast.kind());
-
-        IndexedLocationNode location = (IndexedLocationNode) write.location();
-        Assert.assertEquals(kind, location.getValueKind());
-        Assert.assertEquals(locationIdentity, location.locationIdentity());
-        Assert.assertEquals(1, location.indexScaling());
-
-        if (indexConvert) {
-            ConvertNode convert = (ConvertNode) location.index();
-            Assert.assertEquals(ConvertNode.Op.I2L, convert.opcode);
-            Assert.assertEquals(graph.getLocal(1), convert.value());
-        } else {
-            Assert.assertEquals(graph.getLocal(1), location.index());
-        }
-
-        AbstractStateSplit stateSplit = (AbstractStateSplit) write.next();
-        Assert.assertEquals(FrameState.AFTER_BCI, stateSplit.stateAfter().bci);
-
-        ReturnNode ret = (ReturnNode) stateSplit.next();
-        Assert.assertEquals(null, ret.result());
-    }
-
-    @Snippet
-    public static byte readByte1(Object o, int offset) {
-        return Word.fromObject(o).readByte(offset, ID);
-    }
-
-    @Snippet
-    public static byte readByte2(Object o, int offset) {
-        return Word.fromObject(o).readByte(Word.signed(offset), ID);
-    }
-
-    @Snippet
-    public static byte readByte3(Object o, int offset) {
-        return Word.fromObject(o).readByte(offset);
-    }
-
-    @Snippet
-    public static void writeByte1(Object o, int offset, byte value) {
-        Word.fromObject(o).writeByte(offset, value, ID);
-    }
-
-    @Snippet
-    public static void writeByte2(Object o, int offset, byte value) {
-        Word.fromObject(o).writeByte(Word.signed(offset), value, ID);
-    }
-
-    @Snippet
-    public static void writeByte3(Object o, int offset, byte value) {
-        Word.fromObject(o).writeByte(offset, value);
-    }
-
-    @Snippet
-    public static char readChar1(Object o, int offset) {
-        return Word.fromObject(o).readChar(offset, ID);
-    }
-
-    @Snippet
-    public static char readChar2(Object o, int offset) {
-        return Word.fromObject(o).readChar(Word.signed(offset), ID);
-    }
-
-    @Snippet
-    public static char readChar3(Object o, int offset) {
-        return Word.fromObject(o).readChar(offset);
-    }
-
-    @Snippet
-    public static void writeChar1(Object o, int offset, char value) {
-        Word.fromObject(o).writeChar(offset, value, ID);
-    }
-
-    @Snippet
-    public static void writeChar2(Object o, int offset, char value) {
-        Word.fromObject(o).writeChar(Word.signed(offset), value, ID);
-    }
-
-    @Snippet
-    public static void writeChar3(Object o, int offset, char value) {
-        Word.fromObject(o).writeChar(offset, value);
-    }
-
-    @Snippet
-    public static short readShort1(Object o, int offset) {
-        return Word.fromObject(o).readShort(offset, ID);
-    }
-
-    @Snippet
-    public static short readShort2(Object o, int offset) {
-        return Word.fromObject(o).readShort(Word.signed(offset), ID);
-    }
-
-    @Snippet
-    public static short readShort3(Object o, int offset) {
-        return Word.fromObject(o).readShort(offset);
-    }
-
-    @Snippet
-    public static void writeShort1(Object o, int offset, short value) {
-        Word.fromObject(o).writeShort(offset, value, ID);
-    }
-
-    @Snippet
-    public static void writeShort2(Object o, int offset, short value) {
-        Word.fromObject(o).writeShort(Word.signed(offset), value, ID);
-    }
-
-    @Snippet
-    public static void writeShort3(Object o, int offset, short value) {
-        Word.fromObject(o).writeShort(offset, value);
-    }
-
-    @Snippet
-    public static int readInt1(Object o, int offset) {
-        return Word.fromObject(o).readInt(offset, ID);
-    }
-
-    @Snippet
-    public static int readInt2(Object o, int offset) {
-        return Word.fromObject(o).readInt(Word.signed(offset), ID);
-    }
-
-    @Snippet
-    public static int readInt3(Object o, int offset) {
-        return Word.fromObject(o).readInt(offset);
-    }
-
-    @Snippet
-    public static void writeInt1(Object o, int offset, int value) {
-        Word.fromObject(o).writeInt(offset, value, ID);
-    }
-
-    @Snippet
-    public static void writeInt2(Object o, int offset, int value) {
-        Word.fromObject(o).writeInt(Word.signed(offset), value, ID);
-    }
-
-    @Snippet
-    public static void writeInt3(Object o, int offset, int value) {
-        Word.fromObject(o).writeInt(offset, value);
-    }
-
-    @Snippet
-    public static long readLong1(Object o, int offset) {
-        return Word.fromObject(o).readLong(offset, ID);
-    }
-
-    @Snippet
-    public static long readLong2(Object o, int offset) {
-        return Word.fromObject(o).readLong(Word.signed(offset), ID);
-    }
-
-    @Snippet
-    public static long readLong3(Object o, int offset) {
-        return Word.fromObject(o).readLong(offset);
-    }
-
-    @Snippet
-    public static void writeLong1(Object o, int offset, long value) {
-        Word.fromObject(o).writeLong(offset, value, ID);
-    }
-
-    @Snippet
-    public static void writeLong2(Object o, int offset, long value) {
-        Word.fromObject(o).writeLong(Word.signed(offset), value, ID);
-    }
-
-    @Snippet
-    public static void writeLong3(Object o, int offset, long value) {
-        Word.fromObject(o).writeLong(offset, value);
-    }
-
-    @Snippet
-    public static float readFloat1(Object o, int offset) {
-        return Word.fromObject(o).readFloat(offset, ID);
-    }
-
-    @Snippet
-    public static float readFloat2(Object o, int offset) {
-        return Word.fromObject(o).readFloat(Word.signed(offset), ID);
-    }
-
-    @Snippet
-    public static float readFloat3(Object o, int offset) {
-        return Word.fromObject(o).readFloat(offset);
-    }
-
-    @Snippet
-    public static void writeFloat1(Object o, int offset, float value) {
-        Word.fromObject(o).writeFloat(offset, value, ID);
-    }
-
-    @Snippet
-    public static void writeFloat2(Object o, int offset, float value) {
-        Word.fromObject(o).writeFloat(Word.signed(offset), value, ID);
-    }
-
-    @Snippet
-    public static void writeFloat3(Object o, int offset, float value) {
-        Word.fromObject(o).writeFloat(offset, value);
-    }
-
-    @Snippet
-    public static double readDouble1(Object o, int offset) {
-        return Word.fromObject(o).readDouble(offset, ID);
-    }
-
-    @Snippet
-    public static double readDouble2(Object o, int offset) {
-        return Word.fromObject(o).readDouble(Word.signed(offset), ID);
-    }
-
-    @Snippet
-    public static double readDouble3(Object o, int offset) {
-        return Word.fromObject(o).readDouble(offset);
-    }
-
-    @Snippet
-    public static void writeDouble1(Object o, int offset, double value) {
-        Word.fromObject(o).writeDouble(offset, value, ID);
-    }
-
-    @Snippet
-    public static void writeDouble2(Object o, int offset, double value) {
-        Word.fromObject(o).writeDouble(Word.signed(offset), value, ID);
-    }
-
-    @Snippet
-    public static void writeDouble3(Object o, int offset, double value) {
-        Word.fromObject(o).writeDouble(offset, value);
-    }
-
-    @Snippet
-    public static Object readObject1(Object o, int offset) {
-        return Word.fromObject(o).readObject(offset, ID);
-    }
-
-    @Snippet
-    public static Object readObject2(Object o, int offset) {
-        return Word.fromObject(o).readObject(Word.signed(offset), ID);
-    }
-
-    @Snippet
-    public static Object readObject3(Object o, int offset) {
-        return Word.fromObject(o).readObject(offset);
-    }
-
-    @Snippet
-    public static void writeObject1(Object o, int offset, Object value) {
-        Word.fromObject(o).writeObject(offset, value, ID);
-    }
-
-    @Snippet
-    public static void writeObject2(Object o, int offset, Object value) {
-        Word.fromObject(o).writeObject(Word.signed(offset), value, ID);
-    }
-
-    @Snippet
-    public static void writeObject3(Object o, int offset, Object value) {
-        Word.fromObject(o).writeObject(offset, value);
-    }
-
-}
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/TypeCheckTest.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2011, 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.snippets;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType;
-import com.oracle.graal.compiler.test.*;
-import com.oracle.graal.nodes.*;
-
-/**
- * Base class for checkcast and instanceof test classes.
- */
-public abstract class TypeCheckTest extends GraalCompilerTest {
-
-    protected abstract void replaceProfile(StructuredGraph graph, JavaTypeProfile profile);
-
-    protected JavaTypeProfile currentProfile;
-
-    @Override
-    protected InstalledCode getCode(final ResolvedJavaMethod method, final StructuredGraph graph) {
-        boolean forceCompile = false;
-        if (currentProfile != null) {
-            replaceProfile(graph, currentProfile);
-            forceCompile = true;
-        }
-        return super.getCode(method, graph, forceCompile);
-    }
-
-    protected JavaTypeProfile profile(Class... types) {
-        if (types.length == 0) {
-            return null;
-        }
-        ProfiledType[] ptypes = new ProfiledType[types.length];
-        for (int i = 0; i < types.length; i++) {
-            ptypes[i] = new ProfiledType(runtime.lookupJavaType(types[i]), 1.0D / types.length);
-        }
-        return new JavaTypeProfile(0.0D, ptypes);
-    }
-
-    protected void test(String name, JavaTypeProfile profile, Object... args) {
-        assert currentProfile == null;
-        currentProfile = profile;
-        try {
-            super.test(name, args);
-        } finally {
-            currentProfile = null;
-        }
-    }
-}
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/WordTest.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,227 +0,0 @@
-/*
- * Copyright (c) 2011, 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.snippets;
-
-import java.lang.reflect.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.compiler.test.*;
-import com.oracle.graal.test.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.snippets.Snippet.SnippetInliningPolicy;
-import com.oracle.graal.word.*;
-
-/**
- * Tests for the {@link Word} type.
- */
-public class WordTest extends GraalCompilerTest implements SnippetsInterface {
-
-    private final SnippetInstaller installer;
-
-    public WordTest() {
-        TargetDescription target = Graal.getRequiredCapability(CodeCacheProvider.class).getTarget();
-        installer = new SnippetInstaller(runtime, new Assumptions(false), target);
-    }
-
-    private static final ThreadLocal<SnippetInliningPolicy> inliningPolicy = new ThreadLocal<>();
-
-    @Override
-    protected StructuredGraph parse(Method m) {
-        ResolvedJavaMethod resolvedMethod = runtime.lookupJavaMethod(m);
-        return installer.makeGraph(resolvedMethod, inliningPolicy.get());
-    }
-
-    @LongTest
-    public void construction() {
-        long[] words = new long[]{Long.MIN_VALUE, Long.MIN_VALUE + 1, -1L, 0L, 1L, Long.MAX_VALUE - 1, Long.MAX_VALUE, Integer.MAX_VALUE - 1L, Integer.MAX_VALUE, Integer.MAX_VALUE + 1L,
-                        Integer.MIN_VALUE - 1L, Integer.MIN_VALUE, Integer.MIN_VALUE + 1L};
-        for (long word : words) {
-            test("unsigned_long", word);
-            test("unsigned_int", (int) word);
-            test("signed_long", word);
-            test("signed_int", (int) word);
-        }
-    }
-
-    @LongTest
-    public void test_arithmetic() {
-        long[] words = new long[]{Long.MIN_VALUE, Long.MIN_VALUE + 1, -1L, 0L, 1L, Long.MAX_VALUE - 1, Long.MAX_VALUE, Integer.MAX_VALUE - 1L, Integer.MAX_VALUE, Integer.MAX_VALUE + 1L,
-                        Integer.MIN_VALUE - 1L, Integer.MIN_VALUE, Integer.MIN_VALUE + 1L};
-        for (long word : words) {
-            test("unsigned_not", word);
-            test("signed_not", word);
-            for (long addend : words) {
-                test("unsigned_plus_int", word, (int) addend);
-                test("unsigned_minus_int", word, (int) addend);
-                test("unsigned_plus_int", word, -((int) addend));
-                test("unsigned_minus_int", word, -((int) addend));
-                test("unsigned_plus_long", word, addend);
-                test("unsigned_minus_long", word, addend);
-                test("unsigned_plus_long", word, -addend);
-                test("unsigned_minus_long", word, -addend);
-                test("signed_plus_int", word, (int) addend);
-                test("signed_minus_int", word, (int) addend);
-                test("signed_plus_int", word, -((int) addend));
-                test("signed_minus_int", word, -((int) addend));
-                test("signed_plus_long", word, addend);
-                test("signed_minus_long", word, addend);
-                test("signed_plus_long", word, -addend);
-                test("signed_minus_long", word, -addend);
-
-                test("and_int", word, (int) addend);
-                test("or_int", word, (int) addend);
-                test("and_int", word, -((int) addend));
-                test("or_int", word, -((int) addend));
-                test("and_long", word, addend);
-                test("or_long", word, addend);
-                test("and_long", word, -addend);
-                test("or_long", word, -addend);
-            }
-        }
-    }
-
-    @LongTest
-    public void test_compare() {
-        long[] words = new long[]{Long.MIN_VALUE, Long.MIN_VALUE + 1, -1L, 0L, 1L, Long.MAX_VALUE - 1, Long.MAX_VALUE};
-        for (long word1 : words) {
-            for (long word2 : words) {
-                for (String method : new String[]{"aboveOrEqual", "above", "belowOrEqual", "below"}) {
-                    test(method, word1, word2);
-                    test(method, word2, word1);
-                }
-            }
-        }
-    }
-
-    @Snippet
-    public static long unsigned_long(long word) {
-        return Word.unsigned(word).rawValue();
-    }
-
-    @Snippet
-    public static long unsigned_int(int word) {
-        return Word.unsigned(word).rawValue();
-    }
-
-    @Snippet
-    public static long signed_long(long word) {
-        return Word.signed(word).rawValue();
-    }
-
-    @Snippet
-    public static long signed_int(int word) {
-        return Word.signed(word).rawValue();
-    }
-
-    @Snippet
-    public static long unsigned_plus_int(long word, int addend) {
-        return Word.unsigned(word).add(addend).rawValue();
-    }
-
-    @Snippet
-    public static long unsigned_minus_int(long word, int addend) {
-        return Word.unsigned(word).subtract(addend).rawValue();
-    }
-
-    @Snippet
-    public static long unsigned_plus_long(long word, long addend) {
-        return Word.unsigned(word).add(Word.unsigned(addend)).rawValue();
-    }
-
-    @Snippet
-    public static long unsigned_minus_long(long word, long addend) {
-        return Word.unsigned(word).subtract(Word.unsigned(addend)).rawValue();
-    }
-
-    @Snippet
-    public static long signed_plus_int(long word, int addend) {
-        return Word.signed(word).add(addend).rawValue();
-    }
-
-    @Snippet
-    public static long signed_minus_int(long word, int addend) {
-        return Word.signed(word).subtract(addend).rawValue();
-    }
-
-    @Snippet
-    public static long signed_plus_long(long word, long addend) {
-        return Word.signed(word).add(Word.signed(addend)).rawValue();
-    }
-
-    @Snippet
-    public static long signed_minus_long(long word, long addend) {
-        return Word.signed(word).subtract(Word.signed(addend)).rawValue();
-    }
-
-    @Snippet
-    public static long signed_not(long word) {
-        return Word.signed(word).not().rawValue();
-    }
-
-    @Snippet
-    public static long unsigned_not(long word) {
-        return Word.unsigned(word).not().rawValue();
-    }
-
-    @Snippet
-    public static boolean aboveOrEqual(long word1, long word2) {
-        return Word.unsigned(word1).aboveOrEqual(Word.unsigned(word2));
-    }
-
-    @Snippet
-    public static boolean above(long word1, long word2) {
-        return Word.unsigned(word1).aboveThan(Word.unsigned(word2));
-    }
-
-    @Snippet
-    public static boolean belowOrEqual(long word1, long word2) {
-        return Word.unsigned(word1).belowOrEqual(Word.unsigned(word2));
-    }
-
-    @Snippet
-    public static boolean below(long word1, long word2) {
-        return Word.unsigned(word1).belowThan(Word.unsigned(word2));
-    }
-
-    @Snippet
-    public static long and_int(long word, int addend) {
-        return Word.unsigned(word).and(addend).rawValue();
-    }
-
-    @Snippet
-    public static long or_int(long word, int addend) {
-        return Word.unsigned(word).or(addend).rawValue();
-    }
-
-    @Snippet
-    public static long and_long(long word, long addend) {
-        return Word.unsigned(word).and(Word.unsigned(addend)).rawValue();
-    }
-
-    @Snippet
-    public static long or_long(long word, long addend) {
-        return Word.unsigned(word).or(Word.unsigned(addend)).rawValue();
-    }
-}
--- a/graal/com.oracle.graal.snippets/overview.html	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
-<head>
-<!--
-
-Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
-DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-
-This code is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License version 2 only, as
-published by the Free Software Foundation.  Oracle designates this
-particular file as subject to the "Classpath" exception as provided
-by Oracle in the LICENSE file that accompanied this code.
-
-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.
--->
-
-</head>
-<body>
-
-Documentation for the <code>com.oracle.graal.snippets</code> project.
-
-</body>
-</html>
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/ClassSubstitution.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,130 +0,0 @@
-/*
- * Copyright (c) 2011, 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.snippets;
-
-import java.lang.annotation.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.snippets.nodes.*;
-
-/**
- * Denotes a class that substitutes methods of another specified class. The substitute methods are
- * exactly those annotated by {@link MethodSubstitution}.
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-public @interface ClassSubstitution {
-
-    /**
-     * Specifies the original class.
-     * <p>
-     * If the default value is specified for this element, then a non-default value must be given
-     * for the {@link #className()} element.
-     */
-    Class<?> value() default ClassSubstitution.class;
-
-    /**
-     * Specifies the original class.
-     * <p>
-     * This method is provided for cases where the original class is not accessible (according to
-     * Java language access control rules).
-     * <p>
-     * If the default value is specified for this element, then a non-default value must be given
-     * for the {@link #value()} element.
-     */
-    String className() default "";
-
-    /**
-     * Denotes a substitute method. A substitute method can call the original/substituted method by
-     * making a recursive call to itself.
-     */
-    @Retention(RetentionPolicy.RUNTIME)
-    @Target(ElementType.METHOD)
-    public @interface MethodSubstitution {
-
-        /**
-         * Gets the name of the original method.
-         * <p>
-         * If the default value is specified for this element, then the name of the original method
-         * is same as the substitute method.
-         */
-        String value() default "";
-
-        /**
-         * Determines if the original method is static.
-         */
-        boolean isStatic() default true;
-
-        /**
-         * Gets the {@linkplain MetaUtil#signatureToMethodDescriptor signature} of the original
-         * method.
-         * <p>
-         * If the default value is specified for this element, then the signature of the original
-         * method is the same as the substitute method.
-         */
-        String signature() default "";
-    }
-
-    /**
-     * Denotes a macro substitute method. This replaces a method invocation with an instance of the
-     * specified node class.
-     * 
-     * A macro substitution can be combined with a normal substitution, so that the macro node can
-     * be replaced with the actual substitution code during lowering.
-     */
-    @Retention(RetentionPolicy.RUNTIME)
-    @Target(ElementType.METHOD)
-    public @interface MacroSubstitution {
-
-        /**
-         * Gets the name of the substituted method.
-         * <p>
-         * If the default value is specified for this element, then the name of the substituted
-         * method is same as the substitute method.
-         */
-        String value() default "";
-
-        /**
-         * Determines if the substituted method is static.
-         */
-        boolean isStatic() default true;
-
-        /**
-         * Gets the {@linkplain MetaUtil#signatureToMethodDescriptor signature} of the substituted
-         * method.
-         * <p>
-         * If the default value is specified for this element, then the signature of the substituted
-         * method is the same as the substitute method.
-         */
-        String signature() default "";
-
-        /**
-         * The node class with which the method invocation should be replaced. It needs to be a
-         * subclass of {@link FixedWithNextNode}, and it is expected to provide a public constructor
-         * that takes an InvokeNode as a parameter. For most cases this class should subclass
-         * {@link MacroNode} and use its constructor.
-         */
-        Class<? extends FixedWithNextNode> macro();
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/DoubleSubstitutions.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2011, 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.snippets;
-
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.snippets.ClassSubstitution.*;
-
-/**
- * Substitutions for {@link java.lang.Double} methods.
- */
-@ClassSubstitution(java.lang.Double.class)
-public class DoubleSubstitutions {
-
-    private static final long NAN_RAW_LONG_BITS = Double.doubleToRawLongBits(Double.NaN);
-
-    @MethodSubstitution
-    public static long doubleToRawLongBits(double value) {
-        @JavacBug(id = 6995200)
-        Long result = ConvertNode.convert(ConvertNode.Op.MOV_D2L, value);
-        return result;
-    }
-
-    // TODO This method is not necessary, since the JDK method does exactly this
-    @MethodSubstitution
-    public static long doubleToLongBits(double value) {
-        if (value != value) {
-            return NAN_RAW_LONG_BITS;
-        } else {
-            return doubleToRawLongBits(value);
-        }
-    }
-
-    @MethodSubstitution
-    public static double longBitsToDouble(long bits) {
-        @JavacBug(id = 6995200)
-        Double result = ConvertNode.convert(ConvertNode.Op.MOV_L2D, bits);
-        return result;
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/FloatSubstitutions.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2011, 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.snippets;
-
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.snippets.ClassSubstitution.*;
-
-/**
- * Substitutions for {@link java.lang.Float} methods.
- */
-@ClassSubstitution(java.lang.Float.class)
-public class FloatSubstitutions {
-
-    private static final int NAN_RAW_INT_BITS = Float.floatToRawIntBits(Float.NaN);
-
-    @MethodSubstitution
-    public static int floatToRawIntBits(float value) {
-        @JavacBug(id = 6995200)
-        Integer result = ConvertNode.convert(ConvertNode.Op.MOV_F2I, value);
-        return result;
-    }
-
-    // TODO This method is not necessary, since the JDK method does exactly this
-    @MethodSubstitution
-    public static int floatToIntBits(float value) {
-        if (value != value) {
-            return NAN_RAW_INT_BITS;
-        } else {
-            return floatToRawIntBits(value);
-        }
-    }
-
-    @MethodSubstitution
-    public static float intBitsToFloat(int bits) {
-        @JavacBug(id = 6995200)
-        Float result = ConvertNode.convert(ConvertNode.Op.MOV_I2F, bits);
-        return result;
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/GraalIntrinsics.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2011, 2011, 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.snippets;
-
-import com.oracle.graal.phases.*;
-
-/**
- * Definition of the snippets that are VM-independent and can be intrinsified by Graal in any VM.
- */
-public class GraalIntrinsics {
-
-    public static void installIntrinsics(SnippetInstaller installer) {
-        if (GraalOptions.Intrinsify) {
-            installer.installSubstitutions(MathSubstitutionsX86.class);
-            installer.installSubstitutions(DoubleSubstitutions.class);
-            installer.installSubstitutions(FloatSubstitutions.class);
-            installer.installSubstitutions(NodeClassSubstitutions.class);
-            installer.installSubstitutions(LongSubstitutions.class);
-            installer.installSubstitutions(IntegerSubstitutions.class);
-            installer.installSubstitutions(UnsignedMathSubstitutions.class);
-        }
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/InstanceOfSnippetsTemplates.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,341 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets;
-
-import static com.oracle.graal.nodes.calc.CompareNode.*;
-
-import java.util.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-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.util.*;
-import com.oracle.graal.snippets.SnippetTemplate.AbstractTemplates;
-import com.oracle.graal.snippets.SnippetTemplate.Arguments;
-import com.oracle.graal.snippets.SnippetTemplate.Key;
-import com.oracle.graal.snippets.SnippetTemplate.UsageReplacer;
-
-/**
- * Helper class for lowering {@link InstanceOfNode}s with snippets. The majority of the complexity
- * in such a lowering derives from the fact that {@link InstanceOfNode} is a floating node. A
- * snippet used to lower an {@link InstanceOfNode} will almost always incorporate control flow and
- * replacing a floating node with control flow is not trivial.
- * <p>
- * The mechanism implemented in this class ensures that the graph for an instanceof snippet is
- * instantiated once per {@link InstanceOfNode} being lowered. The result produced the graph is then
- * re-used by all usages of the node. Additionally, if there is a single usage that is an
- * {@link IfNode}, the control flow in the snippet is connected directly to the true and false
- * successors of the {@link IfNode}. This avoids materializating the instanceof test as a boolean
- * which is then retested by the {@link IfNode}.
- */
-public abstract class InstanceOfSnippetsTemplates<T extends SnippetsInterface> extends AbstractTemplates<T> {
-
-    public InstanceOfSnippetsTemplates(MetaAccessProvider runtime, Assumptions assumptions, TargetDescription target, Class<T> snippetsClass) {
-        super(runtime, assumptions, target, snippetsClass);
-    }
-
-    /**
-     * The key and arguments used to retrieve and instantiate an instanceof snippet template.
-     */
-    public static class KeyAndArguments {
-
-        public final Key key;
-        public final Arguments arguments;
-
-        public KeyAndArguments(Key key, Arguments arguments) {
-            this.key = key;
-            this.arguments = arguments;
-        }
-
-    }
-
-    /**
-     * Gets the key and arguments used to retrieve and instantiate an instanceof snippet template.
-     */
-    protected abstract KeyAndArguments getKeyAndArguments(InstanceOfUsageReplacer replacer, LoweringTool tool);
-
-    public void lower(FloatingNode instanceOf, LoweringTool tool) {
-        assert instanceOf instanceof InstanceOfNode || instanceOf instanceof InstanceOfDynamicNode;
-        List<Node> usages = instanceOf.usages().snapshot();
-        int nUsages = usages.size();
-
-        Instantiation instantiation = new Instantiation();
-        for (Node usage : usages) {
-            final StructuredGraph graph = (StructuredGraph) usage.graph();
-
-            InstanceOfUsageReplacer replacer = createReplacer(instanceOf, tool, nUsages, instantiation, usage, graph);
-
-            if (instantiation.isInitialized()) {
-                // No need to re-instantiate the snippet - just re-use its result
-                replacer.replaceUsingInstantiation();
-            } else {
-                KeyAndArguments keyAndArguments = getKeyAndArguments(replacer, tool);
-                SnippetTemplate template = cache.get(keyAndArguments.key, assumptions);
-                template.instantiate(runtime, instanceOf, replacer, tool, keyAndArguments.arguments);
-            }
-        }
-
-        assert instanceOf.usages().isEmpty();
-        if (!instanceOf.isDeleted()) {
-            GraphUtil.killWithUnusedFloatingInputs(instanceOf);
-        }
-    }
-
-    /**
-     * Gets the specific replacer object used to replace the usage of an instanceof node with the
-     * result of an instantiated instanceof snippet.
-     */
-    protected InstanceOfUsageReplacer createReplacer(FloatingNode instanceOf, LoweringTool tool, int nUsages, Instantiation instantiation, Node usage, final StructuredGraph graph) {
-        InstanceOfUsageReplacer replacer;
-        if (usage instanceof IfNode) {
-            replacer = new IfUsageReplacer(instantiation, ConstantNode.forInt(1, graph), ConstantNode.forInt(0, graph), instanceOf, (IfNode) usage, nUsages == 1, tool);
-        } else {
-            assert usage instanceof ConditionalNode : "unexpected usage of " + instanceOf + ": " + usage;
-            ConditionalNode c = (ConditionalNode) usage;
-            replacer = new ConditionalUsageReplacer(instantiation, c.trueValue(), c.falseValue(), instanceOf, c);
-        }
-        return replacer;
-    }
-
-    /**
-     * The result of an instantiating an instanceof snippet. This enables a snippet instantiation to
-     * be re-used which reduces compile time and produces better code.
-     */
-    public static final class Instantiation {
-
-        private PhiNode result;
-        private CompareNode condition;
-        private ValueNode trueValue;
-        private ValueNode falseValue;
-
-        /**
-         * Determines if the instantiation has occurred.
-         */
-        boolean isInitialized() {
-            return result != null;
-        }
-
-        void initialize(PhiNode phi, ValueNode t, ValueNode f) {
-            assert !isInitialized();
-            this.result = phi;
-            this.trueValue = t;
-            this.falseValue = f;
-        }
-
-        /**
-         * Gets the result of this instantiation as a condition.
-         * 
-         * @param testValue the returned condition is true if the result is equal to this value
-         */
-        CompareNode asCondition(ValueNode testValue) {
-            assert isInitialized();
-            if (condition == null || condition.y() != testValue) {
-                // Re-use previously generated condition if the trueValue for the test is the same
-                condition = createCompareNode(Condition.EQ, result, testValue);
-            }
-            return condition;
-        }
-
-        /**
-         * Gets the result of the instantiation as a materialized value.
-         * 
-         * @param t the true value for the materialization
-         * @param f the false value for the materialization
-         */
-        ValueNode asMaterialization(ValueNode t, ValueNode f) {
-            assert isInitialized();
-            if (t == this.trueValue && f == this.falseValue) {
-                // Can simply use the phi result if the same materialized values are expected.
-                return result;
-            } else {
-                return t.graph().unique(new ConditionalNode(asCondition(trueValue), t, f));
-            }
-        }
-    }
-
-    /**
-     * Replaces a usage of an {@link InstanceOfNode} or {@link InstanceOfDynamicNode}.
-     */
-    public abstract static class InstanceOfUsageReplacer implements UsageReplacer {
-
-        public final Instantiation instantiation;
-        public final FloatingNode instanceOf;
-        public final ValueNode trueValue;
-        public final ValueNode falseValue;
-
-        public InstanceOfUsageReplacer(Instantiation instantiation, FloatingNode instanceOf, ValueNode trueValue, ValueNode falseValue) {
-            assert instanceOf instanceof InstanceOfNode || instanceOf instanceof InstanceOfDynamicNode;
-            this.instantiation = instantiation;
-            this.instanceOf = instanceOf;
-            this.trueValue = trueValue;
-            this.falseValue = falseValue;
-        }
-
-        /**
-         * Does the replacement based on a previously snippet instantiation.
-         */
-        public abstract void replaceUsingInstantiation();
-    }
-
-    /**
-     * Replaces an {@link IfNode} usage of an {@link InstanceOfNode} or
-     * {@link InstanceOfDynamicNode}.
-     */
-    public static class IfUsageReplacer extends InstanceOfUsageReplacer {
-
-        private final boolean solitaryUsage;
-        private final IfNode usage;
-        private final boolean sameBlock;
-
-        public IfUsageReplacer(Instantiation instantiation, ValueNode trueValue, ValueNode falseValue, FloatingNode instanceOf, IfNode usage, boolean solitaryUsage, LoweringTool tool) {
-            super(instantiation, instanceOf, trueValue, falseValue);
-            this.sameBlock = tool.getBlockFor(usage) == tool.getBlockFor(instanceOf);
-            this.solitaryUsage = solitaryUsage;
-            this.usage = usage;
-        }
-
-        @Override
-        public void replaceUsingInstantiation() {
-            usage.replaceFirstInput(instanceOf, instantiation.asCondition(trueValue));
-        }
-
-        private boolean usageFollowsInstantiation() {
-            return instantiation.result != null && instantiation.result.merge().next() == usage;
-        }
-
-        @Override
-        public void replace(ValueNode oldNode, ValueNode newNode) {
-            assert newNode instanceof PhiNode;
-            assert oldNode == instanceOf;
-            if (sameBlock && solitaryUsage && usageFollowsInstantiation()) {
-                removeIntermediateMaterialization(newNode);
-            } else {
-                newNode.inferStamp();
-                instantiation.initialize((PhiNode) newNode, trueValue, falseValue);
-                usage.replaceFirstInput(oldNode, instantiation.asCondition(trueValue));
-            }
-        }
-
-        /**
-         * Directly wires the incoming edges of the merge at the end of the snippet to the outgoing
-         * edges of the IfNode that uses the materialized result.
-         */
-        private void removeIntermediateMaterialization(ValueNode newNode) {
-            IfNode ifNode = usage;
-            PhiNode phi = (PhiNode) newNode;
-            MergeNode merge = phi.merge();
-            assert merge.stateAfter() == null;
-
-            List<EndNode> mergePredecessors = merge.cfgPredecessors().snapshot();
-            assert phi.valueCount() == mergePredecessors.size();
-
-            List<EndNode> falseEnds = new ArrayList<>(mergePredecessors.size());
-            List<EndNode> trueEnds = new ArrayList<>(mergePredecessors.size());
-
-            int endIndex = 0;
-            for (EndNode end : mergePredecessors) {
-                ValueNode endValue = phi.valueAt(endIndex++);
-                if (endValue == trueValue) {
-                    trueEnds.add(end);
-                } else {
-                    assert endValue == falseValue;
-                    falseEnds.add(end);
-                }
-            }
-
-            BeginNode trueSuccessor = ifNode.trueSuccessor();
-            BeginNode falseSuccessor = ifNode.falseSuccessor();
-            ifNode.setTrueSuccessor(null);
-            ifNode.setFalseSuccessor(null);
-
-            connectEnds(merge, trueEnds, trueSuccessor);
-            connectEnds(merge, falseEnds, falseSuccessor);
-
-            GraphUtil.killCFG(merge);
-            GraphUtil.killCFG(ifNode);
-
-            assert !merge.isAlive() : merge;
-            assert !phi.isAlive() : phi;
-        }
-
-        private static void connectEnds(MergeNode merge, List<EndNode> ends, BeginNode successor) {
-            if (ends.size() == 0) {
-                // InstanceOf has been lowered to always true or always false - this successor is
-                // therefore unreachable.
-                GraphUtil.killCFG(successor);
-            } else if (ends.size() == 1) {
-                EndNode end = ends.get(0);
-                ((FixedWithNextNode) end.predecessor()).setNext(successor);
-                merge.removeEnd(end);
-                GraphUtil.killCFG(end);
-            } else {
-                assert ends.size() > 1;
-                MergeNode newMerge = merge.graph().add(new MergeNode());
-
-                for (EndNode end : ends) {
-                    newMerge.addForwardEnd(end);
-                }
-                newMerge.setNext(successor);
-            }
-        }
-    }
-
-    /**
-     * Replaces a {@link ConditionalNode} usage of an {@link InstanceOfNode} or
-     * {@link InstanceOfDynamicNode}.
-     */
-    public static class ConditionalUsageReplacer extends InstanceOfUsageReplacer {
-
-        public final ConditionalNode usage;
-
-        public ConditionalUsageReplacer(Instantiation instantiation, ValueNode trueValue, ValueNode falseValue, FloatingNode instanceOf, ConditionalNode usage) {
-            super(instantiation, instanceOf, trueValue, falseValue);
-            this.usage = usage;
-        }
-
-        @Override
-        public void replaceUsingInstantiation() {
-            ValueNode newValue = instantiation.asMaterialization(trueValue, falseValue);
-            usage.replaceAtUsages(newValue);
-            usage.clearInputs();
-            assert usage.usages().isEmpty();
-            GraphUtil.killWithUnusedFloatingInputs(usage);
-        }
-
-        @Override
-        public void replace(ValueNode oldNode, ValueNode newNode) {
-            assert newNode instanceof PhiNode;
-            assert oldNode == instanceOf;
-            newNode.inferStamp();
-            instantiation.initialize((PhiNode) newNode, trueValue, falseValue);
-            usage.replaceAtUsages(newNode);
-            usage.clearInputs();
-            assert usage.usages().isEmpty();
-            GraphUtil.killWithUnusedFloatingInputs(usage);
-        }
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/IntegerSubstitutions.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets;
-
-import com.oracle.graal.snippets.ClassSubstitution.*;
-import com.oracle.graal.snippets.nodes.*;
-
-@ClassSubstitution(Integer.class)
-public class IntegerSubstitutions {
-
-    @MethodSubstitution
-    public static int reverseBytes(int i) {
-        return ReverseBytesNode.reverse(i);
-    }
-
-    @MethodSubstitution
-    public static int numberOfLeadingZeros(int i) {
-        if (i == 0) {
-            return 32;
-        }
-        return 31 - BitScanReverseNode.scan(i);
-    }
-
-    @MethodSubstitution
-    public static int numberOfTrailingZeros(int i) {
-        if (i == 0) {
-            return 32;
-        }
-        return BitScanForwardNode.scan(i);
-    }
-
-    @MethodSubstitution
-    public static int bitCount(int i) {
-        return BitCountNode.bitCount(i);
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/JavacBug.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2011, 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.snippets;
-
-/**
- * Used to indicate that an otherwise strange looking code pattern is required to work around a bug
- * in javac.
- */
-public @interface JavacBug {
-
-    /**
-     * A description of the bug. Only really useful if there is no existing entry for the bug in the
-     * <a href="http://bugs.sun.com/bugdatabase/">Bug Database</a>.
-     */
-    String value() default "";
-
-    /**
-     * An identifier in the <a href="http://bugs.sun.com/bugdatabase/">Bug Database</a>.
-     */
-    int id() default 0;
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Log.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,201 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets;
-
-import java.io.*;
-
-import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.Node.ConstantNodeParameter;
-import com.oracle.graal.graph.Node.NodeIntrinsic;
-import com.oracle.graal.nodes.extended.*;
-
-//JaCoCo Exclude
-
-/**
- * Provides {@link PrintStream}-like logging facility. This should only be used in
- * {@linkplain Snippet snippets}.
- */
-public final class Log {
-
-    public static final Descriptor LOG_PRIMITIVE = new Descriptor("logPrimitive", false, void.class, int.class, long.class, boolean.class);
-    public static final Descriptor LOG_OBJECT = new Descriptor("logObject", false, void.class, Object.class, int.class);
-    public static final Descriptor LOG_PRINTF = new Descriptor("logPrintf", false, void.class, Object.class, long.class, long.class, long.class);
-
-    // Note: Must be kept in sync with constants in c1_Runtime1.hpp
-    private static final int LOG_OBJECT_NEWLINE = 0x01;
-    private static final int LOG_OBJECT_STRING = 0x02;
-    private static final int LOG_OBJECT_ADDRESS = 0x04;
-
-    @NodeIntrinsic(RuntimeCallNode.class)
-    private static native void log(@ConstantNodeParameter Descriptor logObject, Object object, int flags);
-
-    @NodeIntrinsic(RuntimeCallNode.class)
-    private static native void log(@ConstantNodeParameter Descriptor logPrimitive, int typeChar, long value, boolean newline);
-
-    @NodeIntrinsic(RuntimeCallNode.class)
-    private static native void printf(@ConstantNodeParameter Descriptor logPrintf, String format, long v1, long v2, long v3);
-
-    public static void print(boolean value) {
-        log(LOG_PRIMITIVE, Kind.Boolean.getTypeChar(), value ? 1L : 0L, false);
-    }
-
-    public static void print(byte value) {
-        log(LOG_PRIMITIVE, Kind.Byte.getTypeChar(), value, false);
-    }
-
-    public static void print(char value) {
-        log(LOG_PRIMITIVE, Kind.Char.getTypeChar(), value, false);
-    }
-
-    public static void print(short value) {
-        log(LOG_PRIMITIVE, Kind.Short.getTypeChar(), value, false);
-    }
-
-    public static void print(int value) {
-        log(LOG_PRIMITIVE, Kind.Int.getTypeChar(), value, false);
-    }
-
-    public static void print(long value) {
-        log(LOG_PRIMITIVE, Kind.Long.getTypeChar(), value, false);
-    }
-
-    /**
-     * Prints a formatted string to the log stream.
-     * 
-     * @param format a C style printf format value that can contain at most one conversion specifier
-     *            (i.e., a sequence of characters starting with '%').
-     * @param value the value associated with the conversion specifier
-     */
-    public static void printf(String format, long value) {
-        printf(LOG_PRINTF, format, value, 0L, 0L);
-    }
-
-    public static void printf(String format, long v1, long v2) {
-        printf(LOG_PRINTF, format, v1, v2, 0L);
-    }
-
-    public static void printf(String format, long v1, long v2, long v3) {
-        printf(LOG_PRINTF, format, v1, v2, v3);
-    }
-
-    public static void print(float value) {
-        if (Float.isNaN(value)) {
-            print("NaN");
-        } else if (value == Float.POSITIVE_INFINITY) {
-            print("Infinity");
-        } else if (value == Float.NEGATIVE_INFINITY) {
-            print("-Infinity");
-        } else {
-            log(LOG_PRIMITIVE, Kind.Float.getTypeChar(), Float.floatToRawIntBits(value), false);
-        }
-    }
-
-    public static void print(double value) {
-        if (Double.isNaN(value)) {
-            print("NaN");
-        } else if (value == Double.POSITIVE_INFINITY) {
-            print("Infinity");
-        } else if (value == Double.NEGATIVE_INFINITY) {
-            print("-Infinity");
-        } else {
-            log(LOG_PRIMITIVE, Kind.Double.getTypeChar(), Double.doubleToRawLongBits(value), false);
-        }
-    }
-
-    public static void print(String value) {
-        log(LOG_OBJECT, value, LOG_OBJECT_STRING);
-    }
-
-    public static void printAddress(Object o) {
-        log(LOG_OBJECT, o, LOG_OBJECT_ADDRESS);
-    }
-
-    public static void printObject(Object o) {
-        log(LOG_OBJECT, o, 0);
-    }
-
-    public static void println(boolean value) {
-        log(LOG_PRIMITIVE, Kind.Boolean.getTypeChar(), value ? 1L : 0L, true);
-    }
-
-    public static void println(byte value) {
-        log(LOG_PRIMITIVE, Kind.Byte.getTypeChar(), value, true);
-    }
-
-    public static void println(char value) {
-        log(LOG_PRIMITIVE, Kind.Char.getTypeChar(), value, true);
-    }
-
-    public static void println(short value) {
-        log(LOG_PRIMITIVE, Kind.Short.getTypeChar(), value, true);
-    }
-
-    public static void println(int value) {
-        log(LOG_PRIMITIVE, Kind.Int.getTypeChar(), value, true);
-    }
-
-    public static void println(long value) {
-        log(LOG_PRIMITIVE, Kind.Long.getTypeChar(), value, true);
-    }
-
-    public static void println(float value) {
-        if (Float.isNaN(value)) {
-            println("NaN");
-        } else if (value == Float.POSITIVE_INFINITY) {
-            println("Infinity");
-        } else if (value == Float.NEGATIVE_INFINITY) {
-            println("-Infinity");
-        } else {
-            log(LOG_PRIMITIVE, Kind.Float.getTypeChar(), Float.floatToRawIntBits(value), true);
-        }
-    }
-
-    public static void println(double value) {
-        if (Double.isNaN(value)) {
-            println("NaN");
-        } else if (value == Double.POSITIVE_INFINITY) {
-            println("Infinity");
-        } else if (value == Double.NEGATIVE_INFINITY) {
-            println("-Infinity");
-        } else {
-            log(LOG_PRIMITIVE, Kind.Double.getTypeChar(), Double.doubleToRawLongBits(value), true);
-        }
-    }
-
-    public static void println(String value) {
-        log(LOG_OBJECT, value, LOG_OBJECT_NEWLINE | LOG_OBJECT_STRING);
-    }
-
-    public static void printlnAddress(Object o) {
-        log(LOG_OBJECT, o, LOG_OBJECT_NEWLINE | LOG_OBJECT_ADDRESS);
-    }
-
-    public static void printlnObject(Object o) {
-        log(LOG_OBJECT, o, LOG_OBJECT_NEWLINE);
-    }
-
-    public static void println() {
-        println("");
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/LongSubstitutions.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets;
-
-import com.oracle.graal.snippets.ClassSubstitution.*;
-import com.oracle.graal.snippets.nodes.*;
-
-@ClassSubstitution(Long.class)
-public class LongSubstitutions {
-
-    @MethodSubstitution
-    public static long reverseBytes(long i) {
-        return ReverseBytesNode.reverse(i);
-    }
-
-    @MethodSubstitution
-    public static int numberOfLeadingZeros(long i) {
-        if (i == 0) {
-            return 64;
-        }
-        return 63 - BitScanReverseNode.scan(i);
-    }
-
-    @MethodSubstitution
-    public static int numberOfTrailingZeros(long i) {
-        if (i == 0) {
-            return 64;
-        }
-        return BitScanForwardNode.scan(i);
-    }
-
-    @MethodSubstitution
-    public static int bitCount(long i) {
-        return BitCountNode.bitCount(i);
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/MathSubstitutionsX86.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 2011, 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.snippets;
-
-import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
-import com.oracle.graal.graph.Node.ConstantNodeParameter;
-import com.oracle.graal.graph.Node.NodeIntrinsic;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution;
-import com.oracle.graal.snippets.nodes.*;
-import com.oracle.graal.snippets.nodes.MathIntrinsicNode.Operation;
-
-/**
- * Substitutions for {@link java.lang.Math} methods.
- */
-@ClassSubstitution(java.lang.Math.class)
-public class MathSubstitutionsX86 {
-
-    private static final double PI_4 = 0.7853981633974483;
-
-    @MethodSubstitution
-    public static double abs(double x) {
-        return MathIntrinsicNode.compute(x, Operation.ABS);
-    }
-
-    @MethodSubstitution
-    public static double sqrt(double x) {
-        return MathIntrinsicNode.compute(x, Operation.SQRT);
-    }
-
-    @MethodSubstitution
-    public static double log(double x) {
-        return MathIntrinsicNode.compute(x, Operation.LOG);
-    }
-
-    @MethodSubstitution
-    public static double log10(double x) {
-        return MathIntrinsicNode.compute(x, Operation.LOG10);
-    }
-
-    // NOTE on snippets below:
-    // Math.sin(), .cos() and .tan() guarantee a value within 1 ULP of the
-    // exact result, but x87 trigonometric FPU instructions are only that
-    // accurate within [-pi/4, pi/4]. Examine the passed value and provide
-    // a slow path for inputs outside of that interval.
-
-    @MethodSubstitution
-    public static double sin(double x) {
-        if (abs(x) < PI_4) {
-            return MathIntrinsicNode.compute(x, Operation.SIN);
-        } else {
-            return callDouble(ARITHMETIC_SIN, x);
-        }
-    }
-
-    @MethodSubstitution
-    public static double cos(double x) {
-        if (abs(x) < PI_4) {
-            return MathIntrinsicNode.compute(x, Operation.COS);
-        } else {
-            return callDouble(ARITHMETIC_COS, x);
-        }
-    }
-
-    @MethodSubstitution
-    public static double tan(double x) {
-        if (abs(x) < PI_4) {
-            return MathIntrinsicNode.compute(x, Operation.TAN);
-        } else {
-            return callDouble(ARITHMETIC_TAN, x);
-        }
-    }
-
-    public static final Descriptor ARITHMETIC_SIN = new Descriptor("arithmeticSin", false, double.class, double.class);
-    public static final Descriptor ARITHMETIC_COS = new Descriptor("arithmeticCos", false, double.class, double.class);
-    public static final Descriptor ARITHMETIC_TAN = new Descriptor("arithmeticTan", false, double.class, double.class);
-
-    @NodeIntrinsic(value = RuntimeCallNode.class, setStampFromReturnType = true)
-    public static native double callDouble(@ConstantNodeParameter Descriptor descriptor, double value);
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/NodeClassSubstitutions.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2011, 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.snippets;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.snippets.ClassSubstitution.*;
-
-/**
- * Substitutions for improving the performance of some critical methods in {@link NodeClass}
- * methods. These substitutions improve the performance by forcing the relevant methods to be
- * inlined (intrinsification being a special form of inlining) and removing a checked cast. The
- * latter cannot be done directly in Java code as {@link UnsafeCastNode} is not available to the
- * project containing {@link NodeClass}.
- */
-@ClassSubstitution(NodeClass.class)
-public class NodeClassSubstitutions {
-
-    @MethodSubstitution
-    private static Node getNode(Node node, long offset) {
-        return UnsafeCastNode.unsafeCast(UnsafeLoadNode.load(node, 0, offset, Kind.Object), Node.class, false, false);
-    }
-
-    @MethodSubstitution
-    private static NodeList getNodeList(Node node, long offset) {
-        return UnsafeCastNode.unsafeCast(UnsafeLoadNode.load(node, 0, offset, Kind.Object), NodeList.class, false, false);
-    }
-
-    @MethodSubstitution
-    private static void putNode(Node node, long offset, Node value) {
-        UnsafeStoreNode.store(node, 0, offset, value, Kind.Object);
-    }
-
-    @MethodSubstitution
-    private static void putNodeList(Node node, long offset, NodeList value) {
-        UnsafeStoreNode.store(node, 0, offset, value, Kind.Object);
-    }
-
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,222 +0,0 @@
-/*
- * Copyright (c) 2011, 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.snippets;
-
-import java.lang.annotation.*;
-import java.lang.reflect.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.Node.NodeIntrinsic;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.snippets.nodes.*;
-import com.oracle.graal.word.*;
-
-/**
- * A snippet is a Graal graph expressed as a Java source method. Graal snippets can be used for:
- * <ul>
- * <li>intrinsifying native JDK methods (see {@link ClassSubstitution})</li>
- * <li>lowering operations that have runtime dependent semantics (e.g. the {@code CHECKCAST}
- * bytecode)</li>
- * <li>replacing a method call with a single graph node (see {@link NodeIntrinsic})</li>
- * </ul>
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-public @interface Snippet {
-
-    /**
-     * Specifies the class defining the inlining policy for this snippet. A
-     * {@linkplain DefaultSnippetInliningPolicy default} policy is used if none is supplied.
-     */
-    Class<? extends SnippetInliningPolicy> inlining() default SnippetInliningPolicy.class;
-
-    /**
-     * Guides inlining decisions used when installing a snippet.
-     */
-    public interface SnippetInliningPolicy {
-
-        /**
-         * Determines if {@code method} should be inlined into {@code caller}.
-         */
-        boolean shouldInline(ResolvedJavaMethod method, ResolvedJavaMethod caller);
-    }
-
-    /**
-     * The default inlining policy which inlines everything except for methods in any of the
-     * following categories.
-     * <ul>
-     * <li>{@linkplain Fold foldable} methods</li>
-     * <li>{@linkplain NodeIntrinsic node intrinsics}</li>
-     * <li>native methods</li>
-     * <li>constructors of {@link Throwable} classes</li>
-     * </ul>
-     */
-    public static class DefaultSnippetInliningPolicy implements SnippetInliningPolicy {
-
-        private final MetaAccessProvider metaAccess;
-        private final BoxingMethodPool pool;
-
-        public DefaultSnippetInliningPolicy(MetaAccessProvider metaAccess, BoxingMethodPool pool) {
-            this.metaAccess = metaAccess;
-            this.pool = pool;
-        }
-
-        @Override
-        public boolean shouldInline(ResolvedJavaMethod method, ResolvedJavaMethod caller) {
-            if (Modifier.isNative(method.getModifiers())) {
-                return false;
-            }
-            if (method.getAnnotation(Fold.class) != null) {
-                return false;
-            }
-            if (method.getAnnotation(NodeIntrinsic.class) != null) {
-                return false;
-            }
-            if (metaAccess.lookupJavaType(Throwable.class).isAssignableFrom(method.getDeclaringClass())) {
-                if (method.getName().equals("<init>")) {
-                    return false;
-                }
-            }
-            if (method.getAnnotation(Word.Operation.class) != null) {
-                return false;
-            }
-            if (pool.isSpecialMethod(method)) {
-                return false;
-            }
-            return true;
-        }
-    }
-
-    /**
-     * Annotates a method replaced by a compile-time constant. A (resolved) call to the annotated
-     * method is replaced with a constant obtained by calling the annotated method via reflection.
-     * 
-     * All arguments to such a method (including the receiver if applicable) must be compile-time
-     * constants.
-     */
-    @Retention(RetentionPolicy.RUNTIME)
-    @Target(ElementType.METHOD)
-    public static @interface Fold {
-    }
-
-    /**
-     * Denotes a snippet parameter that will be bound during snippet template
-     * {@linkplain SnippetTemplate#instantiate instantiation}.
-     */
-    @Retention(RetentionPolicy.RUNTIME)
-    @Target(ElementType.PARAMETER)
-    public @interface Parameter {
-
-        /**
-         * The name of this parameter.
-         */
-        String value();
-    }
-
-    /**
-     * Denotes a snippet parameter representing 0 or more arguments that will be bound during
-     * snippet template {@linkplain SnippetTemplate#instantiate instantiation}. During snippet
-     * template creation, its value must be an array whose length specifies the number of arguments
-     * (the contents of the array are ignored) bound to the parameter during
-     * {@linkplain SnippetTemplate#instantiate instantiation}.
-     * 
-     * Such a parameter must be used in a counted loop in the snippet preceded by a call to
-     * {@link ExplodeLoopNode#explodeLoop()}. The counted looped must be a standard iteration over
-     * all the loop's elements (i.e. {@code for (T e : arr) ... }).
-     */
-    @Retention(RetentionPolicy.RUNTIME)
-    @Target(ElementType.PARAMETER)
-    public @interface VarargsParameter {
-
-        /**
-         * The name of this parameter.
-         */
-        String value();
-    }
-
-    /**
-     * Denotes a snippet parameter that will bound to a constant value during snippet template
-     * {@linkplain SnippetTemplate#instantiate instantiation}.
-     */
-    @Retention(RetentionPolicy.RUNTIME)
-    @Target(ElementType.PARAMETER)
-    public @interface ConstantParameter {
-
-        /**
-         * The name of this constant.
-         */
-        String value();
-    }
-
-    /**
-     * Wrapper for the prototype value of a {@linkplain VarargsParameter varargs} parameter.
-     */
-    public static class Varargs {
-
-        private final Object args;
-        private final Class argType;
-        private final int length;
-        private final Stamp argStamp;
-
-        public static Varargs vargargs(Object array, Stamp argStamp) {
-            return new Varargs(array, argStamp);
-        }
-
-        public Varargs(Object array, Stamp argStamp) {
-            assert array != null;
-            this.argType = array.getClass().getComponentType();
-            this.argStamp = argStamp;
-            assert this.argType != null;
-            this.length = java.lang.reflect.Array.getLength(array);
-            this.args = array;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj instanceof Varargs) {
-                Varargs other = (Varargs) obj;
-                return other.argType == argType && other.length == length;
-            }
-            return false;
-        }
-
-        public Object getArray() {
-            return args;
-        }
-
-        public Stamp getArgStamp() {
-            return argStamp;
-        }
-
-        @Override
-        public int hashCode() {
-            return argType.hashCode() ^ length;
-        }
-
-        @Override
-        public String toString() {
-            return argType.getName() + "[" + length + "]";
-        }
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetCounter.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,155 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets;
-
-//JaCoCo Exclude
-
-import static com.oracle.graal.graph.FieldIntrospection.*;
-
-import java.io.*;
-import java.util.*;
-
-import com.oracle.graal.graph.*;
-import com.oracle.graal.snippets.Snippet.Fold;
-import com.oracle.graal.snippets.nodes.*;
-
-/**
- * A counter that can be safely {@linkplain #inc() incremented} from within a snippet for gathering
- * snippet specific metrics.
- */
-public class SnippetCounter implements Comparable<SnippetCounter> {
-
-    /**
-     * A group of related counters.
-     */
-    public static class Group {
-
-        final String name;
-        final List<SnippetCounter> counters;
-
-        public Group(String name) {
-            this.name = name;
-            this.counters = new ArrayList<>();
-        }
-
-        @Override
-        public synchronized String toString() {
-            Collections.sort(counters);
-
-            long total = 0;
-            int maxNameLen = 0;
-            for (SnippetCounter c : counters) {
-                total += c.value;
-                maxNameLen = Math.max(c.name.length(), maxNameLen);
-            }
-
-            StringBuilder buf = new StringBuilder(String.format("Counters: %s%n", name));
-
-            for (SnippetCounter c : counters) {
-                double percent = total == 0D ? 0D : ((double) (c.value * 100)) / total;
-                buf.append(String.format("  %" + maxNameLen + "s: %5.2f%%%10d  // %s%n", c.name, percent, c.value, c.description));
-            }
-            return buf.toString();
-        }
-    }
-
-    /**
-     * Sorts counters in descending order of their {@linkplain #value() values}.
-     */
-    @Override
-    public int compareTo(SnippetCounter o) {
-        if (value > o.value) {
-            return -1;
-        } else if (o.value < value) {
-            return 1;
-        }
-        return 0;
-    }
-
-    private static final List<Group> groups = new ArrayList<>();
-
-    private final Group group;
-    private final int index;
-    private final String name;
-    private final String description;
-    private long value;
-
-    @Fold
-    private static int countOffset() {
-        try {
-            return (int) unsafe.objectFieldOffset(SnippetCounter.class.getDeclaredField("value"));
-        } catch (Exception e) {
-            throw new GraalInternalError(e);
-        }
-    }
-
-    /**
-     * Creates a counter.
-     * 
-     * @param group the group to which the counter belongs. If this is null, the newly created
-     *            counter is disabled and {@linkplain #inc() incrementing} is a no-op.
-     * @param name the name of the counter
-     * @param description a brief comment describing the metric represented by the counter
-     */
-    public SnippetCounter(Group group, String name, String description) {
-        this.group = group;
-        this.name = name;
-        this.description = description;
-        if (group != null) {
-            List<SnippetCounter> counters = group.counters;
-            this.index = counters.size();
-            counters.add(this);
-            if (index == 0) {
-                groups.add(group);
-            }
-        } else {
-            this.index = -1;
-        }
-    }
-
-    /**
-     * Increments the value of this counter. This method can be safely used in a snippet if it is
-     * invoked on a compile-time constant {@link SnippetCounter} object.
-     */
-    public void inc() {
-        if (group != null) {
-            DirectObjectStoreNode.storeLong(this, countOffset(), 0, value + 1);
-        }
-    }
-
-    /**
-     * Gets the value of this counter.
-     */
-    public long value() {
-        return value;
-    }
-
-    /**
-     * Prints all the counter groups to a given stream.
-     */
-    public static void printGroups(PrintStream out) {
-        for (Group group : groups) {
-            out.println(group);
-        }
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetFrameStateCleanupPhase.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2011, 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.snippets;
-
-import java.util.*;
-
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.util.*;
-import com.oracle.graal.phases.*;
-import com.oracle.graal.phases.graph.*;
-import com.oracle.graal.phases.graph.ReentrantNodeIterator.LoopInfo;
-import com.oracle.graal.phases.graph.ReentrantNodeIterator.NodeIteratorClosure;
-
-/**
- * Removes frame states from {@linkplain StateSplit#hasSideEffect() non-side-effecting} nodes in a
- * snippet.
- * 
- * The frame states of side-effecting nodes are replaced with
- * {@linkplain FrameState#INVALID_FRAMESTATE_BCI invalid} frame states. Loops that contain invalid
- * frame states are also assigned an invalid frame state.
- * 
- * The invalid frame states ensure that no deoptimization to a snippet frame state will happen.
- */
-public class SnippetFrameStateCleanupPhase extends Phase {
-
-    @Override
-    protected void run(StructuredGraph graph) {
-        ReentrantNodeIterator.apply(new SnippetFrameStateCleanupClosure(), graph.start(), new CleanupState(false), null);
-    }
-
-    private static class CleanupState {
-
-        public boolean containsFrameState;
-
-        public CleanupState(boolean containsFrameState) {
-            this.containsFrameState = containsFrameState;
-        }
-    }
-
-    /**
-     * A proper (loop-aware) iteration over the graph is used to detect loops that contain invalid
-     * frame states, so that they can be marked with an invalid frame state.
-     */
-    private static class SnippetFrameStateCleanupClosure extends NodeIteratorClosure<CleanupState> {
-
-        @Override
-        protected void processNode(FixedNode node, CleanupState currentState) {
-            if (node instanceof StateSplit) {
-                StateSplit stateSplit = (StateSplit) node;
-                FrameState frameState = stateSplit.stateAfter();
-                if (frameState != null) {
-                    if (stateSplit.hasSideEffect()) {
-                        currentState.containsFrameState = true;
-                        stateSplit.setStateAfter(node.graph().add(new FrameState(FrameState.INVALID_FRAMESTATE_BCI)));
-                    } else {
-                        stateSplit.setStateAfter(null);
-                    }
-                    if (frameState.usages().isEmpty()) {
-                        GraphUtil.killWithUnusedFloatingInputs(frameState);
-                    }
-                }
-            }
-        }
-
-        @Override
-        protected CleanupState merge(MergeNode merge, List<CleanupState> states) {
-            for (CleanupState state : states) {
-                if (state.containsFrameState) {
-                    return new CleanupState(true);
-                }
-            }
-            return new CleanupState(false);
-        }
-
-        @Override
-        protected CleanupState afterSplit(BeginNode node, CleanupState oldState) {
-            return new CleanupState(oldState.containsFrameState);
-        }
-
-        @Override
-        protected Map<LoopExitNode, CleanupState> processLoop(LoopBeginNode loop, CleanupState initialState) {
-            LoopInfo<CleanupState> info = ReentrantNodeIterator.processLoop(this, loop, new CleanupState(false));
-            boolean containsFrameState = false;
-            for (CleanupState state : info.endStates.values()) {
-                containsFrameState |= state.containsFrameState;
-            }
-            if (containsFrameState) {
-                loop.setStateAfter(loop.graph().add(new FrameState(FrameState.INVALID_FRAMESTATE_BCI)));
-            }
-            if (containsFrameState || initialState.containsFrameState) {
-                for (CleanupState state : info.exitStates.values()) {
-                    state.containsFrameState = true;
-                }
-            }
-            return info.exitStates;
-        }
-
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,392 +0,0 @@
-/*
- * Copyright (c) 2011, 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.snippets;
-
-import static com.oracle.graal.api.meta.MetaUtil.*;
-
-import java.lang.reflect.*;
-import java.util.*;
-import java.util.concurrent.*;
-
-import sun.misc.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.debug.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.java.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
-import com.oracle.graal.phases.*;
-import com.oracle.graal.phases.common.*;
-import com.oracle.graal.snippets.ClassSubstitution.MacroSubstitution;
-import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution;
-import com.oracle.graal.snippets.Snippet.DefaultSnippetInliningPolicy;
-import com.oracle.graal.snippets.Snippet.SnippetInliningPolicy;
-import com.oracle.graal.word.phases.*;
-
-/**
- * Utility for {@linkplain #installSnippets(Class) snippet} and
- * {@linkplain #installSubstitutions(Class) substitution} installation.
- */
-public class SnippetInstaller {
-
-    protected final MetaAccessProvider runtime;
-    protected final TargetDescription target;
-    protected final Assumptions assumptions;
-    protected final BoxingMethodPool pool;
-    private final Thread owner;
-
-    /**
-     * A graph cache used by this installer to avoid using the compiler storage for each method
-     * processed during snippet installation. Without this, all processed methods are to be
-     * determined as {@linkplain InliningUtil#canIntrinsify intrinsifiable}.
-     */
-    private final Map<ResolvedJavaMethod, StructuredGraph> graphCache;
-
-    public SnippetInstaller(MetaAccessProvider runtime, Assumptions assumptions, TargetDescription target) {
-        this.runtime = runtime;
-        this.target = target;
-        this.assumptions = assumptions;
-        this.pool = new BoxingMethodPool(runtime);
-        this.graphCache = new HashMap<>();
-        this.owner = Thread.currentThread();
-    }
-
-    /**
-     * Finds all the snippet methods in a given class, builds a graph for them and installs the
-     * graph with the key value of {@code Graph.class} in the
-     * {@linkplain ResolvedJavaMethod#getCompilerStorage() compiler storage} of each method.
-     */
-    public void installSnippets(Class<? extends SnippetsInterface> clazz) {
-        for (Method method : clazz.getDeclaredMethods()) {
-            if (method.getAnnotation(Snippet.class) != null) {
-                int modifiers = method.getModifiers();
-                if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) {
-                    throw new RuntimeException("Snippet must not be abstract or native");
-                }
-                ResolvedJavaMethod snippet = runtime.lookupJavaMethod(method);
-                assert snippet.getCompilerStorage().get(Graph.class) == null : method;
-                StructuredGraph graph = makeGraph(snippet, inliningPolicy(snippet));
-                // System.out.println("snippet: " + graph);
-                snippet.getCompilerStorage().put(Graph.class, graph);
-            }
-        }
-    }
-
-    /**
-     * Finds all the {@linkplain MethodSubstitution substitution} methods in a given class, builds a
-     * graph for them. If the original class is resolvable, then the graph is installed with the key
-     * value of {@code Graph.class} in the {@linkplain ResolvedJavaMethod#getCompilerStorage()
-     * compiler storage} of each original method.
-     */
-    public void installSubstitutions(Class<?> substitutions) {
-        assert owner == Thread.currentThread() : "substitution installation must be single threaded";
-        ClassSubstitution classSubstitution = substitutions.getAnnotation(ClassSubstitution.class);
-        assert classSubstitution != null;
-        assert !SnippetsInterface.class.isAssignableFrom(substitutions);
-        for (Method substituteMethod : substitutions.getDeclaredMethods()) {
-            MethodSubstitution methodSubstitution = substituteMethod.getAnnotation(MethodSubstitution.class);
-            MacroSubstitution macroSubstitution = substituteMethod.getAnnotation(MacroSubstitution.class);
-            if (methodSubstitution == null && macroSubstitution == null) {
-                continue;
-            }
-
-            int modifiers = substituteMethod.getModifiers();
-            if (!Modifier.isStatic(modifiers)) {
-                throw new RuntimeException("Substitution methods must be static: " + substituteMethod);
-            }
-
-            if (methodSubstitution != null) {
-                if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) {
-                    throw new RuntimeException("Substitution method must not be abstract or native: " + substituteMethod);
-                }
-                String originalName = originalName(substituteMethod, methodSubstitution.value());
-                Class[] originalParameters = originalParameters(substituteMethod, methodSubstitution.signature(), methodSubstitution.isStatic());
-                Member originalMethod = originalMethod(classSubstitution, originalName, originalParameters);
-                installMethodSubstitution(originalMethod, substituteMethod);
-            }
-            if (macroSubstitution != null) {
-                String originalName = originalName(substituteMethod, macroSubstitution.value());
-                Class[] originalParameters = originalParameters(substituteMethod, macroSubstitution.signature(), macroSubstitution.isStatic());
-                Member originalMethod = originalMethod(classSubstitution, originalName, originalParameters);
-                installMacroSubstitution(originalMethod, macroSubstitution.macro());
-            }
-        }
-    }
-
-    // These fields are used to detect calls from the substitute method to the original method.
-    ResolvedJavaMethod substitute;
-    ResolvedJavaMethod original;
-    boolean substituteCallsOriginal;
-
-    /**
-     * Installs a method substitution.
-     * 
-     * @param originalMethod a method or constructor being substituted
-     * @param substituteMethod the substitute method
-     */
-    protected void installMethodSubstitution(Member originalMethod, Method substituteMethod) {
-        substitute = runtime.lookupJavaMethod(substituteMethod);
-        if (originalMethod instanceof Method) {
-            original = runtime.lookupJavaMethod((Method) originalMethod);
-        } else {
-            original = runtime.lookupJavaConstructor((Constructor) originalMethod);
-        }
-        try {
-            Debug.log("inlinable substitution: " + MetaUtil.format("%H.%n(%p)", original) + " --> " + MetaUtil.format("%H.%n(%p)", substitute));
-            StructuredGraph graph = makeGraph(substitute, inliningPolicy(substitute));
-            Object oldValue = original.getCompilerStorage().put(Graph.class, graph);
-            assert oldValue == null;
-
-            Debug.log("compilable substitution: " + MetaUtil.format("%H.%n(%p)", original) + " --> " + MetaUtil.format("%H.%n(%p)", substitute));
-            graph = makeGraph(substitute, inliningPolicy(substitute));
-            oldValue = original.getCompilerStorage().put(MethodSubstitution.class, graph);
-            assert oldValue == null;
-        } finally {
-            substitute = null;
-            original = null;
-            substituteCallsOriginal = false;
-        }
-    }
-
-    /**
-     * Installs a macro substitution.
-     * 
-     * @param originalMethod a method or constructor being substituted
-     * @param macro the substitute macro node class
-     */
-    protected void installMacroSubstitution(Member originalMethod, Class<? extends FixedWithNextNode> macro) {
-        ResolvedJavaMethod originalJavaMethod;
-        if (originalMethod instanceof Method) {
-            originalJavaMethod = runtime.lookupJavaMethod((Method) originalMethod);
-        } else {
-            originalJavaMethod = runtime.lookupJavaConstructor((Constructor) originalMethod);
-        }
-        Object oldValue = originalJavaMethod.getCompilerStorage().put(Node.class, macro);
-        assert oldValue == null;
-    }
-
-    private SnippetInliningPolicy inliningPolicy(ResolvedJavaMethod method) {
-        Class<? extends SnippetInliningPolicy> policyClass = SnippetInliningPolicy.class;
-        Snippet snippet = method.getAnnotation(Snippet.class);
-        if (snippet != null) {
-            policyClass = snippet.inlining();
-        }
-        if (policyClass == SnippetInliningPolicy.class) {
-            return new DefaultSnippetInliningPolicy(runtime, pool);
-        }
-        try {
-            return policyClass.getConstructor().newInstance();
-        } catch (Exception e) {
-            throw new GraalInternalError(e);
-        }
-    }
-
-    /**
-     * Does final processing of a snippet graph.
-     */
-    protected void finalizeGraph(ResolvedJavaMethod method, StructuredGraph graph) {
-        new SnippetIntrinsificationPhase(runtime, pool).apply(graph);
-        assert SnippetTemplate.hasConstantParameter(method) || SnippetIntrinsificationVerificationPhase.verify(graph);
-
-        new SnippetFrameStateCleanupPhase().apply(graph);
-        new DeadCodeEliminationPhase().apply(graph);
-
-        new InsertStateAfterPlaceholderPhase().apply(graph);
-    }
-
-    public StructuredGraph makeGraph(final ResolvedJavaMethod method, final SnippetInliningPolicy policy) {
-        return Debug.scope("BuildSnippetGraph", new Object[]{method}, new Callable<StructuredGraph>() {
-
-            @Override
-            public StructuredGraph call() throws Exception {
-                StructuredGraph graph = parseGraph(method, policy);
-
-                finalizeGraph(method, graph);
-
-                Debug.dump(graph, "%s: Final", method.getName());
-
-                return graph;
-            }
-        });
-    }
-
-    private StructuredGraph parseGraph(final ResolvedJavaMethod method, final SnippetInliningPolicy policy) {
-        StructuredGraph graph = graphCache.get(method);
-        if (graph == null) {
-            graph = buildGraph(method, policy == null ? inliningPolicy(method) : policy);
-            graphCache.put(method, graph);
-        }
-        return graph;
-    }
-
-    /**
-     * Builds the initial graph for a snippet.
-     */
-    protected StructuredGraph buildInitialGraph(final ResolvedJavaMethod method) {
-        final StructuredGraph graph = new StructuredGraph(method);
-        GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault();
-        GraphBuilderPhase graphBuilder = new GraphBuilderPhase(runtime, config, OptimisticOptimizations.NONE);
-        graphBuilder.apply(graph);
-
-        Debug.dump(graph, "%s: %s", method.getName(), GraphBuilderPhase.class.getSimpleName());
-
-        new WordTypeVerificationPhase(runtime, target.wordKind).apply(graph);
-        new SnippetIntrinsificationPhase(runtime, pool).apply(graph);
-
-        return graph;
-    }
-
-    /**
-     * Called after a graph is inlined.
-     * 
-     * @param caller the graph into which {@code callee} was inlined
-     * @param callee the graph that was inlined into {@code caller}
-     */
-    protected void afterInline(StructuredGraph caller, StructuredGraph callee) {
-        if (GraalOptions.OptCanonicalizer) {
-            new WordTypeRewriterPhase(runtime, target.wordKind).apply(caller);
-            new CanonicalizerPhase(runtime, assumptions).apply(caller);
-        }
-    }
-
-    /**
-     * Called after all inlining for a given graph is complete.
-     */
-    protected void afterInlining(StructuredGraph graph) {
-        new SnippetIntrinsificationPhase(runtime, pool).apply(graph);
-
-        new WordTypeRewriterPhase(runtime, target.wordKind).apply(graph);
-
-        new DeadCodeEliminationPhase().apply(graph);
-        if (GraalOptions.OptCanonicalizer) {
-            new CanonicalizerPhase(runtime, assumptions).apply(graph);
-        }
-    }
-
-    private StructuredGraph buildGraph(final ResolvedJavaMethod method, final SnippetInliningPolicy policy) {
-        assert !Modifier.isAbstract(method.getModifiers()) && !Modifier.isNative(method.getModifiers()) : method;
-        final StructuredGraph graph = buildInitialGraph(method);
-
-        for (Invoke invoke : graph.getInvokes()) {
-            MethodCallTargetNode callTarget = invoke.methodCallTarget();
-            ResolvedJavaMethod callee = callTarget.targetMethod();
-            if (callee == substitute) {
-                final StructuredGraph originalGraph = new StructuredGraph(original);
-                new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(originalGraph);
-                InliningUtil.inline(invoke, originalGraph, true);
-
-                Debug.dump(graph, "after inlining %s", callee);
-                afterInline(graph, originalGraph);
-                substituteCallsOriginal = true;
-            } else {
-                if ((callTarget.invokeKind() == InvokeKind.Static || callTarget.invokeKind() == InvokeKind.Special) && policy.shouldInline(callee, method)) {
-                    StructuredGraph targetGraph = parseGraph(callee, policy);
-                    InliningUtil.inline(invoke, targetGraph, true);
-                    Debug.dump(graph, "after inlining %s", callee);
-                    afterInline(graph, targetGraph);
-                }
-            }
-        }
-
-        afterInlining(graph);
-
-        for (LoopEndNode end : graph.getNodes(LoopEndNode.class)) {
-            end.disableSafepoint();
-        }
-
-        if (GraalOptions.ProbabilityAnalysis) {
-            new DeadCodeEliminationPhase().apply(graph);
-            new ComputeProbabilityPhase().apply(graph);
-        }
-        return graph;
-    }
-
-    private static String originalName(Method substituteMethod, String methodSubstitution) {
-        if (methodSubstitution.isEmpty()) {
-            return substituteMethod.getName();
-        } else {
-            return methodSubstitution;
-        }
-    }
-
-    private static Class resolveType(String className) {
-        try {
-            // Need to use launcher class path to handle classes
-            // that are not on the boot class path
-            ClassLoader cl = Launcher.getLauncher().getClassLoader();
-            return Class.forName(className, false, cl);
-        } catch (ClassNotFoundException e) {
-            throw new GraalInternalError("Could not resolve type " + className);
-        }
-    }
-
-    private static Class resolveType(JavaType type) {
-        JavaType base = type;
-        int dimensions = 0;
-        while (base.getComponentType() != null) {
-            base = base.getComponentType();
-            dimensions++;
-        }
-
-        Class baseClass = base.getKind() != Kind.Object ? base.getKind().toJavaClass() : resolveType(toJavaName(base));
-        return dimensions == 0 ? baseClass : Array.newInstance(baseClass, new int[dimensions]).getClass();
-    }
-
-    private Class[] originalParameters(Method substituteMethod, String methodSubstitution, boolean isStatic) {
-        Class[] parameters;
-        if (methodSubstitution.isEmpty()) {
-            parameters = substituteMethod.getParameterTypes();
-            if (!isStatic) {
-                assert parameters.length > 0 : "must be a static method with the 'this' object as its first parameter";
-                parameters = Arrays.copyOfRange(parameters, 1, parameters.length);
-            }
-        } else {
-            Signature signature = runtime.parseMethodDescriptor(methodSubstitution);
-            parameters = new Class[signature.getParameterCount(false)];
-            for (int i = 0; i < parameters.length; i++) {
-                parameters[i] = resolveType(signature.getParameterType(i, null));
-            }
-        }
-        return parameters;
-    }
-
-    private static Member originalMethod(ClassSubstitution classSubstitution, String name, Class[] parameters) {
-        Class<?> originalClass = classSubstitution.value();
-        if (originalClass == ClassSubstitution.class) {
-            originalClass = resolveType(classSubstitution.className());
-        }
-        try {
-            if (name.equals("<init>")) {
-                return originalClass.getDeclaredConstructor(parameters);
-            } else {
-                return originalClass.getDeclaredMethod(name, parameters);
-            }
-        } catch (NoSuchMethodException | SecurityException e) {
-            throw new GraalInternalError(e);
-        }
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,389 +0,0 @@
-/*
- * Copyright (c) 2011, 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.snippets;
-
-import static com.oracle.graal.api.meta.MetaUtil.*;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.Node.ConstantNodeParameter;
-import com.oracle.graal.graph.Node.NodeIntrinsic;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.nodes.util.*;
-import com.oracle.graal.phases.*;
-import com.oracle.graal.snippets.Snippet.Fold;
-
-public class SnippetIntrinsificationPhase extends Phase {
-
-    private final MetaAccessProvider runtime;
-    private final BoxingMethodPool pool;
-
-    public SnippetIntrinsificationPhase(MetaAccessProvider runtime, BoxingMethodPool pool) {
-        this.runtime = runtime;
-        this.pool = pool;
-    }
-
-    @Override
-    protected void run(StructuredGraph graph) {
-        for (Invoke i : graph.getInvokes()) {
-            if (i.callTarget() instanceof MethodCallTargetNode) {
-                tryIntrinsify(i);
-            }
-        }
-    }
-
-    public static Class<?>[] signatureToTypes(Signature signature, ResolvedJavaType accessingClass) {
-        int count = signature.getParameterCount(false);
-        Class<?>[] result = new Class<?>[count];
-        for (int i = 0; i < result.length; ++i) {
-            result[i] = getMirrorOrFail(signature.getParameterType(i, accessingClass).resolve(accessingClass), Thread.currentThread().getContextClassLoader());
-        }
-        return result;
-    }
-
-    private boolean tryIntrinsify(Invoke invoke) {
-        ResolvedJavaMethod target = invoke.methodCallTarget().targetMethod();
-        NodeIntrinsic intrinsic = target.getAnnotation(Node.NodeIntrinsic.class);
-        ResolvedJavaType declaringClass = target.getDeclaringClass();
-        if (intrinsic != null) {
-            assert target.getAnnotation(Fold.class) == null;
-            assert Modifier.isNative(target.getModifiers()) : "node intrinsic " + target + " should be native";
-
-            Class<?>[] parameterTypes = signatureToTypes(target.getSignature(), declaringClass);
-            ResolvedJavaType returnType = target.getSignature().getReturnType(declaringClass).resolve(declaringClass);
-
-            // Prepare the arguments for the reflective constructor call on the node class.
-            Object[] nodeConstructorArguments = prepareArguments(invoke, parameterTypes, target, false);
-            if (nodeConstructorArguments == null) {
-                return false;
-            }
-
-            // Create the new node instance.
-            Class<?> c = getNodeClass(target, intrinsic);
-            Node newInstance = createNodeInstance(c, parameterTypes, returnType, intrinsic.setStampFromReturnType(), nodeConstructorArguments);
-
-            // Replace the invoke with the new node.
-            invoke.node().graph().add(newInstance);
-            invoke.intrinsify(newInstance);
-
-            // Clean up checkcast instructions inserted by javac if the return type is generic.
-            cleanUpReturnCheckCast(newInstance);
-        } else if (target.getAnnotation(Fold.class) != null) {
-            Class<?>[] parameterTypes = signatureToTypes(target.getSignature(), declaringClass);
-
-            // Prepare the arguments for the reflective method call
-            Object[] arguments = prepareArguments(invoke, parameterTypes, target, true);
-            if (arguments == null) {
-                return false;
-            }
-            Object receiver = null;
-            if (!invoke.methodCallTarget().isStatic()) {
-                receiver = arguments[0];
-                arguments = Arrays.asList(arguments).subList(1, arguments.length).toArray();
-            }
-
-            // Call the method
-            Constant constant = callMethod(target.getSignature().getReturnKind(), getMirrorOrFail(declaringClass, Thread.currentThread().getContextClassLoader()), target.getName(), parameterTypes,
-                            receiver, arguments);
-
-            if (constant != null) {
-                // Replace the invoke with the result of the call
-                ConstantNode node = ConstantNode.forConstant(constant, runtime, invoke.node().graph());
-                invoke.intrinsify(node);
-
-                // Clean up checkcast instructions inserted by javac if the return type is generic.
-                cleanUpReturnCheckCast(node);
-            } else {
-                // Remove the invoke
-                invoke.intrinsify(null);
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Converts the arguments of an invoke node to object values suitable for use as the arguments
-     * to a reflective invocation of a Java constructor or method.
-     * 
-     * @param folding specifies if the invocation is for handling a {@link Fold} annotation
-     * @return the arguments for the reflective invocation or null if an argument of {@code invoke}
-     *         that is expected to be constant isn't
-     */
-    private Object[] prepareArguments(Invoke invoke, Class<?>[] parameterTypes, ResolvedJavaMethod target, boolean folding) {
-        NodeInputList<ValueNode> arguments = invoke.callTarget().arguments();
-        Object[] reflectionCallArguments = new Object[arguments.size()];
-        for (int i = 0; i < reflectionCallArguments.length; ++i) {
-            int parameterIndex = i;
-            if (!invoke.methodCallTarget().isStatic()) {
-                parameterIndex--;
-            }
-            ValueNode argument = tryBoxingElimination(parameterIndex, target, arguments.get(i));
-            if (folding || MetaUtil.getParameterAnnotation(ConstantNodeParameter.class, parameterIndex, target) != null) {
-                if (!(argument instanceof ConstantNode)) {
-                    return null;
-                }
-                ConstantNode constantNode = (ConstantNode) argument;
-                Constant constant = constantNode.asConstant();
-                Object o = constant.asBoxedValue();
-                if (o instanceof Class<?>) {
-                    reflectionCallArguments[i] = runtime.lookupJavaType((Class<?>) o);
-                    parameterTypes[i] = ResolvedJavaType.class;
-                } else {
-                    if (parameterTypes[i] == boolean.class) {
-                        reflectionCallArguments[i] = Boolean.valueOf(constant.asInt() != 0);
-                    } else if (parameterTypes[i] == byte.class) {
-                        reflectionCallArguments[i] = Byte.valueOf((byte) constant.asInt());
-                    } else if (parameterTypes[i] == short.class) {
-                        reflectionCallArguments[i] = Short.valueOf((short) constant.asInt());
-                    } else if (parameterTypes[i] == char.class) {
-                        reflectionCallArguments[i] = Character.valueOf((char) constant.asInt());
-                    } else {
-                        reflectionCallArguments[i] = o;
-                    }
-                }
-            } else {
-                reflectionCallArguments[i] = argument;
-                parameterTypes[i] = ValueNode.class;
-            }
-        }
-        return reflectionCallArguments;
-    }
-
-    private static Class<?> getNodeClass(ResolvedJavaMethod target, NodeIntrinsic intrinsic) {
-        Class<?> result = intrinsic.value();
-        if (result == NodeIntrinsic.class) {
-            return getMirrorOrFail(target.getDeclaringClass(), Thread.currentThread().getContextClassLoader());
-        }
-        assert Node.class.isAssignableFrom(result);
-        return result;
-    }
-
-    private ValueNode tryBoxingElimination(int parameterIndex, ResolvedJavaMethod target, ValueNode node) {
-        if (parameterIndex >= 0) {
-            Type type = target.getGenericParameterTypes()[parameterIndex];
-            if (type instanceof TypeVariable) {
-                TypeVariable typeVariable = (TypeVariable) type;
-                if (typeVariable.getBounds().length == 1) {
-                    Type boundType = typeVariable.getBounds()[0];
-                    if (boundType instanceof Class && ((Class) boundType).getSuperclass() == null) {
-                        // Unbound generic => try boxing elimination
-                        if (node.usages().count() == 2) {
-                            if (node instanceof Invoke) {
-                                Invoke invokeNode = (Invoke) node;
-                                MethodCallTargetNode callTarget = invokeNode.methodCallTarget();
-                                if (pool.isBoxingMethod(callTarget.targetMethod())) {
-                                    FrameState stateAfter = invokeNode.stateAfter();
-                                    assert stateAfter.usages().count() == 1;
-                                    invokeNode.node().replaceAtUsages(null);
-                                    ValueNode result = callTarget.arguments().get(0);
-                                    StructuredGraph graph = (StructuredGraph) node.graph();
-                                    if (invokeNode instanceof InvokeWithExceptionNode) {
-                                        // Destroy exception edge & clear stateAfter.
-                                        InvokeWithExceptionNode invokeWithExceptionNode = (InvokeWithExceptionNode) invokeNode;
-
-                                        invokeWithExceptionNode.killExceptionEdge();
-                                        graph.removeSplit(invokeWithExceptionNode, invokeWithExceptionNode.next());
-                                    } else {
-                                        graph.removeFixed((InvokeNode) invokeNode);
-                                    }
-                                    stateAfter.safeDelete();
-                                    GraphUtil.propagateKill(callTarget);
-                                    return result;
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        return node;
-    }
-
-    private static Class asBoxedType(Class type) {
-        if (!type.isPrimitive()) {
-            return type;
-        }
-
-        if (Boolean.TYPE == type) {
-            return Boolean.class;
-        }
-        if (Character.TYPE == type) {
-            return Character.class;
-        }
-        if (Byte.TYPE == type) {
-            return Byte.class;
-        }
-        if (Short.TYPE == type) {
-            return Short.class;
-        }
-        if (Integer.TYPE == type) {
-            return Integer.class;
-        }
-        if (Long.TYPE == type) {
-            return Long.class;
-        }
-        if (Float.TYPE == type) {
-            return Float.class;
-        }
-        assert Double.TYPE == type;
-        return Double.class;
-    }
-
-    static final int VARARGS = 0x00000080;
-
-    private static Node createNodeInstance(Class<?> nodeClass, Class<?>[] parameterTypes, ResolvedJavaType returnType, boolean setStampFromReturnType, Object[] nodeConstructorArguments) {
-        Object[] arguments = null;
-        Constructor<?> constructor = null;
-        nextConstructor: for (Constructor c : nodeClass.getDeclaredConstructors()) {
-            Class[] signature = c.getParameterTypes();
-            if ((c.getModifiers() & VARARGS) != 0) {
-                int fixedArgs = signature.length - 1;
-                if (parameterTypes.length < fixedArgs) {
-                    continue nextConstructor;
-                }
-
-                for (int i = 0; i < fixedArgs; i++) {
-                    if (!parameterTypes[i].equals(signature[i])) {
-                        continue nextConstructor;
-                    }
-                }
-
-                Class componentType = signature[fixedArgs].getComponentType();
-                assert componentType != null : "expected last parameter of varargs constructor " + c + " to be an array type";
-                Class boxedType = asBoxedType(componentType);
-                for (int i = fixedArgs; i < nodeConstructorArguments.length; i++) {
-                    if (!boxedType.isInstance(nodeConstructorArguments[i])) {
-                        continue nextConstructor;
-                    }
-                }
-
-                arguments = Arrays.copyOf(nodeConstructorArguments, fixedArgs + 1);
-                int varargsLength = nodeConstructorArguments.length - fixedArgs;
-                Object varargs = Array.newInstance(componentType, varargsLength);
-                for (int i = fixedArgs; i < nodeConstructorArguments.length; i++) {
-                    Array.set(varargs, i - fixedArgs, nodeConstructorArguments[i]);
-                }
-                arguments[fixedArgs] = varargs;
-                constructor = c;
-                break;
-            } else if (Arrays.equals(parameterTypes, signature)) {
-                arguments = nodeConstructorArguments;
-                constructor = c;
-                break;
-            }
-        }
-        if (constructor == null) {
-            throw new GraalInternalError("Could not find constructor in " + nodeClass + " compatible with signature " + Arrays.toString(parameterTypes));
-        }
-        constructor.setAccessible(true);
-        try {
-            ValueNode intrinsicNode = (ValueNode) constructor.newInstance(arguments);
-            if (setStampFromReturnType) {
-                if (returnType.getKind() == Kind.Object) {
-                    intrinsicNode.setStamp(StampFactory.declared(returnType));
-                } else {
-                    intrinsicNode.setStamp(StampFactory.forKind(returnType.getKind()));
-                }
-            }
-            return intrinsicNode;
-        } catch (Exception e) {
-            throw new RuntimeException(constructor + Arrays.toString(nodeConstructorArguments), e);
-        }
-    }
-
-    /**
-     * Calls a Java method via reflection.
-     */
-    private static Constant callMethod(Kind returnKind, Class<?> holder, String name, Class<?>[] parameterTypes, Object receiver, Object[] arguments) {
-        Method method;
-        try {
-            method = holder.getDeclaredMethod(name, parameterTypes);
-            method.setAccessible(true);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-        try {
-            Object result = method.invoke(receiver, arguments);
-            if (result == null) {
-                return null;
-            }
-            return Constant.forBoxed(returnKind, result);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private static String sourceLocation(Node n) {
-        String loc = GraphUtil.approxSourceLocation(n);
-        return loc == null ? "<unknown>" : loc;
-    }
-
-    public void cleanUpReturnCheckCast(Node newInstance) {
-        if (newInstance instanceof ValueNode && (((ValueNode) newInstance).kind() != Kind.Object || ((ValueNode) newInstance).stamp() == StampFactory.forNodeIntrinsic())) {
-            StructuredGraph graph = (StructuredGraph) newInstance.graph();
-            for (CheckCastNode checkCastNode : newInstance.usages().filter(CheckCastNode.class).snapshot()) {
-                for (ProxyNode vpn : checkCastNode.usages().filter(ProxyNode.class).snapshot()) {
-                    graph.replaceFloating(vpn, checkCastNode);
-                }
-                for (Node checkCastUsage : checkCastNode.usages().snapshot()) {
-                    if (checkCastUsage instanceof ValueAnchorNode) {
-                        ValueAnchorNode valueAnchorNode = (ValueAnchorNode) checkCastUsage;
-                        graph.removeFixed(valueAnchorNode);
-                    } else if (checkCastUsage instanceof MethodCallTargetNode) {
-                        MethodCallTargetNode checkCastCallTarget = (MethodCallTargetNode) checkCastUsage;
-                        assert pool.isUnboxingMethod(checkCastCallTarget.targetMethod()) : "checkcast at " + sourceLocation(checkCastNode) + " not used by an unboxing method but by a call at " +
-                                        sourceLocation(checkCastCallTarget.usages().first()) + " to " + checkCastCallTarget.targetMethod();
-                        Invoke invokeNode = checkCastCallTarget.invoke();
-                        invokeNode.node().replaceAtUsages(newInstance);
-                        if (invokeNode instanceof InvokeWithExceptionNode) {
-                            // Destroy exception edge & clear stateAfter.
-                            InvokeWithExceptionNode invokeWithExceptionNode = (InvokeWithExceptionNode) invokeNode;
-
-                            invokeWithExceptionNode.killExceptionEdge();
-                            graph.removeSplit(invokeWithExceptionNode, invokeWithExceptionNode.next());
-                        } else {
-                            graph.removeFixed((InvokeNode) invokeNode);
-                        }
-                        checkCastCallTarget.safeDelete();
-                    } else if (checkCastUsage instanceof FrameState) {
-                        checkCastUsage.replaceFirstInput(checkCastNode, null);
-                    } else if (checkCastUsage instanceof ReturnNode && checkCastNode.object().stamp() == StampFactory.forNodeIntrinsic()) {
-                        checkCastUsage.replaceFirstInput(checkCastNode, checkCastNode.object());
-                    } else {
-                        assert false : sourceLocation(checkCastUsage) + " has unexpected usage " + checkCastUsage + " of checkcast at " + sourceLocation(checkCastNode);
-                    }
-                }
-                FixedNode next = checkCastNode.next();
-                checkCastNode.setNext(null);
-                checkCastNode.replaceAtPredecessor(next);
-                GraphUtil.killCFG(checkCastNode);
-            }
-        }
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationVerificationPhase.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2011, 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.snippets;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.Node.NodeIntrinsic;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.phases.*;
-import com.oracle.graal.snippets.Snippet.Fold;
-
-/**
- * Checks that a graph contains no calls to {@link NodeIntrinsic} or {@link Fold} methods.
- */
-public class SnippetIntrinsificationVerificationPhase extends Phase {
-
-    public static boolean verify(StructuredGraph graph) {
-        new SnippetIntrinsificationVerificationPhase().apply(graph);
-        return true;
-    }
-
-    @Override
-    protected void run(StructuredGraph graph) {
-        for (Invoke i : graph.getInvokes()) {
-            if (i.callTarget() instanceof MethodCallTargetNode) {
-                checkInvoke(i);
-            }
-        }
-    }
-
-    private static void checkInvoke(Invoke invoke) {
-        ResolvedJavaMethod target = invoke.methodCallTarget().targetMethod();
-        NodeIntrinsic intrinsic = target.getAnnotation(Node.NodeIntrinsic.class);
-        if (intrinsic != null) {
-            throw new GraalInternalError("Illegal call to node intrinsic in " + invoke.graph() + ": " + invoke);
-        } else if (target.getAnnotation(Fold.class) != null) {
-            throw new GraalInternalError("Illegal call to foldable method in " + invoke.graph() + ": " + invoke);
-        }
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetProvider.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.compiler.target.*;
-
-public interface SnippetProvider {
-
-    void installSnippets(Backend backend, SnippetInstaller installer, Assumptions assumptions);
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,755 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets;
-
-import java.lang.reflect.*;
-import java.util.*;
-import java.util.Map.Entry;
-import java.util.concurrent.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.debug.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.loop.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-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.util.*;
-import com.oracle.graal.phases.common.*;
-import com.oracle.graal.snippets.Snippet.ConstantParameter;
-import com.oracle.graal.snippets.Snippet.Parameter;
-import com.oracle.graal.snippets.Snippet.Varargs;
-import com.oracle.graal.snippets.Snippet.VarargsParameter;
-import com.oracle.graal.snippets.nodes.*;
-import com.oracle.graal.word.*;
-import com.oracle.graal.word.phases.*;
-
-/**
- * A snippet template is a graph created by parsing a snippet method and then specialized by binding
- * constants to the snippet's {@link ConstantParameter} parameters.
- * 
- * Snippet templates can be managed in a {@link Cache}.
- */
-public class SnippetTemplate {
-
-    /**
-     * A snippet template key encapsulates the method from which a snippet was built and the
-     * arguments used to specialize the snippet.
-     * 
-     * @see Cache
-     */
-    public static class Key implements Iterable<Map.Entry<String, Object>> {
-
-        public final ResolvedJavaMethod method;
-        private final HashMap<String, Object> map = new HashMap<>();
-        private int hash;
-
-        public Key(ResolvedJavaMethod method) {
-            this.method = method;
-            this.hash = method.hashCode();
-        }
-
-        public Key add(String name, Object value) {
-            assert !map.containsKey(name);
-            map.put(name, value);
-            hash = hash ^ name.hashCode();
-            if (value != null) {
-                hash *= (value.hashCode() + 1);
-            }
-            return this;
-        }
-
-        public int length() {
-            return map.size();
-        }
-
-        public Object get(String name) {
-            return map.get(name);
-        }
-
-        @Override
-        public Iterator<Entry<String, Object>> iterator() {
-            return map.entrySet().iterator();
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj instanceof Key) {
-                Key other = (Key) obj;
-                return other.method == method && other.map.equals(map);
-            }
-            return false;
-        }
-
-        @Override
-        public int hashCode() {
-            return hash;
-        }
-
-        @Override
-        public String toString() {
-            return MetaUtil.format("%h.%n", method) + map.toString();
-        }
-
-        public Set<String> names() {
-            return map.keySet();
-        }
-    }
-
-    /**
-     * Arguments used to instantiate a template.
-     */
-    public static class Arguments implements Iterable<Map.Entry<String, Object>> {
-
-        private final HashMap<String, Object> map = new HashMap<>();
-
-        public static Arguments arguments(String name, Object value) {
-            return new Arguments().add(name, value);
-        }
-
-        public Arguments add(String name, Object value) {
-            assert !map.containsKey(name);
-            map.put(name, value);
-            return this;
-        }
-
-        public int length() {
-            return map.size();
-        }
-
-        @Override
-        public Iterator<Entry<String, Object>> iterator() {
-            return map.entrySet().iterator();
-        }
-
-        @Override
-        public String toString() {
-            return map.toString();
-        }
-    }
-
-    /**
-     * A collection of snippet templates accessed by a {@link Key} instance.
-     */
-    public static class Cache {
-
-        private final ConcurrentHashMap<SnippetTemplate.Key, SnippetTemplate> templates = new ConcurrentHashMap<>();
-        private final MetaAccessProvider runtime;
-        private final TargetDescription target;
-
-        public Cache(MetaAccessProvider runtime, TargetDescription target) {
-            this.runtime = runtime;
-            this.target = target;
-        }
-
-        /**
-         * Gets a template for a given key, creating it first if necessary.
-         */
-        public SnippetTemplate get(final SnippetTemplate.Key key, final Assumptions assumptions) {
-            SnippetTemplate template = templates.get(key);
-            if (template == null) {
-                template = Debug.scope("SnippetSpecialization", key.method, new Callable<SnippetTemplate>() {
-
-                    @Override
-                    public SnippetTemplate call() throws Exception {
-                        return new SnippetTemplate(runtime, assumptions, target, key);
-                    }
-                });
-                // System.out.println(key + " -> " + template);
-                templates.put(key, template);
-            }
-            return template;
-        }
-    }
-
-    public abstract static class AbstractTemplates<T extends SnippetsInterface> {
-
-        protected final Cache cache;
-        protected final MetaAccessProvider runtime;
-        protected final Assumptions assumptions;
-        protected Class<?> snippetsClass;
-
-        public AbstractTemplates(MetaAccessProvider runtime, Assumptions assumptions, TargetDescription target, Class<T> snippetsClass) {
-            this.runtime = runtime;
-            this.assumptions = assumptions;
-            if (snippetsClass == null) {
-                assert this instanceof SnippetsInterface;
-                this.snippetsClass = getClass();
-            } else {
-                this.snippetsClass = snippetsClass;
-            }
-            this.cache = new Cache(runtime, target);
-        }
-
-        protected ResolvedJavaMethod snippet(String name, Class<?>... parameterTypes) {
-            try {
-                ResolvedJavaMethod snippet = runtime.lookupJavaMethod(snippetsClass.getDeclaredMethod(name, parameterTypes));
-                assert snippet.getAnnotation(Snippet.class) != null : "snippet is not annotated with @" + Snippet.class.getSimpleName();
-                return snippet;
-            } catch (NoSuchMethodException e) {
-                throw new GraalInternalError(e);
-            }
-        }
-    }
-
-    private static final Object UNUSED_PARAMETER = "DEAD PARAMETER";
-
-    /**
-     * Determines if any parameter of a given method is annotated with {@link ConstantParameter}.
-     */
-    public static boolean hasConstantParameter(ResolvedJavaMethod method) {
-        for (ConstantParameter p : MetaUtil.getParameterAnnotations(ConstantParameter.class, method)) {
-            if (p != null) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Creates a snippet template.
-     */
-    public SnippetTemplate(MetaAccessProvider runtime, Assumptions assumptions, TargetDescription target, SnippetTemplate.Key key) {
-        ResolvedJavaMethod method = key.method;
-        assert Modifier.isStatic(method.getModifiers()) : "snippet method must be static: " + method;
-        Signature signature = method.getSignature();
-
-        // Copy snippet graph, replacing constant parameters with given arguments
-        StructuredGraph snippetGraph = (StructuredGraph) method.getCompilerStorage().get(Graph.class);
-        StructuredGraph snippetCopy = new StructuredGraph(snippetGraph.name, snippetGraph.method());
-        IdentityHashMap<Node, Node> replacements = new IdentityHashMap<>();
-        replacements.put(snippetGraph.start(), snippetCopy.start());
-
-        int parameterCount = signature.getParameterCount(false);
-        assert checkTemplate(runtime, key, parameterCount, method, signature);
-
-        Parameter[] parameterAnnotations = new Parameter[parameterCount];
-        VarargsParameter[] varargsParameterAnnotations = new VarargsParameter[parameterCount];
-        ConstantNode[] placeholders = new ConstantNode[parameterCount];
-        for (int i = 0; i < parameterCount; i++) {
-            ConstantParameter c = MetaUtil.getParameterAnnotation(ConstantParameter.class, i, method);
-            if (c != null) {
-                String name = c.value();
-                Object arg = key.get(name);
-                Kind kind = signature.getParameterKind(i);
-                Constant constantArg;
-                if (arg instanceof Constant) {
-                    constantArg = (Constant) arg;
-                } else {
-                    constantArg = Constant.forBoxed(kind, arg);
-                }
-                replacements.put(snippetGraph.getLocal(i), ConstantNode.forConstant(constantArg, runtime, snippetCopy));
-            } else {
-                VarargsParameter vp = MetaUtil.getParameterAnnotation(VarargsParameter.class, i, method);
-                if (vp != null) {
-                    String name = vp.value();
-                    Varargs varargs = (Varargs) key.get(name);
-                    Object array = varargs.getArray();
-                    ConstantNode placeholder = ConstantNode.forObject(array, runtime, snippetCopy);
-                    replacements.put(snippetGraph.getLocal(i), placeholder);
-                    placeholders[i] = placeholder;
-                    varargsParameterAnnotations[i] = vp;
-                } else {
-                    parameterAnnotations[i] = MetaUtil.getParameterAnnotation(Parameter.class, i, method);
-                }
-            }
-        }
-        snippetCopy.addDuplicates(snippetGraph.getNodes(), replacements);
-
-        Debug.dump(snippetCopy, "Before specialization");
-        if (!replacements.isEmpty()) {
-            // Do deferred intrinsification of node intrinsics
-            new SnippetIntrinsificationPhase(runtime, new BoxingMethodPool(runtime)).apply(snippetCopy);
-            new WordTypeRewriterPhase(runtime, target.wordKind).apply(snippetCopy);
-
-            new CanonicalizerPhase(runtime, assumptions, 0, null).apply(snippetCopy);
-        }
-        assert SnippetIntrinsificationVerificationPhase.verify(snippetCopy);
-
-        // Gather the template parameters
-        parameters = new HashMap<>();
-        for (int i = 0; i < parameterCount; i++) {
-            VarargsParameter vp = varargsParameterAnnotations[i];
-            if (vp != null) {
-                assert snippetCopy.getLocal(i) == null;
-                Varargs varargs = (Varargs) key.get(vp.value());
-                Object array = varargs.getArray();
-                int length = Array.getLength(array);
-                LocalNode[] locals = new LocalNode[length];
-                Stamp stamp = varargs.getArgStamp();
-                for (int j = 0; j < length; j++) {
-                    assert (parameterCount & 0xFFFF) == parameterCount;
-                    int idx = i << 16 | j;
-                    LocalNode local = snippetCopy.unique(new LocalNode(idx, stamp));
-                    locals[j] = local;
-                }
-                parameters.put(vp.value(), locals);
-
-                ConstantNode placeholder = placeholders[i];
-                assert placeholder != null;
-                for (Node usage : placeholder.usages().snapshot()) {
-                    if (usage instanceof LoadIndexedNode) {
-                        LoadIndexedNode loadIndexed = (LoadIndexedNode) usage;
-                        Debug.dump(snippetCopy, "Before replacing %s", loadIndexed);
-                        LoadSnippetVarargParameterNode loadSnippetParameter = snippetCopy.add(new LoadSnippetVarargParameterNode(locals, loadIndexed.index(), loadIndexed.stamp()));
-                        snippetCopy.replaceFixedWithFixed(loadIndexed, loadSnippetParameter);
-                        Debug.dump(snippetCopy, "After replacing %s", loadIndexed);
-                    }
-                }
-            } else {
-                Parameter p = parameterAnnotations[i];
-                if (p != null) {
-                    LocalNode local = snippetCopy.getLocal(i);
-                    if (local == null) {
-                        // Parameter value was eliminated
-                        parameters.put(p.value(), UNUSED_PARAMETER);
-                    } else {
-                        parameters.put(p.value(), local);
-                    }
-                }
-            }
-        }
-
-        // Do any required loop explosion
-        boolean exploded = false;
-        do {
-            exploded = false;
-            ExplodeLoopNode explodeLoop = snippetCopy.getNodes().filter(ExplodeLoopNode.class).first();
-            if (explodeLoop != null) { // Earlier canonicalization may have removed the loop
-                                       // altogether
-                LoopBeginNode loopBegin = explodeLoop.findLoopBegin();
-                if (loopBegin != null) {
-                    LoopEx loop = new LoopsData(snippetCopy).loop(loopBegin);
-                    int mark = snippetCopy.getMark();
-                    LoopTransformations.fullUnroll(loop, runtime, null);
-                    new CanonicalizerPhase(runtime, assumptions, mark, null).apply(snippetCopy);
-                }
-                FixedNode explodeLoopNext = explodeLoop.next();
-                explodeLoop.clearSuccessors();
-                explodeLoop.replaceAtPredecessor(explodeLoopNext);
-                explodeLoop.replaceAtUsages(null);
-                GraphUtil.killCFG(explodeLoop);
-                exploded = true;
-            }
-        } while (exploded);
-
-        // Remove all frame states from inlined snippet graph. Snippets must be atomic (i.e. free
-        // of side-effects that prevent deoptimizing to a point before the snippet).
-        ArrayList<StateSplit> curSideEffectNodes = new ArrayList<>();
-        ArrayList<ValueNode> curStampNodes = new ArrayList<>();
-        for (Node node : snippetCopy.getNodes()) {
-            if (node instanceof ValueNode && ((ValueNode) node).stamp() == StampFactory.forNodeIntrinsic()) {
-                curStampNodes.add((ValueNode) node);
-            }
-            if (node instanceof StateSplit) {
-                StateSplit stateSplit = (StateSplit) node;
-                FrameState frameState = stateSplit.stateAfter();
-                if (stateSplit.hasSideEffect()) {
-                    curSideEffectNodes.add((StateSplit) node);
-                }
-                if (frameState != null) {
-                    stateSplit.setStateAfter(null);
-                }
-            }
-        }
-
-        new DeadCodeEliminationPhase().apply(snippetCopy);
-
-        assert checkAllVarargPlaceholdersAreDeleted(parameterCount, placeholders);
-
-        this.snippet = snippetCopy;
-        ReturnNode retNode = null;
-        StartNode entryPointNode = snippet.start();
-
-        new DeadCodeEliminationPhase().apply(snippetCopy);
-
-        nodes = new ArrayList<>(snippet.getNodeCount());
-        for (Node node : snippet.getNodes()) {
-            if (node == entryPointNode || node == entryPointNode.stateAfter()) {
-                // Do nothing.
-            } else {
-                nodes.add(node);
-                if (node instanceof ReturnNode) {
-                    retNode = (ReturnNode) node;
-                }
-            }
-        }
-
-        this.sideEffectNodes = curSideEffectNodes;
-        this.stampNodes = curStampNodes;
-        this.returnNode = retNode;
-    }
-
-    private static boolean checkAllVarargPlaceholdersAreDeleted(int parameterCount, ConstantNode[] placeholders) {
-        for (int i = 0; i < parameterCount; i++) {
-            if (placeholders[i] != null) {
-                assert placeholders[i].isDeleted() : placeholders[i];
-            }
-        }
-        return true;
-    }
-
-    private static boolean checkConstantArgument(MetaAccessProvider runtime, final ResolvedJavaMethod method, Signature signature, int i, String name, Object arg, Kind kind) {
-        ResolvedJavaType type = signature.getParameterType(i, method.getDeclaringClass()).resolve(method.getDeclaringClass());
-        if (runtime.lookupJavaType(WordBase.class).isAssignableFrom(type)) {
-            assert arg instanceof Constant : method + ": word constant parameters must be passed boxed in a Constant value: " + arg;
-            return true;
-        }
-        if (kind == Kind.Object) {
-            assert arg == null || type.isInstance(Constant.forObject(arg)) : method + ": wrong value type for " + name + ": expected " + type.getName() + ", got " + arg.getClass().getName();
-        } else {
-            assert arg != null && kind.toBoxedJavaClass() == arg.getClass() : method + ": wrong value kind for " + name + ": expected " + kind + ", got " +
-                            (arg == null ? "null" : arg.getClass().getSimpleName());
-        }
-        return true;
-    }
-
-    private static boolean checkVarargs(final ResolvedJavaMethod method, Signature signature, int i, String name, Varargs varargs) {
-        Object arg = varargs.getArray();
-        ResolvedJavaType type = (ResolvedJavaType) signature.getParameterType(i, method.getDeclaringClass());
-        assert type.isArray() : "varargs parameter must be an array type";
-        assert type.isInstance(Constant.forObject(arg)) : "value for " + name + " is not a " + MetaUtil.toJavaName(type) + " instance: " + arg;
-        return true;
-    }
-
-    /**
-     * The graph built from the snippet method.
-     */
-    private final StructuredGraph snippet;
-
-    /**
-     * The named parameters of this template that must be bound to values during instantiation. For
-     * a parameter that is still live after specialization, the value in this map is either a
-     * {@link LocalNode} instance or a {@link LocalNode} array. For an eliminated parameter, the
-     * value is identical to the key.
-     */
-    private final Map<String, Object> parameters;
-
-    /**
-     * The return node (if any) of the snippet.
-     */
-    private final ReturnNode returnNode;
-
-    /**
-     * Nodes that inherit the {@link StateSplit#stateAfter()} from the replacee during
-     * instantiation.
-     */
-    private final ArrayList<StateSplit> sideEffectNodes;
-
-    /**
-     * The nodes that inherit the {@link ValueNode#stamp()} from the replacee during instantiation.
-     */
-    private final ArrayList<ValueNode> stampNodes;
-
-    /**
-     * The nodes to be inlined when this specialization is instantiated.
-     */
-    private final ArrayList<Node> nodes;
-
-    /**
-     * Gets the instantiation-time bindings to this template's parameters.
-     * 
-     * @return the map that will be used to bind arguments to parameters when inlining this template
-     */
-    private IdentityHashMap<Node, Node> bind(StructuredGraph replaceeGraph, MetaAccessProvider runtime, SnippetTemplate.Arguments args) {
-        IdentityHashMap<Node, Node> replacements = new IdentityHashMap<>();
-        assert args.length() == parameters.size() : "number of args (" + args.length() + ") != number of parameters (" + parameters.size() + ")";
-        for (Map.Entry<String, Object> e : args) {
-            String name = e.getKey();
-            Object parameter = parameters.get(name);
-            assert parameter != null : this + " has no parameter named " + name;
-            Object argument = e.getValue();
-            if (parameter instanceof LocalNode) {
-                if (argument instanceof ValueNode) {
-                    replacements.put((LocalNode) parameter, (ValueNode) argument);
-                } else {
-                    Kind kind = ((LocalNode) parameter).kind();
-                    assert argument != null || kind == Kind.Object : this + " cannot accept null for non-object parameter named " + name;
-                    Constant constant = Constant.forBoxed(kind, argument);
-                    replacements.put((LocalNode) parameter, ConstantNode.forConstant(constant, runtime, replaceeGraph));
-                }
-            } else if (parameter instanceof LocalNode[]) {
-                LocalNode[] locals = (LocalNode[]) parameter;
-                int length = locals.length;
-                List list = null;
-                Object array = null;
-                if (argument instanceof List) {
-                    list = (List) argument;
-                    assert list.size() == length : length + " != " + list.size();
-                } else {
-                    array = argument;
-                    assert array != null && array.getClass().isArray();
-                    assert Array.getLength(array) == length : length + " != " + Array.getLength(array);
-                }
-
-                for (int j = 0; j < length; j++) {
-                    LocalNode local = locals[j];
-                    assert local != null;
-                    Object value = list != null ? list.get(j) : Array.get(array, j);
-                    if (value instanceof ValueNode) {
-                        replacements.put(local, (ValueNode) value);
-                    } else {
-                        Constant constant = Constant.forBoxed(local.kind(), value);
-                        ConstantNode element = ConstantNode.forConstant(constant, runtime, replaceeGraph);
-                        replacements.put(local, element);
-                    }
-                }
-            } else {
-                assert parameter == UNUSED_PARAMETER : "unexpected entry for parameter: " + name + " -> " + parameter;
-            }
-        }
-        return replacements;
-    }
-
-    /**
-     * Logic for replacing a snippet-lowered node at its usages with the return value of the
-     * snippet. An alternative to the {@linkplain SnippetTemplate#DEFAULT_REPLACER default}
-     * replacement logic can be used to handle mismatches between the stamp of the node being
-     * lowered and the stamp of the snippet's return value.
-     */
-    public interface UsageReplacer {
-
-        /**
-         * Replaces all usages of {@code oldNode} with direct or indirect usages of {@code newNode}.
-         */
-        void replace(ValueNode oldNode, ValueNode newNode);
-    }
-
-    /**
-     * Represents the default {@link UsageReplacer usage replacer} logic which simply delegates to
-     * {@link Node#replaceAtUsages(Node)}.
-     */
-    public static final UsageReplacer DEFAULT_REPLACER = new UsageReplacer() {
-
-        @Override
-        public void replace(ValueNode oldNode, ValueNode newNode) {
-            oldNode.replaceAtUsages(newNode);
-        }
-    };
-
-    /**
-     * Replaces a given fixed node with this specialized snippet.
-     * 
-     * @param runtime
-     * @param replacee the node that will be replaced
-     * @param replacer object that replaces the usages of {@code replacee}
-     * @param args the arguments to be bound to the flattened positional parameters of the snippet
-     * @return the map of duplicated nodes (original -> duplicate)
-     */
-    public Map<Node, Node> instantiate(MetaAccessProvider runtime, FixedNode replacee, UsageReplacer replacer, SnippetTemplate.Arguments args) {
-
-        // Inline the snippet nodes, replacing parameters with the given args in the process
-        String name = snippet.name == null ? "{copy}" : snippet.name + "{copy}";
-        StructuredGraph snippetCopy = new StructuredGraph(name, snippet.method());
-        StartNode entryPointNode = snippet.start();
-        FixedNode firstCFGNode = entryPointNode.next();
-        StructuredGraph replaceeGraph = (StructuredGraph) replacee.graph();
-        IdentityHashMap<Node, Node> replacements = bind(replaceeGraph, runtime, args);
-        Map<Node, Node> duplicates = replaceeGraph.addDuplicates(nodes, replacements);
-        Debug.dump(replaceeGraph, "After inlining snippet %s", snippetCopy.method());
-
-        // Re-wire the control flow graph around the replacee
-        FixedNode firstCFGNodeDuplicate = (FixedNode) duplicates.get(firstCFGNode);
-        replacee.replaceAtPredecessor(firstCFGNodeDuplicate);
-        FixedNode next = null;
-        if (replacee instanceof FixedWithNextNode) {
-            FixedWithNextNode fwn = (FixedWithNextNode) replacee;
-            next = fwn.next();
-            fwn.setNext(null);
-        }
-
-        if (replacee instanceof StateSplit) {
-            for (StateSplit sideEffectNode : sideEffectNodes) {
-                assert ((StateSplit) replacee).hasSideEffect();
-                Node sideEffectDup = duplicates.get(sideEffectNode);
-                ((StateSplit) sideEffectDup).setStateAfter(((StateSplit) replacee).stateAfter());
-            }
-        }
-        for (ValueNode stampNode : stampNodes) {
-            Node stampDup = duplicates.get(stampNode);
-            ((ValueNode) stampDup).setStamp(((ValueNode) replacee).stamp());
-        }
-
-        // Replace all usages of the replacee with the value returned by the snippet
-        ValueNode returnValue = null;
-        if (returnNode != null) {
-            if (returnNode.result() instanceof LocalNode) {
-                returnValue = (ValueNode) replacements.get(returnNode.result());
-            } else {
-                returnValue = (ValueNode) duplicates.get(returnNode.result());
-            }
-            assert returnValue != null || replacee.usages().isEmpty();
-            replacer.replace(replacee, returnValue);
-
-            Node returnDuplicate = duplicates.get(returnNode);
-            if (returnDuplicate.isAlive()) {
-                returnDuplicate.clearInputs();
-                returnDuplicate.replaceAndDelete(next);
-            }
-        }
-
-        // Remove the replacee from its graph
-        replacee.clearInputs();
-        replacee.replaceAtUsages(null);
-        GraphUtil.killCFG(replacee);
-
-        Debug.dump(replaceeGraph, "After lowering %s with %s", replacee, this);
-        return duplicates;
-    }
-
-    /**
-     * Gets a copy of the specialized graph.
-     */
-    public StructuredGraph copySpecializedGraph() {
-        return snippet.copy();
-    }
-
-    /**
-     * Replaces a given floating node with this specialized snippet.
-     * 
-     * @param runtime
-     * @param replacee the node that will be replaced
-     * @param replacer object that replaces the usages of {@code replacee}
-     * @param args the arguments to be bound to the flattened positional parameters of the snippet
-     */
-    public void instantiate(MetaAccessProvider runtime, FloatingNode replacee, UsageReplacer replacer, LoweringTool tool, SnippetTemplate.Arguments args) {
-
-        // Inline the snippet nodes, replacing parameters with the given args in the process
-        String name = snippet.name == null ? "{copy}" : snippet.name + "{copy}";
-        StructuredGraph snippetCopy = new StructuredGraph(name, snippet.method());
-        StartNode entryPointNode = snippet.start();
-        FixedNode firstCFGNode = entryPointNode.next();
-        StructuredGraph replaceeGraph = (StructuredGraph) replacee.graph();
-        IdentityHashMap<Node, Node> replacements = bind(replaceeGraph, runtime, args);
-        Map<Node, Node> duplicates = replaceeGraph.addDuplicates(nodes, replacements);
-        Debug.dump(replaceeGraph, "After inlining snippet %s", snippetCopy.method());
-
-        FixedWithNextNode lastFixedNode = tool.lastFixedNode();
-        assert lastFixedNode != null && lastFixedNode.isAlive() : replaceeGraph;
-        FixedNode next = lastFixedNode.next();
-        lastFixedNode.setNext(null);
-        FixedNode firstCFGNodeDuplicate = (FixedNode) duplicates.get(firstCFGNode);
-        replaceeGraph.addAfterFixed(lastFixedNode, firstCFGNodeDuplicate);
-
-        if (replacee instanceof StateSplit) {
-            for (StateSplit sideEffectNode : sideEffectNodes) {
-                assert ((StateSplit) replacee).hasSideEffect();
-                Node sideEffectDup = duplicates.get(sideEffectNode);
-                ((StateSplit) sideEffectDup).setStateAfter(((StateSplit) replacee).stateAfter());
-            }
-        }
-        for (ValueNode stampNode : stampNodes) {
-            Node stampDup = duplicates.get(stampNode);
-            ((ValueNode) stampDup).setStamp(((ValueNode) replacee).stamp());
-        }
-
-        // Replace all usages of the replacee with the value returned by the snippet
-        assert returnNode != null : replaceeGraph;
-        ValueNode returnValue = null;
-        if (returnNode.result() instanceof LocalNode) {
-            returnValue = (ValueNode) replacements.get(returnNode.result());
-        } else {
-            returnValue = (ValueNode) duplicates.get(returnNode.result());
-        }
-        assert returnValue != null || replacee.usages().isEmpty();
-        replacer.replace(replacee, returnValue);
-
-        tool.setLastFixedNode(null);
-        Node returnDuplicate = duplicates.get(returnNode);
-        if (returnDuplicate.isAlive()) {
-            returnDuplicate.clearInputs();
-            returnDuplicate.replaceAndDelete(next);
-            if (next != null && next.predecessor() instanceof FixedWithNextNode) {
-                tool.setLastFixedNode((FixedWithNextNode) next.predecessor());
-            }
-        }
-
-        Debug.dump(replaceeGraph, "After lowering %s with %s", replacee, this);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder buf = new StringBuilder(snippet.toString()).append('(');
-        String sep = "";
-        for (Map.Entry<String, Object> e : parameters.entrySet()) {
-            String name = e.getKey();
-            Object value = e.getValue();
-            buf.append(sep);
-            sep = ", ";
-            if (value == UNUSED_PARAMETER) {
-                buf.append("<unused> ").append(name);
-            } else if (value instanceof LocalNode) {
-                LocalNode local = (LocalNode) value;
-                buf.append(local.kind().getJavaName()).append(' ').append(name);
-            } else {
-                LocalNode[] locals = (LocalNode[]) value;
-                String kind = locals.length == 0 ? "?" : locals[0].kind().getJavaName();
-                buf.append(kind).append('[').append(locals.length).append("] ").append(name);
-            }
-        }
-        return buf.append(')').toString();
-    }
-
-    private static boolean checkTemplate(MetaAccessProvider runtime, SnippetTemplate.Key key, int parameterCount, ResolvedJavaMethod method, Signature signature) {
-        Set<String> expected = new HashSet<>();
-        for (int i = 0; i < parameterCount; i++) {
-            ConstantParameter c = MetaUtil.getParameterAnnotation(ConstantParameter.class, i, method);
-            VarargsParameter vp = MetaUtil.getParameterAnnotation(VarargsParameter.class, i, method);
-            Parameter p = MetaUtil.getParameterAnnotation(Parameter.class, i, method);
-            if (c != null) {
-                assert vp == null && p == null;
-                String name = c.value();
-                expected.add(name);
-                Kind kind = signature.getParameterKind(i);
-                assert key.names().contains(name) : "key for " + method + " is missing \"" + name + "\": " + key;
-                assert checkConstantArgument(runtime, method, signature, i, c.value(), key.get(name), kind);
-            } else if (vp != null) {
-                assert p == null;
-                String name = vp.value();
-                expected.add(name);
-                assert key.names().contains(name) : "key for " + method + " is missing \"" + name + "\": " + key;
-                assert key.get(name) instanceof Varargs;
-                Varargs varargs = (Varargs) key.get(name);
-                assert checkVarargs(method, signature, i, name, varargs);
-            } else {
-                assert p != null : method + ": parameter " + i + " must be annotated with exactly one of " + "@" + ConstantParameter.class.getSimpleName() + " or " + "@" +
-                                VarargsParameter.class.getSimpleName() + " or " + "@" + Parameter.class.getSimpleName();
-            }
-        }
-        if (!key.names().containsAll(expected)) {
-            expected.removeAll(key.names());
-            assert false : expected + " missing from key " + key;
-        }
-        if (!expected.containsAll(key.names())) {
-            Set<String> namesCopy = new HashSet<>(key.names());
-            namesCopy.removeAll(expected);
-            assert false : "parameter(s) " + namesCopy + " should be annotated with @" + ConstantParameter.class.getSimpleName() + " or @" + VarargsParameter.class.getSimpleName() + " in " +
-                            MetaUtil.format("%H.%n(%p)", method);
-        }
-        return true;
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetsInterface.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2011, 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.snippets;
-
-/**
- * Tagging interface for interfaces or classes providing snippets.
- */
-public interface SnippetsInterface {
-
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/UnsafeSubstitutions.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,383 +0,0 @@
-/*
- * Copyright (c) 2011, 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.snippets;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution;
-import com.oracle.graal.snippets.nodes.*;
-
-/**
- * Substitutions for {@link sun.misc.Unsafe} methods.
- */
-@ClassSubstitution(sun.misc.Unsafe.class)
-public class UnsafeSubstitutions {
-
-    @MethodSubstitution(isStatic = false)
-    public static boolean compareAndSwapObject(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, Object expected, Object x) {
-        return CompareAndSwapNode.compareAndSwap(o, 0, offset, expected, x);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static boolean compareAndSwapInt(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, int expected, int x) {
-        return CompareAndSwapNode.compareAndSwap(o, 0, offset, expected, x);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static boolean compareAndSwapLong(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, long expected, long x) {
-        return CompareAndSwapNode.compareAndSwap(o, 0, offset, expected, x);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static Object getObject(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
-        return UnsafeLoadNode.load(o, 0, offset, Kind.Object);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static Object getObjectVolatile(final Object thisObj, Object o, long offset) {
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
-        Object result = getObject(thisObj, o, offset);
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
-        return result;
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putObject(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, Object x) {
-        UnsafeStoreNode.store(o, 0, offset, x, Kind.Object);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putObjectVolatile(final Object thisObj, Object o, long offset, Object x) {
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
-        putObject(thisObj, o, offset, x);
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putOrderedObject(final Object thisObj, Object o, long offset, Object x) {
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
-        putObject(thisObj, o, offset, x);
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static int getInt(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
-        Integer value = UnsafeLoadNode.load(o, 0, offset, Kind.Int);
-        return value;
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static int getIntVolatile(final Object thisObj, Object o, long offset) {
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
-        int result = getInt(thisObj, o, offset);
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
-        return result;
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putInt(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, int x) {
-        UnsafeStoreNode.store(o, 0, offset, x, Kind.Int);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putIntVolatile(final Object thisObj, Object o, long offset, int x) {
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
-        putInt(thisObj, o, offset, x);
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putOrderedInt(final Object thisObj, Object o, long offset, int x) {
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
-        putInt(thisObj, o, offset, x);
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static boolean getBoolean(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
-        @JavacBug(id = 6995200)
-        Boolean result = UnsafeLoadNode.load(o, 0, offset, Kind.Boolean);
-        return result;
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static boolean getBooleanVolatile(final Object thisObj, Object o, long offset) {
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
-        boolean result = getBoolean(thisObj, o, offset);
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
-        return result;
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putBoolean(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, boolean x) {
-        UnsafeStoreNode.store(o, 0, offset, x, Kind.Boolean);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putBooleanVolatile(final Object thisObj, Object o, long offset, boolean x) {
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
-        putBoolean(thisObj, o, offset, x);
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static byte getByte(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
-        @JavacBug(id = 6995200)
-        Byte result = UnsafeLoadNode.load(o, 0, offset, Kind.Byte);
-        return result;
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static byte getByteVolatile(final Object thisObj, Object o, long offset) {
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
-        byte result = getByte(thisObj, o, offset);
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
-        return result;
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putByte(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, byte x) {
-        UnsafeStoreNode.store(o, 0, offset, x, Kind.Byte);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putByteVolatile(final Object thisObj, Object o, long offset, byte x) {
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
-        putByte(thisObj, o, offset, x);
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static short getShort(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
-        @JavacBug(id = 6995200)
-        Short result = UnsafeLoadNode.load(o, 0, offset, Kind.Short);
-        return result;
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static short getShortVolatile(final Object thisObj, Object o, long offset) {
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
-        short result = getShort(thisObj, o, offset);
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
-        return result;
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putShort(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, short x) {
-        UnsafeStoreNode.store(o, 0, offset, x, Kind.Short);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putShortVolatile(final Object thisObj, Object o, long offset, short x) {
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
-        putShort(thisObj, o, offset, x);
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static char getChar(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
-        @JavacBug(id = 6995200)
-        Character result = UnsafeLoadNode.load(o, 0, offset, Kind.Char);
-        return result;
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static char getCharVolatile(final Object thisObj, Object o, long offset) {
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
-        char result = getChar(thisObj, o, offset);
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
-        return result;
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putChar(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, char x) {
-        UnsafeStoreNode.store(o, 0, offset, x, Kind.Char);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putCharVolatile(final Object thisObj, Object o, long offset, char x) {
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
-        putChar(thisObj, o, offset, x);
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static long getLong(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
-        @JavacBug(id = 6995200)
-        Long result = UnsafeLoadNode.load(o, 0, offset, Kind.Long);
-        return result;
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static long getLongVolatile(final Object thisObj, Object o, long offset) {
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
-        long result = getLong(thisObj, o, offset);
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
-        return result;
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putLong(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, long x) {
-        UnsafeStoreNode.store(o, 0, offset, x, Kind.Long);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putLongVolatile(final Object thisObj, Object o, long offset, long x) {
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
-        putLong(thisObj, o, offset, x);
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putOrderedLong(final Object thisObj, Object o, long offset, long x) {
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
-        putLong(thisObj, o, offset, x);
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static float getFloat(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
-        @JavacBug(id = 6995200)
-        Float result = UnsafeLoadNode.load(o, 0, offset, Kind.Float);
-        return result;
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static float getFloatVolatile(final Object thisObj, Object o, long offset) {
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
-        float result = getFloat(thisObj, o, offset);
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
-        return result;
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putFloat(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, float x) {
-        UnsafeStoreNode.store(o, 0, offset, x, Kind.Float);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putFloatVolatile(final Object thisObj, Object o, long offset, float x) {
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
-        putFloat(thisObj, o, offset, x);
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static double getDouble(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
-        @JavacBug(id = 6995200)
-        Double result = UnsafeLoadNode.load(o, 0, offset, Kind.Double);
-        return result;
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static double getDoubleVolatile(final Object thisObj, Object o, long offset) {
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
-        double result = getDouble(thisObj, o, offset);
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
-        return result;
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putDouble(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, double x) {
-        UnsafeStoreNode.store(o, 0, offset, x, Kind.Double);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putDoubleVolatile(final Object thisObj, Object o, long offset, double x) {
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
-        putDouble(thisObj, o, offset, x);
-        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putByte(@SuppressWarnings("unused") final Object thisObj, long address, byte value) {
-        DirectStoreNode.store(address, value, Kind.Byte);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putShort(@SuppressWarnings("unused") final Object thisObj, long address, short value) {
-        DirectStoreNode.store(address, value, Kind.Short);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putChar(@SuppressWarnings("unused") final Object thisObj, long address, char value) {
-        DirectStoreNode.store(address, value, Kind.Char);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putInt(@SuppressWarnings("unused") final Object thisObj, long address, int value) {
-        DirectStoreNode.store(address, value, Kind.Int);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putLong(@SuppressWarnings("unused") final Object thisObj, long address, long value) {
-        DirectStoreNode.store(address, value, Kind.Long);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putFloat(@SuppressWarnings("unused") final Object thisObj, long address, float value) {
-        DirectStoreNode.store(address, value, Kind.Float);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putDouble(@SuppressWarnings("unused") final Object thisObj, long address, double value) {
-        DirectStoreNode.store(address, value, Kind.Double);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static byte getByte(@SuppressWarnings("unused") final Object thisObj, long address) {
-        return DirectReadNode.read(address, Kind.Byte);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static short getShort(@SuppressWarnings("unused") final Object thisObj, long address) {
-        return DirectReadNode.read(address, Kind.Short);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static char getChar(@SuppressWarnings("unused") final Object thisObj, long address) {
-        return DirectReadNode.read(address, Kind.Char);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static int getInt(@SuppressWarnings("unused") final Object thisObj, long address) {
-        return DirectReadNode.read(address, Kind.Int);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static long getLong(@SuppressWarnings("unused") final Object thisObj, long address) {
-        return DirectReadNode.read(address, Kind.Long);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static float getFloat(@SuppressWarnings("unused") final Object thisObj, long address) {
-        return DirectReadNode.read(address, Kind.Float);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static double getDouble(@SuppressWarnings("unused") final Object thisObj, long address) {
-        return DirectReadNode.read(address, Kind.Double);
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/UnsignedMathSubstitutions.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-/*
- * Copyright (c) 2011, 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.snippets;
-
-import static com.oracle.graal.nodes.calc.ConditionalNode.*;
-import static com.oracle.graal.nodes.calc.Condition.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.snippets.ClassSubstitution.*;
-
-/**
- * Substitutions for {@link UnsignedMath}.
- */
-@ClassSubstitution(UnsignedMath.class)
-public class UnsignedMathSubstitutions {
-
-    @MethodSubstitution
-    public static boolean aboveThan(int a, int b) {
-        return materializeCondition(BT, b, a);
-    }
-
-    @MethodSubstitution
-    public static boolean aboveOrEqual(int a, int b) {
-        return !materializeCondition(BT, a, b);
-    }
-
-    /**
-     * Unsigned comparison belowThan for two numbers.
-     */
-    @MethodSubstitution
-    public static boolean belowThan(int a, int b) {
-        return materializeCondition(BT, a, b);
-    }
-
-    /**
-     * Unsigned comparison belowOrEqual for two numbers.
-     */
-    @MethodSubstitution
-    public static boolean belowOrEqual(int a, int b) {
-        return !materializeCondition(BT, b, a);
-    }
-
-    /**
-     * Unsigned comparison aboveThan for two numbers.
-     */
-    @MethodSubstitution
-    public static boolean aboveThan(long a, long b) {
-        return materializeCondition(BT, b, a);
-    }
-
-    /**
-     * Unsigned comparison aboveOrEqual for two numbers.
-     */
-    @MethodSubstitution
-    public static boolean aboveOrEqual(long a, long b) {
-        return !materializeCondition(BT, a, b);
-    }
-
-    /**
-     * Unsigned comparison belowThan for two numbers.
-     */
-    @MethodSubstitution
-    public static boolean belowThan(long a, long b) {
-        return materializeCondition(BT, a, b);
-    }
-
-    /**
-     * Unsigned comparison belowOrEqual for two numbers.
-     */
-    @MethodSubstitution
-    public static boolean belowOrEqual(long a, long b) {
-        return !materializeCondition(BT, b, a);
-    }
-
-    /**
-     * Unsigned division for two numbers.
-     */
-    @MethodSubstitution
-    public static int divide(int a, int b) {
-        return unsignedDivide(Kind.Int, a, b);
-    }
-
-    /**
-     * Unsigned remainder for two numbers.
-     */
-    @MethodSubstitution
-    public static int remainder(int a, int b) {
-        return unsignedRemainder(Kind.Int, a, b);
-    }
-
-    /**
-     * Unsigned division for two numbers.
-     */
-    @MethodSubstitution
-    public static long divide(long a, long b) {
-        return unsignedDivide(Kind.Long, a, b);
-    }
-
-    /**
-     * Unsigned remainder for two numbers.
-     */
-    @MethodSubstitution
-    public static long remainder(long a, long b) {
-        return unsignedRemainder(Kind.Long, a, b);
-    }
-
-    @NodeIntrinsic(UnsignedDivNode.class)
-    private static native int unsignedDivide(@ConstantNodeParameter Kind kind, int a, int b);
-
-    @NodeIntrinsic(UnsignedDivNode.class)
-    private static native long unsignedDivide(@ConstantNodeParameter Kind kind, long a, long b);
-
-    @NodeIntrinsic(UnsignedRemNode.class)
-    private static native int unsignedRemainder(@ConstantNodeParameter Kind kind, int a, int b);
-
-    @NodeIntrinsic(UnsignedRemNode.class)
-    private static native long unsignedRemainder(@ConstantNodeParameter Kind kind, long a, long b);
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitCountNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets.nodes;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.gen.*;
-import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-
-public class BitCountNode extends FloatingNode implements LIRGenLowerable, Canonicalizable {
-
-    @Input private ValueNode value;
-
-    public BitCountNode(ValueNode value) {
-        super(StampFactory.forInteger(Kind.Int, 0, value.kind().getBitCount()));
-        this.value = value;
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        if (value.isConstant()) {
-            long v = value.asConstant().asLong();
-            if (value.kind().getStackKind() == Kind.Int) {
-                return ConstantNode.forInt(Integer.bitCount((int) v), graph());
-            } else if (value.kind() == Kind.Long) {
-                return ConstantNode.forInt(Long.bitCount(v), graph());
-            }
-        }
-        return this;
-    }
-
-    @NodeIntrinsic
-    public static native int bitCount(int v);
-
-    @NodeIntrinsic
-    public static native int bitCount(long v);
-
-    @Override
-    public void generate(LIRGenerator gen) {
-        Variable result = gen.newVariable(Kind.Int);
-        gen.emitBitCount(result, gen.operand(value));
-        gen.setResult(this, result);
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanForwardNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets.nodes;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.gen.*;
-import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-
-public class BitScanForwardNode extends FloatingNode implements LIRGenLowerable, Canonicalizable {
-
-    @Input private ValueNode value;
-
-    public BitScanForwardNode(ValueNode value) {
-        super(StampFactory.forInteger(Kind.Int, 0, value.kind().getBitCount()));
-        this.value = value;
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        if (value.isConstant()) {
-            long v = value.asConstant().asLong();
-            if (value.kind().getStackKind() == Kind.Int) {
-                return ConstantNode.forInt(Integer.numberOfTrailingZeros((int) v), graph());
-            } else if (value.kind() == Kind.Long) {
-                return ConstantNode.forInt(Long.numberOfTrailingZeros(v), graph());
-            }
-        }
-        return this;
-    }
-
-    @NodeIntrinsic
-    public static native int scan(long v);
-
-    @Override
-    public void generate(LIRGenerator gen) {
-        Variable result = gen.newVariable(Kind.Int);
-        gen.emitBitScanForward(result, gen.operand(value));
-        gen.setResult(this, result);
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanReverseNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets.nodes;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.gen.*;
-import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-
-public class BitScanReverseNode extends FloatingNode implements LIRGenLowerable, Canonicalizable {
-
-    @Input private ValueNode value;
-
-    public BitScanReverseNode(ValueNode value) {
-        super(StampFactory.forInteger(Kind.Int, 0, value.kind().getBitCount()));
-        this.value = value;
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        if (value.isConstant()) {
-            long v = value.asConstant().asLong();
-            if (value.kind().getStackKind() == Kind.Int) {
-                return ConstantNode.forInt(31 - Integer.numberOfLeadingZeros((int) v), graph());
-            } else if (value.kind() == Kind.Long) {
-                return ConstantNode.forInt(63 - Long.numberOfLeadingZeros(v), graph());
-            }
-        }
-        return this;
-    }
-
-    @NodeIntrinsic
-    public static native int scan(int v);
-
-    @NodeIntrinsic
-    public static native int scan(long v);
-
-    @Override
-    public void generate(LIRGenerator gen) {
-        Variable result = gen.newVariable(Kind.Int);
-        gen.emitBitScanReverse(result, gen.operand(value));
-        gen.setResult(this, result);
-    }
-
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BranchProbabilityNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- * 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.snippets.nodes;
-
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.nodes.util.*;
-
-/**
- * Instances of this node class will look for a preceding if node and put the given probability into
- * the if node's taken probability. Then the branch probability node will be removed. This node is
- * intended primarily for snippets, so that they can define their fast and slow paths.
- */
-public class BranchProbabilityNode extends FixedWithNextNode implements Simplifiable {
-
-    public static final double LIKELY_PROBABILITY = 0.6;
-    public static final double NOT_LIKELY_PROBABILITY = 1 - LIKELY_PROBABILITY;
-
-    public static final double FREQUENT_PROBABILITY = 0.9;
-    public static final double NOT_FREQUENT_PROBABILITY = 1 - FREQUENT_PROBABILITY;
-
-    public static final double FAST_PATH_PROBABILITY = 0.99;
-    public static final double SLOW_PATH_PROBABILITY = 1 - FAST_PATH_PROBABILITY;
-
-    public static final double NOT_DEOPT_PATH_PROBABILITY = 0.999;
-    public static final double DEOPT_PATH_PROBABILITY = 1 - NOT_DEOPT_PATH_PROBABILITY;
-
-    private final double probability;
-
-    public BranchProbabilityNode(double probability) {
-        super(StampFactory.forVoid());
-        assert probability >= 0 && probability <= 1;
-        this.probability = probability;
-    }
-
-    @Override
-    public void simplify(SimplifierTool tool) {
-        FixedNode current = this;
-        while (!(current instanceof BeginNode)) {
-            current = (FixedNode) current.predecessor();
-        }
-        BeginNode begin = (BeginNode) current;
-        assert begin.predecessor() instanceof IfNode : "explicit branch probability cannot follow a merge, only if nodes";
-        IfNode ifNode = (IfNode) begin.predecessor();
-        if (ifNode.trueSuccessor() == begin) {
-            ifNode.setTrueSuccessorProbability(probability);
-        } else {
-            ifNode.setTrueSuccessorProbability(1 - probability);
-        }
-
-        FixedNode next = next();
-        setNext(null);
-        ((FixedWithNextNode) predecessor()).setNext(next);
-        GraphUtil.killCFG(this);
-    }
-
-    @NodeIntrinsic
-    public static native void probability(@ConstantNodeParameter double probability);
-
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/DirectObjectStoreNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets.nodes;
-
-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.word.*;
-
-/**
- * A special purpose store node that differs from {@link UnsafeStoreNode} in that it is not a
- * {@link StateSplit} and does not include a write barrier.
- */
-public class DirectObjectStoreNode extends FixedWithNextNode implements Lowerable {
-
-    @Input private ValueNode object;
-    @Input private ValueNode value;
-    @Input private ValueNode offset;
-    private final int displacement;
-
-    public DirectObjectStoreNode(ValueNode object, int displacement, ValueNode offset, ValueNode value) {
-        super(StampFactory.forVoid());
-        this.object = object;
-        this.value = value;
-        this.offset = offset;
-        this.displacement = displacement;
-    }
-
-    @NodeIntrinsic
-    public static native void storeObject(Object obj, @ConstantNodeParameter int displacement, long offset, Object value);
-
-    @NodeIntrinsic
-    public static native void storeLong(Object obj, @ConstantNodeParameter int displacement, long offset, long value);
-
-    @NodeIntrinsic
-    public static native void storeWord(Object obj, @ConstantNodeParameter int displacement, long offset, Word value);
-
-    @NodeIntrinsic
-    public static native void storeInt(Object obj, @ConstantNodeParameter int displacement, long offset, int value);
-
-    @Override
-    public void lower(LoweringTool tool) {
-        StructuredGraph graph = (StructuredGraph) this.graph();
-        IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, value.kind(), displacement, offset, graph, 1);
-        WriteNode write = graph.add(new WriteNode(object, value, location));
-        graph.replaceFixedWithFixed(this, write);
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/DirectReadNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets.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.*;
-
-/**
- * A special purpose store node that differs from {@link UnsafeStoreNode} in that it is not a
- * {@link StateSplit} and takes a computed address instead of an object.
- */
-public class DirectReadNode extends FixedWithNextNode implements LIRLowerable {
-
-    @Input private ValueNode address;
-    private final Kind readKind;
-
-    public DirectReadNode(ValueNode address, Kind readKind) {
-        super(StampFactory.forKind(readKind));
-        this.address = address;
-        this.readKind = readKind;
-    }
-
-    @Override
-    public void generate(LIRGeneratorTool gen) {
-        gen.setResult(this, gen.emitLoad(readKind, gen.operand(address), 0, Value.ILLEGAL, 0, false));
-    }
-
-    @NodeIntrinsic
-    public static native <T> T read(long address, @ConstantNodeParameter Kind kind);
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/DirectStoreNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets.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.*;
-
-/**
- * A special purpose store node that differs from {@link UnsafeStoreNode} in that it is not a
- * {@link StateSplit} and takes a computed address instead of an object.
- */
-public class DirectStoreNode extends FixedWithNextNode implements LIRLowerable {
-
-    @Input private ValueNode address;
-    @Input private ValueNode value;
-    private final Kind kind;
-
-    public DirectStoreNode(ValueNode address, ValueNode value, Kind kind) {
-        super(StampFactory.forVoid());
-        this.address = address;
-        this.value = value;
-        this.kind = kind;
-    }
-
-    @Override
-    public void generate(LIRGeneratorTool gen) {
-        Value v = gen.operand(value);
-        gen.emitStore(kind, gen.operand(address), 0, Value.ILLEGAL, 0, v, false);
-    }
-
-    /*
-     * The kind of the store is provided explicitly in these intrinsics because it is not always
-     * possible to determine the kind from the given value during compilation (because stack kinds
-     * are used).
-     */
-
-    @NodeIntrinsic
-    public static native void store(long address, boolean value, @ConstantNodeParameter Kind kind);
-
-    @NodeIntrinsic
-    public static native void store(long address, byte value, @ConstantNodeParameter Kind kind);
-
-    @NodeIntrinsic
-    public static native void store(long address, short value, @ConstantNodeParameter Kind kind);
-
-    @NodeIntrinsic
-    public static native void store(long address, char value, @ConstantNodeParameter Kind kind);
-
-    @NodeIntrinsic
-    public static native void store(long address, int value, @ConstantNodeParameter Kind kind);
-
-    @NodeIntrinsic
-    public static native void store(long address, long value, @ConstantNodeParameter Kind kind);
-
-    @NodeIntrinsic
-    public static native void store(long address, float value, @ConstantNodeParameter Kind kind);
-
-    @NodeIntrinsic
-    public static native void store(long address, double value, @ConstantNodeParameter Kind kind);
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/ExplodeLoopNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets.nodes;
-
-import java.util.*;
-
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.snippets.Snippet.VarargsParameter;
-
-/**
- * Placeholder node to denote to snippet preparation that the following loop must be completely
- * unrolled.
- * 
- * @see VarargsParameter
- */
-public final class ExplodeLoopNode extends FixedWithNextNode {
-
-    public ExplodeLoopNode() {
-        super(StampFactory.forVoid());
-    }
-
-    public LoopBeginNode findLoopBegin() {
-        Node next = next();
-        ArrayList<Node> succs = new ArrayList<>();
-        while (!(next instanceof LoopBeginNode)) {
-            assert next != null : "cannot find loop after " + this;
-            for (Node n : next.cfgSuccessors()) {
-                succs.add(n);
-            }
-            if (succs.size() == 1) {
-                next = succs.get(0);
-            } else {
-                return null;
-            }
-        }
-        return (LoopBeginNode) next;
-    }
-
-    /**
-     * A call to this method must be placed immediately prior to the loop that is to be exploded.
-     */
-    @NodeIntrinsic
-    public static native void explodeLoop();
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/LoadSnippetVarargParameterNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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.snippets.nodes;
-
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.snippets.Snippet.VarargsParameter;
-
-/**
- * Implements the semantics of {@link VarargsParameter}.
- */
-public final class LoadSnippetVarargParameterNode extends FixedWithNextNode implements Canonicalizable {
-
-    @Input private ValueNode index;
-
-    private final LocalNode[] locals;
-
-    public LoadSnippetVarargParameterNode(LocalNode[] locals, ValueNode index, Stamp stamp) {
-        super(stamp);
-        this.index = index;
-        this.locals = locals;
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        if (index.isConstant()) {
-            return locals[index.asConstant().asInt()];
-        }
-        return this;
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/MacroNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +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.snippets.nodes;
-
-import java.lang.reflect.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.phases.common.*;
-
-public class MacroNode extends AbstractStateSplit implements Lowerable {
-
-    @Input protected final NodeInputList<ValueNode> arguments;
-
-    private final int bci;
-    private final ResolvedJavaMethod targetMethod;
-    private final JavaType returnType;
-
-    protected MacroNode(Invoke invoke) {
-        super(invoke.node().stamp(), invoke.stateAfter());
-        this.arguments = new NodeInputList<>(this, invoke.methodCallTarget().arguments());
-        this.bci = invoke.bci();
-        this.targetMethod = invoke.methodCallTarget().targetMethod();
-        this.returnType = invoke.methodCallTarget().returnType();
-    }
-
-    public int getBci() {
-        return bci;
-    }
-
-    public ResolvedJavaMethod getTargetMethod() {
-        return targetMethod;
-    }
-
-    @SuppressWarnings("unused")
-    protected StructuredGraph getSnippetGraph(LoweringTool tool) {
-        return null;
-    }
-
-    @Override
-    public void lower(LoweringTool tool) {
-        StructuredGraph snippetGraph = getSnippetGraph(tool);
-
-        InvokeNode invoke = replaceWithInvoke();
-
-        if (snippetGraph != null) {
-            InliningUtil.inline(invoke, snippetGraph, false);
-        }
-    }
-
-    private InvokeNode replaceWithInvoke() {
-        InvokeNode invoke = createInvoke();
-        ((StructuredGraph) graph()).replaceFixedWithFixed(this, invoke);
-        return invoke;
-    }
-
-    protected InvokeNode createInvoke() {
-        InvokeKind invokeKind = Modifier.isStatic(targetMethod.getModifiers()) ? InvokeKind.Static : InvokeKind.Special;
-        MethodCallTargetNode callTarget = graph().add(new MethodCallTargetNode(invokeKind, targetMethod, arguments.toArray(new ValueNode[arguments.size()]), returnType));
-        InvokeNode invoke = graph().add(new InvokeNode(callTarget, bci));
-        invoke.setStateAfter(stateAfter());
-        return invoke;
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/MathIntrinsicNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets.nodes;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.gen.*;
-import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-
-public class MathIntrinsicNode extends FloatingNode implements Canonicalizable, LIRGenLowerable {
-
-    @Input private ValueNode x;
-    private final Operation operation;
-
-    public enum Operation {
-        ABS, SQRT, LOG, LOG10, SIN, COS, TAN
-    }
-
-    public ValueNode x() {
-        return x;
-    }
-
-    public Operation operation() {
-        return operation;
-    }
-
-    public MathIntrinsicNode(ValueNode x, Operation op) {
-        super(StampFactory.forKind(x.kind()));
-        assert x.kind() == Kind.Double;
-        this.x = x;
-        this.operation = op;
-    }
-
-    @Override
-    public void generate(LIRGenerator gen) {
-        Variable input = gen.load(gen.operand(x()));
-        Variable result = gen.newVariable(kind());
-        switch (operation()) {
-            case ABS:
-                gen.emitMathAbs(result, input);
-                break;
-            case SQRT:
-                gen.emitMathSqrt(result, input);
-                break;
-            case LOG:
-                gen.emitMathLog(result, input, false);
-                break;
-            case LOG10:
-                gen.emitMathLog(result, input, true);
-                break;
-            case SIN:
-                gen.emitMathSin(result, input);
-                break;
-            case COS:
-                gen.emitMathCos(result, input);
-                break;
-            case TAN:
-                gen.emitMathTan(result, input);
-                break;
-            default:
-                throw GraalInternalError.shouldNotReachHere();
-        }
-        gen.setResult(this, result);
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        if (x().isConstant()) {
-            double value = x().asConstant().asDouble();
-            switch (operation()) {
-                case ABS:
-                    return ConstantNode.forDouble(Math.abs(value), graph());
-                case SQRT:
-                    return ConstantNode.forDouble(Math.sqrt(value), graph());
-                case LOG:
-                    return ConstantNode.forDouble(Math.log(value), graph());
-                case LOG10:
-                    return ConstantNode.forDouble(Math.log10(value), graph());
-                case SIN:
-                    return ConstantNode.forDouble(Math.sin(value), graph());
-                case COS:
-                    return ConstantNode.forDouble(Math.cos(value), graph());
-                case TAN:
-                    return ConstantNode.forDouble(Math.tan(value), graph());
-            }
-        }
-        return this;
-    }
-
-    @NodeIntrinsic
-    public static native double compute(double x, @ConstantNodeParameter Operation op);
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/ReadRegisterNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*
- * 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.snippets.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.graph.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.type.*;
-
-/**
- * Access the value of a specific register.
- */
-@NodeInfo(nameTemplate = "ReadRegister %{p#register}")
-public final class ReadRegisterNode extends FixedWithNextNode implements LIRGenLowerable {
-
-    /**
-     * The fixed register to access.
-     */
-    private final Register register;
-
-    /**
-     * When true, subsequent uses of this node use the fixed register; when false, the value is
-     * moved into a new virtual register so that the fixed register is not seen by uses.
-     */
-    private final boolean directUse;
-
-    /**
-     * When true, this node is also an implicit definition of the value for the register allocator,
-     * i.e., the register is an implicit incoming value; when false, the register must be defined in
-     * the same method or must be an register excluded from register allocation.
-     */
-    private final boolean incoming;
-
-    public ReadRegisterNode(Register register, Kind kind, boolean directUse, boolean incoming) {
-        super(StampFactory.forKind(kind));
-        this.register = register;
-        this.directUse = directUse;
-        this.incoming = incoming;
-    }
-
-    /**
-     * Constructor to be used by node intrinsics where the stamp is inferred from the intrinsic
-     * definition.
-     */
-    public ReadRegisterNode(Register register, boolean directUse, boolean incoming) {
-        super(StampFactory.forNodeIntrinsic());
-        this.register = register;
-        this.directUse = directUse;
-        this.incoming = incoming;
-    }
-
-    @Override
-    public void generate(LIRGenerator generator) {
-        Value result = register.asValue(kind());
-        if (incoming) {
-            generator.emitIncomingValues(new Value[]{result});
-        }
-        if (!directUse) {
-            result = generator.emitMove(result);
-        }
-        generator.setResult(this, result);
-    }
-
-    @Override
-    public String toString(Verbosity verbosity) {
-        if (verbosity == Verbosity.Name) {
-            return super.toString(Verbosity.Name) + "%" + register;
-        } else {
-            return super.toString(verbosity);
-        }
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/ReverseBytesNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets.nodes;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.gen.*;
-import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-
-public class ReverseBytesNode extends FloatingNode implements LIRGenLowerable, Canonicalizable {
-
-    @Input private ValueNode value;
-
-    public ReverseBytesNode(ValueNode value) {
-        super(StampFactory.forKind(value.kind()));
-        assert kind().getStackKind() == Kind.Int || kind() == Kind.Long;
-        this.value = value;
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        if (value.isConstant()) {
-            long v = value.asConstant().asLong();
-            if (kind().getStackKind() == Kind.Int) {
-                return ConstantNode.forInt(Integer.reverseBytes((int) v), graph());
-            } else if (kind() == Kind.Long) {
-                return ConstantNode.forLong(Long.reverseBytes(v), graph());
-            }
-        }
-        return this;
-    }
-
-    @NodeIntrinsic
-    public static native int reverse(int v);
-
-    @NodeIntrinsic
-    public static native long reverse(long v);
-
-    @Override
-    public void generate(LIRGenerator gen) {
-        Variable result = gen.newVariable(value.kind());
-        gen.emitByteSwap(result, gen.operand(value));
-        gen.setResult(this, result);
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/WriteRegisterNode.java	Thu Mar 21 13:12:36 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2013, 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.snippets.nodes;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-
-/**
- * Changes the value of a specific register.
- */
-@NodeInfo(nameTemplate = "WriteRegister %{p#register}")
-public final class WriteRegisterNode extends FixedWithNextNode implements LIRLowerable {
-
-    /**
-     * The fixed register to access.
-     */
-    private final Register register;
-
-    /**
-     * The new value assigned to the register.
-     */
-    @Input private ValueNode value;
-
-    public WriteRegisterNode(Register register, ValueNode value) {
-        super(StampFactory.forVoid());
-        this.register = register;
-        this.value = value;
-    }
-
-    @Override
-    public void generate(LIRGeneratorTool generator) {
-        Value val = generator.operand(value);
-        generator.emitMove(val, register.asValue(val.getKind()));
-    }
-
-    @Override
-    public String toString(Verbosity verbosity) {
-        if (verbosity == Verbosity.Name) {
-            return super.toString(Verbosity.Name) + "%" + register;
-        } else {
-            return super.toString(verbosity);
-        }
-    }
-}
--- a/make/build-graal.xml	Thu Mar 21 13:12:36 2013 +0100
+++ b/make/build-graal.xml	Thu Mar 21 13:13:07 2013 +0100
@@ -48,7 +48,7 @@
       <src path="${src.dir}/com.oracle.graal.bytecode"/>
       <src path="${src.dir}/com.oracle.graal.java"/>
       <src path="${src.dir}/com.oracle.graal.word"/>
-      <src path="${src.dir}/com.oracle.graal.snippets"/>
+      <src path="${src.dir}/com.oracle.graal.replacements"/>
       <src path="${src.dir}/com.oracle.graal.api.runtime"/>
       <src path="${src.dir}/com.oracle.graal.printer"/>
       <src path="${src.dir}/com.oracle.graal.hotspot"/>
@@ -56,7 +56,7 @@
       <src path="${src.dir}/com.oracle.graal.asm.amd64"/>
       <src path="${src.dir}/com.oracle.graal.lir.amd64"/>
       <src path="${src.dir}/com.oracle.graal.compiler.amd64"/>
-      <src path="${src.dir}/com.oracle.graal.snippets.amd64"/>
+      <src path="${src.dir}/com.oracle.graal.replacements.amd64"/>
       <src path="${src.dir}/com.oracle.graal.hotspot.amd64"/>
       <src path="${src.dir}/com.oracle.graal.sparc"/>
       <src path="${src.dir}/com.oracle.graal.asm.sparc"/>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mx/JUnitWrapper.java	Thu Mar 21 13:13:07 2013 +0100
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+
+/* Execute testcases by reading names from a given file, due to limits of
+ * the operating system regarding command line size (windows: 32k,
+ * linux [depending on the settings]: ~2097k)
+ * see http://msdn.microsoft.com/en-us/library/ms682425%28VS.85%29.aspx
+ */
+
+import org.junit.runner.*;
+import java.io.*;
+import java.util.*;
+
+public class JUnitWrapper {
+
+    /**
+     * @param args
+     *            args[0] is the path where to read the names of the testclasses.
+     */
+    public static void main(String[] args) {
+        if (args.length == 0) {
+            System.err.printf("wrong usage. provide a filename\n");
+            System.exit(1);
+        }
+        ArrayList<String> tests = new ArrayList<String>(1000);
+        BufferedReader br = null;
+        try {
+            br = new BufferedReader(new FileReader(args[0]));
+
+            String buf;
+            while ((buf = br.readLine()) != null) {
+                tests.add(buf);
+            }
+        } catch (IOException ioe) {
+            ioe.printStackTrace();
+            System.exit(2);
+        } finally {
+            try {
+                if (br != null) {
+                    br.close();
+                }
+            } catch (IOException ioe) {
+                ioe.printStackTrace();
+                System.exit(3);
+            }
+        }
+
+        String[] strargs = tests.toArray(new String[tests.size()]);
+        System.out.printf("executing junit tests now... (%d testclasses)\n", strargs.length);
+        JUnitCore.main(strargs);
+    }
+}
--- a/mx/commands.py	Thu Mar 21 13:12:36 2013 +0100
+++ b/mx/commands.py	Thu Mar 21 13:13:07 2013 +0100
@@ -27,7 +27,7 @@
 # ----------------------------------------------------------------------------------------------------
 
 import os, sys, shutil, zipfile, tempfile, re, time, datetime, platform, subprocess, multiprocessing
-from os.path import join, exists, dirname, basename
+from os.path import join, exists, dirname, basename, getmtime
 from argparse import ArgumentParser, REMAINDER
 import mx
 import sanitycheck
@@ -719,7 +719,7 @@
     matches = lambda line : len([a for a in annotations if line == a or line.startswith(a + '(')]) != 0
     return p.find_classes_with_matching_source_line(pkgRoot, matches, includeInnerClasses)
 
-def _run_tests(args, harness, annotations):
+def _run_tests(args, harness, annotations, testfile):
     pos = [a for a in args if a[0] != '-' and a[0] != '@' ]
     neg = [a[1:] for a in args if a[0] == '-']
     vmArgs = [a[1:] for a in args if a[0] == '@']
@@ -742,13 +742,27 @@
     projectscp = mx.classpath([pcp.name for pcp in mx.projects()])
 
     if len(classes) != 0:
-        harness(projectscp, vmArgs, classes)
+        f_testfile = open(testfile, 'w')
+        for c in classes:
+            f_testfile.write(c + '\n')
+        f_testfile.close()
+        harness(projectscp, vmArgs)
 
 def _unittest(args, annotations):
-    def harness(projectscp, vmArgs, classes):
+    mxdir = dirname(__file__)
+    name = 'JUnitWrapper'
+    javaSource = join(mxdir, name + '.java')
+    javaClass = join(mxdir, name + '.class')
+    (_, testfile) = tempfile.mkstemp(".testclasses", "graal")
+
+    def harness(projectscp, vmArgs):
+        if not exists(javaClass) or getmtime(javaClass) < getmtime(javaSource):
+            subprocess.check_call([mx.java().javac, '-cp', projectscp, '-d', mxdir, javaSource])
         prefixArgs = ['-XX:-BootstrapGraal', '-esa', '-ea']
-        vm(prefixArgs + vmArgs + ['-cp', projectscp, 'org.junit.runner.JUnitCore'] + classes)
-    _run_tests(args, harness, annotations)
+        vm(prefixArgs + vmArgs + ['-cp', projectscp + ':' + mxdir, name] + [testfile])
+
+    _run_tests(args, harness, annotations, testfile)
+    os.remove(testfile)
 
 def unittest(args):
     """run the JUnit tests (all testcases)
--- a/mx/projects	Thu Mar 21 13:12:36 2013 +0100
+++ b/mx/projects	Thu Mar 21 13:13:07 2013 +0100
@@ -82,14 +82,14 @@
 # graal.hotspot
 project@com.oracle.graal.hotspot@subDir=graal
 project@com.oracle.graal.hotspot@sourceDirs=src
-project@com.oracle.graal.hotspot@dependencies=com.oracle.graal.snippets,com.oracle.graal.api.runtime,com.oracle.graal.printer
+project@com.oracle.graal.hotspot@dependencies=com.oracle.graal.replacements,com.oracle.graal.api.runtime,com.oracle.graal.printer
 project@com.oracle.graal.hotspot@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.hotspot@javaCompliance=1.7
 
 # graal.hotspot.amd64
 project@com.oracle.graal.hotspot.amd64@subDir=graal
 project@com.oracle.graal.hotspot.amd64@sourceDirs=src
-project@com.oracle.graal.hotspot.amd64@dependencies=com.oracle.graal.hotspot,com.oracle.graal.compiler.amd64,com.oracle.graal.snippets.amd64
+project@com.oracle.graal.hotspot.amd64@dependencies=com.oracle.graal.hotspot,com.oracle.graal.compiler.amd64,com.oracle.graal.replacements.amd64
 project@com.oracle.graal.hotspot.amd64@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.hotspot.amd64@javaCompliance=1.7
 
@@ -114,6 +114,13 @@
 project@com.oracle.graal.hotspot.test@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.hotspot.test@javaCompliance=1.7
 
+# graal.hotspot.amd64.test
+project@com.oracle.graal.hotspot.amd64.test@subDir=graal
+project@com.oracle.graal.hotspot.amd64.test@sourceDirs=src
+project@com.oracle.graal.hotspot.amd64.test@dependencies=com.oracle.graal.asm.amd64,com.oracle.graal.compiler.test
+project@com.oracle.graal.hotspot.amd64.test@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.hotspot.amd64.test@javaCompliance=1.7
+
 # graal.graph
 project@com.oracle.graal.graph@subDir=graal
 project@com.oracle.graal.graph@sourceDirs=src
@@ -175,26 +182,26 @@
 project@com.oracle.graal.word@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.word@javaCompliance=1.7
 
-# graal.snippets
-project@com.oracle.graal.snippets@subDir=graal
-project@com.oracle.graal.snippets@sourceDirs=src
-project@com.oracle.graal.snippets@dependencies=com.oracle.graal.compiler,com.oracle.graal.java,com.oracle.graal.word
-project@com.oracle.graal.snippets@checkstyle=com.oracle.graal.graph
-project@com.oracle.graal.snippets@javaCompliance=1.7
+# graal.replacements
+project@com.oracle.graal.replacements@subDir=graal
+project@com.oracle.graal.replacements@sourceDirs=src
+project@com.oracle.graal.replacements@dependencies=com.oracle.graal.compiler,com.oracle.graal.java,com.oracle.graal.word
+project@com.oracle.graal.replacements@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.replacements@javaCompliance=1.7
 
-# graal.snippets.amd64
-project@com.oracle.graal.snippets.amd64@subDir=graal
-project@com.oracle.graal.snippets.amd64@sourceDirs=src
-project@com.oracle.graal.snippets.amd64@dependencies=com.oracle.graal.snippets
-project@com.oracle.graal.snippets.amd64@checkstyle=com.oracle.graal.graph
-project@com.oracle.graal.snippets.amd64@javaCompliance=1.7
+# graal.replacements.amd64
+project@com.oracle.graal.replacements.amd64@subDir=graal
+project@com.oracle.graal.replacements.amd64@sourceDirs=src
+project@com.oracle.graal.replacements.amd64@dependencies=com.oracle.graal.replacements
+project@com.oracle.graal.replacements.amd64@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.replacements.amd64@javaCompliance=1.7
 
-# graal.snippets.test
-project@com.oracle.graal.snippets.test@subDir=graal
-project@com.oracle.graal.snippets.test@sourceDirs=src
-project@com.oracle.graal.snippets.test@dependencies=com.oracle.graal.snippets,com.oracle.graal.compiler.test
-project@com.oracle.graal.snippets.test@checkstyle=com.oracle.graal.graph
-project@com.oracle.graal.snippets.test@javaCompliance=1.7
+# graal.replacements.test
+project@com.oracle.graal.replacements.test@subDir=graal
+project@com.oracle.graal.replacements.test@sourceDirs=src
+project@com.oracle.graal.replacements.test@dependencies=com.oracle.graal.replacements,com.oracle.graal.compiler.test
+project@com.oracle.graal.replacements.test@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.replacements.test@javaCompliance=1.7
 
 # graal.nodes
 project@com.oracle.graal.nodes@subDir=graal
@@ -248,7 +255,7 @@
 # graal.compiler.amd64.test
 project@com.oracle.graal.compiler.amd64.test@subDir=graal
 project@com.oracle.graal.compiler.amd64.test@sourceDirs=src
-project@com.oracle.graal.compiler.amd64.test@dependencies=com.oracle.graal.compiler.test,com.oracle.graal.asm.amd64
+project@com.oracle.graal.compiler.amd64.test@dependencies=com.oracle.graal.compiler.test
 project@com.oracle.graal.compiler.amd64.test@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.compiler.amd64.test@javaCompliance=1.7
 
--- a/mx/sanitycheck.py	Thu Mar 21 13:12:36 2013 +0100
+++ b/mx/sanitycheck.py	Thu Mar 21 13:13:07 2013 +0100
@@ -47,7 +47,7 @@
 dacapoScalaSanityWarmup = {
     'actors':     [0, 0, 2,  8, 10],
 # (lstadler) apparat was disabled due to a deadlock which I think is the benchmarks fault.
-#    'apparat':    [0, 0, 1,  2,  3],
+    'apparat':    [0, 0, 0,  0,  0],
     'factorie':   [0, 0, 2,  5,  5],
     'kiama':      [0, 0, 3, 13, 15],
     'scalac':     [0, 0, 5, 15, 20],
@@ -56,7 +56,8 @@
     'scalariform':[0, 0, 6, 15, 20],
     'scalatest':  [0, 0, 2, 10, 12],
     'scalaxb':    [0, 0, 5, 15, 25],
-    'specs':      [0, 0, 3, 13, 18],
+#(gdub) specs sometimes returns a non-zero value event though there is no apparent failure
+    'specs':      [0, 0, 0,  0,  0],
     'tmt':        [0, 0, 3, 10, 12]
 }
 
--- a/mxtool/mx.py	Thu Mar 21 13:12:36 2013 +0100
+++ b/mxtool/mx.py	Thu Mar 21 13:13:07 2013 +0100
@@ -1061,11 +1061,11 @@
 class JavaVersion:
     def __init__(self, versionString):
         validChar = '[\x21-\x25\x27-\x29\x2c\x2f-\x5e\x60-\x7f]'
-        separator = '[.-_]'
+        separator = '[.\-_]'
         m = re.match(validChar + '+(' + separator + validChar + '+)*', versionString)
         assert m is not None, 'not a recognized version string: ' + versionString
         self.versionString = versionString;
-        self.parts = versionString.split(separator)
+        self.parts = [int(f) if f.isdigit() else f for f in re.split(separator, versionString)]
         
     def __str__(self):
         return self.versionString
--- a/src/cpu/x86/vm/graalRuntime_x86.cpp	Thu Mar 21 13:12:36 2013 +0100
+++ b/src/cpu/x86/vm/graalRuntime_x86.cpp	Thu Mar 21 13:13:07 2013 +0100
@@ -100,7 +100,7 @@
     restore_live_registers(this, false);
     movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD);
     leave();
-    movl(rscratch1, Deoptimization::make_trap_request(Deoptimization::Reason_constraint, Deoptimization::Action_reinterpret));
+    movl(Address(thread, ThreadShadow::pending_deoptimization_offset()), Deoptimization::make_trap_request(Deoptimization::Reason_constraint, Deoptimization::Action_reinterpret));
     jump(RuntimeAddress(SharedRuntime::deopt_blob()->uncommon_trap()));
     bind(L);
   }
--- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Thu Mar 21 13:12:36 2013 +0100
+++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Thu Mar 21 13:13:07 2013 +0100
@@ -3419,7 +3419,7 @@
   __ set_last_Java_frame(noreg, noreg, NULL);
 
   __ movl(c_rarg1, Address(r15_thread, in_bytes(ThreadShadow::pending_deoptimization_offset())));
-  __ movl(Address(r15_thread, in_bytes(ThreadShadow::pending_deoptimization_offset())), 0);
+  __ movl(Address(r15_thread, in_bytes(ThreadShadow::pending_deoptimization_offset())), -1);
 
   __ movl(r14, (int32_t)Deoptimization::Unpack_reexecute);
   __ mov(c_rarg0, r15_thread);
--- a/src/share/tools/IdealGraphVisualizer/Difference/src/com/sun/hotspot/igv/difference/Difference.java	Thu Mar 21 13:12:36 2013 +0100
+++ b/src/share/tools/IdealGraphVisualizer/Difference/src/com/sun/hotspot/igv/difference/Difference.java	Thu Mar 21 13:13:07 2013 +0100
@@ -207,12 +207,16 @@
             InputNode nodeTo = inputNodeMap.get(a.getNode(to));
             char fromIndex = e.getFromIndex();
             char toIndex = e.getToIndex();
-
-            InputEdge newEdge = new InputEdge(fromIndex, toIndex, nodeFrom.getId(), nodeTo.getId());
-            if (!newEdges.contains(newEdge)) {
-                markAsDeleted(newEdge);
-                newEdges.add(newEdge);
-                graph.addEdge(newEdge);
+            
+            if (nodeFrom == null || nodeTo == null) {
+                System.out.println("Unexpected edge : " + from + " -> " + to);
+            } else {
+                InputEdge newEdge = new InputEdge(fromIndex, toIndex, nodeFrom.getId(), nodeTo.getId());
+                if (!newEdges.contains(newEdge)) {
+                    markAsDeleted(newEdge);
+                    newEdges.add(newEdge);
+                    graph.addEdge(newEdge);
+                }
             }
         }
 
@@ -224,17 +228,21 @@
             char fromIndex = e.getFromIndex();
             char toIndex = e.getToIndex();
 
-            InputEdge newEdge = new InputEdge(fromIndex, toIndex, nodeFrom.getId(), nodeTo.getId());
-            if (!newEdges.contains(newEdge)) {
-                markAsNew(newEdge);
-                newEdges.add(newEdge);
-                graph.addEdge(newEdge);
+            if (nodeFrom == null || nodeTo == null) {
+                System.out.println("Unexpected edge : " + from + " -> " + to);
             } else {
-                newEdges.remove(newEdge);
-                graph.removeEdge(newEdge);
-                markAsSame(newEdge);
-                newEdges.add(newEdge);
-                graph.addEdge(newEdge);
+                InputEdge newEdge = new InputEdge(fromIndex, toIndex, nodeFrom.getId(), nodeTo.getId());
+                if (!newEdges.contains(newEdge)) {
+                    markAsNew(newEdge);
+                    newEdges.add(newEdge);
+                    graph.addEdge(newEdge);
+                } else {
+                    newEdges.remove(newEdge);
+                    graph.removeEdge(newEdge);
+                    markAsSame(newEdge);
+                    newEdges.add(newEdge);
+                    graph.addEdge(newEdge);
+                }
             }
         }
 
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Thu Mar 21 13:12:36 2013 +0100
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Thu Mar 21 13:13:07 2013 +0100
@@ -386,7 +386,6 @@
 
   // (very) conservative estimate: each site needs a constant section entry
   _constants_size = _sites->length() * (BytesPerLong*2);
-  _total_size = align_size_up(_code_size, HeapWordSize) + _constants_size;
 
   _next_call_type = MARK_INVOKE_INVALID;
 }
--- a/src/share/vm/graal/graalCodeInstaller.hpp	Thu Mar 21 13:12:36 2013 +0100
+++ b/src/share/vm/graal/graalCodeInstaller.hpp	Thu Mar 21 13:13:07 2013 +0100
@@ -62,7 +62,6 @@
   jint          _custom_stack_area_offset;
   jint          _parameter_count;
   jint          _constants_size;
-  jint          _total_size;
 
   MarkId        _next_call_type;
   address       _invoke_mark_pc;
--- a/src/share/vm/graal/graalRuntime.hpp	Thu Mar 21 13:12:36 2013 +0100
+++ b/src/share/vm/graal/graalRuntime.hpp	Thu Mar 21 13:13:07 2013 +0100
@@ -149,7 +149,7 @@
   static jint identity_hash_code(JavaThread* thread, oopDesc* objd);
   static jboolean thread_is_interrupted(JavaThread* thread, oopDesc* obj, jboolean clear_interrupte);
 
-  // Note: Must be kept in sync with constants in com.oracle.graal.snippets.Log
+  // Note: Must be kept in sync with constants in com.oracle.graal.replacements.Log
   enum {
     LOG_OBJECT_NEWLINE = 0x01,
     LOG_OBJECT_STRING  = 0x02,
--- a/src/share/vm/runtime/arguments.cpp	Thu Mar 21 13:12:36 2013 +0100
+++ b/src/share/vm/runtime/arguments.cpp	Thu Mar 21 13:13:07 2013 +0100
@@ -2070,26 +2070,41 @@
   }
 #ifdef GRAAL
   if (UseCompressedOops) {
-    jio_fprintf(defaultStream::error_stream(),
+    if (IgnoreUnrecognizedVMOptions) {
+      warning("UseCompressedOops is disabled, because it is not supported by Graal");
+      FLAG_SET_CMDLINE(bool, UseCompressedOops, false);
+    } else {
+      jio_fprintf(defaultStream::error_stream(),
                     "CompressedOops are not supported in Graal at the moment\n");
-        status = false;
+      status = false;
+    }
   } else {
     // This prevents the flag being set to true by set_ergonomics_flags()
     FLAG_SET_CMDLINE(bool, UseCompressedOops, false);
   }
 
   if (UseCompressedKlassPointers) {
-    jio_fprintf(defaultStream::error_stream(),
+    if (IgnoreUnrecognizedVMOptions) {
+      warning("UseCompressedKlassPointers is disabled, because it is not supported by Graal");
+      FLAG_SET_CMDLINE(bool, UseCompressedKlassPointers, false);
+    } else {
+      jio_fprintf(defaultStream::error_stream(),
                     "UseCompressedKlassPointers are not supported in Graal at the moment\n");
-        status = false;
+      status = false;
+    }
   } else {
     // This prevents the flag being set to true by set_ergonomics_flags()
     FLAG_SET_CMDLINE(bool, UseCompressedKlassPointers, false);
   }
   if (UseG1GC) {
-    jio_fprintf(defaultStream::error_stream(),
+    if (IgnoreUnrecognizedVMOptions) {
+      warning("UseG1GC is disabled, because it is not supported by Graal");
+      FLAG_SET_CMDLINE(bool, UseG1GC, false);
+    } else {
+      jio_fprintf(defaultStream::error_stream(),
                         "G1 is not supported in Graal at the moment\n");
-        status = false;
+      status = false;
+    }
   } else {
     // This prevents the flag being set to true by set_ergonomics_flags()
     FLAG_SET_CMDLINE(bool, UseG1GC, false);