changeset 8142:d413770c6dd0

Merge.
author Roland Schatz <roland.schatz@oracle.com>
date Thu, 07 Mar 2013 09:43:25 +0100
parents 73536049fa29 (current diff) 1446b04e4148 (diff)
children 569b7d482918
files graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DirectCallOp.java
diffstat 32 files changed, 455 insertions(+), 418 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Wed Mar 06 15:20:21 2013 +0100
+++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Thu Mar 07 09:43:25 2013 +0100
@@ -466,4 +466,10 @@
     public void visitSafepointNode(SafepointNode i) {
         throw new InternalError("NYI");
     }
+
+    @Override
+    public void emitUnwind(Value operand) {
+        // TODO Auto-generated method stub
+
+    }
 }
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Wed Mar 06 15:20:21 2013 +0100
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Thu Mar 07 09:43:25 2013 +0100
@@ -368,4 +368,10 @@
         // SPARC: Auto-generated method stub
 
     }
+
+    @Override
+    public void emitUnwind(Value operand) {
+        // TODO Auto-generated method stub
+
+    }
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DirectCallOp.java	Wed Mar 06 15:20:21 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * 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.amd64;
-
-import static com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind.*;
-
-import com.oracle.graal.amd64.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.hotspot.bridge.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.LIRInstruction.Opcode;
-import com.oracle.graal.lir.amd64.*;
-import com.oracle.graal.lir.amd64.AMD64Call.DirectCallOp;
-import com.oracle.graal.lir.asm.*;
-import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
-
-/**
- * A direct call that complies with the conventions for such calls in HotSpot. In particular, for
- * calls using an inline cache, a MOVE instruction is emitted just prior to the aligned direct call.
- * This instruction (which moves 0L in RAX) is patched by the C++ Graal code to replace the 0L
- * constant with Universe::non_oop_word(), a special sentinel used for the initial value of the
- * Klass in an inline cache.
- */
-@Opcode("CALL_DIRECT")
-final class AMD64DirectCallOp extends DirectCallOp {
-
-    private final InvokeKind invokeKind;
-
-    AMD64DirectCallOp(InvokeTarget target, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind) {
-        super(target, result, parameters, temps, state);
-        this.invokeKind = invokeKind;
-        assert invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual;
-    }
-
-    @Override
-    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-        // The mark for an invocation that uses an inline cache must be placed at the
-        // instruction
-        // that loads the Klass from the inline cache so that the C++ code can find it
-        // and replace the inline 0L value with Universe::non_oop_word()
-        tasm.recordMark(invokeKind == Virtual ? Marks.MARK_INVOKEVIRTUAL : Marks.MARK_INVOKEINTERFACE);
-        AMD64Move.move(tasm, masm, AMD64.rax.asValue(Kind.Long), Constant.LONG_0);
-        emitAlignmentForDirectCall(tasm, masm);
-        AMD64Call.directCall(tasm, masm, callTarget, state);
-    }
-}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Wed Mar 06 15:20:21 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Thu Mar 07 09:43:25 2013 +0100
@@ -50,6 +50,7 @@
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
 import com.oracle.graal.phases.*;
 
 /**
@@ -154,7 +155,15 @@
 
         @Override
         protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
-            append(new AMD64DirectCallOp(callTarget.target(), result, parameters, temps, callState, ((HotSpotDirectCallTargetNode) callTarget).invokeKind()));
+            InvokeKind invokeKind = ((HotSpotDirectCallTargetNode) callTarget).invokeKind();
+            if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) {
+                append(new AMD64HotspotDirectVirtualCallOp(callTarget.target(), result, parameters, temps, callState, invokeKind));
+            } else {
+                assert invokeKind == InvokeKind.Static || invokeKind == InvokeKind.Special;
+                HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) callTarget.target();
+                Constant metaspaceMethod = resolvedMethod.getMetaspaceMethodConstant();
+                append(new AMD64HotspotDirectStaticCallOp(callTarget.target(), result, parameters, temps, callState, invokeKind, metaspaceMethod));
+            }
         }
 
         @Override
@@ -165,6 +174,13 @@
             emitMove(targetAddress, operand(callTarget.computedAddress()));
             append(new AMD64IndirectCallOp(callTarget.target(), result, parameters, temps, metaspaceMethod, targetAddress, callState));
         }
+
+        @Override
+        public void emitUnwind(Value exception) {
+            RegisterValue exceptionParameter = AMD64.rax.asValue();
+            emitMove(exceptionParameter, exception);
+            append(new AMD64HotSpotUnwindOp(exceptionParameter));
+        }
     }
 
     /**
@@ -203,7 +219,6 @@
             AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm;
             emitStackOverflowCheck(tasm, 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;
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java	Wed Mar 06 15:20:21 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java	Thu Mar 07 09:43:25 2013 +0100
@@ -37,9 +37,8 @@
 // @formatter:off
 public class AMD64HotSpotRegisterConfig implements RegisterConfig {
 
-    // be careful - the contents of this array are duplicated in graal_CodeInstaller.cpp
     private final Register[] allocatable = {
-        rax, rbx, rcx, rdx, rsi, rdi, r8, r9, /* r10, */r11, r12, r13, r14, /*r15*/
+        rax, rbx, rcx, rdx, /*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
     };
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Wed Mar 06 15:20:21 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Thu Mar 07 09:43:25 2013 +0100
@@ -54,6 +54,10 @@
         Kind word = graalRuntime.getTarget().wordKind;
 
         // @formatter:off
+        addRuntimeCall(AMD64HotSpotUnwindOp.UNWIND_EXCEPTION, config.unwindExceptionStub,
+                        /*           temps */ null,
+                        /*             ret */ ret(Kind.Void),
+                        /* arg0: exception */ javaCallingConvention(Kind.Object));
 
         addRuntimeCall(DEOPTIMIZE, config.deoptimizeStub,
                 /*           temps */ null,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java	Thu Mar 07 09:43:25 2013 +0100
@@ -0,0 +1,64 @@
+/*
+ * 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.amd64;
+
+import static com.oracle.graal.amd64.AMD64.*;
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+
+import com.oracle.graal.amd64.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.RuntimeCallTarget.*;
+import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.lir.LIRInstruction.Opcode;
+import com.oracle.graal.lir.amd64.*;
+import com.oracle.graal.lir.asm.*;
+
+/**
+ * Performs an unwind to throw an exception.
+ */
+@Opcode("CALL_INDIRECT")
+final class AMD64HotSpotUnwindOp extends AMD64LIRInstruction {
+
+    public static final Descriptor UNWIND_EXCEPTION = new Descriptor("unwindException", true, void.class, Object.class);
+
+    /**
+     * Vtable stubs expect the metaspace Method in RBX.
+     */
+    public static final Register METHOD = AMD64.rbx;
+
+    @Use({REG}) protected AllocatableValue exception;
+    @Temp private RegisterValue framePointer;
+
+    AMD64HotSpotUnwindOp(AllocatableValue exception) {
+        this.exception = exception;
+        assert exception == AMD64.rax.asValue();
+        framePointer = AMD64.rbp.asValue();
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        masm.movq(framePointer.getRegister(), rsp);
+        masm.incrementq(framePointer.getRegister(), tasm.frameMap.frameSize() - 8);
+        AMD64Call.directCall(tasm, masm, tasm.runtime.lookupRuntimeCall(UNWIND_EXCEPTION), null);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectStaticCallOp.java	Thu Mar 07 09:43:25 2013 +0100
@@ -0,0 +1,67 @@
+/*
+ * 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.amd64;
+
+import com.oracle.graal.amd64.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.hotspot.bridge.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.LIRInstruction.Opcode;
+import com.oracle.graal.lir.amd64.*;
+import com.oracle.graal.lir.amd64.AMD64Call.DirectCallOp;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
+
+/**
+ * A direct call that complies with the conventions for such calls in HotSpot. In particular, for
+ * calls using an inline cache, a MOVE instruction is emitted just prior to the aligned direct call.
+ * This instruction (which moves 0L in RAX) is patched by the C++ Graal code to replace the 0L
+ * constant with Universe::non_oop_word(), a special sentinel used for the initial value of the
+ * Klass in an inline cache. It puts the called method into rbx before calling.
+ */
+@Opcode("CALL_DIRECT")
+final class AMD64HotspotDirectStaticCallOp extends DirectCallOp {
+
+    private final Constant metaspaceMethod;
+    private final InvokeKind invokeKind;
+
+    AMD64HotspotDirectStaticCallOp(InvokeTarget target, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind, Constant metaspaceMethod) {
+        super(target, result, parameters, temps, state);
+        assert invokeKind == InvokeKind.Static || invokeKind == InvokeKind.Special;
+        this.metaspaceMethod = metaspaceMethod;
+        this.invokeKind = invokeKind;
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        // The mark for an invocation that uses an inline cache must be placed at the
+        // instruction
+        // that loads the Klass from the inline cache so that the C++ code can find it
+        // and replace the inline 0L value with Universe::non_oop_word()
+        AMD64Move.move(tasm, masm, AMD64.rbx.asValue(Kind.Long), metaspaceMethod);
+        tasm.recordMark(invokeKind == InvokeKind.Static ? Marks.MARK_INVOKESTATIC : Marks.MARK_INVOKESPECIAL);
+        AMD64Move.move(tasm, masm, AMD64.rax.asValue(Kind.Long), Constant.LONG_0);
+        super.emitCode(tasm, masm);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectVirtualCallOp.java	Thu Mar 07 09:43:25 2013 +0100
@@ -0,0 +1,66 @@
+/*
+ * 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.amd64;
+
+import static com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind.*;
+
+import com.oracle.graal.amd64.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.hotspot.bridge.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.LIRInstruction.Opcode;
+import com.oracle.graal.lir.amd64.*;
+import com.oracle.graal.lir.amd64.AMD64Call.DirectCallOp;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
+
+/**
+ * A direct call that complies with the conventions for such calls in HotSpot. In particular, for
+ * calls using an inline cache, a MOVE instruction is emitted just prior to the aligned direct call.
+ * This instruction (which moves 0L in RAX) is patched by the C++ Graal code to replace the 0L
+ * constant with Universe::non_oop_word(), a special sentinel used for the initial value of the
+ * Klass in an inline cache.
+ */
+@Opcode("CALL_DIRECT")
+final class AMD64HotspotDirectVirtualCallOp extends DirectCallOp {
+
+    private final InvokeKind invokeKind;
+
+    AMD64HotspotDirectVirtualCallOp(InvokeTarget target, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind) {
+        super(target, result, parameters, temps, state);
+        this.invokeKind = invokeKind;
+        assert invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual;
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        // The mark for an invocation that uses an inline cache must be placed at the
+        // instruction
+        // that loads the Klass from the inline cache so that the C++ code can find it
+        // and replace the inline 0L value with Universe::non_oop_word()
+        tasm.recordMark(invokeKind == Virtual ? Marks.MARK_INVOKEVIRTUAL : Marks.MARK_INVOKEINTERFACE);
+        AMD64Move.move(tasm, masm, AMD64.rax.asValue(Kind.Long), Constant.LONG_0);
+        super.emitCode(tasm, masm);
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Wed Mar 06 15:20:21 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Thu Mar 07 09:43:25 2013 +0100
@@ -304,7 +304,6 @@
     public int typeProfileWidth;
 
     // runtime stubs
-    public long instanceofStub;
     public long newInstanceStub;
     public long newArrayStub;
     public long newMultiArrayStub;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/Marks.java	Wed Mar 06 15:20:21 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/Marks.java	Thu Mar 07 09:43:25 2013 +0100
@@ -36,9 +36,11 @@
     int MARK_DEOPT_HANDLER_ENTRY = 5;
     int MARK_INVOKEINTERFACE = 6;
     int MARK_INVOKEVIRTUAL = 7;
-    int MARK_INLINE_INVOKE = 8;
-    int MARK_POLL_NEAR = 9;
-    int MARK_POLL_RETURN_NEAR = 10;
-    int MARK_POLL_FAR = 11;
-    int MARK_POLL_RETURN_FAR = 12;
+    int MARK_INVOKESTATIC = 8;
+    int MARK_INVOKESPECIAL = 9;
+    int MARK_INLINE_INVOKE = 10;
+    int MARK_POLL_NEAR = 11;
+    int MARK_POLL_RETURN_NEAR = 12;
+    int MARK_POLL_FAR = 13;
+    int MARK_POLL_RETURN_FAR = 14;
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Wed Mar 06 15:20:21 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Thu Mar 07 09:43:25 2013 +0100
@@ -32,7 +32,6 @@
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.hotspot.snippets.SystemSubstitutions.*;
 import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*;
-import static com.oracle.graal.nodes.UnwindNode.*;
 import static com.oracle.graal.nodes.java.RegisterFinalizerNode.*;
 import static com.oracle.graal.snippets.Log.*;
 import static com.oracle.graal.snippets.MathSubstitutionsX86.*;
@@ -204,11 +203,6 @@
 
         // @formatter:off
 
-        addRuntimeCall(UNWIND_EXCEPTION, config.unwindExceptionStub,
-                        /*           temps */ null,
-                        /*             ret */ ret(Kind.Void),
-                        /* arg0: exception */ javaCallingConvention(Kind.Object));
-
         addRuntimeCall(OnStackReplacementPhase.OSR_MIGRATION_END, config.osrMigrationEndStub,
                         /*           temps */ null,
                         /*             ret */ ret(Kind.Void),
@@ -571,13 +565,8 @@
                         }
                     }
                 } else if (callTarget.invokeKind() == InvokeKind.Special || callTarget.invokeKind() == InvokeKind.Static) {
-                    HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) callTarget.targetMethod();
-                    ConstantNode metaspaceMethod = ConstantNode.forConstant(hsMethod.getMetaspaceMethodConstant(), this, graph);
-                    ReadNode compiledEntry = graph.add(new ReadNode(metaspaceMethod, LocationNode.create(LocationNode.ANY_LOCATION, wordKind, config.methodCompiledEntryOffset, graph),
-                                    StampFactory.forKind(wordKind())));
-                    loweredCallTarget = graph.add(new HotSpotIndirectCallTargetNode(metaspaceMethod, compiledEntry, parameters, invoke.node().stamp(), signature, callTarget.targetMethod(),
-                                    CallingConvention.Type.JavaCall));
-                    graph.addBeforeFixed(invoke.node(), compiledEntry);
+                    loweredCallTarget = graph.add(new HotSpotDirectCallTargetNode(parameters, invoke.node().stamp(), signature, callTarget.targetMethod(), CallingConvention.Type.JavaCall,
+                                    callTarget.invokeKind()));
                 }
 
                 if (loweredCallTarget == null) {
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java	Wed Mar 06 15:20:21 2013 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java	Thu Mar 07 09:43:25 2013 +0100
@@ -159,7 +159,7 @@
         @Opcode private final AMD64Arithmetic opcode;
         @Def({REG, HINT}) protected AllocatableValue result;
         @Use({REG, STACK}) protected AllocatableValue x;
-        @Use({CONST}) protected Constant y;
+        protected Constant y;
 
         public BinaryRegConst(AMD64Arithmetic opcode, AllocatableValue result, AllocatableValue x, Constant y) {
             this.opcode = opcode;
@@ -221,7 +221,7 @@
         @Opcode private final AMD64Arithmetic opcode;
         @Def({REG}) protected AllocatableValue result;
         @Use({REG, STACK}) protected AllocatableValue x;
-        @Use({CONST}) protected Constant y;
+        protected Constant y;
 
         public BinaryRegStackConst(AMD64Arithmetic opcode, AllocatableValue result, AllocatableValue x, Constant y) {
             this.opcode = opcode;
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Wed Mar 06 15:20:21 2013 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Thu Mar 07 09:43:25 2013 +0100
@@ -230,7 +230,7 @@
 
     public static class StoreConstantOp extends MemOp {
 
-        @Use({CONST}) protected Constant input;
+        protected final Constant input;
 
         public StoreConstantOp(AMD64Address address, Constant input, LIRFrameState state) {
             super(address, state);
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java	Wed Mar 06 15:20:21 2013 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java	Thu Mar 07 09:43:25 2013 +0100
@@ -58,6 +58,7 @@
 
     private static final Class<?> INSTRUCTION_CLASS = LIRInstruction.class;
     private static final Class<?> VALUE_CLASS = Value.class;
+    private static final Class<?> CONSTANT_CLASS = Constant.class;
     private static final Class<?> VALUE_ARRAY_CLASS = Value[].class;
     private static final Class<?> STATE_CLASS = LIRFrameState.class;
 
@@ -219,7 +220,7 @@
 
         @Override
         protected void scanField(Field field, Class<?> type, long offset) {
-            if (VALUE_CLASS.isAssignableFrom(type)) {
+            if (VALUE_CLASS.isAssignableFrom(type) && type != CONSTANT_CLASS) {
                 assert !Modifier.isFinal(field.getModifiers()) : "Value field must not be declared final because it is modified by register allocator: " + field;
                 OperandModeAnnotation annotation = getOperandModeAnnotation(field);
                 assert annotation != null : "Field must have operand mode annotation: " + field;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnwindNode.java	Wed Mar 06 15:20:21 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnwindNode.java	Thu Mar 07 09:43:25 2013 +0100
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.nodes;
 
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.spi.*;
@@ -35,8 +33,6 @@
  */
 public final class UnwindNode extends FixedNode implements LIRLowerable, Node.IterableNodeType {
 
-    public static final Descriptor UNWIND_EXCEPTION = new Descriptor("unwindException", true, void.class, Object.class);
-
     @Input private ValueNode exception;
 
     public ValueNode exception() {
@@ -51,7 +47,6 @@
 
     @Override
     public void generate(LIRGeneratorTool gen) {
-        RuntimeCallTarget call = gen.getRuntime().lookupRuntimeCall(UNWIND_EXCEPTION);
-        gen.emitCall(call, call.getCallingConvention(), false, gen.operand(exception()));
+        gen.emitUnwind(gen.operand(exception()));
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java	Wed Mar 06 15:20:21 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java	Thu Mar 07 09:43:25 2013 +0100
@@ -132,4 +132,6 @@
     public abstract void visitSafepointNode(SafepointNode i);
 
     public abstract void visitBreakpointNode(BreakpointNode i);
+
+    public abstract void emitUnwind(Value operand);
 }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Wed Mar 06 15:20:21 2013 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Thu Mar 07 09:43:25 2013 +0100
@@ -164,7 +164,7 @@
     public static boolean GenAssertionCode                   = ____;
     public static boolean AlignCallsForPatching              = true;
     public static boolean ResolveClassBeforeStaticInvoke     = ____;
-    public static boolean CanOmitFrame                       = true;
+    public static boolean CanOmitFrame                       = false;
     public static int     SafepointPollOffset                = 256;
 
     public static boolean MemoryAwareScheduling              = true;
--- a/mx/commands.py	Wed Mar 06 15:20:21 2013 +0100
+++ b/mx/commands.py	Thu Mar 07 09:43:25 2013 +0100
@@ -373,8 +373,20 @@
     else:
         if not exists(jdk):
             mx.abort('The ' + build + ' VM has not been created - run \'mx clean; mx build ' + build + '\'')
+            
+    _installGraalJarInJdks(mx.distribution('GRAAL'))
+    
     return jdk
 
+def _installGraalJarInJdks(graalDist):
+    graalJar = graalDist.path
+    jdks = join(_graal_home, 'jdk' + str(mx.java().version))
+    if exists(jdks):
+        for e in os.listdir(jdks):
+            jreLibDir = join(jdks, e, 'jre', 'lib')
+            if exists(jreLibDir):
+                shutil.copyfile(graalJar, join(jreLibDir, 'graal.jar'))
+
 # run a command in the windows SDK Debug Shell
 def _runInDebugShell(cmd, workingDir, logFile=None, findInOutput=None, respondTo={}):
     newLine = os.linesep
@@ -488,25 +500,6 @@
             if not 'Xusage.txt' in line:
                 sys.stderr.write(line + os.linesep)
 
-        # Check that the declaration of graal_projects in arguments.cpp is up to date
-        argumentsCpp = join(_graal_home, 'src', 'share', 'vm', 'runtime', 'arguments.cpp')
-        assert exists(argumentsCpp), 'File does not exist: ' + argumentsCpp
-        with open(argumentsCpp) as fp:
-            source = fp.read();
-            decl = 'const char* graal_projects[] = {'
-            start = source.find(decl)
-            assert start != -1, 'Could not find "' + decl + '" in ' + fp.name
-            end = source.find('};', start)
-            assert end != -1, 'Could not find "' + decl + '" ... "};" in ' + fp.name
-            actual = frozenset(re.findall(r'"([^"]+)"', source[start + len(decl):end]))
-            expected = frozenset([p.name for p in mx.project('com.oracle.graal.hotspot.' + _arch()).all_deps([], False)])
-            missing = expected - actual
-            extra = actual - expected
-            if len(missing) != 0:
-                mx.abort(fp.name + ':' + str(source[:start].count('\n') + 1) + ': add missing project(s) to declaration:\n    ' + '\n    '.join(missing))
-            if len(extra) != 0:
-                mx.abort(fp.name + ':' + str(source[:start].count('\n') + 1) + ': remove project(s) from declaration:\n    ' + '\n    '.join(extra))
-
         # Check if a build really needs to be done
         timestampFile = join(vmDir, '.build-timestamp')
         if opts2.force or not exists(timestampFile):
@@ -656,6 +649,7 @@
         args = ['-javaagent:' + jacocoagent.get_path(True) + '=' + ','.join([k + '=' + v for k, v in agentOptions.items()])] + args
     if '-d64' not in args:
         args = ['-d64'] + args
+
     exe = join(jdk, 'bin', mx.exe_suffix('java'))
     dbg = _native_dbg.split() if _native_dbg is not None else []
     return mx.run(dbg + [exe, '-' + vm] + args, nonZeroIsFatal=nonZeroIsFatal, out=out, err=err, cwd=cwd, timeout=timeout)
@@ -1173,3 +1167,5 @@
     _jacoco = opts.jacoco
     global _native_dbg
     _native_dbg = opts.native_dbg
+
+    mx.distribution('GRAAL').add_update_listener(_installGraalJarInJdks)
--- a/mx/projects	Wed Mar 06 15:20:21 2013 +0100
+++ b/mx/projects	Thu Mar 07 09:43:25 2013 +0100
@@ -22,6 +22,9 @@
 library@DACAPO_SCALA@path=lib/dacapo-scala-0.1.0-20120216.jar
 library@DACAPO_SCALA@urls=http://repo.scalabench.org/snapshots/org/scalabench/benchmarks/scala-benchmark-suite/0.1.0-SNAPSHOT/scala-benchmark-suite-0.1.0-20120216.103539-3.jar
 
+distribution@GRAAL@path=graal.jar
+distribution@GRAAL@dependencies=com.oracle.graal.hotspot.amd64,com.oracle.graal.hotspot.sparc
+
 # graal.api.runtime
 project@com.oracle.graal.api.runtime@subDir=graal
 project@com.oracle.graal.api.runtime@sourceDirs=src
--- a/mxtool/mx.py	Wed Mar 06 15:20:21 2013 +0100
+++ b/mxtool/mx.py	Thu Mar 07 09:43:25 2013 +0100
@@ -143,12 +143,36 @@
 
 _projects = dict()
 _libs = dict()
+_dists = dict()
 _suites = dict()
 _mainSuite = None
 _opts = None
 _java = None
 
 """
+A distribution is a jar or zip file containing the output from one or more Java projects.
+"""
+class Distribution:
+    def __init__(self, suite, name, path, deps):
+        self.suite = suite
+        self.name = name
+        self.path = path.replace('/', os.sep)
+        if not isabs(self.path):
+            self.path = join(suite.dir, self.path)
+        self.deps = deps
+        self.update_listeners = set()
+        
+    def __str__(self):
+        return self.name
+    
+    def add_update_listener(self, listener):
+        self.update_listeners.add(listener)
+        
+    def notify_updated(self):
+        for l in self.update_listeners:
+            l(self)
+    
+"""
 A dependency is a library or project specified in a suite.
 """
 class Dependency:
@@ -416,6 +440,7 @@
         self.dir = d
         self.projects = []
         self.libs = []
+        self.dists = []
         self.includes = []
         self.commands = None
         self.primary = primary
@@ -427,6 +452,7 @@
     def _load_projects(self, mxDir):
         libsMap = dict()
         projsMap = dict()
+        distsMap = dict()
         projectsFile = join(mxDir, 'projects')
         if not exists(projectsFile):
             return
@@ -447,8 +473,10 @@
                         m = projsMap
                     elif kind == 'library':
                         m = libsMap
+                    elif kind == 'distribution':
+                        m = distsMap
                     else:
-                        abort('Property name does not start with "project@" or "library@": ' + key)
+                        abort('Property name does not start with "project@", "library@" or "distribution@": ' + key)
 
                     attrs = m.get(name)
                     if attrs is None:
@@ -494,6 +522,13 @@
             l.__dict__.update(attrs)
             self.libs.append(l)
 
+        for name, attrs in distsMap.iteritems():
+            path = attrs.pop('path')
+            deps = pop_list(attrs, 'dependencies')
+            d = Distribution(self, name, path, deps)
+            d.__dict__.update(attrs)
+            self.dists.append(d)
+
     def _load_commands(self, mxDir):
         commands = join(mxDir, 'commands.py')
         if exists(commands):
@@ -536,8 +571,6 @@
     def _post_init(self, opts):
         mxDir = join(self.dir, 'mx')
         self._load_projects(mxDir)
-        if hasattr(self, 'mx_post_parse_cmd_line'):
-            self.mx_post_parse_cmd_line(opts)
         for p in self.projects:
             existing = _projects.get(p.name)
             if existing is not None:
@@ -549,6 +582,13 @@
             if existing is not None:
                 abort('cannot redefine library  ' + l.name)
             _libs[l.name] = l
+        for d in self.dists:
+            existing = _dists.get(l.name)
+            if existing is not None:
+                abort('cannot redefine distribution  ' + d.name)
+            _dists[d.name] = d
+        if hasattr(self, 'mx_post_parse_cmd_line'):
+            self.mx_post_parse_cmd_line(opts)
 
 class XMLElement(xml.dom.minidom.Element):
     def writexml(self, writer, indent="", addindent="", newl=""):
@@ -653,6 +693,16 @@
     """
     return _projects.values()
 
+def distribution(name, fatalIfMissing=True):
+    """
+    Get the distribution for a given name. This will abort if the named distribution does
+    not exist and 'fatalIfMissing' is true.
+    """
+    d = _dists.get(name)
+    if d is None and fatalIfMissing:
+        abort('distribution named ' + name + ' not found')
+    return d
+
 def project(name, fatalIfMissing=True):
     """
     Get the project for a given name. This will abort if the named project does
@@ -1477,6 +1527,9 @@
         finally:
             for n in toBeDeleted:
                 os.remove(n)
+                
+    for dist in _dists.values():
+        archive(['@' + dist.name])
 
     if suppliedParser:
         return args
@@ -1578,7 +1631,7 @@
     projects = set()
     
     for p in sorted_deps():
-        if _needsEclipseJarBuild(p):
+        if _isAnnotationProcessorDependency(p):
             projects.add(p)
             
     if len(projects) <= 0:
@@ -1586,37 +1639,40 @@
     
     pnames = [p.name for p in projects]
     build(['--projects', ",".join(pnames)])
-    jarprojects(pnames)
-
-def jarprojects(args):
-    """create jar files for the output of one or more projects"""
-    parser = ArgumentParser(prog='mx jar');
-    parser.add_argument('-d', '--dest', help='single jar file to create')
-    parser.add_argument('projects', nargs=REMAINDER, metavar='projects...')
+    archive(pnames)
+
+def archive(args):
+    """create jar files for projects and distributions"""
+    parser = ArgumentParser(prog='mx archive');
+    parser.add_argument('names', nargs=REMAINDER, metavar='[<project>|@<distribution>]...')
     args = parser.parse_args(args)
     
-    if not args.projects:
-        args.projects = [p.name for p in projects()]
-
-    if args.dest is not None:
-        zf = zipfile.ZipFile(args.dest, 'w')
-    
-    for pname in args.projects:
-        p = project(pname, fatalIfMissing=True)
-        if args.dest is None:
+    for name in args.names:
+        if name.startswith('@'):
+            dname = name[1:]
+            d = distribution(dname)
+            zf = zipfile.ZipFile(d.path, 'w')
+            for p in sorted_deps(d.deps):
+                outputDir = p.output_dir()
+                for root, _, files in os.walk(outputDir):
+                    for f in files:
+                        relpath = root[len(outputDir) + 1:]
+                        arcname = join(relpath, f).replace(os.sep, '/')
+                        zf.write(join(root, f), arcname)
+            zf.close()
+            d.notify_updated()
+
+        else:
+            p = project(name)
+            outputDir = p.output_dir()
             jar = join(p.dir, p.name + '.jar')
             zf = zipfile.ZipFile(jar, 'w')
-        outputDir = p.output_dir()
-        for root, _, files in os.walk(outputDir):
-            for f in files:
-                relpath = root[len(outputDir) + 1:]
-                arcname = join(relpath, f).replace(os.sep, '/')
-                zf.write(join(root, f), arcname)
-        if args.dest is None:
+            for root, _, files in os.walk(outputDir):
+                for f in files:
+                    relpath = root[len(outputDir) + 1:]
+                    arcname = join(relpath, f).replace(os.sep, '/')
+                    zf.write(join(root, f), arcname)
             zf.close()
-            
-    if args.dest is not None:
-        zf.close()
 
 def canonicalizeprojects(args):
     """process all project files to canonicalize the dependencies
@@ -1996,6 +2052,12 @@
     if buildProcessorJars:
         processorjars()
 
+    projToDist = dict()
+    for dist in _dists.values():
+        distDeps = sorted_deps(dist.deps)
+        for p in distDeps:
+            projToDist[p.name] = (dist, [dep.name for dep in distDeps])
+
     for p in projects():
         if p.native:
             continue
@@ -2110,24 +2172,14 @@
                 out.element('arguments', data='')
                 out.close('buildCommand')
 
-        if (_needsEclipseJarBuild(p)):
-            targetValues = _genEclipseJarBuild(p);
-            for value in targetValues:
-                out.open('buildCommand')
-                out.element('name', data='org.eclipse.ui.externaltools.ExternalToolBuilder')
-                out.element('triggers', data='auto,full,incremental,')
-                out.open('arguments')
-                out.open('dictionary')
-                out.element('key', data = 'LaunchConfigHandle')
-                out.element('value', data = value)
-                out.close('dictionary')
-                out.open('dictionary')
-                out.element('key', data = 'incclean')
-                out.element('value', data = 'true')
-                out.close('dictionary')
-                out.close('arguments')
-                out.close('buildCommand')       
-                    
+        if _isAnnotationProcessorDependency(p):
+            _genEclipseBuilder(out, p, 'Jar.launch', 'archive ' + p.name, refresh = False, async = False)
+            _genEclipseBuilder(out, p, 'Refresh.launch', '', refresh = True, async = True)
+                       
+        if projToDist.has_key(p.name):
+            dist, distDeps = projToDist[p.name]
+            _genEclipseBuilder(out, p, 'Create' + dist.name + 'Dist.launch', 'archive @' + dist.name, refresh=False, async=True)
+        
         out.close('buildSpec')
         out.open('natures')
         out.element('nature', data='org.eclipse.jdt.core.javanature')
@@ -2182,8 +2234,11 @@
     make_eclipse_attach('localhost', '8000', deps=projects())
 
 
-def _needsEclipseJarBuild(p):
-    processors = set([])
+def _isAnnotationProcessorDependency(p):
+    """
+    Determines if a given project is part of an annotation processor.
+    """
+    processors = set()
     
     for otherProject in projects():
         if hasattr(otherProject, 'annotationProcessors') and len(otherProject.annotationProcessors) > 0:
@@ -2200,13 +2255,7 @@
     
     return False
 
-def _genEclipseJarBuild(p):
-    builders = []
-    builders.append(_genEclipseLaunch(p, 'Jar.launch', ''.join(['jarprojects ', p.name]), refresh = False, async = False))
-    builders.append(_genEclipseLaunch(p, 'Refresh.launch', '', refresh = True, async = True))
-    return builders
-
-def _genEclipseLaunch(p, name, mxCommand, refresh=True, async=False):
+def _genEclipseBuilder(dotProjectDoc, p, name, mxCommand, refresh=True, async=False):
     launchOut = XMLDoc();
     launchOut.open('launchConfiguration', {'type' : 'org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType'})
     if refresh:
@@ -2236,9 +2285,21 @@
         os.makedirs(externalToolDir)
     update_file(join(externalToolDir, name), launchOut.xml(indent='\t', newl='\n'))
     
-    return ''.join(["<project>/.externalToolBuilders/", name])
-
-
+    dotProjectDoc.open('buildCommand')
+    dotProjectDoc.element('name', data='org.eclipse.ui.externaltools.ExternalToolBuilder')
+    dotProjectDoc.element('triggers', data='auto,full,incremental,')
+    dotProjectDoc.open('arguments')
+    dotProjectDoc.open('dictionary')
+    dotProjectDoc.element('key', data = 'LaunchConfigHandle')
+    dotProjectDoc.element('value', data = '<project>/.externalToolBuilders/' + name)
+    dotProjectDoc.close('dictionary')
+    dotProjectDoc.open('dictionary')
+    dotProjectDoc.element('key', data = 'incclean')
+    dotProjectDoc.element('value', data = 'true')
+    dotProjectDoc.close('dictionary')
+    dotProjectDoc.close('arguments')
+    dotProjectDoc.close('buildCommand')
+    
 def netbeansinit(args, suite=None):
     """(re)generate NetBeans project configurations"""
 
@@ -2496,8 +2557,7 @@
                 projectConfigFiles = frozenset(['.classpath', 'nbproject'])
                 indicators = projectConfigFiles.intersection(files)
                 if len(indicators) != 0:
-                    response = raw_input(currentDir + ' looks like a removed project -- delete it? [yn]: ')
-                    if 'y' == response:
+                    if not sys.stdout.isatty() or raw_input(currentDir + ' looks like a removed project -- delete it? [yn]: ') == 'y':
                         shutil.rmtree(currentDir)
                         log('Deleted ' + currentDir)
 
@@ -2956,7 +3016,7 @@
     'help': [help_, '[command]'],
     'ideclean': [ideclean, ''],
     'ideinit': [ideinit, ''],
-    'jarprojects': [jarprojects, '[options]'],
+    'archive': [archive, '[options]'],
     'projectgraph': [projectgraph, ''],
     'javap': [javap, ''],
     'javadoc': [javadoc, '[options]'],
--- a/src/cpu/x86/vm/graalRuntime_x86.cpp	Wed Mar 06 15:20:21 2013 +0100
+++ b/src/cpu/x86/vm/graalRuntime_x86.cpp	Thu Mar 07 09:43:25 2013 +0100
@@ -46,12 +46,6 @@
   assert(!(oop_result1->is_valid() || metadata_result->is_valid()) || oop_result1 != metadata_result, "registers must be different");
   assert(oop_result1 != thread && metadata_result != thread, "registers must be different");
   assert(args_size >= 0, "illegal args_size");
-  bool align_stack = false;
-#ifdef _LP64
-  // At a method handle call, the stack may not be properly aligned
-  // when returning with an exception.
-  align_stack = (stub_id() == false /*GraalRuntime::handle_exception_from_callee_id*/);
-#endif
 
 #ifdef _LP64
   mov(c_rarg0, thread);
@@ -65,20 +59,11 @@
 #endif // _LP64
 
   int call_offset;
-  if (!align_stack) {
-    set_last_Java_frame(thread, noreg, rbp, NULL);
-  } else {
-    address the_pc = pc();
-    call_offset = offset();
-    set_last_Java_frame(thread, noreg, rbp, the_pc);
-    andptr(rsp, -(StackAlignmentInBytes));    // Align stack
-  }
+  set_last_Java_frame(thread, rsp, noreg, NULL);
 
   // do the call
   call(RuntimeAddress(entry));
-  if (!align_stack) {
-    call_offset = offset();
-  }
+  call_offset = offset();
   // verify callee-saved register
 #ifdef ASSERT
   guarantee(thread != rax, "change this code");
@@ -93,7 +78,7 @@
   }
   pop(rax);
 #endif
-  reset_last_Java_frame(thread, true, align_stack);
+  reset_last_Java_frame(thread, true, false);
 
   // discard thread and arguments
   NOT_LP64(addptr(rsp, num_rt_args()*BytesPerWord));
@@ -356,6 +341,7 @@
   map->set_callee_saved(VMRegImpl::stack2reg(rcx_off + num_rt_args), rcx->as_VMReg());
   map->set_callee_saved(VMRegImpl::stack2reg(rdx_off + num_rt_args), rdx->as_VMReg());
   map->set_callee_saved(VMRegImpl::stack2reg(rbx_off + num_rt_args), rbx->as_VMReg());
+  map->set_callee_saved(VMRegImpl::stack2reg(rbp_off + num_rt_args), rbp->as_VMReg());
   map->set_callee_saved(VMRegImpl::stack2reg(rsi_off + num_rt_args), rsi->as_VMReg());
   map->set_callee_saved(VMRegImpl::stack2reg(rdi_off + num_rt_args), rdi->as_VMReg());
 #ifdef _LP64
@@ -373,6 +359,7 @@
   map->set_callee_saved(VMRegImpl::stack2reg(rcxH_off + num_rt_args), rcx->as_VMReg()->next());
   map->set_callee_saved(VMRegImpl::stack2reg(rdxH_off + num_rt_args), rdx->as_VMReg()->next());
   map->set_callee_saved(VMRegImpl::stack2reg(rbxH_off + num_rt_args), rbx->as_VMReg()->next());
+  map->set_callee_saved(VMRegImpl::stack2reg(rbpH_off + num_rt_args), rbp->as_VMReg()->next());
   map->set_callee_saved(VMRegImpl::stack2reg(rsiH_off + num_rt_args), rsi->as_VMReg()->next());
   map->set_callee_saved(VMRegImpl::stack2reg(rdiH_off + num_rt_args), rdi->as_VMReg()->next());
 
@@ -933,69 +920,10 @@
       }
       break;
 
-    case slow_subtype_check_id:
-      {
-        // Typical calling sequence:
-        // __ push(klass_RInfo);  // object klass or other subclass
-        // __ push(sup_k_RInfo);  // array element klass or other superclass
-        // __ call(slow_subtype_check);
-        // Note that the subclass is pushed first, and is therefore deepest.
-        // Previous versions of this code reversed the names 'sub' and 'super'.
-        // This was operationally harmless but made the code unreadable.
-        enum layout {
-          rax_off, SLOT2(raxH_off)
-          rcx_off, SLOT2(rcxH_off)
-          rsi_off, SLOT2(rsiH_off)
-          rdi_off, SLOT2(rdiH_off)
-          // saved_rbp_off, SLOT2(saved_rbpH_off)
-          return_off, SLOT2(returnH_off)
-          sup_k_off, SLOT2(sup_kH_off)
-          klass_off, SLOT2(superH_off)
-          framesize,
-          result_off = klass_off  // deepest argument is also the return value
-        };
-
-        __ set_info("slow_subtype_check", dont_gc_arguments);
-        __ push(rdi);
-        __ push(rsi);
-        __ push(rcx);
-        __ push(rax);
-
-        // This is called by pushing args and not with C abi
-        __ movptr(rsi, Address(rsp, (klass_off) * VMRegImpl::stack_slot_size)); // subclass
-        __ movptr(rax, Address(rsp, (sup_k_off) * VMRegImpl::stack_slot_size)); // superclass
-
-        Label miss;
-        Label success;
-        __ check_klass_subtype_fast_path(rsi, rax, rcx, &success, &miss, NULL);
-
-        __ check_klass_subtype_slow_path(rsi, rax, rcx, rdi, NULL, &miss);
-
-        // fallthrough on success:
-        __ bind(success);
-        __ movptr(Address(rsp, (result_off) * VMRegImpl::stack_slot_size), 1); // result
-        __ pop(rax);
-        __ pop(rcx);
-        __ pop(rsi);
-        __ pop(rdi);
-        __ ret(0);
-
-        __ bind(miss);
-        __ movptr(Address(rsp, (result_off) * VMRegImpl::stack_slot_size), NULL_WORD); // result
-        __ pop(rax);
-        __ pop(rcx);
-        __ pop(rsi);
-        __ pop(rdi);
-        __ ret(0);
-      }
-      break;
-
     case unwind_exception_call_id: {
       // remove the frame from the stack
       __ movptr(rsp, rbp);
       __ pop(rbp);
-      // exception_oop is passed using ordinary java calling conventions
-      __ movptr(rax, j_rarg0);
 
       Label nonNullExceptionOop;
       __ testptr(rax, rax);
--- a/src/share/vm/classfile/classLoader.cpp	Wed Mar 06 15:20:21 2013 +0100
+++ b/src/share/vm/classfile/classLoader.cpp	Thu Mar 07 09:43:25 2013 +0100
@@ -442,20 +442,11 @@
 void ClassLoader::setup_bootstrap_search_path() {
   assert(_first_entry == NULL, "should not setup bootstrap class search path twice");
   char* sys_class_path = os::strdup(Arguments::get_sysclasspath());
-#ifdef GRAAL
-  char* compiler_class_path = os::strdup(Arguments::get_compilerclasspath());
-#endif
   if (TraceClassLoading && Verbose) {
     tty->print_cr("[Bootstrap loader class path=%s]", sys_class_path);
-#ifdef GRAAL
-    tty->print_cr("[Compiler loader class path=%s]", compiler_class_path);
-#endif
   }
 
   setup_bootstrap_search_path(sys_class_path);
-#ifdef GRAAL
-  setup_bootstrap_search_path(compiler_class_path);
-#endif
 }
 
 void ClassLoader::setup_bootstrap_search_path(char* sys_class_path) {
--- a/src/share/vm/code/compiledIC.cpp	Wed Mar 06 15:20:21 2013 +0100
+++ b/src/share/vm/code/compiledIC.cpp	Thu Mar 07 09:43:25 2013 +0100
@@ -95,7 +95,7 @@
   // Don't use ic_destination for this test since that forwards
   // through ICBuffer instead of returning the actual current state of
   // the CompiledIC.
-  if (is_icholder_entry(_ic_call->destination())) {
+  if (is_icholder_entry(_ic_call->destination()) && !_is_optimized) {
     // When patching for the ICStub case the cached value isn't
     // overwritten until the ICStub copied into the CompiledIC during
     // the next safepoint.  Make sure that the CompiledICHolder* is
@@ -126,6 +126,13 @@
   _ic_call->set_destination_mt_safe(entry_point);
 }
 
+#ifdef GRAAL
+  if (_value == NULL) {
+    // Can happen when Graal converted a virtual call into an invoke special based on static analysis.
+    return;
+  }
+#endif
+
   if (is_optimized() || is_icstub) {
     // Optimized call sites don't have a cache value and ICStub call
     // sites only change the entry point.  Changing the value in that
@@ -265,12 +272,14 @@
     // Check if we are calling into our own codeblob (i.e., to a stub)
     CodeBlob* cb = CodeCache::find_blob(_ic_call->instruction_address());
     address dest = ic_destination();
+#ifndef GRAAL
 #ifdef ASSERT
     {
       CodeBlob* db = CodeCache::find_blob_unsafe(dest);
       assert(!db->is_adapter_blob(), "must use stub!");
     }
 #endif /* ASSERT */
+#endif
     is_call_to_interpreted = cb->contains(dest);
   }
   return is_call_to_interpreted;
@@ -551,7 +560,13 @@
 
 
 void CompiledStaticCall::set_to_interpreted(methodHandle callee, address entry) {
+  set_destination_mt_safe(entry);
   address stub=find_stub();
+#ifdef GRAAL
+  if (stub == NULL) {
+    return;
+  }
+#endif
   assert(stub!=NULL, "stub not found");
 
   if (TraceICs) {
@@ -646,7 +661,11 @@
         case relocInfo::poll_type:
         case relocInfo::poll_return_type: // A safepoint can't overlap a call.
         default:
+#ifdef GRAAL
+          return NULL;
+#else
           ShouldNotReachHere();
+#endif
       }
     }
   }
@@ -702,9 +721,11 @@
 
   // Verify stub
   address stub = find_stub();
+#ifndef GRAAL
   assert(stub != NULL, "no stub found for static call");
   NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);   // creation also verifies the object
   NativeJump*        jump          = nativeJump_at(method_holder->next_instruction_address());
+#endif
 
   // Verify state
   assert(is_clean() || is_call_to_compiled() || is_call_to_interpreted(), "sanity check");
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Wed Mar 06 15:20:21 2013 +0100
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Thu Mar 07 09:43:25 2013 +0100
@@ -699,6 +699,21 @@
         _instructions->relocate(call->instruction_address(), virtual_call_Relocation::spec(_invoke_mark_pc), Assembler::call32_operand);
         break;
       }
+      case MARK_INVOKESTATIC: {
+        assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic");
+
+        NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
+        call->set_destination(SharedRuntime::get_resolve_static_call_stub());
+        _instructions->relocate(call->instruction_address(), relocInfo::static_call_type, Assembler::call32_operand);
+        break;
+      }
+      case MARK_INVOKESPECIAL: {
+        assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial");
+        NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
+        call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub());
+        _instructions->relocate(call->instruction_address(), relocInfo::opt_virtual_call_type, Assembler::call32_operand);
+        break;
+      }
       default:
         fatal("invalid _next_call_type value");
         break;
@@ -807,6 +822,8 @@
         n_copy->set_data((intptr_t)Universe::non_oop_word());
       }
       case MARK_INLINE_INVOKE:
+      case MARK_INVOKESTATIC:
+      case MARK_INVOKESPECIAL:
         _next_call_type = (MarkId) id;
         _invoke_mark_pc = instruction;
         break;
--- a/src/share/vm/graal/graalCodeInstaller.hpp	Wed Mar 06 15:20:21 2013 +0100
+++ b/src/share/vm/graal/graalCodeInstaller.hpp	Thu Mar 07 09:43:25 2013 +0100
@@ -38,11 +38,13 @@
     MARK_DEOPT_HANDLER_ENTRY        = 5,
     MARK_INVOKEINTERFACE            = 6,
     MARK_INVOKEVIRTUAL              = 7,
-    MARK_INLINE_INVOKE              = 8,
-    MARK_POLL_NEAR                  = 9,
-    MARK_POLL_RETURN_NEAR           = 10,
-    MARK_POLL_FAR                   = 11,
-    MARK_POLL_RETURN_FAR            = 12,
+    MARK_INVOKESTATIC               = 8,
+    MARK_INVOKESPECIAL              = 9,
+    MARK_INLINE_INVOKE              = 10,
+    MARK_POLL_NEAR                  = 11,
+    MARK_POLL_RETURN_NEAR           = 12,
+    MARK_POLL_FAR                   = 13,
+    MARK_POLL_RETURN_FAR            = 14,
     MARK_INVOKE_INVALID             = -1
   };
 
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Wed Mar 06 15:20:21 2013 +0100
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Thu Mar 07 09:43:25 2013 +0100
@@ -702,7 +702,6 @@
   set_int("layoutHelperHeaderSizeMask", Klass::_lh_header_size_mask);
   set_int("layoutHelperOffset", in_bytes(Klass::layout_helper_offset()));
 
-  set_stub("instanceofStub", GraalRuntime::entry_for(GraalRuntime::slow_subtype_check_id));
   set_stub("newInstanceStub", GraalRuntime::entry_for(GraalRuntime::new_instance_id));
   set_stub("newArrayStub", GraalRuntime::entry_for(GraalRuntime::new_array_id));
   set_stub("newMultiArrayStub", GraalRuntime::entry_for(GraalRuntime::new_multi_array_id));
--- a/src/share/vm/graal/graalGlobals.hpp	Wed Mar 06 15:20:21 2013 +0100
+++ b/src/share/vm/graal/graalGlobals.hpp	Thu Mar 07 09:43:25 2013 +0100
@@ -52,9 +52,6 @@
   product(bool, BootstrapGraal, GRAALVM_ONLY(true) NOT_GRAALVM(false),      \
           "Bootstrap Graal before running Java main method")                \
                                                                             \
-  product(ccstr, GraalClassPath, NULL,                                      \
-          "Use this path, zip, or jar, to locate Graal-specific classes")   \
-                                                                            \
   product(intx, TraceGraal, 0,                                              \
           "Trace level for Graal")                                          \
                                                                             \
--- a/src/share/vm/graal/graalRuntime.cpp	Wed Mar 06 15:20:21 2013 +0100
+++ b/src/share/vm/graal/graalRuntime.cpp	Thu Mar 07 09:43:25 2013 +0100
@@ -127,7 +127,6 @@
   // Make sure that stubs that need oopmaps have them
   switch (id) {
     // These stubs don't need to have an oopmap
-    case slow_subtype_check_id:
 #if defined(SPARC) || defined(PPC)
     case handle_exception_nofpu_id:  // Unused on sparc
 #endif
--- a/src/share/vm/graal/graalRuntime.hpp	Wed Mar 06 15:20:21 2013 +0100
+++ b/src/share/vm/graal/graalRuntime.hpp	Thu Mar 07 09:43:25 2013 +0100
@@ -86,7 +86,6 @@
   stub(new_array)               \
   stub(new_multi_array)         \
   stub(handle_exception_nofpu) /* optimized version that does not preserve fpu registers */ \
-  stub(slow_subtype_check)      \
   stub(unwind_exception_call)   \
   stub(OSR_migration_end)       \
   stub(arithmetic_frem)         \
--- a/src/share/vm/runtime/arguments.cpp	Wed Mar 06 15:20:21 2013 +0100
+++ b/src/share/vm/runtime/arguments.cpp	Thu Mar 07 09:43:25 2013 +0100
@@ -105,9 +105,6 @@
 SystemProperty *Arguments::_java_home = NULL;
 SystemProperty *Arguments::_java_class_path = NULL;
 SystemProperty *Arguments::_sun_boot_class_path = NULL;
-#ifdef GRAAL
-SystemProperty *Arguments::_compiler_class_path = NULL;
-#endif
 
 char* Arguments::_meta_index_path = NULL;
 char* Arguments::_meta_index_dir = NULL;
@@ -169,9 +166,6 @@
   _java_library_path = new SystemProperty("java.library.path", NULL,  true);
   _java_home =  new SystemProperty("java.home", NULL,  true);
   _sun_boot_class_path = new SystemProperty("sun.boot.class.path", NULL,  true);
-#ifdef GRAAL
-  _compiler_class_path = new SystemProperty("compiler.class.path", NULL,  true);
-#endif
 
   _java_class_path = new SystemProperty("java.class.path", "",  true);
 
@@ -183,9 +177,6 @@
   PropertyList_add(&_system_properties, _java_home);
   PropertyList_add(&_system_properties, _java_class_path);
   PropertyList_add(&_system_properties, _sun_boot_class_path);
-#ifdef GRAAL
-  PropertyList_add(&_system_properties, _compiler_class_path);
-#endif
 
   // Set OS specific system properties values
   os::init_system_properties_values();
@@ -2189,59 +2180,6 @@
 }
 
 // Parse JavaVMInitArgs structure
-#ifdef GRAAL
-static void prepend_to_graal_classpath(SysClassPath &cp, const char* path) {
-  cp.add_prefix(path);
-}
-
-static void prepend_to_graal_classpath(SysClassPath &cp, const char* graal_dir, const char* project) {
-  const int BUFFER_SIZE = 1024;
-  char path[BUFFER_SIZE];
-
-  const char fileSep = *os::file_separator();
-  sprintf(path, "%s%c%s%cbin", graal_dir, fileSep, project, fileSep);
-  
-  DIR* dir = os::opendir(path);
-  if (dir == NULL) {
-    jio_fprintf(defaultStream::output_stream(), "Error while starting Graal VM: The Graal class directory %s could not be opened.\n", path);
-    vm_exit(1);
-  }
-  os::closedir(dir);
-  prepend_to_graal_classpath(cp, path);
-}
-
-// Walk up the directory hierarchy starting from JAVA_HOME looking
-// for a directory named "graal". If found, then the full path to
-// this directory is returned in graal_dir.
-static bool find_graal_dir(char* graal_dir) {
-  strcpy(graal_dir, Arguments::get_java_home());
-  char* end = graal_dir + strlen(graal_dir);
-  const char fileSep = *os::file_separator();
-  while (end != graal_dir) {
-    if (fileSep == '/') 
-      strcat(graal_dir, "/graal");
-    else {
-      assert(fileSep == '\\', "unexpected separator char");
-      strcat(graal_dir, "\\graal");
-    }
-    DIR* dir = os::opendir(graal_dir);
-    if (dir != NULL) {
-      os::closedir(dir);
-      return true;
-    }
-    *end = 0;
-    while (end != graal_dir) {
-      if (*end == fileSep) {
-        *end = 0;
-        break;
-      }
-      end--;
-    }
-  }
-  return false;
-}
-#endif
-
 jint Arguments::parse_vm_init_args(const JavaVMInitArgs* args) {
   // For components of the system classpath.
   SysClassPath scp(Arguments::get_sysclasspath());
@@ -2268,72 +2206,6 @@
     return result;
   }
 
-#ifdef GRAAL
-    if (PrintVMOptions) {
-      tty->print_cr("Running Graal VM... ");
-    }
-
-    SysClassPath scp_compiler("");
-
-    if (GraalClassPath != NULL) {
-      prepend_to_graal_classpath(scp_compiler, GraalClassPath);
-    } else {
-      const int BUFFER_SIZE = 1024;
-      char graal_dir[BUFFER_SIZE];
-      if (!os::getenv("GRAAL", graal_dir, sizeof(graal_dir))) {
-        if (find_graal_dir(graal_dir) == false) {
-          jio_fprintf(defaultStream::output_stream(), "Error while starting Graal VM: The GRAAL environment variable needs to point to the directory containing the Graal projects.\n");
-          vm_exit(0);
-        }
-      }
-      if (PrintVMOptions) tty->print_cr("GRAAL=%s", graal_dir);
-    
-      // this declaration is checked for correctness by 'mx build' - only
-      // modify its entries, not its name or shape
-      const char* graal_projects[] = {
-  #ifdef AMD64
-          "com.oracle.graal.amd64",
-          "com.oracle.graal.asm.amd64",
-          "com.oracle.graal.lir.amd64",
-          "com.oracle.graal.compiler.amd64",
-          "com.oracle.graal.hotspot.amd64",
-  #endif
-          "com.oracle.graal.api.runtime",
-          "com.oracle.graal.api.meta",
-          "com.oracle.graal.api.code",
-          "com.oracle.graal.hotspot",
-          "com.oracle.graal.asm",
-          "com.oracle.graal.alloc",
-          "com.oracle.graal.word",
-          "com.oracle.graal.snippets",
-          "com.oracle.graal.compiler",
-          "com.oracle.graal.loop",
-          "com.oracle.graal.phases",
-          "com.oracle.graal.phases.common",
-          "com.oracle.graal.virtual",
-          "com.oracle.graal.nodes",
-          "com.oracle.graal.printer",
-          "com.oracle.graal.debug",
-          "com.oracle.graal.graph",
-          "com.oracle.graal.lir",
-          "com.oracle.graal.bytecode",
-          "com.oracle.graal.java"
-      };
-            
-      const int len = sizeof(graal_projects) / sizeof(char*);
-      for (int i = 0; i < len; i++) {
-        if (PrintVMOptions) {
-          tty->print_cr("Adding project directory %s to bootclasspath", graal_projects[i]);
-        }
-        prepend_to_graal_classpath(scp_compiler, graal_dir, graal_projects[i]);
-      }
-    }
-
-    scp_compiler.expand_endorsed();
-    Arguments::set_compilerclasspath(scp_compiler.combined_path());
-
-#endif
-
   if (AggressiveOpts) {
     // Insert alt-rt.jar between user-specified bootclasspath
     // prefix and the default bootclasspath.  os::set_boot_path()
@@ -2349,6 +2221,20 @@
     FREE_C_HEAP_ARRAY(char, altclasses_path, mtInternal);
   }
 
+#ifdef GRAAL
+  {
+    // Append graal.jar to bootclasspath if enabled
+    const char* jar_file = "graal.jar";
+    const size_t path_len = strlen(get_meta_index_dir()) + 1 + strlen(jar_file);
+    char* path = NEW_C_HEAP_ARRAY(char, path_len, mtInternal);
+    strcpy(path, get_meta_index_dir());
+    strcat(path, jar_file);
+    scp.add_suffix(path);
+    scp_assembly_required = true;
+    FREE_C_HEAP_ARRAY(char, path, mtInternal);
+  }
+#endif
+
   // Parse _JAVA_OPTIONS environment variable (if present) (mimics classic VM)
   result = parse_java_options_environment_variable(&scp, &scp_assembly_required);
   if (result != JNI_OK) {
--- a/src/share/vm/runtime/arguments.hpp	Wed Mar 06 15:20:21 2013 +0100
+++ b/src/share/vm/runtime/arguments.hpp	Thu Mar 07 09:43:25 2013 +0100
@@ -247,9 +247,6 @@
   static SystemProperty *_java_home;
   static SystemProperty *_java_class_path;
   static SystemProperty *_sun_boot_class_path;
-#ifdef GRAAL
-  static SystemProperty *_compiler_class_path;
-#endif
 
   // Meta-index for knowing what packages are in the boot class path
   static char* _meta_index_path;
@@ -537,9 +534,6 @@
   static void set_ext_dirs(char *value) { _java_ext_dirs->set_value(value); }
   static void set_endorsed_dirs(char *value) { _java_endorsed_dirs->set_value(value); }
   static void set_sysclasspath(char *value) { _sun_boot_class_path->set_value(value); }
-#ifdef GRAAL
-  static void set_compilerclasspath(char *value) { _compiler_class_path->set_value(value); }
-#endif
   static void append_sysclasspath(const char *value) { _sun_boot_class_path->append_value(value); }
   static void set_meta_index_path(char* meta_index_path, char* meta_index_dir) {
     _meta_index_path = meta_index_path;
@@ -550,9 +544,6 @@
   static char *get_dll_dir() { return _sun_boot_library_path->value(); }
   static char *get_endorsed_dir() { return _java_endorsed_dirs->value(); }
   static char *get_sysclasspath() { return _sun_boot_class_path->value(); }
-#ifdef GRAAL
-  static char *get_compilerclasspath() { return _compiler_class_path->value(); }
-#endif
   static char* get_meta_index_path() { return _meta_index_path; }
   static char* get_meta_index_dir()  { return _meta_index_dir;  }