# HG changeset patch # User Doug Simon # Date 1435343708 -7200 # Node ID e11e05cc0f2e3dfec1a305c033c0fcad65a78513 # Parent ffa0ab14d70be1894a72df612db835fe5bdd9d99 fixed redundant JavaFrameAnchor code around foreign calls that go through a Graal stub diff -r ffa0ab14d70b -r e11e05cc0f2e graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- 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); diff -r ffa0ab14d70b -r e11e05cc0f2e graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java --- 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; diff -r ffa0ab14d70b -r e11e05cc0f2e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java --- 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(); /** diff -r ffa0ab14d70b -r e11e05cc0f2e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkageImpl.java --- 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() { diff -r ffa0ab14d70b -r e11e05cc0f2e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java --- 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);