changeset 8416:102b5249e97e

rename projects: *snippets* -> *replacements* (GRAAL-178)
author Doug Simon <doug.simon@oracle.com>
date Wed, 20 Mar 2013 22:30:33 +0100
parents 2361bf148c06
children 7e281cb9ea10
files graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java graal/com.oracle.graal.replacements.test/overview.html graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/CheckCastTest.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/InstanceOfDynamicTest.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/InstanceOfTest.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/InvokeTest.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/MethodSubstitutionTest.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/MonitorTest.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/NewArrayTest.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/NewInstanceTest.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/NewMultiArrayTest.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/PointerTest.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/TypeCheckTest.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/WordTest.java graal/com.oracle.graal.replacements/overview.html graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ClassSubstitution.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DoubleSubstitutions.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/FloatSubstitutions.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalIntrinsics.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/IntegerSubstitutions.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/JavacBug.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/Log.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/LongSubstitutions.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/MathSubstitutionsX86.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationVerificationPhase.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsInstaller.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/Snippet.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetCounter.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetFrameStateCleanupPhase.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/Snippets.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsafeSubstitutions.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsignedMathSubstitutions.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitCountNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BranchProbabilityNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectReadNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectStoreNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ExplodeLoopNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/LoadSnippetVarargParameterNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReadRegisterNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReverseBytesNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/WriteRegisterNode.java graal/com.oracle.graal.snippets.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java graal/com.oracle.graal.snippets.test/overview.html graal/com.oracle.graal.snippets.test/src/com/oracle/graal/replacements/CheckCastTest.java graal/com.oracle.graal.snippets.test/src/com/oracle/graal/replacements/InstanceOfDynamicTest.java graal/com.oracle.graal.snippets.test/src/com/oracle/graal/replacements/InstanceOfTest.java graal/com.oracle.graal.snippets.test/src/com/oracle/graal/replacements/InvokeTest.java graal/com.oracle.graal.snippets.test/src/com/oracle/graal/replacements/MethodSubstitutionTest.java graal/com.oracle.graal.snippets.test/src/com/oracle/graal/replacements/MonitorTest.java graal/com.oracle.graal.snippets.test/src/com/oracle/graal/replacements/NewArrayTest.java graal/com.oracle.graal.snippets.test/src/com/oracle/graal/replacements/NewInstanceTest.java graal/com.oracle.graal.snippets.test/src/com/oracle/graal/replacements/NewMultiArrayTest.java graal/com.oracle.graal.snippets.test/src/com/oracle/graal/replacements/PointerTest.java graal/com.oracle.graal.snippets.test/src/com/oracle/graal/replacements/TypeCheckTest.java graal/com.oracle.graal.snippets.test/src/com/oracle/graal/replacements/WordTest.java graal/com.oracle.graal.snippets/overview.html graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/ClassSubstitution.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/DoubleSubstitutions.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/FloatSubstitutions.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/GraalIntrinsics.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/IntegerSubstitutions.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/JavacBug.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/Log.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/LongSubstitutions.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/MathSubstitutionsX86.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/NodeClassSubstitutions.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/NodeIntrinsificationVerificationPhase.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/ReplacementsInstaller.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/Snippet.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/SnippetCounter.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/SnippetFrameStateCleanupPhase.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/SnippetTemplate.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/Snippets.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/UnsafeSubstitutions.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/UnsignedMathSubstitutions.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/BitCountNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/BranchProbabilityNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/DirectReadNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/DirectStoreNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/ExplodeLoopNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/LoadSnippetVarargParameterNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/MacroNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/ReadRegisterNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/ReverseBytesNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/WriteRegisterNode.java make/build-graal.xml mx/projects
diffstat 102 files changed, 7872 insertions(+), 7872 deletions(-) [+]
line wrap: on
line diff
--- /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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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	Wed Mar 20 22:30:33 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/replacements/amd64/AMD64ConvertSnippets.java	Wed Mar 20 22:23:14 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,193 +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.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);
-        }
-    }
-}
--- a/graal/com.oracle.graal.snippets.test/overview.html	Wed Mar 20 22:23:14 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/replacements/CheckCastTest.java	Wed Mar 20 22:23:14 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.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);
-    }
-}
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/replacements/InstanceOfDynamicTest.java	Wed Mar 20 22:23:14 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.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();
-    }
-}
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/replacements/InstanceOfTest.java	Wed Mar 20 22:23:14 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,398 +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.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);
-    }
-}
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/replacements/InvokeTest.java	Wed Mar 20 22:23:14 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.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);
-    }
-}
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/replacements/MethodSubstitutionTest.java	Wed Mar 20 22:23:14 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,462 +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.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 {
-    }
-}
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/replacements/MonitorTest.java	Wed Mar 20 22:23:14 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.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);
-    }
-}
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/replacements/NewArrayTest.java	Wed Mar 20 22:23:14 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.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];
-    }
-}
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/replacements/NewInstanceTest.java	Wed Mar 20 22:23:14 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.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;
-    }
-}
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/replacements/NewMultiArrayTest.java	Wed Mar 20 22:23:14 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.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];
-    }
-}
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/replacements/PointerTest.java	Wed Mar 20 22:23:14 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.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);
-    }
-
-}
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/replacements/TypeCheckTest.java	Wed Mar 20 22:23:14 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.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;
-        }
-    }
-}
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/replacements/WordTest.java	Wed Mar 20 22:23:14 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.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();
-    }
-}
--- a/graal/com.oracle.graal.snippets/overview.html	Wed Mar 20 22:23:14 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/replacements/ClassSubstitution.java	Wed Mar 20 22:23:14 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,136 +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.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();
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/DoubleSubstitutions.java	Wed Mar 20 22:23:14 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.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;
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/FloatSubstitutions.java	Wed Mar 20 22:23:14 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.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;
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/GraalIntrinsics.java	Wed Mar 20 22:23:14 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.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);
-        }
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java	Wed Mar 20 22:23:14 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,338 +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.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);
-        }
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/IntegerSubstitutions.java	Wed Mar 20 22:23:14 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.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);
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/JavacBug.java	Wed Mar 20 22:23:14 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.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;
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/Log.java	Wed Mar 20 22:23:14 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.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("");
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/LongSubstitutions.java	Wed Mar 20 22:23:14 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.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);
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/MathSubstitutionsX86.java	Wed Mar 20 22:23:14 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.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);
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/NodeClassSubstitutions.java	Wed Mar 20 22:23:14 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.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);
-    }
-
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java	Wed Mar 20 22:23:14 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,397 +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.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);
-            }
-        }
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/NodeIntrinsificationVerificationPhase.java	Wed Mar 20 22:23:14 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.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);
-        }
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/ReplacementsInstaller.java	Wed Mar 20 22:23:14 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,406 +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.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);
-        }
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/Snippet.java	Wed Mar 20 22:23:14 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,217 +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.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 + "]";
-        }
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/SnippetCounter.java	Wed Mar 20 22:23:14 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.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);
-        }
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/SnippetFrameStateCleanupPhase.java	Wed Mar 20 22:23:14 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.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;
-        }
-
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/SnippetTemplate.java	Wed Mar 20 22:23:14 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,752 +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.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;
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/Snippets.java	Wed Mar 20 22:23:14 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +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.replacements;
-
-/**
- * Marker interface for a class that defines one or more {@link Snippet}s.
- */
-public interface Snippets {
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/UnsafeSubstitutions.java	Wed Mar 20 22:23:14 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.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);
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/UnsignedMathSubstitutions.java	Wed Mar 20 22:23:14 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.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);
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/BitCountNode.java	Wed Mar 20 22:23:14 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.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);
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java	Wed Mar 20 22:23:14 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.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);
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java	Wed Mar 20 22:23:14 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.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);
-    }
-
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/BranchProbabilityNode.java	Wed Mar 20 22:23:14 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.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);
-
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java	Wed Mar 20 22:23:14 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.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);
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/DirectReadNode.java	Wed Mar 20 22:23:14 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.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);
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/DirectStoreNode.java	Wed Mar 20 22:23:14 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.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);
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/ExplodeLoopNode.java	Wed Mar 20 22:23:14 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.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();
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/LoadSnippetVarargParameterNode.java	Wed Mar 20 22:23:14 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.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;
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/MacroNode.java	Wed Mar 20 22:23:14 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.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;
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java	Wed Mar 20 22:23:14 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.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);
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/ReadRegisterNode.java	Wed Mar 20 22:23:14 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.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);
-        }
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/ReverseBytesNode.java	Wed Mar 20 22:23:14 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.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);
-    }
-}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/replacements/nodes/WriteRegisterNode.java	Wed Mar 20 22:23:14 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.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/make/build-graal.xml	Wed Mar 20 22:23:14 2013 +0100
+++ b/make/build-graal.xml	Wed Mar 20 22:30:33 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"/>
--- a/mx/projects	Wed Mar 20 22:23:14 2013 +0100
+++ b/mx/projects	Wed Mar 20 22:30:33 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
 
@@ -182,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