changeset 23345:3e4b96f3e4d3

Update graal import: stack banging must take space required for deopt into account
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Wed, 20 Jan 2016 23:45:15 -0800
parents 5538acafd12f
children 59be481d0b4c
files graal/com.oracle.graal.code/src/com/oracle/graal/code/CompilationResult.java graal/com.oracle.graal.hotspot.aarch64/src/com/oracle/graal/hotspot/aarch64/AArch64HotSpotBackend.java graal/com.oracle.graal.hotspot.aarch64/src/com/oracle/graal/hotspot/aarch64/AArch64HotSpotLIRGenerationResult.java graal/com.oracle.graal.hotspot.aarch64/src/com/oracle/graal/hotspot/aarch64/AArch64HotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.aarch64/src/com/oracle/graal/hotspot/aarch64/AArch64HotSpotNodeLIRBuilder.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerationResult.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerationResult.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerationResult.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java mx.graal/suite.py
diffstat 18 files changed, 311 insertions(+), 457 deletions(-) [+]
line wrap: on
line diff
--- 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<Mark> 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.
      *
--- 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);
-            }
-        }
-    }
 }
--- 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<LIRFrameState, StandardOp.SaveRegistersOp> 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<LIRFrameState, StandardOp.SaveRegistersOp> getCalleeSaveInfo() {
-        return calleeSaveInfo;
-    }
-}
--- 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;
     }
 
 }
--- 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() {
--- 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);
-            }
-        }
-    }
 }
--- 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<LIRFrameState, SaveRegistersOp> 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<LIRFrameState, SaveRegistersOp> getCalleeSaveInfo() {
-        return calleeSaveInfo;
-    }
-}
--- 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<LIRFrameState, SaveRegistersOp> calleeSaveInfo = ((AMD64HotSpotLIRGenerationResult) getResult()).getCalleeSaveInfo();
+        Map<LIRFrameState, SaveRegistersOp> 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<LIRFrameState, SaveRegistersOp> calleeSaveInfo = ((AMD64HotSpotLIRGenerationResult) getResult()).getCalleeSaveInfo();
+        Map<LIRFrameState, SaveRegistersOp> 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);
         }
--- 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
--- 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);
-            }
-        }
-    }
 }
--- 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<LIRFrameState, SaveRegistersOp> 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<LIRFrameState, SaveRegistersOp> getCalleeSaveInfo() {
-        return calleeSaveInfo;
-    }
-}
--- 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<LIRFrameState, SaveRegistersOp> calleeSaveInfo = ((SPARCHotSpotLIRGenerationResult) getResult()).getCalleeSaveInfo();
+        Map<LIRFrameState, SaveRegistersOp> 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<LIRFrameState, SaveRegistersOp> calleeSaveInfo = ((SPARCHotSpotLIRGenerationResult) getResult()).getCalleeSaveInfo();
+        Map<LIRFrameState, SaveRegistersOp> 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;
+    }
 }
--- 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() {
--- 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;
     }
 }
--- 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);
 }
--- /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<LIRFrameState, SaveRegistersOp> calleeSaveInfo = CollectionsFactory.newMap();
+
+    public HotSpotLIRGenerationResult(String compilationUnitName, LIR lir, FrameMapBuilder frameMapBuilder, Object stub) {
+        super(compilationUnitName, lir, frameMapBuilder);
+        this.stub = stub;
+    }
+
+    public Map<LIRFrameState, SaveRegistersOp> 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;
+    }
+}
--- 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);
     }
--- 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"},