changeset 5234:c1e5e3ab546d

Merge.
author Doug Simon <doug.simon@oracle.com>
date Thu, 12 Apr 2012 15:58:05 +0200
parents efbb1e33e2f3 (diff) ce6cb3a1eb44 (current diff)
children 15c857decc43
files mx/commands.py
diffstat 30 files changed, 544 insertions(+), 462 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Wed Apr 11 15:38:00 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Thu Apr 12 15:58:05 2012 +0200
@@ -41,7 +41,6 @@
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.cfg.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.max.asm.*;
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.cri.ri.*;
 import com.oracle.max.cri.xir.*;
@@ -269,18 +268,9 @@
         return frameMap;
     }
 
-    private TargetMethodAssembler createAssembler(FrameMap frameMap, LIR lir) {
-        AbstractAssembler masm = backend.newAssembler(frameMap.registerConfig);
-        TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime, frameMap, lir.slowPaths, masm);
-        tasm.setFrameSize(frameMap.frameSize());
-        tasm.targetMethod.setCustomStackAreaOffset(frameMap.offsetToCustomArea());
-        return tasm;
-    }
-
     public CiTargetMethod emitCode(CiAssumptions assumptions, RiResolvedMethod method, LIR lir, FrameMap frameMap) {
-        TargetMethodAssembler tasm = createAssembler(frameMap, lir);
-        lir.emitCode(tasm);
-
+        TargetMethodAssembler tasm = backend.newAssembler(frameMap, lir);
+        backend.emitCode(tasm, method, lir);
         CiTargetMethod targetMethod = tasm.finishTargetMethod(method, false);
         if (assumptions != null && !assumptions.isEmpty()) {
             targetMethod.setAssumptions(assumptions);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Wed Apr 11 15:38:00 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Thu Apr 12 15:58:05 2012 +0200
@@ -493,11 +493,6 @@
         }
         append(new ParametersOp(params));
 
-        XirSnippet prologue = xir.genPrologue(null, method);
-        if (prologue != null) {
-            emitXir(prologue, null, null, false);
-        }
-
         for (LocalNode local : graph.getNodes(LocalNode.class)) {
             CiValue param = params[local.index()];
             assert param.kind == local.kind().stackKind();
@@ -603,11 +598,7 @@
             operand = resultOperandFor(x.kind());
             emitMove(operand(x.result()), operand);
         }
-        XirSnippet epilogue = xir.genEpilogue(site(x), method);
-        if (epilogue != null) {
-            emitXir(epilogue, x, null, false);
-            emitReturn(operand);
-        }
+        emitReturn(operand);
     }
 
     protected abstract void emitReturn(CiValue input);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java	Wed Apr 11 15:38:00 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java	Thu Apr 12 15:58:05 2012 +0200
@@ -24,18 +24,26 @@
 
 import java.lang.reflect.*;
 
-import com.oracle.max.asm.*;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.asm.*;
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.cri.ri.*;
 import com.oracle.max.cri.xir.*;
-import com.oracle.graal.compiler.gen.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.lir.*;
 
 /**
  * The {@code Backend} class represents a compiler backend for Graal.
  */
 public abstract class Backend {
+
+    /**
+     * The name of the system property whose value (if non-null) specifies the fully qualified
+     * name of the class to be instantiated by {@link #create(RiRuntime, CiTarget)}.
+     */
+    public static final String BACKEND_CLASS_PROPERTY = "graal.compiler.backend.class";
+
     public final RiRuntime runtime;
     public final CiTarget target;
 
@@ -44,8 +52,13 @@
         this.target = target;
     }
 
-    public static Backend create(CiArchitecture arch, RiRuntime runtime, CiTarget target) {
-        String className = arch.getClass().getName().replace("com.oracle.max.asm", "com.oracle.graal.compiler") + "Backend";
+    /**
+     * Creates the architecture and runtime specific back-end object.
+     * The class of the object instantiated must be in the {@link #BACKEND_CLASS_PROPERTY} system property.
+     */
+    public static Backend create(RiRuntime runtime, CiTarget target) {
+        String className = System.getProperty(BACKEND_CLASS_PROPERTY);
+        assert className != null : "System property must be defined: " + BACKEND_CLASS_PROPERTY;
         try {
             Class<?> c = Class.forName(className);
             Constructor<?> cons = c.getDeclaredConstructor(RiRuntime.class, CiTarget.class);
@@ -55,9 +68,46 @@
         }
     }
 
-    public abstract FrameMap newFrameMap(RiRegisterConfig registerConfig);
+    public FrameMap newFrameMap(RiRegisterConfig registerConfig) {
+        return new FrameMap(runtime, target, registerConfig);
+    }
+
     public abstract LIRGenerator newLIRGenerator(Graph graph, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir);
-    public abstract AbstractAssembler newAssembler(RiRegisterConfig registerConfig);
+
+    public abstract TargetMethodAssembler newAssembler(FrameMap frameMap, LIR lir);
+
     public abstract CiXirAssembler newXirAssembler();
 
+    /**
+     * Emits code to do stack overflow checking.
+     *
+     * @param afterFrameInit specifies if the stack pointer has already been adjusted to allocate the current frame
+     */
+    protected static void emitStackOverflowCheck(TargetMethodAssembler tasm, LIR lir, boolean afterFrameInit) {
+        if (GraalOptions.StackShadowPages > 0) {
+            int frameSize = tasm.frameMap.frameSize();
+            if (frameSize > 0 || lir.containsCalls()) {
+                int lastFramePage = frameSize / tasm.target.pageSize;
+                // emit multiple stack bangs for methods with frames larger than a page
+                for (int i = 0; i <= lastFramePage; i++) {
+                    int disp = (i + GraalOptions.StackShadowPages) * tasm.target.pageSize;
+                    if (afterFrameInit) {
+                        disp -= frameSize;
+                    }
+                    tasm.asm.bangStack(disp);
+                }
+            }
+        }
+    }
+
+    /**
+     * Emits the code for a given method. This includes any architecture/runtime specific
+     * prefix/suffix. A prefix typically contains the code for setting up the frame,
+     * spilling callee-save registers, stack overflow checking, handling multiple entry
+     * points etc. A suffix may contain out-of-line stubs and method end guard instructions.
+     *
+     * @param the method associated with {@code lir}
+     * @param lir the LIR of {@code method}
+     */
+    public abstract void emitCode(TargetMethodAssembler tasm, RiResolvedMethod method, LIR lir);
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64Backend.java	Wed Apr 11 15:38:00 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2009, 2012, 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.compiler.target.amd64;
-
-import com.oracle.max.asm.*;
-import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-import com.oracle.max.cri.xir.*;
-import com.oracle.graal.compiler.gen.*;
-import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.lir.*;
-
-/**
- * The {@code X86Backend} class represents the backend for the AMD64 architecture.
- */
-public class AMD64Backend extends Backend {
-
-    public AMD64Backend(RiRuntime runtime, CiTarget target) {
-        super(runtime, target);
-    }
-    /**
-     * Creates a new LIRGenerator for x86.
-     * @param compilation the compilation for which to create the LIR generator
-     * @return an appropriate LIR generator instance
-     */
-    @Override
-    public LIRGenerator newLIRGenerator(Graph graph, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir) {
-        return new AMD64LIRGenerator(graph, runtime, target, frameMap, method, lir, xir);
-    }
-
-    @Override
-    public FrameMap newFrameMap(RiRegisterConfig registerConfig) {
-        return new FrameMap(runtime, target, registerConfig);
-    }
-
-    @Override
-    public AbstractAssembler newAssembler(RiRegisterConfig registerConfig) {
-        return new AMD64MacroAssembler(target, registerConfig);
-    }
-
-    @Override
-    public CiXirAssembler newXirAssembler() {
-        return new AMD64XirAssembler(target);
-    }
-}
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64DeoptimizationStub.java	Wed Apr 11 15:38:00 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64DeoptimizationStub.java	Thu Apr 12 15:58:05 2012 +0200
@@ -33,7 +33,7 @@
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.cri.ri.*;
 
-public class AMD64DeoptimizationStub extends AMD64SlowPath {
+public class AMD64DeoptimizationStub extends AMD64Code {
     public final Label label = new Label();
     public final LIRDebugInfo info;
     public final RiDeoptAction action;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java	Wed Apr 11 15:38:00 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java	Thu Apr 12 15:58:05 2012 +0200
@@ -97,7 +97,6 @@
 
     public AMD64LIRGenerator(Graph graph, RiRuntime runtime, CiTarget target, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir) {
         super(graph, runtime, target, frameMap, method, lir, xir);
-        lir.methodEndMarker = new AMD64MethodEndStub();
         lir.spillMoveFactory = new AMD64SpillMoveFactory();
     }
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64MethodEndStub.java	Wed Apr 11 15:38:00 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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.compiler.target.amd64;
-
-import com.oracle.max.asm.target.amd64.*;
-import com.oracle.graal.compiler.*;
-import com.oracle.graal.lir.amd64.*;
-import com.oracle.graal.lir.asm.*;
-
-public class AMD64MethodEndStub extends AMD64SlowPath {
-    @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-        for (int i = 0; i < GraalOptions.MethodEndBreakpointGuards; ++i) {
-            masm.int3();
-        }
-    }
-}
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64XirAssembler.java	Wed Apr 11 15:38:00 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64XirAssembler.java	Thu Apr 12 15:58:05 2012 +0200
@@ -188,15 +188,10 @@
                     boundLabels.add(label);
                     break;
                 case Safepoint:
-                case Align:
-                case StackOverflowCheck:
-                case PushFrame:
-                case PopFrame:
                 case Push:
                 case Pop:
                 case Mark:
                 case Nop:
-                case RawBytes:
                 case ShouldNotReachHere:
                     break;
                 default:
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64XirOp.java	Wed Apr 11 15:38:00 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64XirOp.java	Thu Apr 12 15:58:05 2012 +0200
@@ -28,6 +28,10 @@
 
 import java.util.*;
 
+import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.amd64.*;
+import com.oracle.graal.lir.asm.*;
 import com.oracle.max.asm.*;
 import com.oracle.max.asm.target.amd64.*;
 import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
@@ -38,11 +42,6 @@
 import com.oracle.max.cri.xir.CiXirAssembler.XirInstruction;
 import com.oracle.max.cri.xir.CiXirAssembler.XirLabel;
 import com.oracle.max.cri.xir.CiXirAssembler.XirMark;
-import com.oracle.graal.compiler.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.amd64.*;
-import com.oracle.graal.lir.asm.*;
 
 public class AMD64XirOp extends LIRXirInstruction {
     public AMD64XirOp(XirSnippet snippet, CiValue[] operands, CiValue outputOperand, CiValue[] inputs, CiValue[] temps, int[] inputOperandIndices, int[] tempOperandIndices, int outputOperandIndex,
@@ -86,7 +85,7 @@
         }
     }
 
-    private class SlowPath extends AMD64SlowPath {
+    private class SlowPath extends AMD64Code {
         public final Label[] labels;
 
         public SlowPath(Label[] labels) {
@@ -391,52 +390,6 @@
                     masm.nullCheck(asRegister(pointer));
                     break;
                 }
-                case Align: {
-                    masm.align((Integer) inst.extra);
-                    break;
-                }
-                case StackOverflowCheck: {
-                    int frameSize = tasm.frameMap.frameSize();
-                    int lastFramePage = frameSize / tasm.target.pageSize;
-                    // emit multiple stack bangs for methods with frames larger than a page
-                    for (int i = 0; i <= lastFramePage; i++) {
-                        int offset = (i + GraalOptions.StackShadowPages) * tasm.target.pageSize;
-                        // Deduct 'frameSize' to handle frames larger than the shadow
-                        bangStackWithOffset(tasm, masm, offset - frameSize);
-                    }
-                    break;
-                }
-                case PushFrame: {
-                    int frameSize = tasm.frameMap.frameSize();
-                    masm.decrementq(AMD64.rsp, frameSize); // does not emit code for frameSize == 0
-                    if (GraalOptions.ZapStackOnMethodEntry) {
-                        final int intSize = 4;
-                        for (int i = 0; i < frameSize / intSize; ++i) {
-                            masm.movl(new CiAddress(CiKind.Int, AMD64.rsp.asValue(), i * intSize), 0xC1C1C1C1);
-                        }
-                    }
-                    CiCalleeSaveLayout csl = tasm.frameMap.registerConfig.getCalleeSaveLayout();
-                    if (csl != null && csl.size != 0) {
-                        int frameToCSA = tasm.frameMap.offsetToCalleeSaveArea();
-                        assert frameToCSA >= 0;
-                        masm.save(csl, frameToCSA);
-                    }
-                    break;
-                }
-                case PopFrame: {
-                    int frameSize = tasm.frameMap.frameSize();
-
-                    CiCalleeSaveLayout csl = tasm.frameMap.registerConfig.getCalleeSaveLayout();
-                    if (csl != null && csl.size != 0) {
-                        tasm.targetMethod.setRegisterRestoreEpilogueOffset(masm.codeBuffer.position());
-                        // saved all registers, restore all registers
-                        int frameToCSA = tasm.frameMap.offsetToCalleeSaveArea();
-                        masm.restore(csl, frameToCSA);
-                    }
-
-                    masm.incrementq(AMD64.rsp, frameSize);
-                    break;
-                }
                 case Push: {
                     CiRegisterValue value = assureInRegister(tasm, masm, operands[inst.x().index]);
                     masm.push(asRegister(value));
@@ -470,12 +423,6 @@
                     }
                     break;
                 }
-                case RawBytes: {
-                    for (byte b : (byte[]) inst.extra) {
-                        masm.codeBuffer.emitByte(b & 0xff);
-                    }
-                    break;
-                }
                 case ShouldNotReachHere: {
                     AMD64Call.shouldNotReachHere(tasm, masm);
                     break;
@@ -521,16 +468,6 @@
         masm.jcc(cflag, label);
     }
 
-    /**
-     * @param offset the offset RSP at which to bang. Note that this offset is relative to RSP after RSP has been
-     *            adjusted to allocated the frame for the method. It denotes an offset "down" the stack.
-     *            For very large frames, this means that the offset may actually be negative (i.e. denoting
-     *            a slot "up" the stack above RSP).
-     */
-    private static void bangStackWithOffset(TargetMethodAssembler tasm, AMD64MacroAssembler masm, int offset) {
-        masm.movq(new CiAddress(tasm.target.wordKind, AMD64.RSP, -offset), AMD64.rax);
-    }
-
     private static CiValue assureNot64BitConstant(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue value) {
         if (isConstant(value) && (value.kind == CiKind.Long || value.kind == CiKind.Object)) {
             CiRegisterValue register = tasm.frameMap.registerConfig.getScratchRegister().asValue(value.kind);
--- a/graal/com.oracle.graal.examples/src/examples/HelloWorld.java	Wed Apr 11 15:38:00 2012 +0200
+++ b/graal/com.oracle.graal.examples/src/examples/HelloWorld.java	Thu Apr 12 15:58:05 2012 +0200
@@ -25,6 +25,20 @@
 
 public class HelloWorld {
     public static void main(String[] args) {
-        System.out.println("hello world!");
+        new HelloWorld(args).greet();
+    }
+
+    public HelloWorld(String[] args) {
+        name = args.length == 0 ? "world" : args[0];
+    }
+
+    public String name;
+
+    public String getName() {
+        return name;
+    }
+
+    public void greet() {
+        System.out.println("hello " + getName() + "!");
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerImpl.java	Wed Apr 11 15:38:00 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerImpl.java	Thu Apr 12 15:58:05 2012 +0200
@@ -175,7 +175,7 @@
                 generator = LoggingProxy.getProxy(RiXirGenerator.class, generator);
             }
 
-            Backend backend = Backend.create(target.arch, runtime, target);
+            Backend backend = Backend.create(runtime, target);
             generator.initialize(backend.newXirAssembler());
 
             compiler = new GraalCompiler(getRuntime(), getTarget(), backend, generator);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Wed Apr 11 15:38:00 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Thu Apr 12 15:58:05 2012 +0200
@@ -147,7 +147,7 @@
 
     /**
      * This method is the first method compiled during bootstrapping. Put any code in there that warms up compiler paths
-     * that are otherwise no exercised during bootstrapping and lead to later deoptimization when application code is
+     * that are otherwise not exercised during bootstrapping and lead to later deoptimization when application code is
      * compiled.
      */
     @SuppressWarnings("unused")
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRegisterConfig.java	Wed Apr 11 15:38:00 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRegisterConfig.java	Thu Apr 12 15:58:05 2012 +0200
@@ -66,14 +66,7 @@
     private final CiRegister[] xmmParameterRegisters = {xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7};
     private final CiRegister[] allParameterRegisters;
 
-    private final CiRegister[] rsaRegs = {
-        rax,  rcx,  rdx,   rbx,   rsp,   rbp,   rsi,   rdi,
-        r8,   r9,   r10,   r11,   r12,   r13,   r14,   r15,
-        xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
-        xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
-    };
-
-    private final CiCalleeSaveLayout registerSaveArea;
+    private final CiCalleeSaveLayout csl;
 
     public HotSpotRegisterConfig(HotSpotVMConfig config, boolean globalStubConfig) {
         if (config.windowsOs) {
@@ -83,9 +76,20 @@
         }
 
         if (globalStubConfig) {
-            registerSaveArea = new CiCalleeSaveLayout(0, -1, 8, rsaRegs);
+            CiRegister[] regs = {
+                rax,  rcx,  rdx,   rbx,   rsp,   rbp,   rsi,   rdi,
+                r8,   r9,   r10,   r11,   r12,   r13,   r14,   r15,
+                xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
+                xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
+            };
+            csl = new CiCalleeSaveLayout(0, -1, 8, regs);
         } else {
-            registerSaveArea = new CiCalleeSaveLayout(0, 8, 8, new CiRegister[0]);
+            // We reserve space for saving RBP but don't explicitly specify
+            // it as a callee save register since we explicitly do the saving
+            // with push and pop in HotSpotFrameContext
+            final int size = 8;
+            final CiRegister[] regs = {};
+            csl = new CiCalleeSaveLayout(0, size, 8, regs);
         }
 
         attributesMap = RiRegisterAttributes.createMap(this, AMD64.allRegisters);
@@ -191,7 +195,7 @@
     }
 
     public CiCalleeSaveLayout getCalleeSaveLayout() {
-        return registerSaveArea;
+        return csl;
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRuntime.java	Wed Apr 11 15:38:00 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRuntime.java	Thu Apr 12 15:58:05 2012 +0200
@@ -30,11 +30,13 @@
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.phases.*;
 import com.oracle.graal.compiler.phases.PhasePlan.PhasePosition;
+import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.cri.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.Compiler;
 import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.hotspot.target.amd64.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
@@ -42,9 +44,7 @@
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiTargetMethod.Call;
-import com.oracle.max.cri.ci.CiTargetMethod.DataPatch;
-import com.oracle.max.cri.ci.CiTargetMethod.Safepoint;
+import com.oracle.max.cri.ci.CiTargetMethod.*;
 import com.oracle.max.cri.ci.CiUtil.RefMapFormatter;
 import com.oracle.max.cri.ri.*;
 import com.oracle.max.cri.ri.RiType.Representation;
@@ -54,7 +54,7 @@
  * CRI runtime implementation for the HotSpot VM.
  */
 public class HotSpotRuntime implements GraalRuntime {
-    final HotSpotVMConfig config;
+    public final HotSpotVMConfig config;
     final HotSpotRegisterConfig regConfig;
     private final HotSpotRegisterConfig globalStubRegConfig;
     private final Compiler compiler;
@@ -64,6 +64,8 @@
         this.compiler = compiler;
         regConfig = new HotSpotRegisterConfig(config, false);
         globalStubRegConfig = new HotSpotRegisterConfig(config, true);
+
+        System.setProperty(Backend.BACKEND_CLASS_PROPERTY, HotSpotAMD64Backend.class.getName());
     }
 
     @Override
@@ -81,6 +83,44 @@
         return compiler.getVMEntries().disassembleNative(code, address);
     }
 
+    /**
+     * Decodes a call target to a mnemonic if possible.
+     */
+    private String getTargetName(Call call) {
+        Field[] fields = config.getClass().getDeclaredFields();
+        for (Field f : fields) {
+            if (f.getName().endsWith("Stub")) {
+                f.setAccessible(true);
+                try {
+                    if (f.get(config).equals(call.target)) {
+                        return f.getName();
+                    }
+                } catch (Exception e) {
+                }
+            }
+        }
+        return String.valueOf(call.target);
+    }
+
+    /**
+     * Decodes a mark to a mnemonic if possible.
+     */
+    private static String getMarkName(Mark mark) {
+        Field[] fields = HotSpotXirGenerator.class.getDeclaredFields();
+        for (Field f : fields) {
+            if (Modifier.isStatic(f.getModifiers()) && f.getName().startsWith("MARK_")) {
+                f.setAccessible(true);
+                try {
+                    if (f.get(null).equals(mark.id)) {
+                        return f.getName();
+                    }
+                } catch (Exception e) {
+                }
+            }
+        }
+        return "MARK:" + mark.id;
+    }
+
     @Override
     public String disassemble(CiTargetMethod tm) {
         byte[] code = Arrays.copyOf(tm.targetCode(), tm.targetCodeSize());
@@ -96,7 +136,7 @@
                 if (call.debugInfo != null) {
                     hcf.addComment(call.pcOffset + call.size, CiUtil.append(new StringBuilder(100), call.debugInfo, slotFormatter).toString());
                 }
-                addOperandComment(hcf, call.pcOffset, "{" + call.target + "}");
+                addOperandComment(hcf, call.pcOffset, "{" + getTargetName(call) + "}");
             } else {
                 if (safepoint.debugInfo != null) {
                     hcf.addComment(safepoint.pcOffset, CiUtil.append(new StringBuilder(100), safepoint.debugInfo, slotFormatter).toString());
@@ -107,6 +147,9 @@
         for (DataPatch site : tm.dataReferences) {
             hcf.addOperandComment(site.pcOffset, "{" + site.constant + "}");
         }
+        for (Mark mark : tm.marks) {
+            hcf.addComment(mark.pcOffset, getMarkName(mark));
+        }
         return hcf.toEmbeddedString();
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotXirGenerator.java	Wed Apr 11 15:38:00 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotXirGenerator.java	Thu Apr 12 15:58:05 2012 +0200
@@ -23,10 +23,8 @@
 package com.oracle.graal.hotspot.ri;
 
 import static com.oracle.graal.hotspot.ri.TemplateFlag.*;
-import static com.oracle.max.cri.ci.CiCallingConvention.Type.*;
 import static com.oracle.max.cri.ci.CiValueUtil.*;
 
-import java.lang.reflect.*;
 import java.util.*;
 import java.util.concurrent.*;
 
@@ -49,25 +47,25 @@
 
     // this needs to correspond to graal_CodeInstaller.hpp
     // @formatter:off
-    private static final Integer MARK_VERIFIED_ENTRY            = 0x0001;
-    private static final Integer MARK_UNVERIFIED_ENTRY          = 0x0002;
-    private static final Integer MARK_OSR_ENTRY                 = 0x0003;
-    private static final Integer MARK_UNWIND_ENTRY              = 0x0004;
-    private static final Integer MARK_EXCEPTION_HANDLER_ENTRY   = 0x0005;
-    private static final Integer MARK_DEOPT_HANDLER_ENTRY       = 0x0006;
+    public static final Integer MARK_VERIFIED_ENTRY            = 0x0001;
+    public static final Integer MARK_UNVERIFIED_ENTRY          = 0x0002;
+    public static final Integer MARK_OSR_ENTRY                 = 0x0003;
+    public static final Integer MARK_UNWIND_ENTRY              = 0x0004;
+    public static final Integer MARK_EXCEPTION_HANDLER_ENTRY   = 0x0005;
+    public static final Integer MARK_DEOPT_HANDLER_ENTRY       = 0x0006;
 
-    private static final Integer MARK_STATIC_CALL_STUB          = 0x1000;
+    public static final Integer MARK_STATIC_CALL_STUB          = 0x1000;
 
-    private static final Integer MARK_INVOKEINTERFACE           = 0x2001;
-    private static final Integer MARK_INVOKESTATIC              = 0x2002;
-    private static final Integer MARK_INVOKESPECIAL             = 0x2003;
-    private static final Integer MARK_INVOKEVIRTUAL             = 0x2004;
+    public static final Integer MARK_INVOKEINTERFACE           = 0x2001;
+    public static final Integer MARK_INVOKESTATIC              = 0x2002;
+    public static final Integer MARK_INVOKESPECIAL             = 0x2003;
+    public static final Integer MARK_INVOKEVIRTUAL             = 0x2004;
 
-    private static final Integer MARK_IMPLICIT_NULL             = 0x3000;
-    private static final Integer MARK_POLL_NEAR                 = 0x3001;
-    private static final Integer MARK_POLL_RETURN_NEAR          = 0x3002;
-    private static final Integer MARK_POLL_FAR                  = 0x3003;
-    private static final Integer MARK_POLL_RETURN_FAR           = 0x3004;
+    public static final Integer MARK_IMPLICIT_NULL             = 0x3000;
+    public static final Integer MARK_POLL_NEAR                 = 0x3001;
+    public static final Integer MARK_POLL_RETURN_NEAR          = 0x3002;
+    public static final Integer MARK_POLL_FAR                  = 0x3003;
+    public static final Integer MARK_POLL_RETURN_FAR           = 0x3004;
 
     // @formatter:on
 
@@ -104,98 +102,6 @@
         }
     }
 
-    private SimpleTemplates prologueTemplates = new SimpleTemplates(STATIC_METHOD) {
-
-        @Override
-        protected XirTemplate create(CiXirAssembler asm, long flags) {
-            asm.restart(CiKind.Void);
-            XirOperand framePointer = asm.createRegisterTemp("frame pointer", target.wordKind, AMD64.rbp);
-            XirOperand stackPointer = asm.createRegisterTemp("stack pointer", target.wordKind, AMD64.rsp);
-            XirLabel unverifiedStub = null;
-
-            asm.mark(MARK_OSR_ENTRY);
-            asm.mark(MARK_UNVERIFIED_ENTRY);
-            if (!is(STATIC_METHOD, flags)) {
-                unverifiedStub = asm.createOutOfLineLabel("unverified");
-
-                XirOperand temp = asm.createRegisterTemp("temp (r10)", target.wordKind, AMD64.r10);
-                XirOperand cache = asm.createRegisterTemp("cache (rax)", target.wordKind, AMD64.rax);
-
-                CiCallingConvention conventions = registerConfig.getCallingConvention(JavaCallee, new CiKind[] {CiKind.Object}, target, false);
-                XirOperand receiver = asm.createRegister("receiver", target.wordKind, asRegister(conventions.locations[0]));
-
-                asm.pload(target.wordKind, temp, receiver, asm.i(config.hubOffset), false);
-                asm.jneq(unverifiedStub, cache, temp);
-            }
-            asm.align(config.codeEntryAlignment);
-            asm.mark(MARK_VERIFIED_ENTRY);
-            asm.stackOverflowCheck();
-            asm.push(framePointer);
-            asm.mov(framePointer, stackPointer);
-            // Compensate for the push of framePointer (the XIR instruction pushFrame is not flexible enough to reduce the frame size, wait until XIR goes away to fix this).
-            asm.add(stackPointer, stackPointer,  asm.i(8));
-            asm.pushFrame();
-
-            // -- out of line -------------------------------------------------------
-            XirOperand thread = asm.createRegisterTemp("thread", target.wordKind, AMD64.r15);
-            XirOperand exceptionOop = asm.createTemp("exception oop", CiKind.Object);
-            XirLabel unwind = asm.createOutOfLineLabel("unwind");
-            asm.bindOutOfLine(unwind);
-
-            asm.mark(MARK_UNWIND_ENTRY);
-
-            asm.pload(CiKind.Object, exceptionOop, thread, asm.i(config.threadExceptionOopOffset), false);
-            asm.pstore(CiKind.Object, thread, asm.i(config.threadExceptionOopOffset), asm.createConstant(CiConstant.NULL_OBJECT), false);
-            asm.pstore(CiKind.Long, thread, asm.i(config.threadExceptionPcOffset), asm.l(0), false);
-
-            asm.callRuntime(config.unwindExceptionStub, null, exceptionOop);
-            asm.shouldNotReachHere();
-
-            asm.mark(MARK_EXCEPTION_HANDLER_ENTRY);
-            asm.callRuntime(config.handleExceptionStub, null);
-            asm.shouldNotReachHere();
-
-            asm.mark(MARK_DEOPT_HANDLER_ENTRY);
-            asm.callRuntime(config.handleDeoptStub, null);
-            asm.shouldNotReachHere();
-
-            if (!is(STATIC_METHOD, flags)) {
-                asm.bindOutOfLine(unverifiedStub);
-                asm.jmpRuntime(config.inlineCacheMissStub);
-            }
-
-            return asm.finishTemplate(is(STATIC_METHOD, flags) ? "static prologue" : "prologue");
-        }
-    };
-
-    private SimpleTemplates epilogueTemplates = new SimpleTemplates(STATIC_METHOD, SYNCHRONIZED) {
-
-        @Override
-        protected XirTemplate create(CiXirAssembler asm, long flags) {
-            asm.restart(CiKind.Void);
-            XirOperand framePointer = asm.createRegisterTemp("frame pointer", target.wordKind, AMD64.rbp);
-            XirOperand stackPointer = asm.createRegisterTemp("stack pointer", target.wordKind, AMD64.rsp);
-
-            asm.popFrame();
-            asm.pload(CiKind.Long, framePointer, stackPointer, asm.i(-8), false);
-
-            if (GraalOptions.GenSafepoints) {
-                XirOperand temp = asm.createRegisterTemp("temp", target.wordKind, AMD64.r10);
-                if (config.isPollingPageFar) {
-                    asm.mov(temp, wordConst(asm, config.safepointPollingAddress));
-                    asm.mark(MARK_POLL_RETURN_FAR);
-                    asm.pload(target.wordKind, temp, temp, true);
-                } else {
-                    XirOperand rip = asm.createRegister("rip", target.wordKind, AMD64.rip);
-                    asm.mark(MARK_POLL_RETURN_NEAR);
-                    asm.pload(target.wordKind, temp, rip, asm.i(0xEFBEADDE), true);
-                }
-            }
-
-            return asm.finishTemplate("epilogue");
-        }
-    };
-
     private SimpleTemplates safepointTemplates = new SimpleTemplates() {
 
         @Override
@@ -958,17 +864,6 @@
     };
 
     @Override
-    public XirSnippet genPrologue(XirSite site, RiResolvedMethod method) {
-        boolean staticMethod = Modifier.isStatic(method.accessFlags());
-        return new XirSnippet(staticMethod ? prologueTemplates.get(site, STATIC_METHOD) : prologueTemplates.get(site));
-    }
-
-    @Override
-    public XirSnippet genEpilogue(XirSite site, RiResolvedMethod method) {
-        return new XirSnippet(epilogueTemplates.get(site));
-    }
-
-    @Override
     public XirSnippet genSafepointPoll(XirSite site) {
         return new XirSnippet(safepointTemplates.get(site));
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/HotSpotAMD64Backend.java	Thu Apr 12 15:58:05 2012 +0200
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.target.amd64;
+
+import static com.oracle.graal.hotspot.ri.HotSpotXirGenerator.*;
+import static com.oracle.max.asm.target.amd64.AMD64.*;
+import static com.oracle.max.cri.ci.CiCallingConvention.Type.*;
+import static com.oracle.max.cri.ci.CiValueUtil.*;
+
+import java.lang.reflect.*;
+
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.compiler.target.amd64.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.ri.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.amd64.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.max.asm.*;
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.cri.xir.*;
+
+public class HotSpotAMD64Backend extends Backend {
+
+    public HotSpotAMD64Backend(RiRuntime runtime, CiTarget target) {
+        super(runtime, target);
+    }
+
+    @Override
+    public LIRGenerator newLIRGenerator(Graph graph, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir) {
+        return new AMD64LIRGenerator(graph, runtime, target, frameMap, method, lir, xir);
+    }
+
+    @Override
+    public AMD64XirAssembler newXirAssembler() {
+        return new AMD64XirAssembler(target);
+    }
+
+    class HotSpotFrameContext implements FrameContext {
+
+        private final LIR lir;
+        private boolean needsLeave;
+
+        public HotSpotFrameContext(LIR lir) {
+            this.lir = lir;
+        }
+
+        @Override
+        public void enter(TargetMethodAssembler tasm) {
+            FrameMap frameMap = tasm.frameMap;
+            int frameSize = frameMap.frameSize();
+            if (frameSize != 0) {
+                AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm;
+                emitStackOverflowCheck(tasm, lir, false);
+                asm.push(rbp);
+                asm.movq(rbp, rsp);
+                asm.decrementq(rsp, frameSize - 8); // account for the push of RBP above
+                if (GraalOptions.ZapStackOnMethodEntry) {
+                    final int intSize = 4;
+                    for (int i = 0; i < frameSize / intSize; ++i) {
+                        asm.movl(new CiAddress(CiKind.Int, rsp.asValue(), i * intSize), 0xC1C1C1C1);
+                    }
+                }
+                CiCalleeSaveLayout csl = frameMap.registerConfig.getCalleeSaveLayout();
+                if (csl != null && csl.size != 0) {
+                    int frameToCSA = frameMap.offsetToCalleeSaveArea();
+                    assert frameToCSA >= 0;
+                    asm.save(csl, frameToCSA);
+                }
+                needsLeave = true;
+            }
+        }
+
+        @Override
+        public void leave(TargetMethodAssembler tasm) {
+            if (!needsLeave) {
+                return;
+            }
+
+            int frameSize = tasm.frameMap.frameSize();
+            AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm;
+            CiCalleeSaveLayout csl = tasm.frameMap.registerConfig.getCalleeSaveLayout();
+            RiRegisterConfig regConfig = tasm.frameMap.registerConfig;
+
+            if (csl != null && csl.size != 0) {
+                tasm.targetMethod.setRegisterRestoreEpilogueOffset(asm.codeBuffer.position());
+                // saved all registers, restore all registers
+                int frameToCSA = tasm.frameMap.offsetToCalleeSaveArea();
+                asm.restore(csl, frameToCSA);
+            }
+
+            asm.incrementq(rsp, frameSize - 8); // account for the pop of RBP below
+            asm.pop(rbp);
+
+            if (GraalOptions.GenSafepoints) {
+                HotSpotVMConfig config = ((HotSpotRuntime) runtime).config;
+
+                // If at the return point, then the frame has already been popped
+                // so deoptimization cannot be performed here. The HotSpot runtime
+                // detects this case - see the definition of frame::should_be_deoptimized()
+
+                CiRegister scratch = regConfig.getScratchRegister();
+                if (config.isPollingPageFar) {
+                    asm.movq(scratch, config.safepointPollingAddress);
+                    tasm.recordMark(MARK_POLL_RETURN_FAR);
+                    asm.movq(scratch, new CiAddress(tasm.target.wordKind, scratch.asValue()));
+                } else {
+                    tasm.recordMark(MARK_POLL_RETURN_NEAR);
+                    asm.movq(scratch, new CiAddress(tasm.target.wordKind, rip.asValue()));
+                }
+            }
+        }
+    }
+
+    @Override
+    public TargetMethodAssembler newAssembler(FrameMap frameMap, LIR lir) {
+        AbstractAssembler masm = new AMD64MacroAssembler(target, frameMap.registerConfig);
+        HotSpotFrameContext frameContext = new HotSpotFrameContext(lir);
+        TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime, frameMap, masm, frameContext);
+        tasm.setFrameSize(frameMap.frameSize());
+        tasm.targetMethod.setCustomStackAreaOffset(frameMap.offsetToCustomArea());
+        return tasm;
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, RiResolvedMethod method, LIR lir) {
+        AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm;
+        FrameMap frameMap = tasm.frameMap;
+        RiRegisterConfig regConfig = frameMap.registerConfig;
+        HotSpotVMConfig config = ((HotSpotRuntime) runtime).config;
+        Label unverifiedStub = new Label();
+        CiRegister scratch = regConfig.getScratchRegister();
+
+        // Emit the prefix
+        tasm.recordMark(MARK_OSR_ENTRY);
+        tasm.recordMark(MARK_UNVERIFIED_ENTRY);
+
+        boolean isStatic = Modifier.isStatic(method.accessFlags());
+        if (!isStatic) {
+            CiCallingConvention cc = regConfig.getCallingConvention(JavaCallee, new CiKind[] {CiKind.Object}, target, false);
+            CiRegister inlineCacheKlass = rax; // see definition of IC_Klass in c1_LIRAssembler_x86.cpp
+            CiRegister receiver = asRegister(cc.locations[0]);
+            CiAddress src = new CiAddress(target.wordKind, receiver.asValue(), config.hubOffset);
+
+            asm.movq(scratch, src);
+            asm.cmpq(inlineCacheKlass, scratch);
+            asm.jcc(ConditionFlag.notEqual, unverifiedStub);
+        }
+
+        asm.align(config.codeEntryAlignment);
+        tasm.recordMark(MARK_VERIFIED_ENTRY);
+
+        // Emit code for the LIR
+        lir.emitCode(tasm);
+
+        // Emit the suffix (i.e. out-of-line stubs)
+        CiRegister thread = r15;
+        CiRegister exceptionOop = regConfig.getScratchRegister();
+        Label unwind = new Label();
+        asm.bind(unwind);
+        tasm.recordMark(MARK_UNWIND_ENTRY);
+        CiAddress exceptionOopField = new CiAddress(CiKind.Object, thread.asValue(), config.threadExceptionOopOffset);
+        CiAddress exceptionPcField = new CiAddress(CiKind.Object, thread.asValue(), config.threadExceptionPcOffset);
+        asm.movq(exceptionOop, exceptionOopField);
+        asm.xorq(scratch, scratch);
+        asm.movq(exceptionOopField, scratch);
+        asm.movq(exceptionPcField, scratch);
+
+        AMD64Call.directCall(tasm, asm, config.unwindExceptionStub, null);
+        AMD64Call.shouldNotReachHere(tasm, asm);
+
+        tasm.recordMark(MARK_EXCEPTION_HANDLER_ENTRY);
+        AMD64Call.directCall(tasm, asm, config.handleExceptionStub, null);
+        AMD64Call.shouldNotReachHere(tasm, asm);
+
+        tasm.recordMark(MARK_DEOPT_HANDLER_ENTRY);
+        AMD64Call.directCall(tasm, asm, config.handleDeoptStub, null);
+        AMD64Call.shouldNotReachHere(tasm, asm);
+
+        if (!isStatic) {
+            asm.bind(unverifiedStub);
+            AMD64Call.directJmp(tasm, asm, config.inlineCacheMissStub);
+        }
+
+        for (int i = 0; i < GraalOptions.MethodEndBreakpointGuards; ++i) {
+            asm.int3();
+        }
+    }
+}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java	Wed Apr 11 15:38:00 2012 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java	Thu Apr 12 15:58:05 2012 +0200
@@ -510,7 +510,7 @@
         masm.bind(slowPath.continuation);
     }
 
-    private static class ConvertSlowPath extends AMD64SlowPath {
+    private static class ConvertSlowPath extends AMD64Code {
         public final Label start = new Label();
         public final Label continuation = new Label();
         private final CiValue result;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Code.java	Thu Apr 12 15:58:05 2012 +0200
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, 2012, 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.max.asm.target.amd64.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.asm.*;
+
+/**
+ * Convenience class to provide AMD64MacroAssembler for the {@link #emitCode} method.
+ */
+public abstract class AMD64Code implements LIR.Code {
+    @Override
+    public final void emitCode(TargetMethodAssembler tasm) {
+        emitCode(tasm, (AMD64MacroAssembler) tasm.asm);
+    }
+
+    public abstract void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm);
+}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java	Wed Apr 11 15:38:00 2012 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java	Thu Apr 12 15:58:05 2012 +0200
@@ -46,6 +46,7 @@
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            tasm.frameContext.leave(tasm);
             masm.ret(0);
         }
 
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64SlowPath.java	Wed Apr 11 15:38:00 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, 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.max.asm.target.amd64.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.asm.*;
-
-/**
- * Convenience class to provide AMD64MacroAssembler for the {@link #emitCode} method.
- */
-public abstract class AMD64SlowPath implements LIR.SlowPath {
-    @Override
-    public final void emitCode(TargetMethodAssembler tasm) {
-        emitCode(tasm, (AMD64MacroAssembler) tasm.asm);
-    }
-
-    public abstract void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm);
-}
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java	Wed Apr 11 15:38:00 2012 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java	Thu Apr 12 15:58:05 2012 +0200
@@ -55,14 +55,9 @@
     private final List<Block> codeEmittingOrder;
 
 
-    public final List<SlowPath> slowPaths;
-
-    public final List<SlowPath> deoptimizationStubs;
+    public final List<Code> slowPaths;
 
-    /**
-     * The last slow path emitted, which can be used emit marker bytes.
-     */
-    public SlowPath methodEndMarker;
+    public final List<Code> deoptimizationStubs;
 
     private int numVariables;
 
@@ -73,7 +68,10 @@
         LIRInstruction createExchange(CiValue input1, CiValue input2);
     }
 
-    public interface SlowPath {
+    /**
+     * An opaque chunk of machine code.
+     */
+    public interface Code {
         void emitCode(TargetMethodAssembler tasm);
     }
 
@@ -97,6 +95,23 @@
     }
 
     /**
+     * Determines if this LIR contains any calls.
+     */
+    public boolean containsCalls() {
+        if (!slowPaths.isEmpty() || !deoptimizationStubs.isEmpty()) {
+            return true;
+        }
+        for (Block b : linearScanOrder) {
+            for (LIRInstruction op : b.lir) {
+                if (op.hasCall()) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
      * Gets the linear scan ordering of blocks as a list.
      * @return the blocks in linear scan order
      */
@@ -117,20 +132,23 @@
     }
 
     public void emitCode(TargetMethodAssembler tasm) {
+        tasm.frameContext.enter(tasm);
+
         for (Block b : codeEmittingOrder()) {
             emitBlock(tasm, b);
         }
 
         // generate code for slow cases
-        for (SlowPath sp : slowPaths) {
+        for (Code sp : slowPaths) {
+            emitSlowPath(tasm, sp);
+        }
+        for (Code sp : tasm.slowPaths) {
             emitSlowPath(tasm, sp);
         }
         // generate deoptimization stubs
-        for (SlowPath sp : deoptimizationStubs) {
+        for (Code sp : deoptimizationStubs) {
             emitSlowPath(tasm, sp);
         }
-        // generate traps at the end of the method
-        emitSlowPath(tasm, methodEndMarker);
     }
 
     private static void emitBlock(TargetMethodAssembler tasm, Block block) {
@@ -161,7 +179,7 @@
         }
     }
 
-    private static void emitSlowPath(TargetMethodAssembler tasm, SlowPath sp) {
+    private static void emitSlowPath(TargetMethodAssembler tasm, Code sp) {
         if (Debug.isDumpEnabled()) {
             tasm.blockComment(String.format("slow case %s", sp.getClass().getName()));
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/FrameContext.java	Thu Apr 12 15:58:05 2012 +0200
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012, 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.asm;
+
+
+/**
+ * Emits common code for {@linkplain #enter(TargetMethodAssembler) entering} and
+ * {@linkplain #leave(TargetMethodAssembler) leaving} a method.
+ */
+public interface FrameContext {
+    /**
+     * Emits code common to all entry points of a method. This may include:
+     * <ul>
+     * <li>setting up the stack frame</li>
+     * <li>saving callee-saved registers</li>
+     * <li>stack overflow checking</li>
+     * </ul>
+     */
+    void enter(TargetMethodAssembler tasm);
+
+    /**
+     * Emits code to be executed just prior to returning from a method. This may include:
+     * <ul>
+     * <li>restoring callee-saved registers</li>
+     * <li>performing a safepoint</li>
+     * <li>destroying the stack frame</li>
+     * </ul>
+     */
+    void leave(TargetMethodAssembler tasm);
+}
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java	Wed Apr 11 15:38:00 2012 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java	Thu Apr 12 15:58:05 2012 +0200
@@ -51,18 +51,20 @@
     public final CiTarget target;
     public final RiRuntime runtime;
     public final FrameMap frameMap;
-    public final List<SlowPath> slowPaths;
+    public final List<Code> slowPaths;
+    public final FrameContext frameContext;
 
     private List<ExceptionInfo> exceptionInfoList;
     private int lastSafepointPos;
 
-    public TargetMethodAssembler(CiTarget target, RiRuntime runtime, FrameMap frameMap, List<SlowPath> slowPaths, AbstractAssembler asm) {
+    public TargetMethodAssembler(CiTarget target, RiRuntime runtime, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext) {
         this.target = target;
         this.runtime = runtime;
         this.frameMap = frameMap;
-        this.slowPaths = slowPaths;
+        this.slowPaths = new ArrayList<>();
         this.asm = asm;
         this.targetMethod = new CiTargetMethod();
+        this.frameContext = frameContext;
         // 0 is a valid pc for safepoints in template methods
         this.lastSafepointPos = -1;
     }
@@ -71,6 +73,10 @@
         targetMethod.setFrameSize(frameSize);
     }
 
+    public CiTargetMethod.Mark recordMark(Object id) {
+        return targetMethod.recordMark(asm.codeBuffer.position(), id, null);
+    }
+
     public CiTargetMethod.Mark recordMark(Object id, CiTargetMethod.Mark[] references) {
         return targetMethod.recordMark(asm.codeBuffer.position(), id, references);
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/cri/GraalRuntime.java	Wed Apr 11 15:38:00 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/cri/GraalRuntime.java	Thu Apr 12 15:58:05 2012 +0200
@@ -24,10 +24,10 @@
 
 import java.util.*;
 
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.cri.ri.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.*;
 
 /**
  * Graal-specific extensions for the runtime interface that must be implemented by the VM.
--- a/graal/com.oracle.max.asm/src/com/oracle/max/asm/AbstractAssembler.java	Wed Apr 11 15:38:00 2012 +0200
+++ b/graal/com.oracle.max.asm/src/com/oracle/max/asm/AbstractAssembler.java	Thu Apr 12 15:58:05 2012 +0200
@@ -54,6 +54,14 @@
 
     protected abstract void patchJumpTarget(int branch, int jumpTarget);
 
+    /**
+     * Emits instruction(s) that access an address specified by a given displacement from the stack pointer
+     * in the direction that the stack grows (which is down on most architectures).
+     *
+     * @param disp the displacement from the stack pointer at which the stack should be accessed
+     */
+    public abstract void bangStack(int disp);
+
     protected final void emitByte(int x) {
         codeBuffer.emitByte(x);
     }
--- a/graal/com.oracle.max.asm/src/com/oracle/max/asm/target/amd64/AMD64Assembler.java	Wed Apr 11 15:38:00 2012 +0200
+++ b/graal/com.oracle.max.asm/src/com/oracle/max/asm/target/amd64/AMD64Assembler.java	Thu Apr 12 15:58:05 2012 +0200
@@ -2985,4 +2985,9 @@
     public void fstp(int i) {
         emitx87(0xDD, 0xD8, i);
     }
+
+    @Override
+    public void bangStack(int disp) {
+        movq(new CiAddress(target.wordKind, AMD64.RSP, -disp), AMD64.rax);
+    }
 }
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/CiXirAssembler.java	Wed Apr 11 15:38:00 2012 +0200
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/CiXirAssembler.java	Thu Apr 12 15:58:05 2012 +0200
@@ -553,26 +553,6 @@
          */
         Safepoint,
         /**
-         * Align the code following this instruction to a multiple of (int)extra.
-         */
-        Align,
-        /**
-         * Creates the stack banging overflow check.
-         */
-        StackOverflowCheck,
-        /**
-         * Creates the stack frame for the method and spills callee-save registers (if any) to the {@linkplain CiRegisterSaveArea register save area}.
-         */
-        PushFrame,
-        /**
-         * Restores all callee-save registers (if any) and removes the stack frame of the method.
-         */
-        PopFrame,
-        /**
-         * Inserts an array of bytes directly into the code output.
-         */
-        RawBytes,
-        /**
          * Pushes a value onto the stack.
          */
         Push,
@@ -769,27 +749,6 @@
         append(new XirInstruction(CiKind.Void, null, Safepoint, null));
     }
 
-    public void align(int multiple) {
-        assert multiple > 0;
-        append(new XirInstruction(CiKind.Void, multiple, Align, null));
-    }
-
-    public void stackOverflowCheck() {
-        append(new XirInstruction(CiKind.Void, null, StackOverflowCheck, null));
-    }
-
-    public void pushFrame() {
-        append(new XirInstruction(CiKind.Void, null, PushFrame, null));
-    }
-
-    public void popFrame() {
-        append(new XirInstruction(CiKind.Void, null, PopFrame, null));
-    }
-
-    public void rawBytes(byte[] bytes) {
-        append(new XirInstruction(CiKind.Void, bytes, RawBytes, null));
-    }
-
     public void push(XirOperand value) {
         append(new XirInstruction(CiKind.Void, Push, VOID, value));
     }
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/RiXirGenerator.java	Wed Apr 11 15:38:00 2012 +0200
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/RiXirGenerator.java	Thu Apr 12 15:58:05 2012 +0200
@@ -31,16 +31,6 @@
  */
 public interface RiXirGenerator {
 
-    /**
-     * Note: may return {@code null}.
-     */
-    XirSnippet genPrologue(XirSite site, RiResolvedMethod method);
-
-    /**
-     * Note: may return {@code null} in which case the compiler will not emit a return instruction.
-     */
-    XirSnippet genEpilogue(XirSite site, RiResolvedMethod method);
-
     XirSnippet genSafepointPoll(XirSite site);
 
     XirSnippet genExceptionObject(XirSite site);
--- a/hotspot/.project	Wed Apr 11 15:38:00 2012 +0200
+++ b/hotspot/.project	Thu Apr 12 15:58:05 2012 +0200
@@ -86,11 +86,16 @@
 	</natures>
 	<linkedResources>
 		<link>
-			<name>cpu</name>
+			<name>x86</name>
 			<type>2</type>
 			<locationURI>PARENT-1-PROJECT_LOC/src/cpu/x86</locationURI>
 		</link>
 		<link>
+			<name>sparc</name>
+			<type>2</type>
+			<locationURI>PARENT-1-PROJECT_LOC/src/cpu/sparc</locationURI>
+		</link>
+		<link>
 			<name>generated</name>
 			<type>2</type>
 			<locationURI>PARENT-1-PROJECT_LOC/build/linux/linux_amd64_graal/generated</locationURI>
@@ -101,16 +106,21 @@
 			<locationURI>WORKSPACE_LOC/make</locationURI>
 		</link>
 		<link>
-			<name>os</name>
+			<name>linux</name>
 			<type>2</type>
 			<locationURI>PARENT-1-PROJECT_LOC/src/os/linux</locationURI>
 		</link>
 		<link>
-			<name>os_cpu</name>
+			<name>linux_x86</name>
 			<type>2</type>
 			<locationURI>PARENT-1-PROJECT_LOC/src/os_cpu/linux_x86</locationURI>
 		</link>
 		<link>
+			<name>linux_sparc</name>
+			<type>2</type>
+			<locationURI>PARENT-1-PROJECT_LOC/src/os_cpu/linux_sparc</locationURI>
+		</link>
+		<link>
 			<name>vm</name>
 			<type>2</type>
 			<locationURI>PARENT-1-PROJECT_LOC/src/share/vm</locationURI>
--- a/mx/commands.py	Wed Apr 11 15:38:00 2012 +0200
+++ b/mx/commands.py	Thu Apr 12 15:58:05 2012 +0200
@@ -688,6 +688,7 @@
             return self
              
     parser = ArgumentParser(prog='mx gate');
+    parser.add_argument('-j', '--omit-java-clean', action='store_false', dest='cleanJava', help='omit cleaning Java native code')
     parser.add_argument('-n', '--omit-native-build', action='store_false', dest='buildNative', help='omit cleaning and building native code')
     parser.add_argument('-g', '--only-build-graalvm', action='store_false', dest='buildNonGraal', help='only build the Graal VM')
     parser.add_argument('--jacocout', help='specify the output directory for jacoco report')
@@ -699,7 +700,12 @@
     try:
         
         t = Task('Clean')
-        clean([] if args.buildNative else ['--no-native'])
+        cleanArgs = []
+        if not args.buildNative:
+            cleanArgs.append('--no-native')
+        if not args.cleanJava:
+            cleanArgs.append('--no-java')
+        clean(cleanArgs)
         tasks.append(t.stop())
         
         t = Task('BuildJava')