changeset 7362:3a8e79636f8e

Merge.
author Doug Simon <doug.simon@oracle.com>
date Sun, 13 Jan 2013 21:55:49 +0100
parents b79ad92d5a26 (diff) b5280041f59e (current diff)
children f4f3d63d35e6
files
diffstat 36 files changed, 1420 insertions(+), 1283 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java	Sun Jan 13 19:32:16 2013 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java	Sun Jan 13 21:55:49 2013 +0100
@@ -60,6 +60,13 @@
     ResolvedJavaType lookupJavaType(Constant constant);
 
     /**
+     * Parses a <a href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.3">method
+     * descriptor</a> into a {@link Signature}. The behavior of this method is undefined if
+     * the method descriptor is not well formed.
+     */
+    Signature parseMethodDescriptor(String methodDescriptor);
+
+    /**
      * Compares two constants for equality.
      * This is used instead of {@link Constant#equals(Object)} in case the runtime
      * has an interpretation for object equality other than {@code x.asObject() == y.asObject()}.
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Sun Jan 13 19:32:16 2013 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Sun Jan 13 21:55:49 2013 +0100
@@ -494,23 +494,6 @@
     }
 
     /**
-     * Converts a {@link Signature} to internal representation, i.e., the signature
-     * <pre>(int, String, double)void</pre> is converted to <pre>(ILjava/lang/String;D)V</pre>.
-     *
-     * @param sig the {@link Signature} to be converted.
-     *
-     * @return the signature's internal representation as a string.
-     */
-    public static String signatureToInternal(Signature sig) {
-        StringBuilder sb = new StringBuilder("(");
-        for (int i = 0; i < sig.getParameterCount(false); ++i) {
-            sb.append(sig.getParameterType(i, null).getName());
-        }
-        sb.append(')').append(sig.getReturnType(null).getName());
-        return sb.toString();
-    }
-
-    /**
      * Formats some profiling information associated as a string.
      *
      * @param info the profiling info to format
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Signature.java	Sun Jan 13 19:32:16 2013 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Signature.java	Sun Jan 13 21:55:49 2013 +0100
@@ -24,14 +24,14 @@
 
 /**
  * Represents a method signature provided by the runtime.
- * 
- * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html#7035">Method Descriptors</a>
+ *
+ * @see <a href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.3">Method Descriptors</a>
  */
 public interface Signature {
 
     /**
      * Returns the number of parameters in this signature, adding 1 for a receiver if requested.
-     * 
+     *
      * @param receiver true if 1 is to be added to the result for a receiver
      * @return the number of parameters; + 1 iff {@code receiver == true}
      */
@@ -40,7 +40,7 @@
     /**
      * Gets the parameter type at the specified position. This method returns a {@linkplain ResolvedJavaType resolved}
      * type if possible but without triggering any class loading or resolution.
-     * 
+     *
      * @param index the index into the parameters, with {@code 0} indicating the first parameter
      * @param accessingClass the context of the type lookup. If accessing class is provided, its class loader is used to
      *            retrieve an existing resolved type. This value can be {@code null} if the caller does not care for a
@@ -52,7 +52,7 @@
     /**
      * Gets the parameter kind at the specified position. This is the same as calling {@link #getParameterType}.
      * {@link JavaType#getKind getKind}.
-     * 
+     *
      * @param index the index into the parameters, with {@code 0} indicating the first parameter
      * @return the kind of the parameter at the specified position
      */
@@ -61,7 +61,7 @@
     /**
      * Gets the return type of this signature. This method will return a {@linkplain ResolvedJavaType resolved} type if
      * possible but without triggering any class loading or resolution.
-     * 
+     *
      * @param accessingClass the context of the type lookup. If accessing class is provided, its class loader is used to
      *            retrieve an existing resolved type. This value can be {@code null} if the caller does not care for a
      *            resolved type.
@@ -77,10 +77,21 @@
 
     /**
      * Gets the size, in Java slots, of the parameters to this signature.
-     * 
+     *
      * @param withReceiver {@code true} if to add a slot for a receiver object; {@code false} not to include the
      *            receiver
      * @return the size of the parameters in slots
      */
     int getParameterSlots(boolean withReceiver);
+
+    /**
+     * Gets the <a href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.3">method
+     * descriptor</a> corresponding to this signature.
+     * For example:
+     *
+     * <pre>(ILjava/lang/String;D)V</pre>.
+     *
+     * @return the signature as a string
+     */
+    String getMethodDescriptor();
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Sun Jan 13 19:32:16 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Sun Jan 13 21:55:49 2013 +0100
@@ -22,11 +22,14 @@
  */
 package com.oracle.graal.hotspot;
 
+import static com.oracle.graal.nodes.StructuredGraph.*;
+
 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.hotspot.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.*;
@@ -127,7 +130,12 @@
                     @Override
                     public CompilationResult call() throws Exception {
                         graalRuntime.evictDeoptedGraphs();
-                        StructuredGraph graph = new StructuredGraph(method, entryBCI);
+                        StructuredGraph graph = (StructuredGraph) method.getCompilerStorage().get(Graph.class);
+                        if (graph == null || entryBCI != INVOCATION_ENTRY_BCI) {
+                            graph = new StructuredGraph(method, entryBCI);
+                        } else {
+                            // Compiling an intrinsic graph
+                        }
                         return graalRuntime.getCompiler().compileMethod(method, graph, graalRuntime.getCache(), plan, optimisticOpts);
                     }
                 });
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Sun Jan 13 19:32:16 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Sun Jan 13 21:55:49 2013 +0100
@@ -330,7 +330,7 @@
     @Override
     public ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method) {
         assert method instanceof HotSpotMethod;
-        return (ResolvedJavaMethod) HotSpotGraalRuntime.getInstance().getCompilerToVM().resolveMethod(this, method.getName(), ((HotSpotSignature) method.getSignature()).asString());
+        return (ResolvedJavaMethod) HotSpotGraalRuntime.getInstance().getCompilerToVM().resolveMethod(this, method.getName(), ((HotSpotSignature) method.getSignature()).getMethodDescriptor());
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Sun Jan 13 19:32:16 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Sun Jan 13 21:55:49 2013 +0100
@@ -27,12 +27,12 @@
 import static com.oracle.graal.api.meta.DeoptimizationReason.*;
 import static com.oracle.graal.api.meta.Value.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
-import static com.oracle.graal.hotspot.snippets.SystemSnippets.*;
+import static com.oracle.graal.hotspot.snippets.SystemSubstitutions.*;
 import static com.oracle.graal.java.GraphBuilderPhase.*;
 import static com.oracle.graal.nodes.UnwindNode.*;
 import static com.oracle.graal.nodes.java.RegisterFinalizerNode.*;
 import static com.oracle.graal.snippets.Log.*;
-import static com.oracle.graal.snippets.MathSnippetsX86.*;
+import static com.oracle.graal.snippets.MathSubstitutionsX86.*;
 
 import java.lang.reflect.*;
 import java.util.*;
@@ -303,31 +303,31 @@
 
     public void installSnippets(SnippetInstaller installer, Assumptions assumptions) {
         if (GraalOptions.IntrinsifyObjectMethods) {
-            installer.install(ObjectSnippets.class);
+            installer.installSubstitutions(ObjectSubstitutions.class);
         }
         if (GraalOptions.IntrinsifySystemMethods) {
-            installer.install(SystemSnippets.class);
+            installer.installSubstitutions(SystemSubstitutions.class);
         }
         if (GraalOptions.IntrinsifyThreadMethods) {
-            installer.install(ThreadSnippets.class);
+            installer.installSubstitutions(ThreadSubstitutions.class);
         }
         if (GraalOptions.IntrinsifyUnsafeMethods) {
-            installer.install(UnsafeSnippets.class);
+            installer.installSubstitutions(UnsafeSubstitutions.class);
         }
         if (GraalOptions.IntrinsifyClassMethods) {
-            installer.install(ClassSnippets.class);
+            installer.installSubstitutions(ClassSubstitutions.class);
         }
         if (GraalOptions.IntrinsifyArrayCopy) {
-            installer.install(ArrayCopySnippets.class);
+            installer.installSnippets(ArrayCopySnippets.class);
         }
 
-        installer.install(CheckCastSnippets.class);
-        installer.install(InstanceOfSnippets.class);
-        installer.install(NewObjectSnippets.class);
-        installer.install(MonitorSnippets.class);
+        installer.installSnippets(CheckCastSnippets.class);
+        installer.installSnippets(InstanceOfSnippets.class);
+        installer.installSnippets(NewObjectSnippets.class);
+        installer.installSnippets(MonitorSnippets.class);
 
-        installer.install(NewInstanceStub.class);
-        installer.install(NewArrayStub.class);
+        installer.installSnippets(NewInstanceStub.class);
+        installer.installSnippets(NewArrayStub.class);
 
         checkcastSnippets = new CheckCastSnippets.Templates(this, assumptions, graalRuntime.getTarget());
         instanceofSnippets = new InstanceOfSnippets.Templates(this, assumptions, graalRuntime.getTarget());
@@ -458,6 +458,11 @@
     }
 
     @Override
+    public Signature parseMethodDescriptor(String signature) {
+        return new HotSpotSignature(signature);
+    }
+
+    @Override
     public int getSizeOfLockData() {
         return config.basicLockSize;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java	Sun Jan 13 19:32:16 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java	Sun Jan 13 21:55:49 2013 +0100
@@ -25,6 +25,7 @@
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.java.*;
 
@@ -86,7 +87,7 @@
             case 'Z':
                 break;
             default:
-                assert false;
+                throw new GraalInternalError("Invalid character at index " + cur + " in signature: " + signature);
         }
         return cur;
     }
@@ -123,7 +124,8 @@
         return type;
     }
 
-    public String asString() {
+    @Override
+    public String getMethodDescriptor() {
         return originalString;
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ClassSnippets.java	Sun Jan 13 19:32:16 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.hotspot.snippets;
-
-import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
-import static com.oracle.graal.nodes.extended.UnsafeCastNode.*;
-
-import java.lang.reflect.*;
-
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.snippets.*;
-import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution;
-import com.oracle.graal.word.*;
-
-/**
- * Snippets for {@link java.lang.Class} methods.
- */
-@ClassSubstitution(java.lang.Class.class)
-public class ClassSnippets implements SnippetsInterface {
-    @MethodSubstitution(isStatic = false)
-    public static int getModifiers(final Class<?> thisObj) {
-        Word klass = loadWordFromObject(thisObj, klassOffset());
-        if (klass == Word.zero()) {
-            // Class for primitive type
-            return Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC;
-        } else {
-            return klass.readInt(klassModifierFlagsOffset());
-        }
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static boolean isInterface(final Class<?> thisObj) {
-        Word klass = loadWordFromObject(thisObj, klassOffset());
-        if (klass == Word.zero()) {
-            return false;
-        } else {
-            int accessFlags = klass.readInt(klassAccessFlagsOffset());
-            return (accessFlags & Modifier.INTERFACE) != 0;
-        }
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static boolean isArray(final Class<?> thisObj) {
-        Word klass = loadWordFromObject(thisObj, klassOffset());
-        if (klass == Word.zero()) {
-            return false;
-        } else {
-            int layoutHelper = klass.readInt(klassLayoutHelperOffset());
-            return (layoutHelper & arrayKlassLayoutHelperIdentifier()) != 0;
-        }
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static boolean isPrimitive(final Class<?> thisObj) {
-        Word klass = loadWordFromObject(thisObj, klassOffset());
-        return klass == Word.zero();
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static Class<?> getSuperclass(final Class<?> thisObj) {
-        Word klass = loadWordFromObject(thisObj, klassOffset());
-        if (klass != Word.zero()) {
-            int accessFlags = klass.readInt(klassAccessFlagsOffset());
-            if ((accessFlags & Modifier.INTERFACE) == 0) {
-                int layoutHelper = klass.readInt(klassLayoutHelperOffset());
-                if ((layoutHelper & arrayKlassLayoutHelperIdentifier()) != 0) {
-                    return Object.class;
-                } else {
-                    Word superKlass = klass.readWord(klassSuperKlassOffset());
-                    if (superKlass == Word.zero()) {
-                        return null;
-                    } else {
-                        return unsafeCast(superKlass.readObject(classMirrorOffset()), Class.class, true, true);
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static Class<?> getComponentType(final Class<?> thisObj) {
-        Word klass = loadWordFromObject(thisObj, klassOffset());
-        if (klass != Word.zero()) {
-            int layoutHelper = klass.readInt(klassLayoutHelperOffset());
-            if ((layoutHelper & arrayKlassLayoutHelperIdentifier()) != 0) {
-                return unsafeCast(klass.readObject(arrayKlassComponentMirrorOffset()), Class.class, true, true);
-            }
-        }
-        return null;
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static boolean isInstance(final Class<?> thisObj, Object obj) {
-        return !thisObj.isPrimitive() && MaterializeNode.isInstance(thisObj, obj);
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ClassSubstitutions.java	Sun Jan 13 21:55:49 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.hotspot.snippets;
+
+import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
+import static com.oracle.graal.nodes.extended.UnsafeCastNode.*;
+
+import java.lang.reflect.*;
+
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.snippets.*;
+import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution;
+import com.oracle.graal.word.*;
+
+/**
+ * Substitutions for {@link java.lang.Class} methods.
+ */
+@ClassSubstitution(java.lang.Class.class)
+public class ClassSubstitutions {
+    @MethodSubstitution(isStatic = false)
+    public static int getModifiers(final Class<?> thisObj) {
+        Word klass = loadWordFromObject(thisObj, klassOffset());
+        if (klass == Word.zero()) {
+            // Class for primitive type
+            return Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC;
+        } else {
+            return klass.readInt(klassModifierFlagsOffset());
+        }
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static boolean isInterface(final Class<?> thisObj) {
+        Word klass = loadWordFromObject(thisObj, klassOffset());
+        if (klass == Word.zero()) {
+            return false;
+        } else {
+            int accessFlags = klass.readInt(klassAccessFlagsOffset());
+            return (accessFlags & Modifier.INTERFACE) != 0;
+        }
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static boolean isArray(final Class<?> thisObj) {
+        Word klass = loadWordFromObject(thisObj, klassOffset());
+        if (klass == Word.zero()) {
+            return false;
+        } else {
+            int layoutHelper = klass.readInt(klassLayoutHelperOffset());
+            return (layoutHelper & arrayKlassLayoutHelperIdentifier()) != 0;
+        }
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static boolean isPrimitive(final Class<?> thisObj) {
+        Word klass = loadWordFromObject(thisObj, klassOffset());
+        return klass == Word.zero();
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static Class<?> getSuperclass(final Class<?> thisObj) {
+        Word klass = loadWordFromObject(thisObj, klassOffset());
+        if (klass != Word.zero()) {
+            int accessFlags = klass.readInt(klassAccessFlagsOffset());
+            if ((accessFlags & Modifier.INTERFACE) == 0) {
+                int layoutHelper = klass.readInt(klassLayoutHelperOffset());
+                if ((layoutHelper & arrayKlassLayoutHelperIdentifier()) != 0) {
+                    return Object.class;
+                } else {
+                    Word superKlass = klass.readWord(klassSuperKlassOffset());
+                    if (superKlass == Word.zero()) {
+                        return null;
+                    } else {
+                        return unsafeCast(superKlass.readObject(classMirrorOffset()), Class.class, true, true);
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static Class<?> getComponentType(final Class<?> thisObj) {
+        Word klass = loadWordFromObject(thisObj, klassOffset());
+        if (klass != Word.zero()) {
+            int layoutHelper = klass.readInt(klassLayoutHelperOffset());
+            if ((layoutHelper & arrayKlassLayoutHelperIdentifier()) != 0) {
+                return unsafeCast(klass.readObject(arrayKlassComponentMirrorOffset()), Class.class, true, true);
+            }
+        }
+        return null;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static boolean isInstance(final Class<?> thisObj, Object obj) {
+        return !thisObj.isPrimitive() && MaterializeNode.isInstance(thisObj, obj);
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectSnippets.java	Sun Jan 13 19:32:16 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.snippets;
-
-import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
-import static com.oracle.graal.nodes.extended.UnsafeCastNode.*;
-
-import com.oracle.graal.hotspot.nodes.*;
-import com.oracle.graal.snippets.*;
-import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution;
-import com.oracle.graal.word.*;
-
-/**
- * Snippets for {@link java.lang.Object} methods.
- */
-@ClassSubstitution(java.lang.Object.class)
-public class ObjectSnippets implements SnippetsInterface {
-    @MethodSubstitution(isStatic = false)
-    public static Class<?> getClass(final Object thisObj) {
-        Word hub = loadHub(thisObj);
-        return unsafeCast(hub.readFinalObject(Word.signed(classMirrorOffset())), Class.class, true, true);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static int hashCode(final Object thisObj) {
-        Word mark = loadWordFromObject(thisObj, markOffset());
-
-        // this code is independent from biased locking (although it does not look that way)
-        final Word biasedLock = mark.and(biasedLockMaskInPlace());
-        if (biasedLock == Word.unsigned(unlockedMask())) {
-            int hash = (int) mark.unsignedShiftRight(identityHashCodeShift()).rawValue();
-            if (hash != uninitializedIdentityHashCodeValue()) {
-                return hash;
-            }
-        }
-
-        return IdentityHashCodeStubCall.call(thisObj);
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectSubstitutions.java	Sun Jan 13 21:55:49 2013 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.snippets;
+
+import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
+import static com.oracle.graal.nodes.extended.UnsafeCastNode.*;
+
+import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.snippets.*;
+import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution;
+import com.oracle.graal.word.*;
+
+/**
+ * Substitutions for {@link java.lang.Object} methods.
+ */
+@ClassSubstitution(java.lang.Object.class)
+public class ObjectSubstitutions {
+    @MethodSubstitution(isStatic = false)
+    public static Class<?> getClass(final Object thisObj) {
+        Word hub = loadHub(thisObj);
+        return unsafeCast(hub.readFinalObject(Word.signed(classMirrorOffset())), Class.class, true, true);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static int hashCode(final Object thisObj) {
+        Word mark = loadWordFromObject(thisObj, markOffset());
+
+        // this code is independent from biased locking (although it does not look that way)
+        final Word biasedLock = mark.and(biasedLockMaskInPlace());
+        if (biasedLock == Word.unsigned(unlockedMask())) {
+            int hash = (int) mark.unsignedShiftRight(identityHashCodeShift()).rawValue();
+            if (hash != uninitializedIdentityHashCodeValue()) {
+                return hash;
+            }
+        }
+
+        return IdentityHashCodeStubCall.call(thisObj);
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/SystemSnippets.java	Sun Jan 13 19:32:16 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.snippets;
-
-import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
-
-import 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.hotspot.nodes.*;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.snippets.*;
-import com.oracle.graal.word.*;
-
-/**
- * Snippets for {@link java.lang.System} methods.
- */
-@ClassSubstitution(java.lang.System.class)
-public class SystemSnippets implements SnippetsInterface {
-
-    public static final Descriptor JAVA_TIME_MILLIS = new Descriptor("javaTimeMillis", false, long.class);
-    public static final Descriptor JAVA_TIME_NANOS = new Descriptor("javaTimeNanos", false, long.class);
-
-    public static long currentTimeMillis() {
-        return callLong(JAVA_TIME_MILLIS);
-    }
-
-    public static long nanoTime() {
-        return callLong(JAVA_TIME_NANOS);
-    }
-
-    public static int identityHashCode(Object x) {
-        if (x == null) {
-            return 0;
-        }
-
-        Word mark = loadWordFromObject(x, markOffset());
-
-        // this code is independent from biased locking (although it does not look that way)
-        final Word biasedLock = mark.and(biasedLockMaskInPlace());
-        if (biasedLock == Word.unsigned(unlockedMask())) {
-            int hash = (int) mark.unsignedShiftRight(identityHashCodeShift()).rawValue();
-            if (hash != uninitializedIdentityHashCodeValue()) {
-                return hash;
-            }
-        }
-
-        return IdentityHashCodeStubCall.call(x);
-    }
-
-    @NodeIntrinsic(value = RuntimeCallNode.class, setStampFromReturnType = true)
-    public static native long callLong(@ConstantNodeParameter Descriptor descriptor);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/SystemSubstitutions.java	Sun Jan 13 21:55:49 2013 +0100
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.snippets;
+
+import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
+
+import 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.hotspot.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.snippets.*;
+import com.oracle.graal.snippets.ClassSubstitution.*;
+import com.oracle.graal.word.*;
+
+/**
+ * Substitutions for {@link java.lang.System} methods.
+ */
+@ClassSubstitution(java.lang.System.class)
+public class SystemSubstitutions {
+
+    public static final Descriptor JAVA_TIME_MILLIS = new Descriptor("javaTimeMillis", false, long.class);
+    public static final Descriptor JAVA_TIME_NANOS = new Descriptor("javaTimeNanos", false, long.class);
+
+    @MethodSubstitution
+    public static long currentTimeMillis() {
+        return callLong(JAVA_TIME_MILLIS);
+    }
+
+    @MethodSubstitution
+    public static long nanoTime() {
+        return callLong(JAVA_TIME_NANOS);
+    }
+
+    @MethodSubstitution
+    public static int identityHashCode(Object x) {
+        if (x == null) {
+            return 0;
+        }
+
+        Word mark = loadWordFromObject(x, markOffset());
+
+        // this code is independent from biased locking (although it does not look that way)
+        final Word biasedLock = mark.and(biasedLockMaskInPlace());
+        if (biasedLock == Word.unsigned(unlockedMask())) {
+            int hash = (int) mark.unsignedShiftRight(identityHashCodeShift()).rawValue();
+            if (hash != uninitializedIdentityHashCodeValue()) {
+                return hash;
+            }
+        }
+
+        return IdentityHashCodeStubCall.call(x);
+    }
+
+    @NodeIntrinsic(value = RuntimeCallNode.class, setStampFromReturnType = true)
+    public static native long callLong(@ConstantNodeParameter Descriptor descriptor);
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ThreadSnippets.java	Sun Jan 13 19:32:16 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.snippets;
-
-import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
-
-import com.oracle.graal.hotspot.nodes.*;
-import com.oracle.graal.snippets.*;
-import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution;
-import com.oracle.graal.word.*;
-
-/**
- * Snippets for {@link java.lang.Thread} methods.
- */
-@SuppressWarnings("unused")
-@ClassSubstitution(java.lang.Thread.class)
-public class ThreadSnippets implements SnippetsInterface {
-    public static Thread currentThread() {
-        return CurrentThread.get();
-    }
-
-    @MethodSubstitution(isStatic = false)
-    private static boolean isInterrupted(final Thread thisObject, boolean clearInterrupted) {
-        Word rawThread = HotSpotCurrentRawThreadNode.get();
-        Thread thread = (Thread) rawThread.readObject(threadObjectOffset());
-        if (thisObject == thread) {
-            Word osThread = rawThread.readWord(osThreadOffset());
-            boolean interrupted = osThread.readInt(osThreadInterruptedOffset()) != 0;
-            if (!interrupted || !clearInterrupted) {
-                return interrupted;
-            }
-        }
-
-        return ThreadIsInterruptedStubCall.call(thisObject, clearInterrupted) != 0;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ThreadSubstitutions.java	Sun Jan 13 21:55:49 2013 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.snippets;
+
+import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
+
+import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.snippets.*;
+import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution;
+import com.oracle.graal.word.*;
+
+/**
+ * Substitutions for {@link java.lang.Thread} methods.
+ */
+@ClassSubstitution(java.lang.Thread.class)
+public class ThreadSubstitutions {
+
+    @MethodSubstitution
+    public static Thread currentThread() {
+        return CurrentThread.get();
+    }
+
+    @MethodSubstitution(isStatic = false)
+    private static boolean isInterrupted(final Thread thisObject, boolean clearInterrupted) {
+        Word rawThread = HotSpotCurrentRawThreadNode.get();
+        Thread thread = (Thread) rawThread.readObject(threadObjectOffset());
+        if (thisObject == thread) {
+            Word osThread = rawThread.readWord(osThreadOffset());
+            boolean interrupted = osThread.readInt(osThreadInterruptedOffset()) != 0;
+            if (!interrupted || !clearInterrupted) {
+                return interrupted;
+            }
+        }
+
+        return ThreadIsInterruptedStubCall.call(thisObject, clearInterrupted) != 0;
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Sun Jan 13 19:32:16 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Sun Jan 13 21:55:49 2013 +0100
@@ -44,7 +44,6 @@
  * or allocate the object, it calls out to the HotSpot C++ runtime for
  * to complete the allocation.
  */
-@SuppressWarnings("unused")
 public class NewArrayStub extends Stub {
 
     public NewArrayStub(final HotSpotRuntime runtime, Assumptions assumptions, TargetDescription target) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Sun Jan 13 19:32:16 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Sun Jan 13 21:55:49 2013 +0100
@@ -46,7 +46,6 @@
  * or allocate the object, it calls out to the HotSpot C++ runtime for
  * to complete the allocation.
  */
-@SuppressWarnings("unused")
 public class NewInstanceStub extends Stub {
 
     public NewInstanceStub(final HotSpotRuntime runtime, Assumptions assumptions, TargetDescription target) {
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/ClassSubstitution.java	Sun Jan 13 19:32:16 2013 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/ClassSubstitution.java	Sun Jan 13 21:55:49 2013 +0100
@@ -24,31 +24,60 @@
 
 import java.lang.annotation.*;
 
+import com.oracle.graal.api.meta.*;
+
 /**
  * Denotes a class that substitutes methods of another specified class with snippets.
+ * The substitute methods are exactly those annotated by {@link MethodSubstitution}.
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE)
 public @interface ClassSubstitution {
 
-    Class<?> value();
+    /**
+     * Specifies the substituted 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;
 
     /**
-     * Used to map a substitute method to an original method where the default mapping
-     * of name and signature is not possible due to name clashes with final methods in
-     * {@link Object} or signature types that are not public.
+     * Specifies the substituted class.
+     * <p>
+     * This method is provided for cases where the substituted class
+     * is not accessible (according to Java language access control rules).
+     * <p>
+     * If the default value is specified for this element, then a non-default
+     * value must be given for the {@link #value()} element.
+     */
+    String className() default "";
+
+    /**
+     * Denotes a substitute method.
      */
     @Retention(RetentionPolicy.RUNTIME)
     @Target(ElementType.METHOD)
     public @interface MethodSubstitution {
         /**
-         * Get the name of the original method.
+         * 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 "";
 
         /**
-         * Determine if the substituted method is static.
+         * Determines if the substituted method is static.
          */
         boolean isStatic() default true;
+
+        /**
+         * Gets the {@linkplain Signature#getMethodDescriptor() 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 "";
     }
 }
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/DoubleSnippets.java	Sun Jan 13 19:32:16 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets;
-
-import com.oracle.graal.nodes.calc.*;
-
-/**
- * Snippets for {@link java.lang.Double} methods.
- */
-@ClassSubstitution(java.lang.Double.class)
-public class DoubleSnippets implements SnippetsInterface {
-
-    private static final long NAN_RAW_LONG_BITS = Double.doubleToRawLongBits(Double.NaN);
-
-    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
-    public static long doubleToLongBits(double value) {
-        if (value != value) {
-            return NAN_RAW_LONG_BITS;
-        } else {
-            return doubleToRawLongBits(value);
-        }
-    }
-
-    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.snippets/src/com/oracle/graal/snippets/DoubleSubstitutions.java	Sun Jan 13 21:55:49 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.snippets;
+
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.snippets.ClassSubstitution.*;
+
+/**
+ * Substitutions for {@link java.lang.Double} methods.
+ */
+@ClassSubstitution(java.lang.Double.class)
+public class DoubleSubstitutions {
+
+    private static final long NAN_RAW_LONG_BITS = Double.doubleToRawLongBits(Double.NaN);
+
+    @MethodSubstitution
+    public static long doubleToRawLongBits(double value) {
+        @JavacBug(id = 6995200)
+        Long result = ConvertNode.convert(ConvertNode.Op.MOV_D2L, value);
+        return result;
+    }
+
+    // TODO This method is not necessary, since the JDK method does exactly this
+    @MethodSubstitution
+    public static long doubleToLongBits(double value) {
+        if (value != value) {
+            return NAN_RAW_LONG_BITS;
+        } else {
+            return doubleToRawLongBits(value);
+        }
+    }
+
+    @MethodSubstitution
+    public static double longBitsToDouble(long bits) {
+        @JavacBug(id = 6995200)
+        Double result = ConvertNode.convert(ConvertNode.Op.MOV_L2D, bits);
+        return result;
+    }
+}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/FloatSnippets.java	Sun Jan 13 19:32:16 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets;
-
-import com.oracle.graal.nodes.calc.*;
-
-/**
- * Snippets for {@link java.lang.Float} methods.
- */
-@ClassSubstitution(java.lang.Float.class)
-public class FloatSnippets implements SnippetsInterface {
-
-    private static final int NAN_RAW_INT_BITS = Float.floatToRawIntBits(Float.NaN);
-
-    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
-    public static int floatToIntBits(float value) {
-        if (value != value) {
-            return NAN_RAW_INT_BITS;
-        } else {
-            return floatToRawIntBits(value);
-        }
-    }
-
-    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.snippets/src/com/oracle/graal/snippets/FloatSubstitutions.java	Sun Jan 13 21:55:49 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.snippets;
+
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.snippets.ClassSubstitution.*;
+
+/**
+ * Substitutions for {@link java.lang.Float} methods.
+ */
+@ClassSubstitution(java.lang.Float.class)
+public class FloatSubstitutions {
+
+    private static final int NAN_RAW_INT_BITS = Float.floatToRawIntBits(Float.NaN);
+
+    @MethodSubstitution
+    public static int floatToRawIntBits(float value) {
+        @JavacBug(id = 6995200)
+        Integer result = ConvertNode.convert(ConvertNode.Op.MOV_F2I, value);
+        return result;
+    }
+
+    // TODO This method is not necessary, since the JDK method does exactly this
+    @MethodSubstitution
+    public static int floatToIntBits(float value) {
+        if (value != value) {
+            return NAN_RAW_INT_BITS;
+        } else {
+            return floatToRawIntBits(value);
+        }
+    }
+
+    @MethodSubstitution
+    public static float intBitsToFloat(int bits) {
+        @JavacBug(id = 6995200)
+        Float result = ConvertNode.convert(ConvertNode.Op.MOV_I2F, bits);
+        return result;
+    }
+}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/GraalIntrinsics.java	Sun Jan 13 19:32:16 2013 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/GraalIntrinsics.java	Sun Jan 13 21:55:49 2013 +0100
@@ -30,13 +30,13 @@
 public class GraalIntrinsics {
     public static void installIntrinsics(SnippetInstaller installer) {
         if (GraalOptions.Intrinsify) {
-            installer.install(MathSnippetsX86.class);
-            installer.install(DoubleSnippets.class);
-            installer.install(FloatSnippets.class);
-            installer.install(NodeClassSnippets.class);
-            installer.install(LongSnippets.class);
-            installer.install(IntegerSnippets.class);
-            installer.install(UnsignedMathSnippets.class);
+            installer.installSubstitutions(MathSubstitutionsX86.class);
+            installer.installSubstitutions(DoubleSubstitutions.class);
+            installer.installSubstitutions(FloatSubstitutions.class);
+            installer.installSubstitutions(NodeClassSubstitutions.class);
+            installer.installSubstitutions(LongSubstitutions.class);
+            installer.installSubstitutions(IntegerSubstitutions.class);
+            installer.installSubstitutions(UnsignedMathSubstitutions.class);
         }
     }
 }
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/IntegerSnippets.java	Sun Jan 13 19:32:16 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets;
-
-import com.oracle.graal.snippets.nodes.*;
-
-@ClassSubstitution(Integer.class)
-public class IntegerSnippets implements SnippetsInterface{
-
-    public static int reverseBytes(int i) {
-        return ReverseBytesNode.reverse(i);
-    }
-
-    public static int numberOfLeadingZeros(int i) {
-        if (i == 0) {
-            return 32;
-        }
-        return 31 - BitScanReverseNode.scan(i);
-    }
-
-    public static int numberOfTrailingZeros(int i) {
-        if (i == 0) {
-            return 32;
-        }
-        return BitScanForwardNode.scan(i);
-    }
-
-    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.snippets/src/com/oracle/graal/snippets/IntegerSubstitutions.java	Sun Jan 13 21:55:49 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.snippets;
+
+import com.oracle.graal.snippets.ClassSubstitution.*;
+import com.oracle.graal.snippets.nodes.*;
+
+@ClassSubstitution(Integer.class)
+public class IntegerSubstitutions {
+
+    @MethodSubstitution
+    public static int reverseBytes(int i) {
+        return ReverseBytesNode.reverse(i);
+    }
+
+    @MethodSubstitution
+    public static int numberOfLeadingZeros(int i) {
+        if (i == 0) {
+            return 32;
+        }
+        return 31 - BitScanReverseNode.scan(i);
+    }
+
+    @MethodSubstitution
+    public static int numberOfTrailingZeros(int i) {
+        if (i == 0) {
+            return 32;
+        }
+        return BitScanForwardNode.scan(i);
+    }
+
+    @MethodSubstitution
+    public static int bitCount(int i) {
+        return BitCountNode.bitCount(i);
+    }
+}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/LongSnippets.java	Sun Jan 13 19:32:16 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets;
-
-import com.oracle.graal.snippets.nodes.*;
-
-@ClassSubstitution(Long.class)
-public class LongSnippets implements SnippetsInterface{
-
-    public static long reverseBytes(long i) {
-        return ReverseBytesNode.reverse(i);
-    }
-
-    public static int numberOfLeadingZeros(long i) {
-        if (i == 0) {
-            return 64;
-        }
-        return 63 - BitScanReverseNode.scan(i);
-    }
-
-    public static int numberOfTrailingZeros(long i) {
-        if (i == 0) {
-            return 64;
-        }
-        return BitScanForwardNode.scan(i);
-    }
-
-    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.snippets/src/com/oracle/graal/snippets/LongSubstitutions.java	Sun Jan 13 21:55:49 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.snippets;
+
+import com.oracle.graal.snippets.ClassSubstitution.*;
+import com.oracle.graal.snippets.nodes.*;
+
+@ClassSubstitution(Long.class)
+public class LongSubstitutions {
+
+    @MethodSubstitution
+    public static long reverseBytes(long i) {
+        return ReverseBytesNode.reverse(i);
+    }
+
+    @MethodSubstitution
+    public static int numberOfLeadingZeros(long i) {
+        if (i == 0) {
+            return 64;
+        }
+        return 63 - BitScanReverseNode.scan(i);
+    }
+
+    @MethodSubstitution
+    public static int numberOfTrailingZeros(long i) {
+        if (i == 0) {
+            return 64;
+        }
+        return BitScanForwardNode.scan(i);
+    }
+
+    @MethodSubstitution
+    public static int bitCount(long i) {
+        return BitCountNode.bitCount(i);
+    }
+}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/MathSnippetsX86.java	Sun Jan 13 19:32:16 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets;
-
-import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
-import com.oracle.graal.graph.Node.ConstantNodeParameter;
-import com.oracle.graal.graph.Node.NodeIntrinsic;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.snippets.nodes.*;
-import com.oracle.graal.snippets.nodes.MathIntrinsicNode.Operation;
-
-/**
- * Snippets for {@link java.lang.Math} methods.
- */
-@ClassSubstitution(java.lang.Math.class)
-public class MathSnippetsX86 implements SnippetsInterface {
-
-    private static final double PI_4 = 0.7853981633974483;
-
-    public static double abs(double x) {
-        return MathIntrinsicNode.compute(x, Operation.ABS);
-    }
-
-    public static double sqrt(double x) {
-        return MathIntrinsicNode.compute(x, Operation.SQRT);
-    }
-
-    public static double log(double x) {
-        return MathIntrinsicNode.compute(x, Operation.LOG);
-    }
-
-    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.
-
-    public static double sin(double x) {
-        if (abs(x) < PI_4) {
-            return MathIntrinsicNode.compute(x, Operation.SIN);
-        } else {
-            return callDouble(ARITHMETIC_SIN, x);
-        }
-    }
-
-    public static double cos(double x) {
-        if (abs(x) < PI_4) {
-            return MathIntrinsicNode.compute(x, Operation.COS);
-        } else {
-            return callDouble(ARITHMETIC_COS, x);
-        }
-    }
-
-    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.snippets/src/com/oracle/graal/snippets/MathSubstitutionsX86.java	Sun Jan 13 21:55:49 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.snippets;
+
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
+import com.oracle.graal.graph.Node.ConstantNodeParameter;
+import com.oracle.graal.graph.Node.NodeIntrinsic;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution;
+import com.oracle.graal.snippets.nodes.*;
+import com.oracle.graal.snippets.nodes.MathIntrinsicNode.Operation;
+
+/**
+ * Substitutions for {@link java.lang.Math} methods.
+ */
+@ClassSubstitution(java.lang.Math.class)
+public class MathSubstitutionsX86 {
+
+    private static final double PI_4 = 0.7853981633974483;
+
+    @MethodSubstitution
+    public static double abs(double x) {
+        return MathIntrinsicNode.compute(x, Operation.ABS);
+    }
+
+    @MethodSubstitution
+    public static double sqrt(double x) {
+        return MathIntrinsicNode.compute(x, Operation.SQRT);
+    }
+
+    @MethodSubstitution
+    public static double log(double x) {
+        return MathIntrinsicNode.compute(x, Operation.LOG);
+    }
+
+    @MethodSubstitution
+    public static double log10(double x) {
+        return MathIntrinsicNode.compute(x, Operation.LOG10);
+    }
+
+    // NOTE on snippets below:
+    //   Math.sin(), .cos() and .tan() guarantee a value within 1 ULP of the
+    //   exact result, but x87 trigonometric FPU instructions are only that
+    //   accurate within [-pi/4, pi/4]. Examine the passed value and provide
+    //   a slow path for inputs outside of that interval.
+
+    @MethodSubstitution
+    public static double sin(double x) {
+        if (abs(x) < PI_4) {
+            return MathIntrinsicNode.compute(x, Operation.SIN);
+        } else {
+            return callDouble(ARITHMETIC_SIN, x);
+        }
+    }
+
+    @MethodSubstitution
+    public static double cos(double x) {
+        if (abs(x) < PI_4) {
+            return MathIntrinsicNode.compute(x, Operation.COS);
+        } else {
+            return callDouble(ARITHMETIC_COS, x);
+        }
+    }
+
+    @MethodSubstitution
+    public static double tan(double x) {
+        if (abs(x) < PI_4) {
+            return MathIntrinsicNode.compute(x, Operation.TAN);
+        } else {
+            return callDouble(ARITHMETIC_TAN, x);
+        }
+    }
+
+    public static final Descriptor ARITHMETIC_SIN = new Descriptor("arithmeticSin", false, double.class, double.class);
+    public static final Descriptor ARITHMETIC_COS = new Descriptor("arithmeticCos", false, double.class, double.class);
+    public static final Descriptor ARITHMETIC_TAN = new Descriptor("arithmeticTan", false, double.class, double.class);
+
+    @NodeIntrinsic(value = RuntimeCallNode.class, setStampFromReturnType = true)
+    public static native double callDouble(@ConstantNodeParameter Descriptor descriptor, double value);
+}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/NodeClassSnippets.java	Sun Jan 13 19:32:16 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.extended.*;
-
-/**
- * Snippets for improving the performance of some critical methods in {@link NodeClass} methods.
- * These snippets 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}.
- */
-@SuppressWarnings("unused")
-@ClassSubstitution(NodeClass.class)
-public class NodeClassSnippets implements SnippetsInterface {
-
-    private static Node getNode(Node node, long offset) {
-        return UnsafeCastNode.unsafeCast(UnsafeLoadNode.load(node, 0, offset, Kind.Object), Node.class, false, false);
-    }
-
-    private static NodeList getNodeList(Node node, long offset) {
-        return UnsafeCastNode.unsafeCast(UnsafeLoadNode.load(node, 0, offset, Kind.Object), NodeList.class, false, false);
-    }
-
-    private static void putNode(Node node, long offset, Node value) {
-        UnsafeStoreNode.store(node, 0, offset, value, Kind.Object);
-    }
-
-    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.snippets/src/com/oracle/graal/snippets/NodeClassSubstitutions.java	Sun Jan 13 21:55:49 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.snippets;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.snippets.ClassSubstitution.*;
+
+/**
+ * Substitutions for improving the performance of some critical methods in {@link NodeClass} methods.
+ * These substitutions improve the performance by forcing the relevant methods to be inlined
+ * (intrinsification being a special form of inlining) and removing a checked cast.
+ * The latter cannot be done directly in Java code as {@link UnsafeCastNode}
+ * is not available to the project containing {@link NodeClass}.
+ */
+@ClassSubstitution(NodeClass.class)
+public class NodeClassSubstitutions {
+
+    @MethodSubstitution
+    private static Node getNode(Node node, long offset) {
+        return UnsafeCastNode.unsafeCast(UnsafeLoadNode.load(node, 0, offset, Kind.Object), Node.class, false, false);
+    }
+
+    @MethodSubstitution
+    private static NodeList getNodeList(Node node, long offset) {
+        return UnsafeCastNode.unsafeCast(UnsafeLoadNode.load(node, 0, offset, Kind.Object), NodeList.class, false, false);
+    }
+
+    @MethodSubstitution
+    private static void putNode(Node node, long offset, Node value) {
+        UnsafeStoreNode.store(node, 0, offset, value, Kind.Object);
+    }
+
+    @MethodSubstitution
+    private static void putNodeList(Node node, long offset, NodeList value) {
+        UnsafeStoreNode.store(node, 0, offset, value, Kind.Object);
+    }
+
+}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java	Sun Jan 13 19:32:16 2013 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java	Sun Jan 13 21:55:49 2013 +0100
@@ -22,15 +22,18 @@
  */
 package com.oracle.graal.snippets;
 
+import static com.oracle.graal.api.meta.MetaUtil.*;
+
 import java.lang.reflect.*;
 import java.util.*;
 import java.util.concurrent.*;
 
+import sun.misc.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.java.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
@@ -44,7 +47,8 @@
 import com.oracle.graal.word.phases.*;
 
 /**
- * Utility for snippet {@linkplain #install(Class) installation}.
+ * Utility for {@linkplain #installSnippets(Class) snippet} and
+ * {@linkplain #installSubstitutions(Class) substitution} installation.
  */
 public class SnippetInstaller {
 
@@ -73,20 +77,8 @@
      * 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.
-     * <p>
-     * If {@code snippetsHolder} is annotated with {@link ClassSubstitution}, then all
-     * methods in the class are snippets. Otherwise, the snippets are those methods
-     * annotated with {@link Snippet}.
      */
-    public void install(Class<? extends SnippetsInterface> snippetsHolder) {
-        if (snippetsHolder.isAnnotationPresent(ClassSubstitution.class)) {
-            installSubstitutions(snippetsHolder, snippetsHolder.getAnnotation(ClassSubstitution.class).value());
-        } else {
-            installSnippets(snippetsHolder);
-        }
-    }
-
-    private void installSnippets(Class< ? extends SnippetsInterface> clazz) {
+    public void installSnippets(Class< ? extends SnippetsInterface> clazz) {
         for (Method method : clazz.getDeclaredMethods()) {
             if (method.getAnnotation(Snippet.class) != null) {
                 int modifiers = method.getModifiers();
@@ -102,43 +94,36 @@
         }
     }
 
-    private void installSubstitutions(Class< ? extends SnippetsInterface> clazz, Class<?> originalClazz) {
-        for (Method method : clazz.getDeclaredMethods()) {
-            if (method.getAnnotation(NodeIntrinsic.class) != null) {
+    /**
+     * Finds all the {@linkplain MethodSubstitution substitution} methods in a given class,
+     * builds a graph for them. If the original class is resolvable, then the
+     * graph is installed with the key value of {@code Graph.class} in the
+     * {@linkplain ResolvedJavaMethod#getCompilerStorage() compiler storage} of each original method.
+     */
+    public void installSubstitutions(Class<?> substitutions) {
+        ClassSubstitution classSubstitution = substitutions.getAnnotation(ClassSubstitution.class);
+        for (Method substituteMethod : substitutions.getDeclaredMethods()) {
+            MethodSubstitution methodSubstitution = substituteMethod.getAnnotation(MethodSubstitution.class);
+            if (methodSubstitution == null) {
                 continue;
             }
-            try {
-                MethodSubstitution methodSubstitution = method.getAnnotation(MethodSubstitution.class);
-                String originalName = method.getName();
-                Class<?>[] originalParameters = method.getParameterTypes();
-                if (methodSubstitution != null) {
-                    if (!methodSubstitution.value().isEmpty()) {
-                        originalName = methodSubstitution.value();
-                    }
-                    if (!methodSubstitution.isStatic()) {
-                        assert originalParameters.length >= 1 : "must be a static method with the this object as its first parameter";
-                        Class<?>[] newParameters = new Class<?>[originalParameters.length - 1];
-                        System.arraycopy(originalParameters, 1, newParameters, 0, newParameters.length);
-                        originalParameters = newParameters;
-                    }
-                }
-                Method originalMethod = originalClazz.getDeclaredMethod(originalName, originalParameters);
-                if (!originalMethod.getReturnType().isAssignableFrom(method.getReturnType())) {
-                    throw new RuntimeException("Snippet has incompatible return type: " + method);
-                }
-                int modifiers = method.getModifiers();
-                if (!Modifier.isStatic(modifiers)) {
-                    throw new RuntimeException("Snippets must be static methods: " + method);
-                } else if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) {
-                    throw new RuntimeException("Snippet must not be abstract or native: " + method);
-                }
-                ResolvedJavaMethod snippet = runtime.lookupJavaMethod(method);
-                StructuredGraph graph = makeGraph(snippet, inliningPolicy(snippet), true);
-                //System.out.println("snippet: " + graph);
-                runtime.lookupJavaMethod(originalMethod).getCompilerStorage().put(Graph.class, graph);
-            } catch (NoSuchMethodException e) {
-                throw new GraalInternalError("Could not resolve method in " + originalClazz + " to substitute with " + method, e);
+
+            int modifiers = substituteMethod.getModifiers();
+            if (!Modifier.isStatic(modifiers)) {
+                throw new RuntimeException("Substitution methods must be static: " + substituteMethod);
+            } else if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) {
+                throw new RuntimeException("Substitution method must not be abstract or native: " + substituteMethod);
             }
+
+            String originalName = originalName(substituteMethod, methodSubstitution);
+            Class[] originalParameters = originalParameters(substituteMethod, methodSubstitution);
+            ResolvedJavaMethod substitute = runtime.lookupJavaMethod(substituteMethod);
+            Method originalMethod = originalMethod(classSubstitution, originalName, originalParameters);
+            ResolvedJavaMethod substituted = runtime.lookupJavaMethod(originalMethod);
+            //System.out.println("substitution: " + MetaUtil.format("%H.%n(%p)", substituted) + " --> " + MetaUtil.format("%H.%n(%p)", substitute));
+            StructuredGraph graph = makeGraph(substitute, inliningPolicy(substitute), true);
+            Object oldValue = substituted.getCompilerStorage().put(Graph.class, graph);
+            assert oldValue == null;
         }
     }
 
@@ -158,7 +143,7 @@
         }
     }
 
-    public StructuredGraph makeGraph(final ResolvedJavaMethod method, final SnippetInliningPolicy policy, final boolean isSubstitutionSnippet) {
+    public StructuredGraph makeGraph(final ResolvedJavaMethod method, final SnippetInliningPolicy policy, final boolean isSubstitution) {
         return Debug.scope("BuildSnippetGraph", new Object[] {method}, new Callable<StructuredGraph>() {
             @Override
             public StructuredGraph call() throws Exception {
@@ -166,8 +151,8 @@
 
                 new SnippetIntrinsificationPhase(runtime, pool, SnippetTemplate.hasConstantParameter(method)).apply(graph);
 
-                if (isSubstitutionSnippet) {
-                    // TODO (ds) remove the constraint of only processing substitution snippets
+                if (isSubstitution) {
+                    // TODO (ds) remove the constraint of only processing substitutions
                     // once issues with the arraycopy snippets have been resolved
                     new SnippetFrameStateCleanupPhase().apply(graph);
                     new DeadCodeEliminationPhase().apply(graph);
@@ -238,4 +223,65 @@
         }
         return graph;
     }
+
+    private static String originalName(Method substituteMethod, MethodSubstitution methodSubstitution) {
+        String name = substituteMethod.getName();
+        if (!methodSubstitution.value().isEmpty()) {
+            name = methodSubstitution.value();
+        }
+        return name;
+    }
+
+    private static Class resolveType(String className) {
+        try {
+            // Need to use launcher class path to handle classes
+            // that are not on the boot class path
+            ClassLoader cl = Launcher.getLauncher().getClassLoader();
+            return Class.forName(className, false, cl);
+        } catch (ClassNotFoundException e) {
+            throw new GraalInternalError("Could not resolve type " + className);
+        }
+    }
+
+    private static Class resolveType(JavaType type) {
+        JavaType base = type;
+        int dimensions = 0;
+        while (base.getComponentType() != null) {
+            base = base.getComponentType();
+            dimensions++;
+        }
+
+        Class baseClass = base.getKind() != Kind.Object ? base.getKind().toJavaClass() : resolveType(toJavaName(base));
+        return dimensions == 0 ? baseClass : Array.newInstance(baseClass, new int[dimensions]).getClass();
+    }
+
+    private Class[] originalParameters(Method substituteMethod, MethodSubstitution methodSubstitution) {
+        Class[] parameters;
+        if (methodSubstitution.signature().isEmpty()) {
+            parameters = substituteMethod.getParameterTypes();
+            if (!methodSubstitution.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.signature());
+            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 Method originalMethod(ClassSubstitution classSubstitution, String name, Class[] parameters) {
+        Class<?> originalClass = classSubstitution.value();
+        if (originalClass == ClassSubstitution.class) {
+            originalClass = resolveType(classSubstitution.className());
+        }
+        try {
+            return originalClass.getDeclaredMethod(name, parameters);
+        } catch (NoSuchMethodException | SecurityException e) {
+            throw new GraalInternalError(e);
+        }
+    }
 }
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/UnsafeSnippets.java	Sun Jan 13 19:32:16 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,382 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution;
-import com.oracle.graal.snippets.nodes.*;
-
-/**
- * Snippets for {@link sun.misc.Unsafe} methods.
- */
-@ClassSubstitution(sun.misc.Unsafe.class)
-public class UnsafeSnippets implements SnippetsInterface {
-    @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);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putShort(@SuppressWarnings("unused") final Object thisObj, long address, short value) {
-        DirectStoreNode.store(address, value);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putChar(@SuppressWarnings("unused") final Object thisObj, long address, char value) {
-        DirectStoreNode.store(address, value);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putInt(@SuppressWarnings("unused") final Object thisObj, long address, int value) {
-        DirectStoreNode.store(address, value);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putLong(@SuppressWarnings("unused") final Object thisObj, long address, long value) {
-        DirectStoreNode.store(address, value);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putFloat(@SuppressWarnings("unused") final Object thisObj, long address, float value) {
-        DirectStoreNode.store(address, value);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void putDouble(@SuppressWarnings("unused") final Object thisObj, long address, double value) {
-        DirectStoreNode.store(address, value);
-    }
-
-    @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.snippets/src/com/oracle/graal/snippets/UnsafeSubstitutions.java	Sun Jan 13 21:55:49 2013 +0100
@@ -0,0 +1,382 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.snippets;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution;
+import com.oracle.graal.snippets.nodes.*;
+
+/**
+ * Substitutions for {@link sun.misc.Unsafe} methods.
+ */
+@ClassSubstitution(sun.misc.Unsafe.class)
+public class UnsafeSubstitutions {
+    @MethodSubstitution(isStatic = false)
+    public static boolean compareAndSwapObject(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, Object expected, Object x) {
+        return CompareAndSwapNode.compareAndSwap(o, 0, offset, expected, x);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static boolean compareAndSwapInt(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, int expected, int x) {
+        return CompareAndSwapNode.compareAndSwap(o, 0, offset, expected, x);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static boolean compareAndSwapLong(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, long expected, long x) {
+        return CompareAndSwapNode.compareAndSwap(o, 0, offset, expected, x);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static Object getObject(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
+        return UnsafeLoadNode.load(o, 0, offset, Kind.Object);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static Object getObjectVolatile(final Object thisObj, Object o, long offset) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        Object result = getObject(thisObj, o, offset);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putObject(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, Object x) {
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Object);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putObjectVolatile(final Object thisObj, Object o, long offset, Object x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putObject(thisObj, o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putOrderedObject(final Object thisObj, Object o, long offset, Object x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putObject(thisObj, o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static int getInt(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
+        Integer value = UnsafeLoadNode.load(o, 0, offset, Kind.Int);
+        return value;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static int getIntVolatile(final Object thisObj, Object o, long offset) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        int result = getInt(thisObj, o, offset);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putInt(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, int x) {
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Int);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putIntVolatile(final Object thisObj, Object o, long offset, int x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putInt(thisObj, o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putOrderedInt(final Object thisObj, Object o, long offset, int x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putInt(thisObj, o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static boolean getBoolean(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
+        @JavacBug(id = 6995200)
+        Boolean result = UnsafeLoadNode.load(o, 0, offset, Kind.Boolean);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static boolean getBooleanVolatile(final Object thisObj, Object o, long offset) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        boolean result = getBoolean(thisObj, o, offset);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putBoolean(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, boolean x) {
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Boolean);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putBooleanVolatile(final Object thisObj, Object o, long offset, boolean x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putBoolean(thisObj, o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static byte getByte(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
+        @JavacBug(id = 6995200)
+        Byte result = UnsafeLoadNode.load(o, 0, offset, Kind.Byte);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static byte getByteVolatile(final Object thisObj, Object o, long offset) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        byte result = getByte(thisObj, o, offset);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putByte(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, byte x) {
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Byte);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putByteVolatile(final Object thisObj, Object o, long offset, byte x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putByte(thisObj, o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static short getShort(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
+        @JavacBug(id = 6995200)
+        Short result = UnsafeLoadNode.load(o, 0, offset, Kind.Short);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static short getShortVolatile(final Object thisObj, Object o, long offset) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        short result = getShort(thisObj, o, offset);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putShort(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, short x) {
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Short);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putShortVolatile(final Object thisObj, Object o, long offset, short x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putShort(thisObj, o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static char getChar(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
+        @JavacBug(id = 6995200)
+        Character result = UnsafeLoadNode.load(o, 0, offset, Kind.Char);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static char getCharVolatile(final Object thisObj, Object o, long offset) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        char result = getChar(thisObj, o, offset);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putChar(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, char x) {
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Char);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putCharVolatile(final Object thisObj, Object o, long offset, char x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putChar(thisObj, o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static long getLong(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
+        @JavacBug(id = 6995200)
+        Long result = UnsafeLoadNode.load(o, 0, offset, Kind.Long);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static long getLongVolatile(final Object thisObj, Object o, long offset) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        long result = getLong(thisObj, o, offset);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putLong(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, long x) {
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Long);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putLongVolatile(final Object thisObj, Object o, long offset, long x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putLong(thisObj, o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putOrderedLong(final Object thisObj, Object o, long offset, long x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putLong(thisObj, o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static float getFloat(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
+        @JavacBug(id = 6995200)
+        Float result = UnsafeLoadNode.load(o, 0, offset, Kind.Float);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static float getFloatVolatile(final Object thisObj, Object o, long offset) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        float result = getFloat(thisObj, o, offset);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putFloat(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, float x) {
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Float);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putFloatVolatile(final Object thisObj, Object o, long offset, float x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putFloat(thisObj, o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static double getDouble(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
+        @JavacBug(id = 6995200)
+        Double result = UnsafeLoadNode.load(o, 0, offset, Kind.Double);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static double getDoubleVolatile(final Object thisObj, Object o, long offset) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
+        double result = getDouble(thisObj, o, offset);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
+        return result;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putDouble(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, double x) {
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Double);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putDoubleVolatile(final Object thisObj, Object o, long offset, double x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putDouble(thisObj, o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putByte(@SuppressWarnings("unused") final Object thisObj, long address, byte value) {
+        DirectStoreNode.store(address, value);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putShort(@SuppressWarnings("unused") final Object thisObj, long address, short value) {
+        DirectStoreNode.store(address, value);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putChar(@SuppressWarnings("unused") final Object thisObj, long address, char value) {
+        DirectStoreNode.store(address, value);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putInt(@SuppressWarnings("unused") final Object thisObj, long address, int value) {
+        DirectStoreNode.store(address, value);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putLong(@SuppressWarnings("unused") final Object thisObj, long address, long value) {
+        DirectStoreNode.store(address, value);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putFloat(@SuppressWarnings("unused") final Object thisObj, long address, float value) {
+        DirectStoreNode.store(address, value);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static void putDouble(@SuppressWarnings("unused") final Object thisObj, long address, double value) {
+        DirectStoreNode.store(address, value);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static byte getByte(@SuppressWarnings("unused") final Object thisObj, long address) {
+        return DirectReadNode.read(address, Kind.Byte);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static short getShort(@SuppressWarnings("unused") final Object thisObj, long address) {
+        return DirectReadNode.read(address, Kind.Short);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static char getChar(@SuppressWarnings("unused") final Object thisObj, long address) {
+        return DirectReadNode.read(address, Kind.Char);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static int getInt(@SuppressWarnings("unused") final Object thisObj, long address) {
+        return DirectReadNode.read(address, Kind.Int);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static long getLong(@SuppressWarnings("unused") final Object thisObj, long address) {
+        return DirectReadNode.read(address, Kind.Long);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static float getFloat(@SuppressWarnings("unused") final Object thisObj, long address) {
+        return DirectReadNode.read(address, Kind.Float);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static double getDouble(@SuppressWarnings("unused") final Object thisObj, long address) {
+        return DirectReadNode.read(address, Kind.Double);
+    }
+}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/UnsignedMathSnippets.java	Sun Jan 13 19:32:16 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.snippets;
-
-import static com.oracle.graal.nodes.MaterializeNode.*;
-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.*;
-
-/**
- * Snippets for {@link UnsignedMath}.
- */
-@ClassSubstitution(UnsignedMath.class)
-public class UnsignedMathSnippets implements SnippetsInterface {
-
-    public static boolean aboveThan(int a, int b) {
-        return materialize(BT, b, a);
-    }
-
-    public static boolean aboveOrEqual(int a, int b) {
-        return !materialize(BT, a, b);
-    }
-
-    /**
-     * Unsigned comparison belowThan for two numbers.
-     */
-    public static boolean belowThan(int a, int b) {
-        return materialize(BT, a, b);
-    }
-
-    /**
-     * Unsigned comparison belowOrEqual for two numbers.
-     */
-    public static boolean belowOrEqual(int a, int b) {
-        return !materialize(BT, b, a);
-    }
-
-    /**
-     * Unsigned comparison aboveThan for two numbers.
-     */
-    public static boolean aboveThan(long a, long b) {
-        return materialize(BT, b, a);
-    }
-
-    /**
-     * Unsigned comparison aboveOrEqual for two numbers.
-     */
-    public static boolean aboveOrEqual(long a, long b) {
-        return !materialize(BT, a, b);
-    }
-
-    /**
-     * Unsigned comparison belowThan for two numbers.
-     */
-    public static boolean belowThan(long a, long b) {
-        return materialize(BT, a, b);
-    }
-
-    /**
-     * Unsigned comparison belowOrEqual for two numbers.
-     */
-    public static boolean belowOrEqual(long a, long b) {
-        return !materialize(BT, b, a);
-    }
-
-    /**
-     * Unsigned division for two numbers.
-     */
-    public static int divide(int a, int b) {
-        return unsignedDivide(Kind.Int, a, b);
-    }
-
-    /**
-     * Unsigned remainder for two numbers.
-     */
-    public static int remainder(int a, int b) {
-        return unsignedRemainder(Kind.Int, a, b);
-    }
-
-    /**
-     * Unsigned division for two numbers.
-     */
-    public static long divide(long a, long b) {
-        return unsignedDivide(Kind.Long, a, b);
-    }
-
-    /**
-     * Unsigned remainder for two numbers.
-     */
-    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.snippets/src/com/oracle/graal/snippets/UnsignedMathSubstitutions.java	Sun Jan 13 21:55:49 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.snippets;
+
+import static com.oracle.graal.nodes.MaterializeNode.*;
+import static com.oracle.graal.nodes.calc.Condition.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.snippets.ClassSubstitution.*;
+
+/**
+ * Substitutions for {@link UnsignedMath}.
+ */
+@ClassSubstitution(UnsignedMath.class)
+public class UnsignedMathSubstitutions {
+
+    @MethodSubstitution
+    public static boolean aboveThan(int a, int b) {
+        return materialize(BT, b, a);
+    }
+
+    @MethodSubstitution
+    public static boolean aboveOrEqual(int a, int b) {
+        return !materialize(BT, a, b);
+    }
+
+    /**
+     * Unsigned comparison belowThan for two numbers.
+     */
+    @MethodSubstitution
+    public static boolean belowThan(int a, int b) {
+        return materialize(BT, a, b);
+    }
+
+    /**
+     * Unsigned comparison belowOrEqual for two numbers.
+     */
+    @MethodSubstitution
+    public static boolean belowOrEqual(int a, int b) {
+        return !materialize(BT, b, a);
+    }
+
+    /**
+     * Unsigned comparison aboveThan for two numbers.
+     */
+    @MethodSubstitution
+    public static boolean aboveThan(long a, long b) {
+        return materialize(BT, b, a);
+    }
+
+    /**
+     * Unsigned comparison aboveOrEqual for two numbers.
+     */
+    @MethodSubstitution
+    public static boolean aboveOrEqual(long a, long b) {
+        return !materialize(BT, a, b);
+    }
+
+    /**
+     * Unsigned comparison belowThan for two numbers.
+     */
+    @MethodSubstitution
+    public static boolean belowThan(long a, long b) {
+        return materialize(BT, a, b);
+    }
+
+    /**
+     * Unsigned comparison belowOrEqual for two numbers.
+     */
+    @MethodSubstitution
+    public static boolean belowOrEqual(long a, long b) {
+        return !materialize(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);
+}