changeset 9421:20dc10bb82d1

Merge.
author Doug Simon <doug.simon@oracle.com>
date Tue, 30 Apr 2013 00:34:07 +0200
parents 393d62a868da (diff) 16c354398d09 (current diff)
children 149fe42411df a14fef4fca7d
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java src/share/vm/graal/graalCompilerToVM.cpp
diffstat 16 files changed, 322 insertions(+), 144 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Mon Apr 29 11:31:29 2013 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Tue Apr 30 00:34:07 2013 +0200
@@ -25,14 +25,11 @@
 import static com.oracle.graal.amd64.AMD64.*;
 import static com.oracle.graal.compiler.amd64.AMD64LIRGenerator.*;
 import static com.oracle.graal.hotspot.amd64.AMD64DeoptimizeOp.*;
+import static com.oracle.graal.hotspot.amd64.AMD64HotSpotBackend.*;
 import static com.oracle.graal.hotspot.amd64.AMD64HotSpotUnwindOp.*;
 import static com.oracle.graal.hotspot.nodes.IdentityHashCodeStubCall.*;
 import static com.oracle.graal.hotspot.nodes.MonitorEnterStubCall.*;
 import static com.oracle.graal.hotspot.nodes.MonitorExitStubCall.*;
-import static com.oracle.graal.hotspot.nodes.NewArrayStubCall.*;
-import static com.oracle.graal.hotspot.nodes.NewInstanceStubCall.*;
-import static com.oracle.graal.hotspot.nodes.NewMultiArrayStubCall.*;
-import static com.oracle.graal.hotspot.nodes.ThreadIsInterruptedStubCall.*;
 import static com.oracle.graal.hotspot.nodes.VMErrorNode.*;
 import static com.oracle.graal.hotspot.nodes.VerifyOopStubCall.*;
 import static com.oracle.graal.hotspot.nodes.WriteBarrierPostStubCall.*;
@@ -41,9 +38,6 @@
 import static com.oracle.graal.hotspot.replacements.AESCryptSubstitutions.EncryptBlockStubCall.*;
 import static com.oracle.graal.hotspot.replacements.CipherBlockChainingSubstitutions.DecryptAESCryptStubCall.*;
 import static com.oracle.graal.hotspot.replacements.CipherBlockChainingSubstitutions.EncryptAESCryptStubCall.*;
-import static com.oracle.graal.hotspot.stubs.NewArrayStub.*;
-import static com.oracle.graal.hotspot.stubs.NewInstanceStub.*;
-import static com.oracle.graal.hotspot.stubs.NewMultiArrayStub.*;
 
 import com.oracle.graal.amd64.*;
 import com.oracle.graal.api.code.*;
@@ -106,42 +100,6 @@
                 /* arg0: object */ javaCallingConvention(Kind.Object,
                 /* arg1:   lock */                       word));
 
-        addStubCall(NEW_ARRAY,
-                /*          ret */ rax.asValue(Kind.Object),
-                /* arg0:    hub */ rdx.asValue(word),
-                /* arg1: length */ rbx.asValue(Kind.Int));
-
-        addRuntimeCall(NEW_ARRAY_C, config.newArrayAddress,
-                /*        temps */ null,
-                /*          ret */ ret(Kind.Void),
-                /* arg0: thread */ nativeCallingConvention(word,
-                /* arg1:    hub */                         word,
-                /* arg2: length */                         Kind.Int));
-
-        addStubCall(NEW_INSTANCE,
-                /*          ret */ rax.asValue(Kind.Object),
-                /* arg0:    hub */ rdx.asValue(word));
-
-        addRuntimeCall(NEW_INSTANCE_C, config.newInstanceAddress,
-                /*        temps */ null,
-                /*          ret */ ret(Kind.Void),
-                /* arg0: thread */ nativeCallingConvention(word,
-                /* arg1:    hub */                         word));
-
-        addStubCall(NEW_MULTI_ARRAY,
-                /*          ret */ rax.asValue(Kind.Object),
-                /* arg0:    hub */ rax.asValue(word),
-                /* arg1:   rank */ rbx.asValue(Kind.Int),
-                /* arg2:   dims */ rcx.asValue(word));
-
-        addRuntimeCall(NEW_MULTI_ARRAY_C, config.newMultiArrayAddress,
-                /*        temps */ null,
-                /*          ret */ ret(Kind.Void),
-                /* arg0: thread */ nativeCallingConvention(word,
-                /* arg1:    hub */                         word,
-                /* arg2:   rank */                         Kind.Int,
-                /* arg3:   dims */                         word));
-
         addRuntimeCall(VERIFY_OOP, config.verifyOopStub,
                 /*        temps */ null,
                 /*          ret */ ret(Kind.Void),
@@ -159,12 +117,6 @@
                 /*          ret */ rax.asValue(Kind.Int),
                 /* arg0:    obj */ javaCallingConvention(Kind.Object));
 
-        addRuntimeCall(THREAD_IS_INTERRUPTED, config.threadIsInterruptedStub,
-                /*        temps */ null,
-                /*          ret */ rax.asValue(Kind.Boolean),
-                /* arg0: thread */ javaCallingConvention(Kind.Object,
-      /* arg1: clearInterrupted */                       Kind.Boolean));
-
         addRuntimeCall(ENCRYPT_BLOCK, config.aescryptEncryptBlockStub,
                 /*        temps */ null,
                 /*          ret */ ret(Kind.Void),
@@ -197,15 +149,15 @@
                 /* arg3:      r */                         word,
               /* arg4: inLength */                         Kind.Int));
 
-        addRuntimeCall(AMD64HotSpotBackend.EXCEPTION_HANDLER, config.handleExceptionStub,
+        addRuntimeCall(EXCEPTION_HANDLER, config.handleExceptionStub,
                 /*        temps */ null,
                 /*          ret */ ret(Kind.Void));
 
-        addRuntimeCall(AMD64HotSpotBackend.DEOPT_HANDLER, config.handleDeoptStub,
+        addRuntimeCall(DEOPT_HANDLER, config.handleDeoptStub,
                 /*        temps */ null,
                 /*          ret */ ret(Kind.Void));
 
-        addRuntimeCall(AMD64HotSpotBackend.IC_MISS_HANDLER, config.inlineCacheMissStub,
+        addRuntimeCall(IC_MISS_HANDLER, config.inlineCacheMissStub,
                 /*        temps */ null,
                 /*          ret */ ret(Kind.Void));
         // @formatter:on
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java	Mon Apr 29 11:31:29 2013 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java	Tue Apr 30 00:34:07 2013 +0200
@@ -57,8 +57,11 @@
 
     private final CompilerToVM vm;
 
-    public HotSpotRuntimeCallTarget(Descriptor descriptor, long address, CallingConvention cc, CompilerToVM vm) {
+    private final boolean isCRuntimeCall;
+
+    public HotSpotRuntimeCallTarget(Descriptor descriptor, long address, boolean isCRuntimeCall, CallingConvention cc, CompilerToVM vm) {
         this.address = address;
+        this.isCRuntimeCall = isCRuntimeCall;
         this.descriptor = descriptor;
         this.cc = cc;
         this.vm = vm;
@@ -88,7 +91,7 @@
 
     public void finalizeAddress(Backend backend) {
         if (address == 0) {
-            assert stub != null : "linkage without an address must be a stub";
+            assert stub != null : "linkage without an address must be a stub - forgot to register a Stub associated with " + descriptor + "?";
             InstalledCode code = stub.getCode(backend);
 
             AllocatableValue[] argumentLocations = new AllocatableValue[cc.getArgumentCount()];
@@ -118,7 +121,6 @@
      * Determines if this is a link to a C/C++ function in the HotSpot runtime.
      */
     public boolean isCRuntimeCall() {
-        HotSpotVMConfig config = HotSpotGraalRuntime.graalRuntime().getConfig();
-        return address == config.newArrayAddress || address == config.newInstanceAddress || address == config.newMultiArrayAddress;
+        return isCRuntimeCall;
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Mon Apr 29 11:31:29 2013 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Tue Apr 30 00:34:07 2013 +0200
@@ -356,7 +356,6 @@
     public long deoptimizeStub;
     public long unwindExceptionStub;
     public long osrMigrationEndStub;
-    public long registerFinalizerStub;
     public long createNullPointerExceptionStub;
     public long createOutOfBoundsExceptionStub;
     public long javaTimeMillisStub;
@@ -371,7 +370,6 @@
     public long logPrintfStub;
     public long stubPrintfStub;
     public int deoptReasonNone;
-    public long threadIsInterruptedStub;
     public long identityHashCodeStub;
     public long aescryptEncryptBlockStub;
     public long aescryptDecryptBlockStub;
@@ -381,6 +379,8 @@
     public long newInstanceAddress;
     public long newArrayAddress;
     public long newMultiArrayAddress;
+    public long registerFinalizerAddress;
+    public long threadIsInterruptedAddress;
 
     public int deoptReasonNullCheck;
     public int deoptReasonRangeCheck;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Mon Apr 29 11:31:29 2013 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Tue Apr 30 00:34:07 2013 +0200
@@ -33,8 +33,13 @@
 import static com.oracle.graal.hotspot.nodes.NewArrayStubCall.*;
 import static com.oracle.graal.hotspot.nodes.NewInstanceStubCall.*;
 import static com.oracle.graal.hotspot.nodes.NewMultiArrayStubCall.*;
+import static com.oracle.graal.hotspot.nodes.ThreadIsInterruptedStubCall.*;
 import static com.oracle.graal.hotspot.replacements.SystemSubstitutions.*;
-import static com.oracle.graal.hotspot.stubs.Stub.*;
+import static com.oracle.graal.hotspot.stubs.NewArrayStub.*;
+import static com.oracle.graal.hotspot.stubs.NewInstanceStub.*;
+import static com.oracle.graal.hotspot.stubs.NewMultiArrayStub.*;
+import static com.oracle.graal.hotspot.stubs.RegisterFinalizerStub.*;
+import static com.oracle.graal.hotspot.stubs.ThreadIsInterruptedStub.*;
 import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*;
 import static com.oracle.graal.nodes.java.RegisterFinalizerNode.*;
 import static com.oracle.graal.replacements.Log.*;
@@ -204,6 +209,7 @@
         this.graalRuntime = graalRuntime;
         regConfig = createRegisterConfig(false);
         globalStubRegConfig = createRegisterConfig(true);
+        Kind word = graalRuntime.getTarget().wordKind;
 
         // @formatter:off
 
@@ -212,11 +218,48 @@
                         /*             ret */ ret(Kind.Void),
                         /* arg0:      long */ javaCallingConvention(Kind.Long));
 
-        addRuntimeCall(REGISTER_FINALIZER, config.registerFinalizerStub,
-                        /*           temps */ null,
+        addStubCall(REGISTER_FINALIZER,
                         /*             ret */ ret(Kind.Void),
                         /* arg0:    object */ javaCallingConvention(Kind.Object));
 
+        addCRuntimeCall(REGISTER_FINALIZER_C, config.registerFinalizerAddress,
+                        /*             ret */ ret(Kind.Void),
+                        /* arg0:    thread */ nativeCallingConvention(word,
+                        /* arg1:    object */                         Kind.Object));
+
+        addStubCall(NEW_ARRAY,
+                        /*             ret */ ret(Kind.Object),
+                        /* arg0:       hub */ javaCallingConvention(word,
+                        /* arg1:    length */ Kind.Int));
+
+        addCRuntimeCall(NEW_ARRAY_C, config.newArrayAddress,
+                        /*             ret */ ret(Kind.Void),
+                        /* arg0:    thread */ nativeCallingConvention(word,
+                        /* arg1:       hub */                         word,
+                        /* arg2:    length */                         Kind.Int));
+
+        addStubCall(NEW_INSTANCE,
+                        /*             ret */ ret(Kind.Object),
+                        /* arg0:       hub */ javaCallingConvention(word));
+
+        addCRuntimeCall(NEW_INSTANCE_C, config.newInstanceAddress,
+                        /*             ret */ ret(Kind.Void),
+                        /* arg0:    thread */ nativeCallingConvention(word,
+                        /* arg1:       hub */                         word));
+
+        addStubCall(NEW_MULTI_ARRAY,
+                        /*             ret */ ret(Kind.Object),
+                        /* arg0:       hub */ javaCallingConvention(word,
+                        /* arg1:      rank */                       Kind.Int,
+                        /* arg2:      dims */                       word));
+
+        addCRuntimeCall(NEW_MULTI_ARRAY_C, config.newMultiArrayAddress,
+                        /*             ret */ ret(Kind.Void),
+                        /* arg0:    thread */ nativeCallingConvention(word,
+                        /* arg1:       hub */                         word,
+                        /* arg2:      rank */                         Kind.Int,
+                        /* arg3:      dims */                         word));
+
         addRuntimeCall(CREATE_NULL_POINTER_EXCEPTION, config.createNullPointerExceptionStub,
                         /*           temps */ null,
                         /*             ret */ ret(Kind.Object));
@@ -277,6 +320,18 @@
                         /*             ret */ ret(Kind.Void),
                         /* arg0:    object */ javaCallingConvention(Kind.Object,
                         /* arg1:     flags */                       Kind.Int));
+
+        addStubCall(THREAD_IS_INTERRUPTED,
+                        /*             ret */ ret(Kind.Boolean),
+                        /* arg0:    thread */ javaCallingConvention(Kind.Object,
+                 /* arg1: clearInterrupted */                       Kind.Boolean));
+
+        addCRuntimeCall(THREAD_IS_INTERRUPTED_C, config.threadIsInterruptedAddress,
+                        /*             ret */ ret(Kind.Boolean),
+                        /* arg0:    thread */ nativeCallingConvention(word,
+                   /* arg1: receiverThread */                         Kind.Object,
+              /* arg1: clearInterrupted */                            Kind.Boolean));
+
         // @formatter:on
     }
 
@@ -291,6 +346,14 @@
         return addRuntimeCall(descriptor, 0L, null, ret, args);
     }
 
+    protected RuntimeCallTarget addCRuntimeCall(Descriptor descriptor, long address, AllocatableValue ret, AllocatableValue... args) {
+        return addRuntimeCall(descriptor, address, true, null, ret, args);
+    }
+
+    protected RuntimeCallTarget addRuntimeCall(Descriptor descriptor, long address, Register[] tempRegs, AllocatableValue ret, AllocatableValue... args) {
+        return addRuntimeCall(descriptor, address, false, tempRegs, ret, args);
+    }
+
     /**
      * Registers the details for linking a runtime call.
      * 
@@ -300,7 +363,7 @@
      * @param ret where the call returns its result
      * @param args where arguments are passed to the call
      */
-    protected RuntimeCallTarget addRuntimeCall(Descriptor descriptor, long address, Register[] tempRegs, AllocatableValue ret, AllocatableValue... args) {
+    protected RuntimeCallTarget addRuntimeCall(Descriptor descriptor, long address, boolean isCRuntimeCall, Register[] tempRegs, AllocatableValue ret, AllocatableValue... args) {
         AllocatableValue[] temps = tempRegs == null || tempRegs.length == 0 ? AllocatableValue.NONE : new AllocatableValue[tempRegs.length];
         for (int i = 0; i < temps.length; i++) {
             temps[i] = tempRegs[i].asValue();
@@ -311,7 +374,7 @@
         for (int i = 0; i < argTypes.length; i++) {
             assert checkAssignable(argTypes[i], args[i]) : descriptor + " incompatible with argument location " + i + ": " + args[i];
         }
-        HotSpotRuntimeCallTarget runtimeCall = new HotSpotRuntimeCallTarget(descriptor, address, new CallingConvention(temps, 0, ret, args), graalRuntime.getCompilerToVM());
+        HotSpotRuntimeCallTarget runtimeCall = new HotSpotRuntimeCallTarget(descriptor, address, isCRuntimeCall, new CallingConvention(temps, 0, ret, args), graalRuntime.getCompilerToVM());
         runtimeCalls.put(descriptor, runtimeCall);
         return runtimeCall;
     }
@@ -364,6 +427,8 @@
         registerStub(new NewInstanceStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(NEW_INSTANCE)));
         registerStub(new NewArrayStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(NEW_ARRAY)));
         registerStub(new NewMultiArrayStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(NEW_MULTI_ARRAY)));
+        registerStub(new RegisterFinalizerStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(REGISTER_FINALIZER)));
+        registerStub(new ThreadIsInterruptedStub(this, replacements, graalRuntime.getTarget(), runtimeCalls.get(THREAD_IS_INTERRUPTED)));
     }
 
     private void registerStub(Stub stub) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ThreadIsInterruptedStubCall.java	Mon Apr 29 11:31:29 2013 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ThreadIsInterruptedStubCall.java	Tue Apr 30 00:34:07 2013 +0200
@@ -30,12 +30,13 @@
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.type.*;
 
 /**
- * Node implementing a call to HotSpot's ThreadIsInterrupted stub.
+ * Node implementing a call to {@link ThreadIsInterruptedStub}.
  */
 public class ThreadIsInterruptedStubCall extends DeoptimizingStubCall implements LIRGenLowerable {
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/CRuntimeStub.java	Tue Apr 30 00:34:07 2013 +0200
@@ -0,0 +1,49 @@
+/*
+ * 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.stubs;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.replacements.SnippetTemplate.Arguments;
+import com.oracle.graal.replacements.SnippetTemplate.SnippetInfo;
+
+/**
+ * Base class for a stub that saves registers around a C runtime call.
+ */
+public abstract class CRuntimeStub extends Stub {
+
+    public CRuntimeStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotRuntimeCallTarget linkage) {
+        super(runtime, replacements, target, linkage);
+    }
+
+    @Override
+    protected Arguments makeArguments(SnippetInfo stub) {
+        Arguments args = new Arguments(stub);
+        for (int i = 0; i < stub.getParameterCount(); i++) {
+            args.add(stub.getParameterName(i), null);
+        }
+        return args;
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Mon Apr 29 11:31:29 2013 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Tue Apr 30 00:34:07 2013 +0200
@@ -46,14 +46,14 @@
 
 /**
  * Stub implementing the fast path for TLAB refill during instance class allocation. This stub is
- * called from the {@linkplain NewObjectSnippets inline} allocation code when TLAB allocation fails.
- * If this stub fails to refill the TLAB or allocate the object, it calls out to the HotSpot C++
- * runtime to complete the allocation.
+ * called via {@link NewArrayStubCall} from the {@linkplain NewObjectSnippets inline} allocation
+ * code when TLAB allocation fails. If this stub fails to refill the TLAB or allocate the object, it
+ * calls out to the HotSpot C++ runtime to complete the allocation.
  */
 public class NewArrayStub extends Stub {
 
     public NewArrayStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotRuntimeCallTarget linkage) {
-        super(runtime, replacements, target, linkage, "newArray");
+        super(runtime, replacements, target, linkage);
     }
 
     @Override
@@ -116,7 +116,7 @@
         return verifyOop(getAndClearObjectResult(thread()));
     }
 
-    public static final Descriptor NEW_ARRAY_C = new Descriptor("new_array_c", false, void.class, Word.class, Word.class, int.class);
+    public static final Descriptor NEW_ARRAY_C = descriptorFor(NewArrayStub.class, "newArrayC", false);
 
     @NodeIntrinsic(CRuntimeCall.class)
     public static native void newArrayC(@ConstantNodeParameter Descriptor newArrayC, Word thread, Word hub, int length);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Mon Apr 29 11:31:29 2013 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Tue Apr 30 00:34:07 2013 +0200
@@ -48,14 +48,14 @@
 
 /**
  * Stub implementing the fast path for TLAB refill during instance class allocation. This stub is
- * called from the {@linkplain NewObjectSnippets inline} allocation code when TLAB allocation fails.
- * If this stub fails to refill the TLAB or allocate the object, it calls out to the HotSpot C++
- * runtime for to complete the allocation.
+ * called via {@link NewInstanceStubCall} from the {@linkplain NewObjectSnippets inline} allocation
+ * code when TLAB allocation fails. If this stub fails to refill the TLAB or allocate the object, it
+ * calls out to the HotSpot C++ runtime for to complete the allocation.
  */
 public class NewInstanceStub extends Stub {
 
     public NewInstanceStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotRuntimeCallTarget linkage) {
-        super(runtime, replacements, target, linkage, "newInstance");
+        super(runtime, replacements, target, linkage);
     }
 
     @Override
@@ -231,7 +231,7 @@
         return Boolean.getBoolean("graal.newInstanceStub.forceSlowPath");
     }
 
-    public static final Descriptor NEW_INSTANCE_C = new Descriptor("new_instance_c", false, void.class, Word.class, Word.class);
+    public static final Descriptor NEW_INSTANCE_C = descriptorFor(NewInstanceStub.class, "newInstanceC", false);
 
     @NodeIntrinsic(CRuntimeCall.class)
     public static native void newInstanceC(@ConstantNodeParameter Descriptor newInstanceC, Word thread, Word hub);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewMultiArrayStub.java	Mon Apr 29 11:31:29 2013 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewMultiArrayStub.java	Tue Apr 30 00:34:07 2013 +0200
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.hotspot.stubs;
 
-import static com.oracle.graal.api.code.DeoptimizationAction.*;
-import static com.oracle.graal.api.meta.DeoptimizationReason.*;
 import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*;
 
 import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
@@ -35,37 +33,25 @@
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.replacements.*;
-import com.oracle.graal.replacements.SnippetTemplate.Arguments;
-import com.oracle.graal.replacements.SnippetTemplate.SnippetInfo;
 import com.oracle.graal.word.*;
 
-public class NewMultiArrayStub extends Stub {
+/**
+ * Stub called from {@link NewMultiArrayStubCall}.
+ */
+public class NewMultiArrayStub extends CRuntimeStub {
 
     public NewMultiArrayStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotRuntimeCallTarget linkage) {
-        super(runtime, replacements, target, linkage, "newMultiArray");
-    }
-
-    @Override
-    protected Arguments makeArguments(SnippetInfo stub) {
-        Arguments args = new Arguments(stub);
-        args.add("hub", null);
-        args.add("rank", null);
-        args.add("dims", null);
-        return args;
+        super(runtime, replacements, target, linkage);
     }
 
     @Snippet
     private static Object newMultiArray(Word hub, int rank, Word dims) {
         newMultiArrayC(NEW_MULTI_ARRAY_C, thread(), hub, rank, dims);
-
-        if (clearPendingException(thread())) {
-            getAndClearObjectResult(thread());
-            DeoptimizeCallerNode.deopt(InvalidateReprofile, RuntimeConstraint);
-        }
+        handlePendingException(true);
         return verifyOop(getAndClearObjectResult(thread()));
     }
 
-    public static final Descriptor NEW_MULTI_ARRAY_C = new Descriptor("new_multi_array_c", false, void.class, Word.class, Word.class, int.class, Word.class);
+    public static final Descriptor NEW_MULTI_ARRAY_C = descriptorFor(NewMultiArrayStub.class, "newMultiArrayC", false);
 
     @NodeIntrinsic(CRuntimeCall.class)
     public static native void newMultiArrayC(@ConstantNodeParameter Descriptor newArrayC, Word thread, Word hub, int rank, Word dims);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/RegisterFinalizerStub.java	Tue Apr 30 00:34:07 2013 +0200
@@ -0,0 +1,58 @@
+/*
+ * 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.stubs;
+
+import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*;
+
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.graph.Node.ConstantNodeParameter;
+import com.oracle.graal.graph.Node.NodeIntrinsic;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.replacements.*;
+import com.oracle.graal.word.*;
+
+/**
+ * Stub called from {@link RegisterFinalizerNode}.
+ */
+public class RegisterFinalizerStub extends CRuntimeStub {
+
+    public RegisterFinalizerStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotRuntimeCallTarget linkage) {
+        super(runtime, replacements, target, linkage);
+    }
+
+    @Snippet
+    private static void registerFinalizer(Object object) {
+        registerFinalizerC(REGISTER_FINALIZER_C, thread(), object);
+        handlePendingException(false);
+    }
+
+    public static final Descriptor REGISTER_FINALIZER_C = descriptorFor(RegisterFinalizerStub.class, "registerFinalizerC", false);
+
+    @NodeIntrinsic(CRuntimeCall.class)
+    public static native void registerFinalizerC(@ConstantNodeParameter Descriptor registerFinalizerC, Word thread, Object object);
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Mon Apr 29 11:31:29 2013 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Tue Apr 30 00:34:07 2013 +0200
@@ -22,8 +22,12 @@
  */
 package com.oracle.graal.hotspot.stubs;
 
+import static com.oracle.graal.api.code.DeoptimizationAction.*;
+import static com.oracle.graal.api.meta.DeoptimizationReason.*;
 import static com.oracle.graal.hotspot.nodes.CStringNode.*;
+import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*;
 
+import java.lang.reflect.*;
 import java.util.*;
 import java.util.concurrent.*;
 
@@ -39,6 +43,7 @@
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
@@ -99,9 +104,9 @@
      * 
      * @param linkage linkage details for a call to the stub
      */
-    public Stub(HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotRuntimeCallTarget linkage, String methodName) {
+    public Stub(HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotRuntimeCallTarget linkage) {
         super(runtime, replacements, target);
-        this.stubInfo = snippet(getClass(), methodName);
+        this.stubInfo = snippet(getClass(), null);
         this.linkage = linkage;
     }
 
@@ -135,6 +140,28 @@
     }
 
     /**
+     * Looks for a {@link CRuntimeCall} node intrinsic named {@code name} in {@code stubClass} and
+     * returns a {@link Descriptor} based on its signature and the value of {@code hasSideEffect}.
+     */
+    protected static <T extends Stub> Descriptor descriptorFor(Class<T> stubClass, String name, boolean hasSideEffect) {
+        Method found = null;
+        for (Method method : stubClass.getDeclaredMethods()) {
+            if (Modifier.isStatic(method.getModifiers()) && method.getAnnotation(NodeIntrinsic.class) != null && method.getName().equals(name)) {
+                if (method.getAnnotation(NodeIntrinsic.class).value() == CRuntimeCall.class) {
+                    assert found == null : "found more than one C runtime call named " + name + " in " + stubClass;
+                    assert method.getParameterTypes().length != 0 && method.getParameterTypes()[0] == Descriptor.class : "first parameter of C runtime call '" + name + "' in " + stubClass +
+                                    " must be of type " + Descriptor.class.getSimpleName();
+                    found = method;
+                }
+            }
+        }
+        assert found != null : "could not find C runtime call named " + name + " in " + stubClass;
+        List<Class<?>> paramList = Arrays.asList(found.getParameterTypes());
+        Class[] cCallTypes = paramList.subList(1, paramList.size()).toArray(new Class[paramList.size() - 1]);
+        return new Descriptor(name, hasSideEffect, found.getReturnType(), cCallTypes);
+    }
+
+    /**
      * Gets the code for this stub, compiling it first if necessary.
      */
     public synchronized InstalledCode getCode(final Backend backend) {
@@ -166,6 +193,8 @@
                             if (Debug.isDumpEnabled()) {
                                 Debug.dump(new Object[]{compResult, installedCode}, "After code installation");
                             }
+                            // TTY.println(getMethod().toString());
+                            // TTY.println(runtime().disassemble(installedCode));
                             return installedCode;
                         }
                     });
@@ -200,6 +229,15 @@
         }
     }
 
+    static void handlePendingException(boolean isObjectResult) {
+        if (clearPendingException(thread())) {
+            if (isObjectResult) {
+                getAndClearObjectResult(thread());
+            }
+            DeoptimizeCallerNode.deopt(InvalidateReprofile, RuntimeConstraint);
+        }
+    }
+
     public static final Descriptor STUB_PRINTF = new Descriptor("stubPrintf", false, void.class, Word.class, long.class, long.class, long.class);
 
     @NodeIntrinsic(RuntimeCallNode.class)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ThreadIsInterruptedStub.java	Tue Apr 30 00:34:07 2013 +0200
@@ -0,0 +1,58 @@
+/*
+ * 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.stubs;
+
+import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*;
+
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.graph.Node.ConstantNodeParameter;
+import com.oracle.graal.graph.Node.NodeIntrinsic;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.replacements.*;
+import com.oracle.graal.word.*;
+
+/**
+ * Stub called from {@link ThreadIsInterruptedStubCall}.
+ */
+public class ThreadIsInterruptedStub extends CRuntimeStub {
+
+    public ThreadIsInterruptedStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotRuntimeCallTarget linkage) {
+        super(runtime, replacements, target, linkage);
+    }
+
+    @Snippet
+    private static boolean threadIsInterrupted(Thread receiverThread, boolean clearIsInterrupted) {
+        boolean result = threadIsInterruptedC(THREAD_IS_INTERRUPTED_C, thread(), receiverThread, clearIsInterrupted);
+        handlePendingException(false);
+        return result;
+    }
+
+    public static final Descriptor THREAD_IS_INTERRUPTED_C = descriptorFor(ThreadIsInterruptedStub.class, "threadIsInterruptedC", false);
+
+    @NodeIntrinsic(CRuntimeCall.class)
+    public static native boolean threadIsInterruptedC(@ConstantNodeParameter Descriptor newArrayC, Word thread, Thread receiverThread, boolean clearIsInterrupted);
+}
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Mon Apr 29 11:31:29 2013 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Tue Apr 30 00:34:07 2013 +0200
@@ -116,6 +116,10 @@
         public boolean isVarargsParameter(int paramIdx) {
             return varargsParameters[paramIdx];
         }
+
+        public String getParameterName(int paramIdx) {
+            return names[paramIdx];
+        }
     }
 
     /**
@@ -283,16 +287,20 @@
             this.templates = new ConcurrentHashMap<>();
         }
 
+        /**
+         * Finds the method in {@code declaringClass} annotated with {@link Snippet} named
+         * {@code methodName}. If {@code methodName} is null, then there must be exactly one snippet
+         * method in {@code declaringClass}.
+         */
         protected SnippetInfo snippet(Class<? extends Snippets> declaringClass, String methodName) {
             Method found = null;
             for (Method method : declaringClass.getDeclaredMethods()) {
-                if (method.getAnnotation(Snippet.class) != null && method.getName().equals(methodName)) {
-                    assert found == null : "found more than one @" + Snippet.class.getSimpleName() + " method " + methodName + " in " + declaringClass;
+                if (method.getAnnotation(Snippet.class) != null && (methodName == null || method.getName().equals(methodName))) {
+                    assert found == null : "found more than one @" + Snippet.class.getSimpleName() + " method in " + declaringClass + (methodName == null ? "" : " named " + methodName);
                     found = method;
                 }
             }
-            assert found != null : "did not find @" + Snippet.class.getSimpleName() + " method " + methodName + " in " + declaringClass;
-
+            assert found != null : "did not find @" + Snippet.class.getSimpleName() + " method in " + declaringClass + (methodName == null ? "" : " named " + methodName);
             return new SnippetInfo(runtime.lookupJavaMethod(found));
         }
 
--- a/src/cpu/x86/vm/graalRuntime_x86.cpp	Mon Apr 29 11:31:29 2013 -0700
+++ b/src/cpu/x86/vm/graalRuntime_x86.cpp	Tue Apr 30 00:34:07 2013 +0200
@@ -811,27 +811,6 @@
   OopMapSet* oop_maps = NULL;
   switch (id) {
 
-    case register_finalizer_id:
-      {
-        __ set_info("register_finalizer", dont_gc_arguments);
-
-        // This is called via call_runtime so the arguments
-        // will be place in C abi locations
-        __ verify_oop(j_rarg0);
-        __ enter();
-        OopMap* oop_map = save_live_registers(sasm, 2 /*num_rt_args */);
-        int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, SharedRuntime::register_finalizer), j_rarg0);
-        oop_maps = new OopMapSet();
-        oop_maps->add_gc_map(call_offset, oop_map);
-
-        // Now restore all the live registers
-        restore_live_registers(sasm);
-
-        __ leave();
-        __ ret(0);
-      }
-      break;
-
     case handle_exception_nofpu_id:
       { GraalStubFrame f(sasm, "handle_exception", dont_gc_arguments);
         oop_maps = generate_handle_exception(id, sasm);
@@ -1069,8 +1048,7 @@
       }
       __ ret(0);
       break;
-   }
-
+    }
 
     case identity_hash_code_id: {
       Register obj = j_rarg0; // Incoming
@@ -1085,21 +1063,6 @@
       __ ret(0);
       break;
     }
-    case thread_is_interrupted_id: {
-      Register thread = j_rarg0;
-      Register clear_interrupted = j_rarg1;
-
-      __ set_info("identity_hash_code", dont_gc_arguments);
-      __ enter();
-      OopMap* map = save_live_registers(sasm, 1);
-      int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, thread_is_interrupted), thread, clear_interrupted);
-      oop_maps = new OopMapSet();
-      oop_maps->add_gc_map(call_offset, map);
-      restore_live_registers_except_rax(sasm);
-      __ leave();
-      __ ret(0);
-      break;
-    }
 
     default:
       { GraalStubFrame f(sasm, "unimplemented entry", dont_gc_arguments);
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Mon Apr 29 11:31:29 2013 -0700
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Tue Apr 30 00:34:07 2013 +0200
@@ -755,7 +755,6 @@
   set_address("wbPostCallStub", GraalRuntime::entry_for(GraalRuntime::wb_post_call_id));
 
   set_address("identityHashCodeStub", GraalRuntime::entry_for(GraalRuntime::identity_hash_code_id));
-  set_address("threadIsInterruptedStub", GraalRuntime::entry_for(GraalRuntime::thread_is_interrupted_id));
   set_address("inlineCacheMissStub", SharedRuntime::get_ic_miss_stub());
   set_address("handleExceptionStub", GraalRuntime::entry_for(GraalRuntime::handle_exception_nofpu_id));
   set_address("handleDeoptStub", SharedRuntime::deopt_blob()->unpack());
@@ -766,7 +765,6 @@
   set_address("deoptimizeStub", SharedRuntime::deopt_blob()->uncommon_trap());
   set_address("unwindExceptionStub", GraalRuntime::entry_for(GraalRuntime::unwind_exception_call_id));
   set_address("osrMigrationEndStub", GraalRuntime::entry_for(GraalRuntime::OSR_migration_end_id));
-  set_address("registerFinalizerStub", GraalRuntime::entry_for(GraalRuntime::register_finalizer_id));
   set_address("createNullPointerExceptionStub", GraalRuntime::entry_for(GraalRuntime::create_null_pointer_exception_id));
   set_address("createOutOfBoundsExceptionStub", GraalRuntime::entry_for(GraalRuntime::create_out_of_bounds_exception_id));
   set_address("javaTimeMillisStub", CAST_FROM_FN_PTR(address, os::javaTimeMillis));
@@ -788,6 +786,8 @@
   set_address("newInstanceAddress", GraalRuntime::new_instance);
   set_address("newArrayAddress", GraalRuntime::new_array);
   set_address("newMultiArrayAddress", GraalRuntime::new_multi_array);
+  set_address("registerFinalizerAddress", SharedRuntime::register_finalizer);
+  set_address("threadIsInterruptedAddress", GraalRuntime::thread_is_interrupted);
 
   set_int("deoptReasonNone", Deoptimization::Reason_none);
   set_int("deoptReasonNullCheck", Deoptimization::Reason_null_check);
--- a/src/share/vm/graal/graalRuntime.hpp	Mon Apr 29 11:31:29 2013 -0700
+++ b/src/share/vm/graal/graalRuntime.hpp	Tue Apr 30 00:34:07 2013 +0200
@@ -81,7 +81,6 @@
 // runtime routines needed by code code generated
 // by Graal.
 #define GRAAL_STUBS(stub, last_entry) \
-  stub(register_finalizer)      \
   stub(handle_exception_nofpu) /* optimized version that does not preserve fpu registers */ \
   stub(unwind_exception_call)   \
   stub(OSR_migration_end)       \
@@ -98,7 +97,6 @@
   stub(stub_printf)             \
   stub(log_primitive)           \
   stub(identity_hash_code)      \
-  stub(thread_is_interrupted)   \
   stub(wb_pre_call)             \
   stub(wb_post_call)             \
  last_entry(number_of_ids)
@@ -146,7 +144,6 @@
   static void wb_post_call(JavaThread* thread, oopDesc* obj, void* card);
 
   static jint identity_hash_code(JavaThread* thread, oopDesc* objd);
-  static jboolean thread_is_interrupted(JavaThread* thread, oopDesc* obj, jboolean clear_interrupte);
 
   // Note: Must be kept in sync with constants in com.oracle.graal.replacements.Log
   enum {
@@ -160,6 +157,7 @@
   static void new_instance(JavaThread* thread, Klass* klass);
   static void new_array(JavaThread* thread, Klass* klass, jint length);
   static void new_multi_array(JavaThread* thread, Klass* klass, int rank, jint* dims);
+  static jboolean thread_is_interrupted(JavaThread* thread, oopDesc* obj, jboolean clear_interrupte);
   // initialization
   static void initialize(BufferBlob* blob);