# HG changeset patch # User Tom Rodriguez # Date 1453362315 28800 # Node ID 3e4b96f3e4d3cb158fd2db27df6002f239922431 # Parent 5538acafd12f67f729372887813a1cc1acbdd8f9 Update graal import: stack banging must take space required for deopt into account diff -r 5538acafd12f -r 3e4b96f3e4d3 graal/com.oracle.graal.code/src/com/oracle/graal/code/CompilationResult.java --- a/graal/com.oracle.graal.code/src/com/oracle/graal/code/CompilationResult.java Wed Jan 20 22:30:50 2016 +0100 +++ b/graal/com.oracle.graal.code/src/com/oracle/graal/code/CompilationResult.java Wed Jan 20 23:45:15 2016 -0800 @@ -178,6 +178,7 @@ private final List marks = new ArrayList<>(); private int totalFrameSize = -1; + private int maxInterpreterFrameSize = -1; private int customStackAreaOffset = -1; private final String name; @@ -369,6 +370,15 @@ totalFrameSize = size; } + public int getMaxInterpreterFrameSize() { + return maxInterpreterFrameSize; + } + + public void setMaxInterpreterFrameSize(int maxInterpreterFrameSize) { + checkOpen(); + this.maxInterpreterFrameSize = maxInterpreterFrameSize; + } + /** * Sets the machine that has been generated by the compiler. * diff -r 5538acafd12f -r 3e4b96f3e4d3 graal/com.oracle.graal.hotspot.aarch64/src/com/oracle/graal/hotspot/aarch64/AArch64HotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.aarch64/src/com/oracle/graal/hotspot/aarch64/AArch64HotSpotBackend.java Wed Jan 20 22:30:50 2016 +0100 +++ b/graal/com.oracle.graal.hotspot.aarch64/src/com/oracle/graal/hotspot/aarch64/AArch64HotSpotBackend.java Wed Jan 20 23:45:15 2016 -0800 @@ -33,7 +33,6 @@ import static jdk.vm.ci.hotspot.HotSpotVMConfig.config; import static jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig.fp; -import java.lang.reflect.Field; import java.util.Set; import jdk.vm.ci.code.CallingConvention; @@ -44,7 +43,6 @@ import jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig; import jdk.vm.ci.meta.JavaType; import jdk.vm.ci.meta.ResolvedJavaMethod; -import sun.misc.Unsafe; import com.oracle.graal.asm.Assembler; import com.oracle.graal.asm.Label; @@ -59,6 +57,7 @@ import com.oracle.graal.hotspot.HotSpotDataBuilder; import com.oracle.graal.hotspot.HotSpotGraalRuntimeProvider; import com.oracle.graal.hotspot.HotSpotHostBackend; +import com.oracle.graal.hotspot.HotSpotLIRGenerationResult; import com.oracle.graal.hotspot.meta.HotSpotForeignCallsProvider; import com.oracle.graal.hotspot.meta.HotSpotProviders; import com.oracle.graal.hotspot.stubs.Stub; @@ -104,7 +103,7 @@ @Override public LIRGenerationResult newLIRGenerationResult(String compilationUnitName, LIR lir, FrameMapBuilder frameMapBuilder, ResolvedJavaMethod method, Object stub) { - return new AArch64HotSpotLIRGenerationResult(compilationUnitName, lir, frameMapBuilder, stub); + return new HotSpotLIRGenerationResult(compilationUnitName, lir, frameMapBuilder, stub); } @Override @@ -112,32 +111,13 @@ return new AArch64HotSpotNodeLIRBuilder(graph, lirGen, new AArch64NodeMatchRules(lirGen)); } - /** - * Emits code to do stack overflow checking. - * - * @param afterFrameInit specifies if the stack pointer has already been adjusted to allocate - * the current frame - */ - protected static void emitStackOverflowCheck(CompilationResultBuilder crb, int pagesToBang, boolean afterFrameInit) { - if (pagesToBang > 0) { - AArch64MacroAssembler masm = (AArch64MacroAssembler) crb.asm; - int frameSize = crb.frameMap.totalFrameSize(); - if (frameSize > 0) { - int lastFramePage = frameSize / UNSAFE.pageSize(); - // emit multiple stack bangs for methods with frames larger than a page - for (int i = 0; i <= lastFramePage; i++) { - int disp = (i + pagesToBang) * UNSAFE.pageSize(); - if (afterFrameInit) { - disp -= frameSize; - } - crb.blockComment("[stack overflow check]"); - try (ScratchRegister sc = masm.getScratchRegister()) { - Register scratch = sc.getRegister(); - AArch64Address address = masm.makeAddress(sp, -disp, scratch, 8, /* allowOverwrite */false); - masm.str(64, zr, address); - } - } - } + @Override + protected void bangStackWithOffset(CompilationResultBuilder crb, int bangOffset) { + AArch64MacroAssembler masm = (AArch64MacroAssembler) crb.asm; + try (ScratchRegister sc = masm.getScratchRegister()) { + Register scratch = sc.getRegister(); + AArch64Address address = masm.makeAddress(sp, -bangOffset, scratch, 8, /* allowOverwrite */false); + masm.str(64, zr, address); } } @@ -155,8 +135,8 @@ final int totalFrameSize = frameMap.totalFrameSize(); assert frameSize + 2 * crb.target.arch.getWordSize() == totalFrameSize : "total framesize should be framesize + 2 words"; AArch64MacroAssembler masm = (AArch64MacroAssembler) crb.asm; - if (!isStub && pagesToBang > 0) { - emitStackOverflowCheck(crb, pagesToBang, false); + if (!isStub) { + emitStackOverflowCheck(crb); } crb.blockComment("[method prologue]"); @@ -234,7 +214,7 @@ @Override public CompilationResultBuilder newCompilationResultBuilder(LIRGenerationResult lirGenRen, FrameMap frameMap, CompilationResult compilationResult, CompilationResultBuilderFactory factory) { - AArch64HotSpotLIRGenerationResult gen = (AArch64HotSpotLIRGenerationResult) lirGenRen; + HotSpotLIRGenerationResult gen = (HotSpotLIRGenerationResult) lirGenRen; LIR lir = gen.getLIR(); assert gen.getDeoptimizationRescueSlot() == null || frameMap.frameNeedsAllocating() : "method that can deoptimize must have a frame"; @@ -245,6 +225,7 @@ DataBuilder dataBuilder = new HotSpotDataBuilder(getCodeCache().getTarget()); CompilationResultBuilder crb = factory.createBuilder(getCodeCache(), getForeignCalls(), frameMap, masm, dataBuilder, frameContext, compilationResult); crb.setTotalFrameSize(frameMap.frameSize()); + crb.setMaxInterpreterFrameSize(gen.getMaxInterpreterFrameSize()); StackSlot deoptimizationRescueSlot = gen.getDeoptimizationRescueSlot(); if (deoptimizationRescueSlot != null && stub == null) { crb.compilationResult.setCustomStackAreaOffset(frameMap.offsetForStackSlot(deoptimizationRescueSlot)); @@ -336,20 +317,4 @@ RegisterConfig registerConfigNonNull = registerConfig == null ? getCodeCache().getRegisterConfig() : registerConfig; return new AArch64HotSpotRegisterAllocationConfig(registerConfigNonNull); } - - private static final Unsafe UNSAFE = initUnsafe(); - - private static Unsafe initUnsafe() { - try { - return Unsafe.getUnsafe(); - } catch (SecurityException se) { - try { - Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); - theUnsafe.setAccessible(true); - return (Unsafe) theUnsafe.get(Unsafe.class); - } catch (Exception e) { - throw new RuntimeException("exception while trying to get Unsafe", e); - } - } - } } diff -r 5538acafd12f -r 3e4b96f3e4d3 graal/com.oracle.graal.hotspot.aarch64/src/com/oracle/graal/hotspot/aarch64/AArch64HotSpotLIRGenerationResult.java --- a/graal/com.oracle.graal.hotspot.aarch64/src/com/oracle/graal/hotspot/aarch64/AArch64HotSpotLIRGenerationResult.java Wed Jan 20 22:30:50 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.oracle.graal.hotspot.aarch64; - -import java.util.Map; - -import com.oracle.graal.compiler.common.CollectionsFactory; -import com.oracle.graal.hotspot.stubs.Stub; -import com.oracle.graal.lir.LIR; -import com.oracle.graal.lir.LIRFrameState; -import com.oracle.graal.lir.StandardOp; -import com.oracle.graal.lir.framemap.FrameMapBuilder; -import com.oracle.graal.lir.gen.LIRGenerationResultBase; - -import jdk.vm.ci.code.StackSlot; - -public class AArch64HotSpotLIRGenerationResult extends LIRGenerationResultBase { - /** - * The slot reserved for storing the original return address when a frame is marked for - * deoptimization. The return address slot in the callee is overwritten with the address of a - * deoptimization stub. - */ - private StackSlot deoptimizationRescueSlot; - private final Object stub; - - /** - * Map from debug infos that need to be updated with callee save information to the operations - * that provide the information. - */ - private final Map calleeSaveInfo = CollectionsFactory.newMap(); - - public AArch64HotSpotLIRGenerationResult(String compilationUnitName, LIR lir, FrameMapBuilder frameMapBuilder, Object stub) { - super(compilationUnitName, lir, frameMapBuilder); - this.stub = stub; - } - - StackSlot getDeoptimizationRescueSlot() { - return deoptimizationRescueSlot; - } - - public final void setDeoptimizationRescueSlot(StackSlot stackSlot) { - this.deoptimizationRescueSlot = stackSlot; - } - - Stub getStub() { - return (Stub) stub; - } - - Map getCalleeSaveInfo() { - return calleeSaveInfo; - } -} diff -r 5538acafd12f -r 3e4b96f3e4d3 graal/com.oracle.graal.hotspot.aarch64/src/com/oracle/graal/hotspot/aarch64/AArch64HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.aarch64/src/com/oracle/graal/hotspot/aarch64/AArch64HotSpotLIRGenerator.java Wed Jan 20 22:30:50 2016 +0100 +++ b/graal/com.oracle.graal.hotspot.aarch64/src/com/oracle/graal/hotspot/aarch64/AArch64HotSpotLIRGenerator.java Wed Jan 20 23:45:15 2016 -0800 @@ -23,24 +23,6 @@ package com.oracle.graal.hotspot.aarch64; -import com.oracle.graal.asm.aarch64.AArch64Address; -import com.oracle.graal.compiler.aarch64.AArch64ArithmeticLIRGenerator; -import com.oracle.graal.compiler.aarch64.AArch64LIRGenerator; -import com.oracle.graal.compiler.common.spi.ForeignCallLinkage; -import com.oracle.graal.compiler.common.spi.LIRKindTool; -import com.oracle.graal.hotspot.HotSpotBackend; -import com.oracle.graal.hotspot.HotSpotLIRGenerator; -import com.oracle.graal.hotspot.HotSpotLockStack; -import com.oracle.graal.hotspot.meta.HotSpotProviders; -import com.oracle.graal.hotspot.stubs.Stub; -import com.oracle.graal.lir.LIRFrameState; -import com.oracle.graal.lir.StandardOp.SaveRegistersOp; -import com.oracle.graal.lir.Variable; -import com.oracle.graal.lir.VirtualStackSlot; -import com.oracle.graal.lir.aarch64.AArch64AddressValue; -import com.oracle.graal.lir.aarch64.AArch64Move; -import com.oracle.graal.lir.gen.LIRGenerationResult; - import jdk.vm.ci.aarch64.AArch64; import jdk.vm.ci.aarch64.AArch64Kind; import jdk.vm.ci.code.CallingConvention; @@ -55,13 +37,34 @@ import jdk.vm.ci.meta.LIRKind; import jdk.vm.ci.meta.Value; +import com.oracle.graal.asm.aarch64.AArch64Address; +import com.oracle.graal.compiler.aarch64.AArch64ArithmeticLIRGenerator; +import com.oracle.graal.compiler.aarch64.AArch64LIRGenerator; +import com.oracle.graal.compiler.common.spi.ForeignCallLinkage; +import com.oracle.graal.compiler.common.spi.LIRKindTool; +import com.oracle.graal.hotspot.HotSpotBackend; +import com.oracle.graal.hotspot.HotSpotDebugInfoBuilder; +import com.oracle.graal.hotspot.HotSpotLIRGenerationResult; +import com.oracle.graal.hotspot.HotSpotLIRGenerator; +import com.oracle.graal.hotspot.HotSpotLockStack; +import com.oracle.graal.hotspot.meta.HotSpotProviders; +import com.oracle.graal.hotspot.stubs.Stub; +import com.oracle.graal.lir.LIRFrameState; +import com.oracle.graal.lir.StandardOp.SaveRegistersOp; +import com.oracle.graal.lir.Variable; +import com.oracle.graal.lir.VirtualStackSlot; +import com.oracle.graal.lir.aarch64.AArch64AddressValue; +import com.oracle.graal.lir.aarch64.AArch64FrameMapBuilder; +import com.oracle.graal.lir.aarch64.AArch64Move; +import com.oracle.graal.lir.gen.LIRGenerationResult; + /** * LIR generator specialized for AArch64 HotSpot. */ public class AArch64HotSpotLIRGenerator extends AArch64LIRGenerator implements HotSpotLIRGenerator { final HotSpotVMConfig config; - private HotSpotLockStack lockStack; + private HotSpotDebugInfoBuilder debugInfoBuilder; protected AArch64HotSpotLIRGenerator(HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc, LIRGenerationResult lirGenRes) { this(providers, config, cc, lirGenRes, new ConstantTableBaseProvider()); @@ -81,7 +84,7 @@ @Override public boolean needOnlyOopMaps() { // Stubs only need oop maps - return ((AArch64HotSpotLIRGenerationResult) getResult()).getStub() != null; + return getResult().getStub() != null; } @Override @@ -105,13 +108,8 @@ } private HotSpotLockStack getLockStack() { - assert lockStack != null; - return lockStack; - } - - protected void setLockStack(HotSpotLockStack lockStack) { - assert this.lockStack == null; - this.lockStack = lockStack; + assert debugInfoBuilder != null && debugInfoBuilder.lockStack() != null; + return debugInfoBuilder.lockStack(); } @SuppressWarnings("unused") @@ -150,6 +148,17 @@ } @Override + public void beforeRegisterAllocation() { + super.beforeRegisterAllocation(); + boolean hasDebugInfo = getResult().getLIR().hasDebugInfo(); + if (hasDebugInfo) { + getResult().setDeoptimizationRescueSlot(((AArch64FrameMapBuilder) getResult().getFrameMapBuilder()).allocateDeoptimizationRescueSlot()); + } + + getResult().setMaxInterpreterFrameSize(debugInfoBuilder.maxInterpreterFrameSize()); + } + + @Override public void emitDeoptimizeCaller(DeoptimizationAction action, DeoptimizationReason reason) { Value actionAndReason = emitJavaConstant(getMetaAccess().encodeDeoptActionAndReason(action, reason, 0)); Value nullValue = emitConstant(LIRKind.reference(AArch64Kind.QWORD), JavaConstant.NULL_POINTER); @@ -200,7 +209,16 @@ * being generated. */ public Stub getStub() { - return ((AArch64HotSpotLIRGenerationResult) getResult()).getStub(); + return getResult().getStub(); + } + + @Override + public HotSpotLIRGenerationResult getResult() { + return ((HotSpotLIRGenerationResult) super.getResult()); + } + + public void setDebugInfoBuilder(HotSpotDebugInfoBuilder debugInfoBuilder) { + this.debugInfoBuilder = debugInfoBuilder; } } diff -r 5538acafd12f -r 3e4b96f3e4d3 graal/com.oracle.graal.hotspot.aarch64/src/com/oracle/graal/hotspot/aarch64/AArch64HotSpotNodeLIRBuilder.java --- a/graal/com.oracle.graal.hotspot.aarch64/src/com/oracle/graal/hotspot/aarch64/AArch64HotSpotNodeLIRBuilder.java Wed Jan 20 22:30:50 2016 +0100 +++ b/graal/com.oracle.graal.hotspot.aarch64/src/com/oracle/graal/hotspot/aarch64/AArch64HotSpotNodeLIRBuilder.java Wed Jan 20 23:45:15 2016 -0800 @@ -29,6 +29,19 @@ import static jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig.fp; import static jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig.inlineCacheRegister; import static jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig.metaspaceMethodRegister; +import jdk.vm.ci.aarch64.AArch64Kind; +import jdk.vm.ci.amd64.AMD64Kind; +import jdk.vm.ci.code.BytecodeFrame; +import jdk.vm.ci.code.CallingConvention; +import jdk.vm.ci.code.Register; +import jdk.vm.ci.code.RegisterValue; +import jdk.vm.ci.code.StackSlot; +import jdk.vm.ci.code.ValueUtil; +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; +import jdk.vm.ci.meta.AllocatableValue; +import jdk.vm.ci.meta.LIRKind; +import jdk.vm.ci.meta.Value; import com.oracle.graal.compiler.aarch64.AArch64NodeLIRBuilder; import com.oracle.graal.compiler.aarch64.AArch64NodeMatchRules; @@ -36,6 +49,7 @@ import com.oracle.graal.compiler.gen.DebugInfoBuilder; import com.oracle.graal.debug.Debug; import com.oracle.graal.hotspot.HotSpotDebugInfoBuilder; +import com.oracle.graal.hotspot.HotSpotLIRGenerator; import com.oracle.graal.hotspot.HotSpotLockStack; import com.oracle.graal.hotspot.HotSpotNodeLIRBuilder; import com.oracle.graal.hotspot.nodes.DirectCompareAndSwapNode; @@ -55,20 +69,6 @@ import com.oracle.graal.nodes.ValueNode; import com.oracle.graal.nodes.spi.NodeValueMap; -import jdk.vm.ci.aarch64.AArch64Kind; -import jdk.vm.ci.amd64.AMD64Kind; -import jdk.vm.ci.code.BytecodeFrame; -import jdk.vm.ci.code.CallingConvention; -import jdk.vm.ci.code.Register; -import jdk.vm.ci.code.RegisterValue; -import jdk.vm.ci.code.StackSlot; -import jdk.vm.ci.code.ValueUtil; -import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; -import jdk.vm.ci.meta.AllocatableValue; -import jdk.vm.ci.meta.LIRKind; -import jdk.vm.ci.meta.Value; - /** * LIR generator specialized for AArch64 HotSpot. */ @@ -78,13 +78,13 @@ super(graph, gen, nodeMatchRules); assert gen instanceof AArch64HotSpotLIRGenerator; assert getDebugInfoBuilder() instanceof HotSpotDebugInfoBuilder; - ((AArch64HotSpotLIRGenerator) gen).setLockStack(((HotSpotDebugInfoBuilder) getDebugInfoBuilder()).lockStack()); + ((AArch64HotSpotLIRGenerator) gen).setDebugInfoBuilder(((HotSpotDebugInfoBuilder) getDebugInfoBuilder())); } @Override protected DebugInfoBuilder createDebugInfoBuilder(StructuredGraph graph, NodeValueMap nodeValueMap) { HotSpotLockStack lockStack = new HotSpotLockStack(gen.getResult().getFrameMapBuilder(), LIRKind.value(AArch64Kind.QWORD)); - return new HotSpotDebugInfoBuilder(nodeValueMap, lockStack); + return new HotSpotDebugInfoBuilder(nodeValueMap, lockStack, (HotSpotLIRGenerator) gen); } private AArch64HotSpotLIRGenerator getGen() { diff -r 5538acafd12f -r 3e4b96f3e4d3 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Wed Jan 20 22:30:50 2016 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Wed Jan 20 23:45:15 2016 -0800 @@ -31,7 +31,6 @@ import static jdk.vm.ci.code.ValueUtil.asRegister; import static jdk.vm.ci.hotspot.HotSpotVMConfig.config; -import java.lang.reflect.Field; import java.util.Set; import jdk.vm.ci.amd64.AMD64; @@ -42,7 +41,6 @@ import jdk.vm.ci.hotspot.HotSpotVMConfig; import jdk.vm.ci.meta.JavaType; import jdk.vm.ci.meta.ResolvedJavaMethod; -import sun.misc.Unsafe; import com.oracle.graal.asm.Assembler; import com.oracle.graal.asm.Label; @@ -58,6 +56,7 @@ import com.oracle.graal.hotspot.HotSpotDataBuilder; import com.oracle.graal.hotspot.HotSpotGraalRuntimeProvider; import com.oracle.graal.hotspot.HotSpotHostBackend; +import com.oracle.graal.hotspot.HotSpotLIRGenerationResult; import com.oracle.graal.hotspot.meta.HotSpotForeignCallsProvider; import com.oracle.graal.hotspot.meta.HotSpotProviders; import com.oracle.graal.hotspot.stubs.Stub; @@ -103,7 +102,7 @@ @Override public LIRGenerationResult newLIRGenerationResult(String compilationUnitName, LIR lir, FrameMapBuilder frameMapBuilder, ResolvedJavaMethod method, Object stub) { - return new AMD64HotSpotLIRGenerationResult(compilationUnitName, lir, frameMapBuilder, stub); + return new HotSpotLIRGenerationResult(compilationUnitName, lir, frameMapBuilder, stub); } @Override @@ -117,34 +116,12 @@ } - /** - * Emits code to do stack overflow checking. - * - * @param afterFrameInit specifies if the stack pointer has already been adjusted to allocate - * the current frame - * @param isVerifiedEntryPoint specifies if the code buffer is currently at the verified entry - * point - */ - protected static void emitStackOverflowCheck(CompilationResultBuilder crb, int pagesToBang, boolean afterFrameInit, boolean isVerifiedEntryPoint) { - if (pagesToBang > 0) { - - AMD64MacroAssembler asm = (AMD64MacroAssembler) crb.asm; - int frameSize = crb.frameMap.frameSize(); - if (frameSize > 0) { - int lastFramePage = frameSize / UNSAFE.pageSize(); - // emit multiple stack bangs for methods with frames larger than a page - for (int i = 0; i <= lastFramePage; i++) { - int disp = (i + pagesToBang) * UNSAFE.pageSize(); - if (afterFrameInit) { - disp -= frameSize; - } - crb.blockComment("[stack overflow check]"); - int pos = asm.position(); - asm.movl(new AMD64Address(rsp, -disp), AMD64.rax); - assert i > 0 || !isVerifiedEntryPoint || asm.position() - pos >= PATCHED_VERIFIED_ENTRY_POINT_INSTRUCTION_SIZE; - } - } - } + @Override + protected void bangStackWithOffset(CompilationResultBuilder crb, int bangOffset) { + AMD64MacroAssembler asm = (AMD64MacroAssembler) crb.asm; + int pos = asm.position(); + asm.movl(new AMD64Address(rsp, -bangOffset), AMD64.rax); + assert asm.position() - pos >= PATCHED_VERIFIED_ENTRY_POINT_INSTRUCTION_SIZE; } /** @@ -183,9 +160,10 @@ } } else { int verifiedEntryPointOffset = asm.position(); - if (!isStub && pagesToBang > 0) { - emitStackOverflowCheck(crb, pagesToBang, false, true); - assert asm.position() - verifiedEntryPointOffset >= PATCHED_VERIFIED_ENTRY_POINT_INSTRUCTION_SIZE; + if (!isStub) { + emitStackOverflowCheck(crb); + // assert asm.position() - verifiedEntryPointOffset >= + // PATCHED_VERIFIED_ENTRY_POINT_INSTRUCTION_SIZE; } if (!isStub && asm.position() == verifiedEntryPointOffset) { asm.subqWide(rsp, frameSize); @@ -228,7 +206,7 @@ // - has no incoming arguments passed on the stack // - has no deoptimization points // - makes no foreign calls (which require an aligned stack) - AMD64HotSpotLIRGenerationResult gen = (AMD64HotSpotLIRGenerationResult) lirGenRen; + HotSpotLIRGenerationResult gen = (HotSpotLIRGenerationResult) lirGenRen; LIR lir = gen.getLIR(); assert gen.getDeoptimizationRescueSlot() == null || frameMap.frameNeedsAllocating() : "method that can deoptimize must have a frame"; boolean omitFrame = CanOmitFrame.getValue() && !frameMap.frameNeedsAllocating() && !lir.hasArgInCallerFrame() && !gen.hasForeignCall(); @@ -239,6 +217,7 @@ DataBuilder dataBuilder = new HotSpotDataBuilder(getCodeCache().getTarget()); CompilationResultBuilder crb = factory.createBuilder(getCodeCache(), getForeignCalls(), frameMap, masm, dataBuilder, frameContext, compilationResult); crb.setTotalFrameSize(frameMap.totalFrameSize()); + crb.setMaxInterpreterFrameSize(gen.getMaxInterpreterFrameSize()); StackSlot deoptimizationRescueSlot = gen.getDeoptimizationRescueSlot(); if (deoptimizationRescueSlot != null && stub == null) { crb.compilationResult.setCustomStackAreaOffset(frameMap.offsetForStackSlot(deoptimizationRescueSlot)); @@ -346,20 +325,4 @@ RegisterConfig registerConfigNonNull = registerConfig == null ? getCodeCache().getRegisterConfig() : registerConfig; return new AMD64HotSpotRegisterAllocationConfig(registerConfigNonNull); } - - private static final Unsafe UNSAFE = initUnsafe(); - - private static Unsafe initUnsafe() { - try { - return Unsafe.getUnsafe(); - } catch (SecurityException se) { - try { - Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); - theUnsafe.setAccessible(true); - return (Unsafe) theUnsafe.get(Unsafe.class); - } catch (Exception e) { - throw new RuntimeException("exception while trying to get Unsafe", e); - } - } - } } diff -r 5538acafd12f -r 3e4b96f3e4d3 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerationResult.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerationResult.java Wed Jan 20 22:30:50 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.hotspot.amd64; - -import java.util.Map; - -import jdk.vm.ci.code.StackSlot; - -import com.oracle.graal.compiler.common.CollectionsFactory; -import com.oracle.graal.hotspot.stubs.Stub; -import com.oracle.graal.lir.LIR; -import com.oracle.graal.lir.LIRFrameState; -import com.oracle.graal.lir.StandardOp.SaveRegistersOp; -import com.oracle.graal.lir.framemap.FrameMapBuilder; -import com.oracle.graal.lir.gen.LIRGenerationResultBase; - -public class AMD64HotSpotLIRGenerationResult extends LIRGenerationResultBase { - - /** - * The slot reserved for storing the original return address when a frame is marked for - * deoptimization. The return address slot in the callee is overwritten with the address of a - * deoptimization stub. - */ - private StackSlot deoptimizationRescueSlot; - private final Object stub; - - /** - * Map from debug infos that need to be updated with callee save information to the operations - * that provide the information. - */ - private Map calleeSaveInfo = CollectionsFactory.newMap(); - - public AMD64HotSpotLIRGenerationResult(String compilationUnitName, LIR lir, FrameMapBuilder frameMapBuilder, Object stub) { - super(compilationUnitName, lir, frameMapBuilder); - this.stub = stub; - } - - StackSlot getDeoptimizationRescueSlot() { - return deoptimizationRescueSlot; - } - - public final void setDeoptimizationRescueSlot(StackSlot stackSlot) { - this.deoptimizationRescueSlot = stackSlot; - } - - Stub getStub() { - return (Stub) stub; - } - - Map getCalleeSaveInfo() { - return calleeSaveInfo; - } -} diff -r 5538acafd12f -r 3e4b96f3e4d3 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 Wed Jan 20 22:30:50 2016 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Wed Jan 20 23:45:15 2016 -0800 @@ -58,7 +58,9 @@ import com.oracle.graal.compiler.common.spi.LIRKindTool; import com.oracle.graal.debug.Debug; import com.oracle.graal.hotspot.HotSpotBackend; +import com.oracle.graal.hotspot.HotSpotDebugInfoBuilder; import com.oracle.graal.hotspot.HotSpotForeignCallLinkage; +import com.oracle.graal.hotspot.HotSpotLIRGenerationResult; import com.oracle.graal.hotspot.HotSpotLIRGenerator; import com.oracle.graal.hotspot.HotSpotLockStack; import com.oracle.graal.hotspot.debug.BenchmarkCounters; @@ -93,7 +95,7 @@ public class AMD64HotSpotLIRGenerator extends AMD64LIRGenerator implements HotSpotLIRGenerator { final HotSpotVMConfig config; - private HotSpotLockStack lockStack; + private HotSpotDebugInfoBuilder debugInfoBuilder; protected AMD64HotSpotLIRGenerator(HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc, LIRGenerationResult lirGenRes) { this(providers, config, cc, lirGenRes, new BackupSlotProvider(lirGenRes.getFrameMapBuilder())); @@ -223,13 +225,8 @@ } private HotSpotLockStack getLockStack() { - assert lockStack != null; - return lockStack; - } - - protected void setLockStack(HotSpotLockStack lockStack) { - assert this.lockStack == null; - this.lockStack = lockStack; + assert debugInfoBuilder != null && debugInfoBuilder.lockStack() != null; + return debugInfoBuilder.lockStack(); } private Register findPollOnReturnScratchRegister() { @@ -260,7 +257,7 @@ @Override public boolean needOnlyOopMaps() { // Stubs only need oop maps - return ((AMD64HotSpotLIRGenerationResult) getResult()).getStub() != null; + return getResult().getStub() != null; } private LIRFrameState currentRuntimeCallInfo; @@ -348,7 +345,16 @@ * being generated. */ public Stub getStub() { - return ((AMD64HotSpotLIRGenerationResult) getResult()).getStub(); + return getResult().getStub(); + } + + @Override + public HotSpotLIRGenerationResult getResult() { + return ((HotSpotLIRGenerationResult) super.getResult()); + } + + public void setDebugInfoBuilder(HotSpotDebugInfoBuilder debugInfoBuilder) { + this.debugInfoBuilder = debugInfoBuilder; } @Override @@ -384,7 +390,7 @@ if (destroysRegisters) { if (stub != null) { if (stub.preservesRegisters()) { - AMD64HotSpotLIRGenerationResult generationResult = (AMD64HotSpotLIRGenerationResult) getResult(); + HotSpotLIRGenerationResult generationResult = getResult(); assert !generationResult.getCalleeSaveInfo().containsKey(currentRuntimeCallInfo); generationResult.getCalleeSaveInfo().put(currentRuntimeCallInfo, save); emitRestoreRegisters(save); @@ -406,7 +412,7 @@ Variable result = super.emitForeignCall(linkage, null, thread.asValue(LIRKind.value(AMD64Kind.QWORD)), trapRequest, mode); append(new AMD64HotSpotCRuntimeCallEpilogueOp(config.threadLastJavaSpOffset(), config.threadLastJavaFpOffset(), thread)); - Map calleeSaveInfo = ((AMD64HotSpotLIRGenerationResult) getResult()).getCalleeSaveInfo(); + Map calleeSaveInfo = getResult().getCalleeSaveInfo(); assert !calleeSaveInfo.containsKey(currentRuntimeCallInfo); calleeSaveInfo.put(currentRuntimeCallInfo, saveRegisterOp); @@ -422,7 +428,7 @@ Variable result = super.emitForeignCall(linkage, null, thread.asValue(LIRKind.value(AMD64Kind.QWORD)), mode); append(new AMD64HotSpotCRuntimeCallEpilogueOp(config.threadLastJavaSpOffset(), config.threadLastJavaFpOffset(), thread)); - Map calleeSaveInfo = ((AMD64HotSpotLIRGenerationResult) getResult()).getCalleeSaveInfo(); + Map calleeSaveInfo = getResult().getCalleeSaveInfo(); assert !calleeSaveInfo.containsKey(currentRuntimeCallInfo); calleeSaveInfo.put(currentRuntimeCallInfo, saveRegisterOp); @@ -442,7 +448,7 @@ PlatformKind kind = target().arch.getLargestStorableKind(zappedRegisters[i].getRegisterCategory()); zapValues[i] = zapValueForKind(kind); } - ((AMD64HotSpotLIRGenerationResult) getResult()).getCalleeSaveInfo().put(currentRuntimeCallInfo, emitZapRegisters(zappedRegisters, zapValues)); + getResult().getCalleeSaveInfo().put(currentRuntimeCallInfo, emitZapRegisters(zappedRegisters, zapValues)); return true; } @@ -512,9 +518,11 @@ boolean hasDebugInfo = getResult().getLIR().hasDebugInfo(); AllocatableValue savedRbp = saveRbp.finalize(hasDebugInfo); if (hasDebugInfo) { - ((AMD64HotSpotLIRGenerationResult) getResult()).setDeoptimizationRescueSlot(((AMD64FrameMapBuilder) getResult().getFrameMapBuilder()).allocateDeoptimizationRescueSlot()); + getResult().setDeoptimizationRescueSlot(((AMD64FrameMapBuilder) getResult().getFrameMapBuilder()).allocateDeoptimizationRescueSlot()); } + getResult().setMaxInterpreterFrameSize(debugInfoBuilder.maxInterpreterFrameSize()); + for (AMD64HotSpotRestoreRbpOp op : epilogueOps) { op.setSavedRbp(savedRbp); } diff -r 5538acafd12f -r 3e4b96f3e4d3 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java Wed Jan 20 22:30:50 2016 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java Wed Jan 20 23:45:15 2016 -0800 @@ -45,6 +45,7 @@ import com.oracle.graal.compiler.gen.DebugInfoBuilder; import com.oracle.graal.debug.Debug; import com.oracle.graal.hotspot.HotSpotDebugInfoBuilder; +import com.oracle.graal.hotspot.HotSpotLIRGenerator; import com.oracle.graal.hotspot.HotSpotLockStack; import com.oracle.graal.hotspot.HotSpotNodeLIRBuilder; import com.oracle.graal.hotspot.nodes.DirectCompareAndSwapNode; @@ -73,7 +74,7 @@ super(graph, gen, nodeMatchRules); assert gen instanceof AMD64HotSpotLIRGenerator; assert getDebugInfoBuilder() instanceof HotSpotDebugInfoBuilder; - ((AMD64HotSpotLIRGenerator) gen).setLockStack(((HotSpotDebugInfoBuilder) getDebugInfoBuilder()).lockStack()); + ((AMD64HotSpotLIRGenerator) gen).setDebugInfoBuilder(((HotSpotDebugInfoBuilder) getDebugInfoBuilder())); } private AMD64HotSpotLIRGenerator getGen() { @@ -83,7 +84,7 @@ @Override protected DebugInfoBuilder createDebugInfoBuilder(StructuredGraph graph, NodeValueMap nodeValueMap) { HotSpotLockStack lockStack = new HotSpotLockStack(gen.getResult().getFrameMapBuilder(), LIRKind.value(AMD64Kind.QWORD)); - return new HotSpotDebugInfoBuilder(nodeValueMap, lockStack); + return new HotSpotDebugInfoBuilder(nodeValueMap, lockStack, (HotSpotLIRGenerator) gen); } @Override diff -r 5538acafd12f -r 3e4b96f3e4d3 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Wed Jan 20 22:30:50 2016 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Wed Jan 20 23:45:15 2016 -0800 @@ -36,7 +36,6 @@ import static jdk.vm.ci.sparc.SPARC.g5; import static jdk.vm.ci.sparc.SPARC.sp; -import java.lang.reflect.Field; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -50,7 +49,6 @@ import jdk.vm.ci.hotspot.HotSpotVMConfig; import jdk.vm.ci.meta.JavaType; import jdk.vm.ci.meta.ResolvedJavaMethod; -import sun.misc.Unsafe; import com.oracle.graal.asm.Assembler; import com.oracle.graal.asm.Label; @@ -69,6 +67,7 @@ import com.oracle.graal.hotspot.HotSpotDataBuilder; import com.oracle.graal.hotspot.HotSpotGraalRuntimeProvider; import com.oracle.graal.hotspot.HotSpotHostBackend; +import com.oracle.graal.hotspot.HotSpotLIRGenerationResult; import com.oracle.graal.hotspot.meta.HotSpotForeignCallsProvider; import com.oracle.graal.hotspot.meta.HotSpotProviders; import com.oracle.graal.hotspot.stubs.Stub; @@ -141,7 +140,7 @@ @Override public LIRGenerationResult newLIRGenerationResult(String compilationUnitName, LIR lir, FrameMapBuilder frameMapBuilder, ResolvedJavaMethod method, Object stub) { - return new SPARCHotSpotLIRGenerationResult(compilationUnitName, lir, frameMapBuilder, stub); + return new HotSpotLIRGenerationResult(compilationUnitName, lir, frameMapBuilder, stub); } @Override @@ -149,38 +148,19 @@ return new SPARCHotSpotNodeLIRBuilder(graph, lirGen, new SPARCNodeMatchRules(lirGen)); } - /** - * Emits code to do stack overflow checking. - * - * @param afterFrameInit specifies if the stack pointer has already been adjusted to allocate - * the current frame - */ - protected static void emitStackOverflowCheck(CompilationResultBuilder crb, int pagesToBang, boolean afterFrameInit) { - if (pagesToBang > 0) { - SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm; - final int frameSize = crb.frameMap.totalFrameSize(); - if (frameSize > 0) { - int lastFramePage = frameSize / UNSAFE.pageSize(); - // emit multiple stack bangs for methods with frames larger than a page - for (int i = 0; i <= lastFramePage; i++) { - int disp = (i + pagesToBang) * UNSAFE.pageSize(); - if (afterFrameInit) { - disp -= frameSize; - } - crb.blockComment("[stack overflow check]"); - // Use SPARCAddress to get the final displacement including the stack bias. - SPARCAddress address = new SPARCAddress(sp, -disp); - if (SPARCAssembler.isSimm13(address.getDisplacement())) { - masm.stx(g0, address); - } else { - try (ScratchRegister sc = masm.getScratchRegister()) { - Register scratch = sc.getRegister(); - assert afterFrameInit || isGlobalRegister(scratch) : "Only global (g1-g7) registers are allowed if the frame was not initialized here. Got register " + scratch; - masm.setx(address.getDisplacement(), scratch, false); - masm.stx(g0, new SPARCAddress(sp, scratch)); - } - } - } + @Override + protected void bangStackWithOffset(CompilationResultBuilder crb, int bangOffset) { + // Use SPARCAddress to get the final displacement including the stack bias. + SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm; + SPARCAddress address = new SPARCAddress(sp, -bangOffset); + if (SPARCAssembler.isSimm13(address.getDisplacement())) { + masm.stx(g0, address); + } else { + try (ScratchRegister sc = masm.getScratchRegister()) { + Register scratch = sc.getRegister(); + assert isGlobalRegister(scratch) : "Only global (g1-g7) registers are allowed if the frame was not initialized here. Got register " + scratch; + masm.setx(address.getDisplacement(), scratch, false); + masm.stx(g0, new SPARCAddress(sp, scratch)); } } } @@ -202,9 +182,7 @@ final int frameSize = crb.frameMap.totalFrameSize(); final int stackpoinerChange = -frameSize; SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm; - if (!isStub && pagesToBang > 0) { - emitStackOverflowCheck(crb, pagesToBang, false); - } + emitStackOverflowCheck(crb); if (SPARCAssembler.isSimm13(stackpoinerChange)) { masm.save(sp, stackpoinerChange, sp); @@ -240,7 +218,7 @@ @Override public CompilationResultBuilder newCompilationResultBuilder(LIRGenerationResult lirGenRes, FrameMap frameMap, CompilationResult compilationResult, CompilationResultBuilderFactory factory) { - SPARCHotSpotLIRGenerationResult gen = (SPARCHotSpotLIRGenerationResult) lirGenRes; + HotSpotLIRGenerationResult gen = (HotSpotLIRGenerationResult) lirGenRes; LIR lir = gen.getLIR(); assert gen.getDeoptimizationRescueSlot() == null || frameMap.frameNeedsAllocating() : "method that can deoptimize must have a frame"; @@ -251,6 +229,7 @@ DataBuilder dataBuilder = new HotSpotDataBuilder(getCodeCache().getTarget()); CompilationResultBuilder crb = factory.createBuilder(getProviders().getCodeCache(), getProviders().getForeignCalls(), frameMap, masm, dataBuilder, frameContext, compilationResult); crb.setTotalFrameSize(frameMap.totalFrameSize()); + crb.setMaxInterpreterFrameSize(gen.getMaxInterpreterFrameSize()); StackSlot deoptimizationRescueSlot = gen.getDeoptimizationRescueSlot(); if (deoptimizationRescueSlot != null && stub == null) { crb.compilationResult.setCustomStackAreaOffset(frameMap.offsetForStackSlot(deoptimizationRescueSlot)); @@ -507,20 +486,4 @@ RegisterConfig registerConfigNonNull = registerConfig == null ? getCodeCache().getRegisterConfig() : registerConfig; return new SPARCHotSpotRegisterAllocationConfig(registerConfigNonNull); } - - private static final Unsafe UNSAFE = initUnsafe(); - - private static Unsafe initUnsafe() { - try { - return Unsafe.getUnsafe(); - } catch (SecurityException se) { - try { - Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); - theUnsafe.setAccessible(true); - return (Unsafe) theUnsafe.get(Unsafe.class); - } catch (Exception e) { - throw new RuntimeException("exception while trying to get Unsafe", e); - } - } - } } diff -r 5538acafd12f -r 3e4b96f3e4d3 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerationResult.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerationResult.java Wed Jan 20 22:30:50 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.hotspot.sparc; - -import java.util.HashMap; -import java.util.Map; - -import jdk.vm.ci.code.StackSlot; - -import com.oracle.graal.hotspot.stubs.Stub; -import com.oracle.graal.lir.LIR; -import com.oracle.graal.lir.LIRFrameState; -import com.oracle.graal.lir.StandardOp.SaveRegistersOp; -import com.oracle.graal.lir.framemap.FrameMapBuilder; -import com.oracle.graal.lir.gen.LIRGenerationResultBase; - -public class SPARCHotSpotLIRGenerationResult extends LIRGenerationResultBase { - - /** - * The slot reserved for storing the original return address when a frame is marked for - * deoptimization. The return address slot in the callee is overwritten with the address of a - * deoptimization stub. - */ - private StackSlot deoptimizationRescueSlot; - private final Object stub; - - /** - * Map from debug infos that need to be updated with callee save information to the operations - * that provide the information. - */ - private Map calleeSaveInfo = new HashMap<>(); - - public SPARCHotSpotLIRGenerationResult(String compilationUnitName, LIR lir, FrameMapBuilder frameMapBuilder, Object stub) { - super(compilationUnitName, lir, frameMapBuilder); - this.stub = stub; - } - - StackSlot getDeoptimizationRescueSlot() { - return deoptimizationRescueSlot; - } - - public final void setDeoptimizationRescueSlot(StackSlot stackSlot) { - this.deoptimizationRescueSlot = stackSlot; - } - - Stub getStub() { - return (Stub) stub; - } - - Map getCalleeSaveInfo() { - return calleeSaveInfo; - } -} diff -r 5538acafd12f -r 3e4b96f3e4d3 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 Wed Jan 20 22:30:50 2016 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Wed Jan 20 23:45:15 2016 -0800 @@ -94,7 +94,9 @@ import com.oracle.graal.compiler.sparc.SPARCArithmeticLIRGenerator; import com.oracle.graal.compiler.sparc.SPARCLIRGenerator; import com.oracle.graal.hotspot.HotSpotBackend; +import com.oracle.graal.hotspot.HotSpotDebugInfoBuilder; import com.oracle.graal.hotspot.HotSpotForeignCallLinkage; +import com.oracle.graal.hotspot.HotSpotLIRGenerationResult; import com.oracle.graal.hotspot.HotSpotLIRGenerator; import com.oracle.graal.hotspot.HotSpotLockStack; import com.oracle.graal.hotspot.debug.BenchmarkCounters; @@ -121,7 +123,7 @@ public class SPARCHotSpotLIRGenerator extends SPARCLIRGenerator implements HotSpotLIRGenerator { final HotSpotVMConfig config; - private HotSpotLockStack lockStack; + private HotSpotDebugInfoBuilder debugInfoBuilder; private LIRFrameState currentRuntimeCallInfo; public SPARCHotSpotLIRGenerator(HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc, LIRGenerationResult lirGenRes) { @@ -162,13 +164,8 @@ } private HotSpotLockStack getLockStack() { - assert lockStack != null; - return lockStack; - } - - protected void setLockStack(HotSpotLockStack lockStack) { - assert this.lockStack == null; - this.lockStack = lockStack; + assert debugInfoBuilder != null && debugInfoBuilder.lockStack() != null; + return debugInfoBuilder.lockStack(); } @Override @@ -178,7 +175,12 @@ } public Stub getStub() { - return ((SPARCHotSpotLIRGenerationResult) getResult()).getStub(); + return getResult().getStub(); + } + + @Override + public HotSpotLIRGenerationResult getResult() { + return ((HotSpotLIRGenerationResult) super.getResult()); } @Override @@ -186,8 +188,10 @@ super.beforeRegisterAllocation(); boolean hasDebugInfo = getResult().getLIR().hasDebugInfo(); if (hasDebugInfo) { - ((SPARCHotSpotLIRGenerationResult) getResult()).setDeoptimizationRescueSlot(((SPARCFrameMapBuilder) getResult().getFrameMapBuilder()).allocateDeoptimizationRescueSlot()); + getResult().setDeoptimizationRescueSlot(((SPARCFrameMapBuilder) getResult().getFrameMapBuilder()).allocateDeoptimizationRescueSlot()); } + + getResult().setMaxInterpreterFrameSize(debugInfoBuilder.maxInterpreterFrameSize()); } @Override @@ -449,7 +453,7 @@ Variable result = super.emitForeignCall(linkage, null, threadRegister.asValue(LIRKind.value(target().arch.getWordKind())), trapRequest, mode); append(new SPARCHotSpotCRuntimeCallEpilogueOp(config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), config.threadJavaFrameAnchorFlagsOffset(), threadRegister, threadTemp)); - Map calleeSaveInfo = ((SPARCHotSpotLIRGenerationResult) getResult()).getCalleeSaveInfo(); + Map calleeSaveInfo = getResult().getCalleeSaveInfo(); assert currentRuntimeCallInfo != null; assert !calleeSaveInfo.containsKey(currentRuntimeCallInfo); calleeSaveInfo.put(currentRuntimeCallInfo, saveRegisterOp); @@ -469,7 +473,7 @@ Variable result = super.emitForeignCall(linkage, null, threadRegister.asValue(LIRKind.value(target().arch.getWordKind())), mode); append(new SPARCHotSpotCRuntimeCallEpilogueOp(config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), config.threadJavaFrameAnchorFlagsOffset(), threadRegister, threadTemp)); - Map calleeSaveInfo = ((SPARCHotSpotLIRGenerationResult) getResult()).getCalleeSaveInfo(); + Map calleeSaveInfo = getResult().getCalleeSaveInfo(); assert currentRuntimeCallInfo != null; assert !calleeSaveInfo.containsKey(currentRuntimeCallInfo); calleeSaveInfo.put(currentRuntimeCallInfo, saveRegisterOp); @@ -516,4 +520,8 @@ protected StrategySwitchOp createStrategySwitchOp(AllocatableValue base, SwitchStrategy strategy, LabelRef[] keyTargets, LabelRef defaultTarget, Variable key, AllocatableValue scratchValue) { return new SPARCHotSpotStrategySwitchOp(base, strategy, keyTargets, defaultTarget, key, scratchValue); } + + public void setDebugInfoBuilder(HotSpotDebugInfoBuilder debugInfoBuilder) { + this.debugInfoBuilder = debugInfoBuilder; + } } diff -r 5538acafd12f -r 3e4b96f3e4d3 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java Wed Jan 20 22:30:50 2016 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java Wed Jan 20 23:45:15 2016 -0800 @@ -42,6 +42,7 @@ import com.oracle.graal.compiler.sparc.SPARCNodeMatchRules; import com.oracle.graal.debug.Debug; import com.oracle.graal.hotspot.HotSpotDebugInfoBuilder; +import com.oracle.graal.hotspot.HotSpotLIRGenerator; import com.oracle.graal.hotspot.HotSpotLockStack; import com.oracle.graal.hotspot.HotSpotNodeLIRBuilder; import com.oracle.graal.hotspot.nodes.DirectCompareAndSwapNode; @@ -66,13 +67,13 @@ super(graph, lirGen, nodeMatchRules); assert gen instanceof SPARCHotSpotLIRGenerator; assert getDebugInfoBuilder() instanceof HotSpotDebugInfoBuilder; - ((SPARCHotSpotLIRGenerator) gen).setLockStack(((HotSpotDebugInfoBuilder) getDebugInfoBuilder()).lockStack()); + ((SPARCHotSpotLIRGenerator) gen).setDebugInfoBuilder(((HotSpotDebugInfoBuilder) getDebugInfoBuilder())); } @Override protected DebugInfoBuilder createDebugInfoBuilder(StructuredGraph graph, NodeValueMap nodeValueMap) { HotSpotLockStack lockStack = new HotSpotLockStack(gen.getResult().getFrameMapBuilder(), LIRKind.value(SPARCKind.XWORD)); - return new HotSpotDebugInfoBuilder(nodeValueMap, lockStack); + return new HotSpotDebugInfoBuilder(nodeValueMap, lockStack, (HotSpotLIRGenerator) gen); } private SPARCHotSpotLIRGenerator getGen() { diff -r 5538acafd12f -r 3e4b96f3e4d3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java Wed Jan 20 22:30:50 2016 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java Wed Jan 20 23:45:15 2016 -0800 @@ -27,6 +27,7 @@ import jdk.vm.ci.code.StackLockValue; import jdk.vm.ci.code.VirtualObject; import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider; import jdk.vm.ci.meta.JavaValue; import com.oracle.graal.compiler.gen.DebugInfoBuilder; @@ -42,15 +43,24 @@ private final HotSpotLockStack lockStack; - public HotSpotDebugInfoBuilder(NodeValueMap nodeValueMap, HotSpotLockStack lockStack) { + private int maxInterpreterFrameSize; + + private HotSpotCodeCacheProvider codeCacheProvider; + + public HotSpotDebugInfoBuilder(NodeValueMap nodeValueMap, HotSpotLockStack lockStack, HotSpotLIRGenerator gen) { super(nodeValueMap); this.lockStack = lockStack; + this.codeCacheProvider = gen.getProviders().getCodeCache(); } public HotSpotLockStack lockStack() { return lockStack; } + public int maxInterpreterFrameSize() { + return maxInterpreterFrameSize; + } + @Override protected JavaValue computeLockValue(FrameState state, int lockIndex) { int lockDepth = lockIndex; @@ -71,6 +81,8 @@ // This is really a hard error since an incorrect state could crash hotspot throw JVMCIError.shouldNotReachHere("Invalid state " + BytecodeFrame.getPlaceholderBciName(state.bci) + " " + state); } - return super.computeFrameForState(state); + BytecodeFrame result = super.computeFrameForState(state); + maxInterpreterFrameSize = Math.max(maxInterpreterFrameSize, codeCacheProvider.interpreterFrameSize(result)); + return result; } } diff -r 5538acafd12f -r 3e4b96f3e4d3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java Wed Jan 20 22:30:50 2016 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java Wed Jan 20 23:45:15 2016 -0800 @@ -40,6 +40,7 @@ import com.oracle.graal.hotspot.meta.HotSpotProviders; import com.oracle.graal.hotspot.stubs.DeoptimizationStub; import com.oracle.graal.hotspot.stubs.UncommonTrapStub; +import com.oracle.graal.lir.asm.CompilationResultBuilder; import com.oracle.graal.nodes.spi.ReplacementsProvider; /** @@ -61,14 +62,11 @@ */ public static final ForeignCallDescriptor UNCOMMON_TRAP_HANDLER = new ForeignCallDescriptor("uncommonTrapHandler", void.class); - /** - * This will be 0 if stack banging is disabled. - */ - protected final int pagesToBang; + private final HotSpotVMConfig config; public HotSpotHostBackend(HotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers) { super(runtime, providers); - this.pagesToBang = config.useStackBanging ? config.stackShadowPages : 0; + this.config = config; } @Override @@ -83,7 +81,7 @@ foreignCalls.initialize(providers); } try (InitTimer st = timer("lowerer.initialize")) { - lowerer.initialize(providers, jvmciRuntime.getConfig()); + lowerer.initialize(providers, config); } // Install intrinsics. @@ -105,4 +103,43 @@ } } } + + public void emitStackOverflowCheck(CompilationResultBuilder crb) { + if (config.useStackBanging) { + // Each code entry causes one stack bang n pages down the stack where n + // is configurable by StackShadowPages. The setting depends on the maximum + // depth of VM call stack or native before going back into java code, + // since only java code can raise a stack overflow exception using the + // stack banging mechanism. The VM and native code does not detect stack + // overflow. + // The code in JavaCalls::call() checks that there is at least n pages + // available, so all entry code needs to do is bang once for the end of + // this shadow zone. + // The entry code may need to bang additional pages if the framesize + // is greater than a page. + + int pageSize = config.vmPageSize; + int bangEnd = config.stackShadowPages * pageSize; + + // This is how far the previous frame's stack banging extended. + int bangEndSafe = bangEnd; + + int frameSize = Math.max(crb.frameMap.frameSize(), crb.compilationResult.getMaxInterpreterFrameSize()); + if (frameSize > pageSize) { + bangEnd += frameSize; + } + + int bangOffset = bangEndSafe; + if (bangOffset <= bangEnd) { + crb.blockComment("[stack overflow check]"); + } + while (bangOffset <= bangEnd) { + // Need at least one stack bang at end of shadow zone. + bangStackWithOffset(crb, bangOffset); + bangOffset += pageSize; + } + } + } + + protected abstract void bangStackWithOffset(CompilationResultBuilder crb, int bangOffset); } diff -r 5538acafd12f -r 3e4b96f3e4d3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerationResult.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerationResult.java Wed Jan 20 23:45:15 2016 -0800 @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot; + +import java.util.Map; + +import jdk.vm.ci.code.StackSlot; + +import com.oracle.graal.compiler.common.CollectionsFactory; +import com.oracle.graal.hotspot.stubs.Stub; +import com.oracle.graal.lir.LIR; +import com.oracle.graal.lir.LIRFrameState; +import com.oracle.graal.lir.StandardOp.SaveRegistersOp; +import com.oracle.graal.lir.framemap.FrameMapBuilder; +import com.oracle.graal.lir.gen.LIRGenerationResultBase; + +public class HotSpotLIRGenerationResult extends LIRGenerationResultBase { + + /** + * The slot reserved for storing the original return address when a frame is marked for + * deoptimization. The return address slot in the callee is overwritten with the address of a + * deoptimization stub. + */ + private StackSlot deoptimizationRescueSlot; + protected final Object stub; + + private int maxInterpreterFrameSize; + + /** + * Map from debug infos that need to be updated with callee save information to the operations + * that provide the information. + */ + private Map calleeSaveInfo = CollectionsFactory.newMap(); + + public HotSpotLIRGenerationResult(String compilationUnitName, LIR lir, FrameMapBuilder frameMapBuilder, Object stub) { + super(compilationUnitName, lir, frameMapBuilder); + this.stub = stub; + } + + public Map getCalleeSaveInfo() { + return calleeSaveInfo; + } + + public Stub getStub() { + return (Stub) stub; + } + + public StackSlot getDeoptimizationRescueSlot() { + return deoptimizationRescueSlot; + } + + public final void setDeoptimizationRescueSlot(StackSlot stackSlot) { + this.deoptimizationRescueSlot = stackSlot; + } + + public void setMaxInterpreterFrameSize(int maxInterpreterFrameSize) { + this.maxInterpreterFrameSize = maxInterpreterFrameSize; + } + + public int getMaxInterpreterFrameSize() { + return maxInterpreterFrameSize; + } +} diff -r 5538acafd12f -r 3e4b96f3e4d3 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java Wed Jan 20 22:30:50 2016 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java Wed Jan 20 23:45:15 2016 -0800 @@ -145,6 +145,10 @@ compilationResult.setTotalFrameSize(frameSize); } + public void setMaxInterpreterFrameSize(int maxInterpreterFrameSize) { + compilationResult.setMaxInterpreterFrameSize(maxInterpreterFrameSize); + } + public Mark recordMark(Object id) { return compilationResult.recordMark(asm.position(), id); } diff -r 5538acafd12f -r 3e4b96f3e4d3 mx.graal/suite.py --- a/mx.graal/suite.py Wed Jan 20 22:30:50 2016 +0100 +++ b/mx.graal/suite.py Wed Jan 20 23:45:15 2016 -0800 @@ -39,7 +39,7 @@ { "name" : "jvmci", "optional" : "true", - "version" : "5d06abd6d35b9385aaff9af90a6d0cd729c81246", + "version" : "bf8a5a6861b1f17bcbeb5802bd1c37402483444e", "urls" : [ {"url" : "http://lafo.ssw.uni-linz.ac.at/hg/graal-jvmci-8", "kind" : "hg"}, {"url" : "https://curio.ssw.jku.at/nexus/content/repositories/snapshots", "kind" : "binary"},