changeset 22110:e11e05cc0f2e

fixed redundant JavaFrameAnchor code around foreign calls that go through a Graal stub
author Doug Simon <doug.simon@oracle.com>
date Fri, 26 Jun 2015 20:35:08 +0200
parents ffa0ab14d70b
children 3f83cc877a0e
files graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkageImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java
diffstat 5 files changed, 67 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Fri Jun 26 20:32:09 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Fri Jun 26 20:35:08 2015 +0200
@@ -96,7 +96,7 @@
         /**
          * The variable reserved for saving RBP.
          *
-         * This should be either allocated to RBP, or to reserved stack slot.
+         * This should be either allocated to RBP, or to {@link #reservedSlot}.
          */
         private final AllocatableValue rescueSlot;
 
@@ -317,6 +317,10 @@
         append(new AMD64RestoreRegistersOp(save.getSlots().clone(), save));
     }
 
+    /**
+     * Gets the {@link Stub} this generator is generating code for or {@code null} if a stub is not
+     * being generated.
+     */
     public Stub getStub() {
         return ((AMD64HotSpotLIRGenerationResult) getResult()).getStub();
     }
@@ -327,36 +331,33 @@
         boolean destroysRegisters = hotspotLinkage.destroysRegisters();
 
         AMD64SaveRegistersOp save = null;
+        Stub stub = getStub();
         if (destroysRegisters) {
-            if (getStub() != null) {
-                if (getStub().preservesRegisters()) {
-                    Register[] savedRegisters = getResult().getFrameMapBuilder().getRegisterConfig().getAllocatableRegisters();
-                    save = emitSaveAllRegisters(savedRegisters, true);
-                }
+            if (stub != null && stub.preservesRegisters()) {
+                Register[] savedRegisters = getResult().getFrameMapBuilder().getRegisterConfig().getAllocatableRegisters();
+                save = emitSaveAllRegisters(savedRegisters, true);
             }
         }
 
         Variable result;
-        LIRFrameState deoptInfo = null;
+        LIRFrameState debugInfo = null;
         if (hotspotLinkage.canDeoptimize()) {
-            deoptInfo = state;
-            assert deoptInfo != null || getStub() != null;
-            assert hotspotLinkage.needsJavaFrameAnchor();
+            debugInfo = state;
+            assert debugInfo != null || stub != null;
         }
 
         if (hotspotLinkage.needsJavaFrameAnchor()) {
             Register thread = getProviders().getRegisters().getThreadRegister();
             append(new AMD64HotSpotCRuntimeCallPrologueOp(config.threadLastJavaSpOffset(), thread));
-            result = super.emitForeignCall(hotspotLinkage, deoptInfo, args);
+            result = super.emitForeignCall(hotspotLinkage, debugInfo, args);
             append(new AMD64HotSpotCRuntimeCallEpilogueOp(config.threadLastJavaSpOffset(), config.threadLastJavaFpOffset(), thread));
         } else {
-            assert deoptInfo == null;
-            result = super.emitForeignCall(hotspotLinkage, null, args);
+            result = super.emitForeignCall(hotspotLinkage, debugInfo, args);
         }
 
         if (destroysRegisters) {
-            if (getStub() != null) {
-                if (getStub().preservesRegisters()) {
+            if (stub != null) {
+                if (stub.preservesRegisters()) {
                     AMD64HotSpotLIRGenerationResult generationResult = (AMD64HotSpotLIRGenerationResult) getResult();
                     assert !generationResult.getCalleeSaveInfo().containsKey(currentRuntimeCallInfo);
                     generationResult.getCalleeSaveInfo().put(currentRuntimeCallInfo, save);
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Fri Jun 26 20:32:09 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Fri Jun 26 20:35:08 2015 +0200
@@ -125,10 +125,10 @@
     public Variable emitForeignCall(ForeignCallLinkage linkage, LIRFrameState state, Value... args) {
         HotSpotForeignCallLinkage hotspotLinkage = (HotSpotForeignCallLinkage) linkage;
         Variable result;
-        LIRFrameState deoptInfo = null;
+        LIRFrameState debugInfo = null;
         if (hotspotLinkage.canDeoptimize()) {
-            deoptInfo = state;
-            assert deoptInfo != null || getStub() != null;
+            debugInfo = state;
+            assert debugInfo != null || getStub() != null;
         }
 
         if (linkage.destroysRegisters() || hotspotLinkage.needsJavaFrameAnchor()) {
@@ -137,10 +137,10 @@
             Value threadTemp = newVariable(LIRKind.value(Kind.Long));
             Register stackPointer = registers.getStackPointerRegister();
             append(new SPARCHotSpotCRuntimeCallPrologueOp(config.threadLastJavaSpOffset(), thread, stackPointer, threadTemp));
-            result = super.emitForeignCall(hotspotLinkage, deoptInfo, args);
+            result = super.emitForeignCall(hotspotLinkage, debugInfo, args);
             append(new SPARCHotSpotCRuntimeCallEpilogueOp(config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), config.threadJavaFrameAnchorFlagsOffset(), thread, threadTemp));
         } else {
-            result = super.emitForeignCall(hotspotLinkage, deoptInfo, args);
+            result = super.emitForeignCall(hotspotLinkage, debugInfo, args);
         }
 
         return result;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java	Fri Jun 26 20:32:09 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java	Fri Jun 26 20:35:08 2015 +0200
@@ -44,14 +44,38 @@
     }
 
     /**
-     * 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.
+     * Constants for specifying whether a call is a leaf or not and whether a
+     * {@code JavaFrameAnchor} prologue and epilogue is required around the call. A leaf function
+     * does not lock, GC or throw exceptions.
      */
     public enum Transition {
+        /**
+         * A call to a leaf function that is guaranteed to not use floating point registers and will
+         * never have its caller stack inspected by the VM. That is, {@code JavaFrameAnchor}
+         * management around the call can be omitted.
+         */
         LEAF_NOFP,
+
+        /**
+         * A call to a leaf function that might use floating point registers but will never have its
+         * caller stack inspected. That is, {@code JavaFrameAnchor} management around the call can
+         * be omitted.
+         */
         LEAF,
-        LEAF_SP,
+
+        /**
+         * A call to a leaf function that might use floating point registers and may have its caller
+         * stack inspected. That is, {@code JavaFrameAnchor} management code around the call is
+         * required.
+         */
+        STACK_INSPECTABLE_LEAF,
+
+        /**
+         * A function that may lock, GC or raise an exception and thus requires debug info to be
+         * associated with a call site to the function. The execution stack may be inspected while
+         * in the called function. That is, {@code JavaFrameAnchor} management code around the call
+         * is required.
+         */
         NOT_LEAF;
     }
 
@@ -64,16 +88,6 @@
 
     LocationIdentity[] getKilledLocations();
 
-    CallingConvention getOutgoingCallingConvention();
-
-    CallingConvention getIncomingCallingConvention();
-
-    Value[] getTemporaries();
-
-    long getMaxCallTargetOffset();
-
-    ForeignCallDescriptor getDescriptor();
-
     void setCompiledStub(Stub stub);
 
     /**
@@ -85,14 +99,15 @@
 
     long getAddress();
 
-    @Override
-    boolean destroysRegisters();
-
-    @Override
-    boolean canDeoptimize();
-
+    /**
+     * Determines if the runtime function or stub might use floating point registers. If the answer
+     * is no, then no FPU state management prologue or epilogue needs to be emitted around the call.
+     */
     boolean mayContainFP();
 
+    /**
+     * Determines if a {@code JavaFrameAnchor} needs to be set up and torn down around this call.
+     */
     boolean needsJavaFrameAnchor();
 
     /**
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkageImpl.java	Fri Jun 26 20:32:09 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkageImpl.java	Fri Jun 26 20:35:08 2015 +0200
@@ -232,7 +232,16 @@
     }
 
     public boolean needsJavaFrameAnchor() {
-        return canDeoptimize() || transition == Transition.LEAF_SP;
+        if (transition == Transition.NOT_LEAF || transition == Transition.STACK_INSPECTABLE_LEAF) {
+            if (stub != null) {
+                // The stub will do the JavaFrameAnchor management
+                // around the runtime call(s) it makes
+                return false;
+            } else {
+                return true;
+            }
+        }
+        return false;
     }
 
     public String getSymbol() {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java	Fri Jun 26 20:32:09 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java	Fri Jun 26 20:35:08 2015 +0200
@@ -215,7 +215,7 @@
         linkForeignCall(providers, CREATE_NULL_POINTER_EXCEPTION, c.createNullPointerExceptionAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, any());
         linkForeignCall(providers, CREATE_OUT_OF_BOUNDS_EXCEPTION, c.createOutOfBoundsExceptionAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, any());
         linkForeignCall(providers, MONITORENTER, c.monitorenterAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, any());
-        linkForeignCall(providers, MONITOREXIT, c.monitorexitAddress, PREPEND_THREAD, LEAF_SP, NOT_REEXECUTABLE, any());
+        linkForeignCall(providers, MONITOREXIT, c.monitorexitAddress, PREPEND_THREAD, STACK_INSPECTABLE_LEAF, NOT_REEXECUTABLE, any());
         linkForeignCall(providers, NEW_MULTI_ARRAY, c.newMultiArrayAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, INIT_LOCATION, TLAB_TOP_LOCATION, TLAB_END_LOCATION);
         linkForeignCall(providers, DYNAMIC_NEW_ARRAY, c.dynamicNewArrayAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, INIT_LOCATION);
         linkForeignCall(providers, DYNAMIC_NEW_INSTANCE, c.dynamicNewInstanceAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, INIT_LOCATION);