changeset 8282:59744882ddeb

moved logic for reserving a special area/slot in a frame (e.g., for use during deoptimization) out of FrameMap and into platform specific backend class
author Doug Simon <doug.simon@oracle.com>
date Thu, 14 Mar 2013 14:35:53 +0100
parents 8fde1be81b2d
children 09290d9deab3
files graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java
diffstat 4 files changed, 31 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Thu Mar 14 14:08:59 2013 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Thu Mar 14 14:35:53 2013 +0100
@@ -262,6 +262,8 @@
             }
         });
 
+        lirGen.beforeRegisterAllocation();
+
         Debug.scope("Allocator", new Runnable() {
 
             public void run() {
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Thu Mar 14 14:08:59 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Thu Mar 14 14:35:53 2013 +0100
@@ -187,6 +187,20 @@
         public void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason) {
             append(new AMD64DeoptimizeOp(action, reason, state(reason)));
         }
+
+        /**
+         * 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.
+         */
+        StackSlot deoptimizationRescueSlot;
+
+        @Override
+        public void beforeRegisterAllocation() {
+            if (lir.hasDebugInfo()) {
+                deoptimizationRescueSlot = frameMap.allocateSpillSlot(Kind.Long);
+            }
+        }
     }
 
     /**
@@ -274,7 +288,10 @@
         HotSpotFrameContext frameContext = omitFrame ? null : new HotSpotFrameContext();
         TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime(), frameMap, masm, frameContext, compilationResult);
         tasm.setFrameSize(frameMap.frameSize());
-        tasm.compilationResult.setCustomStackAreaOffset(frameMap.offsetToCustomArea());
+        StackSlot deoptimizationRescueSlot = ((HotSpotAMD64LIRGenerator) lirGen).deoptimizationRescueSlot;
+        if (deoptimizationRescueSlot != null) {
+            tasm.compilationResult.setCustomStackAreaOffset(frameMap.offsetForStackSlot(deoptimizationRescueSlot));
+        }
         return tasm;
     }
 
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java	Thu Mar 14 14:08:59 2013 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java	Thu Mar 14 14:35:53 2013 +0100
@@ -70,17 +70,11 @@
  * The spill slot area also includes stack allocated memory blocks (ALLOCA blocks). The size of such
  * a block may be greater than the size of a normal spill slot or the word size.
  * <p>
- * A runtime has two ways to reserve space in the stack frame for its own use:
- * <ul>
- * <li>A memory block somewhere in the frame of size
- * {@link CodeCacheProvider#getCustomStackAreaSize()}. The offset to this block is returned in
- * {@link CompilationResult#getCustomStackAreaOffset()}.
- * <li>At the beginning of the overflow argument area: The calling convention can specify that the
- * first overflow stack argument is not at offset 0, but at a specified offset o. Use
- * {@link CodeCacheProvider#getMinimumOutgoingSize()} to make sure that call-free methods also have
- * this space reserved. Then the VM can use memory the memory at offset 0 relative to the stack
- * pointer.
- * </ul>
+ * A runtime can reserve space at the beginning of the overflow argument area. The calling
+ * convention can specify that the first overflow stack argument is not at offset 0, but at a
+ * specified offset. Use {@link CodeCacheProvider#getMinimumOutgoingSize()} to make sure that
+ * call-free methods also have this space reserved. Then the VM can use the memory at offset 0
+ * relative to the stack pointer.
  */
 public final class FrameMap {
 
@@ -117,12 +111,6 @@
     private final List<StackSlot> objectStackBlocks;
 
     /**
-     * The stack area reserved for use by the VM, or {@code null} if the VM does not request stack
-     * space.
-     */
-    private final StackSlot customArea;
-
-    /**
      * Records whether an offset to an incoming stack argument was ever returned by
      * {@link #offsetForStackSlot(StackSlot)}.
      */
@@ -139,7 +127,6 @@
         this.spillSize = returnAddressSize() + calleeSaveAreaSize();
         this.outgoingSize = runtime.getMinimumOutgoingSize();
         this.objectStackBlocks = new ArrayList<>();
-        this.customArea = allocateStackBlock(runtime.getCustomStackAreaSize(), false);
         this.initialFrameSize = currentFrameSize();
     }
 
@@ -223,16 +210,6 @@
     }
 
     /**
-     * Gets the offset of the stack area stack block reserved for use by the VM, or -1 if the VM
-     * does not request stack space.
-     * 
-     * @return The offset to the custom area (in bytes).
-     */
-    public int offsetToCustomArea() {
-        return customArea == null ? -1 : offsetForStackSlot(customArea);
-    }
-
-    /**
      * Informs the frame map that the compiled code calls a particular method, which may need stack
      * space for outgoing arguments.
      * 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java	Thu Mar 14 14:08:59 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java	Thu Mar 14 14:35:53 2013 +0100
@@ -134,4 +134,10 @@
     public abstract void visitBreakpointNode(BreakpointNode i);
 
     public abstract void emitUnwind(Value operand);
+
+    /**
+     * Called just before register allocation is performed on the LIR owned by this generator.
+     */
+    public void beforeRegisterAllocation() {
+    }
 }