changeset 7221:2ae3e26b7e9a

Merge.
author Christian Haeubl <haeubl@ssw.jku.at>
date Tue, 11 Dec 2012 08:48:12 +0100
parents fcae6d960acd (current diff) 6a8b22829e36 (diff)
children 720925633b3a
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RuntimeCall.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCall.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/SystemSnippets.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java src/cpu/x86/vm/graalRuntime_x86.cpp src/share/vm/graal/graalCompilerToVM.cpp src/share/vm/graal/graalRuntime.cpp src/share/vm/graal/graalRuntime.hpp
diffstat 64 files changed, 3324 insertions(+), 2427 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java	Tue Dec 11 08:48:12 2012 +0100
@@ -23,7 +23,7 @@
 package com.oracle.graal.api.code;
 
 import com.oracle.graal.api.code.CompilationResult.DataPatch;
-import com.oracle.graal.api.code.RuntimeCall.Descriptor;
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
 import com.oracle.graal.api.meta.*;
 
 /**
@@ -39,7 +39,7 @@
      * @param compResult the compilation result to be added
      * @param info the object into which details of the installed code will be written. Ignored if null, otherwise the
      *            info is written to index 0 of this array.
-     * @return a reference to the compiled and ready-to-run code
+     * @return a reference to the compiled and ready-to-run code or null if the code installation failed
      */
     InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, CodeInfo[] info);
 
@@ -61,7 +61,7 @@
      *
      * @param method the top level method of a compilation
      */
-    RegisterConfig lookupRegisterConfig(JavaMethod method);
+    RegisterConfig lookupRegisterConfig(ResolvedJavaMethod method);
 
     /**
      * Custom area on the stack of each compiled method that the VM can use for its own purposes.
@@ -81,12 +81,12 @@
     /**
      * Performs any runtime-specific conversion on the object used to describe the target of a call.
      */
-    Object lookupCallTarget(Object target);
+    Object lookupCallTarget(Object callTarget);
 
     /**
      * Gets the signature and linkage information for a runtime call.
      */
-    RuntimeCall lookupRuntimeCall(Descriptor descriptor);
+    RuntimeCallTarget lookupRuntimeCall(Descriptor descriptor);
 
     /**
      * Encodes a deoptimization action and a deoptimization reason in an integer value.
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RuntimeCall.java	Tue Dec 11 08:28:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,116 +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.api.code;
-
-import java.util.*;
-
-import com.oracle.graal.api.meta.*;
-
-/**
- * The name, signature and calling convention of a call from compiled code to the runtime.
- * The target of such a call may be a leaf stub or a call into the runtime code proper.
- */
-public interface RuntimeCall {
-
-    /**
-     * The name and signature of a runtime call.
-     */
-    public static class Descriptor {
-        private final String name;
-        private final boolean hasSideEffect;
-        private final Kind resultKind;
-        private final Kind[] argumentKinds;
-
-        public Descriptor(String name, boolean hasSideEffect, Kind resultKind, Kind... args) {
-            this.name = name;
-            this.hasSideEffect = hasSideEffect;
-            this.resultKind = resultKind;
-            this.argumentKinds = args;
-        }
-
-        /**
-         * Gets the name of this runtime call.
-         */
-        public String getName() {
-            return name;
-        }
-
-        /**
-         * Determines if this call changes state visible to other threads.
-         * Such calls denote boundaries across which deoptimization
-         * points cannot be moved.
-         */
-        public boolean hasSideEffect() {
-            return hasSideEffect;
-        }
-
-        /**
-         * Gets the return kind of this runtime call.
-         */
-        public Kind getResultKind() {
-            return resultKind;
-        }
-
-        /**
-         * Gets the argument kinds of this runtime call.
-         */
-        public Kind[] getArgumentKinds() {
-            return argumentKinds.clone();
-        }
-
-        @Override
-        public int hashCode() {
-            return name.hashCode();
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj instanceof Descriptor) {
-                Descriptor nas = (Descriptor) obj;
-                return nas.name.equals(name) && nas.resultKind.equals(resultKind) && Arrays.equals(nas.argumentKinds, argumentKinds);
-            }
-            return false;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder sb = new StringBuilder(name).append('(');
-            String sep = "";
-            for (Kind arg : argumentKinds) {
-                sb.append(sep).append(arg);
-                sep = ",";
-            }
-            return sb.append(')').append(resultKind).toString();
-        }
-    }
-
-    CallingConvention getCallingConvention();
-
-    /**
-     * Returns the maximum absolute offset of PC relative call to this stub from any position in the code cache or -1
-     * when not applicable. Intended for determining the required size of address/offset fields.
-     */
-    long getMaxCallTargetOffset();
-
-    Descriptor getDescriptor();
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RuntimeCallTarget.java	Tue Dec 11 08:48:12 2012 +0100
@@ -0,0 +1,116 @@
+/*
+ * 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.api.code;
+
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * The name, signature and calling convention of a call from compiled code to the runtime.
+ * The target of such a call may be a leaf stub or a call into the runtime code proper.
+ */
+public interface RuntimeCallTarget {
+
+    /**
+     * The name and signature of a runtime call.
+     */
+    public static class Descriptor {
+        private final String name;
+        private final boolean hasSideEffect;
+        private final Kind resultKind;
+        private final Kind[] argumentKinds;
+
+        public Descriptor(String name, boolean hasSideEffect, Kind resultKind, Kind... args) {
+            this.name = name;
+            this.hasSideEffect = hasSideEffect;
+            this.resultKind = resultKind;
+            this.argumentKinds = args;
+        }
+
+        /**
+         * Gets the name of this runtime call.
+         */
+        public String getName() {
+            return name;
+        }
+
+        /**
+         * Determines if this call changes state visible to other threads.
+         * Such calls denote boundaries across which deoptimization
+         * points cannot be moved.
+         */
+        public boolean hasSideEffect() {
+            return hasSideEffect;
+        }
+
+        /**
+         * Gets the return kind of this runtime call.
+         */
+        public Kind getResultKind() {
+            return resultKind;
+        }
+
+        /**
+         * Gets the argument kinds of this runtime call.
+         */
+        public Kind[] getArgumentKinds() {
+            return argumentKinds.clone();
+        }
+
+        @Override
+        public int hashCode() {
+            return name.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof Descriptor) {
+                Descriptor nas = (Descriptor) obj;
+                return nas.name.equals(name) && nas.resultKind.equals(resultKind) && Arrays.equals(nas.argumentKinds, argumentKinds);
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder(name).append('(');
+            String sep = "";
+            for (Kind arg : argumentKinds) {
+                sb.append(sep).append(arg);
+                sep = ",";
+            }
+            return sb.append(')').append(resultKind).toString();
+        }
+    }
+
+    CallingConvention getCallingConvention();
+
+    /**
+     * Returns the maximum absolute offset of PC relative call to this stub from any position in the code cache or -1
+     * when not applicable. Intended for determining the required size of address/offset fields.
+     */
+    long getMaxCallTargetOffset();
+
+    Descriptor getDescriptor();
+}
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Tue Dec 11 08:48:12 2012 +0100
@@ -215,9 +215,12 @@
     /**
      * Returns the instance fields of this class, including {@linkplain ResolvedJavaField#isInternal() internal} fields.
      * A zero-length array is returned for array and primitive types. The order of fields returned by this method is
-     * stable. That is, for a single JVM execution the same order is returned each time this method is called.
+     * stable. That is, for a single JVM execution the same order is returned each time this method is called. It is
+     * also the "natural" order, which means that the JVM would expect the fields in this order if no specific order is
+     * given.
      *
-     * @param includeSuperclasses if true, then instance fields for the complete hierarchy of this type are included in the result
+     * @param includeSuperclasses if true, then instance fields for the complete hierarchy of this type are included in
+     *            the result
      * @return an array of instance fields
      */
     ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses);
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64DeoptimizationStub.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64DeoptimizationStub.java	Tue Dec 11 08:48:12 2012 +0100
@@ -25,7 +25,7 @@
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.RuntimeCall.*;
+import com.oracle.graal.api.code.RuntimeCallTarget.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.amd64.*;
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Tue Dec 11 08:48:12 2012 +0100
@@ -29,7 +29,7 @@
 
 import com.oracle.graal.amd64.*;
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.RuntimeCall.Descriptor;
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag;
@@ -382,11 +382,11 @@
                 append(new DivOp(LREM, RDX_L, RAX_L, load(b), state()));
                 return emitMove(RDX_L);
             case Float: {
-                RuntimeCall stub = runtime.lookupRuntimeCall(ARITHMETIC_FREM);
+                RuntimeCallTarget stub = runtime.lookupRuntimeCall(ARITHMETIC_FREM);
                 return emitCall(stub, stub.getCallingConvention(), false, a, b);
             }
             case Double: {
-                RuntimeCall stub = runtime.lookupRuntimeCall(ARITHMETIC_DREM);
+                RuntimeCallTarget stub = runtime.lookupRuntimeCall(ARITHMETIC_DREM);
                 return emitCall(stub, stub.getCallingConvention(), false, a, b);
             }
             default:
@@ -571,11 +571,11 @@
     }
 
     @Override
-    protected void emitCall(Object targetMethod, Value result, Value[] arguments, Value[] temps, Value targetAddress, LIRFrameState info) {
+    protected void emitCall(RuntimeCallTarget callTarget, Value result, Value[] arguments, Value[] temps, Value targetAddress, LIRFrameState info) {
         if (isConstant(targetAddress)) {
-            append(new DirectCallOp(targetMethod, result, arguments, temps, info));
+            append(new DirectCallOp(callTarget, result, arguments, temps, info));
         } else {
-            append(new IndirectCallOp(targetMethod, result, arguments, temps, targetAddress, info));
+            append(new IndirectCallOp(callTarget, result, arguments, temps, targetAddress, info));
         }
     }
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Tue Dec 11 08:48:12 2012 +0100
@@ -216,13 +216,20 @@
         return LabelRef.forSuccessor(lir, currentBlock, suxIndex);
     }
 
+    /**
+     * Determines if only oop maps are required for the code generated from the LIR.
+     */
+    protected boolean needOnlyOopMaps() {
+        return false;
+    }
+
     public LIRFrameState state() {
-        assert lastState != null : "must have state before instruction";
+        assert lastState != null || needOnlyOopMaps() : "must have state before instruction";
         return stateFor(lastState, StructuredGraph.INVALID_GRAPH_ID);
     }
 
     public LIRFrameState state(long leafGraphId) {
-        assert lastState != null : "must have state before instruction";
+        assert lastState != null || needOnlyOopMaps() : "must have state before instruction";
         return stateFor(lastState, leafGraphId);
     }
 
@@ -231,6 +238,9 @@
     }
 
     public LIRFrameState stateFor(FrameState state, List<StackSlot> pointerSlots, LabelRef exceptionEdge, long leafGraphId) {
+        if (needOnlyOopMaps()) {
+            return new LIRFrameState(null, null, null, null);
+        }
         return debugInfoBuilder.build(state, lockDataSlots.subList(0, currentLockCount), pointerSlots, exceptionEdge, leafGraphId);
     }
 
@@ -731,7 +741,7 @@
 
     protected abstract void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState);
 
-    protected abstract void emitCall(Object targetMethod, Value result, Value[] arguments, Value[] temps, Value targetAddress, LIRFrameState info);
+    protected abstract void emitCall(RuntimeCallTarget callTarget, Value result, Value[] arguments, Value[] temps, Value targetAddress, LIRFrameState info);
 
     private static Value toStackKind(Value value) {
         if (value.getKind().getStackKind() != value.getKind()) {
@@ -768,7 +778,7 @@
     protected abstract LabelRef createDeoptStub(DeoptimizationAction action, DeoptimizationReason reason, LIRFrameState info, Object deoptInfo);
 
     @Override
-    public Variable emitCall(@SuppressWarnings("hiding") Object target, CallingConvention cc, boolean canTrap, Value... args) {
+    public Variable emitCall(RuntimeCallTarget callTarget, CallingConvention cc, boolean canTrap, Value... args) {
         LIRFrameState info = canTrap ? state() : null;
 
         // move the arguments into the correct location
@@ -781,7 +791,7 @@
             emitMove(arg, loc);
             argLocations[i] = loc;
         }
-        emitCall(target, cc.getReturn(), argLocations, cc.getTemporaries(), Constant.forLong(0), info);
+        emitCall(callTarget, cc.getReturn(), argLocations, cc.getTemporaries(), Constant.forLong(0), info);
 
         if (isLegal(cc.getReturn())) {
             return emitMove(cc.getReturn());
@@ -792,7 +802,7 @@
 
     @Override
     public void visitRuntimeCall(RuntimeCallNode x) {
-        RuntimeCall call = runtime.lookupRuntimeCall(x.getDescriptor());
+        RuntimeCallTarget call = runtime.lookupRuntimeCall(x.getDescriptor());
         CallingConvention cc = call.getCallingConvention();
         frameMap.callsMethod(cc);
         Value resultOperand = cc.getReturn();
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DirectCallOp.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DirectCallOp.java	Tue Dec 11 08:48:12 2012 +0100
@@ -74,8 +74,8 @@
 
     private final InvokeKind invokeKind;
 
-    AMD64DirectCallOp(Object targetMethod, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind, LIR lir) {
-        super(targetMethod, result, parameters, temps, state);
+    AMD64DirectCallOp(Object target, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind, LIR lir) {
+        super(target, result, parameters, temps, state);
         this.invokeKind = invokeKind;
 
         if (invokeKind == Static || invokeKind == Special) {
@@ -116,6 +116,6 @@
             callsiteMark = tasm.recordMark(null);
         }
 
-        AMD64Call.directCall(tasm, masm, targetMethod, state);
+        AMD64Call.directCall(tasm, masm, callTarget, state);
     }
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Tue Dec 11 08:48:12 2012 +0100
@@ -40,6 +40,7 @@
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.amd64.AMD64Move.CompareAndSwapOp;
@@ -73,7 +74,18 @@
         }
 
         @Override
+        protected boolean needOnlyOopMaps() {
+            // Stubs only need oop maps
+            return runtime().asStub(method) != null;
+        }
+
+        @Override
         protected CallingConvention createCallingConvention() {
+            Stub stub = runtime().asStub(method);
+            if (stub != null) {
+                return stub.getLinkage().getCallingConvention();
+            }
+
             if (graph.getEntryBCI() == StructuredGraph.INVOCATION_ENTRY_BCI) {
                 return super.createCallingConvention();
             } else {
@@ -219,14 +231,14 @@
         //  - has no callee-saved registers
         //  - has no incoming arguments passed on the stack
         //  - has no instructions with debug info
-        boolean canOmitFrame = GraalOptions.CanOmitFrame &&
+        boolean omitFrame = GraalOptions.CanOmitFrame &&
             frameMap.frameSize() == frameMap.initialFrameSize &&
             frameMap.registerConfig.getCalleeSaveLayout().registers.length == 0 &&
             !lir.hasArgInCallerFrame() &&
             !lir.hasDebugInfo();
 
         AbstractAssembler masm = new AMD64MacroAssembler(target, frameMap.registerConfig);
-        HotSpotFrameContext frameContext = canOmitFrame ? null : new HotSpotFrameContext();
+        HotSpotFrameContext frameContext = omitFrame ? null : new HotSpotFrameContext();
         TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime(), frameMap, masm, frameContext, lir.stubs);
         tasm.setFrameSize(frameMap.frameSize());
         tasm.targetMethod.setCustomStackAreaOffset(frameMap.offsetToCustomArea());
@@ -239,11 +251,11 @@
         FrameMap frameMap = tasm.frameMap;
         RegisterConfig regConfig = frameMap.registerConfig;
         HotSpotVMConfig config = runtime().config;
-        Label unverifiedStub = new Label();
+        boolean isStatic = Modifier.isStatic(method.getModifiers());
+        Label unverifiedStub = isStatic ? null : new Label();
 
         // Emit the prefix
 
-        boolean isStatic = Modifier.isStatic(method.getModifiers());
         if (!isStatic) {
             tasm.recordMark(Marks.MARK_UNVERIFIED_ENTRY);
             CallingConvention cc = regConfig.getCallingConvention(JavaCallee, Kind.Void, new Kind[] {Kind.Object}, target, false);
@@ -277,7 +289,7 @@
             assert !frameMap.accessesCallerFrame();
         }
 
-        if (!isStatic) {
+        if (unverifiedStub != null) {
             asm.bind(unverifiedStub);
             AMD64Call.directJmp(tasm, asm, config.inlineCacheMissStub);
         }
@@ -285,5 +297,6 @@
         for (int i = 0; i < GraalOptions.MethodEndBreakpointGuards; ++i) {
             asm.int3();
         }
+
     }
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Tue Dec 11 08:48:12 2012 +0100
@@ -27,7 +27,9 @@
 import static com.oracle.graal.compiler.amd64.AMD64LIRGenerator.*;
 import static com.oracle.graal.hotspot.nodes.MonitorEnterStubCall.*;
 import static com.oracle.graal.hotspot.nodes.MonitorExitStubCall.*;
+import static com.oracle.graal.hotspot.nodes.NewArraySlowStubCall.*;
 import static com.oracle.graal.hotspot.nodes.NewArrayStubCall.*;
+import static com.oracle.graal.hotspot.nodes.NewInstanceSlowStubCall.*;
 import static com.oracle.graal.hotspot.nodes.NewInstanceStubCall.*;
 import static com.oracle.graal.hotspot.nodes.NewMultiArrayStubCall.*;
 import static com.oracle.graal.hotspot.nodes.VMErrorNode.*;
@@ -74,30 +76,35 @@
                 /* arg1:         b */ arg(1, Kind.Double));
 
         addRuntimeCall(MONITORENTER, config.monitorEnterStub,
-                /*        temps */ new Register[] {rax, rbx},
+                /*        temps */ null,
                 /*          ret */ ret(Kind.Void),
                 /* arg0: object */ arg(0, Kind.Object),
                 /* arg1:   lock */ arg(1, word));
 
         addRuntimeCall(MONITOREXIT, config.monitorExitStub,
-                /*        temps */ new Register[] {rax, rbx},
+                /*        temps */ null,
                 /*          ret */ ret(Kind.Void),
                 /* arg0: object */ arg(0, Kind.Object),
                 /* arg1:   lock */ arg(1, word));
 
-        addRuntimeCall(NEW_OBJECT_ARRAY, config.newObjectArrayStub,
-                /*        temps */ new Register[] {rcx, rdi, rsi},
+        addRuntimeCall(NEW_ARRAY, 0L,
+                /*        temps */ null,
                 /*          ret */ rax.asValue(Kind.Object),
                 /* arg0:    hub */ rdx.asValue(word),
                 /* arg1: length */ rbx.asValue(Kind.Int));
 
-        addRuntimeCall(NEW_TYPE_ARRAY, config.newTypeArrayStub,
-                /*        temps */ new Register[] {rcx, rdi, rsi},
+        addRuntimeCall(NEW_ARRAY_SLOW, config.newArrayStub,
+                /*        temps */ null,
                 /*          ret */ rax.asValue(Kind.Object),
                 /* arg0:    hub */ rdx.asValue(word),
                 /* arg1: length */ rbx.asValue(Kind.Int));
 
-        addRuntimeCall(NEW_INSTANCE, config.newInstanceStub,
+        addRuntimeCall(NEW_INSTANCE, 0L,
+                /*        temps */ null,
+                /*          ret */ rax.asValue(Kind.Object),
+                /* arg0:    hub */ rdx.asValue(word));
+
+        addRuntimeCall(NEW_INSTANCE_SLOW, c.newInstanceStub,
                 /*        temps */ null,
                 /*          ret */ rax.asValue(Kind.Object),
                 /* arg0:    hub */ rdx.asValue(word));
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64IndirectCallOp.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64IndirectCallOp.java	Tue Dec 11 08:48:12 2012 +0100
@@ -62,7 +62,7 @@
         tasm.recordMark(Marks.MARK_INLINE_INVOKEVIRTUAL);
         Register callReg = asRegister(targetAddress);
         assert callReg != METHOD;
-        AMD64Call.indirectCall(tasm, masm, callReg, targetMethod, state);
+        AMD64Call.indirectCall(tasm, masm, callReg, callTarget, state);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCall.java	Tue Dec 11 08:28:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +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;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.hotspot.bridge.*;
-
-/**
- * The details required to link a HotSpot runtime or stub call.
- */
-public class HotSpotRuntimeCall implements RuntimeCall {
-
-    /**
-     * The descriptor of the stub. This is for informational purposes only.
-     */
-    public final Descriptor descriptor;
-
-    /**
-     * The entry point address of the stub.
-     */
-    public final long address;
-
-    /**
-     * Where the stub gets its arguments and where it places its result.
-     */
-    public final CallingConvention cc;
-
-    private final CompilerToVM vm;
-
-    public HotSpotRuntimeCall(Descriptor descriptor, long address, CallingConvention cc, CompilerToVM vm) {
-        this.address = address;
-        this.descriptor = descriptor;
-        this.cc = cc;
-        this.vm = vm;
-    }
-
-    @Override
-    public String toString() {
-        return descriptor + "@0x" + Long.toHexString(address) + ":" + cc;
-    }
-
-    public CallingConvention getCallingConvention() {
-        return cc;
-    }
-
-    public long getMaxCallTargetOffset() {
-        return vm.getMaxCallTargetOffset(address);
-    }
-
-    public Descriptor getDescriptor() {
-        return descriptor;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java	Tue Dec 11 08:48:12 2012 +0100
@@ -0,0 +1,95 @@
+/*
+ * 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;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.bridge.*;
+import com.oracle.graal.hotspot.stubs.*;
+
+/**
+ * The details required to link a HotSpot runtime or stub call.
+ */
+public class HotSpotRuntimeCallTarget implements RuntimeCallTarget {
+
+    /**
+     * The descriptor of the stub. This is for informational purposes only.
+     */
+    public final Descriptor descriptor;
+
+    /**
+     * The entry point address of the stub.
+     */
+    private long address;
+
+    /**
+     * Non-null (eventually) iff this is a call to a snippet-based {@linkplain Stub stub}.
+     */
+    private Stub stub;
+
+    /**
+     * Where the stub gets its arguments and where it places its result.
+     */
+    public final CallingConvention cc;
+
+    private final CompilerToVM vm;
+
+    public HotSpotRuntimeCallTarget(Descriptor descriptor, long address, CallingConvention cc, CompilerToVM vm) {
+        this.address = address;
+        this.descriptor = descriptor;
+        this.cc = cc;
+        this.vm = vm;
+    }
+
+    @Override
+    public String toString() {
+        return (stub == null ? descriptor.toString() : MetaUtil.format("%h.%n", stub.getMethod())) + "@0x" + Long.toHexString(address) + ":" + cc;
+    }
+
+    public CallingConvention getCallingConvention() {
+        return cc;
+    }
+
+    public long getMaxCallTargetOffset() {
+        return vm.getMaxCallTargetOffset(address);
+    }
+
+    public Descriptor getDescriptor() {
+        return descriptor;
+    }
+
+    public void setStub(Stub stub) {
+        assert address == 0L : "cannot stub for linkage that already has an address: " + this;
+        this.stub = stub;
+    }
+
+    public void setAddress(long address) {
+        assert this.address == 0L : "cannot re-initialize address of " + this;
+        this.address = address;
+    }
+
+    public long getAddress() {
+        assert address != 0L : "address not yet initialized for " + this;
+        return address;
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Tue Dec 11 08:48:12 2012 +0100
@@ -262,6 +262,29 @@
     public int methodCompiledEntryOffset;
     public int basicLockSize;
     public int basicLockDisplacedHeaderOffset;
+    public long tlabIntArrayMarkWord;
+    public long heapEndAddress;
+    public long heapTopAddress;
+    public int threadTlabStartOffset;
+    public int threadTlabSizeOffset;
+    public int threadAllocatedBytesOffset;
+    public int tlabRefillWasteLimitOffset;
+    public int tlabRefillWasteIncrement;
+    public int tlabAlignmentReserve;
+    public int tlabSlowAllocationsOffset;
+    public int tlabFastRefillWasteOffset;
+    public int tlabNumberOfRefillsOffset;
+    public boolean tlabStats;
+    public int klassInstanceSizeOffset;
+    public boolean inlineContiguousAllocationSupported;
+    public long arrayPrototypeMarkWord;
+    public int layoutHelperLog2ElementSizeShift;
+    public int layoutHelperLog2ElementSizeMask;
+    public int layoutHelperElementTypeShift;
+    public int layoutHelperElementTypeMask;
+    public int layoutHelperHeaderSizeShift;
+    public int layoutHelperHeaderSizeMask;
+    public int layoutHelperOffset;
 
     // methodData information
     public int methodDataOopDataOffset;
@@ -279,8 +302,7 @@
     public long debugStub;
     public long instanceofStub;
     public long newInstanceStub;
-    public long newTypeArrayStub;
-    public long newObjectArrayStub;
+    public long newArrayStub;
     public long newMultiArrayStub;
     public long inlineCacheMissStub;
     public long handleExceptionStub;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Tue Dec 11 08:48:12 2012 +0100
@@ -192,6 +192,4 @@
     long[] getDeoptedLeafGraphIds();
 
     String decodePC(long pc);
-
-    long getPrototypeMarkWord(HotSpotResolvedObjectType hotSpotResolvedJavaType);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Tue Dec 11 08:48:12 2012 +0100
@@ -139,7 +139,4 @@
 
     @Override
     public native String decodePC(long pc);
-
-    @Override
-    public native long getPrototypeMarkWord(HotSpotResolvedObjectType type);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Tue Dec 11 08:48:12 2012 +0100
@@ -136,7 +136,8 @@
 
                 @Override
                 public void run() {
-                    Assumptions assumptions = new Assumptions(GraalOptions.OptAssumptions);
+                    // Snippets cannot have speculative optimizations since they have to be valid for the entire run of the VM.
+                    Assumptions assumptions = new Assumptions(false);
                     VMToCompilerImpl.this.intrinsifyArrayCopy = new IntrinsifyArrayCopyPhase(runtime, assumptions);
                     SnippetInstaller installer = new SnippetInstaller(runtime, assumptions, runtime.getGraalRuntime().getTarget());
                     GraalIntrinsics.installIntrinsics(installer);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java	Tue Dec 11 08:48:12 2012 +0100
@@ -57,7 +57,7 @@
 
     @Override
     public String toString() {
-        return "compiled method " + method + " @" + nmethod;
+        return String.format("InstalledCode[method=%s, nmethod=0x%x]", method, nmethod);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Tue Dec 11 08:48:12 2012 +0100
@@ -63,7 +63,7 @@
     private final boolean hasFinalizableSubclass;
 
     /**
-     * The instance size for an instance type, {@link HotSpotResolvedObjectType#INTERFACE_SPECIES_VALUE} denoting
+     * The instance size (in bytes) for an instance type, {@link HotSpotResolvedObjectType#INTERFACE_SPECIES_VALUE} denoting
      * an interface type or {@link HotSpotResolvedObjectType#ARRAY_SPECIES_VALUE} denoting an array type.
      */
     private final int sizeOrSpecies;
@@ -106,6 +106,7 @@
      * @return the {@link HotSpotResolvedObjectType} corresponding to {@code javaClass}
      */
     public static ResolvedJavaType fromClass(Class javaClass) {
+        assert javaClass != null;
         ResolvedJavaType type = (ResolvedJavaType) unsafe.getObject(javaClass, (long) HotSpotGraalRuntime.getInstance().getConfig().graalMirrorInClassOffset);
         if (type == null) {
             type = HotSpotGraalRuntime.getInstance().getCompilerToVM().getResolvedType(javaClass);
@@ -395,6 +396,13 @@
         return ((HotSpotResolvedJavaMethod) method).uniqueConcreteMethod();
     }
 
+    private static class OffsetComparator implements Comparator<HotSpotResolvedJavaField> {
+        @Override
+        public int compare(HotSpotResolvedJavaField o1, HotSpotResolvedJavaField o2) {
+            return o1.offset() - o2.offset();
+        }
+    }
+
     @Override
     public ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses) {
         if (instanceFields == null) {
@@ -402,6 +410,7 @@
                 instanceFields = new HotSpotResolvedJavaField[0];
             } else {
                 HotSpotResolvedJavaField[] myFields = HotSpotGraalRuntime.getInstance().getCompilerToVM().getInstanceFields(this);
+                Arrays.sort(myFields, new OffsetComparator());
                 if (javaMirror != Object.class) {
                     HotSpotResolvedJavaField[] superFields = (HotSpotResolvedJavaField[]) getSuperclass().getInstanceFields(true);
                     HotSpotResolvedJavaField[] fields = Arrays.copyOf(superFields, superFields.length + myFields.length);
@@ -461,7 +470,12 @@
     }
 
     public long prototypeMarkWord() {
-        return HotSpotGraalRuntime.getInstance().getCompilerToVM().getPrototypeMarkWord(this);
+        HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig();
+        if (isArray()) {
+            return config.arrayPrototypeMarkWord;
+        } else {
+            return unsafeReadWord(metaspaceKlass + config.prototypeMarkWordOffset);
+        }
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Tue Dec 11 08:48:12 2012 +0100
@@ -46,7 +46,7 @@
 import com.oracle.graal.api.code.CompilationResult.Mark;
 import com.oracle.graal.api.code.CompilationResult.Safepoint;
 import com.oracle.graal.api.code.Register.RegisterFlag;
-import com.oracle.graal.api.code.RuntimeCall.Descriptor;
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
@@ -55,6 +55,7 @@
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.hotspot.phases.*;
 import com.oracle.graal.hotspot.snippets.*;
+import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
@@ -81,7 +82,19 @@
     private NewObjectSnippets.Templates newObjectSnippets;
     private MonitorSnippets.Templates monitorSnippets;
 
-    private final Map<Descriptor, RuntimeCall> runtimeCalls = new HashMap<>();
+    private NewInstanceStub newInstanceStub;
+    private NewArrayStub newArrayStub;
+
+    private final Map<Descriptor, HotSpotRuntimeCallTarget> runtimeCalls = new HashMap<>();
+    private final Map<ResolvedJavaMethod, Stub> stubs = new HashMap<>();
+
+    /**
+     * Holds onto objects that will be embedded in compiled code. HotSpot treats oops
+     * embedded in code as weak references so without an external strong root, such
+     * an embedded oop will quickly die. This in turn will cause the nmethod to
+     * be unloaded.
+     */
+    private final Map<Object, Object> gcRoots = new HashMap<>();
 
     /**
      * The offset from the origin of an array to the first element.
@@ -259,10 +272,23 @@
         for (int i = 0; i < argKinds.length; i++) {
             assert argKinds[i].equals(args[i].getKind()) : descriptor + " incompatible with argument location " + i + ": " + args[i];
         }
-        HotSpotRuntimeCall runtimeCall = new HotSpotRuntimeCall(descriptor, address, new CallingConvention(temps, 0, ret, args), graalRuntime.getCompilerToVM());
+        HotSpotRuntimeCallTarget runtimeCall = new HotSpotRuntimeCallTarget(descriptor, address, new CallingConvention(temps, 0, ret, args), graalRuntime.getCompilerToVM());
         runtimeCalls.put(descriptor, runtimeCall);
     }
 
+    /**
+     * Binds a snippet-base {@link Stub} to a runtime call descriptor.
+     *
+     * @return the linkage information for a call to the stub
+     */
+    public HotSpotRuntimeCallTarget registerStub(Descriptor descriptor, Stub stub) {
+        HotSpotRuntimeCallTarget linkage = runtimeCalls.get(descriptor);
+        assert linkage != null;
+        linkage.setStub(stub);
+        stubs.put(stub.getMethod(), stub);
+        return linkage;
+    }
+
     protected abstract RegisterConfig createRegisterConfig(boolean globalStubConfig);
 
     public void installSnippets(SnippetInstaller installer, Assumptions assumptions) {
@@ -290,13 +316,20 @@
         installer.install(NewObjectSnippets.class);
         installer.install(MonitorSnippets.class);
 
+        installer.install(NewInstanceStub.class);
+        installer.install(NewArrayStub.class);
+
         checkcastSnippets = new CheckCastSnippets.Templates(this, assumptions, graalRuntime.getTarget());
         instanceofSnippets = new InstanceOfSnippets.Templates(this, assumptions, graalRuntime.getTarget());
         newObjectSnippets = new NewObjectSnippets.Templates(this, assumptions, graalRuntime.getTarget(), config.useTLAB);
         monitorSnippets = new MonitorSnippets.Templates(this, assumptions, graalRuntime.getTarget(), config.useFastLocking);
+
+        newInstanceStub = new NewInstanceStub(this, assumptions, graalRuntime.getTarget());
+        newArrayStub = new NewArrayStub(this, assumptions, graalRuntime.getTarget());
+        newInstanceStub.install(graalRuntime.getCompiler());
+        newArrayStub.install(graalRuntime.getCompiler());
     }
 
-
     public HotSpotGraalRuntime getGraalRuntime() {
         return graalRuntime;
     }
@@ -425,7 +458,7 @@
     }
 
     @Override
-    public RegisterConfig lookupRegisterConfig(JavaMethod method) {
+    public RegisterConfig lookupRegisterConfig(ResolvedJavaMethod method) {
         return regConfig;
     }
 
@@ -631,6 +664,10 @@
             ReadNode hub = graph.add(new ReadNode(object, location, StampFactory.forKind(wordKind())));
             hub.dependencies().add(guard);
             graph.replaceFixed(loadHub, hub);
+        } else if (n instanceof FixedGuardNode) {
+            FixedGuardNode node = (FixedGuardNode) n;
+            ValueAnchorNode newAnchor = graph.add(new ValueAnchorNode(tool.createGuard(node.condition(), node.getReason(), node.getAction(), node.isNegated(), node.getLeafGraphId())));
+            graph.replaceFixedWithFixed(node, newAnchor);
         } else if (n instanceof CheckCastNode) {
             checkcastSnippets.lower((CheckCastNode) n, tool);
         } else if (n instanceof CheckCastDynamicNode) {
@@ -689,14 +726,24 @@
         return HotSpotResolvedObjectType.fromClass(clazz);
     }
 
-    public Object lookupCallTarget(Object target) {
-        if (target instanceof HotSpotRuntimeCall) {
-            return ((HotSpotRuntimeCall) target).address;
+    public Object lookupCallTarget(Object callTarget) {
+        if (callTarget instanceof HotSpotRuntimeCallTarget) {
+            return ((HotSpotRuntimeCallTarget) callTarget).getAddress();
         }
-        return target;
+        return callTarget;
     }
 
-    public RuntimeCall lookupRuntimeCall(Descriptor descriptor) {
+    /**
+     * Gets the stub corresponding to a given method.
+     *
+     * @return the stub {@linkplain Stub#getMethod() implemented} by {@code method} or null if {@code method} does not
+     *         implement a stub
+     */
+    public Stub asStub(ResolvedJavaMethod method) {
+        return stubs.get(method);
+    }
+
+    public HotSpotRuntimeCallTarget lookupRuntimeCall(Descriptor descriptor) {
         assert runtimeCalls.containsKey(descriptor) : descriptor;
         return runtimeCalls.get(descriptor);
     }
@@ -792,4 +839,18 @@
     public boolean needsDataPatch(Constant constant) {
         return constant.getPrimitiveAnnotation() instanceof HotSpotResolvedObjectType;
     }
+
+    /**
+     * Registers an object created by the compiler and referenced by some generated code.
+     * HotSpot treats oops embedded in code as weak references so without an external strong root, such
+     * an embedded oop will quickly die. This in turn will cause the nmethod to be unloaded.
+     */
+    public synchronized Object registerGCRoot(Object object) {
+        Object existing = gcRoots.get(object);
+        if (existing != null) {
+            return existing;
+        }
+        gcRoots.put(object, object);
+        return object;
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeArrayNode.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeArrayNode.java	Tue Dec 11 08:48:12 2012 +0100
@@ -37,17 +37,17 @@
 
     @Input private final ValueNode memory;
     @Input private final ValueNode length;
-    @Input private final ValueNode size;
+    @Input private final ValueNode allocationSize;
     private final ResolvedJavaType type;
     private final boolean fillContents;
     private final boolean locked;
 
-    public InitializeArrayNode(ValueNode memory, ValueNode length, ValueNode size, ResolvedJavaType type, boolean fillContents, boolean locked) {
+    public InitializeArrayNode(ValueNode memory, ValueNode length, ValueNode allocationSize, ResolvedJavaType type, boolean fillContents, boolean locked) {
         super(StampFactory.exactNonNull(type));
         this.memory = memory;
         this.type = type;
         this.length = length;
-        this.size = size;
+        this.allocationSize = allocationSize;
         this.fillContents = fillContents;
         this.locked = locked;
     }
@@ -61,8 +61,11 @@
         return length;
     }
 
-    public ValueNode size() {
-        return size;
+    /**
+     * Gets the size (in bytes) of the memory chunk allocated for the array.
+     */
+    public ValueNode allocationSize() {
+        return allocationSize;
     }
 
     public ResolvedJavaType type() {
@@ -83,5 +86,5 @@
     }
 
     @NodeIntrinsic
-    public static native Object initialize(Object memory, int length, int size, @ConstantNodeParameter ResolvedJavaType type, @ConstantNodeParameter boolean fillContents, @ConstantNodeParameter boolean locked);
+    public static native Object initialize(Object memory, int length, int allocationSize, @ConstantNodeParameter ResolvedJavaType type, @ConstantNodeParameter boolean fillContents, @ConstantNodeParameter boolean locked);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorEnterStubCall.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorEnterStubCall.java	Tue Dec 11 08:48:12 2012 +0100
@@ -25,7 +25,7 @@
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.RuntimeCall.Descriptor;
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
@@ -50,7 +50,7 @@
 
     @Override
     public void generate(LIRGenerator gen) {
-        RuntimeCall stub = gen.getRuntime().lookupRuntimeCall(MonitorEnterStubCall.MONITORENTER);
+        RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(MonitorEnterStubCall.MONITORENTER);
         gen.emitCall(stub, stub.getCallingConvention(), true, gen.operand(object), gen.operand(lock));
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorExitStubCall.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorExitStubCall.java	Tue Dec 11 08:48:12 2012 +0100
@@ -25,7 +25,7 @@
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.RuntimeCall.Descriptor;
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
@@ -47,7 +47,7 @@
 
     @Override
     public void generate(LIRGenerator gen) {
-        RuntimeCall stub = gen.getRuntime().lookupRuntimeCall(MonitorExitStubCall.MONITOREXIT);
+        RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(MonitorExitStubCall.MONITOREXIT);
         gen.emitCall(stub, stub.getCallingConvention(), true, gen.operand(object), gen.emitLea(gen.peekLock()));
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArraySlowStubCall.java	Tue Dec 11 08:48:12 2012 +0100
@@ -0,0 +1,74 @@
+/*
+ * 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.nodes;
+
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.snippets.*;
+
+/**
+ * Node implementing a call to the {@code new_array} stub.
+ */
+public class NewArraySlowStubCall extends FixedWithNextNode implements LIRGenLowerable {
+
+    private static final Stamp defaultStamp = StampFactory.objectNonNull();
+
+    @Input private final ValueNode hub;
+    @Input private final ValueNode length;
+
+    public static final Descriptor NEW_ARRAY_SLOW = new Descriptor("new_array_slow", false, Kind.Object, wordKind(), Kind.Int);
+
+    public NewArraySlowStubCall(ValueNode hub, ValueNode length) {
+        super(defaultStamp);
+        this.hub = hub;
+        this.length = length;
+    }
+
+    @Override
+    public boolean inferStamp() {
+        if (stamp() == defaultStamp && hub.isConstant()) {
+            updateStamp(StampFactory.exactNonNull(HotSpotResolvedObjectType.fromMetaspaceKlass(hub.asConstant())));
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void generate(LIRGenerator gen) {
+        RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(NEW_ARRAY_SLOW);
+        Variable result = gen.emitCall(stub, stub.getCallingConvention(), true, gen.operand(hub), gen.operand(length));
+        gen.setResult(this, result);
+    }
+
+    @NodeIntrinsic
+    public static native Object call(Word hub, int length);
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java	Tue Dec 11 08:48:12 2012 +0100
@@ -25,18 +25,19 @@
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.RuntimeCall.Descriptor;
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.snippets.*;
 
 /**
- * Node implementing a call to HotSpot's {@code new_[object|type]_array} stub.
+ * A call to the {@link NewArrayStub}.
  */
 public class NewArrayStubCall extends FixedWithNextNode implements LIRGenLowerable {
 
@@ -44,15 +45,11 @@
 
     @Input private final ValueNode hub;
     @Input private final ValueNode length;
-    private final boolean isObjectArray;
 
-    public static final Descriptor NEW_OBJECT_ARRAY = new Descriptor("new_object_array", false, Kind.Object, wordKind(), Kind.Int);
+    public static final Descriptor NEW_ARRAY = new Descriptor("new_array", false, Kind.Object, wordKind(), Kind.Int);
 
-    public static final Descriptor NEW_TYPE_ARRAY = new Descriptor("new_type_array", false, Kind.Object, wordKind(), Kind.Int);
-
-    public NewArrayStubCall(boolean isObjectArray, ValueNode hub, ValueNode length) {
+    public NewArrayStubCall(ValueNode hub, ValueNode length) {
         super(defaultStamp);
-        this.isObjectArray = isObjectArray;
         this.hub = hub;
         this.length = length;
     }
@@ -68,11 +65,11 @@
 
     @Override
     public void generate(LIRGenerator gen) {
-        RuntimeCall stub = gen.getRuntime().lookupRuntimeCall(isObjectArray ? NewArrayStubCall.NEW_OBJECT_ARRAY : NewArrayStubCall.NEW_TYPE_ARRAY);
+        RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(NEW_ARRAY);
         Variable result = gen.emitCall(stub, stub.getCallingConvention(), true, gen.operand(hub), gen.operand(length));
         gen.setResult(this, result);
     }
 
     @NodeIntrinsic
-    public static native Object call(@ConstantNodeParameter boolean isObjectArray, Word hub, int length);
+    public static native Object call(Word hub, int length);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceSlowStubCall.java	Tue Dec 11 08:48:12 2012 +0100
@@ -0,0 +1,72 @@
+/*
+ * 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.nodes;
+
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.snippets.*;
+
+/**
+ * Node implementing a call to HotSpot's {@code new_instance} stub.
+ */
+public class NewInstanceSlowStubCall extends FixedWithNextNode implements LIRGenLowerable {
+
+    private static final Stamp defaultStamp = StampFactory.objectNonNull();
+
+    @Input private final ValueNode hub;
+
+    public static final Descriptor NEW_INSTANCE_SLOW = new Descriptor("new_instance_slow", false, Kind.Object, wordKind());
+
+    public NewInstanceSlowStubCall(ValueNode hub) {
+        super(defaultStamp);
+        this.hub = hub;
+    }
+
+    @Override
+    public boolean inferStamp() {
+        if (stamp() == defaultStamp && hub.isConstant()) {
+            updateStamp(StampFactory.exactNonNull(HotSpotResolvedObjectType.fromMetaspaceKlass(hub.asConstant())));
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void generate(LIRGenerator gen) {
+        RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(NEW_INSTANCE_SLOW);
+        Variable result = gen.emitCall(stub, stub.getCallingConvention(), true, gen.operand(hub));
+        gen.setResult(this, result);
+    }
+
+    @NodeIntrinsic
+    public static native Object call(Word hub);
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java	Tue Dec 11 08:48:12 2012 +0100
@@ -25,18 +25,19 @@
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.RuntimeCall.Descriptor;
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.snippets.*;
 
 /**
- * Node implementing a call to HotSpot's {@code new_instance} stub.
+ * A call to the {@link NewInstanceStub}.
  */
 public class NewInstanceStubCall extends FixedWithNextNode implements LIRGenLowerable {
 
@@ -62,7 +63,7 @@
 
     @Override
     public void generate(LIRGenerator gen) {
-        RuntimeCall stub = gen.getRuntime().lookupRuntimeCall(NewInstanceStubCall.NEW_INSTANCE);
+        RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(NEW_INSTANCE);
         Variable result = gen.emitCall(stub, stub.getCallingConvention(), true, gen.operand(hub));
         gen.setResult(this, result);
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java	Tue Dec 11 08:48:12 2012 +0100
@@ -25,7 +25,7 @@
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.RuntimeCall.Descriptor;
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
@@ -66,7 +66,7 @@
 
     @Override
     public void generate(LIRGenerator gen) {
-        RuntimeCall stub = gen.getRuntime().lookupRuntimeCall(NewMultiArrayStubCall.NEW_MULTI_ARRAY);
+        RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(NewMultiArrayStubCall.NEW_MULTI_ARRAY);
         Variable result = gen.emitCall(stub, stub.getCallingConvention(), true, gen.operand(hub), Constant.forInt(rank), gen.operand(dims));
         gen.setResult(this, result);
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java	Tue Dec 11 08:48:12 2012 +0100
@@ -23,10 +23,11 @@
 package com.oracle.graal.hotspot.nodes;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.RuntimeCall.Descriptor;
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.type.*;
@@ -60,8 +61,17 @@
             where = "in compiled code for " + MetaUtil.format("%H.%n(%p)", gen.method());
         }
 
-        RuntimeCall stub = gen.getRuntime().lookupRuntimeCall(VMErrorNode.VM_ERROR);
-        gen.emitCall(stub, stub.getCallingConvention(), false, Constant.forObject(where), gen.operand(format), gen.operand(value));
+        HotSpotRuntime runtime = (HotSpotRuntime) gen.getRuntime();
+        Constant whereArg = Constant.forObject(runtime.registerGCRoot(where));
+        Value formatArg;
+        if (format.isConstant() && format.kind() == Kind.Object) {
+            formatArg = Constant.forObject(runtime.registerGCRoot(format.asConstant().asObject()));
+        } else {
+            formatArg = gen.operand(format);
+        }
+
+        RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(VMErrorNode.VM_ERROR);
+        gen.emitCall(stub, stub.getCallingConvention(), false, whereArg, formatArg, gen.operand(value));
     }
 
     @NodeIntrinsic
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VerifyOopStubCall.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VerifyOopStubCall.java	Tue Dec 11 08:48:12 2012 +0100
@@ -23,7 +23,7 @@
 package com.oracle.graal.hotspot.nodes;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.RuntimeCall.Descriptor;
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
@@ -45,7 +45,7 @@
 
     @Override
     public void generate(LIRGenerator gen) {
-        RuntimeCall stub = gen.getRuntime().lookupRuntimeCall(VerifyOopStubCall.VERIFY_OOP);
+        RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(VerifyOopStubCall.VERIFY_OOP);
         gen.emitCall(stub, stub.getCallingConvention(), true, gen.operand(object));
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/OnStackReplacementPhase.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/OnStackReplacementPhase.java	Tue Dec 11 08:48:12 2012 +0100
@@ -23,7 +23,7 @@
 package com.oracle.graal.hotspot.phases;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.RuntimeCall.*;
+import com.oracle.graal.api.code.RuntimeCallTarget.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java	Tue Dec 11 08:48:12 2012 +0100
@@ -1,333 +1,485 @@
-/*
- * 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.snippets;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.Node.ConstantNodeParameter;
-import com.oracle.graal.graph.Node.NodeIntrinsic;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.hotspot.nodes.*;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.snippets.Snippet.Fold;
-import com.oracle.graal.snippets.*;
-
-//JaCoCo Exclude
-
-/**
- * A collection of methods used in HotSpot snippets.
- */
-public class HotSpotSnippetUtils {
-
-    @Fold
-    static boolean verifyOops() {
-        return HotSpotGraalRuntime.getInstance().getConfig().verifyOops;
-    }
-
-    @Fold
-    static int threadTlabTopOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().threadTlabTopOffset;
-    }
-
-    @Fold
-    static int threadTlabEndOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().threadTlabEndOffset;
-    }
-
-    @Fold
-    static int threadObjectOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().threadObjectOffset;
-    }
-
-    @Fold
-    static int osThreadOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().osThreadOffset;
-    }
-
-    @Fold
-    static int osThreadInterruptedOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().osThreadInterruptedOffset;
-    }
-
-    @Fold
-    static Kind wordKind() {
-        return HotSpotGraalRuntime.getInstance().getTarget().wordKind;
-    }
-
-    @Fold
-    static Register threadRegister() {
-        return HotSpotGraalRuntime.getInstance().getRuntime().threadRegister();
-    }
-
-    @Fold
-    static Register stackPointerRegister() {
-        return HotSpotGraalRuntime.getInstance().getRuntime().stackPointerRegister();
-    }
-
-    @Fold
-    static int wordSize() {
-        return HotSpotGraalRuntime.getInstance().getTarget().wordSize;
-    }
-
-    @Fold
-    static int pageSize() {
-        return HotSpotGraalRuntime.getInstance().getTarget().pageSize;
-    }
-
-    @Fold
-    static int prototypeMarkWordOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().prototypeMarkWordOffset;
-    }
-
-    @Fold
-    static int klassOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().klassOffset;
-    }
-
-    @Fold
-    static int klassModifierFlagsOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().klassModifierFlagsOffset;
-    }
-
-    @Fold
-    static int klassAccessFlagsOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().klassAccessFlagsOffset;
-    }
-
-    @Fold
-    static int klassLayoutHelperOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().klassLayoutHelperOffset;
-    }
-
-    @Fold
-    static int arrayKlassLayoutHelperIdentifier() {
-        return HotSpotGraalRuntime.getInstance().getConfig().arrayKlassLayoutHelperIdentifier;
-    }
-
-    @Fold
-    static int arrayKlassComponentMirrorOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().arrayKlassComponentMirrorOffset;
-    }
-
-    @Fold
-    static int klassSuperKlassOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().klassSuperKlassOffset;
-    }
-
-    @Fold
-    static int classMirrorOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().classMirrorOffset;
-    }
-
-    @Fold
-    static int markOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().markOffset;
-    }
-
-    @Fold
-    static int unlockedMask() {
-        return HotSpotGraalRuntime.getInstance().getConfig().unlockedMask;
-    }
-
-    /**
-     * Mask for a biasable, locked or unlocked mark word.
-     * <pre>
-     * +----------------------------------+-+-+
-     * |                                 1|1|1|
-     * +----------------------------------+-+-+
-     * </pre>
-     *
-     */
-    @Fold
-    static int biasedLockMaskInPlace() {
-        return HotSpotGraalRuntime.getInstance().getConfig().biasedLockMaskInPlace;
-    }
-
-    @Fold
-    static int epochMaskInPlace() {
-        return HotSpotGraalRuntime.getInstance().getConfig().epochMaskInPlace;
-    }
-
-    /**
-     * Pattern for a biasable, unlocked mark word.
-     * <pre>
-     * +----------------------------------+-+-+
-     * |                                 1|0|1|
-     * +----------------------------------+-+-+
-     * </pre>
-     *
-     */
-    @Fold
-    static int biasedLockPattern() {
-        return HotSpotGraalRuntime.getInstance().getConfig().biasedLockPattern;
-    }
-
-    @Fold
-    static int ageMaskInPlace() {
-        return HotSpotGraalRuntime.getInstance().getConfig().ageMaskInPlace;
-    }
-
-    @Fold
-    static int hubOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().hubOffset;
-    }
-
-    @Fold
-    static int metaspaceArrayLengthOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().metaspaceArrayLengthOffset;
-    }
-
-    @Fold
-    static int metaspaceArrayBaseOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().metaspaceArrayBaseOffset;
-    }
-
-    @Fold
-    static int arrayLengthOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().arrayLengthOffset;
-    }
-
-    @Fold
-    static int arrayBaseOffset(Kind elementKind) {
-        return HotSpotRuntime.getArrayBaseOffset(elementKind);
-    }
-
-    @Fold
-    static int arrayIndexScale(Kind elementKind) {
-        return HotSpotRuntime.getArrayIndexScale(elementKind);
-    }
-
-    @Fold
-    static int cardTableShift() {
-        return HotSpotGraalRuntime.getInstance().getConfig().cardtableShift;
-    }
-
-    @Fold
-    static long cardTableStart() {
-        return HotSpotGraalRuntime.getInstance().getConfig().cardtableStartAddress;
-    }
-
-    @Fold
-    static int superCheckOffsetOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().superCheckOffsetOffset;
-    }
-
-    @Fold
-    static int secondarySuperCacheOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().secondarySuperCacheOffset;
-    }
-
-    @Fold
-    static int secondarySupersOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().secondarySupersOffset;
-    }
-
-    @Fold
-    static int lockDisplacedMarkOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().basicLockDisplacedHeaderOffset;
-    }
-
-    @Fold
-    static boolean useBiasedLocking() {
-        return HotSpotGraalRuntime.getInstance().getConfig().useBiasedLocking;
-    }
-
-    @Fold
-    static int uninitializedIdentityHashCodeValue() {
-        return HotSpotGraalRuntime.getInstance().getConfig().uninitializedIdentityHashCodeValue;
-    }
-
-    @Fold
-    static int identityHashCodeShift() {
-        return HotSpotGraalRuntime.getInstance().getConfig().identityHashCodeShift;
-    }
-
-    /**
-     * Loads the hub from a object, null checking it first.
-     */
-    static Word loadHub(Object object) {
-        return loadHubIntrinsic(object, wordKind());
-    }
-
-    static Object verifyOop(Object object) {
-        if (verifyOops()) {
-            VerifyOopStubCall.call(object);
-        }
-        return object;
-    }
-
-    /**
-     * Gets the value of the stack pointer register as a Word.
-     */
-    static Word stackPointer() {
-        return HotSpotSnippetUtils.registerAsWord(stackPointerRegister());
-    }
-
-    /**
-     * Gets the value of the thread register as a Word.
-     */
-    static Word thread() {
-        return HotSpotSnippetUtils.registerAsWord(threadRegister());
-    }
-
-    static int loadIntFromWord(Word address, int offset) {
-        Integer value = UnsafeLoadNode.load(address, 0, offset, Kind.Int);
-        return value;
-    }
-
-    static Word loadWordFromWord(Word address, int offset) {
-        return loadWordFromWordIntrinsic(address, 0, offset, wordKind());
-    }
-
-    static Object loadObjectFromWord(Word address, int offset) {
-        return UnsafeLoadNode.load(address, 0, offset, Kind.Object);
-    }
-
-    static Word loadWordFromObject(Object object, int offset) {
-        return loadWordFromObjectIntrinsic(object, 0, offset, wordKind());
-    }
-
-    @NodeIntrinsic(value = RegisterNode.class, setStampFromReturnType = true)
-    public static native Word registerAsWord(@ConstantNodeParameter Register register);
-
-    @NodeIntrinsic(value = UnsafeLoadNode.class, setStampFromReturnType = true)
-    private static native Word loadWordFromObjectIntrinsic(Object object, @ConstantNodeParameter int displacement, long offset, @ConstantNodeParameter Kind wordKind);
-
-    @NodeIntrinsic(value = UnsafeLoadNode.class, setStampFromReturnType = true)
-    private static native Word loadWordFromWordIntrinsic(Word address, @ConstantNodeParameter int displacement, long offset, @ConstantNodeParameter Kind wordKind);
-
-    @NodeIntrinsic(value = LoadHubNode.class, setStampFromReturnType = true)
-    static native Word loadHubIntrinsic(Object object, @ConstantNodeParameter Kind word);
-
-    static {
-        assert arrayIndexScale(Kind.Byte) == 1;
-        assert arrayIndexScale(Kind.Boolean) == 1;
-        assert arrayIndexScale(Kind.Char) == 2;
-        assert arrayIndexScale(Kind.Short) == 2;
-        assert arrayIndexScale(Kind.Int) == 4;
-        assert arrayIndexScale(Kind.Long) == 8;
-        assert arrayIndexScale(Kind.Float) == 4;
-        assert arrayIndexScale(Kind.Double) == 8;
-    }
-}
+/*
+ * 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.snippets;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.Node.ConstantNodeParameter;
+import com.oracle.graal.graph.Node.NodeIntrinsic;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.snippets.Snippet.Fold;
+import com.oracle.graal.snippets.*;
+
+//JaCoCo Exclude
+
+/**
+ * A collection of methods used in HotSpot snippets.
+ */
+public class HotSpotSnippetUtils {
+
+    public static HotSpotVMConfig config() {
+        return HotSpotGraalRuntime.getInstance().getConfig();
+    }
+
+    @Fold
+    public static boolean verifyOops() {
+        return config().verifyOops;
+    }
+
+    @Fold
+    public static int threadTlabTopOffset() {
+        return config().threadTlabTopOffset;
+    }
+
+    @Fold
+    public static int threadTlabEndOffset() {
+        return config().threadTlabEndOffset;
+    }
+
+    @Fold
+    public static int threadObjectOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().threadObjectOffset;
+    }
+
+    @Fold
+    public static int osThreadOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().osThreadOffset;
+    }
+
+    @Fold
+    public static int osThreadInterruptedOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().osThreadInterruptedOffset;
+    }
+
+    @Fold
+    public static Kind wordKind() {
+        return HotSpotGraalRuntime.getInstance().getTarget().wordKind;
+    }
+
+    @Fold
+    public static Register threadRegister() {
+        return HotSpotGraalRuntime.getInstance().getRuntime().threadRegister();
+    }
+
+    @Fold
+    public static Register stackPointerRegister() {
+        return HotSpotGraalRuntime.getInstance().getRuntime().stackPointerRegister();
+    }
+
+    @Fold
+    public static int wordSize() {
+        return HotSpotGraalRuntime.getInstance().getTarget().wordSize;
+    }
+
+    @Fold
+    public static int pageSize() {
+        return HotSpotGraalRuntime.getInstance().getTarget().pageSize;
+    }
+
+    @Fold
+    public static int prototypeMarkWordOffset() {
+        return config().prototypeMarkWordOffset;
+    }
+
+    @Fold
+    public static long arrayPrototypeMarkWord() {
+        return config().arrayPrototypeMarkWord;
+    }
+    
+    @Fold
+    public static int klassOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().klassOffset;
+    }
+   
+    @Fold
+    public static int klassModifierFlagsOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().klassModifierFlagsOffset;
+    }
+
+    @Fold
+    public static int klassAccessFlagsOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().klassAccessFlagsOffset;
+    }
+
+    @Fold
+    public static int klassLayoutHelperOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().klassLayoutHelperOffset;
+    }
+
+    @Fold
+    public static int arrayKlassLayoutHelperIdentifier() {
+        return HotSpotGraalRuntime.getInstance().getConfig().arrayKlassLayoutHelperIdentifier;
+    }
+
+    @Fold
+    public static int arrayKlassComponentMirrorOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().arrayKlassComponentMirrorOffset;
+    }
+
+    @Fold
+    public static int klassSuperKlassOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().klassSuperKlassOffset;
+    }
+
+    @Fold
+    public static int classMirrorOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().classMirrorOffset;
+    }
+
+    @Fold
+    public static int markOffset() {
+        return config().markOffset;   
+    }
+
+    @Fold
+    public static int unlockedMask() {
+        return config().unlockedMask;
+    }
+
+    /**
+     * Mask for a biasable, locked or unlocked mark word.
+     * <pre>
+     * +----------------------------------+-+-+
+     * |                                 1|1|1|
+     * +----------------------------------+-+-+
+     * </pre>
+     *
+     */
+    @Fold
+    public static int biasedLockMaskInPlace() {
+        return config().biasedLockMaskInPlace;
+    }
+
+    @Fold
+    public static int epochMaskInPlace() {
+        return config().epochMaskInPlace;
+    }
+
+    /**
+     * Pattern for a biasable, unlocked mark word.
+     * <pre>
+     * +----------------------------------+-+-+
+     * |                                 1|0|1|
+     * +----------------------------------+-+-+
+     * </pre>
+     *
+     */
+    @Fold
+    public static int biasedLockPattern() {
+        return config().biasedLockPattern;
+    }
+
+    @Fold
+    public static int ageMaskInPlace() {
+        return config().ageMaskInPlace;
+    }
+
+    @Fold
+    public static int hubOffset() {
+        return config().hubOffset;
+    }
+
+    @Fold
+    public static int metaspaceArrayLengthOffset() {
+        return config().metaspaceArrayLengthOffset;
+    }
+
+    @Fold
+    public static int metaspaceArrayBaseOffset() {
+        return config().metaspaceArrayBaseOffset;
+    }
+
+    @Fold
+    public static int arrayLengthOffset() {
+        return config().arrayLengthOffset;
+    }
+
+    @Fold
+    public static int arrayBaseOffset(Kind elementKind) {
+        return HotSpotRuntime.getArrayBaseOffset(elementKind);
+    }
+
+    @Fold
+    public static int arrayIndexScale(Kind elementKind) {
+        return HotSpotRuntime.getArrayIndexScale(elementKind);
+    }
+
+    @Fold
+    public static int cardTableShift() {
+        return config().cardtableShift;
+    }
+
+    @Fold
+    public static long cardTableStart() {
+        return config().cardtableStartAddress;
+    }
+
+    @Fold
+    public static int superCheckOffsetOffset() {
+        return config().superCheckOffsetOffset;
+    }
+
+    @Fold
+    public static int secondarySuperCacheOffset() {
+        return config().secondarySuperCacheOffset;
+    }
+
+    @Fold
+    public static int secondarySupersOffset() {
+        return config().secondarySupersOffset;
+    }
+
+    @Fold
+    public static int lockDisplacedMarkOffset() {
+        return config().basicLockDisplacedHeaderOffset;
+    }
+
+    @Fold
+    public static boolean useBiasedLocking() {
+        return config().useBiasedLocking;
+    }
+
+    @Fold
+    static int uninitializedIdentityHashCodeValue() {
+        return HotSpotGraalRuntime.getInstance().getConfig().uninitializedIdentityHashCodeValue;
+    }
+
+    @Fold
+    static int identityHashCodeShift() {
+        return HotSpotGraalRuntime.getInstance().getConfig().identityHashCodeShift;
+    }
+
+    /**
+     * Loads the hub from a object, null checking it first.
+     */
+    public static Word loadHub(Object object) {
+        return loadHubIntrinsic(object, wordKind());
+    }
+
+    public static Object verifyOop(Object object) {
+        if (verifyOops()) {
+            VerifyOopStubCall.call(object);
+        }
+        return object;
+    }
+
+    /**
+     * Gets the value of the stack pointer register as a Word.
+     */
+    public static Word stackPointer() {
+        return HotSpotSnippetUtils.registerAsWord(stackPointerRegister());
+    }
+
+    /**
+     * Gets the value of the thread register as a Word.
+     */
+    public static Word thread() {
+        return HotSpotSnippetUtils.registerAsWord(threadRegister());
+    }
+
+    public static int loadIntFromWord(Word address, int offset) {
+        Integer value = UnsafeLoadNode.load(address, 0, offset, Kind.Int);
+        return value;
+    }
+
+    public static Word loadWordFromWord(Word address, int offset) {
+        return loadWordFromWordIntrinsic(address, 0, offset, wordKind());
+    }
+
+    static Object loadObjectFromWord(Word address, int offset) {
+        return UnsafeLoadNode.load(address, 0, offset, Kind.Object);
+    }
+
+    public static Word loadWordFromObject(Object object, int offset) {
+        return loadWordFromObjectIntrinsic(object, 0, offset, wordKind());
+    }
+
+    @NodeIntrinsic(value = RegisterNode.class, setStampFromReturnType = true)
+    public static native Word registerAsWord(@ConstantNodeParameter Register register);
+
+    @NodeIntrinsic(value = UnsafeLoadNode.class, setStampFromReturnType = true)
+    private static native Word loadWordFromObjectIntrinsic(Object object, @ConstantNodeParameter int displacement, long offset, @ConstantNodeParameter Kind wordKind);
+
+    @NodeIntrinsic(value = UnsafeLoadNode.class, setStampFromReturnType = true)
+    private static native Word loadWordFromWordIntrinsic(Word address, @ConstantNodeParameter int displacement, long offset, @ConstantNodeParameter Kind wordKind);
+
+    @NodeIntrinsic(value = LoadHubNode.class, setStampFromReturnType = true)
+    static native Word loadHubIntrinsic(Object object, @ConstantNodeParameter Kind word);
+
+    @Fold
+    public
+    static int log2WordSize() {
+        return CodeUtil.log2(wordSize());
+    }
+
+    @Fold
+    public
+    static int klassStateOffset() {
+        return config().klassStateOffset;
+    }
+
+    @Fold
+    public
+    static int klassInstanceSizeOffset() {
+        return config().klassInstanceSizeOffset;
+    }
+
+    @Fold
+    public
+    static long heapTopAddress() {
+        return config().heapTopAddress;
+    }
+
+    @Fold
+    public
+    static long heapEndAddress() {
+        return config().heapEndAddress;
+    }
+
+    @Fold
+    public
+    static int threadTlabStartOffset() {
+        return config().threadTlabStartOffset;
+    }
+
+    @Fold
+    public
+    static long tlabIntArrayMarkWord() {
+        return config().tlabIntArrayMarkWord;
+    }
+
+    @Fold
+    public
+    static boolean inlineContiguousAllocationSupported() {
+        return config().inlineContiguousAllocationSupported;
+    }
+
+    @Fold
+    public
+    static int tlabAlignmentReserveInHeapWords() {
+        return config().tlabAlignmentReserve;
+    }
+
+    @Fold
+    public
+    static int threadTlabSizeOffset() {
+        return config().threadTlabSizeOffset;
+    }
+
+    @Fold
+    public
+    static int threadAllocatedBytesOffset() {
+        return config().threadAllocatedBytesOffset;
+    }
+
+    @Fold
+    public
+    static int klassStateFullyInitialized() {
+        return config().klassStateFullyInitialized;
+    }
+
+    @Fold
+    public
+    static int tlabRefillWasteLimitOffset() {
+        return config().tlabRefillWasteLimitOffset;
+    }
+
+    @Fold
+    public
+    static int tlabNumberOfRefillsOffset() {
+        return config().tlabNumberOfRefillsOffset;
+    }
+
+    @Fold
+    public
+    static int tlabFastRefillWasteOffset() {
+        return config().tlabFastRefillWasteOffset;
+    }
+
+    @Fold
+    public
+    static int tlabSlowAllocationsOffset() {
+        return config().tlabSlowAllocationsOffset;
+    }
+
+    @Fold
+    public
+    static int tlabRefillWasteIncrement() {
+        return config().tlabRefillWasteIncrement;
+    }
+
+    @Fold
+    public
+    static boolean tlabStats() {
+        return config().tlabStats;
+    }
+
+    @Fold
+    public static int layoutHelperOffset() {
+        return config().layoutHelperOffset;
+    }
+
+    @Fold
+    public static int layoutHelperHeaderSizeShift() {
+        return config().layoutHelperHeaderSizeShift;
+    }
+
+    @Fold
+    public static int layoutHelperHeaderSizeMask() {
+        return config().layoutHelperHeaderSizeMask;
+    }
+
+    @Fold
+    public static int layoutHelperLog2ElementSizeShift() {
+        return config().layoutHelperLog2ElementSizeShift;
+    }
+
+    @Fold
+    public static int layoutHelperLog2ElementSizeMask() {
+        return config().layoutHelperLog2ElementSizeMask;
+    }
+
+    @Fold
+    public static int layoutHelperElementTypeShift() {
+        return config().layoutHelperElementTypeShift;
+    }
+
+    @Fold
+    public static int layoutHelperElementTypeMask() {
+        return config().layoutHelperElementTypeMask;
+    }
+
+    static {
+        assert arrayIndexScale(Kind.Byte) == 1;
+        assert arrayIndexScale(Kind.Boolean) == 1;
+        assert arrayIndexScale(Kind.Char) == 2;
+        assert arrayIndexScale(Kind.Short) == 2;
+        assert arrayIndexScale(Kind.Int) == 4;
+        assert arrayIndexScale(Kind.Long) == 8;
+        assert arrayIndexScale(Kind.Float) == 4;
+        assert arrayIndexScale(Kind.Double) == 8;
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/MonitorSnippets.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/MonitorSnippets.java	Tue Dec 11 08:48:12 2012 +0100
@@ -37,6 +37,7 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.graph.iterators.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
@@ -520,7 +521,8 @@
                     List<ReturnNode> rets = graph.getNodes().filter(ReturnNode.class).snapshot();
                     for (ReturnNode ret : rets) {
                         returnType = checkCounter.getSignature().getReturnType(checkCounter.getDeclaringClass());
-                        ConstantNode errMsg = ConstantNode.forObject("unbalanced monitors in " + MetaUtil.format("%H.%n(%p)", graph.method()) + ", count = %d", runtime, graph);
+                        Object msg = ((HotSpotRuntime) runtime).registerGCRoot("unbalanced monitors in " + MetaUtil.format("%H.%n(%p)", graph.method()) + ", count = %d");
+                        ConstantNode errMsg = ConstantNode.forObject(msg, runtime, graph);
                         callTarget = graph.add(new MethodCallTargetNode(InvokeKind.Static, checkCounter, new ValueNode[] {errMsg}, returnType));
                         invoke = graph.add(new InvokeNode(callTarget, 0, -1));
                         List<ValueNode> stack = Collections.emptyList();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java	Tue Dec 11 08:48:12 2012 +0100
@@ -95,55 +95,30 @@
     }
 
     @Snippet
-    public static Object initializeObjectArray(
+    public static Object initializeArray(
                     @Parameter("memory") Word memory,
                     @Parameter("hub") Word hub,
                     @Parameter("length") int length,
-                    @Parameter("size") int size,
+                    @Parameter("allocationSize") int allocationSize,
                     @Parameter("prototypeMarkWord") Word prototypeMarkWord,
                     @ConstantParameter("headerSize") int headerSize,
                     @ConstantParameter("fillContents") boolean fillContents,
                     @ConstantParameter("locked") boolean locked) {
         if (locked) {
-            return initializeArray(memory, hub, length, size, thread().or(biasedLockPattern()), headerSize, true, fillContents);
+            return initializeArray(memory, hub, length, allocationSize, thread().or(biasedLockPattern()), headerSize, fillContents);
         } else {
-            return initializeArray(memory, hub, length, size, prototypeMarkWord, headerSize, true, fillContents);
+            return initializeArray(memory, hub, length, allocationSize, prototypeMarkWord, headerSize, fillContents);
         }
     }
 
-    @Snippet
-    public static Object initializePrimitiveArray(
-                    @Parameter("memory") Word memory,
-                    @Parameter("hub") Word hub,
-                    @Parameter("length") int length,
-                    @Parameter("size") int size,
-                    @Parameter("prototypeMarkWord") Word prototypeMarkWord,
-                    @ConstantParameter("headerSize") int headerSize,
-                    @ConstantParameter("fillContents") boolean fillContents,
-                    @ConstantParameter("locked") boolean locked) {
-        if (locked) {
-            return initializeArray(memory, hub, length, size, thread().or(biasedLockPattern()), headerSize, false, fillContents);
-        } else {
-            return initializeArray(memory, hub, length, size, prototypeMarkWord, headerSize, false, fillContents);
-        }
-    }
-
-    private static Object initializeArray(Word memory, Word hub, int length, int size, Word prototypeMarkWord, int headerSize, boolean isObjectArray, boolean fillContents) {
+    private static Object initializeArray(Word memory, Word hub, int length, int allocationSize, Word prototypeMarkWord, int headerSize, boolean fillContents) {
         Object result;
         if (memory == Word.zero()) {
-            if (isObjectArray) {
-                anewarray_stub.inc();
-            } else {
-                newarray_stub.inc();
-            }
-            result = NewArrayStubCall.call(isObjectArray, hub, length);
+            newarray_stub.inc();
+            result = NewArrayStubCall.call(hub, length);
         } else {
-            if (isObjectArray) {
-                anewarray_loopInit.inc();
-            } else {
-                newarray_loopInit.inc();
-            }
-            formatArray(hub, size, length, headerSize, memory, prototypeMarkWord, fillContents);
+            newarray_loopInit.inc();
+            formatArray(hub, allocationSize, length, headerSize, memory, prototypeMarkWord, fillContents);
             result = memory.toObject();
         }
         return unsafeArrayCast(verifyOop(result), length, StampFactory.forNodeIntrinsic());
@@ -152,7 +127,7 @@
     /**
      * Maximum array length for which fast path allocation is used.
      */
-    private static final int MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH = 0x00FFFFFF;
+    public static final int MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH = 0x00FFFFFF;
 
     @Snippet
     public static Object allocateArrayAndInitialize(
@@ -165,12 +140,21 @@
             // This handles both negative array sizes and very large array sizes
             DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.RuntimeConstraint);
         }
-        int size = getArraySize(length, alignment, headerSize, log2ElementSize);
-        Word memory = TLABAllocateNode.allocateVariableSize(size);
-        return InitializeArrayNode.initialize(memory, length, size, type, true, false);
+        int allocationSize = computeArrayAllocationSize(length, alignment, headerSize, log2ElementSize);
+        Word memory = TLABAllocateNode.allocateVariableSize(allocationSize);
+        return InitializeArrayNode.initialize(memory, length, allocationSize, type, true, false);
     }
 
-    public static int getArraySize(int length, int alignment, int headerSize, int log2ElementSize) {
+    /**
+     * Computes the size of the memory chunk allocated for an array. This size accounts for the array
+     * header size, boy size and any padding after the last element to satisfy object alignment requirements.
+     *
+     * @param length the number of elements in the array
+     * @param alignment the object alignment requirement
+     * @param headerSize the size of the array header
+     * @param log2ElementSize log2 of the size of an element in the array
+     */
+    public static int computeArrayAllocationSize(int length, int alignment, int headerSize, int log2ElementSize) {
         int size = (length << log2ElementSize) + headerSize + (alignment - 1);
         int mask = ~(alignment - 1);
         return size & mask;
@@ -225,12 +209,13 @@
     /**
      * Formats some allocated memory with an object header zeroes out the rest.
      */
-    private static void formatArray(Word hub, int size, int length, int headerSize, Word memory, Word prototypeMarkWord, boolean fillContents) {
+    public static void formatArray(Word hub, int allocationSize, int length, int headerSize, Word memory, Word prototypeMarkWord, boolean fillContents) {
         storeWord(memory, 0, markOffset(), prototypeMarkWord);
+        storeInt(memory, 0, arrayLengthOffset(), length);
+        // store hub last as the concurrent garbage collectors assume length is valid if hub field is not null
         storeWord(memory, 0, hubOffset(), hub);
-        storeInt(memory, 0, arrayLengthOffset(), length);
         if (fillContents) {
-            for (int offset = headerSize; offset < size; offset += wordSize()) {
+            for (int offset = headerSize; offset < allocationSize; offset += wordSize()) {
                 storeWord(memory, 0, offset, Word.zero());
             }
         }
@@ -240,8 +225,7 @@
 
         private final ResolvedJavaMethod allocate;
         private final ResolvedJavaMethod initializeObject;
-        private final ResolvedJavaMethod initializeObjectArray;
-        private final ResolvedJavaMethod initializePrimitiveArray;
+        private final ResolvedJavaMethod initializeArray;
         private final ResolvedJavaMethod allocateArrayAndInitialize;
         private final ResolvedJavaMethod newmultiarray;
         private final TargetDescription target;
@@ -253,8 +237,7 @@
             this.useTLAB = useTLAB;
             allocate = snippet("allocate", int.class);
             initializeObject = snippet("initializeObject", Word.class, Word.class, Word.class, int.class, boolean.class, boolean.class);
-            initializeObjectArray = snippet("initializeObjectArray", Word.class, Word.class, int.class, int.class, Word.class, int.class, boolean.class, boolean.class);
-            initializePrimitiveArray = snippet("initializePrimitiveArray", Word.class, Word.class, int.class, int.class, Word.class, int.class, boolean.class, boolean.class);
+            initializeArray = snippet("initializeArray", Word.class, Word.class, int.class, int.class, Word.class, int.class, boolean.class, boolean.class);
             allocateArrayAndInitialize = snippet("allocateArrayAndInitialize", int.class, int.class, int.class, int.class, ResolvedJavaType.class);
             newmultiarray = snippet("newmultiarray", Word.class, int.class, int[].class);
         }
@@ -308,7 +291,7 @@
                 graph.replaceFixedWithFixed(newArrayNode, initializeNode);
             } else if (length != null && belowThan(length, MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH)) {
                 // Calculate aligned size
-                int size = getArraySize(length, alignment, headerSize, log2ElementSize);
+                int size = computeArrayAllocationSize(length, alignment, headerSize, log2ElementSize);
                 ConstantNode sizeNode = ConstantNode.forInt(size, graph);
                 tlabAllocateNode = graph.add(new TLABAllocateNode(sizeNode));
                 graph.addBeforeFixed(newArrayNode, tlabAllocateNode);
@@ -364,11 +347,11 @@
             ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, graph);
             Kind elementKind = elementType.getKind();
             final int headerSize = HotSpotRuntime.getArrayBaseOffset(elementKind);
-            Key key = new Key(elementKind == Kind.Object ? initializeObjectArray : initializePrimitiveArray).add("headerSize", headerSize).add("fillContents", initializeNode.fillContents()).add("locked", initializeNode.locked());
+            Key key = new Key(initializeArray).add("headerSize", headerSize).add("fillContents", initializeNode.fillContents()).add("locked", initializeNode.locked());
             ValueNode memory = initializeNode.memory();
-            Arguments arguments = arguments("memory", memory).add("hub", hub).add("prototypeMarkWord", type.prototypeMarkWord()).add("size", initializeNode.size()).add("length", initializeNode.length());
+            Arguments arguments = arguments("memory", memory).add("hub", hub).add("prototypeMarkWord", type.prototypeMarkWord()).add("allocationSize", initializeNode.allocationSize()).add("length", initializeNode.length());
             SnippetTemplate template = cache.get(key, assumptions);
-            Debug.log("Lowering initializeObjectArray in %s: node=%s, template=%s, arguments=%s", graph, initializeNode, template, arguments);
+            Debug.log("Lowering initializeArray in %s: node=%s, template=%s, arguments=%s", graph, initializeNode, template, arguments);
             template.instantiate(runtime, initializeNode, DEFAULT_REPLACER, arguments);
         }
 
@@ -394,11 +377,7 @@
     private static final SnippetCounter new_loopInit = new SnippetCounter(countersNew, "tlabLoopInit", "TLAB alloc with zeroing in a loop");
     private static final SnippetCounter new_stub = new SnippetCounter(countersNew, "stub", "alloc and zeroing via stub");
 
-    private static final SnippetCounter.Group countersNewPrimitiveArray = GraalOptions.SnippetCounters ? new SnippetCounter.Group("NewPrimitiveArray") : null;
-    private static final SnippetCounter newarray_loopInit = new SnippetCounter(countersNewPrimitiveArray, "tlabLoopInit", "TLAB alloc with zeroing in a loop");
-    private static final SnippetCounter newarray_stub = new SnippetCounter(countersNewPrimitiveArray, "stub", "alloc and zeroing via stub");
-
-    private static final SnippetCounter.Group countersNewObjectArray = GraalOptions.SnippetCounters ? new SnippetCounter.Group("NewObjectArray") : null;
-    private static final SnippetCounter anewarray_loopInit = new SnippetCounter(countersNewObjectArray, "tlabLoopInit", "TLAB alloc with zeroing in a loop");
-    private static final SnippetCounter anewarray_stub = new SnippetCounter(countersNewObjectArray, "stub", "alloc and zeroing via stub");
+    private static final SnippetCounter.Group countersNewArray = GraalOptions.SnippetCounters ? new SnippetCounter.Group("NewArray") : null;
+    private static final SnippetCounter newarray_loopInit = new SnippetCounter(countersNewArray, "tlabLoopInit", "TLAB alloc with zeroing in a loop");
+    private static final SnippetCounter newarray_stub = new SnippetCounter(countersNewArray, "stub", "alloc and zeroing via stub");
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/SystemSnippets.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/SystemSnippets.java	Tue Dec 11 08:48:12 2012 +0100
@@ -22,9 +22,9 @@
  */
 package com.oracle.graal.hotspot.snippets;
 
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
 import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
 
-import com.oracle.graal.api.code.RuntimeCall.Descriptor;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Tue Dec 11 08:48:12 2012 +0100
@@ -0,0 +1,104 @@
+/*
+ * 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.stubs;
+
+import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
+import static com.oracle.graal.hotspot.snippets.NewObjectSnippets.*;
+import static com.oracle.graal.hotspot.stubs.NewInstanceStub.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.hotspot.snippets.*;
+import com.oracle.graal.snippets.*;
+import com.oracle.graal.snippets.Snippet.ConstantParameter;
+import com.oracle.graal.snippets.Snippet.Parameter;
+import com.oracle.graal.snippets.SnippetTemplate.Key;
+
+/**
+ * Stub implementing the fast path for TLAB refill during instance class allocation.
+ * This stub is called from the {@linkplain NewObjectSnippets inline} allocation
+ * code when TLAB allocation fails. If this stub fails to refill the TLAB
+ * or allocate the object, it calls out to the HotSpot C++ runtime for
+ * to complete the allocation.
+ */
+public class NewArrayStub extends Stub {
+
+    public NewArrayStub(final HotSpotRuntime runtime, Assumptions assumptions, TargetDescription target) {
+        super(runtime, assumptions, target, NewArrayStubCall.NEW_ARRAY);
+    }
+
+    @Override
+    protected void populateKey(Key key) {
+        HotSpotResolvedObjectType intArrayType = (HotSpotResolvedObjectType) runtime.lookupJavaType(int[].class);
+        Constant intArrayHub = intArrayType.klass();
+        key.add("intArrayHub", intArrayHub);
+    }
+
+    /**
+     * Re-attempts allocation after an initial TLAB allocation failed or was skipped (e.g., due to -XX:-UseTLAB).
+     *
+     * @param hub the hub of the object to be allocated
+     * @param length the length of the array
+     * @param intArrayHub the hub for {@code int[].class}
+     */
+    @Snippet
+    private static Object newArray(@Parameter("hub") Word hub, @Parameter("length") int length, @ConstantParameter("intArrayHub") Word intArrayHub) {
+        int layoutHelper = loadIntFromWord(hub, layoutHelperOffset());
+        int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask();
+        int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift()) & layoutHelperHeaderSizeMask();
+        int elementKind = (layoutHelper >> layoutHelperElementTypeShift()) & layoutHelperElementTypeMask();
+        int sizeInBytes = computeArrayAllocationSize(length, wordSize(), headerSize, log2ElementSize);
+        logf("newArray: element kind %d\n", elementKind);
+        logf("newArray: array length %d\n", length);
+        logf("newArray: array size %d\n", sizeInBytes);
+        logf("newArray: hub=%p\n", hub.toLong());
+
+        // check that array length is small enough for fast path.
+        if (length <= MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH) {
+            Word memory;
+            if (refillTLAB(intArrayHub, Word.fromLong(tlabIntArrayMarkWord()), tlabAlignmentReserveInHeapWords() * wordSize())) {
+                memory = allocate(sizeInBytes);
+            } else {
+                logf("newArray: allocating directly in eden\n", 0L);
+                memory = edenAllocate(Word.fromInt(sizeInBytes));
+            }
+            if (memory != Word.zero()) {
+                logf("newArray: allocated new array at %p\n", memory.toLong());
+                formatArray(hub, sizeInBytes, length, headerSize, memory, Word.fromLong(arrayPrototypeMarkWord()), true);
+                return verifyOop(memory.toObject());
+            }
+        }
+        logf("newArray: calling new_array_slow", 0L);
+        return verifyOop(NewArraySlowStubCall.call(hub, length));
+    }
+
+    private static final boolean LOGGING_ENABLED = Boolean.getBoolean("graal.logNewArrayStub");
+
+    private static void logf(String format, long value) {
+        if (LOGGING_ENABLED) {
+            Log.printf(format, value);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Tue Dec 11 08:48:12 2012 +0100
@@ -0,0 +1,225 @@
+/*
+ * 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.stubs;
+
+import static com.oracle.graal.hotspot.nodes.DirectCompareAndSwapNode.*;
+import static com.oracle.graal.hotspot.nodes.NewInstanceStubCall.*;
+import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
+import static com.oracle.graal.hotspot.snippets.NewObjectSnippets.*;
+import static com.oracle.graal.snippets.nodes.DirectObjectStoreNode.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.hotspot.snippets.*;
+import com.oracle.graal.snippets.*;
+import com.oracle.graal.snippets.Snippet.ConstantParameter;
+import com.oracle.graal.snippets.Snippet.Parameter;
+import com.oracle.graal.snippets.SnippetTemplate.Key;
+
+/**
+ * Stub implementing the fast path for TLAB refill during instance class allocation.
+ * This stub is called from the {@linkplain NewObjectSnippets inline} allocation
+ * code when TLAB allocation fails. If this stub fails to refill the TLAB
+ * or allocate the object, it calls out to the HotSpot C++ runtime for
+ * to complete the allocation.
+ */
+public class NewInstanceStub extends Stub {
+
+    public NewInstanceStub(final HotSpotRuntime runtime, Assumptions assumptions, TargetDescription target) {
+        super(runtime, assumptions, target, NEW_INSTANCE);
+    }
+
+    @Override
+    protected void populateKey(Key key) {
+        HotSpotResolvedObjectType intArrayType = (HotSpotResolvedObjectType) runtime.lookupJavaType(int[].class);
+        Constant intArrayHub = intArrayType.klass();
+        key.add("intArrayHub", intArrayHub);
+    }
+
+    /**
+     * Re-attempts allocation after an initial TLAB allocation failed or was skipped (e.g., due to -XX:-UseTLAB).
+     *
+     * @param hub the hub of the object to be allocated
+     * @param intArrayHub the hub for {@code int[].class}
+     */
+    @Snippet
+    private static Object newInstance(@Parameter("hub") Word hub, @ConstantParameter("intArrayHub") Word intArrayHub) {
+        int sizeInBytes = loadIntFromWord(hub, klassInstanceSizeOffset());
+        logf("newInstance: size %d\n", sizeInBytes);
+        if (inlineContiguousAllocationSupported()) {
+            if (loadIntFromWord(hub, klassStateOffset()) == klassStateFullyInitialized()) {
+                Word memory;
+                if (refillTLAB(intArrayHub, Word.fromLong(tlabIntArrayMarkWord()), tlabAlignmentReserveInHeapWords() * wordSize())) {
+                    memory = allocate(sizeInBytes);
+                } else {
+                    logf("newInstance: allocating directly in eden\n", 0L);
+                    memory = edenAllocate(Word.fromInt(sizeInBytes));
+                }
+                if (memory != Word.zero()) {
+                    logf("newInstance: allocated new object at %p\n", memory.toLong());
+                    Word prototypeMarkWord = loadWordFromWord(hub, prototypeMarkWordOffset());
+                    storeWord(memory, 0, markOffset(), prototypeMarkWord);
+                    storeWord(memory, 0, hubOffset(), hub);
+                    for (int offset = 2 * wordSize(); offset < sizeInBytes; offset += wordSize()) {
+                        storeWord(memory, 0, offset, Word.zero());
+                    }
+                    return verifyOop(memory.toObject());
+                }
+            }
+        }
+        logf("newInstance: calling new_instance_slow", 0L);
+        return verifyOop(NewInstanceSlowStubCall.call(hub));
+    }
+
+    /**
+     * Attempts to refill the current thread's TLAB.
+     *
+     * @param intArrayHub the hub for {@code int[].class}
+     * @param intArrayMarkWord the mark word for the int array placed in the left over TLAB space
+     * @param alignmentReserveInBytes the amount of extra bytes to reserve in a new TLAB
+     * @return whether or not a new TLAB was allocated
+     */
+    static boolean refillTLAB(Word intArrayHub, Word intArrayMarkWord, int alignmentReserveInBytes) {
+
+        Word thread = thread();
+        Word top = loadWordFromWord(thread, threadTlabTopOffset());
+        Word end = loadWordFromWord(thread, threadTlabEndOffset());
+
+        // calculate amount of free space
+        Word tlabFreeSpaceInBytes = end.minus(top);
+
+        logf("refillTLAB: thread=%p\n", thread.toLong());
+        logf("refillTLAB: top=%p\n", top.toLong());
+        logf("refillTLAB: end=%p\n", end.toLong());
+        logf("refillTLAB: tlabFreeSpaceInBytes=%d\n", tlabFreeSpaceInBytes.toLong());
+
+        // a DIV or SHR operations on Words would be handy here...
+        Word tlabFreeSpaceInWords = Word.fromLong(tlabFreeSpaceInBytes.toLong() >>> log2WordSize());
+
+        // Retain TLAB and allocate object in shared space if
+        // the amount free in the TLAB is too large to discard.
+        if (tlabFreeSpaceInWords.belowOrEqual(loadWordFromWord(thread, tlabRefillWasteLimitOffset()))) {
+            logf("refillTLAB: discarding TLAB\n", 0L);
+
+            if (tlabStats()) {
+                // increment number of refills
+                storeInt(thread, 0, tlabNumberOfRefillsOffset(), loadIntFromWord(thread, tlabNumberOfRefillsOffset()) + 1);
+                // accumulate wastage
+                storeWord(thread, 0, tlabFastRefillWasteOffset(), loadWordFromWord(thread, tlabFastRefillWasteOffset()).plus(tlabFreeSpaceInWords));
+            }
+
+            // if TLAB is currently allocated (top or end != null) then
+            // fill [top, end + alignment_reserve) with array object
+            if (top != Word.zero()) {
+                int headerSize = arrayBaseOffset(Kind.Int);
+                // just like the HotSpot assembler stubs, assumes that tlabFreeSpaceInInts fits in an int
+                int tlabFreeSpaceInInts = (int) tlabFreeSpaceInBytes.toLong() >>> 2;
+                int length = ((alignmentReserveInBytes - headerSize) >>> 2) + tlabFreeSpaceInInts;
+                logf("refillTLAB: alignmentReserveInBytes %d\n", alignmentReserveInBytes);
+                logf("refillTLAB: headerSize %d\n", headerSize);
+                logf("refillTLAB: filler.length %d\n", length);
+                NewObjectSnippets.formatArray(intArrayHub, -1, length, headerSize, top, intArrayMarkWord, false);
+
+                Word allocated = loadWordFromWord(thread, threadAllocatedBytesOffset());
+                allocated = allocated.plus(top.minus(loadWordFromWord(thread, threadTlabStartOffset())));
+                storeWord(thread, 0, threadAllocatedBytesOffset(), allocated);
+            }
+
+            // refill the TLAB with an eden allocation
+            Word tlabRefillSizeInWords = loadWordFromWord(thread, threadTlabSizeOffset());
+            Word tlabRefillSizeInBytes = Word.fromLong(tlabRefillSizeInWords.toLong() * wordSize());
+            // allocate new TLAB, address returned in top
+            top = edenAllocate(tlabRefillSizeInBytes);
+            if (top != Word.zero()) {
+                storeWord(thread, 0, threadTlabStartOffset(), top);
+                storeWord(thread, 0, threadTlabTopOffset(), top);
+
+                end = top.plus(tlabRefillSizeInBytes.minus(alignmentReserveInBytes));
+                storeWord(thread, 0, threadTlabEndOffset(), end);
+                logf("refillTLAB: top'=%p\n", top.toLong());
+                logf("refillTLAB: start'=%p\n", top.toLong());
+                logf("refillTLAB: end'=%p\n", end.toLong());
+                return true;
+            } else {
+                return false;
+            }
+        } else {
+            // Retain TLAB
+            Word newRefillWasteLimit = loadWordFromWord(thread, tlabRefillWasteLimitOffset()).plus(tlabRefillWasteIncrement());
+            storeWord(thread, 0, tlabRefillWasteLimitOffset(), newRefillWasteLimit);
+            logf("refillTLAB: retaining TLAB - newRefillWasteLimit=%p\n", newRefillWasteLimit.toLong());
+
+            if (tlabStats()) {
+                storeInt(thread, 0, tlabSlowAllocationsOffset(), loadIntFromWord(thread, tlabSlowAllocationsOffset()) + 1);
+            }
+
+            return false;
+        }
+    }
+
+    /**
+     * Attempts to allocate a chunk of memory from Eden space.
+     *
+     * @param sizeInBytes the size of the chunk to allocate
+     * @return the allocated chunk or {@link Word#zero()} if allocation fails
+     */
+    static Word edenAllocate(Word sizeInBytes) {
+        Word heapTopAddress = Word.fromLong(heapTopAddress());
+        Word heapEndAddress = Word.fromLong(heapEndAddress());
+        logf("edenAllocate: heapTopAddress %p\n", heapTopAddress.toLong());
+        logf("edenAllocate: heapEndAddress %p\n", heapEndAddress.toLong());
+
+        while (true) {
+            Word heapTop = loadWordFromWord(heapTopAddress, 0);
+            Word newHeapTop = heapTop.plus(sizeInBytes);
+            logf("edenAllocate: heapTop %p\n", heapTop.toLong());
+            logf("edenAllocate: newHeapTop %p\n", newHeapTop.toLong());
+            if (newHeapTop.belowOrEqual(heapTop)) {
+                logf("edenAllocate: fail 1\n", 0L);
+                return Word.zero();
+            }
+
+            Word heapEnd = loadWordFromWord(heapEndAddress, 0);
+            logf("edenAllocate: heapEnd %p\n", heapEnd.toLong());
+            if (newHeapTop.above(heapEnd)) {
+                logf("edenAllocate: fail 2\n", 0L);
+                return Word.zero();
+            }
+
+            if (compareAndSwap(heapTopAddress, 0, heapTop, newHeapTop) == heapTop) {
+                logf("edenAllocate: success %p\n", heapTop.toLong());
+                return heapTop;
+            }
+        }
+    }
+
+    private static final boolean LOGGING_ENABLED = Boolean.getBoolean("graal.logNewInstanceStub");
+
+    private static void logf(String format, long value) {
+        if (LOGGING_ENABLED) {
+            Log.printf(format, value);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Tue Dec 11 08:48:12 2012 +0100
@@ -0,0 +1,151 @@
+/*
+ * 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.stubs;
+
+import static java.lang.reflect.Modifier.*;
+
+import java.lang.reflect.*;
+import java.util.concurrent.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.java.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.PhasePlan.PhasePosition;
+import com.oracle.graal.snippets.*;
+import com.oracle.graal.snippets.Snippet.ConstantParameter;
+import com.oracle.graal.snippets.SnippetTemplate.AbstractTemplates;
+import com.oracle.graal.snippets.SnippetTemplate.Key;
+
+/**
+ * Base class for implementing some low level code providing the out-of-line slow path for a snippet.
+ * A concrete stub is defined a subclass of this class.
+ * <p>
+ * Implementation detail: The stub classes re-use some of the functionality for {@link Snippet}s
+ * purely for convenience (e.g., can re-use the {@link SnippetInstaller}).
+ */
+public abstract class Stub extends AbstractTemplates implements SnippetsInterface {
+
+    /**
+     * The method implementing the stub.
+     */
+    protected final HotSpotResolvedJavaMethod stubMethod;
+
+    /**
+     * The linkage information for the stub.
+     */
+    protected final HotSpotRuntimeCallTarget linkage;
+
+    /**
+     * The code installed for the stub.
+     */
+    protected InstalledCode stubCode;
+
+    /**
+     * Creates a new stub container. The new stub still needs to be {@linkplain #install(GraalCompiler) installed}.
+     *
+     * @param descriptor linkage details for a call to the stub
+     */
+    @SuppressWarnings("unchecked")
+    public Stub(HotSpotRuntime runtime, Assumptions assumptions, TargetDescription target, Descriptor descriptor) {
+        super(runtime, assumptions, target, null);
+        stubMethod = findStubMethod(runtime, getClass());
+        linkage = runtime.registerStub(descriptor, this);
+        assert linkage != null;
+    }
+
+    /**
+     * Adds the {@linkplain ConstantParameter constant} arguments of this stub.
+     */
+    protected abstract void populateKey(Key key);
+
+    protected HotSpotRuntime runtime() {
+        return (HotSpotRuntime) runtime;
+    }
+
+    /**
+     * Gets the method implementing this stub.
+     */
+    public ResolvedJavaMethod getMethod() {
+        return stubMethod;
+    }
+
+    public HotSpotRuntimeCallTarget getLinkage() {
+        return linkage;
+    }
+
+    /**
+     * Compiles the code for this stub, installs it and initializes the address used for calls to it.
+     */
+    public void install(GraalCompiler compiler) {
+        StructuredGraph graph = (StructuredGraph) stubMethod.getCompilerStorage().get(Graph.class);
+
+        Key key = new Key(stubMethod);
+        populateKey(key);
+        SnippetTemplate template = cache.get(key, assumptions);
+        graph = template.copySpecializedGraph();
+
+        PhasePlan phasePlan = new PhasePlan();
+        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
+        phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
+        final CompilationResult compResult = compiler.compileMethod(stubMethod, graph, null, phasePlan, OptimisticOptimizations.ALL);
+
+        final CodeInfo[] info = new CodeInfo[1];
+        stubCode = Debug.scope("CodeInstall", new Object[] {compiler, stubMethod}, new Callable<InstalledCode>() {
+            @Override
+            public InstalledCode call() {
+                InstalledCode installedCode = runtime().addMethod(stubMethod, compResult, info);
+                assert installedCode != null : "error installing stub " + stubMethod;
+                if (Debug.isDumpEnabled()) {
+                    Debug.dump(new Object[] {compResult, info[0]}, "After code installation");
+                }
+                return installedCode;
+            }
+        });
+
+        assert stubCode != null : "error installing stub " + stubMethod;
+        linkage.setAddress(info[0].getStart());
+    }
+
+    /**
+     * Finds the static method annotated with {@link Snippet} in a given class of which there must be exactly one.
+     */
+    private static HotSpotResolvedJavaMethod findStubMethod(HotSpotRuntime runtime, Class<?> stubClass) {
+        HotSpotResolvedJavaMethod m = null;
+        for (Method candidate : stubClass.getDeclaredMethods()) {
+            if (isStatic(candidate.getModifiers()) && candidate.getAnnotation(Snippet.class) != null) {
+                assert m == null : "more than one method annotated with @" + Snippet.class.getSimpleName() + " in " + stubClass;
+                m = (HotSpotResolvedJavaMethod) runtime.lookupJavaMethod(candidate);
+            }
+        }
+        assert m != null : "no static method annotated with @" + Snippet.class.getSimpleName() + " in " + stubClass;
+        return m;
+    }
+}
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue Dec 11 08:48:12 2012 +0100
@@ -29,7 +29,7 @@
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.RuntimeCall.Descriptor;
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType;
 import com.oracle.graal.api.meta.ProfilingInfo.ExceptionSeen;
@@ -775,7 +775,7 @@
         lastInstr = falseSucc;
 
         if (GraalOptions.OmitHotExceptionStacktrace) {
-            ValueNode exception = ConstantNode.forObject(new NullPointerException(), runtime, currentGraph);
+            ValueNode exception = ConstantNode.forObject(cachedNullPointerException, runtime, currentGraph);
             trueSucc.setNext(handleException(exception, bci()));
         } else {
             RuntimeCallNode call = currentGraph.add(new RuntimeCallNode(CREATE_NULL_POINTER_EXCEPTION));
@@ -785,6 +785,14 @@
         }
     }
 
+    private static final ArrayIndexOutOfBoundsException cachedArrayIndexOutOfBoundsException = new ArrayIndexOutOfBoundsException();
+    private static final NullPointerException cachedNullPointerException = new NullPointerException();
+    static {
+        cachedArrayIndexOutOfBoundsException.setStackTrace(new StackTraceElement[0]);
+        cachedNullPointerException.setStackTrace(new StackTraceElement[0]);
+    }
+
+
     private void emitBoundsCheck(ValueNode index, ValueNode length) {
         BlockPlaceholderNode trueSucc = currentGraph.add(new BlockPlaceholderNode());
         BlockPlaceholderNode falseSucc = currentGraph.add(new BlockPlaceholderNode());
@@ -794,7 +802,7 @@
         lastInstr = trueSucc;
 
         if (GraalOptions.OmitHotExceptionStacktrace) {
-            ValueNode exception = ConstantNode.forObject(new ArrayIndexOutOfBoundsException(), runtime, currentGraph);
+            ValueNode exception = ConstantNode.forObject(cachedArrayIndexOutOfBoundsException, runtime, currentGraph);
             falseSucc.setNext(handleException(exception, bci()));
         } else {
             RuntimeCallNode call = currentGraph.add(new RuntimeCallNode(CREATE_OUT_OF_BOUNDS_EXCEPTION, index));
@@ -963,7 +971,7 @@
         Kind resultType = targetMethod.getSignature().getReturnKind();
         if (GraalOptions.DeoptALot) {
             DeoptimizeNode deoptimize = currentGraph.add(new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint, graphId));
-            deoptimize.setMessage("invoke " + targetMethod.getName());
+            deoptimize.setMessage(targetMethod.getName());
             append(deoptimize);
             frameState.pushReturn(resultType, ConstantNode.defaultForKind(resultType, currentGraph));
             return;
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java	Tue Dec 11 08:48:12 2012 +0100
@@ -26,7 +26,7 @@
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.RuntimeCall.Descriptor;
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.lir.*;
@@ -44,10 +44,10 @@
         @Temp protected Value[] temps;
         @State protected LIRFrameState state;
 
-        protected final Object targetMethod;
+        protected final Object callTarget;
 
-        public DirectCallOp(Object targetMethod, Value result, Value[] parameters, Value[] temps, LIRFrameState state) {
-            this.targetMethod = targetMethod;
+        public DirectCallOp(Object callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) {
+            this.callTarget = callTarget;
             this.result = result;
             this.parameters = parameters;
             this.state = state;
@@ -58,7 +58,7 @@
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
             emitAlignmentForDirectCall(tasm, masm);
-            directCall(tasm, masm, targetMethod, state);
+            directCall(tasm, masm, callTarget, state);
         }
 
         protected void emitAlignmentForDirectCall(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
@@ -77,10 +77,10 @@
         @Temp protected Value[] temps;
         @State protected LIRFrameState state;
 
-        protected final Object targetMethod;
+        protected final Object callTarget;
 
-        public IndirectCallOp(Object targetMethod, Value result, Value[] parameters, Value[] temps, Value targetAddress, LIRFrameState state) {
-            this.targetMethod = targetMethod;
+        public IndirectCallOp(Object callTarget, Value result, Value[] parameters, Value[] temps, Value targetAddress, LIRFrameState state) {
+            this.callTarget = callTarget;
             this.result = result;
             this.parameters = parameters;
             this.targetAddress = targetAddress;
@@ -91,7 +91,7 @@
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            indirectCall(tasm, masm, asRegister(targetAddress), targetMethod, state);
+            indirectCall(tasm, masm, asRegister(targetAddress), callTarget, state);
         }
 
         @Override
@@ -101,10 +101,10 @@
         }
     }
 
-    public static void directCall(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Object target, LIRFrameState info) {
+    public static void directCall(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Object callTarget, LIRFrameState info) {
         int before = masm.codeBuffer.position();
-        if (target instanceof RuntimeCall) {
-            long maxOffset = ((RuntimeCall) target).getMaxCallTargetOffset();
+        if (callTarget instanceof RuntimeCallTarget) {
+            long maxOffset = ((RuntimeCallTarget) callTarget).getMaxCallTargetOffset();
             if (maxOffset != (int) maxOffset) {
                 // offset might not fit a 32-bit immediate, generate an
                 // indirect call with a 64-bit immediate
@@ -120,7 +120,7 @@
             masm.call();
         }
         int after = masm.codeBuffer.position();
-        tasm.recordDirectCall(before, after, tasm.runtime.lookupCallTarget(target), info);
+        tasm.recordDirectCall(before, after, tasm.runtime.lookupCallTarget(callTarget), info);
         tasm.recordExceptionHandlers(after, info);
         masm.ensureUniquePC();
     }
@@ -133,11 +133,11 @@
         masm.ensureUniquePC();
     }
 
-    public static void indirectCall(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Register dst, Object target, LIRFrameState info) {
+    public static void indirectCall(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Register dst, Object callTarget, LIRFrameState info) {
         int before = masm.codeBuffer.position();
         masm.call(dst);
         int after = masm.codeBuffer.position();
-        tasm.recordIndirectCall(before, after, tasm.runtime.lookupCallTarget(target), info);
+        tasm.recordIndirectCall(before, after, tasm.runtime.lookupCallTarget(callTarget), info);
         tasm.recordExceptionHandlers(after, info);
         masm.ensureUniquePC();
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java	Tue Dec 11 08:48:12 2012 +0100
@@ -25,7 +25,6 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
@@ -60,6 +59,22 @@
         this.reason = deoptReason;
     }
 
+    public DeoptimizationReason getReason() {
+        return reason;
+    }
+
+    public DeoptimizationAction getAction() {
+        return action;
+    }
+
+    public boolean isNegated() {
+        return negated;
+    }
+
+    public long getLeafGraphId() {
+        return leafGraphId;
+    }
+
     @Override
     public String toString(Verbosity verbosity) {
         if (verbosity == Verbosity.Name && negated) {
@@ -93,8 +108,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        ValueAnchorNode newAnchor = graph().add(new ValueAnchorNode(tool.createGuard(condition, reason, action, negated, leafGraphId)));
-        ((StructuredGraph) graph()).replaceFixedWithFixed(this, newAnchor);
+        tool.getRuntime().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnwindNode.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnwindNode.java	Tue Dec 11 08:48:12 2012 +0100
@@ -23,7 +23,7 @@
 package com.oracle.graal.nodes;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.RuntimeCall.Descriptor;
+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.*;
@@ -50,7 +50,7 @@
 
     @Override
     public void generate(LIRGeneratorTool gen) {
-        RuntimeCall call = gen.getRuntime().lookupRuntimeCall(UNWIND_EXCEPTION);
+        RuntimeCallTarget call = gen.getRuntime().lookupRuntimeCall(UNWIND_EXCEPTION);
         gen.emitCall(call, call.getCallingConvention(), false, gen.operand(exception()));
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java	Tue Dec 11 08:48:12 2012 +0100
@@ -40,7 +40,7 @@
     }
 
     public LoadHubNode(ValueNode object, Kind kind) {
-        super(StampFactory.forKind(kind));
+        super(kind == Kind.Object ? StampFactory.objectNonNull() : StampFactory.forKind(kind));
         this.object = object;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/RuntimeCallNode.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/RuntimeCallNode.java	Tue Dec 11 08:48:12 2012 +0100
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import com.oracle.graal.api.code.RuntimeCall.Descriptor;
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java	Tue Dec 11 08:48:12 2012 +0100
@@ -45,6 +45,10 @@
         return dimensions.size();
     }
 
+    public NodeList<ValueNode> dimensions() {
+        return dimensions;
+    }
+
     /**
      * Constructs a new NewMultiArrayNode.
      * @param type the element type of the array
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java	Tue Dec 11 08:48:12 2012 +0100
@@ -23,7 +23,7 @@
 package com.oracle.graal.nodes.java;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.RuntimeCall.*;
+import com.oracle.graal.api.code.RuntimeCallTarget.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -49,7 +49,7 @@
 
     @Override
     public void generate(LIRGeneratorTool gen) {
-        RuntimeCall call = gen.getRuntime().lookupRuntimeCall(REGISTER_FINALIZER);
+        RuntimeCallTarget call = gen.getRuntime().lookupRuntimeCall(REGISTER_FINALIZER);
         gen.emitCall(call, call.getCallingConvention(), true, gen.operand(object()));
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java	Tue Dec 11 08:48:12 2012 +0100
@@ -85,7 +85,7 @@
     public abstract void emitMembar(int barriers);
     public abstract void emitDeoptimizeOnOverflow(DeoptimizationAction action, DeoptimizationReason reason, Object deoptInfo);
     public abstract void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason, Object deoptInfo, long leafGraphId);
-    public abstract Value emitCall(Object target, CallingConvention cc, boolean canTrap, Value... args);
+    public abstract Value emitCall(RuntimeCallTarget callTarget, CallingConvention cc, boolean canTrap, Value... args);
 
     public abstract void emitIf(IfNode i);
     public abstract void emitConditional(ConditionalNode i);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Tue Dec 11 08:48:12 2012 +0100
@@ -1001,7 +1001,7 @@
         return getIntrinsicGraph(invoke, target, runtime) != null;
     }
 
-    private static StructuredGraph getIntrinsicGraph(Invoke invoke, ResolvedJavaMethod target, GraalCodeCacheProvider runtime) {
+    public static StructuredGraph getIntrinsicGraph(Invoke invoke, ResolvedJavaMethod target, GraalCodeCacheProvider runtime) {
         assert invoke.node().isAlive();
 
         StructuredGraph intrinsicGraph = (StructuredGraph) target.getCompilerStorage().get(Graph.class);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Tue Dec 11 08:48:12 2012 +0100
@@ -104,6 +104,8 @@
     private final GraalCodeCacheProvider runtime;
     private final Assumptions assumptions;
 
+    private boolean deferred;
+
     public LoweringPhase(GraalCodeCacheProvider runtime, Assumptions assumptions) {
         this.runtime = runtime;
         this.assumptions = assumptions;
@@ -127,11 +129,12 @@
             final SchedulePhase schedule = new SchedulePhase();
             schedule.apply(graph, false);
 
+            deferred = false;
             processBlock(schedule.getCFG().getStartBlock(), graph.createNodeBitMap(), null, schedule, processed);
             Debug.dump(graph, "Lowering iteration %d", i++);
             new CanonicalizerPhase(null, runtime, assumptions, mark).apply(graph);
 
-            if (!containsLowerable(graph.getNewNodes(mark))) {
+            if (!deferred && !containsLowerable(graph.getNewNodes(mark))) {
                 // No new lowerable nodes - done!
                 break;
             }
@@ -184,9 +187,14 @@
                 loweringTool.lastFixedNode = fixed;
             }
 
-            if (node.isAlive() && !processed.isMarked(node)) {
-                processed.mark(node);
-                if (node instanceof Lowerable) {
+            if (node.isAlive() && !processed.isMarked(node) && node instanceof Lowerable) {
+                if (loweringTool.lastFixedNode == null) {
+                    // We cannot lower the node now because we don't have a fixed node to anchor the replacements.
+                    // This can happen when previous lowerings in this lowering iteration deleted the BeginNode of this block.
+                    // In the next iteration, we will have the new BeginNode available, and we can lower this node.
+                    deferred = true;
+                } else {
+                    processed.mark(node);
                     ((Lowerable) node).lower(loweringTool);
                 }
             }
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/WordTest.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/WordTest.java	Tue Dec 11 08:48:12 2012 +0100
@@ -116,7 +116,7 @@
 
     @Test
     public void test_fromObject() {
-        inliningPolicy.set(new DefaultSnippetInliningPolicy(new BoxingMethodPool(runtime())) {
+        inliningPolicy.set(new DefaultSnippetInliningPolicy(runtime(), new BoxingMethodPool(runtime())) {
             @Override
             public boolean shouldInline(ResolvedJavaMethod method, ResolvedJavaMethod caller) {
                 return super.shouldInline(method, caller) && !method.getName().equals("hashCode");
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Log.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Log.java	Tue Dec 11 08:48:12 2012 +0100
@@ -24,7 +24,7 @@
 
 import java.io.*;
 
-import com.oracle.graal.api.code.RuntimeCall.Descriptor;
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/MathSnippetsX86.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/MathSnippetsX86.java	Tue Dec 11 08:48:12 2012 +0100
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.snippets;
 
-import com.oracle.graal.api.code.RuntimeCall.Descriptor;
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java	Tue Dec 11 08:48:12 2012 +0100
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.snippets;
 
-import static com.oracle.graal.api.meta.MetaUtil.*;
-
 import java.lang.annotation.*;
 import java.lang.reflect.*;
 
@@ -73,9 +71,11 @@
      * </ul>
      */
     public static class DefaultSnippetInliningPolicy implements SnippetInliningPolicy {
+        private final MetaAccessProvider metaAccess;
         private final BoxingMethodPool pool;
 
-        public DefaultSnippetInliningPolicy(BoxingMethodPool pool) {
+        public DefaultSnippetInliningPolicy(MetaAccessProvider metaAccess, BoxingMethodPool pool) {
+            this.metaAccess = metaAccess;
             this.pool = pool;
         }
 
@@ -90,7 +90,7 @@
             if (method.getAnnotation(NodeIntrinsic.class) != null) {
                 return false;
             }
-            if (Throwable.class.isAssignableFrom(getMirrorOrFail(method.getDeclaringClass(), null))) {
+            if (metaAccess.lookupJavaType(Throwable.class).isAssignableFrom(method.getDeclaringClass())) {
                 if (method.getName().equals("<init>")) {
                     return false;
                 }
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java	Tue Dec 11 08:48:12 2012 +0100
@@ -142,7 +142,7 @@
             policyClass = snippet.inlining();
         }
         if (policyClass == SnippetInliningPolicy.class) {
-            return new DefaultSnippetInliningPolicy(pool);
+            return new DefaultSnippetInliningPolicy(runtime, pool);
         }
         try {
             return policyClass.getConstructor().newInstance();
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java	Tue Dec 11 08:48:12 2012 +0100
@@ -85,7 +85,7 @@
         int count = signature.getParameterCount(false);
         Class<?>[] result = new Class< ? >[count];
         for (int i = 0; i < result.length; ++i) {
-            result[i] = getMirrorOrFail(signature.getParameterType(i, accessingClass).resolve(accessingClass), null);
+            result[i] = getMirrorOrFail(signature.getParameterType(i, accessingClass).resolve(accessingClass), Thread.currentThread().getContextClassLoader());
         }
         return result;
     }
@@ -126,7 +126,7 @@
             }
 
             // Call the method
-            Constant constant = callMethod(target.getSignature().getReturnKind(), getMirrorOrFail(declaringClass, null), target.getName(), parameterTypes, receiver, arguments);
+            Constant constant = callMethod(target.getSignature().getReturnKind(), getMirrorOrFail(declaringClass, Thread.currentThread().getContextClassLoader()), target.getName(), parameterTypes, receiver, arguments);
 
             if (constant != null) {
                 // Replace the invoke with the result of the call
@@ -191,7 +191,7 @@
     private static Class< ? > getNodeClass(ResolvedJavaMethod target, NodeIntrinsic intrinsic) {
         Class< ? > result = intrinsic.value();
         if (result == NodeIntrinsic.class) {
-            return getMirrorOrFail(target.getDeclaringClass(), null);
+            return getMirrorOrFail(target.getDeclaringClass(), Thread.currentThread().getContextClassLoader());
         }
         assert Node.class.isAssignableFrom(result);
         return result;
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java	Tue Dec 11 08:48:12 2012 +0100
@@ -185,12 +185,17 @@
         protected final Cache cache;
         protected final MetaAccessProvider runtime;
         protected final Assumptions assumptions;
-        protected Class<T> snippetsClass;
+        protected Class<?> snippetsClass;
 
         public AbstractTemplates(MetaAccessProvider runtime, Assumptions assumptions, TargetDescription target, Class<T> snippetsClass) {
             this.runtime = runtime;
             this.assumptions = assumptions;
-            this.snippetsClass = snippetsClass;
+            if (snippetsClass == null) {
+                assert this instanceof SnippetsInterface;
+                this.snippetsClass = getClass();
+            } else {
+                this.snippetsClass = snippetsClass;
+            }
             this.cache = new Cache(runtime, target);
         }
 
@@ -243,7 +248,13 @@
                 String name = c.value();
                 Object arg = key.get(name);
                 Kind kind = signature.getParameterKind(i);
-                replacements.put(snippetGraph.getLocal(i), ConstantNode.forConstant(Constant.forBoxed(kind, arg), runtime, snippetCopy));
+                Constant constantArg;
+                if (arg instanceof Constant) {
+                    constantArg = (Constant) arg;
+                } else {
+                    constantArg = Constant.forBoxed(kind, arg);
+                }
+                replacements.put(snippetGraph.getLocal(i), ConstantNode.forConstant(constantArg, runtime, snippetCopy));
             } else {
                 VarargsParameter vp = MetaUtil.getParameterAnnotation(VarargsParameter.class, i, method);
                 if (vp != null) {
@@ -390,8 +401,12 @@
     }
 
     private static boolean checkConstantArgument(final ResolvedJavaMethod method, Signature signature, int i, String name, Object arg, Kind kind) {
+        ResolvedJavaType type = signature.getParameterType(i, method.getDeclaringClass()).resolve(method.getDeclaringClass());
+        if (WordTypeRewriterPhase.isWord(type)) {
+            assert arg instanceof Constant : method + ": word constant parameters must be passed boxed in a Constant value: " + arg;
+            return true;
+        }
         if (kind == Kind.Object) {
-            ResolvedJavaType type = signature.getParameterType(i, method.getDeclaringClass()).resolve(method.getDeclaringClass());
             assert arg == null || type.isInstance(Constant.forObject(arg)) :
                 method + ": wrong value type for " + name + ": expected " + type.getName() + ", got " + arg.getClass().getName();
         } else {
@@ -581,6 +596,13 @@
     }
 
     /**
+     * Gets a copy of the specialized graph.
+     */
+    public StructuredGraph copySpecializedGraph() {
+        return snippet.copy();
+    }
+
+    /**
      * Replaces a given floating node with this specialized snippet.
      *
      * @param runtime
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java	Tue Dec 11 08:28:00 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java	Tue Dec 11 08:48:12 2012 +0100
@@ -43,7 +43,7 @@
  */
 public class WordTypeRewriterPhase extends Phase {
 
-    private static final String WordClassName = MetaUtil.toInternalName(Word.class.getName());
+    public static final String WordClassName = MetaUtil.toInternalName(Word.class.getName());
 
     private final Kind wordKind;
 
@@ -290,6 +290,7 @@
     }
 
     public static boolean isWord(ValueNode node) {
+        node.inferStamp();
         if (node.stamp() == StampFactory.forWord()) {
             return true;
         }
@@ -310,7 +311,7 @@
     }
 
     private void changeToWord(ValueNode valueNode) {
-        assert !(valueNode instanceof ConstantNode);
+        assert !(valueNode instanceof ConstantNode) : "boxed Word constants should not appear in a snippet graph: " + valueNode + ", stamp: " + valueNode.stamp();
         valueNode.setStamp(StampFactory.forKind(wordKind));
 
         // Propagate word kind.
--- a/src/cpu/x86/vm/graalRuntime_x86.cpp	Tue Dec 11 08:28:00 2012 +0100
+++ b/src/cpu/x86/vm/graalRuntime_x86.cpp	Tue Dec 11 08:48:12 2012 +0100
@@ -804,44 +804,18 @@
 
       break;
 
-    case graal_new_type_array_id:
-    case graal_new_object_array_id:
+    case graal_new_array_id:
       {
         Register length   = rbx; // Incoming
         Register klass    = rdx; // Incoming
         Register obj      = rax; // Result
 
-        if (id == graal_new_type_array_id) {
-          __ set_info("new_type_array", dont_gc_arguments);
-        } else {
-          __ set_info("new_object_array", dont_gc_arguments);
-        }
+        __ set_info("new_array", dont_gc_arguments);
 
-#ifdef ASSERT
-        // assert object type is really an array of the proper kind
-        {
-          Label ok;
-          Register t0 = obj;
-          __ movl(t0, Address(klass, Klass::layout_helper_offset()));
-          __ sarl(t0, Klass::_lh_array_tag_shift);
-          int tag = ((id == graal_new_type_array_id)
-                     ? Klass::_lh_array_tag_type_value
-                     : Klass::_lh_array_tag_obj_value);
-          __ cmpl(t0, tag);
-          __ jcc(Assembler::equal, ok);
-          __ stop("assert(is an array klass)");
-          __ should_not_reach_here();
-          __ bind(ok);
-        }
-#endif // ASSERT
         __ enter();
         OopMap* map = save_live_registers(sasm, 3);
         int call_offset;
-        if (id == graal_new_type_array_id) {
-          call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_type_array), klass, length);
-        } else {
-          call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_object_array), klass, length);
-        }
+        call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_array), klass, length);
 
         oop_maps = new OopMapSet();
         oop_maps->add_gc_map(call_offset, map);
--- a/src/share/vm/compiler/abstractCompiler.hpp	Tue Dec 11 08:28:00 2012 +0100
+++ b/src/share/vm/compiler/abstractCompiler.hpp	Tue Dec 11 08:48:12 2012 +0100
@@ -47,8 +47,11 @@
   // Name of this compiler
   virtual const char* name() = 0;
 
-  // Missing feature tests
+  // Should a native wrapper be generated by the runtime. This method
+  // does *not* answer the question "can this compiler generate code for
+  // a native method".
   virtual bool supports_native()                 { return true; }
+
   virtual bool supports_osr   ()                 { return true; }
 #if defined(TIERED) || ( !defined(COMPILER1) && !defined(COMPILER2) && !defined(SHARK) && !defined(GRAAL))
   virtual bool is_c1   ()                        { return false; }
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Tue Dec 11 08:28:00 2012 +0100
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Tue Dec 11 08:48:12 2012 +0100
@@ -538,8 +538,12 @@
   // jint next_pc_offset = Assembler::locate_next_instruction(instruction) - _instructions->start();
   _debug_recorder->add_safepoint(pc_offset, -1, create_oop_map(_total_frame_size, _parameter_count, debug_info));
 
-  oop code_pos = DebugInfo::bytecodePosition(debug_info);
-  record_scope(pc_offset, code_pos, new GrowableArray<ScopeValue*>());
+  oop frame = DebugInfo::bytecodePosition(debug_info);
+  if (frame != NULL) {
+    record_scope(pc_offset, frame, new GrowableArray<ScopeValue*>());
+  } else {
+    // Stubs do not record scope info, just oop maps
+  }
 
   _debug_recorder->end_safepoint(pc_offset);
 }
@@ -595,8 +599,13 @@
 
   if (debug_info != NULL) {
     oop frame = DebugInfo::bytecodePosition(debug_info);
-    _debug_recorder->add_safepoint(next_pc_offset, BytecodeFrame::leafGraphId(frame), create_oop_map(_total_frame_size, _parameter_count, debug_info));
-    record_scope(next_pc_offset, frame, new GrowableArray<ScopeValue*>());
+    jlong leaf_graph_id = frame == NULL ? -1 : BytecodeFrame::leafGraphId(frame);
+    _debug_recorder->add_safepoint(next_pc_offset, leaf_graph_id, create_oop_map(_total_frame_size, _parameter_count, debug_info));
+    if (frame != NULL) {
+      record_scope(next_pc_offset, frame, new GrowableArray<ScopeValue*>());
+    } else {
+      // Stubs do not record scope info, just oop maps
+    }
   }
 
   if (global_stub != NULL) {
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Tue Dec 11 08:28:00 2012 +0100
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Tue Dec 11 08:48:12 2012 +0100
@@ -1,968 +1,984 @@
-/*
- * Copyright (c) 2011, 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.
- */
-
-#include "precompiled.hpp"
-#include "runtime/fieldDescriptor.hpp"
-#include "memory/oopFactory.hpp"
-#include "oops/generateOopMap.hpp"
-#include "oops/fieldStreams.hpp"
-#include "runtime/javaCalls.hpp"
-#include "graal/graalRuntime.hpp"
-#include "compiler/compileBroker.hpp"
-#include "compiler/compilerOracle.hpp"
-#include "graal/graalCompilerToVM.hpp"
-#include "graal/graalCompiler.hpp"
-#include "graal/graalEnv.hpp"
-#include "graal/graalJavaAccess.hpp"
-#include "graal/graalCodeInstaller.hpp"
-#include "graal/graalVMToCompiler.hpp"
-#include "graal/graalVmIds.hpp"
-
-
-Method* getMethodFromHotSpotMethod(oop hotspot_method) {
-  assert(hotspot_method != NULL && hotspot_method->is_a(HotSpotResolvedJavaMethod::klass()), "sanity");
-  return asMethod(HotSpotResolvedJavaMethod::metaspaceMethod(hotspot_method));
-}
-
-// Entry to native method implementation that transitions current thread to '_thread_in_vm'.
-#define C2V_VMENTRY(result_type, name, signature) \
-  JNIEXPORT result_type JNICALL c2v_ ## name signature { \
-  TRACE_graal_3("CompilerToVM::" #name); \
-  GRAAL_VM_ENTRY_MARK; \
-
-// Entry to native method implementation that calls a JNI function
-// and hence cannot transition current thread to '_thread_in_vm'.
-#define C2V_ENTRY(result_type, name, signature) \
-  JNIEXPORT result_type JNICALL c2v_ ## name signature { \
-  TRACE_graal_3("CompilerToVM::" #name); \
-
-#define C2V_END }
-
-C2V_ENTRY(jbyteArray, initializeBytecode, (JNIEnv *env, jobject, jlong metaspace_method, jbyteArray result))
-  methodHandle method = asMethod(metaspace_method);
-  ResourceMark rm;
-  
-  int code_size = method->code_size();
-  jbyte* reconstituted_code = NULL;
-
-  // replace all breakpoints - must be done before undoing any rewriting
-  if (method->number_of_breakpoints() > 0) {
-    reconstituted_code = NEW_RESOURCE_ARRAY(jbyte, code_size);
-    memcpy(reconstituted_code, (jbyte *) method->code_base(), code_size);
-    BreakpointInfo* bp = InstanceKlass::cast(method->method_holder())->breakpoints();
-    for (; bp != NULL; bp = bp->next()) {
-      if (bp->match(method())) {
-        jbyte code = bp->orig_bytecode();
-        reconstituted_code[bp->bci()] = code;
-      }
-    }
-  }
-
-  // iterate over all bytecodes and replace non-Java bytecodes
-  if (RewriteBytecodes || RewriteFrequentPairs || InstanceKlass::cast(method->method_holder())->is_rewritten()) {
-    if (reconstituted_code == NULL) {
-      reconstituted_code = NEW_RESOURCE_ARRAY(jbyte, code_size);
-      memcpy(reconstituted_code, (jbyte *) method->code_base(), code_size);
-    }
-    BytecodeStream s(method);
-    while(!s.is_last_bytecode()) {
-      s.next();
-      Bytecodes::Code opcode = s.raw_code();
-      if (!Bytecodes::is_java_code(opcode)) {
-        jbyte original_opcode = Bytecodes::java_code(opcode);
-        int bci = s.bci();
-        reconstituted_code[bci] = original_opcode;
-        if (opcode == Bytecodes::_fast_aldc_w) {
-          int cpci = Bytes::get_native_u2((address) reconstituted_code + bci + 1);
-          int i = method->constants()->object_to_cp_index(cpci);
-          assert(i < method->constants()->length(), "sanity check");
-          Bytes::put_Java_u2((address) reconstituted_code + bci + 1, (u2)i);
-        } else if (opcode == Bytecodes::_fast_aldc) {
-          int cpci = reconstituted_code[bci + 1] & 0xff;
-          int i = method->constants()->object_to_cp_index(cpci);
-          assert(i < method->constants()->length(), "sanity check");
-          reconstituted_code[bci + 1] = (jbyte)i;
-        }
-      }
-    }
-  }
-
-  if (reconstituted_code == NULL) {
-    env->SetByteArrayRegion(result, 0, code_size, (jbyte *) method->code_base());
-  } else {
-    env->SetByteArrayRegion(result, 0, code_size, reconstituted_code);
-  }
-
-  return result;
-C2V_END
-
-C2V_VMENTRY(jstring, getSignature, (JNIEnv *env, jobject, jlong metaspace_method))
-  Method* method = asMethod(metaspace_method);
-  assert(method != NULL && method->signature() != NULL, "signature required");
-  return VmIds::toString<jstring>(method->signature(), THREAD);
-C2V_END
-
-C2V_VMENTRY(jobjectArray, initializeExceptionHandlers, (JNIEnv *, jobject, jlong metaspace_method, jobjectArray java_handlers))
-  ResourceMark rm;
-  methodHandle method = asMethod(metaspace_method);
-  int handler_count = method->exception_table_length();
-  objArrayHandle array = (objArrayOop) JNIHandles::resolve(java_handlers);
-  assert(array->length() == handler_count, "wrong length");
-  ExceptionTableElement* handlers = handler_count == 0 ? NULL : method->exception_table_start();
-
-  for (int i = 0; i < handler_count; i++) {
-    ExceptionTableElement* handler = handlers + i;
-    Handle entry = array->obj_at(i);
-    assert(!entry.is_null(), "entry should not be null");
-    ExceptionHandler::set_startBCI(entry, handler->start_pc);
-    ExceptionHandler::set_endBCI(entry, handler->end_pc);
-    ExceptionHandler::set_handlerBCI(entry, handler->handler_pc);
-    int catch_class_index = handler->catch_type_index;
-    ExceptionHandler::set_catchTypeCPI(entry, catch_class_index);
-
-    if (catch_class_index == 0) {
-      ExceptionHandler::set_catchType(entry, NULL);
-    } else {
-      ConstantPool* cp = InstanceKlass::cast(method->method_holder())->constants();
-      KlassHandle loading_klass = method->method_holder();
-      Handle catch_class = GraalCompiler::get_JavaType(cp, catch_class_index, loading_klass, CHECK_NULL);
-      if (catch_class->klass() == HotSpotResolvedObjectType::klass() && java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(catch_class)) == SystemDictionary::Throwable_klass()) {
-        ExceptionHandler::set_catchType(entry, NULL);
-        ExceptionHandler::set_catchTypeCPI(entry, 0);
-      } else {
-        ExceptionHandler::set_catchType(entry, catch_class());
-      }
-    }
-    array->obj_at_put(i, entry());
-  }
-
-  return (jobjectArray) JNIHandles::make_local(array());
-C2V_END
-
-C2V_VMENTRY(jint, hasBalancedMonitors, (JNIEnv *, jobject, jlong metaspace_method))
-
-  // Analyze the method to see if monitors are used properly.
-  methodHandle method(THREAD, asMethod(metaspace_method));
-  assert(method->has_monitor_bytecodes(), "should have checked this");
-
-  // Check to see if a previous compilation computed the monitor-matching analysis.
-  if (method->guaranteed_monitor_matching()) {
-    return true;
-  }
-
-  {
-    EXCEPTION_MARK;
-    ResourceMark rm(THREAD);
-    GeneratePairingInfo gpi(method);
-    gpi.compute_map(CATCH);
-    if (!gpi.monitor_safe()) {
-      return false;
-    }
-    method->set_guaranteed_monitor_matching();
-  }
-  return true;
-C2V_END
-
-C2V_VMENTRY(jlong, getMetaspaceMethod, (JNIEnv *, jobject, jobject reflection_method_handle, jobject resultHolder))
-  oop reflection_method = JNIHandles::resolve(reflection_method_handle);
-  oop reflection_holder = java_lang_reflect_Method::clazz(reflection_method);
-  int slot = java_lang_reflect_Method::slot(reflection_method);
-  Klass* holder = java_lang_Class::as_Klass(reflection_holder);
-  methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot);
-  Handle type = GraalCompiler::createHotSpotResolvedObjectType(method, CHECK_0);
-  objArrayOop(JNIHandles::resolve(resultHolder))->obj_at_put(0, type());
-  return (jlong) (address) method();
-}
-
-C2V_VMENTRY(jlong, getMetaspaceConstructor, (JNIEnv *, jobject, jobject reflection_ctor_handle, jobject resultHolder))
-  oop reflection_ctor = JNIHandles::resolve(reflection_ctor_handle);
-  oop reflection_holder = java_lang_reflect_Constructor::clazz(reflection_ctor);
-  int slot = java_lang_reflect_Constructor::slot(reflection_ctor);
-  Klass* holder = java_lang_Class::as_Klass(reflection_holder);
-  methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot);
-  Handle type = GraalCompiler::createHotSpotResolvedObjectType(method, CHECK_0);
-  objArrayOop(JNIHandles::resolve(resultHolder))->obj_at_put(0, type());
-  return (jlong) (address) method();
-}
-
-C2V_VMENTRY(jobject, getJavaField, (JNIEnv *, jobject, jobject reflection_field_handle))
-  oop reflection_field = JNIHandles::resolve(reflection_field_handle);
-  oop reflection_holder = java_lang_reflect_Field::clazz(reflection_field);
-  int slot = java_lang_reflect_Field::slot(reflection_field);
-  InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(reflection_holder));
-
-  int offset = holder->field_offset(slot);
-  int flags = holder->field_access_flags(slot);
-  Symbol* field_name = holder->field_name(slot);
-  Handle field_holder = GraalCompiler::get_JavaTypeFromClass(reflection_holder, CHECK_NULL);
-  Handle field_type = GraalCompiler::get_JavaTypeFromClass(java_lang_reflect_Field::type(reflection_field), CHECK_NULL);
-
-  Handle ret = GraalCompiler::get_JavaField(offset, flags, field_name, field_holder, field_type, CHECK_NULL);
-  return JNIHandles::make_local(THREAD, ret());
-}
-
-C2V_VMENTRY(jlong, getUniqueConcreteMethod, (JNIEnv *, jobject, jlong metaspace_method, jobject resultHolder))
-  methodHandle method = asMethod(metaspace_method);
-  KlassHandle holder = method->method_holder();
-  if (holder->is_interface()) {
-    // Cannot trust interfaces. Because of:
-    // interface I { void foo(); }
-    // class A { public void foo() {} }
-    // class B extends A implements I { }
-    // class C extends B { public void foo() { } }
-    // class D extends B { }
-    // Would lead to identify C.foo() as the unique concrete method for I.foo() without seeing A.foo().
-    return 0L;
-  }
-  methodHandle ucm;
-  {
-    ResourceMark rm;
-    MutexLocker locker(Compile_lock);
-    ucm = Dependencies::find_unique_concrete_method(holder(), method());
-  }
-
-  if (ucm.is_null()) {
-    return 0L;
-  }
-
-  Handle type = GraalCompiler::createHotSpotResolvedObjectType(ucm(), CHECK_0);
-  objArrayOop(JNIHandles::resolve(resultHolder))->obj_at_put(0, type());
-  return (jlong) (address) ucm();
-C2V_END
-
-C2V_ENTRY(jint, getInvocationCount, (JNIEnv *, jobject, jlong metaspace_method))
-  Method* method = asMethod(metaspace_method);
-  return method->invocation_count();
-C2V_END
-
-C2V_VMENTRY(void, initializeMethod,(JNIEnv *, jobject, jlong metaspace_method, jobject hotspot_method))
-  methodHandle method = asMethod(metaspace_method);
-  Handle name = VmIds::toString<Handle>(method->name(), CHECK);
-  InstanceKlass::cast(HotSpotResolvedJavaMethod::klass())->initialize(CHECK);
-  HotSpotResolvedJavaMethod::set_name(hotspot_method, name());
-  HotSpotResolvedJavaMethod::set_codeSize(hotspot_method, method->code_size());
-  HotSpotResolvedJavaMethod::set_exceptionHandlerCount(hotspot_method, method->exception_table_length());
-C2V_END
-
-C2V_VMENTRY(jboolean, isMethodCompilable,(JNIEnv *, jobject, jlong metaspace_method))
-  methodHandle method = asMethod(metaspace_method);
-  return !method->is_not_compilable() && !CompilerOracle::should_not_inline(method);
-C2V_END
-
-C2V_VMENTRY(void, initializeMethodData,(JNIEnv *, jobject, jlong metaspace_method_data, jobject hotspot_method_data))
-  MethodData* method_data = asMethodData(metaspace_method_data);
-  HotSpotMethodData::set_normalDataSize(hotspot_method_data, method_data->data_size());
-  HotSpotMethodData::set_extraDataSize(hotspot_method_data, method_data->extra_data_size());
-C2V_END
-
-// ------------------------------------------------------------------
-// Adjust a CounterData count to be commensurate with
-// interpreter_invocation_count.  If the MDO exists for
-// only 25% of the time the method exists, then the
-// counts in the MDO should be scaled by 4X, so that
-// they can be usefully and stably compared against the
-// invocation counts in methods.
-int scale_count(MethodData* method_data, int count) {
-  if (count > 0) {
-    int counter_life;
-    int method_life = method_data->method()->interpreter_invocation_count();
-    int current_mileage = MethodData::mileage_of(method_data->method());
-    int creation_mileage = method_data->creation_mileage();
-    counter_life = current_mileage - creation_mileage;
-
-    // counter_life due to backedge_counter could be > method_life
-    if (counter_life > method_life)
-      counter_life = method_life;
-    if (0 < counter_life && counter_life <= method_life) {
-      count = (int)((double)count * method_life / counter_life + 0.5);
-      count = (count > 0) ? count : 1;
-    }
-  }
-  return count;
-}
-
-C2V_ENTRY(jint, getCompiledCodeSize, (JNIEnv *env, jobject, jlong metaspace_method))
-  nmethod* code = (asMethod(metaspace_method))->code();
-  return code == NULL ? 0 : code->insts_size();
-C2V_END
-
-C2V_VMENTRY(jobject, lookupType, (JNIEnv *env, jobject, jstring jname, jobject accessingClass, jboolean eagerResolve))
-  ResourceMark rm;
-
-  Symbol* nameSymbol = VmIds::toSymbol(jname);
-  Handle name = JNIHandles::resolve(jname);
-  assert(nameSymbol != NULL, "name to symbol creation failed");
-
-  oop result = NULL;
-  if (nameSymbol == vmSymbols::int_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_INT, THREAD);
-  } else if (nameSymbol == vmSymbols::long_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_LONG, THREAD);
-  } else if (nameSymbol == vmSymbols::bool_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_BOOLEAN, THREAD);
-  } else if (nameSymbol == vmSymbols::char_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_CHAR, THREAD);
-  } else if (nameSymbol == vmSymbols::short_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_SHORT, THREAD);
-  } else if (nameSymbol == vmSymbols::byte_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_BYTE, THREAD);
-  } else if (nameSymbol == vmSymbols::double_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_DOUBLE, THREAD);
-  } else if (nameSymbol == vmSymbols::float_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_FLOAT, THREAD);
-  } else if (nameSymbol == vmSymbols::void_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_VOID, THREAD);
-  } else {
-    Klass* resolved_type = NULL;
-    Handle classloader;
-    Handle protectionDomain;
-    if (JNIHandles::resolve(accessingClass) != NULL) {
-      classloader = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(accessingClass))->class_loader();
-      protectionDomain = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(accessingClass))->protection_domain();
-    }
-
-    if (eagerResolve) {
-      resolved_type = SystemDictionary::resolve_or_fail(nameSymbol, classloader, protectionDomain, true, THREAD);
-    } else {
-      resolved_type = SystemDictionary::resolve_or_null(nameSymbol, classloader, protectionDomain, THREAD);
-    }
-
-    if (!HAS_PENDING_EXCEPTION) {
-      if (resolved_type == NULL) {
-        assert(!eagerResolve, "failed eager resolution should have caused an exception");
-        Handle type = VMToCompiler::createUnresolvedJavaType(name, THREAD);
-        result = type();
-      } else {
-        Handle type = GraalCompiler::createHotSpotResolvedObjectType(resolved_type, name, CHECK_NULL);
-        result = type();
-      }
-    }
-  }
-
-  return JNIHandles::make_local(THREAD, result);
-C2V_END
-
-C2V_VMENTRY(jobject, lookupConstantInPool, (JNIEnv *env, jobject, jobject type, jint index))
-
-  ConstantPool* cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants();
-
-  oop result = NULL;
-  constantTag tag = cp->tag_at(index);
-  if (tag.is_int()) {
-    result = VMToCompiler::createConstant(Kind::Int(), cp->int_at(index), CHECK_0);
-  } else if (tag.is_long()) {
-    result = VMToCompiler::createConstant(Kind::Long(), cp->long_at(index), CHECK_0);
-  } else if (tag.is_float()) {
-    result = VMToCompiler::createConstantFloat(cp->float_at(index), CHECK_0);
-  } else if (tag.is_double()) {
-    result = VMToCompiler::createConstantDouble(cp->double_at(index), CHECK_0);
-  } else if (tag.is_string()) {
-    oop string = NULL;
-    if (cp->is_pseudo_string_at(index)) {
-      int obj_index = cp->cp_to_object_index(index);
-      string = cp->pseudo_string_at(index, obj_index);
-    } else {
-      string = cp->string_at(index, THREAD);
-      if (HAS_PENDING_EXCEPTION) {
-        CLEAR_PENDING_EXCEPTION;
-        // TODO: Gracefully exit compilation.
-        fatal("out of memory during compilation!");
-        return NULL;
-      }
-    }
-    result = VMToCompiler::createConstantObject(string, CHECK_0);
-  } else if (tag.is_klass() || tag.is_unresolved_klass()) {
-    Handle type = GraalCompiler::get_JavaType(cp, index, cp->pool_holder(), CHECK_NULL);
-    result = type();
-  } else if (tag.is_object()) {
-    oop obj = cp->object_at(index);
-    assert(obj->is_instance(), "must be an instance");
-    result = VMToCompiler::createConstantObject(obj, CHECK_NULL);
-  } else {
-    tty->print("unknown constant pool tag (%s) at cpi %d in %s: ", tag.internal_name(), index, cp->pool_holder()->name()->as_C_string());
-    ShouldNotReachHere();
-  }
-
-  return JNIHandles::make_local(THREAD, result);
-C2V_END
-
-C2V_VMENTRY(jobject, lookupMethodInPool, (JNIEnv *env, jobject, jobject type, jint index, jbyte opcode))
-  index = GraalCompiler::to_cp_index_u2(index);
-  constantPoolHandle cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants();
-  instanceKlassHandle pool_holder(cp->pool_holder());
-
-  Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF);
-  methodHandle method = GraalEnv::get_method_by_index(cp, index, bc, pool_holder);
-  if (!method.is_null()) {
-    Handle holder = GraalCompiler::get_JavaType(method->method_holder(), CHECK_NULL);
-    return JNIHandles::make_local(THREAD, VMToCompiler::createResolvedJavaMethod(holder, method(), THREAD));
-  } else {
-    // Get the method's name and signature.
-    Handle name = VmIds::toString<Handle>(cp->name_ref_at(index), CHECK_NULL);
-    Handle signature  = VmIds::toString<Handle>(cp->signature_ref_at(index), CHECK_NULL);
-    int holder_index = cp->klass_ref_index_at(index);
-    Handle type = GraalCompiler::get_JavaType(cp, holder_index, cp->pool_holder(), CHECK_NULL);
-    return JNIHandles::make_local(THREAD, VMToCompiler::createUnresolvedJavaMethod(name, signature, type, THREAD));
-  }
-C2V_END
-
-C2V_VMENTRY(jobject, lookupTypeInPool, (JNIEnv *env, jobject, jobject type, jint index))
-
-  ConstantPool* cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants();
-  Handle result = GraalCompiler::get_JavaType(cp, index, cp->pool_holder(), CHECK_NULL);
-  return JNIHandles::make_local(THREAD, result());
-C2V_END
-
-C2V_VMENTRY(void, lookupReferencedTypeInPool, (JNIEnv *env, jobject, jobject type, jint index, jbyte op))
-  ConstantPool* cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants();
-  int opcode = (op & 0xFF);
-  if (opcode != Bytecodes::_checkcast && opcode != Bytecodes::_instanceof && opcode != Bytecodes::_new && opcode != Bytecodes::_anewarray
-      && opcode != Bytecodes::_multianewarray && opcode != Bytecodes::_ldc && opcode != Bytecodes::_ldc_w && opcode != Bytecodes::_ldc2_w)
-  {
-    index = cp->remap_instruction_operand_from_cache(GraalCompiler::to_cp_index_u2(index));
-  }
-  constantTag tag = cp->tag_at(index);
-  if (tag.is_field_or_method()) {
-    index = cp->uncached_klass_ref_index_at(index);
-    tag = cp->tag_at(index);
-  }
-
-  if (tag.is_unresolved_klass() || tag.is_klass()) {
-    Klass* klass = cp->klass_at(index, CHECK);
-    if (klass->oop_is_instance()) {
-      InstanceKlass::cast(klass)->initialize(CHECK);
-    }
-  }
-C2V_END
-
-C2V_VMENTRY(jobject, lookupFieldInPool, (JNIEnv *env, jobject, jobject constantPoolHolder, jint index, jbyte opcode))
-  ResourceMark rm;
-
-  index = GraalCompiler::to_cp_index_u2(index);
-  constantPoolHandle cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(constantPoolHolder)))->constants();
-
-  int nt_index = cp->name_and_type_ref_index_at(index);
-  int sig_index = cp->signature_ref_index_at(nt_index);
-  Symbol* signature = cp->symbol_at(sig_index);
-  int name_index = cp->name_ref_index_at(nt_index);
-  Symbol* name = cp->symbol_at(name_index);
-  int holder_index = cp->klass_ref_index_at(index);
-  Handle holder = GraalCompiler::get_JavaType(cp, holder_index, cp->pool_holder(), CHECK_NULL);
-  instanceKlassHandle holder_klass;
-  
-  Bytecodes::Code code = (Bytecodes::Code)(((int) opcode) & 0xFF);
-  int offset = -1;
-  AccessFlags flags;
-  BasicType basic_type;
-  if (holder->klass() == SystemDictionary::HotSpotResolvedObjectType_klass()) {
-    FieldAccessInfo result;
-    LinkResolver::resolve_field(result, cp, index,
-                                Bytecodes::java_code(code),
-                                true, false, Thread::current());
-    if (HAS_PENDING_EXCEPTION) {
-      CLEAR_PENDING_EXCEPTION;
-    } else {
-      offset = result.field_offset();
-      flags = result.access_flags();
-      holder_klass = result.klass()();
-      basic_type = result.field_type();
-      holder = GraalCompiler::get_JavaType(holder_klass, CHECK_NULL);
-    }
-  }
-  
-  Handle type = GraalCompiler::get_JavaTypeFromSignature(signature, cp->pool_holder(), CHECK_NULL);
-  Handle field_handle = GraalCompiler::get_JavaField(offset, flags.as_int(), name, holder, type, THREAD);
-
-  return JNIHandles::make_local(THREAD, field_handle());
-C2V_END
-
-C2V_VMENTRY(jobject, resolveMethod, (JNIEnv *, jobject, jobject resolved_type, jstring name, jstring signature))
-
-  assert(JNIHandles::resolve(resolved_type) != NULL, "");
-  Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(resolved_type));
-  Symbol* name_symbol = VmIds::toSymbol(name);
-  Symbol* signature_symbol = VmIds::toSymbol(signature);
-  methodHandle method = klass->lookup_method(name_symbol, signature_symbol);
-  if (method.is_null()) {
-    if (TraceGraal >= 3) {
-      ResourceMark rm;
-      tty->print_cr("Could not resolve method %s %s on klass %s", name_symbol->as_C_string(), signature_symbol->as_C_string(), klass->name()->as_C_string());
-    }
-    return NULL;
-  }
-  Handle holder = GraalCompiler::get_JavaType(method->method_holder(), CHECK_NULL);
-  return JNIHandles::make_local(THREAD, VMToCompiler::createResolvedJavaMethod(holder, method(), THREAD));
-C2V_END
-
-C2V_VMENTRY(jlong, getPrototypeMarkWord, (JNIEnv *, jobject, jobject klass))
-  KlassHandle klass_handle(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(klass)));
-  if (klass_handle->oop_is_array()) {
-    return (int32_t)(intptr_t) markOopDesc::prototype();
-  } else {
-    return (jlong) (intptr_t) klass_handle->prototype_header();
-  }
-C2V_END
-
-C2V_VMENTRY(jboolean, isTypeInitialized,(JNIEnv *, jobject, jobject hotspot_klass))
-  Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(hotspot_klass));
-  assert(klass != NULL, "method must not be called for primitive types");
-  return InstanceKlass::cast(klass)->is_initialized();
-C2V_END
-
-C2V_VMENTRY(void, initializeType, (JNIEnv *, jobject, jobject hotspot_klass))
-  Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(hotspot_klass));
-  assert(klass != NULL, "method must not be called for primitive types");
-  InstanceKlass::cast(klass)->initialize(JavaThread::current());
-C2V_END
-
-C2V_VMENTRY(jobject, getInstanceFields, (JNIEnv *, jobject, jobject klass))
-  ResourceMark rm;
-
-  instanceKlassHandle k = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(klass));
-  GrowableArray<Handle> fields(k->java_fields_count());
-
-  for (AllFieldStream fs(k()); !fs.done(); fs.next()) {
-    if (!fs.access_flags().is_static()) {
-      Handle type = GraalCompiler::get_JavaTypeFromSignature(fs.signature(), k, Thread::current());
-      int flags = fs.access_flags().as_int();
-      bool internal = fs.access_flags().is_internal();
-      Handle name = VmIds::toString<Handle>(fs.name(), Thread::current());
-      Handle field = VMToCompiler::createJavaField(JNIHandles::resolve(klass), name, type, fs.offset(), flags, internal, Thread::current());
-      fields.append(field());
-    }
-  }
-  objArrayHandle field_array = oopFactory::new_objArray(SystemDictionary::HotSpotResolvedJavaField_klass(), fields.length(), CHECK_NULL);
-  for (int i = 0; i < fields.length(); ++i) {
-    field_array->obj_at_put(i, fields.at(i)());
-  }
-  return JNIHandles::make_local(field_array());
-C2V_END
-
-C2V_VMENTRY(jlong, getMaxCallTargetOffset, (JNIEnv *env, jobject, jlong stub))
-  address target_addr = (address) stub;
-  if (target_addr != 0x0) {
-    int64_t off_low = (int64_t)target_addr - ((int64_t)CodeCache::low_bound() + sizeof(int));
-    int64_t off_high = (int64_t)target_addr - ((int64_t)CodeCache::high_bound() + sizeof(int));
-    return MAX2(ABS(off_low), ABS(off_high));
-  }
-  return -1;
-C2V_END
-
-C2V_VMENTRY(jobject, getResolvedType, (JNIEnv *env, jobject, jobject javaClass))
-  oop java_mirror = JNIHandles::resolve(javaClass);
-  assert(java_mirror != NULL, "argument to CompilerToVM.getResolvedType must not be NULL");
-  Handle type = GraalCompiler::get_JavaTypeFromClass(java_mirror, CHECK_NULL);
-  return JNIHandles::make_local(THREAD, type());
-C2V_END
-
-
-// helpers used to set fields in the HotSpotVMConfig object
-jfieldID getFieldID(JNIEnv* env, jobject obj, const char* name, const char* sig) {
-  jfieldID id = env->GetFieldID(env->GetObjectClass(obj), name, sig);
-  if (id == NULL) {
-    fatal(err_msg("field not found: %s (%s)", name, sig));
-  }
-  return id;
-}
-
-void set_boolean(JNIEnv* env, jobject obj, const char* name, bool value) { env->SetBooleanField(obj, getFieldID(env, obj, name, "Z"), value); }
-void set_int(JNIEnv* env, jobject obj, const char* name, int value) { env->SetIntField(obj, getFieldID(env, obj, name, "I"), value); }
-void set_long(JNIEnv* env, jobject obj, const char* name, jlong value) { env->SetLongField(obj, getFieldID(env, obj, name, "J"), value); }
-void set_object(JNIEnv* env, jobject obj, const char* name, jobject value) { env->SetObjectField(obj, getFieldID(env, obj, name, "Ljava/lang/Object;"), value); }
-void set_int_array(JNIEnv* env, jobject obj, const char* name, jarray value) { env->SetObjectField(obj, getFieldID(env, obj, name, "[I"), value); }
-
-jboolean get_boolean(JNIEnv* env, jobject obj, const char* name) { return env->GetBooleanField(obj, getFieldID(env, obj, name, "Z")); }
-jint get_int(JNIEnv* env, jobject obj, const char* name) { return env->GetIntField(obj, getFieldID(env, obj, name, "I")); }
-jlong get_long(JNIEnv* env, jobject obj, const char* name) { return env->GetLongField(obj, getFieldID(env, obj, name, "J")); }
-jobject get_object(JNIEnv* env, jobject obj, const char* name) { return env->GetObjectField(obj, getFieldID(env, obj, name, "Ljava/lang/Object;")); }
-jobject get_object(JNIEnv* env, jobject obj, const char* name, const char* sig) { return env->GetObjectField(obj, getFieldID(env, obj, name, sig)); }
-
-
-BasicType basicTypes[] = { T_BOOLEAN, T_BYTE, T_SHORT, T_CHAR, T_INT, T_FLOAT, T_LONG, T_DOUBLE, T_OBJECT };
-int basicTypeCount = sizeof(basicTypes) / sizeof(BasicType);
-
-C2V_ENTRY(void, initializeConfiguration, (JNIEnv *env, jobject, jobject config))
-#ifdef _WIN64
-  set_boolean(env, config, "windowsOs", true);
-#else
-  set_boolean(env, config, "windowsOs", false);
-#endif
-  set_boolean(env, config, "verifyOops", VerifyOops);
-  set_boolean(env, config, "useFastLocking", UseFastLocking);
-  set_boolean(env, config, "useFastNewObjectArray", UseFastNewObjectArray);
-  set_boolean(env, config, "useBiasedLocking", UseBiasedLocking);
-  set_boolean(env, config, "useFastNewTypeArray", UseFastNewTypeArray);
-  set_boolean(env, config, "useTLAB", UseTLAB);
-  set_int(env, config, "codeEntryAlignment", CodeEntryAlignment);
-  set_int(env, config, "vmPageSize", os::vm_page_size());
-  set_int(env, config, "stackShadowPages", StackShadowPages);
-  set_int(env, config, "hubOffset", oopDesc::klass_offset_in_bytes());
-  set_int(env, config, "markOffset", oopDesc::mark_offset_in_bytes());
-  set_int(env, config, "prototypeMarkWordOffset", in_bytes(Klass::prototype_header_offset()));
-  set_int(env, config, "superCheckOffsetOffset", in_bytes(Klass::super_check_offset_offset()));
-  set_int(env, config, "secondarySuperCacheOffset", in_bytes(Klass::secondary_super_cache_offset()));
-  set_int(env, config, "secondarySupersOffset", in_bytes(Klass::secondary_supers_offset()));
-  set_int(env, config, "subklassOffset", in_bytes(Klass::subklass_offset()));
-  set_int(env, config, "nextSiblingOffset", in_bytes(Klass::next_sibling_offset()));
-  set_int(env, config, "arrayLengthOffset", arrayOopDesc::length_offset_in_bytes());
-  set_int(env, config, "klassStateOffset", in_bytes(InstanceKlass::init_state_offset()));
-  set_int(env, config, "klassStateFullyInitialized", (int)InstanceKlass::fully_initialized);
-  set_int(env, config, "threadTlabTopOffset", in_bytes(JavaThread::tlab_top_offset()));
-  set_int(env, config, "threadTlabEndOffset", in_bytes(JavaThread::tlab_end_offset()));
-  set_int(env, config, "threadObjectOffset", in_bytes(JavaThread::threadObj_offset()));
-  set_int(env, config, "osThreadOffset", in_bytes(JavaThread::osthread_offset()));
-  set_int(env, config, "osThreadInterruptedOffset", in_bytes(OSThread::interrupted_offset()));
-  set_int(env, config, "unlockedMask", (int) markOopDesc::unlocked_value);
-  set_int(env, config, "biasedLockMaskInPlace", (int) markOopDesc::biased_lock_mask_in_place);
-  set_int(env, config, "ageMaskInPlace", (int) markOopDesc::age_mask_in_place);
-  set_int(env, config, "epochMaskInPlace", (int) markOopDesc::epoch_mask_in_place);
-  set_int(env, config, "biasedLockPattern", (int) markOopDesc::biased_lock_pattern);
-  set_int(env, config, "methodMaxLocalsOffset", in_bytes(Method::size_of_locals_offset()));
-  set_int(env, config, "methodMaxStackOffset", in_bytes(Method::max_stack_offset()));
-  set_int(env, config, "extraStackEntries", Method::extra_stack_entries());
-  set_int(env, config, "methodAccessFlagsOffset", in_bytes(Method::access_flags_offset()));
-  set_int(env, config, "klassHasFinalizerFlag", JVM_ACC_HAS_FINALIZER);
-  set_int(env, config, "threadExceptionOopOffset", in_bytes(JavaThread::exception_oop_offset()));
-  set_int(env, config, "threadExceptionPcOffset", in_bytes(JavaThread::exception_pc_offset()));
-  set_long(env, config, "safepointPollingAddress", (jlong)(os::get_polling_page() + (SafepointPollOffset % os::vm_page_size())));
-  set_boolean(env, config, "isPollingPageFar", Assembler::is_polling_page_far());
-  set_int(env, config, "classMirrorOffset", in_bytes(Klass::java_mirror_offset()));
-  set_int(env, config, "runtimeCallStackSize", (jint)frame::arg_reg_save_area_bytes);
-  set_int(env, config, "klassModifierFlagsOffset", in_bytes(Klass::modifier_flags_offset()));
-  set_int(env, config, "klassAccessFlagsOffset", in_bytes(Klass::access_flags_offset()));
-  set_int(env, config, "klassLayoutHelperOffset", in_bytes(Klass::layout_helper_offset()));
-  set_int(env, config, "klassSuperKlassOffset", in_bytes(Klass::super_offset()));
-  set_int(env, config, "klassOffset", java_lang_Class::klass_offset_in_bytes());
-  set_int(env, config, "graalMirrorInClassOffset", java_lang_Class::graal_mirror_offset_in_bytes());
-  set_int(env, config, "methodDataOffset", in_bytes(Method::method_data_offset()));
-  set_int(env, config, "nmethodEntryOffset", nmethod::verified_entry_point_offset());
-  set_int(env, config, "methodCompiledEntryOffset", in_bytes(Method::from_compiled_offset()));
-  set_int(env, config, "basicLockSize", sizeof(BasicLock));
-  set_int(env, config, "basicLockDisplacedHeaderOffset", BasicLock::displaced_header_offset_in_bytes());
-  set_int(env, config, "uninitializedIdentityHashCodeValue", markOopDesc::no_hash);
-  set_int(env, config, "identityHashCodeShift", markOopDesc::hash_shift);
-
-  set_int(env, config, "arrayKlassLayoutHelperIdentifier", 0x80000000);
-  assert((Klass::_lh_array_tag_obj_value & Klass::_lh_array_tag_type_value & 0x80000000) != 0, "obj_array and type_array must have first bit set");
-  set_int(env, config, "arrayKlassComponentMirrorOffset", in_bytes(ArrayKlass::component_mirror_offset()));
-  
-  set_int(env, config, "metaspaceArrayLengthOffset", Array<Klass*>::length_offset_in_bytes());
-  set_int(env, config, "metaspaceArrayBaseOffset", Array<Klass*>::base_offset_in_bytes());
-  set_int(env, config, "methodDataOopDataOffset", in_bytes(MethodData::data_offset()));
-  set_int(env, config, "methodDataOopTrapHistoryOffset", in_bytes(MethodData::trap_history_offset()));
-  set_int(env, config, "dataLayoutHeaderSize", DataLayout::header_size_in_bytes());
-  set_int(env, config, "dataLayoutTagOffset", in_bytes(DataLayout::tag_offset()));
-  set_int(env, config, "dataLayoutFlagsOffset", in_bytes(DataLayout::flags_offset()));
-  set_int(env, config, "dataLayoutBCIOffset", in_bytes(DataLayout::bci_offset()));
-  set_int(env, config, "dataLayoutCellsOffset", in_bytes(DataLayout::cell_offset(0)));
-  set_int(env, config, "dataLayoutCellSize", DataLayout::cell_size);
-  set_int(env, config, "bciProfileWidth", BciProfileWidth);
-  set_int(env, config, "typeProfileWidth", TypeProfileWidth);
-
-  set_long(env, config, "debugStub", VmIds::addStub((address)warning));
-  set_long(env, config, "instanceofStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_slow_subtype_check_id)));
-  set_long(env, config, "newInstanceStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_new_instance_id)));
-  set_long(env, config, "newTypeArrayStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_new_type_array_id)));
-  set_long(env, config, "newObjectArrayStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_new_object_array_id)));
-  set_long(env, config, "newMultiArrayStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_new_multi_array_id)));
-  set_long(env, config, "inlineCacheMissStub", VmIds::addStub(SharedRuntime::get_ic_miss_stub()));
-  set_long(env, config, "handleExceptionStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_handle_exception_nofpu_id)));
-  set_long(env, config, "handleDeoptStub", VmIds::addStub(SharedRuntime::deopt_blob()->unpack()));
-  set_long(env, config, "monitorEnterStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_monitorenter_id)));
-  set_long(env, config, "monitorExitStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_monitorexit_id)));
-  set_long(env, config, "verifyOopStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_verify_oop_id)));
-  set_long(env, config, "vmErrorStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_vm_error_id)));
-  set_long(env, config, "deoptimizeStub", VmIds::addStub(SharedRuntime::deopt_blob()->uncommon_trap()));
-  set_long(env, config, "unwindExceptionStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_unwind_exception_call_id)));
-  set_long(env, config, "osrMigrationEndStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_OSR_migration_end_id)));
-  set_long(env, config, "registerFinalizerStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_register_finalizer_id)));
-  set_long(env, config, "setDeoptInfoStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_set_deopt_info_id)));
-  set_long(env, config, "createNullPointerExceptionStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_create_null_pointer_exception_id)));
-  set_long(env, config, "createOutOfBoundsExceptionStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_create_out_of_bounds_exception_id)));
-  set_long(env, config, "javaTimeMillisStub", VmIds::addStub(CAST_FROM_FN_PTR(address, os::javaTimeMillis)));
-  set_long(env, config, "javaTimeNanosStub", VmIds::addStub(CAST_FROM_FN_PTR(address, os::javaTimeNanos)));
-  set_long(env, config, "arithmeticFremStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_arithmetic_frem_id)));
-  set_long(env, config, "arithmeticDremStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_arithmetic_drem_id)));
-  set_long(env, config, "arithmeticSinStub", VmIds::addStub(CAST_FROM_FN_PTR(address, SharedRuntime::dsin)));
-  set_long(env, config, "arithmeticCosStub", VmIds::addStub(CAST_FROM_FN_PTR(address, SharedRuntime::dcos)));
-  set_long(env, config, "arithmeticTanStub", VmIds::addStub(CAST_FROM_FN_PTR(address, SharedRuntime::dtan)));
-  set_long(env, config, "logPrimitiveStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_log_primitive_id)));
-  set_long(env, config, "logObjectStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_log_object_id)));
-  set_long(env, config, "logPrintfStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_log_printf_id)));
-  set_long(env, config, "identityHashCodeStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_identity_hash_code_id)));
-  set_long(env, config, "threadIsInterruptedStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_thread_is_interrupted_id)));
-
-
-  BarrierSet* bs = Universe::heap()->barrier_set();
-  switch (bs->kind()) {
-    case BarrierSet::CardTableModRef:
-    case BarrierSet::CardTableExtension: {
-      jlong base = (jlong)((CardTableModRefBS*)bs)->byte_map_base;
-      assert(base != 0, "unexpected byte_map_base");
-      set_long(env, config, "cardtableStartAddress", base);
-      set_int(env, config, "cardtableShift", CardTableModRefBS::card_shift);
-      break;
-    }
-    case BarrierSet::ModRef:
-    case BarrierSet::Other:
-      set_long(env, config, "cardtableStartAddress", 0);
-      set_int(env, config, "cardtableShift", 0);
-      // No post barriers
-      break;
-#ifndef SERIALGC
-    case BarrierSet::G1SATBCT:
-    case BarrierSet::G1SATBCTLogging:
-#endif // SERIALGC
-    default:
-      ShouldNotReachHere();
-      break;
-    }
-
-  set_int(env, config, "arrayClassElementOffset", in_bytes(ObjArrayKlass::element_klass_offset()));
-C2V_END
-
-C2V_VMENTRY(jint, installCode0, (JNIEnv *jniEnv, jobject, jobject compResult, jobject installed_code, jobject info))
-  ResourceMark rm;
-  HandleMark hm;
-  Handle compResultHandle = JNIHandles::resolve(compResult);
-  nmethod* nm = NULL;
-  methodHandle method = getMethodFromHotSpotMethod(HotSpotCompilationResult::method(compResult));
-  Handle installed_code_handle = JNIHandles::resolve(installed_code);
-  GraalEnv::CodeInstallResult result;
-  CodeInstaller installer(compResultHandle, method, result, nm, installed_code_handle);
-
-  if (result != GraalEnv::ok) {
-    assert(nm == NULL, "should be");
-  } else {
-    if (info != NULL) {
-      arrayOop codeCopy = oopFactory::new_byteArray(nm->code_size(), CHECK_0);
-      memcpy(codeCopy->base(T_BYTE), nm->code_begin(), nm->code_size());
-      HotSpotCodeInfo::set_code(info, codeCopy);
-      HotSpotCodeInfo::set_start(info, (jlong) nm->code_begin());
-    }
-
-    if (!installed_code_handle.is_null()) {
-      assert(installed_code_handle->is_a(HotSpotInstalledCode::klass()), "wrong type");
-      HotSpotInstalledCode::set_nmethod(installed_code_handle, (jlong) nm);
-      HotSpotInstalledCode::set_method(installed_code_handle, HotSpotCompilationResult::method(compResult));
-      assert(nm == NULL || !installed_code_handle->is_scavengable() || nm->on_scavenge_root_list(), "nm should be scavengable if installed_code is scavengable");
-    }
-  }
-  return result;
-C2V_END
-
-C2V_VMENTRY(jobject, disassembleNative, (JNIEnv *jniEnv, jobject, jbyteArray code, jlong start_address))
-  ResourceMark rm;
-  HandleMark hm;
-
-  stringStream(st);
-  arrayOop code_oop = (arrayOop) JNIHandles::resolve(code);
-  int len = code_oop->length();
-  address begin = (address) code_oop->base(T_BYTE);
-  address end = begin + len;
-  Disassembler::decode(begin, end, &st);
-
-  Handle result = java_lang_String::create_from_platform_dependent_str(st.as_string(), CHECK_NULL);
-  return JNIHandles::make_local(result());
-C2V_END
-
-C2V_VMENTRY(jobject, getStackTraceElement, (JNIEnv *env, jobject, jlong metaspace_method, int bci))
-  ResourceMark rm;
-  HandleMark hm;
-
-  methodHandle method = asMethod(metaspace_method);
-  oop element = java_lang_StackTraceElement::create(method, bci, CHECK_NULL);
-  return JNIHandles::make_local(element);
-C2V_END
-
-C2V_VMENTRY(jobject, executeCompiledMethodVarargs, (JNIEnv *env, jobject, jlong metaspace_method, jlong metaspace_nmethod, jobject args))
-  ResourceMark rm;
-  HandleMark hm;
-
-  assert(metaspace_method != 0, "just checking");
-  methodHandle mh = asMethod(metaspace_method);
-  Symbol* signature = mh->signature();
-  JavaCallArguments jca;
-
-  JavaArgumentUnboxer jap(signature, &jca, (arrayOop) JNIHandles::resolve(args), mh->is_static());
-  JavaValue result(jap.get_ret_type());
-
-  nmethod* nm = (nmethod*) (address) metaspace_nmethod;
-  if (nm == NULL || !nm->is_alive()) {
-    THROW_0(vmSymbols::MethodInvalidatedException());
-  }
-
-  JavaCalls::call(&result, mh, nm, &jca, CHECK_NULL);
-
-  if (jap.get_ret_type() == T_VOID) {
-    return NULL;
-  } else if (jap.get_ret_type() == T_OBJECT || jap.get_ret_type() == T_ARRAY) {
-    return JNIHandles::make_local((oop) result.get_jobject());
-  } else {
-    oop o = java_lang_boxing_object::create(jap.get_ret_type(), (jvalue *) result.get_value_addr(), CHECK_NULL);
-    return JNIHandles::make_local(o);
-  }
-C2V_END
-
-C2V_VMENTRY(jobject, executeCompiledMethod, (JNIEnv *env, jobject, jlong metaspace_method, jlong metaspace_nmethod, jobject arg1, jobject arg2, jobject arg3))
-  ResourceMark rm;
-  HandleMark hm;
-
-  methodHandle method = asMethod(metaspace_method);
-  assert(!method.is_null(), "just checking");
-  JavaValue result(T_OBJECT);
-  JavaCallArguments args;
-  args.push_oop(JNIHandles::resolve(arg1));
-  args.push_oop(JNIHandles::resolve(arg2));
-  args.push_oop(JNIHandles::resolve(arg3));
-
-  nmethod* nm = (nmethod*) (address) metaspace_nmethod;
-  if (nm == NULL || !nm->is_alive()) {
-    THROW_0(vmSymbols::MethodInvalidatedException());
-  }
-
-  JavaCalls::call(&result, method, nm, &args, CHECK_NULL);
-
-  return JNIHandles::make_local((oop) result.get_jobject());
-C2V_END
-
-C2V_VMENTRY(jint, getVtableEntryOffset, (JNIEnv *, jobject, jlong metaspace_method))
-
-  Method* method = asMethod(metaspace_method);
-  assert(!InstanceKlass::cast(method->method_holder())->is_interface(), "vtableEntryOffset cannot be called for interface methods");
-  assert(InstanceKlass::cast(method->method_holder())->is_linked(), "vtableEntryOffset cannot be called is holder is not linked");
-
-  // get entry offset in words
-  int vtable_entry_offset = InstanceKlass::vtable_start_offset() + method->vtable_index() * vtableEntry::size();
-  // convert to bytes
-  vtable_entry_offset = vtable_entry_offset * wordSize + vtableEntry::method_offset_in_bytes();
-
-  return vtable_entry_offset;
-C2V_END
-
-C2V_VMENTRY(jobject, getDeoptedLeafGraphIds, (JNIEnv *, jobject))
-
-  // the contract for this method is as follows:
-  // returning null: no deopted leaf graphs
-  // returning array (size > 0): the ids of the deopted leaf graphs
-  // returning array (size == 0): there was an overflow, the compiler needs to clear its cache completely
-
-  oop array = GraalCompiler::instance()->dump_deopted_leaf_graphs(CHECK_NULL);
-  return JNIHandles::make_local(array);
-C2V_END
-
-C2V_VMENTRY(jobject, decodePC, (JNIEnv *, jobject, jlong pc))
-  stringStream(st);
-  CodeBlob* blob = CodeCache::find_blob_unsafe((void*) pc);
-  if (blob == NULL) {
-    st.print("[unidentified pc]");
-  } else {
-    st.print(blob->name());
-
-    nmethod* nm = blob->as_nmethod_or_null();
-    if (nm != NULL && nm->method() != NULL) {
-      st.print(" %s.", nm->method()->method_holder()->external_name());
-      nm->method()->name()->print_symbol_on(&st);
-      st.print("  @ %d", pc - (jlong) nm->entry_point());
-    }
-  }
-  Handle result = java_lang_String::create_from_platform_dependent_str(st.as_string(), CHECK_NULL);
-  return JNIHandles::make_local(result());
-C2V_END
-
-
-#define CC (char*)  /*cast a literal from (const char*)*/
-#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f))
-
-#define RESOLVED_TYPE         "Lcom/oracle/graal/api/meta/ResolvedJavaType;"
-#define TYPE                  "Lcom/oracle/graal/api/meta/JavaType;"
-#define METHOD                "Lcom/oracle/graal/api/meta/JavaMethod;"
-#define FIELD                 "Lcom/oracle/graal/api/meta/JavaField;"
-#define SIGNATURE             "Lcom/oracle/graal/api/meta/Signature;"
-#define CONSTANT_POOL         "Lcom/oracle/graal/api/meta/ConstantPool;"
-#define CONSTANT              "Lcom/oracle/graal/api/meta/Constant;"
-#define KIND                  "Lcom/oracle/graal/api/meta/Kind;"
-#define RUNTIME_CALL          "Lcom/oracle/graal/api/code/RuntimeCall;"
-#define EXCEPTION_HANDLERS    "[Lcom/oracle/graal/api/meta/ExceptionHandler;"
-#define REFLECT_METHOD        "Ljava/lang/reflect/Method;"
-#define REFLECT_CONSTRUCTOR   "Ljava/lang/reflect/Constructor;"
-#define REFLECT_FIELD         "Ljava/lang/reflect/Field;"
-#define STRING                "Ljava/lang/String;"
-#define OBJECT                "Ljava/lang/Object;"
-#define CLASS                 "Ljava/lang/Class;"
-#define STACK_TRACE_ELEMENT   "Ljava/lang/StackTraceElement;"
-#define HS_RESOLVED_TYPE      "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedObjectType;"
-#define HS_RESOLVED_METHOD    "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;"
-#define HS_RESOLVED_FIELD     "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaField;"
-#define HS_COMP_RESULT        "Lcom/oracle/graal/hotspot/HotSpotCompilationResult;"
-#define HS_CONFIG             "Lcom/oracle/graal/hotspot/HotSpotVMConfig;"
-#define HS_METHOD             "Lcom/oracle/graal/hotspot/meta/HotSpotMethod;"
-#define HS_INSTALLED_CODE     "Lcom/oracle/graal/hotspot/meta/HotSpotInstalledCode;"
-#define HS_CODE_INFO          "Lcom/oracle/graal/hotspot/meta/HotSpotCodeInfo;"
-#define METHOD_DATA           "Lcom/oracle/graal/hotspot/meta/HotSpotMethodData;"
-#define METASPACE_METHOD      "J"
-#define METASPACE_METHOD_DATA "J"
-#define NMETHOD               "J"
-
-JNINativeMethod CompilerToVM_methods[] = {
-  {CC"initializeBytecode",            CC"("METASPACE_METHOD"[B)[B",                                     FN_PTR(initializeBytecode)},
-  {CC"getSignature",                  CC"("METASPACE_METHOD")"STRING,                                   FN_PTR(getSignature)},
-  {CC"initializeExceptionHandlers",   CC"("METASPACE_METHOD EXCEPTION_HANDLERS")"EXCEPTION_HANDLERS,    FN_PTR(initializeExceptionHandlers)},
-  {CC"hasBalancedMonitors",           CC"("METASPACE_METHOD")Z",                                        FN_PTR(hasBalancedMonitors)},
-  {CC"getUniqueConcreteMethod",       CC"("METASPACE_METHOD"["HS_RESOLVED_TYPE")"METASPACE_METHOD,      FN_PTR(getUniqueConcreteMethod)},
-  {CC"getStackTraceElement",          CC"("METASPACE_METHOD"I)"STACK_TRACE_ELEMENT,                     FN_PTR(getStackTraceElement)},
-  {CC"initializeMethod",              CC"("METASPACE_METHOD HS_RESOLVED_METHOD")V",                     FN_PTR(initializeMethod)},
-  {CC"initializeMethodData",          CC"("METASPACE_METHOD_DATA METHOD_DATA")V",                       FN_PTR(initializeMethodData)},
-  {CC"isMethodCompilable",            CC"("METASPACE_METHOD")Z",                                        FN_PTR(isMethodCompilable)},
-  {CC"getInvocationCount",            CC"("METASPACE_METHOD")I",                                        FN_PTR(getInvocationCount)},
-  {CC"getCompiledCodeSize",           CC"("METASPACE_METHOD")I",                                        FN_PTR(getCompiledCodeSize)},
-  {CC"getVtableEntryOffset",          CC"("METASPACE_METHOD")I",                                        FN_PTR(getVtableEntryOffset)},
-  {CC"lookupType",                    CC"("STRING HS_RESOLVED_TYPE"Z)"TYPE,                             FN_PTR(lookupType)},
-  {CC"lookupConstantInPool",          CC"("HS_RESOLVED_TYPE"I)"OBJECT,                                  FN_PTR(lookupConstantInPool)},
-  {CC"lookupMethodInPool",            CC"("HS_RESOLVED_TYPE"IB)"METHOD,                                 FN_PTR(lookupMethodInPool)},
-  {CC"lookupTypeInPool",              CC"("HS_RESOLVED_TYPE"I)"TYPE,                                    FN_PTR(lookupTypeInPool)},
-  {CC"lookupReferencedTypeInPool",    CC"("HS_RESOLVED_TYPE"IB)V",                                      FN_PTR(lookupReferencedTypeInPool)},
-  {CC"lookupFieldInPool",             CC"("HS_RESOLVED_TYPE"IB)"FIELD,                                  FN_PTR(lookupFieldInPool)},
-  {CC"resolveMethod",                 CC"("HS_RESOLVED_TYPE STRING STRING")"METHOD,                     FN_PTR(resolveMethod)},
-  {CC"getPrototypeMarkWord",          CC"("HS_RESOLVED_TYPE")J",                                        FN_PTR(getPrototypeMarkWord)},
-  {CC"getInstanceFields",             CC"("HS_RESOLVED_TYPE")["HS_RESOLVED_FIELD,                       FN_PTR(getInstanceFields)},
-  {CC"isTypeInitialized",             CC"("HS_RESOLVED_TYPE")Z",                                        FN_PTR(isTypeInitialized)},
-  {CC"initializeType",                CC"("HS_RESOLVED_TYPE")V",                                        FN_PTR(initializeType)},
-  {CC"getMaxCallTargetOffset",        CC"(J)J",                                                         FN_PTR(getMaxCallTargetOffset)},
-  {CC"getResolvedType",               CC"("CLASS")"RESOLVED_TYPE,                                       FN_PTR(getResolvedType)},
-  {CC"getMetaspaceMethod",            CC"("REFLECT_METHOD"["HS_RESOLVED_TYPE")"METASPACE_METHOD,        FN_PTR(getMetaspaceMethod)},
-  {CC"getMetaspaceConstructor",       CC"("REFLECT_CONSTRUCTOR"["HS_RESOLVED_TYPE")"METASPACE_METHOD,   FN_PTR(getMetaspaceConstructor)},
-  {CC"getJavaField",                  CC"("REFLECT_FIELD")"HS_RESOLVED_FIELD,                           FN_PTR(getJavaField)},
-  {CC"initializeConfiguration",       CC"("HS_CONFIG")V",                                               FN_PTR(initializeConfiguration)},
-  {CC"installCode0",                  CC"("HS_COMP_RESULT HS_INSTALLED_CODE HS_CODE_INFO")I",           FN_PTR(installCode0)},
-  {CC"disassembleNative",             CC"([BJ)"STRING,                                                  FN_PTR(disassembleNative)},
-  {CC"executeCompiledMethod",         CC"("METASPACE_METHOD NMETHOD OBJECT OBJECT OBJECT")"OBJECT,      FN_PTR(executeCompiledMethod)},
-  {CC"executeCompiledMethodVarargs",  CC"("METASPACE_METHOD NMETHOD "["OBJECT")"OBJECT,                 FN_PTR(executeCompiledMethodVarargs)},
-  {CC"getDeoptedLeafGraphIds",        CC"()[J",                                                         FN_PTR(getDeoptedLeafGraphIds)},
-  {CC"decodePC",                      CC"(J)"STRING,                                                    FN_PTR(decodePC)},
-};
-
-int CompilerToVM_methods_count() {
-  return sizeof(CompilerToVM_methods) / sizeof(JNINativeMethod);
-}
-
+/*
+ * Copyright (c) 2011, 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.
+ */
+
+#include "precompiled.hpp"
+#include "runtime/fieldDescriptor.hpp"
+#include "memory/oopFactory.hpp"
+#include "oops/generateOopMap.hpp"
+#include "oops/fieldStreams.hpp"
+#include "runtime/javaCalls.hpp"
+#include "graal/graalRuntime.hpp"
+#include "compiler/compileBroker.hpp"
+#include "compiler/compilerOracle.hpp"
+#include "graal/graalCompilerToVM.hpp"
+#include "graal/graalCompiler.hpp"
+#include "graal/graalEnv.hpp"
+#include "graal/graalJavaAccess.hpp"
+#include "graal/graalCodeInstaller.hpp"
+#include "graal/graalVMToCompiler.hpp"
+#include "graal/graalVmIds.hpp"
+
+
+Method* getMethodFromHotSpotMethod(oop hotspot_method) {
+  assert(hotspot_method != NULL && hotspot_method->is_a(HotSpotResolvedJavaMethod::klass()), "sanity");
+  return asMethod(HotSpotResolvedJavaMethod::metaspaceMethod(hotspot_method));
+}
+
+// Entry to native method implementation that transitions current thread to '_thread_in_vm'.
+#define C2V_VMENTRY(result_type, name, signature) \
+  JNIEXPORT result_type JNICALL c2v_ ## name signature { \
+  TRACE_graal_3("CompilerToVM::" #name); \
+  GRAAL_VM_ENTRY_MARK; \
+
+// Entry to native method implementation that calls a JNI function
+// and hence cannot transition current thread to '_thread_in_vm'.
+#define C2V_ENTRY(result_type, name, signature) \
+  JNIEXPORT result_type JNICALL c2v_ ## name signature { \
+  TRACE_graal_3("CompilerToVM::" #name); \
+
+#define C2V_END }
+
+C2V_ENTRY(jbyteArray, initializeBytecode, (JNIEnv *env, jobject, jlong metaspace_method, jbyteArray result))
+  methodHandle method = asMethod(metaspace_method);
+  ResourceMark rm;
+  
+  int code_size = method->code_size();
+  jbyte* reconstituted_code = NULL;
+
+  // replace all breakpoints - must be done before undoing any rewriting
+  if (method->number_of_breakpoints() > 0) {
+    reconstituted_code = NEW_RESOURCE_ARRAY(jbyte, code_size);
+    memcpy(reconstituted_code, (jbyte *) method->code_base(), code_size);
+    BreakpointInfo* bp = InstanceKlass::cast(method->method_holder())->breakpoints();
+    for (; bp != NULL; bp = bp->next()) {
+      if (bp->match(method())) {
+        jbyte code = bp->orig_bytecode();
+        reconstituted_code[bp->bci()] = code;
+      }
+    }
+  }
+
+  // iterate over all bytecodes and replace non-Java bytecodes
+  if (RewriteBytecodes || RewriteFrequentPairs || InstanceKlass::cast(method->method_holder())->is_rewritten()) {
+    if (reconstituted_code == NULL) {
+      reconstituted_code = NEW_RESOURCE_ARRAY(jbyte, code_size);
+      memcpy(reconstituted_code, (jbyte *) method->code_base(), code_size);
+    }
+    BytecodeStream s(method);
+    while(!s.is_last_bytecode()) {
+      s.next();
+      Bytecodes::Code opcode = s.raw_code();
+      if (!Bytecodes::is_java_code(opcode)) {
+        jbyte original_opcode = Bytecodes::java_code(opcode);
+        int bci = s.bci();
+        reconstituted_code[bci] = original_opcode;
+        if (opcode == Bytecodes::_fast_aldc_w) {
+          int cpci = Bytes::get_native_u2((address) reconstituted_code + bci + 1);
+          int i = method->constants()->object_to_cp_index(cpci);
+          assert(i < method->constants()->length(), "sanity check");
+          Bytes::put_Java_u2((address) reconstituted_code + bci + 1, (u2)i);
+        } else if (opcode == Bytecodes::_fast_aldc) {
+          int cpci = reconstituted_code[bci + 1] & 0xff;
+          int i = method->constants()->object_to_cp_index(cpci);
+          assert(i < method->constants()->length(), "sanity check");
+          reconstituted_code[bci + 1] = (jbyte)i;
+        }
+      }
+    }
+  }
+
+  if (reconstituted_code == NULL) {
+    env->SetByteArrayRegion(result, 0, code_size, (jbyte *) method->code_base());
+  } else {
+    env->SetByteArrayRegion(result, 0, code_size, reconstituted_code);
+  }
+
+  return result;
+C2V_END
+
+C2V_VMENTRY(jstring, getSignature, (JNIEnv *env, jobject, jlong metaspace_method))
+  Method* method = asMethod(metaspace_method);
+  assert(method != NULL && method->signature() != NULL, "signature required");
+  return VmIds::toString<jstring>(method->signature(), THREAD);
+C2V_END
+
+C2V_VMENTRY(jobjectArray, initializeExceptionHandlers, (JNIEnv *, jobject, jlong metaspace_method, jobjectArray java_handlers))
+  ResourceMark rm;
+  methodHandle method = asMethod(metaspace_method);
+  int handler_count = method->exception_table_length();
+  objArrayHandle array = (objArrayOop) JNIHandles::resolve(java_handlers);
+  assert(array->length() == handler_count, "wrong length");
+  ExceptionTableElement* handlers = handler_count == 0 ? NULL : method->exception_table_start();
+
+  for (int i = 0; i < handler_count; i++) {
+    ExceptionTableElement* handler = handlers + i;
+    Handle entry = array->obj_at(i);
+    assert(!entry.is_null(), "entry should not be null");
+    ExceptionHandler::set_startBCI(entry, handler->start_pc);
+    ExceptionHandler::set_endBCI(entry, handler->end_pc);
+    ExceptionHandler::set_handlerBCI(entry, handler->handler_pc);
+    int catch_class_index = handler->catch_type_index;
+    ExceptionHandler::set_catchTypeCPI(entry, catch_class_index);
+
+    if (catch_class_index == 0) {
+      ExceptionHandler::set_catchType(entry, NULL);
+    } else {
+      ConstantPool* cp = InstanceKlass::cast(method->method_holder())->constants();
+      KlassHandle loading_klass = method->method_holder();
+      Handle catch_class = GraalCompiler::get_JavaType(cp, catch_class_index, loading_klass, CHECK_NULL);
+      if (catch_class->klass() == HotSpotResolvedObjectType::klass() && java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(catch_class)) == SystemDictionary::Throwable_klass()) {
+        ExceptionHandler::set_catchType(entry, NULL);
+        ExceptionHandler::set_catchTypeCPI(entry, 0);
+      } else {
+        ExceptionHandler::set_catchType(entry, catch_class());
+      }
+    }
+    array->obj_at_put(i, entry());
+  }
+
+  return (jobjectArray) JNIHandles::make_local(array());
+C2V_END
+
+C2V_VMENTRY(jint, hasBalancedMonitors, (JNIEnv *, jobject, jlong metaspace_method))
+
+  // Analyze the method to see if monitors are used properly.
+  methodHandle method(THREAD, asMethod(metaspace_method));
+  assert(method->has_monitor_bytecodes(), "should have checked this");
+
+  // Check to see if a previous compilation computed the monitor-matching analysis.
+  if (method->guaranteed_monitor_matching()) {
+    return true;
+  }
+
+  {
+    EXCEPTION_MARK;
+    ResourceMark rm(THREAD);
+    GeneratePairingInfo gpi(method);
+    gpi.compute_map(CATCH);
+    if (!gpi.monitor_safe()) {
+      return false;
+    }
+    method->set_guaranteed_monitor_matching();
+  }
+  return true;
+C2V_END
+
+C2V_VMENTRY(jlong, getMetaspaceMethod, (JNIEnv *, jobject, jobject reflection_method_handle, jobject resultHolder))
+  oop reflection_method = JNIHandles::resolve(reflection_method_handle);
+  oop reflection_holder = java_lang_reflect_Method::clazz(reflection_method);
+  int slot = java_lang_reflect_Method::slot(reflection_method);
+  Klass* holder = java_lang_Class::as_Klass(reflection_holder);
+  methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot);
+  Handle type = GraalCompiler::createHotSpotResolvedObjectType(method, CHECK_0);
+  objArrayOop(JNIHandles::resolve(resultHolder))->obj_at_put(0, type());
+  return (jlong) (address) method();
+}
+
+C2V_VMENTRY(jlong, getMetaspaceConstructor, (JNIEnv *, jobject, jobject reflection_ctor_handle, jobject resultHolder))
+  oop reflection_ctor = JNIHandles::resolve(reflection_ctor_handle);
+  oop reflection_holder = java_lang_reflect_Constructor::clazz(reflection_ctor);
+  int slot = java_lang_reflect_Constructor::slot(reflection_ctor);
+  Klass* holder = java_lang_Class::as_Klass(reflection_holder);
+  methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot);
+  Handle type = GraalCompiler::createHotSpotResolvedObjectType(method, CHECK_0);
+  objArrayOop(JNIHandles::resolve(resultHolder))->obj_at_put(0, type());
+  return (jlong) (address) method();
+}
+
+C2V_VMENTRY(jobject, getJavaField, (JNIEnv *, jobject, jobject reflection_field_handle))
+  oop reflection_field = JNIHandles::resolve(reflection_field_handle);
+  oop reflection_holder = java_lang_reflect_Field::clazz(reflection_field);
+  int slot = java_lang_reflect_Field::slot(reflection_field);
+  InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(reflection_holder));
+
+  int offset = holder->field_offset(slot);
+  int flags = holder->field_access_flags(slot);
+  Symbol* field_name = holder->field_name(slot);
+  Handle field_holder = GraalCompiler::get_JavaTypeFromClass(reflection_holder, CHECK_NULL);
+  Handle field_type = GraalCompiler::get_JavaTypeFromClass(java_lang_reflect_Field::type(reflection_field), CHECK_NULL);
+
+  Handle ret = GraalCompiler::get_JavaField(offset, flags, field_name, field_holder, field_type, CHECK_NULL);
+  return JNIHandles::make_local(THREAD, ret());
+}
+
+C2V_VMENTRY(jlong, getUniqueConcreteMethod, (JNIEnv *, jobject, jlong metaspace_method, jobject resultHolder))
+  methodHandle method = asMethod(metaspace_method);
+  KlassHandle holder = method->method_holder();
+  if (holder->is_interface()) {
+    // Cannot trust interfaces. Because of:
+    // interface I { void foo(); }
+    // class A { public void foo() {} }
+    // class B extends A implements I { }
+    // class C extends B { public void foo() { } }
+    // class D extends B { }
+    // Would lead to identify C.foo() as the unique concrete method for I.foo() without seeing A.foo().
+    return 0L;
+  }
+  methodHandle ucm;
+  {
+    ResourceMark rm;
+    MutexLocker locker(Compile_lock);
+    ucm = Dependencies::find_unique_concrete_method(holder(), method());
+  }
+
+  if (ucm.is_null()) {
+    return 0L;
+  }
+
+  Handle type = GraalCompiler::createHotSpotResolvedObjectType(ucm(), CHECK_0);
+  objArrayOop(JNIHandles::resolve(resultHolder))->obj_at_put(0, type());
+  return (jlong) (address) ucm();
+C2V_END
+
+C2V_ENTRY(jint, getInvocationCount, (JNIEnv *, jobject, jlong metaspace_method))
+  Method* method = asMethod(metaspace_method);
+  return method->invocation_count();
+C2V_END
+
+C2V_VMENTRY(void, initializeMethod,(JNIEnv *, jobject, jlong metaspace_method, jobject hotspot_method))
+  methodHandle method = asMethod(metaspace_method);
+  Handle name = VmIds::toString<Handle>(method->name(), CHECK);
+  InstanceKlass::cast(HotSpotResolvedJavaMethod::klass())->initialize(CHECK);
+  HotSpotResolvedJavaMethod::set_name(hotspot_method, name());
+  HotSpotResolvedJavaMethod::set_codeSize(hotspot_method, method->code_size());
+  HotSpotResolvedJavaMethod::set_exceptionHandlerCount(hotspot_method, method->exception_table_length());
+C2V_END
+
+C2V_VMENTRY(jboolean, isMethodCompilable,(JNIEnv *, jobject, jlong metaspace_method))
+  methodHandle method = asMethod(metaspace_method);
+  return !method->is_not_compilable() && !CompilerOracle::should_not_inline(method);
+C2V_END
+
+C2V_VMENTRY(void, initializeMethodData,(JNIEnv *, jobject, jlong metaspace_method_data, jobject hotspot_method_data))
+  MethodData* method_data = asMethodData(metaspace_method_data);
+  HotSpotMethodData::set_normalDataSize(hotspot_method_data, method_data->data_size());
+  HotSpotMethodData::set_extraDataSize(hotspot_method_data, method_data->extra_data_size());
+C2V_END
+
+// ------------------------------------------------------------------
+// Adjust a CounterData count to be commensurate with
+// interpreter_invocation_count.  If the MDO exists for
+// only 25% of the time the method exists, then the
+// counts in the MDO should be scaled by 4X, so that
+// they can be usefully and stably compared against the
+// invocation counts in methods.
+int scale_count(MethodData* method_data, int count) {
+  if (count > 0) {
+    int counter_life;
+    int method_life = method_data->method()->interpreter_invocation_count();
+    int current_mileage = MethodData::mileage_of(method_data->method());
+    int creation_mileage = method_data->creation_mileage();
+    counter_life = current_mileage - creation_mileage;
+
+    // counter_life due to backedge_counter could be > method_life
+    if (counter_life > method_life)
+      counter_life = method_life;
+    if (0 < counter_life && counter_life <= method_life) {
+      count = (int)((double)count * method_life / counter_life + 0.5);
+      count = (count > 0) ? count : 1;
+    }
+  }
+  return count;
+}
+
+C2V_ENTRY(jint, getCompiledCodeSize, (JNIEnv *env, jobject, jlong metaspace_method))
+  nmethod* code = (asMethod(metaspace_method))->code();
+  return code == NULL ? 0 : code->insts_size();
+C2V_END
+
+C2V_VMENTRY(jobject, lookupType, (JNIEnv *env, jobject, jstring jname, jobject accessingClass, jboolean eagerResolve))
+  ResourceMark rm;
+
+  Symbol* nameSymbol = VmIds::toSymbol(jname);
+  Handle name = JNIHandles::resolve(jname);
+  assert(nameSymbol != NULL, "name to symbol creation failed");
+
+  oop result = NULL;
+  if (nameSymbol == vmSymbols::int_signature()) {
+    result = VMToCompiler::createPrimitiveJavaType((int) T_INT, THREAD);
+  } else if (nameSymbol == vmSymbols::long_signature()) {
+    result = VMToCompiler::createPrimitiveJavaType((int) T_LONG, THREAD);
+  } else if (nameSymbol == vmSymbols::bool_signature()) {
+    result = VMToCompiler::createPrimitiveJavaType((int) T_BOOLEAN, THREAD);
+  } else if (nameSymbol == vmSymbols::char_signature()) {
+    result = VMToCompiler::createPrimitiveJavaType((int) T_CHAR, THREAD);
+  } else if (nameSymbol == vmSymbols::short_signature()) {
+    result = VMToCompiler::createPrimitiveJavaType((int) T_SHORT, THREAD);
+  } else if (nameSymbol == vmSymbols::byte_signature()) {
+    result = VMToCompiler::createPrimitiveJavaType((int) T_BYTE, THREAD);
+  } else if (nameSymbol == vmSymbols::double_signature()) {
+    result = VMToCompiler::createPrimitiveJavaType((int) T_DOUBLE, THREAD);
+  } else if (nameSymbol == vmSymbols::float_signature()) {
+    result = VMToCompiler::createPrimitiveJavaType((int) T_FLOAT, THREAD);
+  } else if (nameSymbol == vmSymbols::void_signature()) {
+    result = VMToCompiler::createPrimitiveJavaType((int) T_VOID, THREAD);
+  } else {
+    Klass* resolved_type = NULL;
+    Handle classloader;
+    Handle protectionDomain;
+    if (JNIHandles::resolve(accessingClass) != NULL) {
+      classloader = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(accessingClass))->class_loader();
+      protectionDomain = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(accessingClass))->protection_domain();
+    }
+
+    if (eagerResolve) {
+      resolved_type = SystemDictionary::resolve_or_fail(nameSymbol, classloader, protectionDomain, true, THREAD);
+    } else {
+      resolved_type = SystemDictionary::resolve_or_null(nameSymbol, classloader, protectionDomain, THREAD);
+    }
+
+    if (!HAS_PENDING_EXCEPTION) {
+      if (resolved_type == NULL) {
+        assert(!eagerResolve, "failed eager resolution should have caused an exception");
+        Handle type = VMToCompiler::createUnresolvedJavaType(name, THREAD);
+        result = type();
+      } else {
+        Handle type = GraalCompiler::createHotSpotResolvedObjectType(resolved_type, name, CHECK_NULL);
+        result = type();
+      }
+    }
+  }
+
+  return JNIHandles::make_local(THREAD, result);
+C2V_END
+
+C2V_VMENTRY(jobject, lookupConstantInPool, (JNIEnv *env, jobject, jobject type, jint index))
+
+  ConstantPool* cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants();
+
+  oop result = NULL;
+  constantTag tag = cp->tag_at(index);
+  if (tag.is_int()) {
+    result = VMToCompiler::createConstant(Kind::Int(), cp->int_at(index), CHECK_0);
+  } else if (tag.is_long()) {
+    result = VMToCompiler::createConstant(Kind::Long(), cp->long_at(index), CHECK_0);
+  } else if (tag.is_float()) {
+    result = VMToCompiler::createConstantFloat(cp->float_at(index), CHECK_0);
+  } else if (tag.is_double()) {
+    result = VMToCompiler::createConstantDouble(cp->double_at(index), CHECK_0);
+  } else if (tag.is_string()) {
+    oop string = NULL;
+    if (cp->is_pseudo_string_at(index)) {
+      int obj_index = cp->cp_to_object_index(index);
+      string = cp->pseudo_string_at(index, obj_index);
+    } else {
+      string = cp->string_at(index, THREAD);
+      if (HAS_PENDING_EXCEPTION) {
+        CLEAR_PENDING_EXCEPTION;
+        // TODO: Gracefully exit compilation.
+        fatal("out of memory during compilation!");
+        return NULL;
+      }
+    }
+    result = VMToCompiler::createConstantObject(string, CHECK_0);
+  } else if (tag.is_klass() || tag.is_unresolved_klass()) {
+    Handle type = GraalCompiler::get_JavaType(cp, index, cp->pool_holder(), CHECK_NULL);
+    result = type();
+  } else if (tag.is_object()) {
+    oop obj = cp->object_at(index);
+    assert(obj->is_instance(), "must be an instance");
+    result = VMToCompiler::createConstantObject(obj, CHECK_NULL);
+  } else {
+    tty->print("unknown constant pool tag (%s) at cpi %d in %s: ", tag.internal_name(), index, cp->pool_holder()->name()->as_C_string());
+    ShouldNotReachHere();
+  }
+
+  return JNIHandles::make_local(THREAD, result);
+C2V_END
+
+C2V_VMENTRY(jobject, lookupMethodInPool, (JNIEnv *env, jobject, jobject type, jint index, jbyte opcode))
+  index = GraalCompiler::to_cp_index_u2(index);
+  constantPoolHandle cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants();
+  instanceKlassHandle pool_holder(cp->pool_holder());
+
+  Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF);
+  methodHandle method = GraalEnv::get_method_by_index(cp, index, bc, pool_holder);
+  if (!method.is_null()) {
+    Handle holder = GraalCompiler::get_JavaType(method->method_holder(), CHECK_NULL);
+    return JNIHandles::make_local(THREAD, VMToCompiler::createResolvedJavaMethod(holder, method(), THREAD));
+  } else {
+    // Get the method's name and signature.
+    Handle name = VmIds::toString<Handle>(cp->name_ref_at(index), CHECK_NULL);
+    Handle signature  = VmIds::toString<Handle>(cp->signature_ref_at(index), CHECK_NULL);
+    int holder_index = cp->klass_ref_index_at(index);
+    Handle type = GraalCompiler::get_JavaType(cp, holder_index, cp->pool_holder(), CHECK_NULL);
+    return JNIHandles::make_local(THREAD, VMToCompiler::createUnresolvedJavaMethod(name, signature, type, THREAD));
+  }
+C2V_END
+
+C2V_VMENTRY(jobject, lookupTypeInPool, (JNIEnv *env, jobject, jobject type, jint index))
+
+  ConstantPool* cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants();
+  Handle result = GraalCompiler::get_JavaType(cp, index, cp->pool_holder(), CHECK_NULL);
+  return JNIHandles::make_local(THREAD, result());
+C2V_END
+
+C2V_VMENTRY(void, lookupReferencedTypeInPool, (JNIEnv *env, jobject, jobject type, jint index, jbyte op))
+  ConstantPool* cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants();
+  int opcode = (op & 0xFF);
+  if (opcode != Bytecodes::_checkcast && opcode != Bytecodes::_instanceof && opcode != Bytecodes::_new && opcode != Bytecodes::_anewarray
+      && opcode != Bytecodes::_multianewarray && opcode != Bytecodes::_ldc && opcode != Bytecodes::_ldc_w && opcode != Bytecodes::_ldc2_w)
+  {
+    index = cp->remap_instruction_operand_from_cache(GraalCompiler::to_cp_index_u2(index));
+  }
+  constantTag tag = cp->tag_at(index);
+  if (tag.is_field_or_method()) {
+    index = cp->uncached_klass_ref_index_at(index);
+    tag = cp->tag_at(index);
+  }
+
+  if (tag.is_unresolved_klass() || tag.is_klass()) {
+    Klass* klass = cp->klass_at(index, CHECK);
+    if (klass->oop_is_instance()) {
+      InstanceKlass::cast(klass)->initialize(CHECK);
+    }
+  }
+C2V_END
+
+C2V_VMENTRY(jobject, lookupFieldInPool, (JNIEnv *env, jobject, jobject constantPoolHolder, jint index, jbyte opcode))
+  ResourceMark rm;
+
+  index = GraalCompiler::to_cp_index_u2(index);
+  constantPoolHandle cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(constantPoolHolder)))->constants();
+
+  int nt_index = cp->name_and_type_ref_index_at(index);
+  int sig_index = cp->signature_ref_index_at(nt_index);
+  Symbol* signature = cp->symbol_at(sig_index);
+  int name_index = cp->name_ref_index_at(nt_index);
+  Symbol* name = cp->symbol_at(name_index);
+  int holder_index = cp->klass_ref_index_at(index);
+  Handle holder = GraalCompiler::get_JavaType(cp, holder_index, cp->pool_holder(), CHECK_NULL);
+  instanceKlassHandle holder_klass;
+  
+  Bytecodes::Code code = (Bytecodes::Code)(((int) opcode) & 0xFF);
+  int offset = -1;
+  AccessFlags flags;
+  BasicType basic_type;
+  if (holder->klass() == SystemDictionary::HotSpotResolvedObjectType_klass()) {
+    FieldAccessInfo result;
+    LinkResolver::resolve_field(result, cp, index,
+                                Bytecodes::java_code(code),
+                                true, false, Thread::current());
+    if (HAS_PENDING_EXCEPTION) {
+      CLEAR_PENDING_EXCEPTION;
+    } else {
+      offset = result.field_offset();
+      flags = result.access_flags();
+      holder_klass = result.klass()();
+      basic_type = result.field_type();
+      holder = GraalCompiler::get_JavaType(holder_klass, CHECK_NULL);
+    }
+  }
+  
+  Handle type = GraalCompiler::get_JavaTypeFromSignature(signature, cp->pool_holder(), CHECK_NULL);
+  Handle field_handle = GraalCompiler::get_JavaField(offset, flags.as_int(), name, holder, type, THREAD);
+
+  return JNIHandles::make_local(THREAD, field_handle());
+C2V_END
+
+C2V_VMENTRY(jobject, resolveMethod, (JNIEnv *, jobject, jobject resolved_type, jstring name, jstring signature))
+
+  assert(JNIHandles::resolve(resolved_type) != NULL, "");
+  Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(resolved_type));
+  Symbol* name_symbol = VmIds::toSymbol(name);
+  Symbol* signature_symbol = VmIds::toSymbol(signature);
+  methodHandle method = klass->lookup_method(name_symbol, signature_symbol);
+  if (method.is_null()) {
+    if (TraceGraal >= 3) {
+      ResourceMark rm;
+      tty->print_cr("Could not resolve method %s %s on klass %s", name_symbol->as_C_string(), signature_symbol->as_C_string(), klass->name()->as_C_string());
+    }
+    return NULL;
+  }
+  Handle holder = GraalCompiler::get_JavaType(method->method_holder(), CHECK_NULL);
+  return JNIHandles::make_local(THREAD, VMToCompiler::createResolvedJavaMethod(holder, method(), THREAD));
+C2V_END
+
+C2V_VMENTRY(jboolean, isTypeInitialized,(JNIEnv *, jobject, jobject hotspot_klass))
+  Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(hotspot_klass));
+  assert(klass != NULL, "method must not be called for primitive types");
+  return InstanceKlass::cast(klass)->is_initialized();
+C2V_END
+
+C2V_VMENTRY(void, initializeType, (JNIEnv *, jobject, jobject hotspot_klass))
+  Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(hotspot_klass));
+  assert(klass != NULL, "method must not be called for primitive types");
+  InstanceKlass::cast(klass)->initialize(JavaThread::current());
+C2V_END
+
+C2V_VMENTRY(jobject, getInstanceFields, (JNIEnv *, jobject, jobject klass))
+  ResourceMark rm;
+
+  instanceKlassHandle k = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(klass));
+  GrowableArray<Handle> fields(k->java_fields_count());
+
+  for (AllFieldStream fs(k()); !fs.done(); fs.next()) {
+    if (!fs.access_flags().is_static()) {
+      Handle type = GraalCompiler::get_JavaTypeFromSignature(fs.signature(), k, Thread::current());
+      int flags = fs.access_flags().as_int();
+      bool internal = fs.access_flags().is_internal();
+      Handle name = VmIds::toString<Handle>(fs.name(), Thread::current());
+      Handle field = VMToCompiler::createJavaField(JNIHandles::resolve(klass), name, type, fs.offset(), flags, internal, Thread::current());
+      fields.append(field());
+    }
+  }
+  objArrayHandle field_array = oopFactory::new_objArray(SystemDictionary::HotSpotResolvedJavaField_klass(), fields.length(), CHECK_NULL);
+  for (int i = 0; i < fields.length(); ++i) {
+    field_array->obj_at_put(i, fields.at(i)());
+  }
+  return JNIHandles::make_local(field_array());
+C2V_END
+
+C2V_VMENTRY(jlong, getMaxCallTargetOffset, (JNIEnv *env, jobject, jlong stub))
+  address target_addr = (address) stub;
+  if (target_addr != 0x0) {
+    int64_t off_low = (int64_t)target_addr - ((int64_t)CodeCache::low_bound() + sizeof(int));
+    int64_t off_high = (int64_t)target_addr - ((int64_t)CodeCache::high_bound() + sizeof(int));
+    return MAX2(ABS(off_low), ABS(off_high));
+  }
+  return -1;
+C2V_END
+
+C2V_VMENTRY(jobject, getResolvedType, (JNIEnv *env, jobject, jobject javaClass))
+  oop java_mirror = JNIHandles::resolve(javaClass);
+  assert(java_mirror != NULL, "argument to CompilerToVM.getResolvedType must not be NULL");
+  Handle type = GraalCompiler::get_JavaTypeFromClass(java_mirror, CHECK_NULL);
+  return JNIHandles::make_local(THREAD, type());
+C2V_END
+
+
+// helpers used to set fields in the HotSpotVMConfig object
+jfieldID getFieldID(JNIEnv* env, jobject obj, const char* name, const char* sig) {
+  jfieldID id = env->GetFieldID(env->GetObjectClass(obj), name, sig);
+  if (id == NULL) {
+    fatal(err_msg("field not found: %s (%s)", name, sig));
+  }
+  return id;
+}
+
+BasicType basicTypes[] = { T_BOOLEAN, T_BYTE, T_SHORT, T_CHAR, T_INT, T_FLOAT, T_LONG, T_DOUBLE, T_OBJECT };
+int basicTypeCount = sizeof(basicTypes) / sizeof(BasicType);
+
+C2V_ENTRY(void, initializeConfiguration, (JNIEnv *env, jobject, jobject config))
+
+#define set_boolean(name, value) do { env->SetBooleanField(config, getFieldID(env, config, name, "Z"), value); } while (0)
+#define set_int(name, value) do { env->SetIntField(config, getFieldID(env, config, name, "I"), value); } while (0)
+#define set_long(name, value) do { env->SetLongField(config, getFieldID(env, config, name, "J"), value); } while (0)
+#define set_object(name, value) do { env->SetObjectField(config, getFieldID(env, config, name, "Ljava/lang/Object;"), value); } while (0)
+#define set_int_array(name, value) do { env->SetObjectField(config, getFieldID(env, config, name, "[I"), value); } while (0)
+
+  guarantee(HeapWordSize == sizeof(char*), "Graal assumption that HeadWordSize == machine word size is wrong");
+#ifdef _WIN64
+  set_boolean(env, config, "windowsOs", true);
+#else
+  set_boolean("windowsOs", false);
+#endif
+  set_boolean("verifyOops", VerifyOops);
+  set_boolean("useFastLocking", UseFastLocking);
+  set_boolean("useFastNewObjectArray", UseFastNewObjectArray);
+  set_boolean("useBiasedLocking", UseBiasedLocking);
+  set_boolean("useFastNewTypeArray", UseFastNewTypeArray);
+  set_boolean("useTLAB", UseTLAB);
+  set_int("codeEntryAlignment", CodeEntryAlignment);
+  set_int("vmPageSize", os::vm_page_size());
+  set_int("stackShadowPages", StackShadowPages);
+  set_int("hubOffset", oopDesc::klass_offset_in_bytes());
+  set_int("markOffset", oopDesc::mark_offset_in_bytes());
+  set_int("prototypeMarkWordOffset", in_bytes(Klass::prototype_header_offset()));
+  set_int("superCheckOffsetOffset", in_bytes(Klass::super_check_offset_offset()));
+  set_int("secondarySuperCacheOffset", in_bytes(Klass::secondary_super_cache_offset()));
+  set_int("secondarySupersOffset", in_bytes(Klass::secondary_supers_offset()));
+  set_int("subklassOffset", in_bytes(Klass::subklass_offset()));
+  set_int("nextSiblingOffset", in_bytes(Klass::next_sibling_offset()));
+  set_int("arrayLengthOffset", arrayOopDesc::length_offset_in_bytes());
+  set_int("klassStateOffset", in_bytes(InstanceKlass::init_state_offset()));
+  set_int("klassStateFullyInitialized", (int)InstanceKlass::fully_initialized);
+  set_int("threadTlabTopOffset", in_bytes(JavaThread::tlab_top_offset()));
+  set_int("threadTlabEndOffset", in_bytes(JavaThread::tlab_end_offset()));
+  set_int("threadObjectOffset", in_bytes(JavaThread::threadObj_offset()));
+  set_int("osThreadOffset", in_bytes(JavaThread::osthread_offset()));
+  set_int("osThreadInterruptedOffset", in_bytes(OSThread::interrupted_offset()));
+  set_int("unlockedMask", (int) markOopDesc::unlocked_value);
+  set_int("biasedLockMaskInPlace", (int) markOopDesc::biased_lock_mask_in_place);
+  set_int("ageMaskInPlace", (int) markOopDesc::age_mask_in_place);
+  set_int("epochMaskInPlace", (int) markOopDesc::epoch_mask_in_place);
+  set_int("biasedLockPattern", (int) markOopDesc::biased_lock_pattern);
+  set_int("methodMaxLocalsOffset", in_bytes(Method::size_of_locals_offset()));
+  set_int("methodMaxStackOffset", in_bytes(Method::max_stack_offset()));
+  set_int("extraStackEntries", Method::extra_stack_entries());
+  set_int("methodAccessFlagsOffset", in_bytes(Method::access_flags_offset()));
+  set_int("klassHasFinalizerFlag", JVM_ACC_HAS_FINALIZER);
+  set_int("threadExceptionOopOffset", in_bytes(JavaThread::exception_oop_offset()));
+  set_int("threadExceptionPcOffset", in_bytes(JavaThread::exception_pc_offset()));
+  set_long("safepointPollingAddress", (jlong)(os::get_polling_page() + (SafepointPollOffset % os::vm_page_size())));
+  set_boolean("isPollingPageFar", Assembler::is_polling_page_far());
+  set_int("classMirrorOffset", in_bytes(Klass::java_mirror_offset()));
+  set_int("runtimeCallStackSize", (jint)frame::arg_reg_save_area_bytes);
+  set_int("klassModifierFlagsOffset", in_bytes(Klass::modifier_flags_offset()));
+  set_int("klassAccessFlagsOffset", in_bytes(Klass::access_flags_offset()));
+  set_int("klassOffset", java_lang_Class::klass_offset_in_bytes());
+  set_int("graalMirrorInClassOffset", java_lang_Class::graal_mirror_offset_in_bytes());
+  set_int("klassLayoutHelperOffset", in_bytes(Klass::layout_helper_offset()));
+  set_int("klassSuperKlassOffset", in_bytes(Klass::super_offset()));
+  set_int("methodDataOffset", in_bytes(Method::method_data_offset()));
+  set_int("nmethodEntryOffset", nmethod::verified_entry_point_offset());
+  set_int("methodCompiledEntryOffset", in_bytes(Method::from_compiled_offset()));
+  set_int("basicLockSize", sizeof(BasicLock));
+  set_int("basicLockDisplacedHeaderOffset", BasicLock::displaced_header_offset_in_bytes());
+  set_int("uninitializedIdentityHashCodeValue", markOopDesc::no_hash);
+  set_int("identityHashCodeShift", markOopDesc::hash_shift);
+
+  set_int("arrayKlassLayoutHelperIdentifier", 0x80000000);
+  assert((Klass::_lh_array_tag_obj_value & Klass::_lh_array_tag_type_value & 0x80000000) != 0, "obj_array and type_array must have first bit set");
+  set_int("arrayKlassComponentMirrorOffset", in_bytes(ArrayKlass::component_mirror_offset()));
+  
+  set_int("metaspaceArrayLengthOffset", Array<Klass*>::length_offset_in_bytes());
+  set_int("metaspaceArrayBaseOffset", Array<Klass*>::base_offset_in_bytes());
+  set_int("methodDataOopDataOffset", in_bytes(MethodData::data_offset()));
+  set_int("methodDataOopTrapHistoryOffset", in_bytes(MethodData::trap_history_offset()));
+  set_int("dataLayoutHeaderSize", DataLayout::header_size_in_bytes());
+  set_int("dataLayoutTagOffset", in_bytes(DataLayout::tag_offset()));
+  set_int("dataLayoutFlagsOffset", in_bytes(DataLayout::flags_offset()));
+  set_int("dataLayoutBCIOffset", in_bytes(DataLayout::bci_offset()));
+  set_int("dataLayoutCellsOffset", in_bytes(DataLayout::cell_offset(0)));
+  set_int("dataLayoutCellSize", DataLayout::cell_size);
+  set_int("bciProfileWidth", BciProfileWidth);
+  set_int("typeProfileWidth", TypeProfileWidth);
+
+  set_int("tlabAlignmentReserve", (int32_t)ThreadLocalAllocBuffer::alignment_reserve());
+  set_long("tlabIntArrayMarkWord", (intptr_t)markOopDesc::prototype()->copy_set_hash(0x2));
+  set_long("heapTopAddress", (jlong)(address) Universe::heap()->top_addr());
+  set_long("heapEndAddress", (jlong)(address) Universe::heap()->end_addr());
+  set_int("threadTlabStartOffset", in_bytes(JavaThread::tlab_start_offset()));
+  set_int("threadTlabSizeOffset", in_bytes(JavaThread::tlab_size_offset()));
+  set_int("threadAllocatedBytesOffset", in_bytes(JavaThread::allocated_bytes_offset()));
+  set_int("tlabSlowAllocationsOffset", in_bytes(JavaThread::tlab_slow_allocations_offset()));
+  set_int("tlabFastRefillWasteOffset", in_bytes(JavaThread::tlab_fast_refill_waste_offset()));
+  set_int("tlabNumberOfRefillsOffset", in_bytes(JavaThread::tlab_number_of_refills_offset()));
+  set_int("tlabRefillWasteLimitOffset", in_bytes(JavaThread::tlab_refill_waste_limit_offset()));
+  set_int("tlabRefillWasteIncrement", (int32_t) ThreadLocalAllocBuffer::refill_waste_limit_increment());
+  set_int("klassInstanceSizeOffset", in_bytes(Klass::layout_helper_offset()));
+  set_boolean("tlabStats", TLABStats);
+  set_boolean("inlineContiguousAllocationSupported", !CMSIncrementalMode && Universe::heap()->supports_inline_contig_alloc());
+
+  set_long("arrayPrototypeMarkWord", (intptr_t)markOopDesc::prototype());
+  set_int("layoutHelperLog2ElementSizeShift", Klass::_lh_log2_element_size_shift);
+  set_int("layoutHelperLog2ElementSizeMask", Klass::_lh_log2_element_size_mask);
+  set_int("layoutHelperElementTypeShift", Klass::_lh_element_type_shift);
+  set_int("layoutHelperElementTypeMask", Klass::_lh_element_type_mask);
+  set_int("layoutHelperHeaderSizeShift", Klass::_lh_header_size_shift);
+  set_int("layoutHelperHeaderSizeMask", Klass::_lh_header_size_mask);
+  set_int("layoutHelperOffset", in_bytes(Klass::layout_helper_offset()));
+
+  set_long("debugStub", VmIds::addStub((address)warning));
+  set_long("instanceofStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_slow_subtype_check_id)));
+  set_long("newInstanceStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_new_instance_id)));
+  set_long("newArrayStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_new_array_id)));
+  set_long("newMultiArrayStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_new_multi_array_id)));
+  set_long("identityHashCodeStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_identity_hash_code_id)));
+  set_long("threadIsInterruptedStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_thread_is_interrupted_id)));
+  set_long("inlineCacheMissStub", VmIds::addStub(SharedRuntime::get_ic_miss_stub()));
+  set_long("handleExceptionStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_handle_exception_nofpu_id)));
+  set_long("handleDeoptStub", VmIds::addStub(SharedRuntime::deopt_blob()->unpack()));
+  set_long("monitorEnterStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_monitorenter_id)));
+  set_long("monitorExitStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_monitorexit_id)));
+  set_long("verifyOopStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_verify_oop_id)));
+  set_long("vmErrorStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_vm_error_id)));
+  set_long("deoptimizeStub", VmIds::addStub(SharedRuntime::deopt_blob()->uncommon_trap()));
+  set_long("unwindExceptionStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_unwind_exception_call_id)));
+  set_long("osrMigrationEndStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_OSR_migration_end_id)));
+  set_long("registerFinalizerStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_register_finalizer_id)));
+  set_long("setDeoptInfoStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_set_deopt_info_id)));
+  set_long("createNullPointerExceptionStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_create_null_pointer_exception_id)));
+  set_long("createOutOfBoundsExceptionStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_create_out_of_bounds_exception_id)));
+  set_long("javaTimeMillisStub", VmIds::addStub(CAST_FROM_FN_PTR(address, os::javaTimeMillis)));
+  set_long("javaTimeNanosStub", VmIds::addStub(CAST_FROM_FN_PTR(address, os::javaTimeNanos)));
+  set_long("arithmeticFremStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_arithmetic_frem_id)));
+  set_long("arithmeticDremStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_arithmetic_drem_id)));
+  set_long("arithmeticSinStub", VmIds::addStub(CAST_FROM_FN_PTR(address, SharedRuntime::dsin)));
+  set_long("arithmeticCosStub", VmIds::addStub(CAST_FROM_FN_PTR(address, SharedRuntime::dcos)));
+  set_long("arithmeticTanStub", VmIds::addStub(CAST_FROM_FN_PTR(address, SharedRuntime::dtan)));
+  set_long("logPrimitiveStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_log_primitive_id)));
+  set_long("logObjectStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_log_object_id)));
+  set_long("logPrintfStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_log_printf_id)));
+
+
+  BarrierSet* bs = Universe::heap()->barrier_set();
+  switch (bs->kind()) {
+    case BarrierSet::CardTableModRef:
+    case BarrierSet::CardTableExtension: {
+      jlong base = (jlong)((CardTableModRefBS*)bs)->byte_map_base;
+      assert(base != 0, "unexpected byte_map_base");
+      set_long("cardtableStartAddress", base);
+      set_int("cardtableShift", CardTableModRefBS::card_shift);
+      break;
+    }
+    case BarrierSet::ModRef:
+    case BarrierSet::Other:
+      set_long("cardtableStartAddress", 0);
+      set_int("cardtableShift", 0);
+      // No post barriers
+      break;
+#ifndef SERIALGC
+    case BarrierSet::G1SATBCT:
+    case BarrierSet::G1SATBCTLogging:
+#endif // SERIALGC
+    default:
+      ShouldNotReachHere();
+      break;
+    }
+
+  set_int("arrayClassElementOffset", in_bytes(ObjArrayKlass::element_klass_offset()));
+
+#undef set_boolean
+#undef set_int
+#undef set_long
+#undef set_object
+#undef set_int_array
+
+C2V_END
+
+C2V_VMENTRY(jint, installCode0, (JNIEnv *jniEnv, jobject, jobject compResult, jobject installed_code, jobject info))
+  ResourceMark rm;
+  HandleMark hm;
+  Handle compResultHandle = JNIHandles::resolve(compResult);
+  nmethod* nm = NULL;
+  methodHandle method = getMethodFromHotSpotMethod(HotSpotCompilationResult::method(compResult));
+  Handle installed_code_handle = JNIHandles::resolve(installed_code);
+  GraalEnv::CodeInstallResult result;
+  CodeInstaller installer(compResultHandle, method, result, nm, installed_code_handle);
+
+  if (result != GraalEnv::ok) {
+    assert(nm == NULL, "should be");
+  } else {
+    if (info != NULL) {
+      arrayOop codeCopy = oopFactory::new_byteArray(nm->code_size(), CHECK_0);
+      memcpy(codeCopy->base(T_BYTE), nm->code_begin(), nm->code_size());
+      HotSpotCodeInfo::set_code(info, codeCopy);
+      HotSpotCodeInfo::set_start(info, (jlong) nm->code_begin());
+    }
+
+    if (!installed_code_handle.is_null()) {
+      assert(installed_code_handle->is_a(HotSpotInstalledCode::klass()), "wrong type");
+      HotSpotInstalledCode::set_nmethod(installed_code_handle, (jlong) nm);
+      HotSpotInstalledCode::set_method(installed_code_handle, HotSpotCompilationResult::method(compResult));
+      assert(nm == NULL || !installed_code_handle->is_scavengable() || nm->on_scavenge_root_list(), "nm should be scavengable if installed_code is scavengable");
+    }
+  }
+  return result;
+C2V_END
+
+C2V_VMENTRY(jobject, disassembleNative, (JNIEnv *jniEnv, jobject, jbyteArray code, jlong start_address))
+  ResourceMark rm;
+  HandleMark hm;
+
+  stringStream(st);
+  arrayOop code_oop = (arrayOop) JNIHandles::resolve(code);
+  int len = code_oop->length();
+  address begin = (address) code_oop->base(T_BYTE);
+  address end = begin + len;
+  Disassembler::decode(begin, end, &st);
+
+  Handle result = java_lang_String::create_from_platform_dependent_str(st.as_string(), CHECK_NULL);
+  return JNIHandles::make_local(result());
+C2V_END
+
+C2V_VMENTRY(jobject, getStackTraceElement, (JNIEnv *env, jobject, jlong metaspace_method, int bci))
+  ResourceMark rm;
+  HandleMark hm;
+
+  methodHandle method = asMethod(metaspace_method);
+  oop element = java_lang_StackTraceElement::create(method, bci, CHECK_NULL);
+  return JNIHandles::make_local(element);
+C2V_END
+
+C2V_VMENTRY(jobject, executeCompiledMethodVarargs, (JNIEnv *env, jobject, jlong metaspace_method, jlong metaspace_nmethod, jobject args))
+  ResourceMark rm;
+  HandleMark hm;
+
+  assert(metaspace_method != 0, "just checking");
+  methodHandle mh = asMethod(metaspace_method);
+  Symbol* signature = mh->signature();
+  JavaCallArguments jca;
+
+  JavaArgumentUnboxer jap(signature, &jca, (arrayOop) JNIHandles::resolve(args), mh->is_static());
+  JavaValue result(jap.get_ret_type());
+
+  nmethod* nm = (nmethod*) (address) metaspace_nmethod;
+  if (nm == NULL || !nm->is_alive()) {
+    THROW_0(vmSymbols::MethodInvalidatedException());
+  }
+
+  JavaCalls::call(&result, mh, nm, &jca, CHECK_NULL);
+
+  if (jap.get_ret_type() == T_VOID) {
+    return NULL;
+  } else if (jap.get_ret_type() == T_OBJECT || jap.get_ret_type() == T_ARRAY) {
+    return JNIHandles::make_local((oop) result.get_jobject());
+  } else {
+    oop o = java_lang_boxing_object::create(jap.get_ret_type(), (jvalue *) result.get_value_addr(), CHECK_NULL);
+    return JNIHandles::make_local(o);
+  }
+C2V_END
+
+C2V_VMENTRY(jobject, executeCompiledMethod, (JNIEnv *env, jobject, jlong metaspace_method, jlong metaspace_nmethod, jobject arg1, jobject arg2, jobject arg3))
+  ResourceMark rm;
+  HandleMark hm;
+
+  methodHandle method = asMethod(metaspace_method);
+  assert(!method.is_null(), "just checking");
+  JavaValue result(T_OBJECT);
+  JavaCallArguments args;
+  args.push_oop(JNIHandles::resolve(arg1));
+  args.push_oop(JNIHandles::resolve(arg2));
+  args.push_oop(JNIHandles::resolve(arg3));
+
+  nmethod* nm = (nmethod*) (address) metaspace_nmethod;
+  if (nm == NULL || !nm->is_alive()) {
+    THROW_0(vmSymbols::MethodInvalidatedException());
+  }
+
+  JavaCalls::call(&result, method, nm, &args, CHECK_NULL);
+
+  return JNIHandles::make_local((oop) result.get_jobject());
+C2V_END
+
+C2V_VMENTRY(jint, getVtableEntryOffset, (JNIEnv *, jobject, jlong metaspace_method))
+
+  Method* method = asMethod(metaspace_method);
+  assert(!InstanceKlass::cast(method->method_holder())->is_interface(), "vtableEntryOffset cannot be called for interface methods");
+  assert(InstanceKlass::cast(method->method_holder())->is_linked(), "vtableEntryOffset cannot be called is holder is not linked");
+
+  // get entry offset in words
+  int vtable_entry_offset = InstanceKlass::vtable_start_offset() + method->vtable_index() * vtableEntry::size();
+  // convert to bytes
+  vtable_entry_offset = vtable_entry_offset * wordSize + vtableEntry::method_offset_in_bytes();
+
+  return vtable_entry_offset;
+C2V_END
+
+C2V_VMENTRY(jobject, getDeoptedLeafGraphIds, (JNIEnv *, jobject))
+
+  // the contract for this method is as follows:
+  // returning null: no deopted leaf graphs
+  // returning array (size > 0): the ids of the deopted leaf graphs
+  // returning array (size == 0): there was an overflow, the compiler needs to clear its cache completely
+
+  oop array = GraalCompiler::instance()->dump_deopted_leaf_graphs(CHECK_NULL);
+  return JNIHandles::make_local(array);
+C2V_END
+
+C2V_VMENTRY(jobject, decodePC, (JNIEnv *, jobject, jlong pc))
+  stringStream(st);
+  CodeBlob* blob = CodeCache::find_blob_unsafe((void*) pc);
+  if (blob == NULL) {
+    st.print("[unidentified pc]");
+  } else {
+    st.print(blob->name());
+
+    nmethod* nm = blob->as_nmethod_or_null();
+    if (nm != NULL && nm->method() != NULL) {
+      st.print(" %s.", nm->method()->method_holder()->external_name());
+      nm->method()->name()->print_symbol_on(&st);
+      st.print("  @ %d", pc - (jlong) nm->entry_point());
+    }
+  }
+  Handle result = java_lang_String::create_from_platform_dependent_str(st.as_string(), CHECK_NULL);
+  return JNIHandles::make_local(result());
+C2V_END
+
+
+#define CC (char*)  /*cast a literal from (const char*)*/
+#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f))
+
+#define RESOLVED_TYPE         "Lcom/oracle/graal/api/meta/ResolvedJavaType;"
+#define TYPE                  "Lcom/oracle/graal/api/meta/JavaType;"
+#define METHOD                "Lcom/oracle/graal/api/meta/JavaMethod;"
+#define FIELD                 "Lcom/oracle/graal/api/meta/JavaField;"
+#define SIGNATURE             "Lcom/oracle/graal/api/meta/Signature;"
+#define CONSTANT_POOL         "Lcom/oracle/graal/api/meta/ConstantPool;"
+#define CONSTANT              "Lcom/oracle/graal/api/meta/Constant;"
+#define KIND                  "Lcom/oracle/graal/api/meta/Kind;"
+#define RUNTIME_CALL          "Lcom/oracle/graal/api/code/RuntimeCall;"
+#define EXCEPTION_HANDLERS    "[Lcom/oracle/graal/api/meta/ExceptionHandler;"
+#define REFLECT_METHOD        "Ljava/lang/reflect/Method;"
+#define REFLECT_CONSTRUCTOR   "Ljava/lang/reflect/Constructor;"
+#define REFLECT_FIELD         "Ljava/lang/reflect/Field;"
+#define STRING                "Ljava/lang/String;"
+#define OBJECT                "Ljava/lang/Object;"
+#define CLASS                 "Ljava/lang/Class;"
+#define STACK_TRACE_ELEMENT   "Ljava/lang/StackTraceElement;"
+#define HS_RESOLVED_TYPE      "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedObjectType;"
+#define HS_RESOLVED_METHOD    "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;"
+#define HS_RESOLVED_FIELD     "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaField;"
+#define HS_COMP_RESULT        "Lcom/oracle/graal/hotspot/HotSpotCompilationResult;"
+#define HS_CONFIG             "Lcom/oracle/graal/hotspot/HotSpotVMConfig;"
+#define HS_METHOD             "Lcom/oracle/graal/hotspot/meta/HotSpotMethod;"
+#define HS_INSTALLED_CODE     "Lcom/oracle/graal/hotspot/meta/HotSpotInstalledCode;"
+#define HS_CODE_INFO          "Lcom/oracle/graal/hotspot/meta/HotSpotCodeInfo;"
+#define METHOD_DATA           "Lcom/oracle/graal/hotspot/meta/HotSpotMethodData;"
+#define METASPACE_METHOD      "J"
+#define METASPACE_METHOD_DATA "J"
+#define NMETHOD               "J"
+
+JNINativeMethod CompilerToVM_methods[] = {
+  {CC"initializeBytecode",            CC"("METASPACE_METHOD"[B)[B",                                     FN_PTR(initializeBytecode)},
+  {CC"getSignature",                  CC"("METASPACE_METHOD")"STRING,                                   FN_PTR(getSignature)},
+  {CC"initializeExceptionHandlers",   CC"("METASPACE_METHOD EXCEPTION_HANDLERS")"EXCEPTION_HANDLERS,    FN_PTR(initializeExceptionHandlers)},
+  {CC"hasBalancedMonitors",           CC"("METASPACE_METHOD")Z",                                        FN_PTR(hasBalancedMonitors)},
+  {CC"getUniqueConcreteMethod",       CC"("METASPACE_METHOD"["HS_RESOLVED_TYPE")"METASPACE_METHOD,      FN_PTR(getUniqueConcreteMethod)},
+  {CC"getStackTraceElement",          CC"("METASPACE_METHOD"I)"STACK_TRACE_ELEMENT,                     FN_PTR(getStackTraceElement)},
+  {CC"initializeMethod",              CC"("METASPACE_METHOD HS_RESOLVED_METHOD")V",                     FN_PTR(initializeMethod)},
+  {CC"initializeMethodData",          CC"("METASPACE_METHOD_DATA METHOD_DATA")V",                       FN_PTR(initializeMethodData)},
+  {CC"isMethodCompilable",            CC"("METASPACE_METHOD")Z",                                        FN_PTR(isMethodCompilable)},
+  {CC"getInvocationCount",            CC"("METASPACE_METHOD")I",                                        FN_PTR(getInvocationCount)},
+  {CC"getCompiledCodeSize",           CC"("METASPACE_METHOD")I",                                        FN_PTR(getCompiledCodeSize)},
+  {CC"getVtableEntryOffset",          CC"("METASPACE_METHOD")I",                                        FN_PTR(getVtableEntryOffset)},
+  {CC"lookupType",                    CC"("STRING HS_RESOLVED_TYPE"Z)"TYPE,                             FN_PTR(lookupType)},
+  {CC"lookupConstantInPool",          CC"("HS_RESOLVED_TYPE"I)"OBJECT,                                  FN_PTR(lookupConstantInPool)},
+  {CC"lookupMethodInPool",            CC"("HS_RESOLVED_TYPE"IB)"METHOD,                                 FN_PTR(lookupMethodInPool)},
+  {CC"lookupTypeInPool",              CC"("HS_RESOLVED_TYPE"I)"TYPE,                                    FN_PTR(lookupTypeInPool)},
+  {CC"lookupReferencedTypeInPool",    CC"("HS_RESOLVED_TYPE"IB)V",                                      FN_PTR(lookupReferencedTypeInPool)},
+  {CC"lookupFieldInPool",             CC"("HS_RESOLVED_TYPE"IB)"FIELD,                                  FN_PTR(lookupFieldInPool)},
+  {CC"resolveMethod",                 CC"("HS_RESOLVED_TYPE STRING STRING")"METHOD,                     FN_PTR(resolveMethod)},
+  {CC"getInstanceFields",             CC"("HS_RESOLVED_TYPE")["HS_RESOLVED_FIELD,                       FN_PTR(getInstanceFields)},
+  {CC"isTypeInitialized",             CC"("HS_RESOLVED_TYPE")Z",                                        FN_PTR(isTypeInitialized)},
+  {CC"initializeType",                CC"("HS_RESOLVED_TYPE")V",                                        FN_PTR(initializeType)},
+  {CC"getMaxCallTargetOffset",        CC"(J)J",                                                         FN_PTR(getMaxCallTargetOffset)},
+  {CC"getResolvedType",               CC"("CLASS")"RESOLVED_TYPE,                                       FN_PTR(getResolvedType)},
+  {CC"getMetaspaceMethod",            CC"("REFLECT_METHOD"["HS_RESOLVED_TYPE")"METASPACE_METHOD,        FN_PTR(getMetaspaceMethod)},
+  {CC"getMetaspaceConstructor",       CC"("REFLECT_CONSTRUCTOR"["HS_RESOLVED_TYPE")"METASPACE_METHOD,   FN_PTR(getMetaspaceConstructor)},
+  {CC"getJavaField",                  CC"("REFLECT_FIELD")"HS_RESOLVED_FIELD,                           FN_PTR(getJavaField)},
+  {CC"initializeConfiguration",       CC"("HS_CONFIG")V",                                               FN_PTR(initializeConfiguration)},
+  {CC"installCode0",                  CC"("HS_COMP_RESULT HS_INSTALLED_CODE HS_CODE_INFO")I",           FN_PTR(installCode0)},
+  {CC"disassembleNative",             CC"([BJ)"STRING,                                                  FN_PTR(disassembleNative)},
+  {CC"executeCompiledMethod",         CC"("METASPACE_METHOD NMETHOD OBJECT OBJECT OBJECT")"OBJECT,      FN_PTR(executeCompiledMethod)},
+  {CC"executeCompiledMethodVarargs",  CC"("METASPACE_METHOD NMETHOD "["OBJECT")"OBJECT,                 FN_PTR(executeCompiledMethodVarargs)},
+  {CC"getDeoptedLeafGraphIds",        CC"()[J",                                                         FN_PTR(getDeoptedLeafGraphIds)},
+  {CC"decodePC",                      CC"(J)"STRING,                                                    FN_PTR(decodePC)},
+};
+
+int CompilerToVM_methods_count() {
+  return sizeof(CompilerToVM_methods) / sizeof(JNINativeMethod);
+}
+
--- a/src/share/vm/graal/graalRuntime.cpp	Tue Dec 11 08:28:00 2012 +0100
+++ b/src/share/vm/graal/graalRuntime.cpp	Tue Dec 11 08:48:12 2012 +0100
@@ -1,618 +1,606 @@
-/*
- * 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.
- */
-
-#include "precompiled.hpp"
-#include "runtime/interfaceSupport.hpp"
-#include "prims/jvm.h"
-#include "graal/graalRuntime.hpp"
-#include "graal/graalVMToCompiler.hpp"
-#include "asm/codeBuffer.hpp"
-#include "runtime/biasedLocking.hpp"
-
-// Implementation of GraalStubAssembler
-
-GraalStubAssembler::GraalStubAssembler(CodeBuffer* code, const char * name, int stub_id) : MacroAssembler(code) {
-  _name = name;
-  _must_gc_arguments = false;
-  _frame_size = no_frame_size;
-  _num_rt_args = 0;
-  _stub_id = stub_id;
-}
-
-
-void GraalStubAssembler::set_info(const char* name, bool must_gc_arguments) {
-  _name = name;
-  _must_gc_arguments = must_gc_arguments;
-}
-
-
-void GraalStubAssembler::set_frame_size(int size) {
-  if (_frame_size == no_frame_size) {
-    _frame_size = size;
-  }
-  assert(_frame_size == size, "can't change the frame size");
-}
-
-
-void GraalStubAssembler::set_num_rt_args(int args) {
-  if (_num_rt_args == 0) {
-    _num_rt_args = args;
-  }
-  assert(_num_rt_args == args, "can't change the number of args");
-}
-
-// Implementation of GraalRuntime
-
-CodeBlob* GraalRuntime::_blobs[GraalRuntime::number_of_ids];
-const char *GraalRuntime::_blob_names[] = {
-  GRAAL_STUBS(STUB_NAME, LAST_STUB_NAME)
-};
-
-// Simple helper to see if the caller of a runtime stub which
-// entered the VM has been deoptimized
-
-static bool caller_is_deopted() {
-  JavaThread* thread = JavaThread::current();
-  RegisterMap reg_map(thread, false);
-  frame runtime_frame = thread->last_frame();
-  frame caller_frame = runtime_frame.sender(&reg_map);
-  assert(caller_frame.is_compiled_frame(), "must be compiled");
-  return caller_frame.is_deoptimized_frame();
-}
-
-// Stress deoptimization
-static void deopt_caller() {
-  if ( !caller_is_deopted()) {
-    JavaThread* thread = JavaThread::current();
-    RegisterMap reg_map(thread, false);
-    frame runtime_frame = thread->last_frame();
-    frame caller_frame = runtime_frame.sender(&reg_map);
-    Deoptimization::deoptimize_frame(thread, caller_frame.id(), Deoptimization::Reason_constraint);
-    assert(caller_is_deopted(), "Must be deoptimized");
-  }
-}
-
-static bool setup_code_buffer(CodeBuffer* code) {
-  // Preinitialize the consts section to some large size:
-  int locs_buffer_size = 1 * (relocInfo::length_limit + sizeof(relocInfo));
-  char* locs_buffer = NEW_RESOURCE_ARRAY(char, locs_buffer_size);
-  code->insts()->initialize_shared_locs((relocInfo*)locs_buffer,
-                                        locs_buffer_size / sizeof(relocInfo));
-
-  // Global stubs have neither constants nor local stubs
-  code->initialize_consts_size(0);
-  code->initialize_stubs_size(0);
-
-  return true;
-}
-
-void GraalRuntime::generate_blob_for(BufferBlob* buffer_blob, StubID id) {
-  assert(0 <= id && id < number_of_ids, "illegal stub id");
-  ResourceMark rm;
-  // create code buffer for code storage
-  CodeBuffer code(buffer_blob);
-
-  setup_code_buffer(&code);
-
-  // create assembler for code generation
-  GraalStubAssembler* sasm = new GraalStubAssembler(&code, name_for(id), id);
-  // generate code for runtime stub
-  OopMapSet* oop_maps;
-  oop_maps = generate_code_for(id, sasm);
-  assert(oop_maps == NULL || sasm->frame_size() != no_frame_size,
-         "if stub has an oop map it must have a valid frame size");
-
-#ifdef ASSERT
-  // Make sure that stubs that need oopmaps have them
-  switch (id) {
-    // These stubs don't need to have an oopmap
-    case graal_slow_subtype_check_id:
-#if defined(SPARC) || defined(PPC)
-    case handle_exception_nofpu_id:  // Unused on sparc
-#endif
-#ifdef GRAAL
-    case graal_verify_oop_id:
-    case graal_unwind_exception_call_id:
-    case graal_OSR_migration_end_id:
-    case graal_arithmetic_frem_id:
-    case graal_arithmetic_drem_id:
-    case graal_set_deopt_info_id:
-#endif
-      break;
-
-    // All other stubs should have oopmaps
-    default:
-      assert(oop_maps != NULL, "must have an oopmap");
-  }
-#endif
-
-  // align so printing shows nop's instead of random code at the end (SimpleStubs are aligned)
-  sasm->align(BytesPerWord);
-  // make sure all code is in code buffer
-  sasm->flush();
-  // create blob - distinguish a few special cases
-  CodeBlob* blob = RuntimeStub::new_runtime_stub(name_for(id),
-                                                 &code,
-                                                 CodeOffsets::frame_never_safe,
-                                                 sasm->frame_size(),
-                                                 oop_maps,
-                                                 sasm->must_gc_arguments());
-  // install blob
-  assert(blob != NULL, "blob must exist");
-  _blobs[id] = blob;
-}
-
-
-void GraalRuntime::initialize(BufferBlob* blob) {
-  // generate stubs
-  for (int id = 0; id < number_of_ids; id++) generate_blob_for(blob, (StubID)id);
-  // printing
-#ifndef PRODUCT
-  if (PrintSimpleStubs) {
-    ResourceMark rm;
-    for (int id = 0; id < number_of_ids; id++) {
-      _blobs[id]->print();
-      if (_blobs[id]->oop_maps() != NULL) {
-        _blobs[id]->oop_maps()->print();
-      }
-    }
-  }
-#endif
-}
-
-
-CodeBlob* GraalRuntime::blob_for(StubID id) {
-  assert(0 <= id && id < number_of_ids, "illegal stub id");
-  return _blobs[id];
-}
-
-
-const char* GraalRuntime::name_for(StubID id) {
-  assert(0 <= id && id < number_of_ids, "illegal stub id");
-  return _blob_names[id];
-}
-
-const char* GraalRuntime::name_for_address(address entry) {
-  for (int id = 0; id < number_of_ids; id++) {
-    if (entry == entry_for((StubID)id)) return name_for((StubID)id);
-  }
-
-#define FUNCTION_CASE(a, f) \
-  if ((intptr_t)a == CAST_FROM_FN_PTR(intptr_t, f))  return #f
-
-  FUNCTION_CASE(entry, os::javaTimeMillis);
-  FUNCTION_CASE(entry, os::javaTimeNanos);
-  FUNCTION_CASE(entry, SharedRuntime::OSR_migration_end);
-  FUNCTION_CASE(entry, SharedRuntime::d2f);
-  FUNCTION_CASE(entry, SharedRuntime::d2i);
-  FUNCTION_CASE(entry, SharedRuntime::d2l);
-  FUNCTION_CASE(entry, SharedRuntime::dcos);
-  FUNCTION_CASE(entry, SharedRuntime::dexp);
-  FUNCTION_CASE(entry, SharedRuntime::dlog);
-  FUNCTION_CASE(entry, SharedRuntime::dlog10);
-  FUNCTION_CASE(entry, SharedRuntime::dpow);
-  FUNCTION_CASE(entry, SharedRuntime::drem);
-  FUNCTION_CASE(entry, SharedRuntime::dsin);
-  FUNCTION_CASE(entry, SharedRuntime::dtan);
-  FUNCTION_CASE(entry, SharedRuntime::f2i);
-  FUNCTION_CASE(entry, SharedRuntime::f2l);
-  FUNCTION_CASE(entry, SharedRuntime::frem);
-  FUNCTION_CASE(entry, SharedRuntime::l2d);
-  FUNCTION_CASE(entry, SharedRuntime::l2f);
-  FUNCTION_CASE(entry, SharedRuntime::ldiv);
-  FUNCTION_CASE(entry, SharedRuntime::lmul);
-  FUNCTION_CASE(entry, SharedRuntime::lrem);
-  FUNCTION_CASE(entry, SharedRuntime::lrem);
-  FUNCTION_CASE(entry, SharedRuntime::dtrace_method_entry);
-  FUNCTION_CASE(entry, SharedRuntime::dtrace_method_exit);
-#ifdef TRACE_HAVE_INTRINSICS
-  FUNCTION_CASE(entry, TRACE_TIME_METHOD);
-#endif
-
-  ShouldNotReachHere();
-  return NULL;
-
-#undef FUNCTION_CASE
-}
-
-
-JRT_ENTRY(void, GraalRuntime::new_instance(JavaThread* thread, Klass* klass))
-  assert(klass->is_klass(), "not a class");
-  instanceKlassHandle h(thread, klass);
-  h->check_valid_for_instantiation(true, CHECK);
-  // make sure klass is initialized
-  h->initialize(CHECK);
-  // allocate instance and return via TLS
-  oop obj = h->allocate_instance(CHECK);
-  thread->set_vm_result(obj);
-JRT_END
-
-
-JRT_ENTRY(void, GraalRuntime::new_type_array(JavaThread* thread, Klass* klass, jint length))
-  // Note: no handle for klass needed since they are not used
-  //       anymore after new_typeArray() and no GC can happen before.
-  //       (This may have to change if this code changes!)
-  assert(klass->is_klass(), "not a class");
-  BasicType elt_type = TypeArrayKlass::cast(klass)->element_type();
-  oop obj = oopFactory::new_typeArray(elt_type, length, CHECK);
-  thread->set_vm_result(obj);
-  // This is pretty rare but this runtime patch is stressful to deoptimization
-  // if we deoptimize here so force a deopt to stress the path.
-  if (DeoptimizeALot) {
-    deopt_caller();
-  }
-
-JRT_END
-
-
-JRT_ENTRY(void, GraalRuntime::new_object_array(JavaThread* thread, Klass* array_klass, jint length))
-  // Note: no handle for klass needed since they are not used
-  //       anymore after new_objArray() and no GC can happen before.
-  //       (This may have to change if this code changes!)
-  assert(array_klass->is_klass(), "not a class");
-  Klass* elem_klass = ObjArrayKlass::cast(array_klass)->element_klass();
-  objArrayOop obj = oopFactory::new_objArray(elem_klass, length, CHECK);
-  thread->set_vm_result(obj);
-  // This is pretty rare but this runtime patch is stressful to deoptimization
-  // if we deoptimize here so force a deopt to stress the path.
-  if (DeoptimizeALot) {
-    deopt_caller();
-  }
-JRT_END
-
-
-JRT_ENTRY(void, GraalRuntime::new_multi_array(JavaThread* thread, Klass* klass, int rank, jint* dims))
-  assert(klass->is_klass(), "not a class");
-  assert(rank >= 1, "rank must be nonzero");
-  oop obj = ArrayKlass::cast(klass)->multi_allocate(rank, dims, CHECK);
-  thread->set_vm_result(obj);
-JRT_END
-
-JRT_ENTRY(void, GraalRuntime::unimplemented_entry(JavaThread* thread, StubID id))
-  tty->print_cr("GraalRuntime::entry_for(%d) returned unimplemented entry point", id);
-JRT_END
-
-extern void vm_exit(int code);
-
-// Enter this method from compiled code handler below. This is where we transition
-// to VM mode. This is done as a helper routine so that the method called directly
-// from compiled code does not have to transition to VM. This allows the entry
-// method to see if the nmethod that we have just looked up a handler for has
-// been deoptimized while we were in the vm. This simplifies the assembly code
-// cpu directories.
-//
-// We are entering here from exception stub (via the entry method below)
-// If there is a compiled exception handler in this method, we will continue there;
-// otherwise we will unwind the stack and continue at the caller of top frame method
-// Note: we enter in Java using a special JRT wrapper. This wrapper allows us to
-// control the area where we can allow a safepoint. After we exit the safepoint area we can
-// check to see if the handler we are going to return is now in a nmethod that has
-// been deoptimized. If that is the case we return the deopt blob
-// unpack_with_exception entry instead. This makes life for the exception blob easier
-// because making that same check and diverting is painful from assembly language.
-JRT_ENTRY_NO_ASYNC(static address, exception_handler_for_pc_helper(JavaThread* thread, oopDesc* ex, address pc, nmethod*& nm))
-  // Reset method handle flag.
-  thread->set_is_method_handle_return(false);
-
-  Handle exception(thread, ex);
-  nm = CodeCache::find_nmethod(pc);
-  assert(nm != NULL, "this is not an nmethod");
-  // Adjust the pc as needed/
-  if (nm->is_deopt_pc(pc)) {
-    RegisterMap map(thread, false);
-    frame exception_frame = thread->last_frame().sender(&map);
-    // if the frame isn't deopted then pc must not correspond to the caller of last_frame
-    assert(exception_frame.is_deoptimized_frame(), "must be deopted");
-    pc = exception_frame.pc();
-  }
-#ifdef ASSERT
-  assert(exception.not_null(), "NULL exceptions should be handled by throw_exception");
-  assert(exception->is_oop(), "just checking");
-  // Check that exception is a subclass of Throwable, otherwise we have a VerifyError
-  if (!(exception->is_a(SystemDictionary::Throwable_klass()))) {
-    if (ExitVMOnVerifyError) vm_exit(-1);
-    ShouldNotReachHere();
-  }
-#endif
-
-  // Check the stack guard pages and reenable them if necessary and there is
-  // enough space on the stack to do so.  Use fast exceptions only if the guard
-  // pages are enabled.
-  bool guard_pages_enabled = thread->stack_yellow_zone_enabled();
-  if (!guard_pages_enabled) guard_pages_enabled = thread->reguard_stack();
-
-  if (JvmtiExport::can_post_on_exceptions()) {
-    // To ensure correct notification of exception catches and throws
-    // we have to deoptimize here.  If we attempted to notify the
-    // catches and throws during this exception lookup it's possible
-    // we could deoptimize on the way out of the VM and end back in
-    // the interpreter at the throw site.  This would result in double
-    // notifications since the interpreter would also notify about
-    // these same catches and throws as it unwound the frame.
-
-    RegisterMap reg_map(thread);
-    frame stub_frame = thread->last_frame();
-    frame caller_frame = stub_frame.sender(&reg_map);
-
-    // We don't really want to deoptimize the nmethod itself since we
-    // can actually continue in the exception handler ourselves but I
-    // don't see an easy way to have the desired effect.
-    Deoptimization::deoptimize_frame(thread, caller_frame.id(), Deoptimization::Reason_constraint);
-    assert(caller_is_deopted(), "Must be deoptimized");
-
-    return SharedRuntime::deopt_blob()->unpack_with_exception_in_tls();
-  }
-
-  // ExceptionCache is used only for exceptions at call sites and not for implicit exceptions
-  if (guard_pages_enabled) {
-    address fast_continuation = nm->handler_for_exception_and_pc(exception, pc);
-    if (fast_continuation != NULL) {
-      // Set flag if return address is a method handle call site.
-      thread->set_is_method_handle_return(nm->is_method_handle_return(pc));
-      return fast_continuation;
-    }
-  }
-
-  // If the stack guard pages are enabled, check whether there is a handler in
-  // the current method.  Otherwise (guard pages disabled), force an unwind and
-  // skip the exception cache update (i.e., just leave continuation==NULL).
-  address continuation = NULL;
-  if (guard_pages_enabled) {
-
-    // New exception handling mechanism can support inlined methods
-    // with exception handlers since the mappings are from PC to PC
-
-    // debugging support
-    // tracing
-    if (TraceExceptions) {
-      ttyLocker ttyl;
-      ResourceMark rm;
-      int offset = pc - nm->code_begin();
-      tty->print_cr("Exception <%s> (0x%x) thrown in compiled method <%s> at PC " PTR_FORMAT " [" PTR_FORMAT "+%d] for thread 0x%x",
-                    exception->print_value_string(), (address)exception(), nm->method()->print_value_string(), pc, nm->code_begin(), offset, thread);
-    }
-    // for AbortVMOnException flag
-    NOT_PRODUCT(Exceptions::debug_check_abort(exception));
-
-    // Clear out the exception oop and pc since looking up an
-    // exception handler can cause class loading, which might throw an
-    // exception and those fields are expected to be clear during
-    // normal bytecode execution.
-    thread->set_exception_oop(NULL);
-    thread->set_exception_pc(NULL);
-
-    continuation = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, false, false);
-    // If an exception was thrown during exception dispatch, the exception oop may have changed
-    thread->set_exception_oop(exception());
-    thread->set_exception_pc(pc);
-
-    // the exception cache is used only by non-implicit exceptions
-    if (continuation != NULL && !SharedRuntime::deopt_blob()->contains(continuation)) {
-      nm->add_handler_for_exception_and_pc(exception, pc, continuation);
-    }
-  }
-
-  thread->set_vm_result(exception());
-  // Set flag if return address is a method handle call site.
-  thread->set_is_method_handle_return(nm->is_method_handle_return(pc));
-
-  if (TraceExceptions) {
-    ttyLocker ttyl;
-    ResourceMark rm;
-    tty->print_cr("Thread " PTR_FORMAT " continuing at PC " PTR_FORMAT " for exception thrown at PC " PTR_FORMAT,
-                  thread, continuation, pc);
-  }
-
-  return continuation;
-JRT_END
-
-// Enter this method from compiled code only if there is a Java exception handler
-// in the method handling the exception.
-// We are entering here from exception stub. We don't do a normal VM transition here.
-// We do it in a helper. This is so we can check to see if the nmethod we have just
-// searched for an exception handler has been deoptimized in the meantime.
-address GraalRuntime::exception_handler_for_pc(JavaThread* thread) {
-  oop exception = thread->exception_oop();
-  address pc = thread->exception_pc();
-  // Still in Java mode
-  DEBUG_ONLY(ResetNoHandleMark rnhm);
-  nmethod* nm = NULL;
-  address continuation = NULL;
-  {
-    // Enter VM mode by calling the helper
-    ResetNoHandleMark rnhm;
-    continuation = exception_handler_for_pc_helper(thread, exception, pc, nm);
-  }
-  // Back in JAVA, use no oops DON'T safepoint
-
-  // Now check to see if the nmethod we were called from is now deoptimized.
-  // If so we must return to the deopt blob and deoptimize the nmethod
-  if (nm != NULL && caller_is_deopted()) {
-    continuation = SharedRuntime::deopt_blob()->unpack_with_exception_in_tls();
-  }
-
-  assert(continuation != NULL, "no handler found");
-  return continuation;
-}
-
-JRT_ENTRY(void, GraalRuntime::graal_create_null_exception(JavaThread* thread))
-  thread->set_vm_result(Exceptions::new_exception(thread, vmSymbols::java_lang_NullPointerException(), NULL)());
-JRT_END
-
-JRT_ENTRY(void, GraalRuntime::graal_create_out_of_bounds_exception(JavaThread* thread, jint index))
-  char message[jintAsStringSize];
-  sprintf(message, "%d", index);
-  thread->set_vm_result(Exceptions::new_exception(thread, vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), message)());
-JRT_END
-
-JRT_ENTRY_NO_ASYNC(void, GraalRuntime::graal_monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock))
-  if (TraceGraal >= 3) {
-    char type[O_BUFLEN];
-    obj->klass()->name()->as_C_string(type, O_BUFLEN);
-    markOop mark = obj->mark();
-    tty->print_cr("%s: entered locking slow case with obj=" INTPTR_FORMAT ", type=%s, mark=" INTPTR_FORMAT ", lock=" INTPTR_FORMAT, thread->name(), obj, type, mark, lock);
-    tty->flush();
-  }
-#ifdef ASSERT
-  if (PrintBiasedLockingStatistics) {
-    Atomic::inc(BiasedLocking::slow_path_entry_count_addr());
-  }
-#endif
-  Handle h_obj(thread, obj);
-  assert(h_obj()->is_oop(), "must be NULL or an object");
-  if (UseBiasedLocking) {
-    // Retry fast entry if bias is revoked to avoid unnecessary inflation
-    ObjectSynchronizer::fast_enter(h_obj, lock, true, CHECK);
-  } else {
-    if (UseFastLocking) {
-      // When using fast locking, the compiled code has already tried the fast case
-      ObjectSynchronizer::slow_enter(h_obj, lock, THREAD);
-    } else {
-      ObjectSynchronizer::fast_enter(h_obj, lock, false, THREAD);
-    }
-  }
-  if (TraceGraal >= 3) {
-    tty->print_cr("%s: exiting locking slow with obj=" INTPTR_FORMAT, thread->name(), obj);
-  }
-JRT_END
-
-
-JRT_LEAF(void, GraalRuntime::graal_monitorexit(JavaThread* thread, oopDesc* obj, BasicLock* lock))
-  assert(thread == JavaThread::current(), "threads must correspond");
-  assert(thread->last_Java_sp(), "last_Java_sp must be set");
-  // monitorexit is non-blocking (leaf routine) => no exceptions can be thrown
-  EXCEPTION_MARK;
-
-#ifdef DEBUG
-  if (!obj->is_oop()) {
-    ResetNoHandleMark rhm;
-    nmethod* method = thread->last_frame().cb()->as_nmethod_or_null();
-    if (method != NULL) {
-      tty->print_cr("ERROR in monitorexit in method %s wrong obj " INTPTR_FORMAT, method->name(), obj);
-    }
-    thread->print_stack_on(tty);
-    assert(false, "invalid lock object pointer dected");
-  }
-#endif
-
-  if (UseFastLocking) {
-    // When using fast locking, the compiled code has already tried the fast case
-    ObjectSynchronizer::slow_exit(obj, lock, THREAD);
-  } else {
-    ObjectSynchronizer::fast_exit(obj, lock, THREAD);
-  }
-  if (TraceGraal >= 3) {
-    char type[O_BUFLEN];
-    obj->klass()->name()->as_C_string(type, O_BUFLEN);
-    tty->print_cr("%s: exited locking slow case with obj=" INTPTR_FORMAT ", type=%s, mark=" INTPTR_FORMAT ", lock=" INTPTR_FORMAT, thread->name(), obj, type, obj->mark(), lock);
-    tty->flush();
-  }
-JRT_END
-
-JRT_ENTRY(void, GraalRuntime::graal_log_object(JavaThread* thread, oop obj, jint flags))
-  bool string =  mask_bits_are_true(flags, LOG_OBJECT_STRING);
-  bool address = mask_bits_are_true(flags, LOG_OBJECT_ADDRESS);
-  bool newline = mask_bits_are_true(flags, LOG_OBJECT_NEWLINE);
-  if (!string) {
-    if (!address && obj->is_oop_or_null(true)) {
-      char buf[O_BUFLEN];
-      tty->print("%s@%p", obj->klass()->name()->as_C_string(buf, O_BUFLEN), obj);
-    } else {
-      tty->print("%p", obj);
-    }
-  } else {
-    ResourceMark rm;
-    assert(obj != NULL && java_lang_String::is_instance(obj), "must be");
-    char *buf = java_lang_String::as_utf8_string(obj);
-    tty->print(buf);
-  }
-  if (newline) {
-    tty->cr();
-  }
-JRT_END
-
-JRT_ENTRY(void, GraalRuntime::graal_vm_error(JavaThread* thread, oop where, oop format, jlong value))
-  ResourceMark rm;
-  assert(where == NULL || java_lang_String::is_instance(where), "must be");
-  const char *error_msg = where == NULL ? "<internal Graal error>" : java_lang_String::as_utf8_string(where);
-  char *detail_msg = NULL;
-  if (format != NULL) {
-    const char* buf = java_lang_String::as_utf8_string(format);
-    size_t detail_msg_length = strlen(buf) * 2;
-    detail_msg = (char *) NEW_RESOURCE_ARRAY(u_char, detail_msg_length);
-    jio_snprintf(detail_msg, detail_msg_length, buf, value);
-  }
-  report_vm_error(__FILE__, __LINE__, error_msg, detail_msg);
-JRT_END
-
-JRT_ENTRY(void, GraalRuntime::graal_log_printf(JavaThread* thread, oop format, jlong val))
-  ResourceMark rm;
-  assert(format != NULL && java_lang_String::is_instance(format), "must be");
-  char *buf = java_lang_String::as_utf8_string(format);
-  tty->print(buf, val);
-JRT_END
-
-JRT_ENTRY(void, GraalRuntime::graal_log_primitive(JavaThread* thread, jchar typeChar, jlong value, jboolean newline))
-  union {
-      jlong l;
-      jdouble d;
-      jfloat f;
-  } uu;
-  uu.l = value;
-  switch (typeChar) {
-    case 'z': tty->print(value == 0 ? "false" : "true"); break;
-    case 'b': tty->print("%d", (jbyte) value); break;
-    case 'c': tty->print("%c", (jchar) value); break;
-    case 's': tty->print("%d", (jshort) value); break;
-    case 'i': tty->print("%d", (jint) value); break;
-    case 'f': tty->print("%f", uu.f); break;
-    case 'j': tty->print(INT64_FORMAT, value); break;
-    case 'd': tty->print("%lf", uu.d); break;
-    default: assert(false, "unknown typeChar"); break;
-  }
-  if (newline) {
-    tty->cr();
-  }
-JRT_END
-
-JRT_ENTRY(jint, GraalRuntime::graal_identity_hash_code(JavaThread* thread, oop obj))
-  return (jint) obj->identity_hash();
-JRT_END
-
-JRT_ENTRY(jboolean, GraalRuntime::graal_thread_is_interrupted(JavaThread* thread, oop receiver, jboolean clear_interrupted))
-  // TEMP:
-  tty->print_cr("ThreadIsInterruptedSlowCase");
-
+/*
+ * 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.
+ */
+
+#include "precompiled.hpp"
+#include "runtime/interfaceSupport.hpp"
+#include "prims/jvm.h"
+#include "graal/graalRuntime.hpp"
+#include "graal/graalVMToCompiler.hpp"
+#include "asm/codeBuffer.hpp"
+#include "runtime/biasedLocking.hpp"
+
+// Implementation of GraalStubAssembler
+
+GraalStubAssembler::GraalStubAssembler(CodeBuffer* code, const char * name, int stub_id) : MacroAssembler(code) {
+  _name = name;
+  _must_gc_arguments = false;
+  _frame_size = no_frame_size;
+  _num_rt_args = 0;
+  _stub_id = stub_id;
+}
+
+
+void GraalStubAssembler::set_info(const char* name, bool must_gc_arguments) {
+  _name = name;
+  _must_gc_arguments = must_gc_arguments;
+}
+
+
+void GraalStubAssembler::set_frame_size(int size) {
+  if (_frame_size == no_frame_size) {
+    _frame_size = size;
+  }
+  assert(_frame_size == size, "can't change the frame size");
+}
+
+
+void GraalStubAssembler::set_num_rt_args(int args) {
+  if (_num_rt_args == 0) {
+    _num_rt_args = args;
+  }
+  assert(_num_rt_args == args, "can't change the number of args");
+}
+
+// Implementation of GraalRuntime
+
+CodeBlob* GraalRuntime::_blobs[GraalRuntime::number_of_ids];
+const char *GraalRuntime::_blob_names[] = {
+  GRAAL_STUBS(STUB_NAME, LAST_STUB_NAME)
+};
+
+// Simple helper to see if the caller of a runtime stub which
+// entered the VM has been deoptimized
+
+static bool caller_is_deopted() {
+  JavaThread* thread = JavaThread::current();
+  RegisterMap reg_map(thread, false);
+  frame runtime_frame = thread->last_frame();
+  frame caller_frame = runtime_frame.sender(&reg_map);
+  assert(caller_frame.is_compiled_frame(), "must be compiled");
+  return caller_frame.is_deoptimized_frame();
+}
+
+// Stress deoptimization
+static void deopt_caller() {
+  if ( !caller_is_deopted()) {
+    JavaThread* thread = JavaThread::current();
+    RegisterMap reg_map(thread, false);
+    frame runtime_frame = thread->last_frame();
+    frame caller_frame = runtime_frame.sender(&reg_map);
+    Deoptimization::deoptimize_frame(thread, caller_frame.id(), Deoptimization::Reason_constraint);
+    assert(caller_is_deopted(), "Must be deoptimized");
+  }
+}
+
+static bool setup_code_buffer(CodeBuffer* code) {
+  // Preinitialize the consts section to some large size:
+  int locs_buffer_size = 1 * (relocInfo::length_limit + sizeof(relocInfo));
+  char* locs_buffer = NEW_RESOURCE_ARRAY(char, locs_buffer_size);
+  code->insts()->initialize_shared_locs((relocInfo*)locs_buffer,
+                                        locs_buffer_size / sizeof(relocInfo));
+
+  // Global stubs have neither constants nor local stubs
+  code->initialize_consts_size(0);
+  code->initialize_stubs_size(0);
+
+  return true;
+}
+
+void GraalRuntime::generate_blob_for(BufferBlob* buffer_blob, StubID id) {
+  assert(0 <= id && id < number_of_ids, "illegal stub id");
+  ResourceMark rm;
+  // create code buffer for code storage
+  CodeBuffer code(buffer_blob);
+
+  setup_code_buffer(&code);
+
+  // create assembler for code generation
+  GraalStubAssembler* sasm = new GraalStubAssembler(&code, name_for(id), id);
+  // generate code for runtime stub
+  OopMapSet* oop_maps;
+  oop_maps = generate_code_for(id, sasm);
+  assert(oop_maps == NULL || sasm->frame_size() != no_frame_size,
+         "if stub has an oop map it must have a valid frame size");
+
+#ifdef ASSERT
+  // Make sure that stubs that need oopmaps have them
+  switch (id) {
+    // These stubs don't need to have an oopmap
+    case graal_slow_subtype_check_id:
+#if defined(SPARC) || defined(PPC)
+    case handle_exception_nofpu_id:  // Unused on sparc
+#endif
+#ifdef GRAAL
+    case graal_verify_oop_id:
+    case graal_unwind_exception_call_id:
+    case graal_OSR_migration_end_id:
+    case graal_arithmetic_frem_id:
+    case graal_arithmetic_drem_id:
+    case graal_set_deopt_info_id:
+#endif
+      break;
+
+    // All other stubs should have oopmaps
+    default:
+      assert(oop_maps != NULL, "must have an oopmap");
+  }
+#endif
+
+  // align so printing shows nop's instead of random code at the end (SimpleStubs are aligned)
+  sasm->align(BytesPerWord);
+  // make sure all code is in code buffer
+  sasm->flush();
+  // create blob - distinguish a few special cases
+  CodeBlob* blob = RuntimeStub::new_runtime_stub(name_for(id),
+                                                 &code,
+                                                 CodeOffsets::frame_never_safe,
+                                                 sasm->frame_size(),
+                                                 oop_maps,
+                                                 sasm->must_gc_arguments());
+  // install blob
+  assert(blob != NULL, "blob must exist");
+  _blobs[id] = blob;
+}
+
+
+void GraalRuntime::initialize(BufferBlob* blob) {
+  // generate stubs
+  for (int id = 0; id < number_of_ids; id++) generate_blob_for(blob, (StubID)id);
+  // printing
+#ifndef PRODUCT
+  if (PrintSimpleStubs) {
+    ResourceMark rm;
+    for (int id = 0; id < number_of_ids; id++) {
+      _blobs[id]->print();
+      if (_blobs[id]->oop_maps() != NULL) {
+        _blobs[id]->oop_maps()->print();
+      }
+    }
+  }
+#endif
+}
+
+
+CodeBlob* GraalRuntime::blob_for(StubID id) {
+  assert(0 <= id && id < number_of_ids, "illegal stub id");
+  return _blobs[id];
+}
+
+
+const char* GraalRuntime::name_for(StubID id) {
+  assert(0 <= id && id < number_of_ids, "illegal stub id");
+  return _blob_names[id];
+}
+
+const char* GraalRuntime::name_for_address(address entry) {
+  for (int id = 0; id < number_of_ids; id++) {
+    if (entry == entry_for((StubID)id)) return name_for((StubID)id);
+  }
+
+#define FUNCTION_CASE(a, f) \
+  if ((intptr_t)a == CAST_FROM_FN_PTR(intptr_t, f))  return #f
+
+  FUNCTION_CASE(entry, os::javaTimeMillis);
+  FUNCTION_CASE(entry, os::javaTimeNanos);
+  FUNCTION_CASE(entry, SharedRuntime::OSR_migration_end);
+  FUNCTION_CASE(entry, SharedRuntime::d2f);
+  FUNCTION_CASE(entry, SharedRuntime::d2i);
+  FUNCTION_CASE(entry, SharedRuntime::d2l);
+  FUNCTION_CASE(entry, SharedRuntime::dcos);
+  FUNCTION_CASE(entry, SharedRuntime::dexp);
+  FUNCTION_CASE(entry, SharedRuntime::dlog);
+  FUNCTION_CASE(entry, SharedRuntime::dlog10);
+  FUNCTION_CASE(entry, SharedRuntime::dpow);
+  FUNCTION_CASE(entry, SharedRuntime::drem);
+  FUNCTION_CASE(entry, SharedRuntime::dsin);
+  FUNCTION_CASE(entry, SharedRuntime::dtan);
+  FUNCTION_CASE(entry, SharedRuntime::f2i);
+  FUNCTION_CASE(entry, SharedRuntime::f2l);
+  FUNCTION_CASE(entry, SharedRuntime::frem);
+  FUNCTION_CASE(entry, SharedRuntime::l2d);
+  FUNCTION_CASE(entry, SharedRuntime::l2f);
+  FUNCTION_CASE(entry, SharedRuntime::ldiv);
+  FUNCTION_CASE(entry, SharedRuntime::lmul);
+  FUNCTION_CASE(entry, SharedRuntime::lrem);
+  FUNCTION_CASE(entry, SharedRuntime::lrem);
+  FUNCTION_CASE(entry, SharedRuntime::dtrace_method_entry);
+  FUNCTION_CASE(entry, SharedRuntime::dtrace_method_exit);
+#ifdef TRACE_HAVE_INTRINSICS
+  FUNCTION_CASE(entry, TRACE_TIME_METHOD);
+#endif
+
+  ShouldNotReachHere();
+  return NULL;
+
+#undef FUNCTION_CASE
+}
+
+
+JRT_ENTRY(void, GraalRuntime::new_instance(JavaThread* thread, Klass* klass))
+  assert(klass->is_klass(), "not a class");
+  instanceKlassHandle h(thread, klass);
+  h->check_valid_for_instantiation(true, CHECK);
+  // make sure klass is initialized
+  h->initialize(CHECK);
+  // allocate instance and return via TLS
+  oop obj = h->allocate_instance(CHECK);
+  thread->set_vm_result(obj);
+JRT_END
+
+JRT_ENTRY(void, GraalRuntime::new_array(JavaThread* thread, Klass* array_klass, jint length))
+  // Note: no handle for klass needed since they are not used
+  //       anymore after new_objArray() and no GC can happen before.
+  //       (This may have to change if this code changes!)
+  assert(array_klass->is_klass(), "not a class");
+  oop obj;
+  if (array_klass->oop_is_typeArray()) {
+    BasicType elt_type = TypeArrayKlass::cast(array_klass)->element_type();
+    obj = oopFactory::new_typeArray(elt_type, length, CHECK);
+  } else {
+    Klass* elem_klass = ObjArrayKlass::cast(array_klass)->element_klass();
+    obj = oopFactory::new_objArray(elem_klass, length, CHECK);
+  }
+  thread->set_vm_result(obj);
+  // This is pretty rare but this runtime patch is stressful to deoptimization
+  // if we deoptimize here so force a deopt to stress the path.
+  if (DeoptimizeALot) {
+    deopt_caller();
+  }
+JRT_END
+
+
+JRT_ENTRY(void, GraalRuntime::new_multi_array(JavaThread* thread, Klass* klass, int rank, jint* dims))
+  assert(klass->is_klass(), "not a class");
+  assert(rank >= 1, "rank must be nonzero");
+  oop obj = ArrayKlass::cast(klass)->multi_allocate(rank, dims, CHECK);
+  thread->set_vm_result(obj);
+JRT_END
+
+JRT_ENTRY(void, GraalRuntime::unimplemented_entry(JavaThread* thread, StubID id))
+  tty->print_cr("GraalRuntime::entry_for(%d) returned unimplemented entry point", id);
+JRT_END
+
+extern void vm_exit(int code);
+
+// Enter this method from compiled code handler below. This is where we transition
+// to VM mode. This is done as a helper routine so that the method called directly
+// from compiled code does not have to transition to VM. This allows the entry
+// method to see if the nmethod that we have just looked up a handler for has
+// been deoptimized while we were in the vm. This simplifies the assembly code
+// cpu directories.
+//
+// We are entering here from exception stub (via the entry method below)
+// If there is a compiled exception handler in this method, we will continue there;
+// otherwise we will unwind the stack and continue at the caller of top frame method
+// Note: we enter in Java using a special JRT wrapper. This wrapper allows us to
+// control the area where we can allow a safepoint. After we exit the safepoint area we can
+// check to see if the handler we are going to return is now in a nmethod that has
+// been deoptimized. If that is the case we return the deopt blob
+// unpack_with_exception entry instead. This makes life for the exception blob easier
+// because making that same check and diverting is painful from assembly language.
+JRT_ENTRY_NO_ASYNC(static address, exception_handler_for_pc_helper(JavaThread* thread, oopDesc* ex, address pc, nmethod*& nm))
+  // Reset method handle flag.
+  thread->set_is_method_handle_return(false);
+
+  Handle exception(thread, ex);
+  nm = CodeCache::find_nmethod(pc);
+  assert(nm != NULL, "this is not an nmethod");
+  // Adjust the pc as needed/
+  if (nm->is_deopt_pc(pc)) {
+    RegisterMap map(thread, false);
+    frame exception_frame = thread->last_frame().sender(&map);
+    // if the frame isn't deopted then pc must not correspond to the caller of last_frame
+    assert(exception_frame.is_deoptimized_frame(), "must be deopted");
+    pc = exception_frame.pc();
+  }
+#ifdef ASSERT
+  assert(exception.not_null(), "NULL exceptions should be handled by throw_exception");
+  assert(exception->is_oop(), "just checking");
+  // Check that exception is a subclass of Throwable, otherwise we have a VerifyError
+  if (!(exception->is_a(SystemDictionary::Throwable_klass()))) {
+    if (ExitVMOnVerifyError) vm_exit(-1);
+    ShouldNotReachHere();
+  }
+#endif
+
+  // Check the stack guard pages and reenable them if necessary and there is
+  // enough space on the stack to do so.  Use fast exceptions only if the guard
+  // pages are enabled.
+  bool guard_pages_enabled = thread->stack_yellow_zone_enabled();
+  if (!guard_pages_enabled) guard_pages_enabled = thread->reguard_stack();
+
+  if (JvmtiExport::can_post_on_exceptions()) {
+    // To ensure correct notification of exception catches and throws
+    // we have to deoptimize here.  If we attempted to notify the
+    // catches and throws during this exception lookup it's possible
+    // we could deoptimize on the way out of the VM and end back in
+    // the interpreter at the throw site.  This would result in double
+    // notifications since the interpreter would also notify about
+    // these same catches and throws as it unwound the frame.
+
+    RegisterMap reg_map(thread);
+    frame stub_frame = thread->last_frame();
+    frame caller_frame = stub_frame.sender(&reg_map);
+
+    // We don't really want to deoptimize the nmethod itself since we
+    // can actually continue in the exception handler ourselves but I
+    // don't see an easy way to have the desired effect.
+    Deoptimization::deoptimize_frame(thread, caller_frame.id(), Deoptimization::Reason_constraint);
+    assert(caller_is_deopted(), "Must be deoptimized");
+
+    return SharedRuntime::deopt_blob()->unpack_with_exception_in_tls();
+  }
+
+  // ExceptionCache is used only for exceptions at call sites and not for implicit exceptions
+  if (guard_pages_enabled) {
+    address fast_continuation = nm->handler_for_exception_and_pc(exception, pc);
+    if (fast_continuation != NULL) {
+      // Set flag if return address is a method handle call site.
+      thread->set_is_method_handle_return(nm->is_method_handle_return(pc));
+      return fast_continuation;
+    }
+  }
+
+  // If the stack guard pages are enabled, check whether there is a handler in
+  // the current method.  Otherwise (guard pages disabled), force an unwind and
+  // skip the exception cache update (i.e., just leave continuation==NULL).
+  address continuation = NULL;
+  if (guard_pages_enabled) {
+
+    // New exception handling mechanism can support inlined methods
+    // with exception handlers since the mappings are from PC to PC
+
+    // debugging support
+    // tracing
+    if (TraceExceptions) {
+      ttyLocker ttyl;
+      ResourceMark rm;
+      int offset = pc - nm->code_begin();
+      tty->print_cr("Exception <%s> (0x%x) thrown in compiled method <%s> at PC " PTR_FORMAT " [" PTR_FORMAT "+%d] for thread 0x%x",
+                    exception->print_value_string(), (address)exception(), nm->method()->print_value_string(), pc, nm->code_begin(), offset, thread);
+    }
+    // for AbortVMOnException flag
+    NOT_PRODUCT(Exceptions::debug_check_abort(exception));
+
+    // Clear out the exception oop and pc since looking up an
+    // exception handler can cause class loading, which might throw an
+    // exception and those fields are expected to be clear during
+    // normal bytecode execution.
+    thread->set_exception_oop(NULL);
+    thread->set_exception_pc(NULL);
+
+    continuation = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, false, false);
+    // If an exception was thrown during exception dispatch, the exception oop may have changed
+    thread->set_exception_oop(exception());
+    thread->set_exception_pc(pc);
+
+    // the exception cache is used only by non-implicit exceptions
+    if (continuation != NULL && !SharedRuntime::deopt_blob()->contains(continuation)) {
+      nm->add_handler_for_exception_and_pc(exception, pc, continuation);
+    }
+  }
+
+  thread->set_vm_result(exception());
+  // Set flag if return address is a method handle call site.
+  thread->set_is_method_handle_return(nm->is_method_handle_return(pc));
+
+  if (TraceExceptions) {
+    ttyLocker ttyl;
+    ResourceMark rm;
+    tty->print_cr("Thread " PTR_FORMAT " continuing at PC " PTR_FORMAT " for exception thrown at PC " PTR_FORMAT,
+                  thread, continuation, pc);
+  }
+
+  return continuation;
+JRT_END
+
+// Enter this method from compiled code only if there is a Java exception handler
+// in the method handling the exception.
+// We are entering here from exception stub. We don't do a normal VM transition here.
+// We do it in a helper. This is so we can check to see if the nmethod we have just
+// searched for an exception handler has been deoptimized in the meantime.
+address GraalRuntime::exception_handler_for_pc(JavaThread* thread) {
+  oop exception = thread->exception_oop();
+  address pc = thread->exception_pc();
+  // Still in Java mode
+  DEBUG_ONLY(ResetNoHandleMark rnhm);
+  nmethod* nm = NULL;
+  address continuation = NULL;
+  {
+    // Enter VM mode by calling the helper
+    ResetNoHandleMark rnhm;
+    continuation = exception_handler_for_pc_helper(thread, exception, pc, nm);
+  }
+  // Back in JAVA, use no oops DON'T safepoint
+
+  // Now check to see if the nmethod we were called from is now deoptimized.
+  // If so we must return to the deopt blob and deoptimize the nmethod
+  if (nm != NULL && caller_is_deopted()) {
+    continuation = SharedRuntime::deopt_blob()->unpack_with_exception_in_tls();
+  }
+
+  assert(continuation != NULL, "no handler found");
+  return continuation;
+}
+
+JRT_ENTRY(void, GraalRuntime::graal_create_null_exception(JavaThread* thread))
+  thread->set_vm_result(Exceptions::new_exception(thread, vmSymbols::java_lang_NullPointerException(), NULL)());
+JRT_END
+
+JRT_ENTRY(void, GraalRuntime::graal_create_out_of_bounds_exception(JavaThread* thread, jint index))
+  char message[jintAsStringSize];
+  sprintf(message, "%d", index);
+  thread->set_vm_result(Exceptions::new_exception(thread, vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), message)());
+JRT_END
+
+JRT_ENTRY_NO_ASYNC(void, GraalRuntime::graal_monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock))
+  if (TraceGraal >= 3) {
+    char type[O_BUFLEN];
+    obj->klass()->name()->as_C_string(type, O_BUFLEN);
+    markOop mark = obj->mark();
+    tty->print_cr("%s: entered locking slow case with obj=" INTPTR_FORMAT ", type=%s, mark=" INTPTR_FORMAT ", lock=" INTPTR_FORMAT, thread->name(), obj, type, mark, lock);
+    tty->flush();
+  }
+#ifdef ASSERT
+  if (PrintBiasedLockingStatistics) {
+    Atomic::inc(BiasedLocking::slow_path_entry_count_addr());
+  }
+#endif
+  Handle h_obj(thread, obj);
+  assert(h_obj()->is_oop(), "must be NULL or an object");
+  if (UseBiasedLocking) {
+    // Retry fast entry if bias is revoked to avoid unnecessary inflation
+    ObjectSynchronizer::fast_enter(h_obj, lock, true, CHECK);
+  } else {
+    if (UseFastLocking) {
+      // When using fast locking, the compiled code has already tried the fast case
+      ObjectSynchronizer::slow_enter(h_obj, lock, THREAD);
+    } else {
+      ObjectSynchronizer::fast_enter(h_obj, lock, false, THREAD);
+    }
+  }
+  if (TraceGraal >= 3) {
+    tty->print_cr("%s: exiting locking slow with obj=" INTPTR_FORMAT, thread->name(), obj);
+  }
+JRT_END
+
+
+JRT_LEAF(void, GraalRuntime::graal_monitorexit(JavaThread* thread, oopDesc* obj, BasicLock* lock))
+  assert(thread == JavaThread::current(), "threads must correspond");
+  assert(thread->last_Java_sp(), "last_Java_sp must be set");
+  // monitorexit is non-blocking (leaf routine) => no exceptions can be thrown
+  EXCEPTION_MARK;
+
+#ifdef DEBUG
+  if (!obj->is_oop()) {
+    ResetNoHandleMark rhm;
+    nmethod* method = thread->last_frame().cb()->as_nmethod_or_null();
+    if (method != NULL) {
+      tty->print_cr("ERROR in monitorexit in method %s wrong obj " INTPTR_FORMAT, method->name(), obj);
+    }
+    thread->print_stack_on(tty);
+    assert(false, "invalid lock object pointer dected");
+  }
+#endif
+
+  if (UseFastLocking) {
+    // When using fast locking, the compiled code has already tried the fast case
+    ObjectSynchronizer::slow_exit(obj, lock, THREAD);
+  } else {
+    ObjectSynchronizer::fast_exit(obj, lock, THREAD);
+  }
+  if (TraceGraal >= 3) {
+    char type[O_BUFLEN];
+    obj->klass()->name()->as_C_string(type, O_BUFLEN);
+    tty->print_cr("%s: exited locking slow case with obj=" INTPTR_FORMAT ", type=%s, mark=" INTPTR_FORMAT ", lock=" INTPTR_FORMAT, thread->name(), obj, type, obj->mark(), lock);
+    tty->flush();
+  }
+JRT_END
+
+JRT_ENTRY(void, GraalRuntime::graal_log_object(JavaThread* thread, oop obj, jint flags))
+  bool string =  mask_bits_are_true(flags, LOG_OBJECT_STRING);
+  bool address = mask_bits_are_true(flags, LOG_OBJECT_ADDRESS);
+  bool newline = mask_bits_are_true(flags, LOG_OBJECT_NEWLINE);
+  if (!string) {
+    if (!address && obj->is_oop_or_null(true)) {
+      char buf[O_BUFLEN];
+      tty->print("%s@%p", obj->klass()->name()->as_C_string(buf, O_BUFLEN), obj);
+    } else {
+      tty->print("%p", obj);
+    }
+  } else {
+    ResourceMark rm;
+    assert(obj != NULL && java_lang_String::is_instance(obj), "must be");
+    char *buf = java_lang_String::as_utf8_string(obj);
+    tty->print(buf);
+  }
+  if (newline) {
+    tty->cr();
+  }
+JRT_END
+
+JRT_ENTRY(void, GraalRuntime::graal_vm_error(JavaThread* thread, oop where, oop format, jlong value))
+  ResourceMark rm;
+  assert(where == NULL || java_lang_String::is_instance(where), "must be");
+  const char *error_msg = where == NULL ? "<internal Graal error>" : java_lang_String::as_utf8_string(where);
+  char *detail_msg = NULL;
+  if (format != NULL) {
+    const char* buf = java_lang_String::as_utf8_string(format);
+    size_t detail_msg_length = strlen(buf) * 2;
+    detail_msg = (char *) NEW_RESOURCE_ARRAY(u_char, detail_msg_length);
+    jio_snprintf(detail_msg, detail_msg_length, buf, value);
+  }
+  report_vm_error(__FILE__, __LINE__, error_msg, detail_msg);
+JRT_END
+
+JRT_ENTRY(void, GraalRuntime::graal_log_printf(JavaThread* thread, oop format, jlong val))
+  ResourceMark rm;
+  assert(format != NULL && java_lang_String::is_instance(format), "must be");
+  char *buf = java_lang_String::as_utf8_string(format);
+  tty->print(buf, val);
+JRT_END
+
+JRT_ENTRY(void, GraalRuntime::graal_log_primitive(JavaThread* thread, jchar typeChar, jlong value, jboolean newline))
+  union {
+      jlong l;
+      jdouble d;
+      jfloat f;
+  } uu;
+  uu.l = value;
+  switch (typeChar) {
+    case 'z': tty->print(value == 0 ? "false" : "true"); break;
+    case 'b': tty->print("%d", (jbyte) value); break;
+    case 'c': tty->print("%c", (jchar) value); break;
+    case 's': tty->print("%d", (jshort) value); break;
+    case 'i': tty->print("%d", (jint) value); break;
+    case 'f': tty->print("%f", uu.f); break;
+    case 'j': tty->print(INT64_FORMAT, value); break;
+    case 'd': tty->print("%lf", uu.d); break;
+    default: assert(false, "unknown typeChar"); break;
+  }
+  if (newline) {
+    tty->cr();
+  }
+JRT_END
+
+JRT_ENTRY(jint, GraalRuntime::graal_identity_hash_code(JavaThread* thread, oop obj))
+  return (jint) obj->identity_hash();
+JRT_END
+
+JRT_ENTRY(jboolean, GraalRuntime::graal_thread_is_interrupted(JavaThread* thread, oop receiver, jboolean clear_interrupted))
+  // TEMP:
+  tty->print_cr("ThreadIsInterruptedSlowCase");
+
   // Ensure that the C++ Thread and OSThread structures aren't freed before we operate
   Handle receiverHandle(thread, receiver);
   JRT_BLOCK
     MutexLockerEx ml(thread->threadObj() == receiver ? NULL : Threads_lock);
     JavaThread* receiverThread = java_lang_Thread::thread(receiverHandle());
     return (jint) Thread::is_interrupted(receiverThread, clear_interrupted != 0);
-  JRT_BLOCK_END
-JRT_END
-
-// JVM_InitializeGraalRuntime
-JVM_ENTRY(jobject, JVM_InitializeGraalRuntime(JNIEnv *env, jclass graalclass))
-  return VMToCompiler::graalRuntimePermObject();
-JVM_END
+  JRT_BLOCK_END
+JRT_END
+
+// JVM_InitializeGraalRuntime
+JVM_ENTRY(jobject, JVM_InitializeGraalRuntime(JNIEnv *env, jclass graalclass))
+  return VMToCompiler::graalRuntimePermObject();
+JVM_END
--- a/src/share/vm/graal/graalRuntime.hpp	Tue Dec 11 08:28:00 2012 +0100
+++ b/src/share/vm/graal/graalRuntime.hpp	Tue Dec 11 08:48:12 2012 +0100
@@ -80,8 +80,7 @@
 #define GRAAL_STUBS(stub, last_entry) \
   stub(graal_register_finalizer)      \
   stub(graal_new_instance)            \
-  stub(graal_new_type_array)          \
-  stub(graal_new_object_array)  \
+  stub(graal_new_array)               \
   stub(graal_new_multi_array)         \
   stub(graal_handle_exception_nofpu) /* optimized version that does not preserve fpu registers */ \
   stub(graal_slow_subtype_check)      \
@@ -130,12 +129,11 @@
                                        Register arg1 = noreg, Register arg2 = noreg, Register arg3 = noreg);
 
   // runtime entry points
-  static void new_instance    (JavaThread* thread, Klass* klass);
-  static void new_type_array  (JavaThread* thread, Klass* klass, jint length);
-  static void new_object_array(JavaThread* thread, Klass* klass, jint length);
-  static void new_multi_array (JavaThread* thread, Klass* klass, int rank, jint* dims);
+  static void new_instance(JavaThread* thread, Klass* klass);
+  static void new_array(JavaThread* thread, Klass* klass, jint length);
+  static void new_multi_array(JavaThread* thread, Klass* klass, int rank, jint* dims);
 
-  static void unimplemented_entry   (JavaThread* thread, StubID id);
+  static void unimplemented_entry(JavaThread* thread, StubID id);
 
   static address exception_handler_for_pc(JavaThread* thread);
 
--- a/src/share/vm/runtime/deoptimization.cpp	Tue Dec 11 08:28:00 2012 +0100
+++ b/src/share/vm/runtime/deoptimization.cpp	Tue Dec 11 08:48:12 2012 +0100
@@ -36,9 +36,7 @@
 #include "memory/resourceArea.hpp"
 #include "oops/method.hpp"
 #include "oops/oop.inline.hpp"
-#ifdef GRAAL
 #include "oops/fieldStreams.hpp"
-#endif
 #include "prims/jvmtiThreadState.hpp"
 #include "runtime/biasedLocking.hpp"
 #include "runtime/compilationPolicy.hpp"
@@ -809,77 +807,6 @@
   return true;
 }
 
-// This assumes that the fields are stored in ObjectValue in the same order
-// they are yielded by do_nonstatic_fields.
-class FieldReassigner: public FieldClosure {
-  frame* _fr;
-  RegisterMap* _reg_map;
-  ObjectValue* _sv;
-  InstanceKlass* _ik;
-  oop _obj;
-
-  int _i;
-public:
-  FieldReassigner(frame* fr, RegisterMap* reg_map, ObjectValue* sv, oop obj) :
-    _fr(fr), _reg_map(reg_map), _sv(sv), _obj(obj), _i(0) {}
-
-  int i() const { return _i; }
-
-
-  void do_field(fieldDescriptor* fd) {
-    intptr_t val;
-    StackValue* value =
-      StackValue::create_stack_value(_fr, _reg_map, _sv->field_at(i()));
-    int offset = fd->offset();
-    switch (fd->field_type()) {
-    case T_OBJECT: case T_ARRAY:
-      assert(value->type() == T_OBJECT, "Agreement.");
-      _obj->obj_field_put(offset, value->get_obj()());
-      break;
-
-    case T_LONG: case T_DOUBLE: {
-      assert(value->type() == T_INT, "Agreement.");
-      StackValue* low =
-        StackValue::create_stack_value(_fr, _reg_map, _sv->field_at(++_i));
-#ifdef _LP64
-      jlong res = (jlong)low->get_int();
-#else
-#ifdef SPARC
-      // For SPARC we have to swap high and low words.
-      jlong res = jlong_from((jint)low->get_int(), (jint)value->get_int());
-#else
-      jlong res = jlong_from((jint)value->get_int(), (jint)low->get_int());
-#endif //SPARC
-#endif
-      _obj->long_field_put(offset, res);
-      break;
-    }
-    // Have to cast to INT (32 bits) pointer to avoid little/big-endian problem.
-    case T_INT: case T_FLOAT: // 4 bytes.
-      assert(value->type() == T_INT, "Agreement.");
-      val = value->get_int();
-      _obj->int_field_put(offset, (jint)*((jint*)&val));
-      break;
-
-    case T_SHORT: case T_CHAR: // 2 bytes
-      assert(value->type() == T_INT, "Agreement.");
-      val = value->get_int();
-      _obj->short_field_put(offset, (jshort)*((jint*)&val));
-      break;
-
-    case T_BOOLEAN: case T_BYTE: // 1 byte
-      assert(value->type() == T_INT, "Agreement.");
-      val = value->get_int();
-      _obj->bool_field_put(offset, (jboolean)*((jint*)&val));
-      break;
-
-    default:
-      ShouldNotReachHere();
-    }
-    _i++;
-  }
-};
-
 // restore elements of an eliminated type array
 void Deoptimization::reassign_type_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, typeArrayOop obj, BasicType type) {
   int index = 0;
@@ -932,7 +859,6 @@
   }
 }
 
-
 // restore fields of an eliminated object array
 void Deoptimization::reassign_object_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, objArrayOop obj) {
   for (int i = 0; i < sv->field_size(); i++) {
@@ -942,7 +868,15 @@
   }
 }
 
-#ifdef GRAAL
+typedef struct {
+  int offset;
+  BasicType type;
+} ReassignedField;
+
+int compare(ReassignedField* left, ReassignedField* right) {
+  return left->offset - right->offset;
+}
+
 // Restore fields of an eliminated instance object using the same field order
 // returned by HotSpotResolvedObjectType.getInstanceFields(true)
 static int reassign_fields_by_klass(InstanceKlass* klass, frame* fr, RegisterMap* reg_map, ObjectValue* sv, int svIndex, oop obj) {
@@ -950,14 +884,21 @@
     svIndex = reassign_fields_by_klass(klass->superklass(), fr, reg_map, sv, svIndex, obj);
   }
 
+  GrowableArray<ReassignedField>* fields = new GrowableArray<ReassignedField>();
   for (AllFieldStream fs(klass); !fs.done(); fs.next()) {
-    if (fs.access_flags().is_static()) {
-      continue;
+    if (!fs.access_flags().is_static()) {
+      ReassignedField field;
+      field.offset = fs.offset();
+      field.type = FieldType::basic_type(fs.signature());
+      fields->append(field);
     }
+  }
+  fields->sort(compare);
+  for (int i = 0; i < fields->length(); i++) {
     intptr_t val;
     StackValue* value = StackValue::create_stack_value(fr, reg_map, sv->field_at(svIndex));
-    int offset = fs.offset();
-    BasicType type = FieldType::basic_type(fs.signature());
+    int offset = fields->at(i).offset;
+    BasicType type = fields->at(i).type;
     switch (type) {
       case T_OBJECT: case T_ARRAY:
         assert(value->type() == T_OBJECT, "Agreement.");
@@ -1006,8 +947,6 @@
   }
   return svIndex;
 }
-#endif
-
 
 // restore fields of all eliminated objects and arrays
 void Deoptimization::reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects) {
@@ -1022,12 +961,7 @@
 
     if (k->oop_is_instance()) {
       InstanceKlass* ik = InstanceKlass::cast(k());
-#ifndef GRAAL
-      FieldReassigner reassign(fr, reg_map, sv, obj());
-      ik->do_nonstatic_fields(&reassign);
-#else
       reassign_fields_by_klass(ik, fr, reg_map, sv, 0, obj());
-#endif
     } else if (k->oop_is_typeArray()) {
       TypeArrayKlass* ak = TypeArrayKlass::cast(k());
       reassign_type_array_elements(fr, reg_map, sv, (typeArrayOop) obj(), ak->element_type());