diff graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java @ 9731:f7bd4594cbbf

added support for declaring a foreign function call to be a leaf
author Doug Simon <doug.simon@oracle.com>
date Wed, 15 May 2013 21:37:25 +0200
parents d04944441454
children 2e4f035186cf
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java	Wed May 15 16:46:39 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java	Wed May 15 21:37:25 2013 +0200
@@ -31,7 +31,6 @@
 import com.oracle.graal.api.code.CallingConvention.Type;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.word.*;
@@ -51,6 +50,15 @@
     }
 
     /**
+     * Constants for specifying whether a call is a leaf or not. A leaf function does not lock, GC
+     * or throw exceptions. That is, the thread's execution state during the call is never inspected
+     * by another thread.
+     */
+    public enum Transition {
+        LEAF, NOT_LEAF;
+    }
+
+    /**
      * Sentinel marker for a computed jump address.
      */
     public static final long JUMP_ADDRESS = 0xDEADDEADBEEFBEEFL;
@@ -75,9 +83,9 @@
      */
     private CallingConvention cc;
 
-    private final CompilerToVM vm;
+    private final RegisterEffect effect;
 
-    private final RegisterEffect effect;
+    private final Transition transition;
 
     /**
      * Creates a {@link HotSpotRuntimeCallTarget}.
@@ -87,18 +95,18 @@
      * @param effect specifies if the call destroys or preserves all registers (apart from
      *            temporaries which are always destroyed)
      * @param ccType calling convention type
-     * @param ccProvider calling convention provider
-     * @param vm the Java to HotSpot C/C++ runtime interface
+     * @param transition specifies if this is a {@linkplain #isLeaf() leaf} call
      */
-    public static HotSpotRuntimeCallTarget create(Descriptor descriptor, long address, RegisterEffect effect, Type ccType, RegisterConfig ccProvider, HotSpotRuntime runtime, CompilerToVM vm) {
-        CallingConvention targetCc = createCallingConvention(descriptor, ccType, ccProvider, runtime);
-        return new HotSpotRuntimeCallTarget(descriptor, address, effect, targetCc, vm);
+    public static HotSpotRuntimeCallTarget create(Descriptor descriptor, long address, RegisterEffect effect, Type ccType, Transition transition) {
+        CallingConvention targetCc = createCallingConvention(descriptor, ccType);
+        return new HotSpotRuntimeCallTarget(descriptor, address, effect, transition, targetCc);
     }
 
     /**
      * Gets a calling convention for a given descriptor and call type.
      */
-    public static CallingConvention createCallingConvention(Descriptor descriptor, Type ccType, RegisterConfig ccProvider, HotSpotRuntime runtime) {
+    public static CallingConvention createCallingConvention(Descriptor descriptor, Type ccType) {
+        HotSpotRuntime runtime = graalRuntime().getRuntime();
         Class<?>[] argumentTypes = descriptor.getArgumentTypes();
         JavaType[] parameterTypes = new JavaType[argumentTypes.length];
         for (int i = 0; i < parameterTypes.length; ++i) {
@@ -106,7 +114,7 @@
         }
         TargetDescription target = graalRuntime().getTarget();
         JavaType returnType = asJavaType(descriptor.getResultType(), runtime);
-        return ccProvider.getCallingConvention(ccType, returnType, parameterTypes, target, false);
+        return runtime.lookupRegisterConfig().getCallingConvention(ccType, returnType, parameterTypes, target, false);
     }
 
     private static JavaType asJavaType(Class type, HotSpotRuntime runtime) {
@@ -117,12 +125,12 @@
         }
     }
 
-    public HotSpotRuntimeCallTarget(Descriptor descriptor, long address, RegisterEffect effect, CallingConvention cc, CompilerToVM vm) {
+    public HotSpotRuntimeCallTarget(Descriptor descriptor, long address, RegisterEffect effect, Transition transition, CallingConvention cc) {
         this.address = address;
         this.effect = effect;
+        this.transition = transition;
         this.descriptor = descriptor;
         this.cc = cc;
-        this.vm = vm;
     }
 
     @Override
@@ -135,7 +143,7 @@
     }
 
     public long getMaxCallTargetOffset() {
-        return vm.getMaxCallTargetOffset(address);
+        return graalRuntime().getCompilerToVM().getMaxCallTargetOffset(address);
     }
 
     public Descriptor getDescriptor() {
@@ -180,4 +188,12 @@
     public boolean destroysRegisters() {
         return effect == DESTROYS_REGISTERS;
     }
+
+    /**
+     * Determines if this is call to a function that does not lock, GC or throw exceptions. That is,
+     * the thread's execution state during the call is never inspected by another thread.
+     */
+    public boolean isLeaf() {
+        return transition == Transition.LEAF;
+    }
 }