changeset 9418:8d3a7fb9eb5f

moved binding of parameter locations to runtime call descriptors from platform specific code to shared code for stubs that are now compiled stubs
author Doug Simon <doug.simon@oracle.com>
date Mon, 29 Apr 2013 22:41:24 +0200
parents ffa27c3058e9
children 640d86a6bf4a
files graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewMultiArrayStub.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java
diffstat 7 files changed, 95 insertions(+), 61 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Mon Apr 29 21:18:37 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Mon Apr 29 22:41:24 2013 +0200
@@ -25,13 +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.*;
@@ -41,9 +39,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 +101,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),
@@ -197,15 +156,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 21:18:37 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java	Mon Apr 29 22:41:24 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/meta/HotSpotRuntime.java	Mon Apr 29 21:18:37 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Mon Apr 29 22:41:24 2013 +0200
@@ -34,7 +34,9 @@
 import static com.oracle.graal.hotspot.nodes.NewInstanceStubCall.*;
 import static com.oracle.graal.hotspot.nodes.NewMultiArrayStubCall.*;
 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.java.GraphBuilderPhase.RuntimeCalls.*;
 import static com.oracle.graal.nodes.java.RegisterFinalizerNode.*;
 import static com.oracle.graal.replacements.Log.*;
@@ -204,6 +206,7 @@
         this.graalRuntime = graalRuntime;
         regConfig = createRegisterConfig(false);
         globalStubRegConfig = createRegisterConfig(true);
+        Kind word = graalRuntime.getTarget().wordKind;
 
         // @formatter:off
 
@@ -217,6 +220,42 @@
                         /*             ret */ ret(Kind.Void),
                         /* arg0:    object */ javaCallingConvention(Kind.Object));
 
+        addStubCall(NEW_ARRAY,
+                        /*             ret */ ret(Kind.Object),
+                        /* arg0:       hub */ javaCallingConvention(word,
+                        /* arg1:    length */ Kind.Int));
+
+        addCRuntimeCall(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 */ ret(Kind.Object),
+                        /* arg0:       hub */ javaCallingConvention(word));
+
+        addCRuntimeCall(NEW_INSTANCE_C, config.newInstanceAddress,
+                        /*           temps */ null,
+                        /*             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,
+                        /*           temps */ null,
+                        /*             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));
@@ -291,6 +330,14 @@
         return addRuntimeCall(descriptor, 0L, null, ret, args);
     }
 
+    protected RuntimeCallTarget addCRuntimeCall(Descriptor descriptor, long address, Register[] tempRegs, AllocatableValue ret, AllocatableValue... args) {
+        return addRuntimeCall(descriptor, address, true, tempRegs, 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 +347,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 +358,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;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Mon Apr 29 21:18:37 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Mon Apr 29 22:41:24 2013 +0200
@@ -46,9 +46,9 @@
 
 /**
  * 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 {
 
@@ -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 21:18:37 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Mon Apr 29 22:41:24 2013 +0200
@@ -48,9 +48,9 @@
 
 /**
  * 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 {
 
@@ -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 21:18:37 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewMultiArrayStub.java	Mon Apr 29 22:41:24 2013 +0200
@@ -35,6 +35,9 @@
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.word.*;
 
+/**
+ * Stub called from {@link NewMultiArrayStubCall}.
+ */
 public class NewMultiArrayStub extends CRuntimeStub {
 
     public NewMultiArrayStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotRuntimeCallTarget linkage) {
@@ -48,7 +51,7 @@
         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);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Mon Apr 29 21:18:37 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Mon Apr 29 22:41:24 2013 +0200
@@ -27,6 +27,7 @@
 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.*;
 
@@ -139,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) {