changeset 18464:e6b6463c9c06

Merge (FrameMapBuilder).
author Josef Eisl <josef.eisl@jku.at>
date Wed, 19 Nov 2014 16:06:49 +0100
parents eeed42f7e38c (diff) 0ea607f6a680 (current diff)
children f0a8b72315c1
files
diffstat 81 files changed, 1244 insertions(+), 666 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGELOG.md	Wed Nov 19 13:43:12 2014 +0100
+++ b/CHANGELOG.md	Wed Nov 19 16:06:49 2014 +0100
@@ -3,6 +3,7 @@
 ## `tip`
 ### Graal
 * Changed name suite specification from `mx/projects.py` to `mx/suite.py`.
+* Changed semantics (and signature) of `ResolvedJavaType#resolveMethod()` (old behavior available via `resolveConcreteMethod()`).
 * ...
 
 ### Truffle
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/StackSlot.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/StackSlot.java	Wed Nov 19 16:06:49 2014 +0100
@@ -28,7 +28,7 @@
  * Represents a compiler spill slot or an outgoing stack-based argument in a method's frame or an
  * incoming stack-based argument in a method's {@linkplain #isInCallerFrame() caller's frame}.
  */
-public final class StackSlot extends AllocatableValue {
+public final class StackSlot extends StackSlotValue {
 
     private static final long serialVersionUID = -7725071921307318433L;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/StackSlotValue.java	Wed Nov 19 16:06:49 2014 +0100
@@ -0,0 +1,35 @@
+/*
+ * 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.api.code;
+
+import com.oracle.graal.api.meta.*;
+
+public abstract class StackSlotValue extends AllocatableValue {
+
+    private static final long serialVersionUID = 5106407801795483337L;
+
+    public StackSlotValue(LIRKind lirKind) {
+        super(lirKind);
+    }
+
+}
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ValueUtil.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ValueUtil.java	Wed Nov 19 16:06:49 2014 +0100
@@ -80,6 +80,26 @@
         return (StackSlot) value;
     }
 
+    public static boolean isStackSlotValue(Value value) {
+        assert value != null;
+        return value instanceof StackSlotValue;
+    }
+
+    public static StackSlotValue asStackSlotValue(Value value) {
+        assert value != null;
+        return (StackSlotValue) value;
+    }
+
+    public static boolean isVirtualStackSlot(Value value) {
+        assert value != null;
+        return value instanceof VirtualStackSlot;
+    }
+
+    public static VirtualStackSlot asVirtualStackSlot(Value value) {
+        assert value != null;
+        return (VirtualStackSlot) value;
+    }
+
     public static boolean isRegister(Value value) {
         assert value != null;
         return value instanceof RegisterValue;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualStackSlot.java	Wed Nov 19 16:06:49 2014 +0100
@@ -0,0 +1,73 @@
+/*
+ * 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.api.code;
+
+import com.oracle.graal.api.meta.*;
+
+public abstract class VirtualStackSlot extends StackSlotValue {
+
+    private static final long serialVersionUID = 2823688688873398219L;
+    private static int idCounter = 0;
+    private final int id;
+
+    public VirtualStackSlot(LIRKind lirKind) {
+        super(lirKind);
+        id = idCounter++;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    @Override
+    public String toString() {
+        return "vstack(" + id + ")" + getKindSuffix();
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = super.hashCode();
+        result = prime * result + id;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        VirtualStackSlot other = (VirtualStackSlot) obj;
+        if (id != other.id) {
+            return false;
+        }
+        return true;
+    }
+
+}
--- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java	Wed Nov 19 16:06:49 2014 +0100
@@ -43,6 +43,7 @@
 import com.oracle.graal.java.BciBlockMapping.LocalLiveness;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.BlockEndOp;
+import com.oracle.graal.lir.framemap.*;
 import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.phases.*;
 
@@ -134,6 +135,7 @@
 
             RegisterConfig registerConfig = null;
             FrameMapBuilder frameMapBuilder = backend.newFrameMapBuilder(registerConfig);
+            frameMapBuilder.requireMapping(lir);
             TargetDescription target = backend.getTarget();
             CallingConvention cc = CodeUtil.getCallingConvention(backend.getProviders().getCodeCache(), CallingConvention.Type.JavaCallee, method, false);
             this.lirGenRes = backend.newLIRGenerationResult(lir, frameMapBuilder, method, null);
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Wed Nov 19 16:06:49 2014 +0100
@@ -108,7 +108,7 @@
     protected AMD64LIRInstruction createMove(AllocatableValue dst, Value src) {
         if (src instanceof AMD64AddressValue) {
             return new LeaOp(dst, (AMD64AddressValue) src);
-        } else if (isRegister(src) || isStackSlot(dst)) {
+        } else if (isRegister(src) || isStackSlotValue(dst)) {
             return new MoveFromRegOp(dst.getKind(), dst, src);
         } else {
             return new MoveToRegOp(dst.getKind(), dst, src);
@@ -196,7 +196,7 @@
     }
 
     @Override
-    public Variable emitAddress(StackSlot address) {
+    public Variable emitAddress(StackSlotValue address) {
         Variable result = newVariable(LIRKind.value(target().wordKind));
         append(new StackLeaOp(result, address));
         return result;
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java	Wed Nov 19 16:06:49 2014 +0100
@@ -86,7 +86,7 @@
     protected HSAILLIRInstruction createMove(AllocatableValue dst, Value src) {
         if (src instanceof HSAILAddressValue) {
             return new LeaOp(dst, (HSAILAddressValue) src);
-        } else if (isRegister(src) || isStackSlot(dst)) {
+        } else if (isRegister(src) || isStackSlotValue(dst)) {
             return new MoveFromRegOp(dst.getKind(), dst, src);
         } else {
             return new MoveToRegOp(dst.getKind(), dst, src);
@@ -152,7 +152,7 @@
     }
 
     @Override
-    public Variable emitAddress(StackSlot address) {
+    public Variable emitAddress(StackSlotValue address) {
         throw GraalInternalError.unimplemented();
     }
 
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Wed Nov 19 16:06:49 2014 +0100
@@ -127,7 +127,7 @@
 
     @Override
     public void emitMove(AllocatableValue dst, Value src) {
-        if (isRegister(src) || isStackSlot(dst)) {
+        if (isRegister(src) || isStackSlotValue(dst)) {
             append(new MoveFromRegOp(dst, src));
         } else {
             append(new MoveToRegOp(dst, src));
@@ -216,7 +216,7 @@
     }
 
     @Override
-    public Variable emitAddress(StackSlot address) {
+    public Variable emitAddress(StackSlotValue address) {
         throw GraalInternalError.unimplemented("PTXLIRGenerator.emitAddress()");
     }
 
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Wed Nov 19 16:06:49 2014 +0100
@@ -68,7 +68,7 @@
  */
 public abstract class SPARCLIRGenerator extends LIRGenerator {
 
-    private StackSlot tmpStackSlot;
+    private StackSlotValue tmpStackSlot;
 
     private class SPARCSpillMoveFactory implements LIR.SpillMoveFactory {
 
@@ -100,7 +100,7 @@
     protected SPARCLIRInstruction createMove(AllocatableValue dst, Value src) {
         if (src instanceof SPARCAddressValue) {
             return new LoadAddressOp(dst, (SPARCAddressValue) src);
-        } else if (isRegister(src) || isStackSlot(dst)) {
+        } else if (isRegister(src) || isStackSlotValue(dst)) {
             return new MoveFromRegOp(dst, src);
         } else {
             return new MoveToRegOp(dst, src);
@@ -189,7 +189,7 @@
     }
 
     @Override
-    public Value emitAddress(StackSlot address) {
+    public Value emitAddress(StackSlotValue address) {
         Variable result = newVariable(LIRKind.value(target().wordKind));
         append(new StackLoadAddressOp(result, address));
         return result;
@@ -911,14 +911,14 @@
 
     private void moveBetweenFpGp(AllocatableValue dst, AllocatableValue src) {
         if (!getArchitecture().getFeatures().contains(CPUFeature.VIS3)) {
-            StackSlot tempSlot = getTempSlot(LIRKind.value(Kind.Long));
+            StackSlotValue tempSlot = getTempSlot(LIRKind.value(Kind.Long));
             append(new MoveFpGp(dst, src, tempSlot));
         } else {
             append(new MoveFpGpVIS3(dst, src));
         }
     }
 
-    private StackSlot getTempSlot(LIRKind kind) {
+    private StackSlotValue getTempSlot(LIRKind kind) {
         if (tmpStackSlot == null) {
             tmpStackSlot = getResult().getFrameMapBuilder().allocateSpillSlot(kind);
         }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java	Wed Nov 19 16:06:49 2014 +0100
@@ -98,7 +98,7 @@
                     if (ValueUtil.isRegister(use)) {
                         regRegMoves++;
                     }
-                } else if (ValueUtil.isStackSlot(def)) {
+                } else if (ValueUtil.isStackSlotValue(def)) {
                     spillMoves++;
                 }
             }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Wed Nov 19 16:06:49 2014 +0100
@@ -44,6 +44,7 @@
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.constopt.*;
+import com.oracle.graal.lir.framemap.*;
 import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.cfg.*;
@@ -322,6 +323,7 @@
         }
         try (Scope ds = Debug.scope("BackEnd", lir)) {
             FrameMapBuilder frameMapBuilder = backend.newFrameMapBuilder(registerConfig);
+            frameMapBuilder.requireMapping(lir);
             LIRGenerationResult lirGenRes = backend.newLIRGenerationResult(lir, frameMapBuilder, graph.method(), stub);
             LIRGeneratorTool lirGen = backend.newLIRGenerator(cc, lirGenRes);
             NodeLIRBuilderTool nodeLirGen = backend.newNodeLIRBuilder(graph, lirGen);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/Interval.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/Interval.java	Wed Nov 19 16:06:49 2014 +0100
@@ -452,7 +452,7 @@
     /**
      * The stack slot to which all splits of this interval are spilled if necessary.
      */
-    private StackSlot spillSlot;
+    private StackSlotValue spillSlot;
 
     /**
      * The kind of this interval.
@@ -546,8 +546,8 @@
         } else if (isIllegal(newLocation)) {
             assert canMaterialize();
         } else {
-            assert this.location == null || isRegister(this.location) : "cannot re-assign location for " + this;
-            assert isStackSlot(newLocation);
+            assert this.location == null || isRegister(this.location) || (isVirtualStackSlot(this.location) && isStackSlot(newLocation)) : "cannot re-assign location for " + this;
+            assert isStackSlotValue(newLocation);
             assert !newLocation.getLIRKind().equals(LIRKind.Illegal);
             assert newLocation.getLIRKind().equals(this.kind);
         }
@@ -615,12 +615,12 @@
     /**
      * Gets the canonical spill slot for this interval.
      */
-    StackSlot spillSlot() {
+    StackSlotValue spillSlot() {
         return splitParent().spillSlot;
     }
 
-    void setSpillSlot(StackSlot slot) {
-        assert splitParent().spillSlot == null : "connot overwrite existing spill slot";
+    void setSpillSlot(StackSlotValue slot) {
+        assert splitParent().spillSlot == null || (isVirtualStackSlot(splitParent().spillSlot) && isStackSlot(slot)) : "connot overwrite existing spill slot";
         splitParent().spillSlot = slot;
     }
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Wed Nov 19 16:06:49 2014 +0100
@@ -45,6 +45,7 @@
 import com.oracle.graal.lir.LIRInstruction.OperandFlag;
 import com.oracle.graal.lir.LIRInstruction.OperandMode;
 import com.oracle.graal.lir.StandardOp.MoveOp;
+import com.oracle.graal.lir.framemap.*;
 import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.options.*;
@@ -260,7 +261,7 @@
         } else if (interval.spillSlot() != null) {
             interval.assignLocation(interval.spillSlot());
         } else {
-            StackSlot slot = frameMapBuilder.allocateSpillSlot(interval.kind());
+            VirtualStackSlot slot = frameMapBuilder.allocateSpillSlot(interval.kind());
             interval.setSpillSlot(slot);
             interval.assignLocation(slot);
         }
@@ -565,7 +566,7 @@
                                 AllocatableValue toLocation = canonicalSpillOpr(interval);
 
                                 assert isRegister(fromLocation) : "from operand must be a register but is: " + fromLocation + " toLocation=" + toLocation + " spillState=" + interval.spillState();
-                                assert isStackSlot(toLocation) : "to operand must be a stack slot";
+                                assert isStackSlotValue(toLocation) : "to operand must be a stack slot";
 
                                 insertionBuffer.append(j + 1, ir.getSpillMoveFactory().createMove(toLocation, fromLocation));
 
@@ -694,10 +695,12 @@
                     }
                 };
                 ValueConsumer stateConsumer = (operand, mode, flags) -> {
-                    int operandNum = operandNumber(operand);
-                    if (!liveKill.get(operandNum)) {
-                        liveGen.set(operandNum);
-                        Debug.log("liveGen in state for operand %d", operandNum);
+                    if (isVariableOrRegister(operand)) {
+                        int operandNum = operandNumber(operand);
+                        if (!liveKill.get(operandNum)) {
+                            liveGen.set(operandNum);
+                            Debug.log("liveGen in state for operand %d", operandNum);
+                        }
                     }
                 };
                 ValueConsumer defConsumer = (operand, mode, flags) -> {
@@ -1165,9 +1168,11 @@
             };
 
             InstructionValueConsumer stateProc = (op, operand, mode, flags) -> {
-                int opId = op.id();
-                int blockFrom = getFirstLirInstructionId((blockForId(opId)));
-                addUse((AllocatableValue) operand, blockFrom, opId + 1, RegisterPriority.None, operand.getLIRKind());
+                if (isVariableOrRegister(operand)) {
+                    int opId = op.id();
+                    int blockFrom = getFirstLirInstructionId((blockForId(opId)));
+                    addUse((AllocatableValue) operand, blockFrom, opId + 1, RegisterPriority.None, operand.getLIRKind());
+                }
             };
 
             // create a list with all caller-save registers (cpu, fpu, xmm)
@@ -1556,7 +1561,7 @@
     // * Phase 7: assign register numbers back to LIR
     // (includes computation of debug information and oop maps)
 
-    static StackSlot canonicalSpillOpr(Interval interval) {
+    static StackSlotValue canonicalSpillOpr(Interval interval) {
         assert interval.spillSlot() != null : "canonical spill slot not set";
         return interval.spillSlot();
     }
@@ -1728,7 +1733,7 @@
         // the intervals
         // if the interval is not live, colorLirOperand will cause an assert on failure
         Value result = colorLirOperand((Variable) operand, tempOpId, mode);
-        assert !hasCall(tempOpId) || isStackSlot(result) || isConstant(result) || !isCallerSave(result) : "cannot have caller-save register operands at calls";
+        assert !hasCall(tempOpId) || isStackSlotValue(result) || isConstant(result) || !isCallerSave(result) : "cannot have caller-save register operands at calls";
         return result;
     }
 
@@ -1804,6 +1809,31 @@
         }
     }
 
+    private class Mapper implements FrameMappable {
+
+        public void map(FrameMappingTool tool) {
+            try (Scope scope = Debug.scope("StackSlotMappingLSRA")) {
+                for (Interval current : intervals) {
+                    if (current != null) {
+                        if (isVirtualStackSlot(current.location())) {
+                            VirtualStackSlot value = asVirtualStackSlot(current.location());
+                            StackSlot stackSlot = tool.getStackSlot(value);
+                            Debug.log("map %s -> %s", value, stackSlot);
+                            current.assignLocation(stackSlot);
+                        }
+                        if (current.isSplitParent() && current.spillSlot() != null && isVirtualStackSlot(current.spillSlot())) {
+                            VirtualStackSlot value = asVirtualStackSlot(current.spillSlot());
+                            StackSlot stackSlot = tool.getStackSlot(value);
+                            Debug.log("map %s -> %s", value, stackSlot);
+                            current.setSpillSlot(stackSlot);
+                        }
+                    }
+                }
+            }
+        }
+
+    }
+
     public static void allocate(TargetDescription target, LIRGenerationResult res) {
         new LinearScan(target, res).allocate();
     }
@@ -1848,11 +1878,15 @@
             }
 
             try (Scope s = Debug.scope("DebugInfo")) {
+                printIntervals("After register allocation");
+                printLir("After register allocation", true);
+
+                // register interval mapper
+                frameMapBuilder.requireMapping(new Mapper());
                 // build frame map
                 res.buildFrameMap();
 
-                printIntervals("After register allocation");
-                printLir("After register allocation", true);
+                printLir("After FrameMap building", true);
 
                 sortIntervalsAfterAllocation();
 
@@ -1896,7 +1930,7 @@
                 Interval firstSpillChild = null;
                 try (Indent indent = Debug.logAndIndent("interval %s (%s)", interval, defBlock)) {
                     for (Interval splitChild : interval.getSplitChildren()) {
-                        if (isStackSlot(splitChild.location())) {
+                        if (isStackSlotValue(splitChild.location())) {
                             if (firstSpillChild == null || splitChild.from() < firstSpillChild.from()) {
                                 firstSpillChild = splitChild;
                             } else {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java	Wed Nov 19 16:06:49 2014 +0100
@@ -535,7 +535,7 @@
      * This is called for every interval that is assigned to a stack slot.
      */
     protected void handleSpillSlot(Interval interval) {
-        assert interval.location() != null && (interval.canMaterialize() || isStackSlot(interval.location())) : "interval not assigned to a stack slot " + interval;
+        assert interval.location() != null && (interval.canMaterialize() || isStackSlotValue(interval.location())) : "interval not assigned to a stack slot " + interval;
         // Do nothing. Stack slots are not processed in this implementation.
     }
 
@@ -853,7 +853,7 @@
         try (Indent indent = Debug.logAndIndent("activating interval %s,  splitParent: %d", interval, interval.splitParent().operandNumber)) {
 
             final Value operand = interval.operand;
-            if (interval.location() != null && isStackSlot(interval.location())) {
+            if (interval.location() != null && isStackSlotValue(interval.location())) {
                 // activating an interval that has a stack slot assigned . split it at first use
                 // position
                 // used for method parameters
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/MoveResolver.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/MoveResolver.java	Wed Nov 19 16:06:49 2014 +0100
@@ -278,7 +278,7 @@
                 // do not allocate a new spill slot for temporary interval, but
                 // use spill slot assigned to fromInterval. Otherwise moves from
                 // one stack slot to another can happen (not allowed by LIRAssembler
-                StackSlot spillSlot = fromInterval.spillSlot();
+                StackSlotValue spillSlot = fromInterval.spillSlot();
                 if (spillSlot == null) {
                     spillSlot = allocator.frameMapBuilder.allocateSpillSlot(spillInterval.kind());
                     fromInterval.setSpillSlot(spillSlot);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/OptimizingLinearScanWalker.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/OptimizingLinearScanWalker.java	Wed Nov 19 16:06:49 2014 +0100
@@ -53,10 +53,10 @@
     protected void handleSpillSlot(Interval interval) {
         assert interval.location() != null : "interval  not assigned " + interval;
         if (interval.canMaterialize()) {
-            assert !isStackSlot(interval.location()) : "interval can materialize but assigned to a stack slot " + interval;
+            assert !isStackSlotValue(interval.location()) : "interval can materialize but assigned to a stack slot " + interval;
             return;
         }
-        assert isStackSlot(interval.location()) : "interval not assigned to a stack slot " + interval;
+        assert isStackSlotValue(interval.location()) : "interval not assigned to a stack slot " + interval;
         try (Scope s1 = Debug.scope("LSRAOptimization")) {
             Debug.log("adding stack to unhandled list %s", interval);
             unhandledLists.addToListSortedByStartAndUsePositions(RegisterBinding.Stack, interval);
@@ -152,13 +152,13 @@
             return false;
         }
 
-        if (!isStackSlot(predecessorLocation) && !isRegister(predecessorLocation)) {
+        if (!isStackSlotValue(predecessorLocation) && !isRegister(predecessorLocation)) {
             assert predecessorInterval.canMaterialize();
             // value is materialized -> no need for optimization
             return false;
         }
 
-        assert isStackSlot(currentLocation) || isRegister(currentLocation) : "current location not a register or stack slot " + currentLocation;
+        assert isStackSlotValue(currentLocation) || isRegister(currentLocation) : "current location not a register or stack slot " + currentLocation;
 
         try (Indent indent = Debug.logAndIndent("location differs: %s vs. %s", predecessorLocation, currentLocation)) {
             // split current interval at current position
@@ -187,7 +187,7 @@
                 if (isRegister(predecessorLocation)) {
                     splitRegisterInterval(splitPart, asRegister(predecessorLocation));
                 } else {
-                    assert isStackSlot(predecessorLocation);
+                    assert isStackSlotValue(predecessorLocation);
                     Debug.log("assigning interval %s to %s", splitPart, predecessorLocation);
                     splitPart.assignLocation(predecessorLocation);
                     // activate interval
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java	Wed Nov 19 16:06:49 2014 +0100
@@ -30,6 +30,7 @@
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.framemap.*;
 import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -73,7 +74,7 @@
      */
     public abstract FrameMapBuilder newFrameMapBuilder(RegisterConfig registerConfig);
 
-    public abstract FrameMap newFrameMap(FrameMapBuilder frameMapBuilder);
+    public abstract FrameMap newFrameMap(RegisterConfig registerConfig);
 
     public abstract LIRGeneratorTool newLIRGenerator(CallingConvention cc, LIRGenerationResult lirGenRes);
 
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Wed Nov 19 16:06:49 2014 +0100
@@ -46,6 +46,7 @@
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.framemap.*;
 import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -67,12 +68,13 @@
 
     @Override
     public FrameMapBuilder newFrameMapBuilder(RegisterConfig registerConfig) {
-        return new FrameMapBuilderImpl(this::newFrameMap, getCodeCache(), registerConfig);
+        RegisterConfig registerConfigNonNull = registerConfig == null ? getCodeCache().getRegisterConfig() : registerConfig;
+        return new AMD64FrameMapBuilder(newFrameMap(registerConfigNonNull), getCodeCache(), registerConfigNonNull);
     }
 
     @Override
-    public FrameMap newFrameMap(FrameMapBuilder frameMapBuilder) {
-        return new AMD64FrameMap(getCodeCache(), frameMapBuilder.getRegisterConfig());
+    public FrameMap newFrameMap(RegisterConfig registerConfig) {
+        return new AMD64FrameMap(getCodeCache(), registerConfig);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEnterUnpackFramesStackFrameOp.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEnterUnpackFramesStackFrameOp.java	Wed Nov 19 16:06:49 2014 +0100
@@ -34,6 +34,7 @@
 import com.oracle.graal.lir.StandardOp.SaveRegistersOp;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.framemap.*;
 
 /**
  * Emits code that enters a stack frame which is tailored to call the C++ method
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerationResult.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerationResult.java	Wed Nov 19 16:06:49 2014 +0100
@@ -28,6 +28,7 @@
 import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.SaveRegistersOp;
+import com.oracle.graal.lir.framemap.*;
 import com.oracle.graal.lir.gen.*;
 
 public class AMD64HotSpotLIRGenerationResult extends LIRGenerationResultBase {
@@ -52,11 +53,14 @@
     }
 
     StackSlot getDeoptimizationRescueSlot() {
+        if (deoptimizationRescueSlot == null) {
+            return null;
+        }
         return deoptimizationRescueSlot;
     }
 
-    public final void setDeoptimizationRescueSlot(StackSlot deoptimizationRescueSlot) {
-        this.deoptimizationRescueSlot = deoptimizationRescueSlot;
+    public final void setDeoptimizationRescueSlot(StackSlot stackSlot) {
+        this.deoptimizationRescueSlot = stackSlot;
     }
 
     Stub getStub() {
@@ -66,5 +70,4 @@
     Map<LIRFrameState, SaveRegistersOp> getCalleeSaveInfo() {
         return calleeSaveInfo;
     }
-
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Wed Nov 19 16:06:49 2014 +0100
@@ -92,8 +92,8 @@
 
         public SaveRbp(NoOp placeholder) {
             this.placeholder = placeholder;
-            this.reservedSlot = getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(Kind.Long));
-            assert reservedSlot.getRawOffset() == -16 : reservedSlot.getRawOffset();
+            AMD64FrameMapBuilder frameMapBuilder = (AMD64FrameMapBuilder) getResult().getFrameMapBuilder();
+            this.reservedSlot = frameMapBuilder.allocateRBPSpillSlot();
         }
 
         /**
@@ -106,7 +106,7 @@
             if (useStack) {
                 dst = reservedSlot;
             } else {
-                getResult().getFrameMapBuilder().freeSpillSlot(reservedSlot);
+                ((AMD64FrameMapBuilder) getResult().getFrameMapBuilder()).freeRBPSpillSlot();
                 dst = newVariable(LIRKind.value(Kind.Long));
             }
 
@@ -131,7 +131,7 @@
     }
 
     @Override
-    public StackSlot getLockSlot(int lockDepth) {
+    public StackSlotValue getLockSlot(int lockDepth) {
         return getLockStack().makeLockSlot(lockDepth);
     }
 
@@ -218,7 +218,7 @@
      * @param savedRegisterLocations the slots to which the registers are saved
      * @param supportsRemove determines if registers can be pruned
      */
-    protected AMD64SaveRegistersOp emitSaveRegisters(Register[] savedRegisters, StackSlot[] savedRegisterLocations, boolean supportsRemove) {
+    protected AMD64SaveRegistersOp emitSaveRegisters(Register[] savedRegisters, StackSlotValue[] savedRegisterLocations, boolean supportsRemove) {
         AMD64SaveRegistersOp save = new AMD64SaveRegistersOp(savedRegisters, savedRegisterLocations, supportsRemove);
         append(save);
         return save;
@@ -231,11 +231,11 @@
      * @return the register save node
      */
     private AMD64SaveRegistersOp emitSaveAllRegisters(Register[] savedRegisters, boolean supportsRemove) {
-        StackSlot[] savedRegisterLocations = new StackSlot[savedRegisters.length];
+        StackSlotValue[] savedRegisterLocations = new StackSlotValue[savedRegisters.length];
         for (int i = 0; i < savedRegisters.length; i++) {
             PlatformKind kind = target().arch.getLargestStorableKind(savedRegisters[i].getRegisterCategory());
             assert kind != Kind.Illegal;
-            StackSlot spillSlot = getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(kind));
+            VirtualStackSlot spillSlot = getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(kind));
             savedRegisterLocations[i] = spillSlot;
         }
         return emitSaveRegisters(savedRegisters, savedRegisterLocations, supportsRemove);
@@ -417,7 +417,7 @@
         boolean hasDebugInfo = getResult().getLIR().hasDebugInfo();
         AllocatableValue savedRbp = saveRbp.finalize(hasDebugInfo);
         if (hasDebugInfo) {
-            ((AMD64HotSpotLIRGenerationResult) getResult()).setDeoptimizationRescueSlot(getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(Kind.Long)));
+            ((AMD64HotSpotLIRGenerationResult) getResult()).setDeoptimizationRescueSlot(((AMD64FrameMapBuilder) getResult().getFrameMapBuilder()).allocateDeoptimizationRescueSlot());
         }
 
         for (AMD64HotSpotEpilogueOp op : epilogueOps) {
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveCurrentStackFrameOp.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveCurrentStackFrameOp.java	Wed Nov 19 16:06:49 2014 +0100
@@ -30,6 +30,7 @@
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.SaveRegistersOp;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.framemap.*;
 
 /**
  * Pops the current frame off the stack including the return address and restores the return
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveUnpackFramesStackFrameOp.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveUnpackFramesStackFrameOp.java	Wed Nov 19 16:06:49 2014 +0100
@@ -30,6 +30,7 @@
 import com.oracle.graal.lir.StandardOp.SaveRegistersOp;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.framemap.*;
 
 /**
  * Emits code that leaves a stack frame which is tailored to call the C++ method
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java	Wed Nov 19 16:06:49 2014 +0100
@@ -65,6 +65,7 @@
 import com.oracle.graal.java.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.framemap.*;
 import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.lir.hsail.*;
 import com.oracle.graal.lir.hsail.HSAILControlFlow.DeoptimizingOp;
@@ -386,15 +387,16 @@
 
     @Override
     public FrameMapBuilder newFrameMapBuilder(RegisterConfig registerConfig) {
-        return new FrameMapBuilderImpl(this::newFrameMap, getCodeCache(), registerConfig);
+        RegisterConfig registerConfigNonNull = registerConfig == null ? getCodeCache().getRegisterConfig() : registerConfig;
+        return new FrameMapBuilderImpl(newFrameMap(registerConfigNonNull), getCodeCache(), registerConfigNonNull);
     }
 
     /**
      * Use the HSAIL register set when the compilation target is HSAIL.
      */
     @Override
-    public FrameMap newFrameMap(FrameMapBuilder frameMapBuilder) {
-        return new HSAILFrameMap(getCodeCache(), frameMapBuilder.getRegisterConfig());
+    public FrameMap newFrameMap(RegisterConfig registerConfig) {
+        return new HSAILFrameMap(getCodeCache(), registerConfig);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerationResult.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerationResult.java	Wed Nov 19 16:06:49 2014 +0100
@@ -25,6 +25,7 @@
 import java.util.*;
 
 import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.framemap.*;
 import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.lir.hsail.HSAILControlFlow.DeoptimizingOp;
 
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java	Wed Nov 19 16:06:49 2014 +0100
@@ -48,6 +48,7 @@
 import com.oracle.graal.lir.LIRInstruction.OperandMode;
 import com.oracle.graal.lir.StandardOp.LabelOp;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.framemap.*;
 import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.lir.ptx.PTXControlFlow.PTXPredicatedLIRInstruction;
 import com.oracle.graal.lir.ptx.*;
@@ -157,12 +158,13 @@
 
     @Override
     public FrameMapBuilder newFrameMapBuilder(RegisterConfig registerConfig) {
-        return new FrameMapBuilderImpl(this::newFrameMap, getCodeCache(), registerConfig);
+        RegisterConfig registerConfigNonNull = registerConfig == null ? getCodeCache().getRegisterConfig() : registerConfig;
+        return new FrameMapBuilderImpl(newFrameMap(registerConfigNonNull), getCodeCache(), registerConfigNonNull);
     }
 
     @Override
-    public FrameMap newFrameMap(FrameMapBuilder frameMapBuilder) {
-        return new PTXFrameMap(getCodeCache(), frameMapBuilder.getRegisterConfig());
+    public FrameMap newFrameMap(RegisterConfig registerConfig) {
+        return new PTXFrameMap(getCodeCache(), registerConfig);
     }
 
     /**
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Wed Nov 19 16:06:49 2014 +0100
@@ -51,6 +51,7 @@
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.SaveRegistersOp;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.framemap.*;
 import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.lir.sparc.*;
 import com.oracle.graal.nodes.*;
@@ -73,12 +74,13 @@
 
     @Override
     public FrameMapBuilder newFrameMapBuilder(RegisterConfig registerConfig) {
-        return new FrameMapBuilderImpl(this::newFrameMap, getCodeCache(), registerConfig);
+        RegisterConfig registerConfigNonNull = registerConfig == null ? getCodeCache().getRegisterConfig() : registerConfig;
+        return new FrameMapBuilderImpl(newFrameMap(registerConfigNonNull), getCodeCache(), registerConfigNonNull);
     }
 
     @Override
-    public FrameMap newFrameMap(FrameMapBuilder frameMapBuilder) {
-        return new SPARCFrameMap(getCodeCache(), frameMapBuilder.getRegisterConfig());
+    public FrameMap newFrameMap(RegisterConfig registerConfig) {
+        return new SPARCFrameMap(getCodeCache(), registerConfig);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerationResult.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerationResult.java	Wed Nov 19 16:06:49 2014 +0100
@@ -22,12 +22,15 @@
  */
 package com.oracle.graal.hotspot.sparc;
 
+import static com.oracle.graal.api.code.ValueUtil.*;
+
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.*;
+import com.oracle.graal.lir.framemap.*;
 import com.oracle.graal.lir.gen.*;
 
 public class SPARCHotSpotLIRGenerationResult extends LIRGenerationResultBase {
@@ -37,7 +40,7 @@
      * deoptimization. The return address slot in the callee is overwritten with the address of a
      * deoptimization stub.
      */
-    private StackSlot deoptimizationRescueSlot;
+    private VirtualStackSlot deoptimizationRescueSlot;
     private final Object stub;
 
     /**
@@ -52,11 +55,15 @@
     }
 
     StackSlot getDeoptimizationRescueSlot() {
-        return deoptimizationRescueSlot;
+        if (deoptimizationRescueSlot == null) {
+            return null;
+        }
+        assert isStackSlot(deoptimizationRescueSlot);
+        return asStackSlot(deoptimizationRescueSlot);
     }
 
-    public final void setDeoptimizationRescueSlot(StackSlot deoptimizationRescueSlot) {
-        this.deoptimizationRescueSlot = deoptimizationRescueSlot;
+    public final void setDeoptimizationRescueSlot(VirtualStackSlot stackSlot) {
+        this.deoptimizationRescueSlot = stackSlot;
     }
 
     Stub getStub() {
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Wed Nov 19 16:06:49 2014 +0100
@@ -73,7 +73,7 @@
     private StackSlot deoptimizationRescueSlot;
 
     @Override
-    public StackSlot getLockSlot(int lockDepth) {
+    public StackSlotValue getLockSlot(int lockDepth) {
         return getLockStack().makeLockSlot(lockDepth);
     }
 
@@ -254,7 +254,7 @@
      * @param savedRegisterLocations the slots to which the registers are saved
      * @param supportsRemove determines if registers can be pruned
      */
-    protected SPARCSaveRegistersOp emitSaveRegisters(Register[] savedRegisters, StackSlot[] savedRegisterLocations, boolean supportsRemove) {
+    protected SPARCSaveRegistersOp emitSaveRegisters(Register[] savedRegisters, StackSlotValue[] savedRegisterLocations, boolean supportsRemove) {
         SPARCSaveRegistersOp save = new SPARCSaveRegistersOp(savedRegisters, savedRegisterLocations, supportsRemove);
         append(save);
         return save;
@@ -277,11 +277,11 @@
                         d56,          d58,          d60,          d62
         };
         // @formatter:on
-        StackSlot[] savedRegisterLocations = new StackSlot[savedRegisters.length];
+        StackSlotValue[] savedRegisterLocations = new StackSlotValue[savedRegisters.length];
         for (int i = 0; i < savedRegisters.length; i++) {
             PlatformKind kind = target().arch.getLargestStorableKind(savedRegisters[i].getRegisterCategory());
             assert kind != Kind.Illegal;
-            StackSlot spillSlot = getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(kind));
+            VirtualStackSlot spillSlot = getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(kind));
             savedRegisterLocations[i] = spillSlot;
         }
         return emitSaveRegisters(savedRegisters, savedRegisterLocations, false);
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Wed Nov 19 16:06:49 2014 +0100
@@ -33,7 +33,7 @@
 import com.oracle.graal.asm.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.hotspot.*;
-import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.framemap.*;
 import com.oracle.graal.sparc.*;
 
 public class SPARCHotSpotRegisterConfig implements RegisterConfig {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java	Wed Nov 19 16:06:49 2014 +0100
@@ -40,6 +40,7 @@
 import com.oracle.graal.lir.LIRInstruction.OperandMode;
 import com.oracle.graal.lir.StandardOp.LabelOp;
 import com.oracle.graal.lir.StandardOp.SaveRegistersOp;
+import com.oracle.graal.lir.framemap.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.tiers.*;
 import com.oracle.graal.word.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java	Wed Nov 19 16:06:49 2014 +0100
@@ -52,7 +52,7 @@
         if (state.outerFrameState() != null) {
             lockDepth += state.outerFrameState().nestedLockDepth();
         }
-        StackSlot slot = lockStack.makeLockSlot(lockDepth);
+        StackSlotValue slot = lockStack.makeLockSlot(lockDepth);
         ValueNode lock = state.lockAt(lockIndex);
         JavaValue object = toValue(lock);
         boolean eliminated = object instanceof VirtualObject && state.monitorIdAt(lockIndex) != null;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRFrameState.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRFrameState.java	Wed Nov 19 16:06:49 2014 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.hotspot;
 
+import static com.oracle.graal.api.code.ValueUtil.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.hotspot.meta.*;
@@ -47,6 +49,10 @@
                     monitor.setOwner((JavaValue) proc.doValue(inst, owner, OperandMode.ALIVE, STATE_FLAGS));
                 }
             }
+            Value slot = monitor.getSlot();
+            if (isVirtualStackSlot(slot) && processed(slot)) {
+                monitor.setSlot(asStackSlotValue(proc.doValue(inst, slot, OperandMode.ALIVE, STATE_FLAGS)));
+            }
             return value;
         } else {
             return super.processValue(inst, proc, value);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerator.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerator.java	Wed Nov 19 16:06:49 2014 +0100
@@ -130,7 +130,7 @@
     /**
      * Gets a stack slot for a lock at a given lock nesting depth.
      */
-    StackSlot getLockSlot(int lockDepth);
+    StackSlotValue getLockSlot(int lockDepth);
 
     HotSpotProviders getProviders();
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLockStack.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLockStack.java	Wed Nov 19 16:06:49 2014 +0100
@@ -26,7 +26,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.framemap.*;
 
 /**
  * Manages allocation and re-use of lock slots in a scoped manner. The slots are used in HotSpot's
@@ -34,7 +34,7 @@
  */
 public class HotSpotLockStack {
 
-    private StackSlot[] locks;
+    private StackSlotValue[] locks;
     private final FrameMapBuilder frameMapBuilder;
     private final LIRKind slotKind;
 
@@ -46,9 +46,9 @@
     /**
      * Gets a stack slot for a lock at a given lock nesting depth, allocating it first if necessary.
      */
-    public StackSlot makeLockSlot(int lockDepth) {
+    public StackSlotValue makeLockSlot(int lockDepth) {
         if (locks == null) {
-            locks = new StackSlot[lockDepth + 1];
+            locks = new StackSlotValue[lockDepth + 1];
         } else if (locks.length < lockDepth + 1) {
             locks = Arrays.copyOf(locks, lockDepth + 1);
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMonitorValue.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMonitorValue.java	Wed Nov 19 16:06:49 2014 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.hotspot.meta;
 
+import static com.oracle.graal.api.code.ValueUtil.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 
@@ -33,10 +35,10 @@
     private static final long serialVersionUID = 8241681800464483691L;
 
     private JavaValue owner;
-    private final StackSlot slot;
+    private StackSlotValue slot;
     private final boolean eliminated;
 
-    public HotSpotMonitorValue(JavaValue owner, StackSlot slot, boolean eliminated) {
+    public HotSpotMonitorValue(JavaValue owner, StackSlotValue slot, boolean eliminated) {
         super(LIRKind.Illegal);
         this.owner = owner;
         this.slot = slot;
@@ -82,4 +84,9 @@
         }
         return false;
     }
+
+    public void setSlot(StackSlotValue stackSlot) {
+        assert slot == null || (isVirtualStackSlot(slot) && (slot.equals(stackSlot) || isStackSlot(stackSlot))) : String.format("Can not set slot for %s to %s", this, stackSlot);
+        slot = stackSlot;
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/AllocaNode.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/AllocaNode.java	Wed Nov 19 16:06:49 2014 +0100
@@ -63,7 +63,7 @@
 
     @Override
     public void generate(NodeLIRBuilderTool gen) {
-        StackSlot array = gen.getLIRGeneratorTool().getResult().getFrameMapBuilder().allocateStackSlots(slots, objects, null);
+        VirtualStackSlot array = gen.getLIRGeneratorTool().getResult().getFrameMapBuilder().allocateStackSlots(slots, objects, null);
         Value result = gen.getLIRGeneratorTool().emitAddress(array);
         gen.setResult(this, result);
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java	Wed Nov 19 16:06:49 2014 +0100
@@ -65,7 +65,7 @@
     public void generate(NodeLIRBuilderTool gen) {
         assert lockDepth != -1;
         HotSpotLIRGenerator hsGen = (HotSpotLIRGenerator) gen.getLIRGeneratorTool();
-        StackSlot slot = hsGen.getLockSlot(lockDepth);
+        StackSlotValue slot = hsGen.getLockSlot(lockDepth);
         Value result = gen.getLIRGeneratorTool().emitAddress(slot);
         gen.setResult(this, result);
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentLockNode.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentLockNode.java	Wed Nov 19 16:06:49 2014 +0100
@@ -51,7 +51,7 @@
     public void generate(NodeLIRBuilderTool gen) {
         assert lockDepth != -1;
         HotSpotLIRGenerator hsGen = (HotSpotLIRGenerator) gen.getLIRGeneratorTool();
-        StackSlot slot = hsGen.getLockSlot(lockDepth);
+        StackSlotValue slot = hsGen.getLockSlot(lockDepth);
         // The register allocator cannot handle stack -> register moves so we use an LEA here
         Value result = gen.getLIRGeneratorTool().emitMove(gen.getLIRGeneratorTool().emitAddress(slot));
         gen.setResult(this, result);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DimensionsNode.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DimensionsNode.java	Wed Nov 19 16:06:49 2014 +0100
@@ -58,7 +58,7 @@
         int size = rank * 4;
         int wordSize = lirGen.target().wordSize;
         int slots = roundUp(size, wordSize) / wordSize;
-        StackSlot array = lirGen.getResult().getFrameMapBuilder().allocateStackSlots(slots, new BitSet(0), null);
+        VirtualStackSlot array = lirGen.getResult().getFrameMapBuilder().allocateStackSlots(slots, new BitSet(0), null);
         Value result = lirGen.emitAddress(array);
         gen.setResult(this, result);
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorCounterNode.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorCounterNode.java	Wed Nov 19 16:06:49 2014 +0100
@@ -48,7 +48,7 @@
     @Override
     public void generate(NodeLIRBuilderTool gen) {
         assert graph().getNodes().filter(MonitorCounterNode.class).count() == 1 : "monitor counters not canonicalized to single instance";
-        StackSlot counter = gen.getLIRGeneratorTool().getResult().getFrameMapBuilder().allocateStackSlots(1, new BitSet(0), null);
+        VirtualStackSlot counter = gen.getLIRGeneratorTool().getResult().getFrameMapBuilder().allocateStackSlots(1, new BitSet(0), null);
         Value result = gen.getLIRGeneratorTool().emitAddress(counter);
         gen.setResult(this, result);
     }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64FrameMap.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64FrameMap.java	Wed Nov 19 16:06:49 2014 +0100
@@ -22,10 +22,12 @@
  */
 package com.oracle.graal.lir.amd64;
 
+import static com.oracle.graal.api.code.ValueUtil.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
-import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.framemap.*;
 
 /**
  * AMD64 specific frame map.
@@ -70,6 +72,8 @@
  */
 public class AMD64FrameMap extends FrameMap {
 
+    private StackSlot rbpSpillSlot;
+
     public AMD64FrameMap(CodeCacheProvider codeCache, RegisterConfig registerConfig) {
         super(codeCache, registerConfig);
         // (negative) offset relative to sp + total frame size
@@ -101,4 +105,26 @@
     protected StackSlot allocateNewSpillSlot(LIRKind kind, int additionalOffset) {
         return StackSlot.get(kind, -spillSize + additionalOffset, true);
     }
+
+    /**
+     * For non-leaf methods, RBP is preserved in the special stack slot required by the HotSpot
+     * runtime for walking/inspecting frames of such methods.
+     */
+    StackSlot allocateRBPSpillSlot() {
+        assert spillSize == initialSpillSize : "RBP spill slot must be the first allocated stack slots";
+        rbpSpillSlot = allocateSpillSlot(LIRKind.value(Kind.Long));
+        assert asStackSlot(rbpSpillSlot).getRawOffset() == -16 : asStackSlot(rbpSpillSlot).getRawOffset();
+        return rbpSpillSlot;
+    }
+
+    void freeRBPSpillSlot() {
+        int size = spillSlotSize(LIRKind.value(Kind.Long));
+        assert spillSize == NumUtil.roundUp(initialSpillSize + size, size) : "RBP spill slot can not be freed after allocation other stack slots";
+        spillSize = initialSpillSize;
+    }
+
+    public StackSlot allocateDeoptimizationRescueSlot() {
+        assert spillSize == initialSpillSize || spillSize == initialSpillSize + spillSlotSize(LIRKind.value(Kind.Long)) : "Deoptimization rescue slot must be the first or second (if there is an RBP spill slot) stack slot";
+        return allocateSpillSlot(LIRKind.value(Kind.Long));
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64FrameMapBuilder.java	Wed Nov 19 16:06:49 2014 +0100
@@ -0,0 +1,49 @@
+/*
+ * 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.lir.amd64;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.lir.framemap.*;
+
+public class AMD64FrameMapBuilder extends FrameMapBuilderImpl {
+
+    public AMD64FrameMapBuilder(FrameMap frameMap, CodeCacheProvider codeCache, RegisterConfig registerConfig) {
+        super(frameMap, codeCache, registerConfig);
+    }
+
+    /**
+     * For non-leaf methods, RBP is preserved in the special stack slot required by the HotSpot
+     * runtime for walking/inspecting frames of such methods.
+     */
+    public StackSlot allocateRBPSpillSlot() {
+        return ((AMD64FrameMap) frameMap).allocateRBPSpillSlot();
+    }
+
+    public void freeRBPSpillSlot() {
+        ((AMD64FrameMap) frameMap).freeRBPSpillSlot();
+    }
+
+    public StackSlot allocateDeoptimizationRescueSlot() {
+        return ((AMD64FrameMap) frameMap).allocateDeoptimizationRescueSlot();
+    }
+}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Wed Nov 19 16:06:49 2014 +0100
@@ -339,9 +339,10 @@
     public static class StackLeaOp extends AMD64LIRInstruction {
 
         @Def({REG}) protected AllocatableValue result;
-        @Use({STACK, UNINITIALIZED}) protected StackSlot slot;
+        @Use({STACK, UNINITIALIZED}) protected StackSlotValue slot;
 
-        public StackLeaOp(AllocatableValue result, StackSlot slot) {
+        public StackLeaOp(AllocatableValue result, StackSlotValue slot) {
+            assert isStackSlotValue(slot) : "Not a stack slot: " + slot;
             this.result = result;
             this.slot = slot;
         }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64RestoreRegistersOp.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64RestoreRegistersOp.java	Wed Nov 19 16:06:49 2014 +0100
@@ -22,8 +22,11 @@
  */
 package com.oracle.graal.lir.amd64;
 
+import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 
+import java.util.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.lir.*;
@@ -38,15 +41,16 @@
     /**
      * The slots from which the registers are restored.
      */
-    @Use(STACK) protected final StackSlot[] slots;
+    @Use(STACK) protected final StackSlotValue[] slots;
 
     /**
      * The operation that saved the registers restored by this operation.
      */
     private final AMD64SaveRegistersOp save;
 
-    public AMD64RestoreRegistersOp(StackSlot[] source, AMD64SaveRegistersOp save) {
-        this.slots = source;
+    public AMD64RestoreRegistersOp(StackSlotValue[] values, AMD64SaveRegistersOp save) {
+        assert Arrays.asList(values).stream().allMatch(ValueUtil::isVirtualStackSlot);
+        this.slots = values;
         this.save = save;
     }
 
@@ -64,7 +68,8 @@
         Register[] savedRegisters = getSavedRegisters();
         for (int i = 0; i < savedRegisters.length; i++) {
             if (savedRegisters[i] != null) {
-                restoreRegister(crb, masm, savedRegisters[i], slots[i]);
+                assert isStackSlot(slots[i]) : "not a StackSlot: " + slots[i];
+                restoreRegister(crb, masm, savedRegisters[i], asStackSlot(slots[i]));
             }
         }
     }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64SaveRegistersOp.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64SaveRegistersOp.java	Wed Nov 19 16:06:49 2014 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.lir.amd64;
 
+import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 
 import java.util.*;
@@ -31,6 +32,7 @@
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.SaveRegistersOp;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.framemap.*;
 
 /**
  * Saves registers to stack slots.
@@ -46,7 +48,7 @@
     /**
      * The slots to which the registers are saved.
      */
-    @Def(STACK) protected final StackSlot[] slots;
+    @Def(STACK) protected final StackSlotValue[] slots;
 
     /**
      * Specifies if {@link #remove(Set)} should have an effect.
@@ -57,12 +59,13 @@
      *
      * @param savedRegisters the registers saved by this operation which may be subject to
      *            {@linkplain #remove(Set) pruning}
-     * @param slots the slots to which the registers are saved
+     * @param savedRegisterLocations the slots to which the registers are saved
      * @param supportsRemove determines if registers can be {@linkplain #remove(Set) pruned}
      */
-    public AMD64SaveRegistersOp(Register[] savedRegisters, StackSlot[] slots, boolean supportsRemove) {
+    public AMD64SaveRegistersOp(Register[] savedRegisters, StackSlotValue[] savedRegisterLocations, boolean supportsRemove) {
+        assert Arrays.asList(savedRegisterLocations).stream().allMatch(ValueUtil::isVirtualStackSlot);
         this.savedRegisters = savedRegisters;
-        this.slots = slots;
+        this.slots = savedRegisterLocations;
         this.supportsRemove = supportsRemove;
     }
 
@@ -75,12 +78,13 @@
     public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
         for (int i = 0; i < savedRegisters.length; i++) {
             if (savedRegisters[i] != null) {
-                saveRegister(crb, masm, slots[i], savedRegisters[i]);
+                assert isStackSlot(slots[i]) : "not a StackSlot: " + slots[i];
+                saveRegister(crb, masm, asStackSlot(slots[i]), savedRegisters[i]);
             }
         }
     }
 
-    public StackSlot[] getSlots() {
+    public StackSlotValue[] getSlots() {
         return slots;
     }
 
@@ -122,7 +126,8 @@
             for (int i = 0; i < savedRegisters.length; i++) {
                 if (savedRegisters[i] != null) {
                     keys[mapIndex] = savedRegisters[i];
-                    StackSlot slot = slots[i];
+                    assert isStackSlot(slots[i]) : "not a StackSlot: " + slots[i];
+                    StackSlot slot = asStackSlot(slots[i]);
                     values[mapIndex] = indexForStackSlot(frameMap, slot);
                     mapIndex++;
                 }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ZapRegistersOp.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ZapRegistersOp.java	Wed Nov 19 16:06:49 2014 +0100
@@ -33,6 +33,7 @@
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.SaveRegistersOp;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.framemap.*;
 
 /**
  * Writes well known garbage values to registers.
--- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILAddressValue.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILAddressValue.java	Wed Nov 19 16:06:49 2014 +0100
@@ -62,7 +62,7 @@
         super(kind);
         this.base = base;
         this.displacement = displacement;
-        assert !isStackSlot(base);
+        assert !isStackSlotValue(base);
     }
 
     public HSAILAddress toAddress() {
--- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILFrameMap.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILFrameMap.java	Wed Nov 19 16:06:49 2014 +0100
@@ -24,7 +24,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.framemap.*;
 
 /**
  * HSAIL specific frame map.
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXAddressValue.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXAddressValue.java	Wed Nov 19 16:06:49 2014 +0100
@@ -64,7 +64,7 @@
         this.base = base;
         this.displacement = displacement;
 
-        assert !isStackSlot(base);
+        assert !isStackSlotValue(base);
     }
 
     public PTXAddress toAddress() {
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXFrameMap.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXFrameMap.java	Wed Nov 19 16:06:49 2014 +0100
@@ -24,7 +24,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.framemap.*;
 
 /**
  * PTX specific frame map.
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java	Wed Nov 19 16:06:49 2014 +0100
@@ -40,7 +40,7 @@
     @Def({REG, HINT}) protected Value result;
     @Use({REG}) protected Value input;
     @Temp({REG}) protected Value tempIndex;
-    @Use({STACK}) protected StackSlot tmpSlot;
+    @Use({STACK}) protected StackSlotValue tmpSlot;
 
     public SPARCByteSwapOp(LIRGeneratorTool tool, Value result, Value input) {
         this.result = result;
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCFrameMap.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCFrameMap.java	Wed Nov 19 16:06:49 2014 +0100
@@ -25,7 +25,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
-import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.framemap.*;
 import com.oracle.graal.sparc.*;
 
 /**
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Wed Nov 19 16:06:49 2014 +0100
@@ -134,9 +134,9 @@
 
         @Def({REG}) protected AllocatableValue result;
         @Use({REG}) protected AllocatableValue input;
-        @Use({STACK}) protected StackSlot temp;
+        @Use({STACK}) protected StackSlotValue temp;
 
-        public MoveFpGp(AllocatableValue result, AllocatableValue input, StackSlot temp) {
+        public MoveFpGp(AllocatableValue result, AllocatableValue input, StackSlotValue temp) {
             super();
             this.result = result;
             this.input = input;
@@ -456,11 +456,11 @@
     public static class StackLoadAddressOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction {
 
         @Def({REG}) protected AllocatableValue result;
-        @Use({STACK, UNINITIALIZED}) protected StackSlot slot;
+        @Use({STACK, UNINITIALIZED}) protected StackSlotValue slot;
 
-        public StackLoadAddressOp(AllocatableValue result, StackSlot slot) {
+        public StackLoadAddressOp(AllocatableValue result, StackSlotValue address) {
             this.result = result;
-            this.slot = slot;
+            this.slot = address;
         }
 
         @Override
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCSaveRegistersOp.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCSaveRegistersOp.java	Wed Nov 19 16:06:49 2014 +0100
@@ -22,16 +22,19 @@
  */
 package com.oracle.graal.lir.sparc;
 
+import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.asm.sparc.SPARCAssembler.*;
 import com.oracle.graal.asm.sparc.*;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Lddf;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Stx;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.SaveRegistersOp;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.framemap.*;
 import com.oracle.graal.sparc.*;
 
 /**
@@ -48,7 +51,7 @@
     /**
      * The slots to which the registers are saved.
      */
-    @Def(STACK) protected final StackSlot[] slots;
+    @Def(STACK) protected final StackSlotValue[] slots;
 
     /**
      * Specifies if {@link #remove(Set)} should have an effect.
@@ -59,12 +62,13 @@
      *
      * @param savedRegisters the registers saved by this operation which may be subject to
      *            {@linkplain #remove(Set) pruning}
-     * @param slots the slots to which the registers are saved
+     * @param savedRegisterLocations the slots to which the registers are saved
      * @param supportsRemove determines if registers can be {@linkplain #remove(Set) pruned}
      */
-    public SPARCSaveRegistersOp(Register[] savedRegisters, StackSlot[] slots, boolean supportsRemove) {
+    public SPARCSaveRegistersOp(Register[] savedRegisters, StackSlotValue[] savedRegisterLocations, boolean supportsRemove) {
+        assert Arrays.asList(savedRegisterLocations).stream().allMatch(ValueUtil::isVirtualStackSlot);
         this.savedRegisters = savedRegisters;
-        this.slots = slots;
+        this.slots = savedRegisterLocations;
         this.supportsRemove = supportsRemove;
     }
 
@@ -86,12 +90,13 @@
         // Now save the registers
         for (int i = 0; i < savedRegisters.length; i++) {
             if (savedRegisters[i] != null) {
-                saveRegister(crb, masm, slots[i], savedRegisters[i]);
+                assert isStackSlot(slots[i]) : "not a StackSlot: " + slots[i];
+                saveRegister(crb, masm, asStackSlot(slots[i]), savedRegisters[i]);
             }
         }
     }
 
-    public StackSlot[] getSlots() {
+    public StackSlotValue[] getSlots() {
         return slots;
     }
 
@@ -133,7 +138,8 @@
             for (int i = 0; i < savedRegisters.length; i++) {
                 if (savedRegisters[i] != null) {
                     keys[mapIndex] = savedRegisters[i];
-                    StackSlot slot = slots[i];
+                    assert isStackSlot(slots[i]) : "not a StackSlot: " + slots[i];
+                    StackSlot slot = asStackSlot(slots[i]);
                     values[mapIndex] = indexForStackSlot(frameMap, slot);
                     mapIndex++;
                 }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java	Wed Nov 19 13:43:12 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,381 +0,0 @@
-/*
- * Copyright (c) 2009, 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.lir;
-
-import static com.oracle.graal.api.code.ValueUtil.*;
-
-import java.util.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.*;
-
-/**
- * This class is used to build the stack frame layout for a compiled method. A {@link StackSlot} is
- * used to index slots of the frame relative to the stack pointer. The frame size is only fixed
- * after register allocation when all spill slots have been allocated. Both the outgoing argument
- * area and the spill are can grow until then. Therefore, outgoing arguments are indexed from the
- * stack pointer, while spill slots are indexed from the beginning of the frame (and the total frame
- * size has to be added to get the actual offset from the stack pointer).
- */
-public abstract class FrameMap {
-
-    private final TargetDescription target;
-    private final RegisterConfig registerConfig;
-
-    /**
-     * The final frame size, not including the size of the
-     * {@link Architecture#getReturnAddressSize() return address slot}. The value is only set after
-     * register allocation is complete, i.e., after all spill slots have been allocated.
-     */
-    private int frameSize;
-
-    /**
-     * Initial size of the area occupied by spill slots and other stack-allocated memory blocks.
-     */
-    protected int initialSpillSize;
-
-    /**
-     * Size of the area occupied by spill slots and other stack-allocated memory blocks.
-     */
-    protected int spillSize;
-
-    /**
-     * Size of the area occupied by outgoing overflow arguments. This value is adjusted as calling
-     * conventions for outgoing calls are retrieved. On some platforms, there is a minimum outgoing
-     * size even if no overflow arguments are on the stack.
-     */
-    protected int outgoingSize;
-
-    /**
-     * Determines if this frame has values on the stack for outgoing calls.
-     */
-    private boolean hasOutgoingStackArguments;
-
-    /**
-     * The list of stack slots allocated in this frame that are present in every reference map.
-     */
-    private final List<StackSlot> objectStackSlots;
-
-    /**
-     * Records whether an offset to an incoming stack argument was ever returned by
-     * {@link #offsetForStackSlot(StackSlot)}.
-     */
-    private boolean accessesCallerFrame;
-
-    /**
-     * Creates a new frame map for the specified method. The given registerConfig is optional, in
-     * case null is passed the default RegisterConfig from the CodeCacheProvider will be used.
-     */
-    public FrameMap(CodeCacheProvider codeCache, RegisterConfig registerConfig) {
-        this.target = codeCache.getTarget();
-        this.registerConfig = registerConfig == null ? codeCache.getRegisterConfig() : registerConfig;
-        this.frameSize = -1;
-        this.outgoingSize = codeCache.getMinimumOutgoingSize();
-        this.objectStackSlots = new ArrayList<>();
-    }
-
-    public RegisterConfig getRegisterConfig() {
-        return registerConfig;
-    }
-
-    public TargetDescription getTarget() {
-        return target;
-    }
-
-    protected int returnAddressSize() {
-        return getTarget().arch.getReturnAddressSize();
-    }
-
-    protected int calleeSaveAreaSize() {
-        CalleeSaveLayout csl = getRegisterConfig().getCalleeSaveLayout();
-        return csl != null ? csl.size : 0;
-    }
-
-    /**
-     * Determines if an offset to an incoming stack argument was ever returned by
-     * {@link #offsetForStackSlot(StackSlot)}.
-     */
-    public boolean accessesCallerFrame() {
-        return accessesCallerFrame;
-    }
-
-    /**
-     * Gets the frame size of the compiled frame, not including the size of the
-     * {@link Architecture#getReturnAddressSize() return address slot}.
-     *
-     * @return The size of the frame (in bytes).
-     */
-    public int frameSize() {
-        assert frameSize != -1 : "frame size not computed yet";
-        return frameSize;
-    }
-
-    public int outgoingSize() {
-        return outgoingSize;
-    }
-
-    /**
-     * Determines if any space is used in the frame apart from the
-     * {@link Architecture#getReturnAddressSize() return address slot}.
-     */
-    public boolean frameNeedsAllocating() {
-        int unalignedFrameSize = spillSize - returnAddressSize();
-        return hasOutgoingStackArguments || unalignedFrameSize != 0;
-    }
-
-    /**
-     * Gets the total frame size of the compiled frame, including the size of the
-     * {@link Architecture#getReturnAddressSize() return address slot}.
-     *
-     * @return The total size of the frame (in bytes).
-     */
-    public abstract int totalFrameSize();
-
-    /**
-     * Gets the current size of this frame. This is the size that would be returned by
-     * {@link #frameSize()} if {@link #finish()} were called now.
-     */
-    public abstract int currentFrameSize();
-
-    /**
-     * Aligns the given frame size to the stack alignment size and return the aligned size.
-     *
-     * @param size the initial frame size to be aligned
-     * @return the aligned frame size
-     */
-    protected abstract int alignFrameSize(int size);
-
-    /**
-     * Computes the final size of this frame. After this method has been called, methods that change
-     * the frame size cannot be called anymore, e.g., no more spill slots or outgoing arguments can
-     * be requested.
-     */
-    public void finish() {
-        assert this.frameSize == -1 : "must only be set once";
-        if (freedSlots != null) {
-            // If the freed slots cover the complete spill area (except for the return
-            // address slot), then the spill size is reset to its initial value.
-            // Without this, frameNeedsAllocating() would never return true.
-            int total = 0;
-            for (StackSlot s : freedSlots) {
-                total += getTarget().getSizeInBytes(s.getKind());
-            }
-            if (total == spillSize - initialSpillSize) {
-                // reset spill area size
-                spillSize = initialSpillSize;
-            }
-            freedSlots = null;
-        }
-        frameSize = currentFrameSize();
-        if (frameSize > getRegisterConfig().getMaximumFrameSize()) {
-            throw new BailoutException("Frame size (%d) exceeded maximum allowed frame size (%d).", frameSize, getRegisterConfig().getMaximumFrameSize());
-        }
-    }
-
-    /**
-     * Computes the offset of a stack slot relative to the frame register.
-     *
-     * @param slot a stack slot
-     * @return the offset of the stack slot
-     */
-    public int offsetForStackSlot(StackSlot slot) {
-        // @formatter:off
-        assert (!slot.getRawAddFrameSize() && slot.getRawOffset() <  outgoingSize) ||
-               (slot.getRawAddFrameSize() && slot.getRawOffset()  <  0 && -slot.getRawOffset() <= spillSize) ||
-               (slot.getRawAddFrameSize() && slot.getRawOffset()  >= 0) :
-                   String.format("RawAddFrameSize: %b RawOffset: 0x%x spillSize: 0x%x outgoingSize: 0x%x", slot.getRawAddFrameSize(), slot.getRawOffset(), spillSize, outgoingSize);
-        // @formatter:on
-        if (slot.isInCallerFrame()) {
-            accessesCallerFrame = true;
-        }
-        return slot.getOffset(totalFrameSize());
-    }
-
-    /**
-     * Gets the offset from the stack pointer to the stack area where callee-saved registers are
-     * stored.
-     *
-     * @return The offset to the callee save area (in bytes).
-     */
-    public abstract int offsetToCalleeSaveArea();
-
-    /**
-     * Informs the frame map that the compiled code calls a particular method, which may need stack
-     * space for outgoing arguments.
-     *
-     * @param cc The calling convention for the called method.
-     */
-    public void callsMethod(CallingConvention cc) {
-        reserveOutgoing(cc.getStackSize());
-    }
-
-    /**
-     * Reserves space for stack-based outgoing arguments.
-     *
-     * @param argsSize The amount of space (in bytes) to reserve for stack-based outgoing arguments.
-     */
-    public void reserveOutgoing(int argsSize) {
-        assert frameSize == -1 : "frame size must not yet be fixed";
-        outgoingSize = Math.max(outgoingSize, argsSize);
-        hasOutgoingStackArguments = hasOutgoingStackArguments || argsSize > 0;
-    }
-
-    /**
-     * Reserves a new spill slot in the frame of the method being compiled. The returned slot is
-     * aligned on its natural alignment, i.e., an 8-byte spill slot is aligned at an 8-byte
-     * boundary.
-     *
-     * @param kind The kind of the spill slot to be reserved.
-     * @param additionalOffset
-     * @return A spill slot denoting the reserved memory area.
-     */
-    protected abstract StackSlot allocateNewSpillSlot(LIRKind kind, int additionalOffset);
-
-    /**
-     * Returns the spill slot size for the given {@link LIRKind}. The default value is the size in
-     * bytes for the target architecture.
-     *
-     * @param kind the {@link LIRKind} to be stored in the spill slot.
-     * @return the size in bytes
-     */
-    public int spillSlotSize(LIRKind kind) {
-        return getTarget().getSizeInBytes(kind.getPlatformKind());
-    }
-
-    /**
-     * Reserves a spill slot in the frame of the method being compiled. The returned slot is aligned
-     * on its natural alignment, i.e., an 8-byte spill slot is aligned at an 8-byte boundary, unless
-     * overridden by a subclass.
-     *
-     * @param kind The kind of the spill slot to be reserved.
-     * @return A spill slot denoting the reserved memory area.
-     */
-    public StackSlot allocateSpillSlot(LIRKind kind) {
-        assert frameSize == -1 : "frame size must not yet be fixed";
-        if (freedSlots != null) {
-            for (Iterator<StackSlot> iter = freedSlots.iterator(); iter.hasNext();) {
-                StackSlot s = iter.next();
-                if (s.getLIRKind().equals(kind)) {
-                    iter.remove();
-                    if (freedSlots.isEmpty()) {
-                        freedSlots = null;
-                    }
-                    return s;
-                }
-            }
-        }
-        int size = spillSlotSize(kind);
-        spillSize = NumUtil.roundUp(spillSize + size, size);
-        return allocateNewSpillSlot(kind, 0);
-    }
-
-    private Set<StackSlot> freedSlots;
-
-    /**
-     * Frees a spill slot that was obtained via {@link #allocateSpillSlot(LIRKind)} such that it can
-     * be reused for the next allocation request for the same kind of slot.
-     */
-    public void freeSpillSlot(StackSlot slot) {
-        if (freedSlots == null) {
-            freedSlots = new HashSet<>();
-        }
-        freedSlots.add(slot);
-    }
-
-    /**
-     * Reserves a number of contiguous slots in the frame of the method being compiled. If the
-     * requested number of slots is 0, this method returns {@code null}.
-     *
-     * @param slots the number of slots to reserve
-     * @param objects specifies the indexes of the object pointer slots. The caller is responsible
-     *            for guaranteeing that each such object pointer slot is initialized before any
-     *            instruction that uses a reference map. Without this guarantee, the garbage
-     *            collector could see garbage object values.
-     * @param outObjectStackSlots if non-null, the object pointer slots allocated are added to this
-     *            list
-     * @return the first reserved stack slot (i.e., at the lowest address)
-     */
-    public StackSlot allocateStackSlots(int slots, BitSet objects, List<StackSlot> outObjectStackSlots) {
-        assert frameSize == -1 : "frame size must not yet be fixed";
-        if (slots == 0) {
-            return null;
-        }
-        spillSize += (slots * getTarget().wordSize);
-
-        if (!objects.isEmpty()) {
-            assert objects.length() <= slots;
-            StackSlot result = null;
-            for (int slotIndex = 0; slotIndex < slots; slotIndex++) {
-                StackSlot objectSlot = null;
-                if (objects.get(slotIndex)) {
-                    objectSlot = allocateNewSpillSlot(LIRKind.reference(Kind.Object), slotIndex * getTarget().wordSize);
-                    objectStackSlots.add(objectSlot);
-                    if (outObjectStackSlots != null) {
-                        outObjectStackSlots.add(objectSlot);
-                    }
-                }
-                if (slotIndex == 0) {
-                    if (objectSlot != null) {
-                        result = objectSlot;
-                    } else {
-                        result = allocateNewSpillSlot(LIRKind.value(getTarget().wordKind), 0);
-                    }
-                }
-            }
-            assert result != null;
-            return result;
-
-        } else {
-            return allocateNewSpillSlot(LIRKind.value(getTarget().wordKind), 0);
-        }
-    }
-
-    public ReferenceMap initReferenceMap(boolean hasRegisters) {
-        ReferenceMap refMap = getTarget().createReferenceMap(hasRegisters, frameSize() / getTarget().wordSize);
-        for (StackSlot slot : objectStackSlots) {
-            setReference(slot, refMap);
-        }
-        return refMap;
-    }
-
-    /**
-     * Marks the specified location as a reference in the reference map of the debug information.
-     * The tracked location can be a {@link RegisterValue} or a {@link StackSlot}. Note that a
-     * {@link JavaConstant} is automatically tracked.
-     *
-     * @param location The location to be added to the reference map.
-     * @param refMap A reference map, as created by {@link #initReferenceMap(boolean)}.
-     */
-    public void setReference(Value location, ReferenceMap refMap) {
-        LIRKind kind = location.getLIRKind();
-        if (isRegister(location)) {
-            refMap.setRegister(asRegister(location).getReferenceMapIndex(), kind);
-        } else if (isStackSlot(location)) {
-            int offset = offsetForStackSlot(asStackSlot(location));
-            refMap.setStackSlot(offset, kind);
-        } else {
-            assert isConstant(location);
-        }
-    }
-}
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMapBuilder.java	Wed Nov 19 13:43:12 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +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.lir;
-
-import java.util.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-
-/**
- * A {@link FrameMapBuilder} is used to collect all information necessary to
- * {@linkplain #buildFrameMap() create} a {@link FrameMap}.
- */
-public interface FrameMapBuilder {
-
-    /**
-     * Reserves a spill slot in the frame of the method being compiled. The returned slot is aligned
-     * on its natural alignment, i.e., an 8-byte spill slot is aligned at an 8-byte boundary, unless
-     * overridden by a subclass.
-     *
-     * @param kind The kind of the spill slot to be reserved.
-     * @return A spill slot denoting the reserved memory area.
-     */
-    StackSlot allocateSpillSlot(LIRKind kind);
-
-    /**
-     * Reserves a number of contiguous slots in the frame of the method being compiled. If the
-     * requested number of slots is 0, this method returns {@code null}.
-     *
-     * @param slots the number of slots to reserve
-     * @param objects specifies the indexes of the object pointer slots. The caller is responsible
-     *            for guaranteeing that each such object pointer slot is initialized before any
-     *            instruction that uses a reference map. Without this guarantee, the garbage
-     *            collector could see garbage object values.
-     * @param outObjectStackSlots if non-null, the object pointer slots allocated are added to this
-     *            list
-     * @return the first reserved stack slot (i.e., at the lowest address)
-     */
-    StackSlot allocateStackSlots(int slots, BitSet objects, List<StackSlot> outObjectStackSlots);
-
-    RegisterConfig getRegisterConfig();
-
-    /**
-     * Frees a spill slot that was obtained via {@link #allocateSpillSlot(LIRKind)} such that it can
-     * be reused for the next allocation request for the same kind of slot.
-     */
-    void freeSpillSlot(StackSlot slot);
-
-    /**
-     * Informs the frame map that the compiled code calls a particular method, which may need stack
-     * space for outgoing arguments.
-     *
-     * @param cc The calling convention for the called method.
-     */
-    void callsMethod(CallingConvention cc);
-
-    /**
-     * Creates a {@linkplain FrameMap} based on the information collected by this
-     * {@linkplain FrameMapBuilder}.
-     */
-    FrameMap buildFrameMap();
-}
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMapBuilderImpl.java	Wed Nov 19 13:43:12 2014 +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.lir;
-
-import java.util.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-
-/**
- * A simple forwarder to {@link FrameMap}.
- */
-public class FrameMapBuilderImpl implements FrameMapBuilder {
-
-    @FunctionalInterface
-    public interface FrameMapFactory {
-        FrameMap newFrameMap(FrameMapBuilder frameMapBuilder);
-    }
-
-    private final FrameMap frameMap;
-    private final RegisterConfig registerConfig;
-
-    public FrameMapBuilderImpl(FrameMapFactory factory, CodeCacheProvider codeCache, RegisterConfig registerConfig) {
-        this.registerConfig = registerConfig == null ? codeCache.getRegisterConfig() : registerConfig;
-        this.frameMap = factory.newFrameMap(this);
-    }
-
-    public StackSlot allocateSpillSlot(LIRKind kind) {
-        return frameMap.allocateSpillSlot(kind);
-    }
-
-    public StackSlot allocateStackSlots(int slots, BitSet objects, List<StackSlot> outObjectStackSlots) {
-        return frameMap.allocateStackSlots(slots, objects, outObjectStackSlots);
-    }
-
-    public RegisterConfig getRegisterConfig() {
-        return registerConfig;
-    }
-
-    public void freeSpillSlot(StackSlot slot) {
-        frameMap.freeSpillSlot(slot);
-    }
-
-    public void callsMethod(CallingConvention cc) {
-        frameMap.callsMethod(cc);
-    }
-
-    public FrameMap buildFrameMap() {
-        frameMap.finish();
-        return frameMap;
-    }
-
-}
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java	Wed Nov 19 16:06:49 2014 +0100
@@ -22,17 +22,24 @@
  */
 package com.oracle.graal.lir;
 
+import static com.oracle.graal.api.code.ValueUtil.*;
+
 import java.util.*;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.cfg.*;
-import com.oracle.graal.lir.StandardOp.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
+import com.oracle.graal.lir.StandardOp.BlockEndOp;
+import com.oracle.graal.lir.StandardOp.LabelOp;
+import com.oracle.graal.lir.framemap.*;
 
 /**
  * This class implements the overall container for the LIR graph and directs its construction,
  * optimization, and finalization.
  */
-public class LIR {
+public class LIR implements FrameMappable {
 
     private final AbstractControlFlowGraph<?> cfg;
 
@@ -218,4 +225,31 @@
             }
         }
     }
+
+    public void map(FrameMappingTool tool) {
+        try (Scope scope = Debug.scope("StackSlotMappingLIR")) {
+            ValueProcedure updateProc = (value, mode, flags) -> {
+                if (isVirtualStackSlot(value)) {
+                    StackSlot stackSlot = tool.getStackSlot(asVirtualStackSlot(value));
+                    Debug.log("map %s -> %s", value, stackSlot);
+                    return stackSlot;
+                }
+                return value;
+            };
+            for (AbstractBlock<?> block : getControlFlowGraph().getBlocks()) {
+                try (Indent indent0 = Debug.logAndIndent("block: %s", block)) {
+                    for (LIRInstruction inst : getLIRforBlock(block)) {
+                        try (Indent indent1 = Debug.logAndIndent("Inst: %d: %s", inst.id(), inst)) {
+                            inst.forEachAlive(updateProc);
+                            inst.forEachInput(updateProc);
+                            inst.forEachOutput(updateProc);
+                            inst.forEachTemp(updateProc);
+                            inst.forEachState(updateProc);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
 }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java	Wed Nov 19 16:06:49 2014 +0100
@@ -30,6 +30,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.lir.LIRInstruction.OperandFlag;
 import com.oracle.graal.lir.LIRInstruction.OperandMode;
+import com.oracle.graal.lir.framemap.*;
 
 /**
  * This class represents garbage collection and deoptimization information attached to a LIR
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java	Wed Nov 19 16:06:49 2014 +0100
@@ -34,6 +34,7 @@
 import com.oracle.graal.debug.*;
 import com.oracle.graal.lir.LIRInstruction.OperandFlag;
 import com.oracle.graal.lir.LIRInstruction.OperandMode;
+import com.oracle.graal.lir.framemap.*;
 
 public final class LIRVerifier {
 
@@ -226,7 +227,7 @@
     private static void allowed(Object op, Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
         if ((isVariable(value) && flags.contains(OperandFlag.REG)) ||
             (isRegister(value) && flags.contains(OperandFlag.REG)) ||
-            (isStackSlot(value) && flags.contains(OperandFlag.STACK)) ||
+            (isStackSlotValue(value) && flags.contains(OperandFlag.STACK)) ||
             (isConstant(value) && flags.contains(OperandFlag.CONST) && mode != OperandMode.DEF) ||
             (isIllegal(value) && flags.contains(OperandFlag.ILLEGAL))) {
             return;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/RedundantMoveElimination.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/RedundantMoveElimination.java	Wed Nov 19 16:06:49 2014 +0100
@@ -33,6 +33,7 @@
 import com.oracle.graal.lir.LIRInstruction.OperandFlag;
 import com.oracle.graal.lir.LIRInstruction.OperandMode;
 import com.oracle.graal.lir.StandardOp.MoveOp;
+import com.oracle.graal.lir.framemap.*;
 
 /**
  * Removes move instructions, where the destination value is already in place.
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java	Wed Nov 19 16:06:49 2014 +0100
@@ -32,6 +32,7 @@
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.cfg.*;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.framemap.*;
 
 /**
  * A collection of machine-independent LIR operations, as well as interfaces to be implemented for
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java	Wed Nov 19 16:06:49 2014 +0100
@@ -37,6 +37,7 @@
 import com.oracle.graal.compiler.common.cfg.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.framemap.*;
 
 /**
  * Fills in a {@link CompilationResult} as its code is being assembled.
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilderFactory.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilderFactory.java	Wed Nov 19 16:06:49 2014 +0100
@@ -24,7 +24,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.asm.*;
-import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.framemap.*;
 
 /**
  * Factory class for creating {@link CompilationResultBuilder}s.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMap.java	Wed Nov 19 16:06:49 2014 +0100
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 2009, 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.lir.framemap;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.*;
+
+/**
+ * This class is used to build the stack frame layout for a compiled method. A {@link StackSlot} is
+ * used to index slots of the frame relative to the stack pointer. The frame size is only fixed
+ * after register allocation when all spill slots have been allocated. Both the outgoing argument
+ * area and the spill are can grow until then. Therefore, outgoing arguments are indexed from the
+ * stack pointer, while spill slots are indexed from the beginning of the frame (and the total frame
+ * size has to be added to get the actual offset from the stack pointer).
+ */
+public abstract class FrameMap {
+
+    private final TargetDescription target;
+    private final RegisterConfig registerConfig;
+
+    /**
+     * The final frame size, not including the size of the
+     * {@link Architecture#getReturnAddressSize() return address slot}. The value is only set after
+     * register allocation is complete, i.e., after all spill slots have been allocated.
+     */
+    private int frameSize;
+
+    /**
+     * Initial size of the area occupied by spill slots and other stack-allocated memory blocks.
+     */
+    protected int initialSpillSize;
+
+    /**
+     * Size of the area occupied by spill slots and other stack-allocated memory blocks.
+     */
+    protected int spillSize;
+
+    /**
+     * Size of the area occupied by outgoing overflow arguments. This value is adjusted as calling
+     * conventions for outgoing calls are retrieved. On some platforms, there is a minimum outgoing
+     * size even if no overflow arguments are on the stack.
+     */
+    protected int outgoingSize;
+
+    /**
+     * Determines if this frame has values on the stack for outgoing calls.
+     */
+    private boolean hasOutgoingStackArguments;
+
+    /**
+     * The list of stack slots allocated in this frame that are present in every reference map.
+     */
+    private final List<StackSlot> objectStackSlots;
+
+    /**
+     * Records whether an offset to an incoming stack argument was ever returned by
+     * {@link #offsetForStackSlot(StackSlot)}.
+     */
+    private boolean accessesCallerFrame;
+
+    /**
+     * Creates a new frame map for the specified method. The given registerConfig is optional, in
+     * case null is passed the default RegisterConfig from the CodeCacheProvider will be used.
+     */
+    public FrameMap(CodeCacheProvider codeCache, RegisterConfig registerConfig) {
+        this.target = codeCache.getTarget();
+        this.registerConfig = registerConfig == null ? codeCache.getRegisterConfig() : registerConfig;
+        this.frameSize = -1;
+        this.outgoingSize = codeCache.getMinimumOutgoingSize();
+        this.objectStackSlots = new ArrayList<>();
+    }
+
+    public RegisterConfig getRegisterConfig() {
+        return registerConfig;
+    }
+
+    public TargetDescription getTarget() {
+        return target;
+    }
+
+    protected int returnAddressSize() {
+        return getTarget().arch.getReturnAddressSize();
+    }
+
+    protected int calleeSaveAreaSize() {
+        CalleeSaveLayout csl = getRegisterConfig().getCalleeSaveLayout();
+        return csl != null ? csl.size : 0;
+    }
+
+    /**
+     * Determines if an offset to an incoming stack argument was ever returned by
+     * {@link #offsetForStackSlot(StackSlot)}.
+     */
+    public boolean accessesCallerFrame() {
+        return accessesCallerFrame;
+    }
+
+    /**
+     * Gets the frame size of the compiled frame, not including the size of the
+     * {@link Architecture#getReturnAddressSize() return address slot}.
+     *
+     * @return The size of the frame (in bytes).
+     */
+    public int frameSize() {
+        assert frameSize != -1 : "frame size not computed yet";
+        return frameSize;
+    }
+
+    public int outgoingSize() {
+        return outgoingSize;
+    }
+
+    /**
+     * Determines if any space is used in the frame apart from the
+     * {@link Architecture#getReturnAddressSize() return address slot}.
+     */
+    public boolean frameNeedsAllocating() {
+        int unalignedFrameSize = spillSize - returnAddressSize();
+        return hasOutgoingStackArguments || unalignedFrameSize != 0;
+    }
+
+    /**
+     * Gets the total frame size of the compiled frame, including the size of the
+     * {@link Architecture#getReturnAddressSize() return address slot}.
+     *
+     * @return The total size of the frame (in bytes).
+     */
+    public abstract int totalFrameSize();
+
+    /**
+     * Gets the current size of this frame. This is the size that would be returned by
+     * {@link #frameSize()} if {@link #finish()} were called now.
+     */
+    public abstract int currentFrameSize();
+
+    /**
+     * Aligns the given frame size to the stack alignment size and return the aligned size.
+     *
+     * @param size the initial frame size to be aligned
+     * @return the aligned frame size
+     */
+    protected abstract int alignFrameSize(int size);
+
+    /**
+     * Computes the final size of this frame. After this method has been called, methods that change
+     * the frame size cannot be called anymore, e.g., no more spill slots or outgoing arguments can
+     * be requested.
+     */
+    public void finish() {
+        frameSize = currentFrameSize();
+        if (frameSize > getRegisterConfig().getMaximumFrameSize()) {
+            throw new BailoutException("Frame size (%d) exceeded maximum allowed frame size (%d).", frameSize, getRegisterConfig().getMaximumFrameSize());
+        }
+    }
+
+    /**
+     * Computes the offset of a stack slot relative to the frame register.
+     *
+     * @param slot a stack slot
+     * @return the offset of the stack slot
+     */
+    public int offsetForStackSlot(StackSlot slot) {
+        // @formatter:off
+        assert (!slot.getRawAddFrameSize() && slot.getRawOffset() <  outgoingSize) ||
+               (slot.getRawAddFrameSize() && slot.getRawOffset()  <  0 && -slot.getRawOffset() <= spillSize) ||
+               (slot.getRawAddFrameSize() && slot.getRawOffset()  >= 0) :
+                   String.format("RawAddFrameSize: %b RawOffset: 0x%x spillSize: 0x%x outgoingSize: 0x%x", slot.getRawAddFrameSize(), slot.getRawOffset(), spillSize, outgoingSize);
+        // @formatter:on
+        if (slot.isInCallerFrame()) {
+            accessesCallerFrame = true;
+        }
+        return slot.getOffset(totalFrameSize());
+    }
+
+    /**
+     * Gets the offset from the stack pointer to the stack area where callee-saved registers are
+     * stored.
+     *
+     * @return The offset to the callee save area (in bytes).
+     */
+    public abstract int offsetToCalleeSaveArea();
+
+    /**
+     * Informs the frame map that the compiled code calls a particular method, which may need stack
+     * space for outgoing arguments.
+     *
+     * @param cc The calling convention for the called method.
+     */
+    public void callsMethod(CallingConvention cc) {
+        reserveOutgoing(cc.getStackSize());
+    }
+
+    /**
+     * Reserves space for stack-based outgoing arguments.
+     *
+     * @param argsSize The amount of space (in bytes) to reserve for stack-based outgoing arguments.
+     */
+    public void reserveOutgoing(int argsSize) {
+        assert frameSize == -1 : "frame size must not yet be fixed";
+        outgoingSize = Math.max(outgoingSize, argsSize);
+        hasOutgoingStackArguments = hasOutgoingStackArguments || argsSize > 0;
+    }
+
+    /**
+     * Reserves a new spill slot in the frame of the method being compiled. The returned slot is
+     * aligned on its natural alignment, i.e., an 8-byte spill slot is aligned at an 8-byte
+     * boundary.
+     *
+     * @param kind The kind of the spill slot to be reserved.
+     * @param additionalOffset
+     * @return A spill slot denoting the reserved memory area.
+     */
+    protected abstract StackSlot allocateNewSpillSlot(LIRKind kind, int additionalOffset);
+
+    /**
+     * Returns the spill slot size for the given {@link LIRKind}. The default value is the size in
+     * bytes for the target architecture.
+     *
+     * @param kind the {@link LIRKind} to be stored in the spill slot.
+     * @return the size in bytes
+     */
+    public int spillSlotSize(LIRKind kind) {
+        return getTarget().getSizeInBytes(kind.getPlatformKind());
+    }
+
+    /**
+     * Reserves a spill slot in the frame of the method being compiled. The returned slot is aligned
+     * on its natural alignment, i.e., an 8-byte spill slot is aligned at an 8-byte boundary, unless
+     * overridden by a subclass.
+     *
+     * @param kind The kind of the spill slot to be reserved.
+     * @return A spill slot denoting the reserved memory area.
+     */
+    protected StackSlot allocateSpillSlot(LIRKind kind) {
+        assert frameSize == -1 : "frame size must not yet be fixed";
+        int size = spillSlotSize(kind);
+        spillSize = NumUtil.roundUp(spillSize + size, size);
+        return allocateNewSpillSlot(kind, 0);
+    }
+
+    /**
+     * Reserves a number of contiguous slots in the frame of the method being compiled. If the
+     * requested number of slots is 0, this method returns {@code null}.
+     *
+     * @param slots the number of slots to reserve
+     * @param objects specifies the indexes of the object pointer slots. The caller is responsible
+     *            for guaranteeing that each such object pointer slot is initialized before any
+     *            instruction that uses a reference map. Without this guarantee, the garbage
+     *            collector could see garbage object values.
+     * @return the first reserved stack slot (i.e., at the lowest address)
+     */
+    protected StackSlot allocateStackSlots(int slots, BitSet objects) {
+        assert frameSize == -1 : "frame size must not yet be fixed";
+        if (slots == 0) {
+            return null;
+        }
+        spillSize += (slots * getTarget().wordSize);
+
+        if (!objects.isEmpty()) {
+            assert objects.length() <= slots;
+            StackSlot result = null;
+            for (int slotIndex = 0; slotIndex < slots; slotIndex++) {
+                StackSlot objectSlot = null;
+                if (objects.get(slotIndex)) {
+                    objectSlot = allocateNewSpillSlot(LIRKind.reference(Kind.Object), slotIndex * getTarget().wordSize);
+                    addObjectStackSlot(objectSlot);
+                }
+                if (slotIndex == 0) {
+                    if (objectSlot != null) {
+                        result = objectSlot;
+                    } else {
+                        result = allocateNewSpillSlot(LIRKind.value(getTarget().wordKind), 0);
+                    }
+                }
+            }
+            assert result != null;
+            return result;
+
+        } else {
+            return allocateNewSpillSlot(LIRKind.value(getTarget().wordKind), 0);
+        }
+    }
+
+    protected void addObjectStackSlot(StackSlot objectSlot) {
+        objectStackSlots.add(objectSlot);
+    }
+
+    public ReferenceMap initReferenceMap(boolean hasRegisters) {
+        ReferenceMap refMap = getTarget().createReferenceMap(hasRegisters, frameSize() / getTarget().wordSize);
+        for (StackSlot slot : objectStackSlots) {
+            setReference(slot, refMap);
+        }
+        return refMap;
+    }
+
+    /**
+     * Marks the specified location as a reference in the reference map of the debug information.
+     * The tracked location can be a {@link RegisterValue} or a {@link StackSlot}. Note that a
+     * {@link JavaConstant} is automatically tracked.
+     *
+     * @param location The location to be added to the reference map.
+     * @param refMap A reference map, as created by {@link #initReferenceMap(boolean)}.
+     */
+    public void setReference(Value location, ReferenceMap refMap) {
+        LIRKind kind = location.getLIRKind();
+        if (isRegister(location)) {
+            refMap.setRegister(asRegister(location).getReferenceMapIndex(), kind);
+        } else if (isStackSlot(location)) {
+            int offset = offsetForStackSlot(asStackSlot(location));
+            refMap.setStackSlot(offset, kind);
+        } else {
+            assert isConstant(location);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMapBuilder.java	Wed Nov 19 16:06:49 2014 +0100
@@ -0,0 +1,85 @@
+/*
+ * 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.lir.framemap;
+
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.lir.gen.*;
+
+/**
+ * A {@link FrameMapBuilder} is used to collect all information necessary to
+ * {@linkplain #buildFrameMap create} a {@link FrameMap}.
+ */
+public interface FrameMapBuilder {
+
+    /**
+     * Reserves a spill slot in the frame of the method being compiled. The returned slot is aligned
+     * on its natural alignment, i.e., an 8-byte spill slot is aligned at an 8-byte boundary, unless
+     * overridden by a subclass.
+     *
+     * @param kind The kind of the spill slot to be reserved.
+     * @return A spill slot denoting the reserved memory area.
+     */
+    VirtualStackSlot allocateSpillSlot(LIRKind kind);
+
+    /**
+     * Reserves a number of contiguous slots in the frame of the method being compiled. If the
+     * requested number of slots is 0, this method returns {@code null}.
+     *
+     * @param slots the number of slots to reserve
+     * @param objects specifies the indexes of the object pointer slots. The caller is responsible
+     *            for guaranteeing that each such object pointer slot is initialized before any
+     *            instruction that uses a reference map. Without this guarantee, the garbage
+     *            collector could see garbage object values.
+     * @param outObjectStackSlots if non-null, the object pointer slots allocated are added to this
+     *            list
+     * @return the first reserved stack slot (i.e., at the lowest address)
+     */
+    VirtualStackSlot allocateStackSlots(int slots, BitSet objects, List<VirtualStackSlot> outObjectStackSlots);
+
+    RegisterConfig getRegisterConfig();
+
+    CodeCacheProvider getCodeCache();
+
+    /**
+     * Informs the frame map that the compiled code calls a particular method, which may need stack
+     * space for outgoing arguments.
+     *
+     * @param cc The calling convention for the called method.
+     */
+    void callsMethod(CallingConvention cc);
+
+    /**
+     * Registers a FrameMappable class so that virtual stack slots can be changed to real stack
+     * slots.
+     */
+    void requireMapping(FrameMappable mappable);
+
+    /**
+     * Creates a {@linkplain FrameMap} based on the information collected by this
+     * {@linkplain FrameMapBuilder}.
+     */
+    FrameMap buildFrameMap(LIRGenerationResult result);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMapBuilderImpl.java	Wed Nov 19 16:06:49 2014 +0100
@@ -0,0 +1,105 @@
+/*
+ * 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.lir.framemap;
+
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.*;
+import com.oracle.graal.lir.gen.*;
+
+/**
+ * A FrameMapBuilder that records allocation.
+ */
+public class FrameMapBuilderImpl implements FrameMapBuilder {
+
+    private final RegisterConfig registerConfig;
+    private final CodeCacheProvider codeCache;
+    protected final FrameMap frameMap;
+    private final List<VirtualStackSlot> stackSlots;
+    private final List<CallingConvention> calls;
+
+    public FrameMapBuilderImpl(FrameMap frameMap, CodeCacheProvider codeCache, RegisterConfig registerConfig) {
+        assert registerConfig != null : "No register config!";
+        this.registerConfig = registerConfig == null ? codeCache.getRegisterConfig() : registerConfig;
+        this.codeCache = codeCache;
+        this.frameMap = frameMap;
+        this.stackSlots = new ArrayList<>();
+        this.calls = new ArrayList<>();
+        this.mappables = new ArrayList<>();
+    }
+
+    private final List<FrameMappable> mappables;
+
+    public VirtualStackSlot allocateSpillSlot(LIRKind kind) {
+        SimpleVirtualStackSlot slot = new SimpleVirtualStackSlot(kind);
+        stackSlots.add(slot);
+        return slot;
+    }
+
+    public VirtualStackSlot allocateStackSlots(int slots, BitSet objects, List<VirtualStackSlot> outObjectStackSlots) {
+        if (slots == 0) {
+            return null;
+        }
+        if (outObjectStackSlots != null) {
+            throw GraalInternalError.unimplemented();
+        }
+        VirtualStackSlotRange slot = new VirtualStackSlotRange(slots, objects);
+        stackSlots.add(slot);
+        return slot;
+    }
+
+    public RegisterConfig getRegisterConfig() {
+        return registerConfig;
+    }
+
+    public CodeCacheProvider getCodeCache() {
+        return codeCache;
+    }
+
+    public void callsMethod(CallingConvention cc) {
+        calls.add(cc);
+    }
+
+    public FrameMap buildFrameMap(LIRGenerationResult res) {
+        FrameMappingTool mapper = new SimpleStackSlotAllocator().allocateStackSlots(this);
+        for (CallingConvention cc : calls) {
+            frameMap.callsMethod(cc);
+        }
+        // rewrite
+        mappables.forEach(m -> m.map(mapper));
+
+        frameMap.finish();
+        return frameMap;
+    }
+
+    public void requireMapping(FrameMappable mappable) {
+        this.mappables.add(mappable);
+    }
+
+    List<VirtualStackSlot> getStackSlots() {
+        return stackSlots;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMappable.java	Wed Nov 19 16:06:49 2014 +0100
@@ -0,0 +1,32 @@
+/*
+ * 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.lir.framemap;
+
+/**
+ * This interface should be implemented by all classes that store virtual stack slots to convert
+ * them into real stack slots when {@link FrameMapBuilder#buildFrameMap} is called. Implementors
+ * should register themselves using {@link FrameMapBuilder#requireMapping(FrameMappable)}.
+ */
+public interface FrameMappable {
+    void map(FrameMappingTool tool);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMappingTool.java	Wed Nov 19 16:06:49 2014 +0100
@@ -0,0 +1,33 @@
+/*
+ * 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.lir.framemap;
+
+import com.oracle.graal.api.code.*;
+
+/**
+ * A tool to get the real stack slot from a virtual stack slot.
+ */
+@FunctionalInterface
+public interface FrameMappingTool {
+    StackSlot getStackSlot(VirtualStackSlot slot);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/SimpleStackSlotAllocator.java	Wed Nov 19 16:06:49 2014 +0100
@@ -0,0 +1,55 @@
+/*
+ * 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.lir.framemap;
+
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.compiler.common.*;
+
+public class SimpleStackSlotAllocator implements StackSlotAllocator {
+
+    public FrameMappingTool allocateStackSlots(FrameMapBuilderImpl builder) {
+        HashMap<VirtualStackSlot, StackSlot> mapping = new HashMap<>();
+        for (VirtualStackSlot virtualSlot : builder.getStackSlots()) {
+            final StackSlot slot;
+            if (virtualSlot instanceof SimpleVirtualStackSlot) {
+                slot = mapSimpleVirtualStackSlot(builder, (SimpleVirtualStackSlot) virtualSlot);
+            } else if (virtualSlot instanceof VirtualStackSlotRange) {
+                slot = mapVirtualStackSlotRange(builder, (VirtualStackSlotRange) virtualSlot);
+            } else {
+                throw GraalInternalError.shouldNotReachHere("Unknown VirtualStackSlot: " + virtualSlot);
+            }
+            mapping.put(virtualSlot, slot);
+        }
+        return mapping::get;
+    }
+
+    protected StackSlot mapSimpleVirtualStackSlot(FrameMapBuilderImpl builder, SimpleVirtualStackSlot virtualStackSlot) {
+        return builder.frameMap.allocateSpillSlot(virtualStackSlot.getLIRKind());
+    }
+
+    protected StackSlot mapVirtualStackSlotRange(FrameMapBuilderImpl builder, VirtualStackSlotRange virtualStackSlot) {
+        return builder.frameMap.allocateStackSlots(virtualStackSlot.getSlots(), virtualStackSlot.getObjects());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/SimpleVirtualStackSlot.java	Wed Nov 19 16:06:49 2014 +0100
@@ -0,0 +1,39 @@
+/*
+ * 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.lir.framemap;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Represents a {@link VirtualStackSlot virtual stack slot} for a specific {@link LIRKind kind}.
+ */
+class SimpleVirtualStackSlot extends VirtualStackSlot {
+
+    private static final long serialVersionUID = 7654295701165421750L;
+
+    public SimpleVirtualStackSlot(LIRKind lirKind) {
+        super(lirKind);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/StackSlotAllocator.java	Wed Nov 19 16:06:49 2014 +0100
@@ -0,0 +1,33 @@
+/*
+ * 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.lir.framemap;
+
+import com.oracle.graal.api.code.*;
+
+/**
+ * A {@link StackSlotAllocator} is responsible for translating {@link VirtualStackSlot virtual}
+ * stack slots into {@link StackSlot real} stack slots.
+ */
+public interface StackSlotAllocator {
+    FrameMappingTool allocateStackSlots(FrameMapBuilderImpl builder);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/VirtualStackSlotRange.java	Wed Nov 19 16:06:49 2014 +0100
@@ -0,0 +1,54 @@
+/*
+ * 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.lir.framemap;
+
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Represents a {@link #getSlots() numbered} range of {@link VirtualStackSlot virtual stack slot} of
+ * size {@link TargetDescription#wordSize}.
+ */
+class VirtualStackSlotRange extends VirtualStackSlot {
+
+    private static final long serialVersionUID = 5152592950118317121L;
+    private final BitSet objects;
+    private final int slots;
+
+    public VirtualStackSlotRange(int slots, BitSet objects) {
+        super(LIRKind.reference(Kind.Object));
+        this.slots = slots;
+        this.objects = (BitSet) objects.clone();
+    }
+
+    public int getSlots() {
+        return slots;
+    }
+
+    public BitSet getObjects() {
+        return (BitSet) objects.clone();
+    }
+
+}
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerationResult.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerationResult.java	Wed Nov 19 16:06:49 2014 +0100
@@ -23,6 +23,7 @@
 package com.oracle.graal.lir.gen;
 
 import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.framemap.*;
 
 public interface LIRGenerationResult {
 
@@ -38,7 +39,7 @@
      * Creates a {@link FrameMap} out of the {@link FrameMapBuilder}. This method should only be
      * called once. After calling it, {@link #getFrameMapBuilder()} can no longer be used.
      *
-     * @see FrameMapBuilder#buildFrameMap()
+     * @see FrameMapBuilder#buildFrameMap
      */
     void buildFrameMap();
 
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerationResultBase.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerationResultBase.java	Wed Nov 19 16:06:49 2014 +0100
@@ -23,6 +23,7 @@
 package com.oracle.graal.lir.gen;
 
 import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.framemap.*;
 
 public class LIRGenerationResultBase implements LIRGenerationResult {
     private final LIR lir;
@@ -60,7 +61,7 @@
 
     public void buildFrameMap() {
         assert frameMap == null : "buildFrameMap() can only be called once!";
-        frameMap = frameMapBuilder.buildFrameMap();
+        frameMap = frameMapBuilder.buildFrameMap(this);
     }
 
     public FrameMap getFrameMap() {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java	Wed Nov 19 16:06:49 2014 +0100
@@ -112,7 +112,7 @@
 
     Value emitAddress(Value base, long displacement, Value index, int scale);
 
-    Value emitAddress(StackSlot slot);
+    Value emitAddress(StackSlotValue slot);
 
     void emitMembar(int barriers);
 
--- a/graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64OptimizedCallTargetInstrumentationFactory.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64OptimizedCallTargetInstrumentationFactory.java	Wed Nov 19 16:06:49 2014 +0100
@@ -32,8 +32,8 @@
 import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.framemap.*;
 import com.oracle.graal.truffle.*;
 import com.oracle.graal.truffle.hotspot.*;
 
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/OptimizedCallTargetInstrumentation.java	Wed Nov 19 13:43:12 2014 +0100
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/OptimizedCallTargetInstrumentation.java	Wed Nov 19 16:06:49 2014 +0100
@@ -31,8 +31,8 @@
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.MarkId;
 import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.framemap.*;
 import com.oracle.graal.truffle.*;
 
 /**
--- a/src/share/vm/graal/graalJavaAccess.hpp	Wed Nov 19 13:43:12 2014 +0100
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Wed Nov 19 16:06:49 2014 +0100
@@ -253,7 +253,7 @@
   end_class                                                                                                                                                    \
   start_class(HotSpotMonitorValue)                                                                                                                             \
     oop_field(HotSpotMonitorValue, owner, "Lcom/oracle/graal/api/meta/JavaValue;")                                                                             \
-    oop_field(HotSpotMonitorValue, slot, "Lcom/oracle/graal/api/code/StackSlot;")                                                                              \
+    oop_field(HotSpotMonitorValue, slot, "Lcom/oracle/graal/api/code/StackSlotValue;")                                                                              \
     boolean_field(HotSpotMonitorValue, eliminated)                                                                                                             \
   end_class                                                                                                                                                    \
   start_class(SpeculationLog)                                                                                                                                  \