diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/framemap/FrameMap.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/framemap/FrameMap.java index 4268a6f07b22..c8eec757bab0 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/framemap/FrameMap.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/framemap/FrameMap.java @@ -182,6 +182,7 @@ protected int alignFrameSize(int size) { * be requested. */ public void finish() { + GraalError.guarantee(frameSize == -1, "frame size may only be computed once"); frameSize = currentFrameSize(); if (frameSize > getRegisterConfig().getMaximumFrameSize()) { throw new PermanentBailoutException("Frame size (%d) exceeded maximum allowed frame size (%d).", frameSize, getRegisterConfig().getMaximumFrameSize()); diff --git a/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/FramePointerPhase.java b/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/FramePointerPhase.java index 86d4de0f4804..e395470041d0 100644 --- a/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/FramePointerPhase.java +++ b/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/FramePointerPhase.java @@ -27,6 +27,7 @@ import java.util.ArrayList; import com.oracle.svm.core.SubstrateOptions; +import com.oracle.svm.core.SubstrateUtil; import com.oracle.svm.core.graal.code.SubstrateBackend.SubstrateMarkId; import jdk.graal.compiler.asm.amd64.AMD64MacroAssembler; @@ -51,9 +52,13 @@ * * @see LIRInstruction#modifiesStackPointer */ -class FramePointerPhase extends PreAllocationOptimizationPhase { +public class FramePointerPhase extends PreAllocationOptimizationPhase { @Override protected void run(TargetDescription target, LIRGenerationResult lirGenRes, PreAllocationOptimizationContext context) { + if (!isSupported(lirGenRes)) { + return; + } + LIR lir = lirGenRes.getLIR(); if (!modifiesStackPointer(lir)) { return; @@ -101,6 +106,16 @@ protected void run(TargetDescription target, LIRGenerationResult lirGenRes, PreA } } + static boolean isSupported(LIRGenerationResult lirGenRes) { + /* + * JIT compilation and deopt targets are not supported, see GR-64771. For these unsupported + * methods, a base pointer is not used, even if there are LIR instructions that modify the + * stack pointer directly. + */ + SubstrateAMD64Backend.SubstrateLIRGenerationResult result = (SubstrateAMD64Backend.SubstrateLIRGenerationResult) lirGenRes; + return SubstrateUtil.HOSTED && !result.getMethod().isDeoptTarget(); + } + /** Returns true if any LIR instruction modifies the stack pointer, false otherwise. */ private static boolean modifiesStackPointer(LIR lir) { for (int blockId : lir.getBlocks()) { diff --git a/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/SubstrateAMD64Backend.java b/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/SubstrateAMD64Backend.java index cd13e0b2279e..8a67ca65048f 100644 --- a/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/SubstrateAMD64Backend.java +++ b/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/SubstrateAMD64Backend.java @@ -1151,12 +1151,9 @@ private static ForeignCallDescriptor chooseCPUFeatureVariant(ForeignCallDescript * If a method doesn't need a frame pointer, we use the following forms: * *
- * | needsFramePointer | + * | needsFramePointer = false | * +---------------------------------+ - * | false | - * +---------------------------------+ - * | preserveFramePointer | - * +----------------+----------------+ + * | preserveFramePointer = ... | * | false | true | * --------+----------------+----------------+ * | ; prologue | ; prologue | @@ -1187,12 +1184,9 @@ private static ForeignCallDescriptor chooseCPUFeatureVariant(ForeignCallDescript * If a method does need a frame pointer, we use the following forms: * *- * | needsFramePointer | - * +---------------------------------------------------+ - * | true | + * | needsFramePointer = true | * +---------------------------------------------------+ - * | preserveFramePointer | - * +-------------------------+-------------------------+ + * | preserveFramePointer = ... | * | false | true | * --------+-------------------------+-------------------------+ * | ; prologue | ; prologue | @@ -1675,7 +1669,7 @@ static class SubstrateAMD64FrameMap extends AMD64FrameMap { private boolean needsFramePointer; /** The offset at which the frame pointer save area is located. */ - private int framePointerSaveAreaOffset; + private int framePointerSaveAreaOffset = -1; SubstrateAMD64FrameMap(CodeCacheProvider codeCache, SubstrateAMD64RegisterConfig registerConfig, ReferenceMapBuilderFactory referenceMapFactory, SharedMethod method) { super(codeCache, registerConfig, referenceMapFactory, registerConfig.shouldUseBasePointer()); @@ -1704,6 +1698,7 @@ public void finish() { * return address. */ private void allocateFramePointerSaveArea() { + assert framePointerSaveAreaOffset == -1; int framePointerSaveAreaSize = getTarget().wordSize; if (preserveFramePointer()) { framePointerSaveAreaSize += returnAddressSize(); @@ -1724,6 +1719,7 @@ boolean needsFramePointer() { int getFramePointerSaveAreaOffset() { assert needsFramePointer() : "no frame pointer save area"; + assert framePointerSaveAreaOffset != -1; return framePointerSaveAreaOffset; } } diff --git a/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/VerifyFramePointerPhase.java b/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/VerifyFramePointerPhase.java index e5f80a1f8091..eb9889f8a243 100644 --- a/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/VerifyFramePointerPhase.java +++ b/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/VerifyFramePointerPhase.java @@ -41,6 +41,10 @@ class VerifyFramePointerPhase extends FinalCodeAnalysisPhase { @Override protected void run(TargetDescription target, LIRGenerationResult lirGenRes, FinalCodeAnalysisContext context) { + if (!FramePointerPhase.isSupported(lirGenRes)) { + return; + } + LIR lir = lirGenRes.getLIR(); for (int blockId : lir.getBlocks()) { if (LIR.isBlockDeleted(blockId)) { diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/code/SharedCompilationResult.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/code/SharedCompilationResult.java index ca235da4e2cb..4380cab50089 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/code/SharedCompilationResult.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/code/SharedCompilationResult.java @@ -41,15 +41,22 @@ public int getFrameSize() { return frameSize; } - public void setFrameSize(int frameSize) { - this.frameSize = frameSize; + public void setFrameSize(int value) { + assert frameSize == -1; + this.frameSize = value; + } + + public boolean hasFramePointerSaveAreaOffset() { + return framePointerSaveAreaOffset != -1; } public int getFramePointerSaveAreaOffset() { + assert hasFramePointerSaveAreaOffset(); return framePointerSaveAreaOffset; } - public void setFramePointerSaveAreaOffset(int framePointerSaveAreaOffset) { - this.framePointerSaveAreaOffset = framePointerSaveAreaOffset; + public void setFramePointerSaveAreaOffset(int value) { + assert !hasFramePointerSaveAreaOffset(); + this.framePointerSaveAreaOffset = value; } } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/WindowsUnwindInfoFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/WindowsUnwindInfoFeature.java index 9502d547c50d..b687f2499bfd 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/WindowsUnwindInfoFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/WindowsUnwindInfoFeature.java @@ -221,8 +221,8 @@ private static void visitRanges(CompilationResult compilation, RangeVisitor visi return; /* No frame, no unwind info needed. */ } - int framePointerSaveAreaOffset = ((SharedCompilationResult) compilation).getFramePointerSaveAreaOffset(); - if (framePointerSaveAreaOffset < 0) { + SharedCompilationResult cr = (SharedCompilationResult) compilation; + if (!cr.hasFramePointerSaveAreaOffset()) { /* There is no frame pointer, so there is only the primary range. */ visitor.visit(RUNTIME_FUNCTION.PRIMARY_RANGE, START_MARK, compilation.getTargetCodeSize()); return;