changeset 7229:855b2c53543f

enforce that method substitution snippets are static methods
author Christian Haeubl <haeubl@ssw.jku.at>
date Fri, 14 Dec 2012 14:33:56 +0100
parents 57e6f9162c43
children 762717d2cf90
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ClassSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ThreadSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/UnsafeSnippets.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/ClassSubstitution.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java
diffstat 6 files changed, 147 insertions(+), 82 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ClassSnippets.java	Fri Dec 14 13:26:19 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ClassSnippets.java	Fri Dec 14 14:33:56 2012 +0100
@@ -27,14 +27,14 @@
 import java.lang.reflect.*;
 
 import com.oracle.graal.snippets.*;
-import com.oracle.graal.snippets.ClassSubstitution.InstanceMethodSubstitution;
+import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution;
 
 /**
  * Snippets for {@link java.lang.Class} methods.
  */
 @ClassSubstitution(java.lang.Class.class)
 public class ClassSnippets implements SnippetsInterface {
-    @InstanceMethodSubstitution
+    @MethodSubstitution(isStatic = false)
     public static int getModifiers(final Class<?> thisObj) {
         Word klass = loadWordFromObject(thisObj, klassOffset());
         if (klass == Word.zero()) {
@@ -45,7 +45,7 @@
         }
     }
 
-    @InstanceMethodSubstitution
+    @MethodSubstitution(isStatic = false)
     public static boolean isInterface(final Class<?> thisObj) {
         Word klass = loadWordFromObject(thisObj, klassOffset());
         if (klass == Word.zero()) {
@@ -56,7 +56,7 @@
         }
     }
 
-    @InstanceMethodSubstitution
+    @MethodSubstitution(isStatic = false)
     public static boolean isArray(final Class<?> thisObj) {
         Word klass = loadWordFromObject(thisObj, klassOffset());
         if (klass == Word.zero()) {
@@ -67,13 +67,13 @@
         }
     }
 
-    @InstanceMethodSubstitution
+    @MethodSubstitution(isStatic = false)
     public static boolean isPrimitive(final Class<?> thisObj) {
         Word klass = loadWordFromObject(thisObj, klassOffset());
         return klass == Word.zero();
     }
 
-    @InstanceMethodSubstitution
+    @MethodSubstitution(isStatic = false)
     public static Class<?> getSuperclass(final Class<?> thisObj) {
         Word klass = loadWordFromObject(thisObj, klassOffset());
         if (klass != Word.zero()) {
@@ -95,7 +95,7 @@
         return null;
     }
 
-    @InstanceMethodSubstitution
+    @MethodSubstitution(isStatic = false)
     public static Class<?> getComponentType(final Class<?> thisObj) {
         Word klass = loadWordFromObject(thisObj, klassOffset());
         if (klass != Word.zero()) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectSnippets.java	Fri Dec 14 13:26:19 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectSnippets.java	Fri Dec 14 14:33:56 2012 +0100
@@ -26,20 +26,20 @@
 
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.snippets.*;
-import com.oracle.graal.snippets.ClassSubstitution.InstanceMethodSubstitution;
+import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution;
 
 /**
  * Snippets for {@link java.lang.Object} methods.
  */
 @ClassSubstitution(java.lang.Object.class)
 public class ObjectSnippets implements SnippetsInterface {
-    @InstanceMethodSubstitution
+    @MethodSubstitution(isStatic = false)
     public static Class<?> getClass(final Object thisObj) {
         Word hub = loadHub(thisObj);
         return (Class<?>) readFinalObject(hub, classMirrorOffset());
     }
 
-    @InstanceMethodSubstitution
+    @MethodSubstitution(isStatic = false)
     public static int hashCode(final Object thisObj) {
         Word mark = loadWordFromObject(thisObj, markOffset());
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ThreadSnippets.java	Fri Dec 14 13:26:19 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ThreadSnippets.java	Fri Dec 14 14:33:56 2012 +0100
@@ -26,7 +26,7 @@
 
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.snippets.*;
-import com.oracle.graal.snippets.ClassSubstitution.InstanceMethodSubstitution;
+import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution;
 
 /**
  * Snippets for {@link java.lang.Thread} methods.
@@ -37,7 +37,7 @@
         return CurrentThread.get();
     }
 
-    @InstanceMethodSubstitution
+    @MethodSubstitution(isStatic = false)
     @SuppressWarnings("unused")
     private static boolean isInterrupted(final Thread thisObject, boolean clearInterrupted) {
         Word rawThread = HotSpotCurrentRawThreadNode.get();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/UnsafeSnippets.java	Fri Dec 14 13:26:19 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/UnsafeSnippets.java	Fri Dec 14 14:33:56 2012 +0100
@@ -28,300 +28,356 @@
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.snippets.*;
+import com.oracle.graal.snippets.ClassSubstitution.*;
 
 /**
  * Snippets for {@link sun.misc.Unsafe} methods.
  */
 @ClassSubstitution(sun.misc.Unsafe.class)
 public class UnsafeSnippets implements SnippetsInterface {
-
-    public boolean compareAndSwapObject(Object o, long offset, Object expected, Object x) {
+    @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);
     }
 
-    public boolean compareAndSwapInt(Object o, long offset, int expected, int 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);
     }
 
-    public boolean compareAndSwapLong(Object o, long offset, long expected, long 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);
     }
 
-    public Object getObject(Object o, long offset) {
+    @MethodSubstitution(isStatic = false)
+    public static Object getObject(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
         return UnsafeLoadNode.load(o, 0, offset, Kind.Object);
     }
 
-    public Object getObjectVolatile(Object o, long offset) {
+    @MethodSubstitution(isStatic = false)
+    public static Object getObjectVolatile(final Object thisObj, Object o, long offset) {
         MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
-        Object result = getObject(o, offset);
+        Object result = getObject(thisObj, o, offset);
         MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
         return result;
     }
 
-    public void putObject(Object o, long offset, Object x) {
+    @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);
     }
 
-    public void putObjectVolatile(Object o, long offset, Object x) {
+    @MethodSubstitution(isStatic = false)
+    public static void putObjectVolatile(final Object thisObj, Object o, long offset, Object x) {
         MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
-        putObject(o, offset, x);
+        putObject(thisObj, o, offset, x);
         MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
     }
 
-    public void putOrderedObject(Object o, long offset, Object x) {
+    @MethodSubstitution(isStatic = false)
+    public static void putOrderedObject(final Object thisObj, Object o, long offset, Object x) {
         MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
-        putObject(o, offset, x);
+        putObject(thisObj, o, offset, x);
         MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
     }
 
-    public int getInt(Object o, long offset) {
+    @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;
     }
 
-    public int getIntVolatile(Object o, long offset) {
+    @MethodSubstitution(isStatic = false)
+    public static int getIntVolatile(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
         MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
         int result = getInt(o, offset);
         MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
         return result;
     }
 
-    public void putInt(Object o, long offset, int x) {
+    @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);
     }
 
-    public void putIntVolatile(Object o, long offset, int x) {
+    @MethodSubstitution(isStatic = false)
+    public static void putIntVolatile(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, int x) {
         MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
         putInt(o, offset, x);
         MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
     }
 
-    public void putOrderedInt(Object o, long offset, int x) {
+    @MethodSubstitution(isStatic = false)
+    public static void putOrderedInt(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, int x) {
         MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
         putInt(o, offset, x);
         MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
     }
 
-    public boolean getBoolean(Object o, long offset) {
+    @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;
     }
 
-    public boolean getBooleanVolatile(Object o, long offset) {
+    @MethodSubstitution(isStatic = false)
+    public static boolean getBooleanVolatile(final Object thisObj, Object o, long offset) {
         MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
-        boolean result = getBoolean(o, offset);
+        boolean result = getBoolean(thisObj, o, offset);
         MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
         return result;
     }
 
-    public void putBoolean(Object o, long offset, boolean x) {
+    @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);
     }
 
-    public void putBooleanVolatile(Object o, long offset, boolean x) {
+    @MethodSubstitution(isStatic = false)
+    public static void putBooleanVolatile(final Object thisObj, Object o, long offset, boolean x) {
         MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
-        putBoolean(o, offset, x);
+        putBoolean(thisObj, o, offset, x);
         MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
     }
 
-    public byte getByte(Object o, long offset) {
+    @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;
     }
 
-    public byte getByteVolatile(Object o, long offset) {
+    @MethodSubstitution(isStatic = false)
+    public static byte getByteVolatile(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
         MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
         byte result = getByte(o, offset);
         MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
         return result;
     }
 
-    public void putByte(Object o, long offset, byte x) {
+    @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);
     }
 
-    public void putByteVolatile(Object o, long offset, byte x) {
+    @MethodSubstitution(isStatic = false)
+    public static void putByteVolatile(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, byte x) {
         MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
         putByte(o, offset, x);
         MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
     }
 
-    public short getShort(Object o, long offset) {
+    @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;
     }
 
-    public short getShortVolatile(Object o, long offset) {
+    @MethodSubstitution(isStatic = false)
+    public static short getShortVolatile(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
         MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
         short result = getShort(o, offset);
         MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
         return result;
     }
 
-    public void putShort(Object o, long offset, short x) {
+    @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);
     }
 
-    public void putShortVolatile(Object o, long offset, short x) {
+    @MethodSubstitution(isStatic = false)
+    public static void putShortVolatile(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, short x) {
         MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
         putShort(o, offset, x);
         MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
     }
 
-    public char getChar(Object o, long offset) {
+    @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;
     }
 
-    public char getCharVolatile(Object o, long offset) {
+    @MethodSubstitution(isStatic = false)
+    public static char getCharVolatile(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
         MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
         char result = getChar(o, offset);
         MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
         return result;
     }
 
-    public void putChar(Object o, long offset, char x) {
+    @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);
     }
 
-    public void putCharVolatile(Object o, long offset, char x) {
+    @MethodSubstitution(isStatic = false)
+    public static void putCharVolatile(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, char x) {
         MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
         putChar(o, offset, x);
         MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
     }
 
-    public long getLong(Object o, long offset) {
+    @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;
     }
 
-    public long getLongVolatile(Object o, long offset) {
+    @MethodSubstitution(isStatic = false)
+    public static long getLongVolatile(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
         MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
         long result = getLong(o, offset);
         MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
         return result;
     }
 
-    public void putLong(Object o, long offset, long x) {
+    @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);
     }
 
-    public void putLongVolatile(Object o, long offset, long x) {
+    @MethodSubstitution(isStatic = false)
+    public static void putLongVolatile(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, long x) {
         MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
         putLong(o, offset, x);
         MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
     }
 
-    public void putOrderedLong(Object o, long offset, long x) {
+    @MethodSubstitution(isStatic = false)
+    public static void putOrderedLong(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, long x) {
         MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
         putLong(o, offset, x);
         MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
     }
 
-    public float getFloat(Object o, long offset) {
+    @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;
     }
 
-    public float getFloatVolatile(Object o, long offset) {
+    @MethodSubstitution(isStatic = false)
+    public static float getFloatVolatile(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
         MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
         float result = getFloat(o, offset);
         MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
         return result;
     }
 
-    public void putFloat(Object o, long offset, float x) {
+    @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);
     }
 
-    public void putFloatVolatile(Object o, long offset, float x) {
+    @MethodSubstitution(isStatic = false)
+    public static void putFloatVolatile(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, float x) {
         MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
         putFloat(o, offset, x);
         MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
     }
 
-    public double getDouble(Object o, long offset) {
+    @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;
     }
 
-    public double getDoubleVolatile(Object o, long offset) {
+    @MethodSubstitution(isStatic = false)
+    public static double getDoubleVolatile(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
         MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
         double result = getDouble(o, offset);
         MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
         return result;
     }
 
-    public void putDouble(Object o, long offset, double x) {
+    @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);
     }
 
-    public void putDoubleVolatile(Object o, long offset, double x) {
+    @MethodSubstitution(isStatic = false)
+    public static void putDoubleVolatile(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, double x) {
         MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
         putDouble(o, offset, x);
         MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
     }
 
-    public void putByte(long address, byte value) {
+    @MethodSubstitution(isStatic = false)
+    public static void putByte(@SuppressWarnings("unused") final Object thisObj, long address, byte value) {
         DirectStoreNode.store(address, value);
     }
 
-    public void putShort(long address, short value) {
+    @MethodSubstitution(isStatic = false)
+    public static void putShort(@SuppressWarnings("unused") final Object thisObj, long address, short value) {
         DirectStoreNode.store(address, value);
     }
 
-    public void putChar(long address, char value) {
+    @MethodSubstitution(isStatic = false)
+    public static void putChar(@SuppressWarnings("unused") final Object thisObj, long address, char value) {
         DirectStoreNode.store(address, value);
     }
 
-    public void putInt(long address, int value) {
+    @MethodSubstitution(isStatic = false)
+    public static void putInt(@SuppressWarnings("unused") final Object thisObj, long address, int value) {
         DirectStoreNode.store(address, value);
     }
 
-    public void putLong(long address, long value) {
+    @MethodSubstitution(isStatic = false)
+    public static void putLong(@SuppressWarnings("unused") final Object thisObj, long address, long value) {
         DirectStoreNode.store(address, value);
     }
 
-    public void putFloat(long address, float value) {
+    @MethodSubstitution(isStatic = false)
+    public static void putFloat(@SuppressWarnings("unused") final Object thisObj, long address, float value) {
         DirectStoreNode.store(address, value);
     }
 
-    public void putDouble(long address, double value) {
+    @MethodSubstitution(isStatic = false)
+    public static void putDouble(@SuppressWarnings("unused") final Object thisObj, long address, double value) {
         DirectStoreNode.store(address, value);
     }
 
-    public byte getByte(long address) {
+    @MethodSubstitution(isStatic = false)
+    public static byte getByte(@SuppressWarnings("unused") final Object thisObj, long address) {
         return DirectReadNode.read(address, Kind.Byte);
     }
 
-    public short getShort(long address) {
+    @MethodSubstitution(isStatic = false)
+    public static short getShort(@SuppressWarnings("unused") final Object thisObj, long address) {
         return DirectReadNode.read(address, Kind.Short);
     }
 
-    public char getChar(long address) {
+    @MethodSubstitution(isStatic = false)
+    public static char getChar(@SuppressWarnings("unused") final Object thisObj, long address) {
         return DirectReadNode.read(address, Kind.Char);
     }
 
-    public int getInt(long address) {
+    @MethodSubstitution(isStatic = false)
+    public static int getInt(@SuppressWarnings("unused") final Object thisObj, long address) {
         return DirectReadNode.read(address, Kind.Int);
     }
 
-    public long getLong(long address) {
+    @MethodSubstitution(isStatic = false)
+    public static long getLong(@SuppressWarnings("unused") final Object thisObj, long address) {
         return DirectReadNode.read(address, Kind.Long);
     }
 
-    public float getFloat(long address) {
+    @MethodSubstitution(isStatic = false)
+    public static float getFloat(@SuppressWarnings("unused") final Object thisObj, long address) {
         return DirectReadNode.read(address, Kind.Float);
     }
 
-    public double getDouble(long address) {
+    @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/ClassSubstitution.java	Fri Dec 14 13:26:19 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/ClassSubstitution.java	Fri Dec 14 14:33:56 2012 +0100
@@ -40,10 +40,15 @@
      */
     @Retention(RetentionPolicy.RUNTIME)
     @Target(ElementType.METHOD)
-    public @interface InstanceMethodSubstitution {
+    public @interface MethodSubstitution {
         /**
          * Get the name of the original method.
          */
         String value() default "";
+
+        /**
+         * Determine if the substituted method is static.
+         */
+        boolean isStatic() default true;
     }
 }
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java	Fri Dec 14 13:26:19 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java	Fri Dec 14 14:33:56 2012 +0100
@@ -37,7 +37,7 @@
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
-import com.oracle.graal.snippets.ClassSubstitution.InstanceMethodSubstitution;
+import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution;
 import com.oracle.graal.snippets.Snippet.DefaultSnippetInliningPolicy;
 import com.oracle.graal.snippets.Snippet.SnippetInliningPolicy;
 
@@ -106,24 +106,28 @@
                 continue;
             }
             try {
-                InstanceMethodSubstitution methodSubstitution = method.getAnnotation(InstanceMethodSubstitution.class);
+                MethodSubstitution methodSubstitution = method.getAnnotation(MethodSubstitution.class);
                 String originalName = method.getName();
                 Class<?>[] originalParameters = method.getParameterTypes();
                 if (methodSubstitution != null) {
                     if (!methodSubstitution.value().isEmpty()) {
                         originalName = methodSubstitution.value();
                     }
-                    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;
+                    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");
                 }
                 int modifiers = method.getModifiers();
-                if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) {
+                if (!Modifier.isStatic(modifiers)) {
+                    throw new RuntimeException("Snippets must be static methods");
+                } else if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) {
                     throw new RuntimeException("Snippet must not be abstract or native");
                 }
                 ResolvedJavaMethod snippet = runtime.lookupJavaMethod(method);