changeset 7151:ff6df8b7ce81

Merge.
author Doug Simon <doug.simon@oracle.com>
date Tue, 11 Dec 2012 08:29:25 +0100
parents 807bf592eb90 (current diff) 6a8b22829e36 (diff)
children e86ac899c5be
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RuntimeCall.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCall.java
diffstat 64 files changed, 1607 insertions(+), 710 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java	Tue Dec 11 08:29:25 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:27:01 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:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64DeoptimizationStub.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DirectCallOp.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Tue Dec 11 08:29:25 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.*;
@@ -73,30 +75,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, c.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, c.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, c.newTypeArrayStub,
-                /*        temps */ new Register[] {rcx, rdi, rsi},
+        addRuntimeCall(NEW_ARRAY_SLOW, c.newArrayStub,
+                /*        temps */ null,
                 /*          ret */ rax.asValue(Kind.Object),
                 /* arg0:    hub */ rdx.asValue(word),
                 /* arg1: length */ rbx.asValue(Kind.Int));
 
-        addRuntimeCall(NEW_INSTANCE, c.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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64IndirectCallOp.java	Tue Dec 11 08:29:25 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:27:01 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:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Tue Dec 11 08:29:25 2012 +0100
@@ -222,6 +222,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;
@@ -239,8 +262,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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Tue Dec 11 08:29:25 2012 +0100
@@ -47,7 +47,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.*;
@@ -56,6 +56,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.*;
@@ -82,7 +83,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.
@@ -260,10 +273,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) {
@@ -276,13 +302,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;
     }
@@ -411,7 +444,7 @@
     }
 
     @Override
-    public RegisterConfig lookupRegisterConfig(JavaMethod method) {
+    public RegisterConfig lookupRegisterConfig(ResolvedJavaMethod method) {
         return regConfig;
     }
 
@@ -617,6 +650,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) {
@@ -723,14 +760,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);
     }
@@ -826,4 +873,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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeArrayNode.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorEnterStubCall.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorExitStubCall.java	Tue Dec 11 08:29:25 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:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java	Tue Dec 11 08:29:25 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:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VerifyOopStubCall.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/OnStackReplacementPhase.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java	Tue Dec 11 08:29:25 2012 +0100
@@ -40,59 +40,68 @@
  */
 public class HotSpotSnippetUtils {
 
+    public static HotSpotVMConfig config() {
+        return HotSpotGraalRuntime.getInstance().getConfig();
+    }
+
     @Fold
-    static boolean verifyOops() {
-        return HotSpotGraalRuntime.getInstance().getConfig().verifyOops;
+    public static boolean verifyOops() {
+        return config().verifyOops;
     }
 
     @Fold
-    static int threadTlabTopOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().threadTlabTopOffset;
+    public static int threadTlabTopOffset() {
+        return config().threadTlabTopOffset;
     }
 
     @Fold
-    static int threadTlabEndOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().threadTlabEndOffset;
+    public static int threadTlabEndOffset() {
+        return config().threadTlabEndOffset;
     }
 
     @Fold
-    static Kind wordKind() {
+    public static Kind wordKind() {
         return HotSpotGraalRuntime.getInstance().getTarget().wordKind;
     }
 
     @Fold
-    static Register threadRegister() {
+    public static Register threadRegister() {
         return HotSpotGraalRuntime.getInstance().getRuntime().threadRegister();
     }
 
     @Fold
-    static Register stackPointerRegister() {
+    public static Register stackPointerRegister() {
         return HotSpotGraalRuntime.getInstance().getRuntime().stackPointerRegister();
     }
 
     @Fold
-    static int wordSize() {
+    public static int wordSize() {
         return HotSpotGraalRuntime.getInstance().getTarget().wordSize;
     }
 
     @Fold
-    static int pageSize() {
+    public static int pageSize() {
         return HotSpotGraalRuntime.getInstance().getTarget().pageSize;
     }
 
     @Fold
-    static int prototypeMarkWordOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().prototypeMarkWordOffset;
+    public static int prototypeMarkWordOffset() {
+        return config().prototypeMarkWordOffset;
     }
 
     @Fold
-    static int markOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().markOffset;
+    public static long arrayPrototypeMarkWord() {
+        return config().arrayPrototypeMarkWord;
     }
 
     @Fold
-    static int unlockedMask() {
-        return HotSpotGraalRuntime.getInstance().getConfig().unlockedMask;
+    public static int markOffset() {
+        return config().markOffset;
+    }
+
+    @Fold
+    public static int unlockedMask() {
+        return config().unlockedMask;
     }
 
     /**
@@ -105,13 +114,13 @@
      *
      */
     @Fold
-    static int biasedLockMaskInPlace() {
-        return HotSpotGraalRuntime.getInstance().getConfig().biasedLockMaskInPlace;
+    public static int biasedLockMaskInPlace() {
+        return config().biasedLockMaskInPlace;
     }
 
     @Fold
-    static int epochMaskInPlace() {
-        return HotSpotGraalRuntime.getInstance().getConfig().epochMaskInPlace;
+    public static int epochMaskInPlace() {
+        return config().epochMaskInPlace;
     }
 
     /**
@@ -124,88 +133,88 @@
      *
      */
     @Fold
-    static int biasedLockPattern() {
-        return HotSpotGraalRuntime.getInstance().getConfig().biasedLockPattern;
+    public static int biasedLockPattern() {
+        return config().biasedLockPattern;
     }
 
     @Fold
-    static int ageMaskInPlace() {
-        return HotSpotGraalRuntime.getInstance().getConfig().ageMaskInPlace;
+    public static int ageMaskInPlace() {
+        return config().ageMaskInPlace;
     }
 
     @Fold
-    static int hubOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().hubOffset;
+    public static int hubOffset() {
+        return config().hubOffset;
     }
 
     @Fold
-    static int metaspaceArrayLengthOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().metaspaceArrayLengthOffset;
+    public static int metaspaceArrayLengthOffset() {
+        return config().metaspaceArrayLengthOffset;
     }
 
     @Fold
-    static int metaspaceArrayBaseOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().metaspaceArrayBaseOffset;
+    public static int metaspaceArrayBaseOffset() {
+        return config().metaspaceArrayBaseOffset;
     }
 
     @Fold
-    static int arrayLengthOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().arrayLengthOffset;
+    public static int arrayLengthOffset() {
+        return config().arrayLengthOffset;
     }
 
     @Fold
-    static int arrayBaseOffset(Kind elementKind) {
+    public static int arrayBaseOffset(Kind elementKind) {
         return HotSpotRuntime.getArrayBaseOffset(elementKind);
     }
 
     @Fold
-    static int arrayIndexScale(Kind elementKind) {
+    public static int arrayIndexScale(Kind elementKind) {
         return HotSpotRuntime.getArrayIndexScale(elementKind);
     }
 
     @Fold
-    static int cardTableShift() {
-        return HotSpotGraalRuntime.getInstance().getConfig().cardtableShift;
+    public static int cardTableShift() {
+        return config().cardtableShift;
     }
 
     @Fold
-    static long cardTableStart() {
-        return HotSpotGraalRuntime.getInstance().getConfig().cardtableStartAddress;
+    public static long cardTableStart() {
+        return config().cardtableStartAddress;
     }
 
     @Fold
-    static int superCheckOffsetOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().superCheckOffsetOffset;
+    public static int superCheckOffsetOffset() {
+        return config().superCheckOffsetOffset;
     }
 
     @Fold
-    static int secondarySuperCacheOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().secondarySuperCacheOffset;
+    public static int secondarySuperCacheOffset() {
+        return config().secondarySuperCacheOffset;
     }
 
     @Fold
-    static int secondarySupersOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().secondarySupersOffset;
+    public static int secondarySupersOffset() {
+        return config().secondarySupersOffset;
     }
 
     @Fold
-    static int lockDisplacedMarkOffset() {
-        return HotSpotGraalRuntime.getInstance().getConfig().basicLockDisplacedHeaderOffset;
+    public static int lockDisplacedMarkOffset() {
+        return config().basicLockDisplacedHeaderOffset;
     }
 
     @Fold
-    static boolean useBiasedLocking() {
-        return HotSpotGraalRuntime.getInstance().getConfig().useBiasedLocking;
+    public static boolean useBiasedLocking() {
+        return config().useBiasedLocking;
     }
 
     /**
      * Loads the hub from a object, null checking it first.
      */
-    static Word loadHub(Object object) {
+    public static Word loadHub(Object object) {
         return loadHubIntrinsic(object, wordKind());
     }
 
-    static Object verifyOop(Object object) {
+    public static Object verifyOop(Object object) {
         if (verifyOops()) {
             VerifyOopStubCall.call(object);
         }
@@ -215,27 +224,27 @@
     /**
      * Gets the value of the stack pointer register as a Word.
      */
-    static Word stackPointer() {
+    public static Word stackPointer() {
         return HotSpotSnippetUtils.registerAsWord(stackPointerRegister());
     }
 
     /**
      * Gets the value of the thread register as a Word.
      */
-    static Word thread() {
+    public static Word thread() {
         return HotSpotSnippetUtils.registerAsWord(threadRegister());
     }
 
-    static int loadIntFromWord(Word address, int offset) {
+    public 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) {
+    public static Word loadWordFromWord(Word address, int offset) {
         return loadWordFromWordIntrinsic(address, 0, offset, wordKind());
     }
 
-    static Word loadWordFromObject(Object object, int offset) {
+    public static Word loadWordFromObject(Object object, int offset) {
         return loadWordFromObjectIntrinsic(object, 0, offset, wordKind());
     }
 
@@ -251,6 +260,149 @@
     @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;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/MonitorSnippets.java	Tue Dec 11 08:27:01 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/MonitorSnippets.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/SystemSnippets.java	Tue Dec 11 08:29:25 2012 +0100
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.hotspot.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;
--- /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:29:25 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:29:25 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:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java	Tue Dec 11 08:29:25 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) {
@@ -79,10 +79,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;
@@ -93,7 +93,7 @@
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            indirectCall(tasm, masm, asRegister(targetAddress), targetMethod, state);
+            indirectCall(tasm, masm, asRegister(targetAddress), callTarget, state);
         }
 
         @Override
@@ -103,10 +103,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
@@ -122,7 +122,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();
     }
@@ -135,11 +135,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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnwindNode.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/RuntimeCallNode.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Tue Dec 11 08:29:25 2012 +0100
@@ -987,7 +987,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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/WordTest.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Log.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/MathSnippetsX86.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java	Tue Dec 11 08:29:25 2012 +0100
@@ -130,7 +130,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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/src/cpu/x86/vm/graalRuntime_x86.cpp	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/src/share/vm/compiler/abstractCompiler.hpp	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Tue Dec 11 08:29:25 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:27:01 2012 +0100
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Tue Dec 11 08:29:25 2012 +0100
@@ -514,15 +514,6 @@
   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");
@@ -585,120 +576,139 @@
   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))
+
+#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(env, config, "windowsOs", false);
+  set_boolean("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, "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, "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_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("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("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(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_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(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("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("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();
@@ -707,14 +717,14 @@
     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);
+      set_long("cardtableStartAddress", base);
+      set_int("cardtableShift", CardTableModRefBS::card_shift);
       break;
     }
     case BarrierSet::ModRef:
     case BarrierSet::Other:
-      set_long(env, config, "cardtableStartAddress", 0);
-      set_int(env, config, "cardtableShift", 0);
+      set_long("cardtableStartAddress", 0);
+      set_int("cardtableShift", 0);
       // No post barriers
       break;
 #ifndef SERIALGC
@@ -726,7 +736,14 @@
       break;
     }
 
-  set_int(env, config, "arrayClassElementOffset", in_bytes(ObjArrayKlass::element_klass_offset()));
+  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))
@@ -932,7 +949,6 @@
   {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)},
--- a/src/share/vm/graal/graalRuntime.cpp	Tue Dec 11 08:27:01 2012 +0100
+++ b/src/share/vm/graal/graalRuntime.cpp	Tue Dec 11 08:29:25 2012 +0100
@@ -244,31 +244,19 @@
   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))
+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");
-  Klass* elem_klass = ObjArrayKlass::cast(array_klass)->element_klass();
-  objArrayOop obj = oopFactory::new_objArray(elem_klass, length, CHECK);
+  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.
--- a/src/share/vm/graal/graalRuntime.hpp	Tue Dec 11 08:27:01 2012 +0100
+++ b/src/share/vm/graal/graalRuntime.hpp	Tue Dec 11 08:29:25 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)      \
@@ -128,12 +127,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:27:01 2012 +0100
+++ b/src/share/vm/runtime/deoptimization.cpp	Tue Dec 11 08:29:25 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());