changeset 7143:445193cc2a7d

added support for writing stubs in Java and wrote the TLAB fast refill stub
author Doug Simon <doug.simon@oracle.com>
date Fri, 07 Dec 2012 15:12:05 +0100
parents 283fe237085b
children ae69cd8c08a9
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DirectCallOp.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64IndirectCallOp.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCall.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceSlowStubCall.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/MonitorSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java src/share/vm/graal/graalCompilerToVM.cpp
diffstat 22 files changed, 909 insertions(+), 216 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java	Fri Dec 07 11:14:12 2012 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java	Fri Dec 07 15:12:05 2012 +0100
@@ -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,7 +81,7 @@
     /**
      * 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.
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Fri Dec 07 11:14:12 2012 +0100
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Fri Dec 07 15:12:05 2012 +0100
@@ -571,11 +571,11 @@
     }
 
     @Override
-    protected void emitCall(Object targetMethod, Value result, Value[] arguments, Value[] temps, Value targetAddress, LIRFrameState info) {
+    protected void emitCall(RuntimeCall 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	Fri Dec 07 11:14:12 2012 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Fri Dec 07 15:12:05 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 callTarget, Value result, Value[] arguments, Value[] temps, Value targetAddress, LIRFrameState info);
+    protected abstract void emitCall(RuntimeCall callTarget, Value result, Value[] arguments, Value[] temps, Value targetAddress, LIRFrameState info);
 
     private static Value toStackKind(Value value) {
         if (value.getKind().getStackKind() != value.getKind()) {
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DirectCallOp.java	Fri Dec 07 11:14:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DirectCallOp.java	Fri Dec 07 15:12:05 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	Fri Dec 07 11:14:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Fri Dec 07 15:12:05 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	Fri Dec 07 11:14:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Fri Dec 07 15:12:05 2012 +0100
@@ -28,6 +28,7 @@
 import static com.oracle.graal.hotspot.nodes.MonitorEnterStubCall.*;
 import static com.oracle.graal.hotspot.nodes.MonitorExitStubCall.*;
 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.*;
@@ -96,7 +97,12 @@
                 /* 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	Fri Dec 07 11:14:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64IndirectCallOp.java	Fri Dec 07 15:12:05 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	Fri Dec 07 11:14:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCall.java	Fri Dec 07 15:12:05 2012 +0100
@@ -23,7 +23,9 @@
 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.
@@ -38,7 +40,12 @@
     /**
      * The entry point address of the stub.
      */
-    public final long address;
+    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.
@@ -56,7 +63,7 @@
 
     @Override
     public String toString() {
-        return descriptor + "@0x" + Long.toHexString(address) + ":" + cc;
+        return (stub == null ? descriptor.toString() : MetaUtil.format("%h.%n", stub.getMethod())) + "@0x" + Long.toHexString(address) + ":" + cc;
     }
 
     public CallingConvention getCallingConvention() {
@@ -70,4 +77,19 @@
     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	Fri Dec 07 11:14:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Fri Dec 07 15:12:05 2012 +0100
@@ -222,6 +222,21 @@
     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;
 
     // methodData information
     public int methodDataOopDataOffset;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java	Fri Dec 07 11:14:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java	Fri Dec 07 15:12:05 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	Fri Dec 07 11:14:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Fri Dec 07 15:12:05 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;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Fri Dec 07 11:14:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Fri Dec 07 15:12:05 2012 +0100
@@ -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,18 @@
     private NewObjectSnippets.Templates newObjectSnippets;
     private MonitorSnippets.Templates monitorSnippets;
 
-    private final Map<Descriptor, RuntimeCall> runtimeCalls = new HashMap<>();
+    private NewInstanceStub newInstanceStub;
+
+    private final Map<Descriptor, HotSpotRuntimeCall> 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.
@@ -264,6 +276,19 @@
         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 HotSpotRuntimeCall registerStub(Descriptor descriptor, Stub stub) {
+        HotSpotRuntimeCall 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) {
@@ -275,14 +300,17 @@
         installer.install(InstanceOfSnippets.class);
         installer.install(NewObjectSnippets.class);
         installer.install(MonitorSnippets.class);
+        installer.install(NewInstanceStub.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());
+        newInstanceStub.install(graalRuntime.getCompiler());
     }
 
-
     public HotSpotGraalRuntime getGraalRuntime() {
         return graalRuntime;
     }
@@ -411,7 +439,7 @@
     }
 
     @Override
-    public RegisterConfig lookupRegisterConfig(JavaMethod method) {
+    public RegisterConfig lookupRegisterConfig(ResolvedJavaMethod method) {
         return regConfig;
     }
 
@@ -727,14 +755,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 HotSpotRuntimeCall) {
+            return ((HotSpotRuntimeCall) 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 HotSpotRuntimeCall lookupRuntimeCall(Descriptor descriptor) {
         assert runtimeCalls.containsKey(descriptor) : descriptor;
         return runtimeCalls.get(descriptor);
     }
@@ -830,4 +868,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;
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceSlowStubCall.java	Fri Dec 07 15:12:05 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.RuntimeCall.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) {
+        RuntimeCall 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	Fri Dec 07 11:14:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java	Fri Dec 07 15:12:05 2012 +0100
@@ -30,13 +30,14 @@
 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);
+        RuntimeCall 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/VMErrorNode.java	Fri Dec 07 11:14:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java	Fri Dec 07 15:12:05 2012 +0100
@@ -27,6 +27,7 @@
 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());
         }
 
+        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);
+        }
+
         RuntimeCall stub = gen.getRuntime().lookupRuntimeCall(VMErrorNode.VM_ERROR);
-        gen.emitCall(stub, stub.getCallingConvention(), false, Constant.forObject(where), gen.operand(format), gen.operand(value));
+        gen.emitCall(stub, stub.getCallingConvention(), false, whereArg, formatArg, gen.operand(value));
     }
 
     @NodeIntrinsic
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java	Fri Dec 07 11:14:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java	Fri Dec 07 15:12:05 2012 +0100
@@ -40,59 +40,63 @@
  */
 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 int markOffset() {
+        return config().markOffset;
     }
 
     @Fold
-    static int unlockedMask() {
-        return HotSpotGraalRuntime.getInstance().getConfig().unlockedMask;
+    public static int unlockedMask() {
+        return config().unlockedMask;
     }
 
     /**
@@ -105,13 +109,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 +128,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 +219,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());
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/MonitorSnippets.java	Fri Dec 07 11:14:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/MonitorSnippets.java	Fri Dec 07 15:12:05 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	Fri Dec 07 11:14:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java	Fri Dec 07 15:12:05 2012 +0100
@@ -225,10 +225,11 @@
     /**
      * 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 size, 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()) {
                 storeWord(memory, 0, offset, Word.zero());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Fri Dec 07 15:12:05 2012 +0100
@@ -0,0 +1,316 @@
+/*
+ * 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.Fold;
+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) {
+        logf("newInstance: hub=%p\n", hub.toLong());
+        if (inlineContiguousAllocationSupported()) {
+            if (loadIntFromWord(hub, klassStateOffset()) == klassStateFullyInitialized()) {
+                int sizeInBytes = loadIntFromWord(hub, klassInstanceSizeOffset());
+                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
+     */
+    private 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
+     */
+    private 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);
+        }
+    }
+
+    @Fold
+    static int log2WordSize() {
+        return CodeUtil.log2(wordSize());
+    }
+
+    @Fold
+    static int klassStateOffset() {
+        return config().klassStateOffset;
+    }
+
+    @Fold
+    static int klassInstanceSizeOffset() {
+        return config().klassInstanceSizeOffset;
+    }
+
+    @Fold
+    static long heapTopAddress() {
+        return config().heapTopAddress;
+    }
+
+    @Fold
+    static long heapEndAddress() {
+        return config().heapEndAddress;
+    }
+
+    @Fold
+    static int threadTlabStartOffset() {
+        return config().threadTlabStartOffset;
+    }
+
+    @Fold
+    static long tlabIntArrayMarkWord() {
+        return config().tlabIntArrayMarkWord;
+    }
+
+    @Fold
+    static boolean inlineContiguousAllocationSupported() {
+        return config().inlineContiguousAllocationSupported;
+    }
+
+    @Fold
+    static int tlabAlignmentReserveInHeapWords() {
+        return config().tlabAlignmentReserve;
+    }
+
+    @Fold
+    static int threadTlabSizeOffset() {
+        return config().threadTlabSizeOffset;
+    }
+
+    @Fold
+    static int threadAllocatedBytesOffset() {
+        return config().threadAllocatedBytesOffset;
+    }
+
+    @Fold
+    static int klassStateFullyInitialized() {
+        return config().klassStateFullyInitialized;
+    }
+
+    @Fold
+    static int tlabRefillWasteLimitOffset() {
+        return config().tlabRefillWasteLimitOffset;
+    }
+
+    @Fold
+    static int tlabNumberOfRefillsOffset() {
+        return config().tlabNumberOfRefillsOffset;
+    }
+
+    @Fold
+    static int tlabFastRefillWasteOffset() {
+        return config().tlabFastRefillWasteOffset;
+    }
+
+    @Fold
+    static int tlabSlowAllocationsOffset() {
+        return config().tlabSlowAllocationsOffset;
+    }
+
+    @Fold
+    static int tlabRefillWasteIncrement() {
+        return config().tlabRefillWasteIncrement;
+    }
+
+    @Fold
+    static boolean tlabStats() {
+        return config().tlabStats;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Fri Dec 07 15:12:05 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.RuntimeCall.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 HotSpotRuntimeCall 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 HotSpotRuntimeCall 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.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java	Fri Dec 07 11:14:12 2012 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java	Fri Dec 07 15:12:05 2012 +0100
@@ -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 RuntimeCall) {
+            long maxOffset = ((RuntimeCall) 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/src/share/vm/graal/graalCompilerToVM.cpp	Fri Dec 07 11:14:12 2012 +0100
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Fri Dec 07 15:12:05 2012 +0100
@@ -585,120 +585,131 @@
   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("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("newTypeArrayStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_new_type_array_id)));
+  set_long("newObjectArrayStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_new_object_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 +718,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 +737,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))