changeset 7221:2ae3e26b7e9a

Merge.
author Christian Haeubl <haeubl@ssw.jku.at>
date Tue, 11 Dec 2012 08:48:12 +0100
parents fcae6d960acd (diff) 6a8b22829e36 (current diff)
children 720925633b3a
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RuntimeCall.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCall.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/SystemSnippets.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java src/cpu/x86/vm/graalRuntime_x86.cpp src/share/vm/graal/graalCompilerToVM.cpp src/share/vm/graal/graalRuntime.cpp src/share/vm/graal/graalRuntime.hpp
diffstat 37 files changed, 3109 insertions(+), 2082 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Assumptions.java	Mon Dec 10 22:19:07 2012 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Assumptions.java	Tue Dec 11 08:48:12 2012 +0100
@@ -64,7 +64,7 @@
         public ConcreteSubtype(ResolvedJavaType context, ResolvedJavaType subtype) {
             this.context = context;
             this.subtype = subtype;
-            assert !subtype.isInterface();
+            assert !subtype.isInterface() : subtype.toString() + " : " + context.toString();
         }
 
         @Override
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64AsmOptions.java	Mon Dec 10 22:19:07 2012 +0100
+++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64AsmOptions.java	Tue Dec 11 08:48:12 2012 +0100
@@ -24,7 +24,7 @@
 
 public class AMD64AsmOptions {
     public static int     Atomics                       = 0;
-    public static boolean UseNormalNop                  = true;
+    public static boolean UseNormalNop                  = false;
     public static boolean UseAddressNop                 = true;
     public static boolean UseIncDec                     = false;
     public static boolean UseXmmLoadAndClearUpper       = true;
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Mon Dec 10 22:19:07 2012 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Tue Dec 11 08:48:12 2012 +0100
@@ -34,6 +34,8 @@
 import static com.oracle.graal.hotspot.nodes.NewMultiArrayStubCall.*;
 import static com.oracle.graal.hotspot.nodes.VMErrorNode.*;
 import static com.oracle.graal.hotspot.nodes.VerifyOopStubCall.*;
+import static com.oracle.graal.hotspot.nodes.IdentityHashCodeStubCall.*;
+import static com.oracle.graal.hotspot.nodes.ThreadIsInterruptedStubCall.*;
 import static com.oracle.graal.lir.amd64.AMD64Call.*;
 
 import com.oracle.graal.api.code.*;
@@ -46,7 +48,6 @@
     public AMD64HotSpotRuntime(HotSpotVMConfig config, HotSpotGraalRuntime graalRuntime) {
         super(config, graalRuntime);
 
-        HotSpotVMConfig c = config;
         Kind word = graalRuntime.getTarget().wordKind;
 
         addRuntimeCall(DEOPTIMIZE, config.deoptimizeStub,
@@ -80,7 +81,7 @@
                 /* arg0: object */ arg(0, Kind.Object),
                 /* arg1:   lock */ arg(1, word));
 
-        addRuntimeCall(MONITOREXIT, c.monitorExitStub,
+        addRuntimeCall(MONITOREXIT, config.monitorExitStub,
                 /*        temps */ null,
                 /*          ret */ ret(Kind.Void),
                 /* arg0: object */ arg(0, Kind.Object),
@@ -92,7 +93,7 @@
                 /* arg0:    hub */ rdx.asValue(word),
                 /* arg1: length */ rbx.asValue(Kind.Int));
 
-        addRuntimeCall(NEW_ARRAY_SLOW, c.newArrayStub,
+        addRuntimeCall(NEW_ARRAY_SLOW, config.newArrayStub,
                 /*        temps */ null,
                 /*          ret */ rax.asValue(Kind.Object),
                 /* arg0:    hub */ rdx.asValue(word),
@@ -108,25 +109,35 @@
                 /*          ret */ rax.asValue(Kind.Object),
                 /* arg0:    hub */ rdx.asValue(word));
 
-        addRuntimeCall(NEW_MULTI_ARRAY, c.newMultiArrayStub,
+        addRuntimeCall(NEW_MULTI_ARRAY, config.newMultiArrayStub,
                 /*        temps */ null,
                 /*          ret */ rax.asValue(Kind.Object),
                 /* arg0:    hub */ rax.asValue(word),
                 /* arg1:   rank */ rbx.asValue(Kind.Int),
                 /* arg2:   dims */ rcx.asValue(word));
 
-        addRuntimeCall(VERIFY_OOP, c.verifyOopStub,
+        addRuntimeCall(VERIFY_OOP, config.verifyOopStub,
                 /*        temps */ null,
                 /*          ret */ ret(Kind.Void),
                 /* arg0: object */ r13.asValue(Kind.Object));
 
-        addRuntimeCall(VM_ERROR, c.vmErrorStub,
+        addRuntimeCall(VM_ERROR, config.vmErrorStub,
                 /*        temps */ null,
                 /*          ret */ ret(Kind.Void),
                 /* arg0:  where */ arg(0, Kind.Object),
                 /* arg1: format */ arg(1, Kind.Object),
                 /* arg2:  value */ arg(2, Kind.Long));
 
+        addRuntimeCall(IDENTITY_HASHCODE, config.identityHashCodeStub,
+                /*        temps */ null,
+                /*          ret */ rax.asValue(Kind.Int),
+                /* arg0:    obj */ rdx.asValue(Kind.Object));
+
+        addRuntimeCall(THREAD_IS_INTERRUPTED, config.threadIsInterruptedStub,
+                /*        temps */ null,
+                /*          ret */ rax.asValue(Kind.Boolean),
+                /* arg0: thread */ rdx.asValue(Kind.Object),
+      /* arg1: clearInterrupted */ rdx.asValue(Kind.Boolean));
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Mon Dec 10 22:19:07 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Tue Dec 11 08:48:12 2012 +0100
@@ -36,6 +36,7 @@
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.*;
+import com.oracle.graal.snippets.*;
 
 /**
  * Singleton class holding the instance of the {@link GraalRuntime}.
@@ -240,15 +241,12 @@
     @SuppressWarnings("unchecked")
     @Override
     public <T> T getCapability(Class<T> clazz) {
-        if (clazz == GraalCodeCacheProvider.class || clazz == MetaAccessProvider.class) {
+        if (clazz == GraalCodeCacheProvider.class || clazz == MetaAccessProvider.class || clazz == SnippetProvider.class) {
             return (T) getRuntime();
         }
         if (clazz == GraalCompiler.class) {
             return (T) getCompiler();
         }
-        if (clazz == MetaAccessProvider.class) {
-            return (T) getRuntime();
-        }
         if (clazz == RuntimeInterpreterInterface.class) {
             return (T) getRuntimeInterpreterInterface();
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Mon Dec 10 22:19:07 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Tue Dec 11 08:48:12 2012 +0100
@@ -130,6 +130,16 @@
     public int threadObjectOffset;
 
     /**
+     * The value of JavaThread::osthread_offset().
+     */
+    public int osThreadOffset;
+
+    /**
+     * The value of OSThread::interrupted_offset().
+     */
+    public int osThreadInterruptedOffset;
+
+    /**
      * The value of markOopDesc::unlocked_value.
      */
     public int unlockedMask;
@@ -155,6 +165,16 @@
     public int biasedLockPattern;
 
     /**
+     * Identity hash code value when uninitialized.
+     */
+    public int uninitializedIdentityHashCodeValue;
+
+    /**
+     * Mark word right shift to get identity hash code.
+     */
+    public int identityHashCodeShift;
+
+    /**
      * Offset of _access_flags in metaspace Method object.
      */
     public int methodAccessFlagsOffset;
@@ -204,6 +224,26 @@
     public int klassAccessFlagsOffset;
 
     /**
+     * The offset of the _layout_helper field in a Klass.
+     */
+    public int klassLayoutHelperOffset;
+
+    /**
+     * Bit pattern in the klass layout helper that can be used to identify arrays.
+     */
+    public int arrayKlassLayoutHelperIdentifier;
+
+    /**
+     * The offset of the _componentMirror field in an ArrayKlass.
+     */
+    public int arrayKlassComponentMirrorOffset;
+
+    /**
+     * The offset of the _super field in a Klass.
+     */
+    public int klassSuperKlassOffset;
+
+    /**
      * The offset of the injected klass field in a {@link Class}.
      */
     public int klassOffset;
@@ -288,6 +328,8 @@
     public long logPrimitiveStub;
     public long logObjectStub;
     public long logPrintfStub;
+    public long threadIsInterruptedStub;
+    public long identityHashCodeStub;
 
     public void check() {
         assert vmPageSize >= 16;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Mon Dec 10 22:19:07 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Tue Dec 11 08:48:12 2012 +0100
@@ -574,7 +574,7 @@
         if (onStackReplacement) {
             phasePlan.addPhase(PhasePosition.AFTER_PARSING, new OnStackReplacementPhase());
         }
-        if (GraalOptions.Intrinsify) {
+        if (GraalOptions.Intrinsify && GraalOptions.IntrinsifyArrayCopy) {
             phasePlan.addPhase(PhasePosition.HIGH_LEVEL, intrinsifyArrayCopy);
         }
         return phasePlan;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Mon Dec 10 22:19:07 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Tue Dec 11 08:48:12 2012 +0100
@@ -175,7 +175,7 @@
                 }
                 type = (HotSpotResolvedObjectType) fromMetaspaceKlass(subklass);
             }
-            if (unsafeReadWord(type.metaspaceKlass + config.subklassOffset) != 0) {
+            if (type.isInterface() || unsafeReadWord(type.metaspaceKlass + config.subklassOffset) != 0) {
                 return null;
             }
             return type;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Mon Dec 10 22:19:07 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Tue Dec 11 08:48:12 2012 +0100
@@ -29,7 +29,6 @@
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.hotspot.snippets.SystemSnippets.*;
 import static com.oracle.graal.java.GraphBuilderPhase.*;
-import static com.oracle.graal.nodes.StructuredGraph.*;
 import static com.oracle.graal.nodes.UnwindNode.*;
 import static com.oracle.graal.nodes.java.RegisterFinalizerNode.*;
 import static com.oracle.graal.snippets.Log.*;
@@ -71,7 +70,7 @@
 /**
  * HotSpot implementation of {@link GraalCodeCacheProvider}.
  */
-public abstract class HotSpotRuntime implements GraalCodeCacheProvider {
+public abstract class HotSpotRuntime implements GraalCodeCacheProvider, SnippetProvider {
     public final HotSpotVMConfig config;
 
     protected final RegisterConfig regConfig;
@@ -293,9 +292,24 @@
     protected abstract RegisterConfig createRegisterConfig(boolean globalStubConfig);
 
     public void installSnippets(SnippetInstaller installer, Assumptions assumptions) {
-        installer.install(SystemSnippets.class);
-        installer.install(UnsafeSnippets.class);
-        installer.install(ArrayCopySnippets.class);
+        if (GraalOptions.IntrinsifyObjectMethods) {
+            installer.install(ObjectSnippets.class);
+        }
+        if (GraalOptions.IntrinsifySystemMethods) {
+            installer.install(SystemSnippets.class);
+        }
+        if (GraalOptions.IntrinsifyThreadMethods) {
+            installer.install(ThreadSnippets.class);
+        }
+        if (GraalOptions.IntrinsifyUnsafeMethods) {
+            installer.install(UnsafeSnippets.class);
+        }
+        if (GraalOptions.IntrinsifyClassMethods) {
+            installer.install(ClassSnippets.class);
+        }
+        if (GraalOptions.IntrinsifyArrayCopy) {
+            installer.install(ArrayCopySnippets.class);
+        }
 
         installer.install(CheckCastSnippets.class);
         installer.install(InstanceOfSnippets.class);
@@ -701,54 +715,6 @@
 
     @Override
     public StructuredGraph intrinsicGraph(ResolvedJavaMethod caller, int bci, ResolvedJavaMethod method, List<? extends Node> parameters) {
-        ResolvedJavaType holder = method.getDeclaringClass();
-        String fullName = method.getName() + ((HotSpotSignature) method.getSignature()).asString();
-        Kind wordKind = graalRuntime.getTarget().wordKind;
-        if (MetaUtil.isJavaLangObject(holder)) {
-            if (fullName.equals("getClass()Ljava/lang/Class;")) {
-                ValueNode obj = (ValueNode) parameters.get(0);
-                ObjectStamp stamp = (ObjectStamp) obj.stamp();
-                if (stamp.nonNull() && stamp.isExactType()) {
-                    HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) stamp.type();
-                    StructuredGraph graph = new StructuredGraph();
-                    ValueNode result = ConstantNode.forObject(type.mirror(), this, graph);
-                    ReturnNode ret = graph.add(new ReturnNode(result));
-                    graph.start().setNext(ret);
-                    return graph;
-                }
-                StructuredGraph graph = new StructuredGraph();
-                LocalNode receiver = graph.unique(new LocalNode(0, StampFactory.objectNonNull()));
-                LoadHubNode hub = graph.add(new LoadHubNode(receiver, wordKind));
-                Stamp resultStamp = StampFactory.declaredNonNull(lookupJavaType(Class.class));
-                FloatingReadNode result = graph.unique(new FloatingReadNode(hub, LocationNode.create(LocationNode.FINAL_LOCATION, Kind.Object, config.classMirrorOffset, graph), null, resultStamp));
-                ReturnNode ret = graph.add(new ReturnNode(result));
-                graph.start().setNext(hub);
-                hub.setNext(ret);
-                return graph;
-            }
-        } else if (holder.equals(lookupJavaType(Class.class))) {
-            if (fullName.equals("getModifiers()I")) {
-                StructuredGraph graph = new StructuredGraph();
-                LocalNode receiver = graph.unique(new LocalNode(0, StampFactory.objectNonNull()));
-                SafeReadNode klass = safeRead(graph, wordKind, receiver, config.klassOffset, StampFactory.forKind(wordKind), INVALID_GRAPH_ID);
-                graph.start().setNext(klass);
-                LocationNode location = LocationNode.create(LocationNode.FINAL_LOCATION, Kind.Int, config.klassModifierFlagsOffset, graph);
-                FloatingReadNode readModifiers = graph.unique(new FloatingReadNode(klass, location, null, StampFactory.intValue()));
-                CompareNode isZero = CompareNode.createCompareNode(Condition.EQ, klass, ConstantNode.defaultForKind(wordKind, graph));
-                GuardNode guard = graph.unique(new GuardNode(isZero, graph.start(), NullCheckException, InvalidateReprofile, true, INVALID_GRAPH_ID));
-                readModifiers.dependencies().add(guard);
-                ReturnNode ret = graph.add(new ReturnNode(readModifiers));
-                klass.setNext(ret);
-                return graph;
-            }
-        } else if (holder.equals(lookupJavaType(Thread.class))) {
-            if (fullName.equals("currentThread()Ljava/lang/Thread;")) {
-                StructuredGraph graph = new StructuredGraph();
-                ReturnNode ret = graph.add(new ReturnNode(graph.unique(new CurrentThread(config.threadObjectOffset, this))));
-                graph.start().setNext(ret);
-                return graph;
-            }
-        }
         return null;
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentThread.java	Mon Dec 10 22:19:07 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentThread.java	Tue Dec 11 08:48:12 2012 +0100
@@ -33,8 +33,8 @@
 
     private int threadObjectOffset;
 
-    public CurrentThread(int threadObjectOffset, CodeCacheProvider runtime) {
-        super(StampFactory.declaredNonNull(runtime.lookupJavaType(Thread.class)));
+    public CurrentThread(int threadObjectOffset) {
+        super(StampFactory.declaredNonNull(HotSpotGraalRuntime.getInstance().getRuntime().lookupJavaType(Thread.class)));
         this.threadObjectOffset = threadObjectOffset;
     }
 
@@ -45,5 +45,5 @@
     }
 
     @NodeIntrinsic
-    public static native Object get(@ConstantNodeParameter int threadObjectOffset);
+    public static native Thread get(@ConstantNodeParameter int threadObjectOffset);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/IdentityHashCodeStubCall.java	Tue Dec 11 08:48:12 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * 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 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.lir.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * Node implementing a call to HotSpot's {@code graal_identityhashcode} stub.
+ */
+public class IdentityHashCodeStubCall extends FixedWithNextNode implements LIRGenLowerable {
+    @Input private final ValueNode object;
+    public static final Descriptor IDENTITY_HASHCODE = new Descriptor("identity_hashcode", false, Kind.Int, Kind.Object);
+
+    public IdentityHashCodeStubCall(ValueNode object) {
+        super(StampFactory.forKind(Kind.Int));
+        this.object = object;
+    }
+
+    @Override
+    public void generate(LIRGenerator gen) {
+        RuntimeCall stub = gen.getRuntime().lookupRuntimeCall(IdentityHashCodeStubCall.IDENTITY_HASHCODE);
+        Variable result = gen.emitCall(stub, stub.getCallingConvention(), true, gen.operand(object));
+        gen.setResult(this, result);
+    }
+
+    @NodeIntrinsic
+    public static native int call(Object object);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ThreadIsInterruptedStubCall.java	Tue Dec 11 08:48:12 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * 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 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.lir.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * Node implementing a call to HotSpot's ThreadIsInterrupted stub.
+ */
+public class ThreadIsInterruptedStubCall extends FixedWithNextNode implements LIRGenLowerable {
+    @Input private final ValueNode thread;
+    public static final Descriptor THREAD_IS_INTERRUPTED = new Descriptor("thread_is_interrupted", false, Kind.Boolean, Kind.Object, Kind.Boolean);
+
+    public ThreadIsInterruptedStubCall(ValueNode thread) {
+        super(StampFactory.forKind(Kind.Boolean));
+        this.thread = thread;
+    }
+
+    @Override
+    public void generate(LIRGenerator gen) {
+        RuntimeCall stub = gen.getRuntime().lookupRuntimeCall(ThreadIsInterruptedStubCall.THREAD_IS_INTERRUPTED);
+        Variable result = gen.emitCall(stub, stub.getCallingConvention(), true, gen.operand(thread));
+        gen.setResult(this, result);
+    }
+
+    @NodeIntrinsic
+    public static native boolean call(Thread thread);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ClassSnippets.java	Tue Dec 11 08:48:12 2012 +0100
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.snippets;
+
+import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
+
+import java.lang.reflect.*;
+
+import com.oracle.graal.snippets.*;
+
+@ClassSubstitution(java.lang.Class.class)
+public class ClassSnippets implements SnippetsInterface {
+    @InstanceMethodSubstitution
+    public static int getModifiers(final Class<?> thisObj) {
+        Word klass = loadWordFromObject(thisObj, klassOffset());
+        if (klass == Word.zero()) {
+            return Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC;
+        } else {
+            return loadIntFromWord(klass, klassModifierFlagsOffset());
+        }
+    }
+
+    @InstanceMethodSubstitution
+    public static boolean isInterface(final Class<?> thisObj) {
+        Word klass = loadWordFromObject(thisObj, klassOffset());
+        if (klass == Word.zero()) {
+            return false;
+        } else {
+            int accessFlags = loadIntFromWord(klass, klassAccessFlagsOffset());
+            return (accessFlags & Modifier.INTERFACE) != 0;
+        }
+    }
+
+    @InstanceMethodSubstitution
+    public static boolean isArray(final Class<?> thisObj) {
+        Word klass = loadWordFromObject(thisObj, klassOffset());
+        if (klass == Word.zero()) {
+            return false;
+        } else {
+            int layoutHelper = loadIntFromWord(klass, klassLayoutHelperOffset());
+            return (layoutHelper & arrayKlassLayoutHelperIdentifier()) != 0;
+        }
+    }
+
+    @InstanceMethodSubstitution
+    public static boolean isPrimitive(final Class<?> thisObj) {
+        Word klass = loadWordFromObject(thisObj, klassOffset());
+        return klass == Word.zero();
+    }
+
+    @InstanceMethodSubstitution
+    public static Class<?> getSuperclass(final Class<?> thisObj) {
+        Word klass = loadWordFromObject(thisObj, klassOffset());
+        if (klass != Word.zero()) {
+            int accessFlags = loadIntFromWord(klass, klassAccessFlagsOffset());
+            if ((accessFlags & Modifier.INTERFACE) == 0) {
+                int layoutHelper = loadIntFromWord(klass, klassLayoutHelperOffset());
+                if ((layoutHelper & arrayKlassLayoutHelperIdentifier()) != 0) {
+                    return Object.class;
+                } else {
+                    Word superKlass = loadWordFromWord(klass, klassSuperKlassOffset());
+                    if (superKlass == Word.zero()) {
+                        return null;
+                    } else {
+                        return (Class<?>) loadObjectFromWord(superKlass, classMirrorOffset());
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    @InstanceMethodSubstitution
+    public static Class<?> getComponentType(final Class<?> thisObj) {
+        Word klass = loadWordFromObject(thisObj, klassOffset());
+        if (klass != Word.zero()) {
+            int layoutHelper = loadIntFromWord(klass, klassLayoutHelperOffset());
+            if ((layoutHelper & arrayKlassLayoutHelperIdentifier()) != 0) {
+                return (Class<?>) loadObjectFromWord(klass, arrayKlassComponentMirrorOffset());
+            }
+        }
+        return null;
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java	Mon Dec 10 22:19:07 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java	Tue Dec 11 08:48:12 2012 +0100
@@ -1,416 +1,485 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.snippets;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.Node.ConstantNodeParameter;
-import com.oracle.graal.graph.Node.NodeIntrinsic;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.hotspot.nodes.*;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.snippets.Snippet.Fold;
-import com.oracle.graal.snippets.*;
-
-//JaCoCo Exclude
-
-/**
- * A collection of methods used in HotSpot snippets.
- */
-public class HotSpotSnippetUtils {
-
-    public static HotSpotVMConfig config() {
-        return HotSpotGraalRuntime.getInstance().getConfig();
-    }
-
-    @Fold
-    public static boolean verifyOops() {
-        return config().verifyOops;
-    }
-
-    @Fold
-    public static int threadTlabTopOffset() {
-        return config().threadTlabTopOffset;
-    }
-
-    @Fold
-    public static int threadTlabEndOffset() {
-        return config().threadTlabEndOffset;
-    }
-
-    @Fold
-    public static Kind wordKind() {
-        return HotSpotGraalRuntime.getInstance().getTarget().wordKind;
-    }
-
-    @Fold
-    public static Register threadRegister() {
-        return HotSpotGraalRuntime.getInstance().getRuntime().threadRegister();
-    }
-
-    @Fold
-    public static Register stackPointerRegister() {
-        return HotSpotGraalRuntime.getInstance().getRuntime().stackPointerRegister();
-    }
-
-    @Fold
-    public static int wordSize() {
-        return HotSpotGraalRuntime.getInstance().getTarget().wordSize;
-    }
-
-    @Fold
-    public static int pageSize() {
-        return HotSpotGraalRuntime.getInstance().getTarget().pageSize;
-    }
-
-    @Fold
-    public static int prototypeMarkWordOffset() {
-        return config().prototypeMarkWordOffset;
-    }
-
-    @Fold
-    public static long arrayPrototypeMarkWord() {
-        return config().arrayPrototypeMarkWord;
-    }
-
-    @Fold
-    public static int markOffset() {
-        return config().markOffset;
-    }
-
-    @Fold
-    public static int unlockedMask() {
-        return config().unlockedMask;
-    }
-
-    /**
-     * Mask for a biasable, locked or unlocked mark word.
-     * <pre>
-     * +----------------------------------+-+-+
-     * |                                 1|1|1|
-     * +----------------------------------+-+-+
-     * </pre>
-     *
-     */
-    @Fold
-    public static int biasedLockMaskInPlace() {
-        return config().biasedLockMaskInPlace;
-    }
-
-    @Fold
-    public static int epochMaskInPlace() {
-        return config().epochMaskInPlace;
-    }
-
-    /**
-     * Pattern for a biasable, unlocked mark word.
-     * <pre>
-     * +----------------------------------+-+-+
-     * |                                 1|0|1|
-     * +----------------------------------+-+-+
-     * </pre>
-     *
-     */
-    @Fold
-    public static int biasedLockPattern() {
-        return config().biasedLockPattern;
-    }
-
-    @Fold
-    public static int ageMaskInPlace() {
-        return config().ageMaskInPlace;
-    }
-
-    @Fold
-    public static int hubOffset() {
-        return config().hubOffset;
-    }
-
-    @Fold
-    public static int metaspaceArrayLengthOffset() {
-        return config().metaspaceArrayLengthOffset;
-    }
-
-    @Fold
-    public static int metaspaceArrayBaseOffset() {
-        return config().metaspaceArrayBaseOffset;
-    }
-
-    @Fold
-    public static int arrayLengthOffset() {
-        return config().arrayLengthOffset;
-    }
-
-    @Fold
-    public static int arrayBaseOffset(Kind elementKind) {
-        return HotSpotRuntime.getArrayBaseOffset(elementKind);
-    }
-
-    @Fold
-    public static int arrayIndexScale(Kind elementKind) {
-        return HotSpotRuntime.getArrayIndexScale(elementKind);
-    }
-
-    @Fold
-    public static int cardTableShift() {
-        return config().cardtableShift;
-    }
-
-    @Fold
-    public static long cardTableStart() {
-        return config().cardtableStartAddress;
-    }
-
-    @Fold
-    public static int superCheckOffsetOffset() {
-        return config().superCheckOffsetOffset;
-    }
-
-    @Fold
-    public static int secondarySuperCacheOffset() {
-        return config().secondarySuperCacheOffset;
-    }
-
-    @Fold
-    public static int secondarySupersOffset() {
-        return config().secondarySupersOffset;
-    }
-
-    @Fold
-    public static int lockDisplacedMarkOffset() {
-        return config().basicLockDisplacedHeaderOffset;
-    }
-
-    @Fold
-    public static boolean useBiasedLocking() {
-        return config().useBiasedLocking;
-    }
-
-    /**
-     * Loads the hub from a object, null checking it first.
-     */
-    public static Word loadHub(Object object) {
-        return loadHubIntrinsic(object, wordKind());
-    }
-
-    public static Object verifyOop(Object object) {
-        if (verifyOops()) {
-            VerifyOopStubCall.call(object);
-        }
-        return object;
-    }
-
-    /**
-     * Gets the value of the stack pointer register as a Word.
-     */
-    public static Word stackPointer() {
-        return HotSpotSnippetUtils.registerAsWord(stackPointerRegister());
-    }
-
-    /**
-     * Gets the value of the thread register as a Word.
-     */
-    public static Word thread() {
-        return HotSpotSnippetUtils.registerAsWord(threadRegister());
-    }
-
-    public static int loadIntFromWord(Word address, int offset) {
-        Integer value = UnsafeLoadNode.load(address, 0, offset, Kind.Int);
-        return value;
-    }
-
-    public static Word loadWordFromWord(Word address, int offset) {
-        return loadWordFromWordIntrinsic(address, 0, offset, wordKind());
-    }
-
-    public static Word loadWordFromObject(Object object, int offset) {
-        return loadWordFromObjectIntrinsic(object, 0, offset, wordKind());
-    }
-
-    @NodeIntrinsic(value = RegisterNode.class, setStampFromReturnType = true)
-    public static native Word registerAsWord(@ConstantNodeParameter Register register);
-
-    @NodeIntrinsic(value = UnsafeLoadNode.class, setStampFromReturnType = true)
-    private static native Word loadWordFromObjectIntrinsic(Object object, @ConstantNodeParameter int displacement, long offset, @ConstantNodeParameter Kind wordKind);
-
-    @NodeIntrinsic(value = UnsafeLoadNode.class, setStampFromReturnType = true)
-    private static native Word loadWordFromWordIntrinsic(Word address, @ConstantNodeParameter int displacement, long offset, @ConstantNodeParameter Kind wordKind);
-
-    @NodeIntrinsic(value = LoadHubNode.class, setStampFromReturnType = true)
-    static native Word loadHubIntrinsic(Object object, @ConstantNodeParameter Kind word);
-
-    @Fold
-    public
-    static int log2WordSize() {
-        return CodeUtil.log2(wordSize());
-    }
-
-    @Fold
-    public
-    static int klassStateOffset() {
-        return config().klassStateOffset;
-    }
-
-    @Fold
-    public
-    static int klassInstanceSizeOffset() {
-        return config().klassInstanceSizeOffset;
-    }
-
-    @Fold
-    public
-    static long heapTopAddress() {
-        return config().heapTopAddress;
-    }
-
-    @Fold
-    public
-    static long heapEndAddress() {
-        return config().heapEndAddress;
-    }
-
-    @Fold
-    public
-    static int threadTlabStartOffset() {
-        return config().threadTlabStartOffset;
-    }
-
-    @Fold
-    public
-    static long tlabIntArrayMarkWord() {
-        return config().tlabIntArrayMarkWord;
-    }
-
-    @Fold
-    public
-    static boolean inlineContiguousAllocationSupported() {
-        return config().inlineContiguousAllocationSupported;
-    }
-
-    @Fold
-    public
-    static int tlabAlignmentReserveInHeapWords() {
-        return config().tlabAlignmentReserve;
-    }
-
-    @Fold
-    public
-    static int threadTlabSizeOffset() {
-        return config().threadTlabSizeOffset;
-    }
-
-    @Fold
-    public
-    static int threadAllocatedBytesOffset() {
-        return config().threadAllocatedBytesOffset;
-    }
-
-    @Fold
-    public
-    static int klassStateFullyInitialized() {
-        return config().klassStateFullyInitialized;
-    }
-
-    @Fold
-    public
-    static int tlabRefillWasteLimitOffset() {
-        return config().tlabRefillWasteLimitOffset;
-    }
-
-    @Fold
-    public
-    static int tlabNumberOfRefillsOffset() {
-        return config().tlabNumberOfRefillsOffset;
-    }
-
-    @Fold
-    public
-    static int tlabFastRefillWasteOffset() {
-        return config().tlabFastRefillWasteOffset;
-    }
-
-    @Fold
-    public
-    static int tlabSlowAllocationsOffset() {
-        return config().tlabSlowAllocationsOffset;
-    }
-
-    @Fold
-    public
-    static int tlabRefillWasteIncrement() {
-        return config().tlabRefillWasteIncrement;
-    }
-
-    @Fold
-    public
-    static boolean tlabStats() {
-        return config().tlabStats;
-    }
-
-    @Fold
-    public static int layoutHelperOffset() {
-        return config().layoutHelperOffset;
-    }
-
-    @Fold
-    public static int layoutHelperHeaderSizeShift() {
-        return config().layoutHelperHeaderSizeShift;
-    }
-
-    @Fold
-    public static int layoutHelperHeaderSizeMask() {
-        return config().layoutHelperHeaderSizeMask;
-    }
-
-    @Fold
-    public static int layoutHelperLog2ElementSizeShift() {
-        return config().layoutHelperLog2ElementSizeShift;
-    }
-
-    @Fold
-    public static int layoutHelperLog2ElementSizeMask() {
-        return config().layoutHelperLog2ElementSizeMask;
-    }
-
-    @Fold
-    public static int layoutHelperElementTypeShift() {
-        return config().layoutHelperElementTypeShift;
-    }
-
-    @Fold
-    public static int layoutHelperElementTypeMask() {
-        return config().layoutHelperElementTypeMask;
-    }
-
-    static {
-        assert arrayIndexScale(Kind.Byte) == 1;
-        assert arrayIndexScale(Kind.Boolean) == 1;
-        assert arrayIndexScale(Kind.Char) == 2;
-        assert arrayIndexScale(Kind.Short) == 2;
-        assert arrayIndexScale(Kind.Int) == 4;
-        assert arrayIndexScale(Kind.Long) == 8;
-        assert arrayIndexScale(Kind.Float) == 4;
-        assert arrayIndexScale(Kind.Double) == 8;
-    }
-}
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.snippets;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.Node.ConstantNodeParameter;
+import com.oracle.graal.graph.Node.NodeIntrinsic;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.snippets.Snippet.Fold;
+import com.oracle.graal.snippets.*;
+
+//JaCoCo Exclude
+
+/**
+ * A collection of methods used in HotSpot snippets.
+ */
+public class HotSpotSnippetUtils {
+
+    public static HotSpotVMConfig config() {
+        return HotSpotGraalRuntime.getInstance().getConfig();
+    }
+
+    @Fold
+    public static boolean verifyOops() {
+        return config().verifyOops;
+    }
+
+    @Fold
+    public static int threadTlabTopOffset() {
+        return config().threadTlabTopOffset;
+    }
+
+    @Fold
+    public static int threadTlabEndOffset() {
+        return config().threadTlabEndOffset;
+    }
+
+    @Fold
+    public static int threadObjectOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().threadObjectOffset;
+    }
+
+    @Fold
+    public static int osThreadOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().osThreadOffset;
+    }
+
+    @Fold
+    public static int osThreadInterruptedOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().osThreadInterruptedOffset;
+    }
+
+    @Fold
+    public static Kind wordKind() {
+        return HotSpotGraalRuntime.getInstance().getTarget().wordKind;
+    }
+
+    @Fold
+    public static Register threadRegister() {
+        return HotSpotGraalRuntime.getInstance().getRuntime().threadRegister();
+    }
+
+    @Fold
+    public static Register stackPointerRegister() {
+        return HotSpotGraalRuntime.getInstance().getRuntime().stackPointerRegister();
+    }
+
+    @Fold
+    public static int wordSize() {
+        return HotSpotGraalRuntime.getInstance().getTarget().wordSize;
+    }
+
+    @Fold
+    public static int pageSize() {
+        return HotSpotGraalRuntime.getInstance().getTarget().pageSize;
+    }
+
+    @Fold
+    public static int prototypeMarkWordOffset() {
+        return config().prototypeMarkWordOffset;
+    }
+
+    @Fold
+    public static long arrayPrototypeMarkWord() {
+        return config().arrayPrototypeMarkWord;
+    }
+    
+    @Fold
+    public static int klassOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().klassOffset;
+    }
+   
+    @Fold
+    public static int klassModifierFlagsOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().klassModifierFlagsOffset;
+    }
+
+    @Fold
+    public static int klassAccessFlagsOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().klassAccessFlagsOffset;
+    }
+
+    @Fold
+    public static int klassLayoutHelperOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().klassLayoutHelperOffset;
+    }
+
+    @Fold
+    public static int arrayKlassLayoutHelperIdentifier() {
+        return HotSpotGraalRuntime.getInstance().getConfig().arrayKlassLayoutHelperIdentifier;
+    }
+
+    @Fold
+    public static int arrayKlassComponentMirrorOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().arrayKlassComponentMirrorOffset;
+    }
+
+    @Fold
+    public static int klassSuperKlassOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().klassSuperKlassOffset;
+    }
+
+    @Fold
+    public static int classMirrorOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().classMirrorOffset;
+    }
+
+    @Fold
+    public static int markOffset() {
+        return config().markOffset;   
+    }
+
+    @Fold
+    public static int unlockedMask() {
+        return config().unlockedMask;
+    }
+
+    /**
+     * Mask for a biasable, locked or unlocked mark word.
+     * <pre>
+     * +----------------------------------+-+-+
+     * |                                 1|1|1|
+     * +----------------------------------+-+-+
+     * </pre>
+     *
+     */
+    @Fold
+    public static int biasedLockMaskInPlace() {
+        return config().biasedLockMaskInPlace;
+    }
+
+    @Fold
+    public static int epochMaskInPlace() {
+        return config().epochMaskInPlace;
+    }
+
+    /**
+     * Pattern for a biasable, unlocked mark word.
+     * <pre>
+     * +----------------------------------+-+-+
+     * |                                 1|0|1|
+     * +----------------------------------+-+-+
+     * </pre>
+     *
+     */
+    @Fold
+    public static int biasedLockPattern() {
+        return config().biasedLockPattern;
+    }
+
+    @Fold
+    public static int ageMaskInPlace() {
+        return config().ageMaskInPlace;
+    }
+
+    @Fold
+    public static int hubOffset() {
+        return config().hubOffset;
+    }
+
+    @Fold
+    public static int metaspaceArrayLengthOffset() {
+        return config().metaspaceArrayLengthOffset;
+    }
+
+    @Fold
+    public static int metaspaceArrayBaseOffset() {
+        return config().metaspaceArrayBaseOffset;
+    }
+
+    @Fold
+    public static int arrayLengthOffset() {
+        return config().arrayLengthOffset;
+    }
+
+    @Fold
+    public static int arrayBaseOffset(Kind elementKind) {
+        return HotSpotRuntime.getArrayBaseOffset(elementKind);
+    }
+
+    @Fold
+    public static int arrayIndexScale(Kind elementKind) {
+        return HotSpotRuntime.getArrayIndexScale(elementKind);
+    }
+
+    @Fold
+    public static int cardTableShift() {
+        return config().cardtableShift;
+    }
+
+    @Fold
+    public static long cardTableStart() {
+        return config().cardtableStartAddress;
+    }
+
+    @Fold
+    public static int superCheckOffsetOffset() {
+        return config().superCheckOffsetOffset;
+    }
+
+    @Fold
+    public static int secondarySuperCacheOffset() {
+        return config().secondarySuperCacheOffset;
+    }
+
+    @Fold
+    public static int secondarySupersOffset() {
+        return config().secondarySupersOffset;
+    }
+
+    @Fold
+    public static int lockDisplacedMarkOffset() {
+        return config().basicLockDisplacedHeaderOffset;
+    }
+
+    @Fold
+    public static boolean useBiasedLocking() {
+        return config().useBiasedLocking;
+    }
+
+    @Fold
+    static int uninitializedIdentityHashCodeValue() {
+        return HotSpotGraalRuntime.getInstance().getConfig().uninitializedIdentityHashCodeValue;
+    }
+
+    @Fold
+    static int identityHashCodeShift() {
+        return HotSpotGraalRuntime.getInstance().getConfig().identityHashCodeShift;
+    }
+
+    /**
+     * Loads the hub from a object, null checking it first.
+     */
+    public static Word loadHub(Object object) {
+        return loadHubIntrinsic(object, wordKind());
+    }
+
+    public static Object verifyOop(Object object) {
+        if (verifyOops()) {
+            VerifyOopStubCall.call(object);
+        }
+        return object;
+    }
+
+    /**
+     * Gets the value of the stack pointer register as a Word.
+     */
+    public static Word stackPointer() {
+        return HotSpotSnippetUtils.registerAsWord(stackPointerRegister());
+    }
+
+    /**
+     * Gets the value of the thread register as a Word.
+     */
+    public static Word thread() {
+        return HotSpotSnippetUtils.registerAsWord(threadRegister());
+    }
+
+    public static int loadIntFromWord(Word address, int offset) {
+        Integer value = UnsafeLoadNode.load(address, 0, offset, Kind.Int);
+        return value;
+    }
+
+    public static Word loadWordFromWord(Word address, int offset) {
+        return loadWordFromWordIntrinsic(address, 0, offset, wordKind());
+    }
+
+    static Object loadObjectFromWord(Word address, int offset) {
+        return UnsafeLoadNode.load(address, 0, offset, Kind.Object);
+    }
+
+    public static Word loadWordFromObject(Object object, int offset) {
+        return loadWordFromObjectIntrinsic(object, 0, offset, wordKind());
+    }
+
+    @NodeIntrinsic(value = RegisterNode.class, setStampFromReturnType = true)
+    public static native Word registerAsWord(@ConstantNodeParameter Register register);
+
+    @NodeIntrinsic(value = UnsafeLoadNode.class, setStampFromReturnType = true)
+    private static native Word loadWordFromObjectIntrinsic(Object object, @ConstantNodeParameter int displacement, long offset, @ConstantNodeParameter Kind wordKind);
+
+    @NodeIntrinsic(value = UnsafeLoadNode.class, setStampFromReturnType = true)
+    private static native Word loadWordFromWordIntrinsic(Word address, @ConstantNodeParameter int displacement, long offset, @ConstantNodeParameter Kind wordKind);
+
+    @NodeIntrinsic(value = LoadHubNode.class, setStampFromReturnType = true)
+    static native Word loadHubIntrinsic(Object object, @ConstantNodeParameter Kind word);
+
+    @Fold
+    public
+    static int log2WordSize() {
+        return CodeUtil.log2(wordSize());
+    }
+
+    @Fold
+    public
+    static int klassStateOffset() {
+        return config().klassStateOffset;
+    }
+
+    @Fold
+    public
+    static int klassInstanceSizeOffset() {
+        return config().klassInstanceSizeOffset;
+    }
+
+    @Fold
+    public
+    static long heapTopAddress() {
+        return config().heapTopAddress;
+    }
+
+    @Fold
+    public
+    static long heapEndAddress() {
+        return config().heapEndAddress;
+    }
+
+    @Fold
+    public
+    static int threadTlabStartOffset() {
+        return config().threadTlabStartOffset;
+    }
+
+    @Fold
+    public
+    static long tlabIntArrayMarkWord() {
+        return config().tlabIntArrayMarkWord;
+    }
+
+    @Fold
+    public
+    static boolean inlineContiguousAllocationSupported() {
+        return config().inlineContiguousAllocationSupported;
+    }
+
+    @Fold
+    public
+    static int tlabAlignmentReserveInHeapWords() {
+        return config().tlabAlignmentReserve;
+    }
+
+    @Fold
+    public
+    static int threadTlabSizeOffset() {
+        return config().threadTlabSizeOffset;
+    }
+
+    @Fold
+    public
+    static int threadAllocatedBytesOffset() {
+        return config().threadAllocatedBytesOffset;
+    }
+
+    @Fold
+    public
+    static int klassStateFullyInitialized() {
+        return config().klassStateFullyInitialized;
+    }
+
+    @Fold
+    public
+    static int tlabRefillWasteLimitOffset() {
+        return config().tlabRefillWasteLimitOffset;
+    }
+
+    @Fold
+    public
+    static int tlabNumberOfRefillsOffset() {
+        return config().tlabNumberOfRefillsOffset;
+    }
+
+    @Fold
+    public
+    static int tlabFastRefillWasteOffset() {
+        return config().tlabFastRefillWasteOffset;
+    }
+
+    @Fold
+    public
+    static int tlabSlowAllocationsOffset() {
+        return config().tlabSlowAllocationsOffset;
+    }
+
+    @Fold
+    public
+    static int tlabRefillWasteIncrement() {
+        return config().tlabRefillWasteIncrement;
+    }
+
+    @Fold
+    public
+    static boolean tlabStats() {
+        return config().tlabStats;
+    }
+
+    @Fold
+    public static int layoutHelperOffset() {
+        return config().layoutHelperOffset;
+    }
+
+    @Fold
+    public static int layoutHelperHeaderSizeShift() {
+        return config().layoutHelperHeaderSizeShift;
+    }
+
+    @Fold
+    public static int layoutHelperHeaderSizeMask() {
+        return config().layoutHelperHeaderSizeMask;
+    }
+
+    @Fold
+    public static int layoutHelperLog2ElementSizeShift() {
+        return config().layoutHelperLog2ElementSizeShift;
+    }
+
+    @Fold
+    public static int layoutHelperLog2ElementSizeMask() {
+        return config().layoutHelperLog2ElementSizeMask;
+    }
+
+    @Fold
+    public static int layoutHelperElementTypeShift() {
+        return config().layoutHelperElementTypeShift;
+    }
+
+    @Fold
+    public static int layoutHelperElementTypeMask() {
+        return config().layoutHelperElementTypeMask;
+    }
+
+    static {
+        assert arrayIndexScale(Kind.Byte) == 1;
+        assert arrayIndexScale(Kind.Boolean) == 1;
+        assert arrayIndexScale(Kind.Char) == 2;
+        assert arrayIndexScale(Kind.Short) == 2;
+        assert arrayIndexScale(Kind.Int) == 4;
+        assert arrayIndexScale(Kind.Long) == 8;
+        assert arrayIndexScale(Kind.Float) == 4;
+        assert arrayIndexScale(Kind.Double) == 8;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectSnippets.java	Tue Dec 11 08:48:12 2012 +0100
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.snippets;
+
+import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
+
+import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.snippets.*;
+
+@ClassSubstitution(java.lang.Object.class)
+public class ObjectSnippets implements SnippetsInterface {
+    @InstanceMethodSubstitution("getClass")
+    public static Class<?> getClassSnippet(final Object thisObj) {
+        Word hub = loadHub(thisObj);
+        return (Class<?>) loadObjectFromWord(hub, classMirrorOffset());
+    }
+
+    @InstanceMethodSubstitution
+    public static int hashCode(final Object thisObj) {
+        Word mark = loadWordFromObject(thisObj, markOffset());
+
+        // this code is independent from biased locking (although it does not look that way)
+        final Word biasedLock = mark.and(biasedLockMaskInPlace());
+        if (biasedLock.toLong() == unlockedMask()) {
+            int hash = (int) (mark.toLong() >>> identityHashCodeShift());
+            if (hash != uninitializedIdentityHashCodeValue()) {
+                return hash;
+            }
+        }
+
+        return IdentityHashCodeStubCall.call(thisObj);
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/SystemSnippets.java	Mon Dec 10 22:19:07 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/SystemSnippets.java	Tue Dec 11 08:48:12 2012 +0100
@@ -23,9 +23,12 @@
 package com.oracle.graal.hotspot.snippets;
 
 import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
+import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
+
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
+import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.snippets.*;
 
@@ -46,7 +49,25 @@
         return callLong(JAVA_TIME_NANOS);
     }
 
+    public static int identityHashCode(Object x) {
+        if (x == null) {
+            return 0;
+        }
+
+        Word mark = loadWordFromObject(x, markOffset());
+
+        // this code is independent from biased locking (although it does not look that way)
+        final Word biasedLock = mark.and(biasedLockMaskInPlace());
+        if (biasedLock.toLong() == unlockedMask()) {
+            int hash = (int) (mark.toLong() >>> identityHashCodeShift());
+            if (hash != uninitializedIdentityHashCodeValue()) {
+                return hash;
+            }
+        }
+
+        return IdentityHashCodeStubCall.call(x);
+    }
+
     @NodeIntrinsic(value = RuntimeCallNode.class, setStampFromReturnType = true)
     public static native long callLong(@ConstantNodeParameter Descriptor descriptor);
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ThreadSnippets.java	Tue Dec 11 08:48:12 2012 +0100
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.snippets;
+
+import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
+
+import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.snippets.*;
+
+
+@ClassSubstitution(java.lang.Thread.class)
+public class ThreadSnippets implements SnippetsInterface {
+    public static Thread currentThread() {
+        return CurrentThread.get(threadObjectOffset());
+    }
+
+    @InstanceMethodSubstitution
+    @SuppressWarnings("unused")
+    private static boolean isInterrupted(final Thread thisObject, boolean clearInterrupted) {
+        Thread thread = CurrentThread.get(threadObjectOffset());
+        if (thisObject == thread) {
+            Word osThread = loadWordFromObject(thisObject, osThreadOffset());
+            boolean interrupted = loadIntFromWord(osThread, osThreadInterruptedOffset()) == 1;
+            if (!interrupted || !clearInterrupted) {
+                return interrupted;
+            }
+        }
+
+        return ThreadIsInterruptedStubCall.call(thisObject);
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/UnsafeSnippets.java	Mon Dec 10 22:19:07 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/UnsafeSnippets.java	Tue Dec 11 08:48:12 2012 +0100
@@ -68,6 +68,12 @@
         MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
     }
 
+    public void putOrderedObject(Object o, long offset, Object x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putObject(o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
     public int getInt(Object o, long offset) {
         Integer value = UnsafeLoadNode.load(o, 0, offset, Kind.Int);
         return value;
@@ -90,6 +96,12 @@
         MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
     }
 
+    public void putOrderedInt(Object o, long offset, int x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putInt(o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
     public boolean getBoolean(Object o, long offset) {
         @JavacBug(id = 6995200)
         Boolean result = UnsafeLoadNode.load(o, 0, offset, Kind.Boolean);
@@ -205,6 +217,12 @@
         MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
     }
 
+    public void putOrderedLong(Object o, long offset, long x) {
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
+        putLong(o, offset, x);
+        MembarNode.memoryBarrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
+    }
+
     public float getFloat(Object o, long offset) {
         @JavacBug(id = 6995200)
         Float result = UnsafeLoadNode.load(o, 0, offset, Kind.Float);
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java	Mon Dec 10 22:19:07 2012 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java	Tue Dec 11 08:48:12 2012 +0100
@@ -65,9 +65,7 @@
             // make sure that the displacement word of the call ends up word aligned
             int offset = masm.codeBuffer.position();
             offset += tasm.target.arch.getMachineCodeCallDisplacementOffset();
-            while (offset++ % tasm.target.wordSize != 0) {
-                masm.nop();
-            }
+            masm.nop(tasm.target.wordSize - offset % tasm.target.wordSize);
         }
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java	Mon Dec 10 22:19:07 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java	Tue Dec 11 08:48:12 2012 +0100
@@ -22,8 +22,8 @@
  */
 package com.oracle.graal.nodes.extended;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.meta.ResolvedJavaType.Representation;
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Mon Dec 10 22:19:07 2012 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Tue Dec 11 08:48:12 2012 +0100
@@ -90,9 +90,13 @@
     }
 
     private static InlineInfo logNotInlinedMethodAndReturnNull(Invoke invoke, ResolvedJavaMethod method, String msg) {
+        return logNotInlinedMethodAndReturnNull(invoke, method, msg, new Object[0]);
+    }
+
+    private static InlineInfo logNotInlinedMethodAndReturnNull(Invoke invoke, ResolvedJavaMethod method, String msg, Object... args) {
         if (shouldLogInliningDecision()) {
             String methodString = methodName(method, invoke);
-            logInliningDecision(methodString, false, msg, new Object[0]);
+            logInliningDecision(methodString, false, msg, args);
         }
         return null;
     }
@@ -285,7 +289,7 @@
 
         @Override
         public String toString() {
-            return "type-checked " + MetaUtil.format("%H.%n(%p):%r", concrete);
+            return "type-checked with type " + type.getName() + " and method " + MetaUtil.format("%H.%n(%p):%r", concrete);
         }
     }
 
@@ -594,10 +598,21 @@
         @Override
         public String toString() {
             StringBuilder builder = new StringBuilder(shouldFallbackToInvoke() ? "megamorphic" : "polymorphic");
-            builder.append(String.format(", %d methods with %d type checks:", concretes.size(), ptypes.length));
+            builder.append(", ");
+            builder.append(concretes.size());
+            builder.append(" methods [ ");
             for (int i = 0; i < concretes.size(); i++) {
                 builder.append(MetaUtil.format("  %H.%n(%p):%r", concretes.get(i)));
             }
+            builder.append(" ], ");
+            builder.append(ptypes.length);
+            builder.append(" type checks [ ");
+            for (int i = 0; i < ptypes.length; i++) {
+                builder.append("  ");
+                builder.append(ptypes[i].getType().getName());
+                builder.append(ptypes[i].getProbability());
+            }
+            builder.append(" ]");
             return builder.toString();
         }
     }
@@ -720,12 +735,11 @@
         } else {
             invoke.setPolymorphic(true);
 
-
             if (!optimisticOpts.inlinePolymorphicCalls() && notRecordedTypeProbability == 0) {
-                return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "inlining polymorphic calls is disabled");
+                return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "inlining polymorphic calls is disabled (%d types)", ptypes.length);
             }
             if (!optimisticOpts.inlineMegamorphicCalls() && notRecordedTypeProbability > 0) {
-                return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "inlining megamorphic calls is disabled");
+                return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "inlining megamorphic calls is disabled (%d types, %f %% not recorded types)", ptypes.length, notRecordedTypeProbability * 100);
             }
 
             // TODO (chaeubl) inlining of multiple methods should work differently
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Mon Dec 10 22:19:07 2012 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Tue Dec 11 08:48:12 2012 +0100
@@ -198,6 +198,15 @@
     public static boolean OptTailDuplication                 = true;
     public static boolean OptEliminatePartiallyRedundantGuards = true;
 
+    // Intrinsification settings
+    public static boolean IntrinsifyArrayCopy                = false;
+    public static boolean IntrinsifyObjectMethods            = true;
+    public static boolean IntrinsifySystemMethods            = true;
+    public static boolean IntrinsifyClassMethods             = true;
+    public static boolean IntrinsifyThreadMethods            = true;
+    public static boolean IntrinsifyUnsafeMethods            = true;
+    public static boolean IntrinsifyMathMethods              = true;
+
     /**
      * Counts the various paths taken through snippets.
      */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/IntrinsificationTest.java	Tue Dec 11 08:48:12 2012 +0100
@@ -0,0 +1,393 @@
+/*
+ * 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.snippets;
+
+import static org.junit.Assert.*;
+
+import java.util.concurrent.*;
+
+import org.junit.*;
+
+import sun.misc.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.common.*;
+
+
+public class IntrinsificationTest extends GraalCompilerTest {
+    @Test
+    public void testObjectIntrinsics() {
+        test("getClassSnippet");
+        test("objectHashCodeSnippet");
+    }
+
+    @SuppressWarnings("all")
+    public static boolean getClassSnippet(Object obj) {
+        return obj.getClass() == String.class;
+    }
+    @SuppressWarnings("all")
+    public static int objectHashCodeSnippet(A obj) {
+        return obj.hashCode();
+    }
+
+
+    @Test
+    public void testClassIntrinsics() {
+        test("getModifiersSnippet");
+//        test("isInstanceSnippet");
+        test("isInterfaceSnippet");
+        test("isArraySnippet");
+        test("isPrimitiveSnippet");
+        test("getSuperClassSnippet");
+        test("getComponentTypeSnippet");
+    }
+
+    @SuppressWarnings("all")
+    public static int getModifiersSnippet(Class<?> clazz) {
+        return clazz.getModifiers();
+    }
+    @SuppressWarnings("all")
+    public static boolean isInstanceSnippet(Class<?> clazz) {
+        return clazz.isInstance(Number.class);
+    }
+    @SuppressWarnings("all")
+    public static boolean isInterfaceSnippet(Class<?> clazz) {
+        return clazz.isInterface();
+    }
+    @SuppressWarnings("all")
+    public static boolean isArraySnippet(Class<?> clazz) {
+        return clazz.isArray();
+    }
+    @SuppressWarnings("all")
+    public static boolean isPrimitiveSnippet(Class<?> clazz) {
+        return clazz.isPrimitive();
+    }
+    @SuppressWarnings("all")
+    public static Class<?> getSuperClassSnippet(Class<?> clazz) {
+        return clazz.getSuperclass();
+    }
+    @SuppressWarnings("all")
+    public static Class<?> getComponentTypeSnippet(Class<?> clazz) {
+        return clazz.getComponentType();
+    }
+
+
+    @Test
+    public void testThreadIntrinsics() {
+        test("currentThreadSnippet");
+        test("threadIsInterruptedSnippet");
+        test("threadInterruptedSnippet");
+    }
+
+    @SuppressWarnings("all")
+    public static Thread currentThreadSnippet() {
+        return Thread.currentThread();
+    }
+    @SuppressWarnings("all")
+    public static boolean threadIsInterruptedSnippet(Thread thread) {
+        return thread.isInterrupted();
+    }
+    @SuppressWarnings("all")
+    public static boolean threadInterruptedSnippet() {
+        return Thread.interrupted();
+    }
+
+
+    @Test
+    public void testSystemIntrinsics() {
+        test("systemTimeSnippet");
+        test("systemIdentityHashCode");
+//        test("arraycopySnippet");
+    }
+
+    @SuppressWarnings("all")
+    public static long systemTimeSnippet() {
+        return System.currentTimeMillis() + System.nanoTime();
+    }
+    @SuppressWarnings("all")
+    public static int systemIdentityHashCode(Object obj) {
+        return System.identityHashCode(obj);
+    }
+    @SuppressWarnings("all")
+    public static void arraycopySnippet(int[] src, int srcPos, int[] dest, int destPos, int length) {
+        System.arraycopy(src, srcPos, dest, destPos, length);
+    }
+
+
+    @Test
+    public void testUnsafeIntrinsics() {
+        test("unsafeCompareAndSwapIntSnippet");
+        test("unsafeCompareAndSwapLongSnippet");
+        test("unsafeCompareAndSwapObjectSnippet");
+
+        test("unsafeGetBooleanSnippet");
+        test("unsafeGetByteSnippet");
+        test("unsafeGetShortSnippet");
+        test("unsafeGetCharSnippet");
+        test("unsafeGetIntSnippet");
+        test("unsafeGetFloatSnippet");
+        test("unsafeGetDoubleSnippet");
+        test("unsafeGetObjectSnippet");
+
+        test("unsafePutBooleanSnippet");
+        test("unsafePutByteSnippet");
+        test("unsafePutShortSnippet");
+        test("unsafePutCharSnippet");
+        test("unsafePutIntSnippet");
+        test("unsafePutFloatSnippet");
+        test("unsafePutDoubleSnippet");
+        test("unsafePutObjectSnippet");
+
+        // test("unsafeDirectMemoryReadSnippet");
+        // test("unsafeDirectMemoryWriteSnippet");
+    }
+
+    @SuppressWarnings("all")
+    public static boolean unsafeCompareAndSwapIntSnippet(Unsafe unsafe, Object obj, long offset) {
+        return unsafe.compareAndSwapInt(obj, offset, 0, 1);
+    }
+    @SuppressWarnings("all")
+    public static boolean unsafeCompareAndSwapLongSnippet(Unsafe unsafe, Object obj, long offset) {
+        return unsafe.compareAndSwapLong(obj, offset, 0, 1);
+    }
+    @SuppressWarnings("all")
+    public static boolean unsafeCompareAndSwapObjectSnippet(Unsafe unsafe, Object obj, long offset) {
+        return unsafe.compareAndSwapObject(obj, offset, null, new Object());
+    }
+    @SuppressWarnings("all")
+    public static boolean unsafeGetBooleanSnippet(Unsafe unsafe, Object obj, long offset) {
+        return unsafe.getBoolean(obj, offset) &&
+               unsafe.getBooleanVolatile(obj, offset);
+    }
+    @SuppressWarnings("all")
+    public static int unsafeGetByteSnippet(Unsafe unsafe, Object obj, long offset) {
+        return unsafe.getByte(obj, offset) +
+               unsafe.getByteVolatile(obj, offset);
+    }
+    @SuppressWarnings("all")
+    public static int unsafeGetShortSnippet(Unsafe unsafe, Object obj, long offset) {
+        return unsafe.getShort(obj, offset) +
+               unsafe.getShortVolatile(obj, offset);
+    }
+    @SuppressWarnings("all")
+    public static int unsafeGetCharSnippet(Unsafe unsafe, Object obj, long offset) {
+        return unsafe.getChar(obj, offset) +
+               unsafe.getCharVolatile(obj, offset);
+    }
+    @SuppressWarnings("all")
+    public static int unsafeGetIntSnippet(Unsafe unsafe, Object obj, long offset) {
+        return unsafe.getInt(obj, offset) +
+               unsafe.getIntVolatile(obj, offset);
+    }
+    @SuppressWarnings("all")
+    public static long unsafeGetLongSnippet(Unsafe unsafe, Object obj, long offset) {
+        return unsafe.getLong(obj, offset) +
+               unsafe.getLongVolatile(obj, offset);
+    }
+    @SuppressWarnings("all")
+    public static float unsafeGetFloatSnippet(Unsafe unsafe, Object obj, long offset) {
+        return unsafe.getFloat(obj, offset) +
+               unsafe.getFloatVolatile(obj, offset);
+    }
+    @SuppressWarnings("all")
+    public static double unsafeGetDoubleSnippet(Unsafe unsafe, Object obj, long offset) {
+        return unsafe.getDouble(obj, offset) +
+               unsafe.getDoubleVolatile(obj, offset);
+    }
+    @SuppressWarnings("all")
+    public static boolean unsafeGetObjectSnippet(Unsafe unsafe, Object obj, long offset) {
+        return unsafe.getObject(obj, offset) == unsafe.getObjectVolatile(obj, offset);
+    }
+    @SuppressWarnings("all")
+    public static void unsafePutBooleanSnippet(Unsafe unsafe, Object obj, long offset, boolean value) {
+        unsafe.putBoolean(obj, offset, value);
+        unsafe.putBooleanVolatile(obj, offset, value);
+    }
+    @SuppressWarnings("all")
+    public static void unsafePutByteSnippet(Unsafe unsafe, Object obj, long offset, byte value) {
+        unsafe.putByte(obj, offset, value);
+        unsafe.putByteVolatile(obj, offset, value);
+    }
+    @SuppressWarnings("all")
+    public static void unsafePutShortSnippet(Unsafe unsafe, Object obj, long offset, short value) {
+        unsafe.putShort(obj, offset, value);
+        unsafe.putShortVolatile(obj, offset, value);
+    }
+    @SuppressWarnings("all")
+    public static void unsafePutCharSnippet(Unsafe unsafe, Object obj, long offset, char value) {
+        unsafe.putChar(obj, offset, value);
+        unsafe.putCharVolatile(obj, offset, value);
+    }
+    @SuppressWarnings("all")
+    public static void unsafePutIntSnippet(Unsafe unsafe, Object obj, long offset, int value) {
+        unsafe.putInt(obj, offset, value);
+        unsafe.putIntVolatile(obj, offset, value);
+        unsafe.putOrderedInt(obj, offset, value);
+    }
+    @SuppressWarnings("all")
+    public static void unsafePutLongSnippet(Unsafe unsafe, Object obj, long offset, long value) {
+        unsafe.putLong(obj, offset, value);
+        unsafe.putLongVolatile(obj, offset, value);
+        unsafe.putOrderedLong(obj, offset, value);
+    }
+    @SuppressWarnings("all")
+    public static void unsafePutFloatSnippet(Unsafe unsafe, Object obj, long offset, float value) {
+        unsafe.putFloat(obj, offset, value);
+        unsafe.putFloatVolatile(obj, offset, value);
+    }
+    @SuppressWarnings("all")
+    public static void unsafePutDoubleSnippet(Unsafe unsafe, Object obj, long offset, double value) {
+        unsafe.putDouble(obj, offset, value);
+        unsafe.putDoubleVolatile(obj, offset, value);
+    }
+    @SuppressWarnings("all")
+    public static void unsafePutObjectSnippet(Unsafe unsafe, Object obj, long offset, Object value) {
+        unsafe.putObject(obj, offset, value);
+        unsafe.putObjectVolatile(obj, offset, value);
+        unsafe.putOrderedObject(obj, offset, value);
+    }
+    @SuppressWarnings("all")
+    public static double unsafeDirectMemoryReadSnippet(Unsafe unsafe, long address) {
+        // Unsafe.getBoolean(long) and Unsafe.getObject(long) do not exist
+        return unsafe.getByte(address) +
+               unsafe.getShort(address) +
+               unsafe.getChar(address) +
+               unsafe.getInt(address) +
+               unsafe.getLong(address) +
+               unsafe.getFloat(address) +
+               unsafe.getDouble(address);
+    }
+    @SuppressWarnings("all")
+    public static void unsafeDirectMemoryWriteSnippet(Unsafe unsafe, long address, byte value) {
+        // Unsafe.putBoolean(long) and Unsafe.putObject(long) do not exist
+        unsafe.putByte(address, value);
+        unsafe.putShort(address, value);
+        unsafe.putChar(address, (char) value);
+        unsafe.putInt(address, value);
+        unsafe.putLong(address, value);
+        unsafe.putFloat(address, value);
+        unsafe.putDouble(address, value);
+    }
+
+
+    @Test
+    public void testMathIntrinsics() {
+        test("mathSnippet");
+    }
+
+    @SuppressWarnings("all")
+    public static double mathSnippet(double value) {
+        return Math.abs(value) +
+               Math.sqrt(value) +
+               Math.log(value) +
+               Math.log10(value) +
+               Math.sin(value) +
+               Math.cos(value) +
+               Math.tan(value);
+//               Math.exp(value) +
+//               Math.pow(value, 13);
+    }
+
+
+    @Test
+    public void testIntegerIntrinsics() {
+        // TODO (chaeubl): some methods have Java implementations -> check more than Invoke nodes
+        test("integerSnippet");
+    }
+
+    @SuppressWarnings("all")
+    public static int integerSnippet(int value) {
+        return Integer.reverseBytes(value) +
+               Integer.numberOfLeadingZeros(value) +
+               Integer.numberOfTrailingZeros(value);
+    }
+
+
+    @Test
+    public void testLongIntrinsics() {
+        test("longSnippet");
+    }
+
+    @SuppressWarnings("all")
+    public static long longSnippet(long value) {
+        return Long.reverseBytes(value) +
+               Long.numberOfLeadingZeros(value) +
+               Long.numberOfTrailingZeros(value);
+    }
+
+
+    @Test
+    public void testFloatIntrinsics() {
+        test("floatSnippet");
+    }
+
+    @SuppressWarnings("all")
+    public static float floatSnippet(float value) {
+        return Float.intBitsToFloat(Float.floatToIntBits(value));
+    }
+
+
+    @Test
+    public void testDoubleIntrinsics() {
+        test("doubleSnippet");
+    }
+
+    @SuppressWarnings("all")
+    public static double doubleSnippet(double value) {
+        return Double.longBitsToDouble(Double.doubleToLongBits(value));
+    }
+
+
+    private StructuredGraph test(final String snippet) {
+        return Debug.scope("IntrinsificationTest", new DebugDumpScope(snippet), new Callable<StructuredGraph>() {
+            @Override
+            public StructuredGraph call() {
+                StructuredGraph graph = parse(snippet);
+                PhasePlan phasePlan = getDefaultPhasePlan();
+                Assumptions assumptions = new Assumptions(true);
+                Debug.dump(graph, "Graph");
+                new InliningPhase(null, runtime(), null, assumptions, null, phasePlan, OptimisticOptimizations.ALL).apply(graph);
+                Debug.dump(graph, "Graph");
+                new CanonicalizerPhase(null, runtime(), assumptions).apply(graph);
+                new DeadCodeEliminationPhase().apply(graph);
+
+                assertNoInvokes(graph);
+                return graph;
+            }
+        });
+    }
+
+    private static boolean assertNoInvokes(StructuredGraph graph) {
+        for (Invoke invoke: graph.getInvokes()) {
+            fail(invoke.toString());
+        }
+        return false;
+    }
+
+    private static class A {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/InstanceMethodSubstitution.java	Tue Dec 11 08:48:12 2012 +0100
@@ -0,0 +1,34 @@
+/*
+ * 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.snippets;
+
+import java.lang.annotation.*;
+
+/**
+ * Denotes a method that substitutes a method of another class.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface InstanceMethodSubstitution {
+    String value() default "";
+}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java	Mon Dec 10 22:19:07 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java	Tue Dec 11 08:48:12 2012 +0100
@@ -91,7 +91,7 @@
                     throw new RuntimeException("Snippet must not be abstract or native");
                 }
                 ResolvedJavaMethod snippet = runtime.lookupJavaMethod(method);
-                assert snippet.getCompilerStorage().get(Graph.class) == null;
+                assert snippet.getCompilerStorage().get(Graph.class) == null : method;
                 StructuredGraph graph = makeGraph(snippet, inliningPolicy(snippet));
                 //System.out.println("snippet: " + graph);
                 snippet.getCompilerStorage().put(Graph.class, graph);
@@ -105,7 +105,19 @@
                 continue;
             }
             try {
-                Method originalMethod = originalClazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
+                InstanceMethodSubstitution methodSubstitution = method.getAnnotation(InstanceMethodSubstitution.class);
+                String originalName = method.getName();
+                Class<?>[] originalParameters = method.getParameterTypes();
+                if (methodSubstitution != null) {
+                    if (!methodSubstitution.value().isEmpty()) {
+                        originalName = methodSubstitution.value();
+                    }
+                    assert originalParameters.length >= 1 : "must be a static method with the this object as its first parameter";
+                    Class<?>[] newParameters = new Class<?>[originalParameters.length - 1];
+                    System.arraycopy(originalParameters, 1, newParameters, 0, newParameters.length);
+                    originalParameters = newParameters;
+                }
+                Method originalMethod = originalClazz.getDeclaredMethod(originalName, originalParameters);
                 if (!originalMethod.getReturnType().isAssignableFrom(method.getReturnType())) {
                     throw new RuntimeException("Snippet has incompatible return type");
                 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetProvider.java	Tue Dec 11 08:48:12 2012 +0100
@@ -0,0 +1,30 @@
+/*
+ * 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.snippets;
+
+import com.oracle.graal.api.code.*;
+
+
+public interface SnippetProvider {
+    void installSnippets(SnippetInstaller installer, Assumptions assumptions);
+}
--- a/make/windows/makefiles/projectcreator.make	Mon Dec 10 22:19:07 2012 +0100
+++ b/make/windows/makefiles/projectcreator.make	Tue Dec 11 08:48:12 2012 +0100
@@ -144,6 +144,9 @@
  -ignorePath_TARGET tiered \
  -ignorePath_TARGET c1_
 
+ProjectCreatorIDEOptionsIgnoreGraal=\
+ -ignorePath_TARGET graal
+ 
 ProjectCreatorIDEOptionsIgnoreCompiler2=\
  -ignorePath_TARGET compiler2 \
  -ignorePath_TARGET tiered \
@@ -230,15 +233,18 @@
  -define_compiler1 COMPILER1 \
  -ignorePath_compiler1 core \
  -ignorePath_compiler1 src/share/vm/graal \
-$(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=compiler1)
+ $(ProjectCreatorIDEOptionsIgnoreGraal:TARGET=compiler1) \
+ $(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=compiler1)
 
 ##################################################
 # Graal compiler specific options
 ##################################################
 ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \
- -define_graal COMPILER1 \
  -define_graal GRAAL \
-$(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=graal)
+ -ignorePath_graal core \
+ -ignorePath_graal src/share/vm/c1 \
+ $(ProjectCreatorIDEOptionsIgnoreCompiler1:TARGET=graal) \
+ $(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=graal)
 
 ##################################################
 # Server(C2) compiler specific options
@@ -260,6 +266,7 @@
  -additionalFile_compiler2 ad_$(Platform_arch_model)_pipeline.cpp \
  -additionalFile_compiler2 adGlobals_$(Platform_arch_model).hpp \
  -additionalFile_compiler2 dfa_$(Platform_arch_model).cpp \
+ $(ProjectCreatorIDEOptionsIgnoreGraal:TARGET=compiler2) \
  $(ProjectCreatorIDEOptionsIgnoreCompiler1:TARGET=compiler2)
 
 # Add in the jvmti (JSR-163) options
--- a/make/windows/makefiles/vm.make	Mon Dec 10 22:19:07 2012 +0100
+++ b/make/windows/makefiles/vm.make	Tue Dec 11 08:48:12 2012 +0100
@@ -61,7 +61,7 @@
 !endif
 
 !if "$(Variant)" == "graal"
-CPP_FLAGS=$(CPP_FLAGS) /D "COMPILER1" /D "GRAAL"
+CPP_FLAGS=$(CPP_FLAGS) /D "GRAAL"
 !endif
 
 !if "$(BUILDARCH)" == "i486"
--- a/src/cpu/x86/vm/c1_globals_x86.hpp	Mon Dec 10 22:19:07 2012 +0100
+++ b/src/cpu/x86/vm/c1_globals_x86.hpp	Tue Dec 11 08:48:12 2012 +0100
@@ -57,6 +57,7 @@
 define_pd_global(bool, CICompileOSR,                 true );
 #endif // !TIERED
 define_pd_global(bool, UseTypeProfile,               false);
+define_pd_global(intx, TypeProfileWidth,             0);
 define_pd_global(bool, RoundFPResults,               true );
 
 define_pd_global(bool, LIRFillDelaySlots,            false);
--- a/src/cpu/x86/vm/graalGlobals_x86.hpp	Mon Dec 10 22:19:07 2012 +0100
+++ b/src/cpu/x86/vm/graalGlobals_x86.hpp	Tue Dec 11 08:48:12 2012 +0100
@@ -43,7 +43,6 @@
 define_pd_global(intx, FreqInlineSize,               325  );
 define_pd_global(intx, NewSizeThreadIncrease,        4*K  );
 define_pd_global(uintx,MetaspaceSize,                12*M );
-define_pd_global(uintx,MaxPermSize,                  64*M );
 define_pd_global(bool, NeverActAsServerClassMachine, true );
 define_pd_global(uint64_t,MaxRAM,                    1ULL*G);
 define_pd_global(bool, CICompileOSR,                 true );
@@ -58,13 +57,6 @@
 define_pd_global(uintx,CodeCacheMinBlockLength,      4);
 define_pd_global(intx, TypeProfileWidth,             8);
 
-define_pd_global(bool, RoundFPResults,               true );
-
-define_pd_global(bool, LIRFillDelaySlots,            false);
-define_pd_global(bool, OptimizeSinglePrecision,      true );
-define_pd_global(bool, CSEArrayLength,               false);
-define_pd_global(bool, TwoOperandLIRForm,            true );
-
 define_pd_global(intx, SafepointPollOffset,          256  );
 
 #endif // CPU_X86_VM_GRAALGLOBALS_X86_HPP
--- a/src/cpu/x86/vm/graalRuntime_x86.cpp	Mon Dec 10 22:19:07 2012 +0100
+++ b/src/cpu/x86/vm/graalRuntime_x86.cpp	Tue Dec 11 08:48:12 2012 +0100
@@ -1153,6 +1153,35 @@
       break;
     }
 
+    case graal_identity_hash_code_id: {
+      Register obj = j_rarg0; // Incoming
+      __ set_info("identity_hash_code", dont_gc_arguments);
+      __ enter();
+      OopMap* map = save_live_registers(sasm, 1);
+      int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, graal_identity_hash_code), obj);
+      oop_maps = new OopMapSet();
+      oop_maps->add_gc_map(call_offset, map);
+      restore_live_registers_except_rax(sasm);
+      __ leave();
+      __ ret(0);
+      break;
+    }
+    case graal_thread_is_interrupted_id: {
+      Register thread = j_rarg0;
+      Register clear_interrupted = j_rarg1;
+
+      __ set_info("identity_hash_code", dont_gc_arguments);
+      __ enter();
+      OopMap* map = save_live_registers(sasm, 1);
+      int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, graal_thread_is_interrupted), thread, clear_interrupted);
+      oop_maps = new OopMapSet();
+      oop_maps->add_gc_map(call_offset, map);
+      restore_live_registers_except_rax(sasm);
+      __ leave();
+      __ ret(0);
+      break;
+    }
+
     default:
       { GraalStubFrame f(sasm, "unimplemented entry", dont_gc_arguments);
         __ movptr(rax, (int)id);
--- a/src/share/vm/graal/graalCompiler.cpp	Mon Dec 10 22:19:07 2012 +0100
+++ b/src/share/vm/graal/graalCompiler.cpp	Tue Dec 11 08:48:12 2012 +0100
@@ -49,8 +49,8 @@
   JavaThread* THREAD = JavaThread::current();
   TRACE_graal_1("GraalCompiler::initialize");
 
-  unsigned long heap_end = (long) Universe::heap()->reserved_region().end();
-  unsigned long allocation_end = heap_end + 16l * 1024 * 1024 * 1024;
+  uintptr_t heap_end = (uintptr_t) Universe::heap()->reserved_region().end();
+  uintptr_t allocation_end = heap_end + ((uintptr_t)16) * 1024 * 1024 * 1024;
   guarantee(heap_end < allocation_end, "heap end too close to end of address space (might lead to erroneous TLAB allocations)");
   NOT_LP64(error("check TLAB allocation code for address space conflicts"));
 
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Mon Dec 10 22:19:07 2012 +0100
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Tue Dec 11 08:48:12 2012 +0100
@@ -1,972 +1,984 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include "precompiled.hpp"
-#include "runtime/fieldDescriptor.hpp"
-#include "memory/oopFactory.hpp"
-#include "oops/generateOopMap.hpp"
-#include "oops/fieldStreams.hpp"
-#include "runtime/javaCalls.hpp"
-#include "graal/graalRuntime.hpp"
-#include "compiler/compileBroker.hpp"
-#include "compiler/compilerOracle.hpp"
-#include "graal/graalCompilerToVM.hpp"
-#include "graal/graalCompiler.hpp"
-#include "graal/graalEnv.hpp"
-#include "graal/graalJavaAccess.hpp"
-#include "graal/graalCodeInstaller.hpp"
-#include "graal/graalVMToCompiler.hpp"
-#include "graal/graalVmIds.hpp"
-
-
-Method* getMethodFromHotSpotMethod(oop hotspot_method) {
-  assert(hotspot_method != NULL && hotspot_method->is_a(HotSpotResolvedJavaMethod::klass()), "sanity");
-  return asMethod(HotSpotResolvedJavaMethod::metaspaceMethod(hotspot_method));
-}
-
-// Entry to native method implementation that transitions current thread to '_thread_in_vm'.
-#define C2V_VMENTRY(result_type, name, signature) \
-  JNIEXPORT result_type JNICALL c2v_ ## name signature { \
-  TRACE_graal_3("CompilerToVM::" #name); \
-  GRAAL_VM_ENTRY_MARK; \
-
-// Entry to native method implementation that calls a JNI function
-// and hence cannot transition current thread to '_thread_in_vm'.
-#define C2V_ENTRY(result_type, name, signature) \
-  JNIEXPORT result_type JNICALL c2v_ ## name signature { \
-  TRACE_graal_3("CompilerToVM::" #name); \
-
-#define C2V_END }
-
-C2V_ENTRY(jbyteArray, initializeBytecode, (JNIEnv *env, jobject, jlong metaspace_method, jbyteArray result))
-  methodHandle method = asMethod(metaspace_method);
-  ResourceMark rm;
-  
-  int code_size = method->code_size();
-  jbyte* reconstituted_code = NULL;
-
-  // replace all breakpoints - must be done before undoing any rewriting
-  if (method->number_of_breakpoints() > 0) {
-    reconstituted_code = NEW_RESOURCE_ARRAY(jbyte, code_size);
-    memcpy(reconstituted_code, (jbyte *) method->code_base(), code_size);
-    BreakpointInfo* bp = InstanceKlass::cast(method->method_holder())->breakpoints();
-    for (; bp != NULL; bp = bp->next()) {
-      if (bp->match(method())) {
-        jbyte code = bp->orig_bytecode();
-        reconstituted_code[bp->bci()] = code;
-      }
-    }
-  }
-
-  // iterate over all bytecodes and replace non-Java bytecodes
-  if (RewriteBytecodes || RewriteFrequentPairs || InstanceKlass::cast(method->method_holder())->is_rewritten()) {
-    if (reconstituted_code == NULL) {
-      reconstituted_code = NEW_RESOURCE_ARRAY(jbyte, code_size);
-      memcpy(reconstituted_code, (jbyte *) method->code_base(), code_size);
-    }
-    BytecodeStream s(method);
-    while(!s.is_last_bytecode()) {
-      s.next();
-      Bytecodes::Code opcode = s.raw_code();
-      if (!Bytecodes::is_java_code(opcode)) {
-        jbyte original_opcode = Bytecodes::java_code(opcode);
-        int bci = s.bci();
-        reconstituted_code[bci] = original_opcode;
-        if (opcode == Bytecodes::_fast_aldc_w) {
-          int cpci = Bytes::get_native_u2((address) reconstituted_code + bci + 1);
-          int i = method->constants()->object_to_cp_index(cpci);
-          assert(i < method->constants()->length(), "sanity check");
-          Bytes::put_Java_u2((address) reconstituted_code + bci + 1, (u2)i);
-        } else if (opcode == Bytecodes::_fast_aldc) {
-          int cpci = reconstituted_code[bci + 1] & 0xff;
-          int i = method->constants()->object_to_cp_index(cpci);
-          assert(i < method->constants()->length(), "sanity check");
-          reconstituted_code[bci + 1] = (jbyte)i;
-        }
-      }
-    }
-  }
-
-  if (reconstituted_code == NULL) {
-    env->SetByteArrayRegion(result, 0, code_size, (jbyte *) method->code_base());
-  } else {
-    env->SetByteArrayRegion(result, 0, code_size, reconstituted_code);
-  }
-
-  return result;
-C2V_END
-
-C2V_VMENTRY(jstring, getSignature, (JNIEnv *env, jobject, jlong metaspace_method))
-  Method* method = asMethod(metaspace_method);
-  assert(method != NULL && method->signature() != NULL, "signature required");
-  return VmIds::toString<jstring>(method->signature(), THREAD);
-C2V_END
-
-C2V_VMENTRY(jobjectArray, initializeExceptionHandlers, (JNIEnv *, jobject, jlong metaspace_method, jobjectArray java_handlers))
-  ResourceMark rm;
-  methodHandle method = asMethod(metaspace_method);
-  int handler_count = method->exception_table_length();
-  objArrayHandle array = (objArrayOop) JNIHandles::resolve(java_handlers);
-  assert(array->length() == handler_count, "wrong length");
-  ExceptionTableElement* handlers = handler_count == 0 ? NULL : method->exception_table_start();
-
-  for (int i = 0; i < handler_count; i++) {
-    ExceptionTableElement* handler = handlers + i;
-    Handle entry = array->obj_at(i);
-    assert(!entry.is_null(), "entry should not be null");
-    ExceptionHandler::set_startBCI(entry, handler->start_pc);
-    ExceptionHandler::set_endBCI(entry, handler->end_pc);
-    ExceptionHandler::set_handlerBCI(entry, handler->handler_pc);
-    int catch_class_index = handler->catch_type_index;
-    ExceptionHandler::set_catchTypeCPI(entry, catch_class_index);
-
-    if (catch_class_index == 0) {
-      ExceptionHandler::set_catchType(entry, NULL);
-    } else {
-      ConstantPool* cp = InstanceKlass::cast(method->method_holder())->constants();
-      KlassHandle loading_klass = method->method_holder();
-      Handle catch_class = GraalCompiler::get_JavaType(cp, catch_class_index, loading_klass, CHECK_NULL);
-      if (catch_class->klass() == HotSpotResolvedObjectType::klass() && java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(catch_class)) == SystemDictionary::Throwable_klass()) {
-        ExceptionHandler::set_catchType(entry, NULL);
-        ExceptionHandler::set_catchTypeCPI(entry, 0);
-      } else {
-        ExceptionHandler::set_catchType(entry, catch_class());
-      }
-    }
-    array->obj_at_put(i, entry());
-  }
-
-  return (jobjectArray) JNIHandles::make_local(array());
-C2V_END
-
-C2V_VMENTRY(jint, hasBalancedMonitors, (JNIEnv *, jobject, jlong metaspace_method))
-
-  // Analyze the method to see if monitors are used properly.
-  methodHandle method(THREAD, asMethod(metaspace_method));
-  assert(method->has_monitor_bytecodes(), "should have checked this");
-
-  // Check to see if a previous compilation computed the monitor-matching analysis.
-  if (method->guaranteed_monitor_matching()) {
-    return true;
-  }
-
-  {
-    EXCEPTION_MARK;
-    ResourceMark rm(THREAD);
-    GeneratePairingInfo gpi(method);
-    gpi.compute_map(CATCH);
-    if (!gpi.monitor_safe()) {
-      return false;
-    }
-    method->set_guaranteed_monitor_matching();
-  }
-  return true;
-C2V_END
-
-C2V_VMENTRY(jlong, getMetaspaceMethod, (JNIEnv *, jobject, jobject reflection_method_handle, jobject resultHolder))
-  oop reflection_method = JNIHandles::resolve(reflection_method_handle);
-  oop reflection_holder = java_lang_reflect_Method::clazz(reflection_method);
-  int slot = java_lang_reflect_Method::slot(reflection_method);
-  Klass* holder = java_lang_Class::as_Klass(reflection_holder);
-  methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot);
-  Handle type = GraalCompiler::createHotSpotResolvedObjectType(method, CHECK_0);
-  objArrayOop(JNIHandles::resolve(resultHolder))->obj_at_put(0, type());
-  return (jlong) (address) method();
-}
-
-C2V_VMENTRY(jlong, getMetaspaceConstructor, (JNIEnv *, jobject, jobject reflection_ctor_handle, jobject resultHolder))
-  oop reflection_ctor = JNIHandles::resolve(reflection_ctor_handle);
-  oop reflection_holder = java_lang_reflect_Constructor::clazz(reflection_ctor);
-  int slot = java_lang_reflect_Constructor::slot(reflection_ctor);
-  Klass* holder = java_lang_Class::as_Klass(reflection_holder);
-  methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot);
-  Handle type = GraalCompiler::createHotSpotResolvedObjectType(method, CHECK_0);
-  objArrayOop(JNIHandles::resolve(resultHolder))->obj_at_put(0, type());
-  return (jlong) (address) method();
-}
-
-C2V_VMENTRY(jobject, getJavaField, (JNIEnv *, jobject, jobject reflection_field_handle))
-  oop reflection_field = JNIHandles::resolve(reflection_field_handle);
-  oop reflection_holder = java_lang_reflect_Field::clazz(reflection_field);
-  int slot = java_lang_reflect_Field::slot(reflection_field);
-  InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(reflection_holder));
-
-  int offset = holder->field_offset(slot);
-  int flags = holder->field_access_flags(slot);
-  Symbol* field_name = holder->field_name(slot);
-  Handle field_holder = GraalCompiler::get_JavaTypeFromClass(reflection_holder, CHECK_NULL);
-  Handle field_type = GraalCompiler::get_JavaTypeFromClass(java_lang_reflect_Field::type(reflection_field), CHECK_NULL);
-
-  Handle ret = GraalCompiler::get_JavaField(offset, flags, field_name, field_holder, field_type, CHECK_NULL);
-  return JNIHandles::make_local(THREAD, ret());
-}
-
-C2V_VMENTRY(jlong, getUniqueConcreteMethod, (JNIEnv *, jobject, jlong metaspace_method, jobject resultHolder))
-  methodHandle method = asMethod(metaspace_method);
-  KlassHandle holder = method->method_holder();
-  if (holder->is_interface()) {
-    // Cannot trust interfaces. Because of:
-    // interface I { void foo(); }
-    // class A { public void foo() {} }
-    // class B extends A implements I { }
-    // class C extends B { public void foo() { } }
-    // class D extends B { }
-    // Would lead to identify C.foo() as the unique concrete method for I.foo() without seeing A.foo().
-    return 0L;
-  }
-  methodHandle ucm;
-  {
-    ResourceMark rm;
-    MutexLocker locker(Compile_lock);
-    ucm = Dependencies::find_unique_concrete_method(holder(), method());
-  }
-
-  if (ucm.is_null()) {
-    return 0L;
-  }
-
-  Handle type = GraalCompiler::createHotSpotResolvedObjectType(ucm(), CHECK_0);
-  objArrayOop(JNIHandles::resolve(resultHolder))->obj_at_put(0, type());
-  return (jlong) (address) ucm();
-C2V_END
-
-C2V_ENTRY(jint, getInvocationCount, (JNIEnv *, jobject, jlong metaspace_method))
-  Method* method = asMethod(metaspace_method);
-  return method->invocation_count();
-C2V_END
-
-C2V_VMENTRY(void, initializeMethod,(JNIEnv *, jobject, jlong metaspace_method, jobject hotspot_method))
-  methodHandle method = asMethod(metaspace_method);
-  Handle name = VmIds::toString<Handle>(method->name(), CHECK);
-  InstanceKlass::cast(HotSpotResolvedJavaMethod::klass())->initialize(CHECK);
-  HotSpotResolvedJavaMethod::set_name(hotspot_method, name());
-  HotSpotResolvedJavaMethod::set_codeSize(hotspot_method, method->code_size());
-  HotSpotResolvedJavaMethod::set_exceptionHandlerCount(hotspot_method, method->exception_table_length());
-C2V_END
-
-C2V_VMENTRY(jboolean, isMethodCompilable,(JNIEnv *, jobject, jlong metaspace_method))
-  methodHandle method = asMethod(metaspace_method);
-  return !method->is_not_compilable() && !CompilerOracle::should_not_inline(method);
-C2V_END
-
-C2V_VMENTRY(void, initializeMethodData,(JNIEnv *, jobject, jlong metaspace_method_data, jobject hotspot_method_data))
-  MethodData* method_data = asMethodData(metaspace_method_data);
-  HotSpotMethodData::set_normalDataSize(hotspot_method_data, method_data->data_size());
-  HotSpotMethodData::set_extraDataSize(hotspot_method_data, method_data->extra_data_size());
-C2V_END
-
-// ------------------------------------------------------------------
-// Adjust a CounterData count to be commensurate with
-// interpreter_invocation_count.  If the MDO exists for
-// only 25% of the time the method exists, then the
-// counts in the MDO should be scaled by 4X, so that
-// they can be usefully and stably compared against the
-// invocation counts in methods.
-int scale_count(MethodData* method_data, int count) {
-  if (count > 0) {
-    int counter_life;
-    int method_life = method_data->method()->interpreter_invocation_count();
-    int current_mileage = MethodData::mileage_of(method_data->method());
-    int creation_mileage = method_data->creation_mileage();
-    counter_life = current_mileage - creation_mileage;
-
-    // counter_life due to backedge_counter could be > method_life
-    if (counter_life > method_life)
-      counter_life = method_life;
-    if (0 < counter_life && counter_life <= method_life) {
-      count = (int)((double)count * method_life / counter_life + 0.5);
-      count = (count > 0) ? count : 1;
-    }
-  }
-  return count;
-}
-
-C2V_ENTRY(jint, getCompiledCodeSize, (JNIEnv *env, jobject, jlong metaspace_method))
-  nmethod* code = (asMethod(metaspace_method))->code();
-  return code == NULL ? 0 : code->insts_size();
-C2V_END
-
-C2V_VMENTRY(jobject, lookupType, (JNIEnv *env, jobject, jstring jname, jobject accessingClass, jboolean eagerResolve))
-  ResourceMark rm;
-
-  Symbol* nameSymbol = VmIds::toSymbol(jname);
-  Handle name = JNIHandles::resolve(jname);
-  assert(nameSymbol != NULL, "name to symbol creation failed");
-
-  oop result = NULL;
-  if (nameSymbol == vmSymbols::int_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_INT, THREAD);
-  } else if (nameSymbol == vmSymbols::long_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_LONG, THREAD);
-  } else if (nameSymbol == vmSymbols::bool_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_BOOLEAN, THREAD);
-  } else if (nameSymbol == vmSymbols::char_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_CHAR, THREAD);
-  } else if (nameSymbol == vmSymbols::short_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_SHORT, THREAD);
-  } else if (nameSymbol == vmSymbols::byte_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_BYTE, THREAD);
-  } else if (nameSymbol == vmSymbols::double_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_DOUBLE, THREAD);
-  } else if (nameSymbol == vmSymbols::float_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_FLOAT, THREAD);
-  } else if (nameSymbol == vmSymbols::void_signature()) {
-    result = VMToCompiler::createPrimitiveJavaType((int) T_VOID, THREAD);
-  } else {
-    Klass* resolved_type = NULL;
-    Handle classloader;
-    Handle protectionDomain;
-    if (JNIHandles::resolve(accessingClass) != NULL) {
-      classloader = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(accessingClass))->class_loader();
-      protectionDomain = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(accessingClass))->protection_domain();
-    }
-
-    if (eagerResolve) {
-      resolved_type = SystemDictionary::resolve_or_fail(nameSymbol, classloader, protectionDomain, true, THREAD);
-    } else {
-      resolved_type = SystemDictionary::resolve_or_null(nameSymbol, classloader, protectionDomain, THREAD);
-    }
-
-    if (!HAS_PENDING_EXCEPTION) {
-      if (resolved_type == NULL) {
-        assert(!eagerResolve, "failed eager resolution should have caused an exception");
-        Handle type = VMToCompiler::createUnresolvedJavaType(name, THREAD);
-        result = type();
-      } else {
-        Handle type = GraalCompiler::createHotSpotResolvedObjectType(resolved_type, name, CHECK_NULL);
-        result = type();
-      }
-    }
-  }
-
-  return JNIHandles::make_local(THREAD, result);
-C2V_END
-
-C2V_VMENTRY(jobject, lookupConstantInPool, (JNIEnv *env, jobject, jobject type, jint index))
-
-  ConstantPool* cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants();
-
-  oop result = NULL;
-  constantTag tag = cp->tag_at(index);
-  if (tag.is_int()) {
-    result = VMToCompiler::createConstant(Kind::Int(), cp->int_at(index), CHECK_0);
-  } else if (tag.is_long()) {
-    result = VMToCompiler::createConstant(Kind::Long(), cp->long_at(index), CHECK_0);
-  } else if (tag.is_float()) {
-    result = VMToCompiler::createConstantFloat(cp->float_at(index), CHECK_0);
-  } else if (tag.is_double()) {
-    result = VMToCompiler::createConstantDouble(cp->double_at(index), CHECK_0);
-  } else if (tag.is_string()) {
-    oop string = NULL;
-    if (cp->is_pseudo_string_at(index)) {
-      int obj_index = cp->cp_to_object_index(index);
-      string = cp->pseudo_string_at(index, obj_index);
-    } else {
-      string = cp->string_at(index, THREAD);
-      if (HAS_PENDING_EXCEPTION) {
-        CLEAR_PENDING_EXCEPTION;
-        // TODO: Gracefully exit compilation.
-        fatal("out of memory during compilation!");
-        return NULL;
-      }
-    }
-    result = VMToCompiler::createConstantObject(string, CHECK_0);
-  } else if (tag.is_klass() || tag.is_unresolved_klass()) {
-    Handle type = GraalCompiler::get_JavaType(cp, index, cp->pool_holder(), CHECK_NULL);
-    result = type();
-  } else if (tag.is_object()) {
-    oop obj = cp->object_at(index);
-    assert(obj->is_instance(), "must be an instance");
-    result = VMToCompiler::createConstantObject(obj, CHECK_NULL);
-  } else {
-    tty->print("unknown constant pool tag (%s) at cpi %d in %s: ", tag.internal_name(), index, cp->pool_holder()->name()->as_C_string());
-    ShouldNotReachHere();
-  }
-
-  return JNIHandles::make_local(THREAD, result);
-C2V_END
-
-C2V_VMENTRY(jobject, lookupMethodInPool, (JNIEnv *env, jobject, jobject type, jint index, jbyte opcode))
-  index = GraalCompiler::to_cp_index_u2(index);
-  constantPoolHandle cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants();
-  instanceKlassHandle pool_holder(cp->pool_holder());
-
-  Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF);
-  methodHandle method = GraalEnv::get_method_by_index(cp, index, bc, pool_holder);
-  if (!method.is_null()) {
-    Handle holder = GraalCompiler::get_JavaType(method->method_holder(), CHECK_NULL);
-    return JNIHandles::make_local(THREAD, VMToCompiler::createResolvedJavaMethod(holder, method(), THREAD));
-  } else {
-    // Get the method's name and signature.
-    Handle name = VmIds::toString<Handle>(cp->name_ref_at(index), CHECK_NULL);
-    Handle signature  = VmIds::toString<Handle>(cp->signature_ref_at(index), CHECK_NULL);
-    int holder_index = cp->klass_ref_index_at(index);
-    Handle type = GraalCompiler::get_JavaType(cp, holder_index, cp->pool_holder(), CHECK_NULL);
-    return JNIHandles::make_local(THREAD, VMToCompiler::createUnresolvedJavaMethod(name, signature, type, THREAD));
-  }
-C2V_END
-
-C2V_VMENTRY(jobject, lookupTypeInPool, (JNIEnv *env, jobject, jobject type, jint index))
-
-  ConstantPool* cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants();
-  Handle result = GraalCompiler::get_JavaType(cp, index, cp->pool_holder(), CHECK_NULL);
-  return JNIHandles::make_local(THREAD, result());
-C2V_END
-
-C2V_VMENTRY(void, lookupReferencedTypeInPool, (JNIEnv *env, jobject, jobject type, jint index, jbyte op))
-  ConstantPool* cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants();
-  int opcode = (op & 0xFF);
-  if (opcode != Bytecodes::_checkcast && opcode != Bytecodes::_instanceof && opcode != Bytecodes::_new && opcode != Bytecodes::_anewarray
-      && opcode != Bytecodes::_multianewarray && opcode != Bytecodes::_ldc && opcode != Bytecodes::_ldc_w && opcode != Bytecodes::_ldc2_w)
-  {
-    index = cp->remap_instruction_operand_from_cache(GraalCompiler::to_cp_index_u2(index));
-  }
-  constantTag tag = cp->tag_at(index);
-  if (tag.is_field_or_method()) {
-    index = cp->uncached_klass_ref_index_at(index);
-    tag = cp->tag_at(index);
-  }
-
-  if (tag.is_unresolved_klass() || tag.is_klass()) {
-    Klass* klass = cp->klass_at(index, CHECK);
-    if (klass->oop_is_instance()) {
-      InstanceKlass::cast(klass)->initialize(CHECK);
-    }
-  }
-C2V_END
-
-C2V_VMENTRY(jobject, lookupFieldInPool, (JNIEnv *env, jobject, jobject constantPoolHolder, jint index, jbyte opcode))
-  ResourceMark rm;
-
-  index = GraalCompiler::to_cp_index_u2(index);
-  constantPoolHandle cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(constantPoolHolder)))->constants();
-
-  int nt_index = cp->name_and_type_ref_index_at(index);
-  int sig_index = cp->signature_ref_index_at(nt_index);
-  Symbol* signature = cp->symbol_at(sig_index);
-  int name_index = cp->name_ref_index_at(nt_index);
-  Symbol* name = cp->symbol_at(name_index);
-  int holder_index = cp->klass_ref_index_at(index);
-  Handle holder = GraalCompiler::get_JavaType(cp, holder_index, cp->pool_holder(), CHECK_NULL);
-  instanceKlassHandle holder_klass;
-  
-  Bytecodes::Code code = (Bytecodes::Code)(((int) opcode) & 0xFF);
-  int offset = -1;
-  AccessFlags flags;
-  BasicType basic_type;
-  if (holder->klass() == SystemDictionary::HotSpotResolvedObjectType_klass()) {
-    FieldAccessInfo result;
-    LinkResolver::resolve_field(result, cp, index,
-                                Bytecodes::java_code(code),
-                                true, false, Thread::current());
-    if (HAS_PENDING_EXCEPTION) {
-      CLEAR_PENDING_EXCEPTION;
-    } else {
-      offset = result.field_offset();
-      flags = result.access_flags();
-      holder_klass = result.klass()();
-      basic_type = result.field_type();
-      holder = GraalCompiler::get_JavaType(holder_klass, CHECK_NULL);
-    }
-  }
-  
-  Handle type = GraalCompiler::get_JavaTypeFromSignature(signature, cp->pool_holder(), CHECK_NULL);
-  Handle field_handle = GraalCompiler::get_JavaField(offset, flags.as_int(), name, holder, type, THREAD);
-
-  return JNIHandles::make_local(THREAD, field_handle());
-C2V_END
-
-C2V_VMENTRY(jobject, resolveMethod, (JNIEnv *, jobject, jobject resolved_type, jstring name, jstring signature))
-
-  assert(JNIHandles::resolve(resolved_type) != NULL, "");
-  Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(resolved_type));
-  Symbol* name_symbol = VmIds::toSymbol(name);
-  Symbol* signature_symbol = VmIds::toSymbol(signature);
-  methodHandle method = klass->lookup_method(name_symbol, signature_symbol);
-  if (method.is_null()) {
-    if (TraceGraal >= 3) {
-      ResourceMark rm;
-      tty->print_cr("Could not resolve method %s %s on klass %s", name_symbol->as_C_string(), signature_symbol->as_C_string(), klass->name()->as_C_string());
-    }
-    return NULL;
-  }
-  Handle holder = GraalCompiler::get_JavaType(method->method_holder(), CHECK_NULL);
-  return JNIHandles::make_local(THREAD, VMToCompiler::createResolvedJavaMethod(holder, method(), THREAD));
-C2V_END
-
-C2V_VMENTRY(jboolean, isTypeInitialized,(JNIEnv *, jobject, jobject hotspot_klass))
-  Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(hotspot_klass));
-  assert(klass != NULL, "method must not be called for primitive types");
-  return InstanceKlass::cast(klass)->is_initialized();
-C2V_END
-
-C2V_VMENTRY(void, initializeType, (JNIEnv *, jobject, jobject hotspot_klass))
-  Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(hotspot_klass));
-  assert(klass != NULL, "method must not be called for primitive types");
-  InstanceKlass::cast(klass)->initialize(JavaThread::current());
-C2V_END
-
-C2V_VMENTRY(jobject, getInstanceFields, (JNIEnv *, jobject, jobject klass))
-  ResourceMark rm;
-
-  instanceKlassHandle k = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(klass));
-  GrowableArray<Handle> fields(k->java_fields_count());
-
-  for (AllFieldStream fs(k()); !fs.done(); fs.next()) {
-    if (!fs.access_flags().is_static()) {
-      Handle type = GraalCompiler::get_JavaTypeFromSignature(fs.signature(), k, Thread::current());
-      int flags = fs.access_flags().as_int();
-      bool internal = fs.access_flags().is_internal();
-      Handle name = VmIds::toString<Handle>(fs.name(), Thread::current());
-      Handle field = VMToCompiler::createJavaField(JNIHandles::resolve(klass), name, type, fs.offset(), flags, internal, Thread::current());
-      fields.append(field());
-    }
-  }
-  objArrayHandle field_array = oopFactory::new_objArray(SystemDictionary::HotSpotResolvedJavaField_klass(), fields.length(), CHECK_NULL);
-  for (int i = 0; i < fields.length(); ++i) {
-    field_array->obj_at_put(i, fields.at(i)());
-  }
-  return JNIHandles::make_local(field_array());
-C2V_END
-
-C2V_VMENTRY(jlong, getMaxCallTargetOffset, (JNIEnv *env, jobject, jlong stub))
-  address target_addr = (address) stub;
-  if (target_addr != 0x0) {
-    int64_t off_low = (int64_t)target_addr - ((int64_t)CodeCache::low_bound() + sizeof(int));
-    int64_t off_high = (int64_t)target_addr - ((int64_t)CodeCache::high_bound() + sizeof(int));
-    return MAX2(ABS(off_low), ABS(off_high));
-  }
-  return -1;
-C2V_END
-
-C2V_VMENTRY(jobject, getResolvedType, (JNIEnv *env, jobject, jobject javaClass))
-  oop java_mirror = JNIHandles::resolve(javaClass);
-  assert(java_mirror != NULL, "argument to CompilerToVM.getResolvedType must not be NULL");
-  Handle type = GraalCompiler::get_JavaTypeFromClass(java_mirror, CHECK_NULL);
-  return JNIHandles::make_local(THREAD, type());
-C2V_END
-
-
-// helpers used to set fields in the HotSpotVMConfig object
-jfieldID getFieldID(JNIEnv* env, jobject obj, const char* name, const char* sig) {
-  jfieldID id = env->GetFieldID(env->GetObjectClass(obj), name, sig);
-  if (id == NULL) {
-    fatal(err_msg("field not found: %s (%s)", name, sig));
-  }
-  return id;
-}
-
-BasicType basicTypes[] = { T_BOOLEAN, T_BYTE, T_SHORT, T_CHAR, T_INT, T_FLOAT, T_LONG, T_DOUBLE, T_OBJECT };
-int basicTypeCount = sizeof(basicTypes) / sizeof(BasicType);
-
-C2V_ENTRY(void, initializeConfiguration, (JNIEnv *env, jobject, jobject config))
-
-#define set_boolean(name, value) do { env->SetBooleanField(config, getFieldID(env, config, name, "Z"), value); } while (0)
-#define set_int(name, value) do { env->SetIntField(config, getFieldID(env, config, name, "I"), value); } while (0)
-#define set_long(name, value) do { env->SetLongField(config, getFieldID(env, config, name, "J"), value); } while (0)
-#define set_object(name, value) do { env->SetObjectField(config, getFieldID(env, config, name, "Ljava/lang/Object;"), value); } while (0)
-#define set_int_array(name, value) do { env->SetObjectField(config, getFieldID(env, config, name, "[I"), value); } while (0)
-
-  guarantee(HeapWordSize == sizeof(char*), "Graal assumption that HeadWordSize == machine word size is wrong");
-#ifdef _WIN64
-  set_boolean(env, config, "windowsOs", true);
-#else
-  set_boolean("windowsOs", false);
-#endif
-  set_boolean("verifyOops", VerifyOops);
-  set_boolean("useFastLocking", UseFastLocking);
-  set_boolean("useFastNewObjectArray", UseFastNewObjectArray);
-  set_boolean("useBiasedLocking", UseBiasedLocking);
-  set_boolean("useFastNewTypeArray", UseFastNewTypeArray);
-  set_boolean("useTLAB", UseTLAB);
-  set_int("codeEntryAlignment", CodeEntryAlignment);
-  set_int("vmPageSize", os::vm_page_size());
-  set_int("stackShadowPages", StackShadowPages);
-  set_int("hubOffset", oopDesc::klass_offset_in_bytes());
-  set_int("markOffset", oopDesc::mark_offset_in_bytes());
-  set_int("prototypeMarkWordOffset", in_bytes(Klass::prototype_header_offset()));
-  set_int("superCheckOffsetOffset", in_bytes(Klass::super_check_offset_offset()));
-  set_int("secondarySuperCacheOffset", in_bytes(Klass::secondary_super_cache_offset()));
-  set_int("secondarySupersOffset", in_bytes(Klass::secondary_supers_offset()));
-  set_int("subklassOffset", in_bytes(Klass::subklass_offset()));
-  set_int("nextSiblingOffset", in_bytes(Klass::next_sibling_offset()));
-  set_int("arrayLengthOffset", arrayOopDesc::length_offset_in_bytes());
-  set_int("klassStateOffset", in_bytes(InstanceKlass::init_state_offset()));
-  set_int("klassStateFullyInitialized", (int)InstanceKlass::fully_initialized);
-  set_int("threadTlabTopOffset", in_bytes(JavaThread::tlab_top_offset()));
-  set_int("threadTlabEndOffset", in_bytes(JavaThread::tlab_end_offset()));
-  set_int("threadObjectOffset", in_bytes(JavaThread::threadObj_offset()));
-  set_int("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("metaspaceArrayLengthOffset", Array<Klass*>::length_offset_in_bytes());
-  set_int("metaspaceArrayBaseOffset", Array<Klass*>::base_offset_in_bytes());
-  set_int("methodDataOopDataOffset", in_bytes(MethodData::data_offset()));
-  set_int("methodDataOopTrapHistoryOffset", in_bytes(MethodData::trap_history_offset()));
-  set_int("dataLayoutHeaderSize", DataLayout::header_size_in_bytes());
-  set_int("dataLayoutTagOffset", in_bytes(DataLayout::tag_offset()));
-  set_int("dataLayoutFlagsOffset", in_bytes(DataLayout::flags_offset()));
-  set_int("dataLayoutBCIOffset", in_bytes(DataLayout::bci_offset()));
-  set_int("dataLayoutCellsOffset", in_bytes(DataLayout::cell_offset(0)));
-  set_int("dataLayoutCellSize", DataLayout::cell_size);
-  set_int("bciProfileWidth", BciProfileWidth);
-  set_int("typeProfileWidth", TypeProfileWidth);
-
-  set_int("tlabAlignmentReserve", (int32_t)ThreadLocalAllocBuffer::alignment_reserve());
-  set_long("tlabIntArrayMarkWord", (intptr_t)markOopDesc::prototype()->copy_set_hash(0x2));
-  set_long("heapTopAddress", (jlong)(address) Universe::heap()->top_addr());
-  set_long("heapEndAddress", (jlong)(address) Universe::heap()->end_addr());
-  set_int("threadTlabStartOffset", in_bytes(JavaThread::tlab_start_offset()));
-  set_int("threadTlabSizeOffset", in_bytes(JavaThread::tlab_size_offset()));
-  set_int("threadAllocatedBytesOffset", in_bytes(JavaThread::allocated_bytes_offset()));
-  set_int("tlabSlowAllocationsOffset", in_bytes(JavaThread::tlab_slow_allocations_offset()));
-  set_int("tlabFastRefillWasteOffset", in_bytes(JavaThread::tlab_fast_refill_waste_offset()));
-  set_int("tlabNumberOfRefillsOffset", in_bytes(JavaThread::tlab_number_of_refills_offset()));
-  set_int("tlabRefillWasteLimitOffset", in_bytes(JavaThread::tlab_refill_waste_limit_offset()));
-  set_int("tlabRefillWasteIncrement", (int32_t) ThreadLocalAllocBuffer::refill_waste_limit_increment());
-  set_int("klassInstanceSizeOffset", in_bytes(Klass::layout_helper_offset()));
-  set_boolean("tlabStats", TLABStats);
-  set_boolean("inlineContiguousAllocationSupported", !CMSIncrementalMode && Universe::heap()->supports_inline_contig_alloc());
-
-  set_long("arrayPrototypeMarkWord", (intptr_t)markOopDesc::prototype());
-  set_int("layoutHelperLog2ElementSizeShift", Klass::_lh_log2_element_size_shift);
-  set_int("layoutHelperLog2ElementSizeMask", Klass::_lh_log2_element_size_mask);
-  set_int("layoutHelperElementTypeShift", Klass::_lh_element_type_shift);
-  set_int("layoutHelperElementTypeMask", Klass::_lh_element_type_mask);
-  set_int("layoutHelperHeaderSizeShift", Klass::_lh_header_size_shift);
-  set_int("layoutHelperHeaderSizeMask", Klass::_lh_header_size_mask);
-  set_int("layoutHelperOffset", in_bytes(Klass::layout_helper_offset()));
-
-  set_long("debugStub", VmIds::addStub((address)warning));
-  set_long("instanceofStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_slow_subtype_check_id)));
-  set_long("newInstanceStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_new_instance_id)));
-  set_long("newArrayStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_new_array_id)));
-  set_long("newMultiArrayStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_new_multi_array_id)));
-  set_long("inlineCacheMissStub", VmIds::addStub(SharedRuntime::get_ic_miss_stub()));
-  set_long("handleExceptionStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_handle_exception_nofpu_id)));
-  set_long("handleDeoptStub", VmIds::addStub(SharedRuntime::deopt_blob()->unpack()));
-  set_long("monitorEnterStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_monitorenter_id)));
-  set_long("monitorExitStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_monitorexit_id)));
-  set_long("verifyOopStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_verify_oop_id)));
-  set_long("vmErrorStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_vm_error_id)));
-  set_long("deoptimizeStub", VmIds::addStub(SharedRuntime::deopt_blob()->uncommon_trap()));
-  set_long("unwindExceptionStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_unwind_exception_call_id)));
-  set_long("osrMigrationEndStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_OSR_migration_end_id)));
-  set_long("registerFinalizerStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_register_finalizer_id)));
-  set_long("setDeoptInfoStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_set_deopt_info_id)));
-  set_long("createNullPointerExceptionStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_create_null_pointer_exception_id)));
-  set_long("createOutOfBoundsExceptionStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_create_out_of_bounds_exception_id)));
-  set_long("javaTimeMillisStub", VmIds::addStub(CAST_FROM_FN_PTR(address, os::javaTimeMillis)));
-  set_long("javaTimeNanosStub", VmIds::addStub(CAST_FROM_FN_PTR(address, os::javaTimeNanos)));
-  set_long("arithmeticFremStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_arithmetic_frem_id)));
-  set_long("arithmeticDremStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_arithmetic_drem_id)));
-  set_long("arithmeticSinStub", VmIds::addStub(CAST_FROM_FN_PTR(address, SharedRuntime::dsin)));
-  set_long("arithmeticCosStub", VmIds::addStub(CAST_FROM_FN_PTR(address, SharedRuntime::dcos)));
-  set_long("arithmeticTanStub", VmIds::addStub(CAST_FROM_FN_PTR(address, SharedRuntime::dtan)));
-  set_long("logPrimitiveStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_log_primitive_id)));
-  set_long("logObjectStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_log_object_id)));
-  set_long("logPrintfStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_log_printf_id)));
-
-
-  BarrierSet* bs = Universe::heap()->barrier_set();
-  switch (bs->kind()) {
-    case BarrierSet::CardTableModRef:
-    case BarrierSet::CardTableExtension: {
-      jlong base = (jlong)((CardTableModRefBS*)bs)->byte_map_base;
-      assert(base != 0, "unexpected byte_map_base");
-      set_long("cardtableStartAddress", base);
-      set_int("cardtableShift", CardTableModRefBS::card_shift);
-      break;
-    }
-    case BarrierSet::ModRef:
-    case BarrierSet::Other:
-      set_long("cardtableStartAddress", 0);
-      set_int("cardtableShift", 0);
-      // No post barriers
-      break;
-#ifndef SERIALGC
-    case BarrierSet::G1SATBCT:
-    case BarrierSet::G1SATBCTLogging:
-#endif // SERIALGC
-    default:
-      ShouldNotReachHere();
-      break;
-    }
-
-  set_int("arrayClassElementOffset", in_bytes(ObjArrayKlass::element_klass_offset()));
-
-#undef set_boolean
-#undef set_int
-#undef set_long
-#undef set_object
-#undef set_int_array
-
-C2V_END
-
-C2V_VMENTRY(jint, installCode0, (JNIEnv *jniEnv, jobject, jobject compResult, jobject installed_code, jobject info))
-  ResourceMark rm;
-  HandleMark hm;
-  Handle compResultHandle = JNIHandles::resolve(compResult);
-  nmethod* nm = NULL;
-  methodHandle method = getMethodFromHotSpotMethod(HotSpotCompilationResult::method(compResult));
-  Handle installed_code_handle = JNIHandles::resolve(installed_code);
-  GraalEnv::CodeInstallResult result;
-  CodeInstaller installer(compResultHandle, method, result, nm, installed_code_handle);
-
-  if (result != GraalEnv::ok) {
-    assert(nm == NULL, "should be");
-  } else {
-    if (info != NULL) {
-      arrayOop codeCopy = oopFactory::new_byteArray(nm->code_size(), CHECK_0);
-      memcpy(codeCopy->base(T_BYTE), nm->code_begin(), nm->code_size());
-      HotSpotCodeInfo::set_code(info, codeCopy);
-      HotSpotCodeInfo::set_start(info, (jlong) nm->code_begin());
-    }
-
-    if (!installed_code_handle.is_null()) {
-      assert(installed_code_handle->is_a(HotSpotInstalledCode::klass()), "wrong type");
-      HotSpotInstalledCode::set_nmethod(installed_code_handle, (jlong) nm);
-      HotSpotInstalledCode::set_method(installed_code_handle, HotSpotCompilationResult::method(compResult));
-      assert(nm == NULL || !installed_code_handle->is_scavengable() || nm->on_scavenge_root_list(), "nm should be scavengable if installed_code is scavengable");
-    }
-  }
-  return result;
-C2V_END
-
-C2V_VMENTRY(jobject, disassembleNative, (JNIEnv *jniEnv, jobject, jbyteArray code, jlong start_address))
-  ResourceMark rm;
-  HandleMark hm;
-
-  stringStream(st);
-  arrayOop code_oop = (arrayOop) JNIHandles::resolve(code);
-  int len = code_oop->length();
-  address begin = (address) code_oop->base(T_BYTE);
-  address end = begin + len;
-  Disassembler::decode(begin, end, &st);
-
-  Handle result = java_lang_String::create_from_platform_dependent_str(st.as_string(), CHECK_NULL);
-  return JNIHandles::make_local(result());
-C2V_END
-
-C2V_VMENTRY(jobject, getStackTraceElement, (JNIEnv *env, jobject, jlong metaspace_method, int bci))
-  ResourceMark rm;
-  HandleMark hm;
-
-  methodHandle method = asMethod(metaspace_method);
-  oop element = java_lang_StackTraceElement::create(method, bci, CHECK_NULL);
-  return JNIHandles::make_local(element);
-C2V_END
-
-C2V_VMENTRY(jobject, executeCompiledMethodVarargs, (JNIEnv *env, jobject, jlong metaspace_method, jlong metaspace_nmethod, jobject args))
-  ResourceMark rm;
-  HandleMark hm;
-
-  assert(metaspace_method != 0, "just checking");
-  methodHandle mh = asMethod(metaspace_method);
-  Symbol* signature = mh->signature();
-  JavaCallArguments jca;
-
-  JavaArgumentUnboxer jap(signature, &jca, (arrayOop) JNIHandles::resolve(args), mh->is_static());
-  JavaValue result(jap.get_ret_type());
-
-  nmethod* nm = (nmethod*) (address) metaspace_nmethod;
-  if (nm == NULL || !nm->is_alive()) {
-    THROW_0(vmSymbols::MethodInvalidatedException());
-  }
-
-  JavaCalls::call(&result, mh, nm, &jca, CHECK_NULL);
-
-  if (jap.get_ret_type() == T_VOID) {
-    return NULL;
-  } else if (jap.get_ret_type() == T_OBJECT || jap.get_ret_type() == T_ARRAY) {
-    return JNIHandles::make_local((oop) result.get_jobject());
-  } else {
-    oop o = java_lang_boxing_object::create(jap.get_ret_type(), (jvalue *) result.get_value_addr(), CHECK_NULL);
-    return JNIHandles::make_local(o);
-  }
-C2V_END
-
-C2V_VMENTRY(jobject, executeCompiledMethod, (JNIEnv *env, jobject, jlong metaspace_method, jlong metaspace_nmethod, jobject arg1, jobject arg2, jobject arg3))
-  ResourceMark rm;
-  HandleMark hm;
-
-  methodHandle method = asMethod(metaspace_method);
-  assert(!method.is_null(), "just checking");
-  JavaValue result(T_OBJECT);
-  JavaCallArguments args;
-  args.push_oop(JNIHandles::resolve(arg1));
-  args.push_oop(JNIHandles::resolve(arg2));
-  args.push_oop(JNIHandles::resolve(arg3));
-
-  nmethod* nm = (nmethod*) (address) metaspace_nmethod;
-  if (nm == NULL || !nm->is_alive()) {
-    THROW_0(vmSymbols::MethodInvalidatedException());
-  }
-
-  JavaCalls::call(&result, method, nm, &args, CHECK_NULL);
-
-  return JNIHandles::make_local((oop) result.get_jobject());
-C2V_END
-
-C2V_VMENTRY(jint, getVtableEntryOffset, (JNIEnv *, jobject, jlong metaspace_method))
-
-  Method* method = asMethod(metaspace_method);
-  assert(!InstanceKlass::cast(method->method_holder())->is_interface(), "vtableEntryOffset cannot be called for interface methods");
-  assert(InstanceKlass::cast(method->method_holder())->is_linked(), "vtableEntryOffset cannot be called is holder is not linked");
-
-  // get entry offset in words
-  int vtable_entry_offset = InstanceKlass::vtable_start_offset() + method->vtable_index() * vtableEntry::size();
-  // convert to bytes
-  vtable_entry_offset = vtable_entry_offset * wordSize + vtableEntry::method_offset_in_bytes();
-
-  return vtable_entry_offset;
-C2V_END
-
-C2V_VMENTRY(jobject, getDeoptedLeafGraphIds, (JNIEnv *, jobject))
-
-  // the contract for this method is as follows:
-  // returning null: no deopted leaf graphs
-  // returning array (size > 0): the ids of the deopted leaf graphs
-  // returning array (size == 0): there was an overflow, the compiler needs to clear its cache completely
-
-  oop array = GraalCompiler::instance()->dump_deopted_leaf_graphs(CHECK_NULL);
-  return JNIHandles::make_local(array);
-C2V_END
-
-C2V_VMENTRY(jobject, decodePC, (JNIEnv *, jobject, jlong pc))
-  stringStream(st);
-  CodeBlob* blob = CodeCache::find_blob_unsafe((void*) pc);
-  if (blob == NULL) {
-    st.print("[unidentified pc]");
-  } else {
-    st.print(blob->name());
-
-    nmethod* nm = blob->as_nmethod_or_null();
-    if (nm != NULL && nm->method() != NULL) {
-      st.print(" %s.", nm->method()->method_holder()->external_name());
-      nm->method()->name()->print_symbol_on(&st);
-      st.print("  @ %d", pc - (jlong) nm->entry_point());
-    }
-  }
-  Handle result = java_lang_String::create_from_platform_dependent_str(st.as_string(), CHECK_NULL);
-  return JNIHandles::make_local(result());
-C2V_END
-
-
-#define CC (char*)  /*cast a literal from (const char*)*/
-#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f))
-
-#define RESOLVED_TYPE         "Lcom/oracle/graal/api/meta/ResolvedJavaType;"
-#define TYPE                  "Lcom/oracle/graal/api/meta/JavaType;"
-#define METHOD                "Lcom/oracle/graal/api/meta/JavaMethod;"
-#define FIELD                 "Lcom/oracle/graal/api/meta/JavaField;"
-#define SIGNATURE             "Lcom/oracle/graal/api/meta/Signature;"
-#define CONSTANT_POOL         "Lcom/oracle/graal/api/meta/ConstantPool;"
-#define CONSTANT              "Lcom/oracle/graal/api/meta/Constant;"
-#define KIND                  "Lcom/oracle/graal/api/meta/Kind;"
-#define RUNTIME_CALL          "Lcom/oracle/graal/api/code/RuntimeCall;"
-#define EXCEPTION_HANDLERS    "[Lcom/oracle/graal/api/meta/ExceptionHandler;"
-#define REFLECT_METHOD        "Ljava/lang/reflect/Method;"
-#define REFLECT_CONSTRUCTOR   "Ljava/lang/reflect/Constructor;"
-#define REFLECT_FIELD         "Ljava/lang/reflect/Field;"
-#define STRING                "Ljava/lang/String;"
-#define OBJECT                "Ljava/lang/Object;"
-#define CLASS                 "Ljava/lang/Class;"
-#define STACK_TRACE_ELEMENT   "Ljava/lang/StackTraceElement;"
-#define HS_RESOLVED_TYPE      "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedObjectType;"
-#define HS_RESOLVED_METHOD    "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;"
-#define HS_RESOLVED_FIELD     "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaField;"
-#define HS_COMP_RESULT        "Lcom/oracle/graal/hotspot/HotSpotCompilationResult;"
-#define HS_CONFIG             "Lcom/oracle/graal/hotspot/HotSpotVMConfig;"
-#define HS_METHOD             "Lcom/oracle/graal/hotspot/meta/HotSpotMethod;"
-#define HS_INSTALLED_CODE     "Lcom/oracle/graal/hotspot/meta/HotSpotInstalledCode;"
-#define HS_CODE_INFO          "Lcom/oracle/graal/hotspot/meta/HotSpotCodeInfo;"
-#define METHOD_DATA           "Lcom/oracle/graal/hotspot/meta/HotSpotMethodData;"
-#define METASPACE_METHOD      "J"
-#define METASPACE_METHOD_DATA "J"
-#define NMETHOD               "J"
-
-JNINativeMethod CompilerToVM_methods[] = {
-  {CC"initializeBytecode",            CC"("METASPACE_METHOD"[B)[B",                                     FN_PTR(initializeBytecode)},
-  {CC"getSignature",                  CC"("METASPACE_METHOD")"STRING,                                   FN_PTR(getSignature)},
-  {CC"initializeExceptionHandlers",   CC"("METASPACE_METHOD EXCEPTION_HANDLERS")"EXCEPTION_HANDLERS,    FN_PTR(initializeExceptionHandlers)},
-  {CC"hasBalancedMonitors",           CC"("METASPACE_METHOD")Z",                                        FN_PTR(hasBalancedMonitors)},
-  {CC"getUniqueConcreteMethod",       CC"("METASPACE_METHOD"["HS_RESOLVED_TYPE")"METASPACE_METHOD,      FN_PTR(getUniqueConcreteMethod)},
-  {CC"getStackTraceElement",          CC"("METASPACE_METHOD"I)"STACK_TRACE_ELEMENT,                     FN_PTR(getStackTraceElement)},
-  {CC"initializeMethod",              CC"("METASPACE_METHOD HS_RESOLVED_METHOD")V",                     FN_PTR(initializeMethod)},
-  {CC"initializeMethodData",          CC"("METASPACE_METHOD_DATA METHOD_DATA")V",                       FN_PTR(initializeMethodData)},
-  {CC"isMethodCompilable",            CC"("METASPACE_METHOD")Z",                                        FN_PTR(isMethodCompilable)},
-  {CC"getInvocationCount",            CC"("METASPACE_METHOD")I",                                        FN_PTR(getInvocationCount)},
-  {CC"getCompiledCodeSize",           CC"("METASPACE_METHOD")I",                                        FN_PTR(getCompiledCodeSize)},
-  {CC"getVtableEntryOffset",          CC"("METASPACE_METHOD")I",                                        FN_PTR(getVtableEntryOffset)},
-  {CC"lookupType",                    CC"("STRING HS_RESOLVED_TYPE"Z)"TYPE,                             FN_PTR(lookupType)},
-  {CC"lookupConstantInPool",          CC"("HS_RESOLVED_TYPE"I)"OBJECT,                                  FN_PTR(lookupConstantInPool)},
-  {CC"lookupMethodInPool",            CC"("HS_RESOLVED_TYPE"IB)"METHOD,                                 FN_PTR(lookupMethodInPool)},
-  {CC"lookupTypeInPool",              CC"("HS_RESOLVED_TYPE"I)"TYPE,                                    FN_PTR(lookupTypeInPool)},
-  {CC"lookupReferencedTypeInPool",    CC"("HS_RESOLVED_TYPE"IB)V",                                      FN_PTR(lookupReferencedTypeInPool)},
-  {CC"lookupFieldInPool",             CC"("HS_RESOLVED_TYPE"IB)"FIELD,                                  FN_PTR(lookupFieldInPool)},
-  {CC"resolveMethod",                 CC"("HS_RESOLVED_TYPE STRING STRING")"METHOD,                     FN_PTR(resolveMethod)},
-  {CC"getInstanceFields",             CC"("HS_RESOLVED_TYPE")["HS_RESOLVED_FIELD,                       FN_PTR(getInstanceFields)},
-  {CC"isTypeInitialized",             CC"("HS_RESOLVED_TYPE")Z",                                        FN_PTR(isTypeInitialized)},
-  {CC"initializeType",                CC"("HS_RESOLVED_TYPE")V",                                        FN_PTR(initializeType)},
-  {CC"getMaxCallTargetOffset",        CC"(J)J",                                                         FN_PTR(getMaxCallTargetOffset)},
-  {CC"getResolvedType",               CC"("CLASS")"RESOLVED_TYPE,                                       FN_PTR(getResolvedType)},
-  {CC"getMetaspaceMethod",            CC"("REFLECT_METHOD"["HS_RESOLVED_TYPE")"METASPACE_METHOD,        FN_PTR(getMetaspaceMethod)},
-  {CC"getMetaspaceConstructor",       CC"("REFLECT_CONSTRUCTOR"["HS_RESOLVED_TYPE")"METASPACE_METHOD,   FN_PTR(getMetaspaceConstructor)},
-  {CC"getJavaField",                  CC"("REFLECT_FIELD")"HS_RESOLVED_FIELD,                           FN_PTR(getJavaField)},
-  {CC"initializeConfiguration",       CC"("HS_CONFIG")V",                                               FN_PTR(initializeConfiguration)},
-  {CC"installCode0",                  CC"("HS_COMP_RESULT HS_INSTALLED_CODE HS_CODE_INFO")I",           FN_PTR(installCode0)},
-  {CC"disassembleNative",             CC"([BJ)"STRING,                                                  FN_PTR(disassembleNative)},
-  {CC"executeCompiledMethod",         CC"("METASPACE_METHOD NMETHOD OBJECT OBJECT OBJECT")"OBJECT,      FN_PTR(executeCompiledMethod)},
-  {CC"executeCompiledMethodVarargs",  CC"("METASPACE_METHOD NMETHOD "["OBJECT")"OBJECT,                 FN_PTR(executeCompiledMethodVarargs)},
-  {CC"getDeoptedLeafGraphIds",        CC"()[J",                                                         FN_PTR(getDeoptedLeafGraphIds)},
-  {CC"decodePC",                      CC"(J)"STRING,                                                    FN_PTR(decodePC)},
-};
-
-int CompilerToVM_methods_count() {
-  return sizeof(CompilerToVM_methods) / sizeof(JNINativeMethod);
-}
-
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+#include "runtime/fieldDescriptor.hpp"
+#include "memory/oopFactory.hpp"
+#include "oops/generateOopMap.hpp"
+#include "oops/fieldStreams.hpp"
+#include "runtime/javaCalls.hpp"
+#include "graal/graalRuntime.hpp"
+#include "compiler/compileBroker.hpp"
+#include "compiler/compilerOracle.hpp"
+#include "graal/graalCompilerToVM.hpp"
+#include "graal/graalCompiler.hpp"
+#include "graal/graalEnv.hpp"
+#include "graal/graalJavaAccess.hpp"
+#include "graal/graalCodeInstaller.hpp"
+#include "graal/graalVMToCompiler.hpp"
+#include "graal/graalVmIds.hpp"
+
+
+Method* getMethodFromHotSpotMethod(oop hotspot_method) {
+  assert(hotspot_method != NULL && hotspot_method->is_a(HotSpotResolvedJavaMethod::klass()), "sanity");
+  return asMethod(HotSpotResolvedJavaMethod::metaspaceMethod(hotspot_method));
+}
+
+// Entry to native method implementation that transitions current thread to '_thread_in_vm'.
+#define C2V_VMENTRY(result_type, name, signature) \
+  JNIEXPORT result_type JNICALL c2v_ ## name signature { \
+  TRACE_graal_3("CompilerToVM::" #name); \
+  GRAAL_VM_ENTRY_MARK; \
+
+// Entry to native method implementation that calls a JNI function
+// and hence cannot transition current thread to '_thread_in_vm'.
+#define C2V_ENTRY(result_type, name, signature) \
+  JNIEXPORT result_type JNICALL c2v_ ## name signature { \
+  TRACE_graal_3("CompilerToVM::" #name); \
+
+#define C2V_END }
+
+C2V_ENTRY(jbyteArray, initializeBytecode, (JNIEnv *env, jobject, jlong metaspace_method, jbyteArray result))
+  methodHandle method = asMethod(metaspace_method);
+  ResourceMark rm;
+  
+  int code_size = method->code_size();
+  jbyte* reconstituted_code = NULL;
+
+  // replace all breakpoints - must be done before undoing any rewriting
+  if (method->number_of_breakpoints() > 0) {
+    reconstituted_code = NEW_RESOURCE_ARRAY(jbyte, code_size);
+    memcpy(reconstituted_code, (jbyte *) method->code_base(), code_size);
+    BreakpointInfo* bp = InstanceKlass::cast(method->method_holder())->breakpoints();
+    for (; bp != NULL; bp = bp->next()) {
+      if (bp->match(method())) {
+        jbyte code = bp->orig_bytecode();
+        reconstituted_code[bp->bci()] = code;
+      }
+    }
+  }
+
+  // iterate over all bytecodes and replace non-Java bytecodes
+  if (RewriteBytecodes || RewriteFrequentPairs || InstanceKlass::cast(method->method_holder())->is_rewritten()) {
+    if (reconstituted_code == NULL) {
+      reconstituted_code = NEW_RESOURCE_ARRAY(jbyte, code_size);
+      memcpy(reconstituted_code, (jbyte *) method->code_base(), code_size);
+    }
+    BytecodeStream s(method);
+    while(!s.is_last_bytecode()) {
+      s.next();
+      Bytecodes::Code opcode = s.raw_code();
+      if (!Bytecodes::is_java_code(opcode)) {
+        jbyte original_opcode = Bytecodes::java_code(opcode);
+        int bci = s.bci();
+        reconstituted_code[bci] = original_opcode;
+        if (opcode == Bytecodes::_fast_aldc_w) {
+          int cpci = Bytes::get_native_u2((address) reconstituted_code + bci + 1);
+          int i = method->constants()->object_to_cp_index(cpci);
+          assert(i < method->constants()->length(), "sanity check");
+          Bytes::put_Java_u2((address) reconstituted_code + bci + 1, (u2)i);
+        } else if (opcode == Bytecodes::_fast_aldc) {
+          int cpci = reconstituted_code[bci + 1] & 0xff;
+          int i = method->constants()->object_to_cp_index(cpci);
+          assert(i < method->constants()->length(), "sanity check");
+          reconstituted_code[bci + 1] = (jbyte)i;
+        }
+      }
+    }
+  }
+
+  if (reconstituted_code == NULL) {
+    env->SetByteArrayRegion(result, 0, code_size, (jbyte *) method->code_base());
+  } else {
+    env->SetByteArrayRegion(result, 0, code_size, reconstituted_code);
+  }
+
+  return result;
+C2V_END
+
+C2V_VMENTRY(jstring, getSignature, (JNIEnv *env, jobject, jlong metaspace_method))
+  Method* method = asMethod(metaspace_method);
+  assert(method != NULL && method->signature() != NULL, "signature required");
+  return VmIds::toString<jstring>(method->signature(), THREAD);
+C2V_END
+
+C2V_VMENTRY(jobjectArray, initializeExceptionHandlers, (JNIEnv *, jobject, jlong metaspace_method, jobjectArray java_handlers))
+  ResourceMark rm;
+  methodHandle method = asMethod(metaspace_method);
+  int handler_count = method->exception_table_length();
+  objArrayHandle array = (objArrayOop) JNIHandles::resolve(java_handlers);
+  assert(array->length() == handler_count, "wrong length");
+  ExceptionTableElement* handlers = handler_count == 0 ? NULL : method->exception_table_start();
+
+  for (int i = 0; i < handler_count; i++) {
+    ExceptionTableElement* handler = handlers + i;
+    Handle entry = array->obj_at(i);
+    assert(!entry.is_null(), "entry should not be null");
+    ExceptionHandler::set_startBCI(entry, handler->start_pc);
+    ExceptionHandler::set_endBCI(entry, handler->end_pc);
+    ExceptionHandler::set_handlerBCI(entry, handler->handler_pc);
+    int catch_class_index = handler->catch_type_index;
+    ExceptionHandler::set_catchTypeCPI(entry, catch_class_index);
+
+    if (catch_class_index == 0) {
+      ExceptionHandler::set_catchType(entry, NULL);
+    } else {
+      ConstantPool* cp = InstanceKlass::cast(method->method_holder())->constants();
+      KlassHandle loading_klass = method->method_holder();
+      Handle catch_class = GraalCompiler::get_JavaType(cp, catch_class_index, loading_klass, CHECK_NULL);
+      if (catch_class->klass() == HotSpotResolvedObjectType::klass() && java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(catch_class)) == SystemDictionary::Throwable_klass()) {
+        ExceptionHandler::set_catchType(entry, NULL);
+        ExceptionHandler::set_catchTypeCPI(entry, 0);
+      } else {
+        ExceptionHandler::set_catchType(entry, catch_class());
+      }
+    }
+    array->obj_at_put(i, entry());
+  }
+
+  return (jobjectArray) JNIHandles::make_local(array());
+C2V_END
+
+C2V_VMENTRY(jint, hasBalancedMonitors, (JNIEnv *, jobject, jlong metaspace_method))
+
+  // Analyze the method to see if monitors are used properly.
+  methodHandle method(THREAD, asMethod(metaspace_method));
+  assert(method->has_monitor_bytecodes(), "should have checked this");
+
+  // Check to see if a previous compilation computed the monitor-matching analysis.
+  if (method->guaranteed_monitor_matching()) {
+    return true;
+  }
+
+  {
+    EXCEPTION_MARK;
+    ResourceMark rm(THREAD);
+    GeneratePairingInfo gpi(method);
+    gpi.compute_map(CATCH);
+    if (!gpi.monitor_safe()) {
+      return false;
+    }
+    method->set_guaranteed_monitor_matching();
+  }
+  return true;
+C2V_END
+
+C2V_VMENTRY(jlong, getMetaspaceMethod, (JNIEnv *, jobject, jobject reflection_method_handle, jobject resultHolder))
+  oop reflection_method = JNIHandles::resolve(reflection_method_handle);
+  oop reflection_holder = java_lang_reflect_Method::clazz(reflection_method);
+  int slot = java_lang_reflect_Method::slot(reflection_method);
+  Klass* holder = java_lang_Class::as_Klass(reflection_holder);
+  methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot);
+  Handle type = GraalCompiler::createHotSpotResolvedObjectType(method, CHECK_0);
+  objArrayOop(JNIHandles::resolve(resultHolder))->obj_at_put(0, type());
+  return (jlong) (address) method();
+}
+
+C2V_VMENTRY(jlong, getMetaspaceConstructor, (JNIEnv *, jobject, jobject reflection_ctor_handle, jobject resultHolder))
+  oop reflection_ctor = JNIHandles::resolve(reflection_ctor_handle);
+  oop reflection_holder = java_lang_reflect_Constructor::clazz(reflection_ctor);
+  int slot = java_lang_reflect_Constructor::slot(reflection_ctor);
+  Klass* holder = java_lang_Class::as_Klass(reflection_holder);
+  methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot);
+  Handle type = GraalCompiler::createHotSpotResolvedObjectType(method, CHECK_0);
+  objArrayOop(JNIHandles::resolve(resultHolder))->obj_at_put(0, type());
+  return (jlong) (address) method();
+}
+
+C2V_VMENTRY(jobject, getJavaField, (JNIEnv *, jobject, jobject reflection_field_handle))
+  oop reflection_field = JNIHandles::resolve(reflection_field_handle);
+  oop reflection_holder = java_lang_reflect_Field::clazz(reflection_field);
+  int slot = java_lang_reflect_Field::slot(reflection_field);
+  InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(reflection_holder));
+
+  int offset = holder->field_offset(slot);
+  int flags = holder->field_access_flags(slot);
+  Symbol* field_name = holder->field_name(slot);
+  Handle field_holder = GraalCompiler::get_JavaTypeFromClass(reflection_holder, CHECK_NULL);
+  Handle field_type = GraalCompiler::get_JavaTypeFromClass(java_lang_reflect_Field::type(reflection_field), CHECK_NULL);
+
+  Handle ret = GraalCompiler::get_JavaField(offset, flags, field_name, field_holder, field_type, CHECK_NULL);
+  return JNIHandles::make_local(THREAD, ret());
+}
+
+C2V_VMENTRY(jlong, getUniqueConcreteMethod, (JNIEnv *, jobject, jlong metaspace_method, jobject resultHolder))
+  methodHandle method = asMethod(metaspace_method);
+  KlassHandle holder = method->method_holder();
+  if (holder->is_interface()) {
+    // Cannot trust interfaces. Because of:
+    // interface I { void foo(); }
+    // class A { public void foo() {} }
+    // class B extends A implements I { }
+    // class C extends B { public void foo() { } }
+    // class D extends B { }
+    // Would lead to identify C.foo() as the unique concrete method for I.foo() without seeing A.foo().
+    return 0L;
+  }
+  methodHandle ucm;
+  {
+    ResourceMark rm;
+    MutexLocker locker(Compile_lock);
+    ucm = Dependencies::find_unique_concrete_method(holder(), method());
+  }
+
+  if (ucm.is_null()) {
+    return 0L;
+  }
+
+  Handle type = GraalCompiler::createHotSpotResolvedObjectType(ucm(), CHECK_0);
+  objArrayOop(JNIHandles::resolve(resultHolder))->obj_at_put(0, type());
+  return (jlong) (address) ucm();
+C2V_END
+
+C2V_ENTRY(jint, getInvocationCount, (JNIEnv *, jobject, jlong metaspace_method))
+  Method* method = asMethod(metaspace_method);
+  return method->invocation_count();
+C2V_END
+
+C2V_VMENTRY(void, initializeMethod,(JNIEnv *, jobject, jlong metaspace_method, jobject hotspot_method))
+  methodHandle method = asMethod(metaspace_method);
+  Handle name = VmIds::toString<Handle>(method->name(), CHECK);
+  InstanceKlass::cast(HotSpotResolvedJavaMethod::klass())->initialize(CHECK);
+  HotSpotResolvedJavaMethod::set_name(hotspot_method, name());
+  HotSpotResolvedJavaMethod::set_codeSize(hotspot_method, method->code_size());
+  HotSpotResolvedJavaMethod::set_exceptionHandlerCount(hotspot_method, method->exception_table_length());
+C2V_END
+
+C2V_VMENTRY(jboolean, isMethodCompilable,(JNIEnv *, jobject, jlong metaspace_method))
+  methodHandle method = asMethod(metaspace_method);
+  return !method->is_not_compilable() && !CompilerOracle::should_not_inline(method);
+C2V_END
+
+C2V_VMENTRY(void, initializeMethodData,(JNIEnv *, jobject, jlong metaspace_method_data, jobject hotspot_method_data))
+  MethodData* method_data = asMethodData(metaspace_method_data);
+  HotSpotMethodData::set_normalDataSize(hotspot_method_data, method_data->data_size());
+  HotSpotMethodData::set_extraDataSize(hotspot_method_data, method_data->extra_data_size());
+C2V_END
+
+// ------------------------------------------------------------------
+// Adjust a CounterData count to be commensurate with
+// interpreter_invocation_count.  If the MDO exists for
+// only 25% of the time the method exists, then the
+// counts in the MDO should be scaled by 4X, so that
+// they can be usefully and stably compared against the
+// invocation counts in methods.
+int scale_count(MethodData* method_data, int count) {
+  if (count > 0) {
+    int counter_life;
+    int method_life = method_data->method()->interpreter_invocation_count();
+    int current_mileage = MethodData::mileage_of(method_data->method());
+    int creation_mileage = method_data->creation_mileage();
+    counter_life = current_mileage - creation_mileage;
+
+    // counter_life due to backedge_counter could be > method_life
+    if (counter_life > method_life)
+      counter_life = method_life;
+    if (0 < counter_life && counter_life <= method_life) {
+      count = (int)((double)count * method_life / counter_life + 0.5);
+      count = (count > 0) ? count : 1;
+    }
+  }
+  return count;
+}
+
+C2V_ENTRY(jint, getCompiledCodeSize, (JNIEnv *env, jobject, jlong metaspace_method))
+  nmethod* code = (asMethod(metaspace_method))->code();
+  return code == NULL ? 0 : code->insts_size();
+C2V_END
+
+C2V_VMENTRY(jobject, lookupType, (JNIEnv *env, jobject, jstring jname, jobject accessingClass, jboolean eagerResolve))
+  ResourceMark rm;
+
+  Symbol* nameSymbol = VmIds::toSymbol(jname);
+  Handle name = JNIHandles::resolve(jname);
+  assert(nameSymbol != NULL, "name to symbol creation failed");
+
+  oop result = NULL;
+  if (nameSymbol == vmSymbols::int_signature()) {
+    result = VMToCompiler::createPrimitiveJavaType((int) T_INT, THREAD);
+  } else if (nameSymbol == vmSymbols::long_signature()) {
+    result = VMToCompiler::createPrimitiveJavaType((int) T_LONG, THREAD);
+  } else if (nameSymbol == vmSymbols::bool_signature()) {
+    result = VMToCompiler::createPrimitiveJavaType((int) T_BOOLEAN, THREAD);
+  } else if (nameSymbol == vmSymbols::char_signature()) {
+    result = VMToCompiler::createPrimitiveJavaType((int) T_CHAR, THREAD);
+  } else if (nameSymbol == vmSymbols::short_signature()) {
+    result = VMToCompiler::createPrimitiveJavaType((int) T_SHORT, THREAD);
+  } else if (nameSymbol == vmSymbols::byte_signature()) {
+    result = VMToCompiler::createPrimitiveJavaType((int) T_BYTE, THREAD);
+  } else if (nameSymbol == vmSymbols::double_signature()) {
+    result = VMToCompiler::createPrimitiveJavaType((int) T_DOUBLE, THREAD);
+  } else if (nameSymbol == vmSymbols::float_signature()) {
+    result = VMToCompiler::createPrimitiveJavaType((int) T_FLOAT, THREAD);
+  } else if (nameSymbol == vmSymbols::void_signature()) {
+    result = VMToCompiler::createPrimitiveJavaType((int) T_VOID, THREAD);
+  } else {
+    Klass* resolved_type = NULL;
+    Handle classloader;
+    Handle protectionDomain;
+    if (JNIHandles::resolve(accessingClass) != NULL) {
+      classloader = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(accessingClass))->class_loader();
+      protectionDomain = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(accessingClass))->protection_domain();
+    }
+
+    if (eagerResolve) {
+      resolved_type = SystemDictionary::resolve_or_fail(nameSymbol, classloader, protectionDomain, true, THREAD);
+    } else {
+      resolved_type = SystemDictionary::resolve_or_null(nameSymbol, classloader, protectionDomain, THREAD);
+    }
+
+    if (!HAS_PENDING_EXCEPTION) {
+      if (resolved_type == NULL) {
+        assert(!eagerResolve, "failed eager resolution should have caused an exception");
+        Handle type = VMToCompiler::createUnresolvedJavaType(name, THREAD);
+        result = type();
+      } else {
+        Handle type = GraalCompiler::createHotSpotResolvedObjectType(resolved_type, name, CHECK_NULL);
+        result = type();
+      }
+    }
+  }
+
+  return JNIHandles::make_local(THREAD, result);
+C2V_END
+
+C2V_VMENTRY(jobject, lookupConstantInPool, (JNIEnv *env, jobject, jobject type, jint index))
+
+  ConstantPool* cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants();
+
+  oop result = NULL;
+  constantTag tag = cp->tag_at(index);
+  if (tag.is_int()) {
+    result = VMToCompiler::createConstant(Kind::Int(), cp->int_at(index), CHECK_0);
+  } else if (tag.is_long()) {
+    result = VMToCompiler::createConstant(Kind::Long(), cp->long_at(index), CHECK_0);
+  } else if (tag.is_float()) {
+    result = VMToCompiler::createConstantFloat(cp->float_at(index), CHECK_0);
+  } else if (tag.is_double()) {
+    result = VMToCompiler::createConstantDouble(cp->double_at(index), CHECK_0);
+  } else if (tag.is_string()) {
+    oop string = NULL;
+    if (cp->is_pseudo_string_at(index)) {
+      int obj_index = cp->cp_to_object_index(index);
+      string = cp->pseudo_string_at(index, obj_index);
+    } else {
+      string = cp->string_at(index, THREAD);
+      if (HAS_PENDING_EXCEPTION) {
+        CLEAR_PENDING_EXCEPTION;
+        // TODO: Gracefully exit compilation.
+        fatal("out of memory during compilation!");
+        return NULL;
+      }
+    }
+    result = VMToCompiler::createConstantObject(string, CHECK_0);
+  } else if (tag.is_klass() || tag.is_unresolved_klass()) {
+    Handle type = GraalCompiler::get_JavaType(cp, index, cp->pool_holder(), CHECK_NULL);
+    result = type();
+  } else if (tag.is_object()) {
+    oop obj = cp->object_at(index);
+    assert(obj->is_instance(), "must be an instance");
+    result = VMToCompiler::createConstantObject(obj, CHECK_NULL);
+  } else {
+    tty->print("unknown constant pool tag (%s) at cpi %d in %s: ", tag.internal_name(), index, cp->pool_holder()->name()->as_C_string());
+    ShouldNotReachHere();
+  }
+
+  return JNIHandles::make_local(THREAD, result);
+C2V_END
+
+C2V_VMENTRY(jobject, lookupMethodInPool, (JNIEnv *env, jobject, jobject type, jint index, jbyte opcode))
+  index = GraalCompiler::to_cp_index_u2(index);
+  constantPoolHandle cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants();
+  instanceKlassHandle pool_holder(cp->pool_holder());
+
+  Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF);
+  methodHandle method = GraalEnv::get_method_by_index(cp, index, bc, pool_holder);
+  if (!method.is_null()) {
+    Handle holder = GraalCompiler::get_JavaType(method->method_holder(), CHECK_NULL);
+    return JNIHandles::make_local(THREAD, VMToCompiler::createResolvedJavaMethod(holder, method(), THREAD));
+  } else {
+    // Get the method's name and signature.
+    Handle name = VmIds::toString<Handle>(cp->name_ref_at(index), CHECK_NULL);
+    Handle signature  = VmIds::toString<Handle>(cp->signature_ref_at(index), CHECK_NULL);
+    int holder_index = cp->klass_ref_index_at(index);
+    Handle type = GraalCompiler::get_JavaType(cp, holder_index, cp->pool_holder(), CHECK_NULL);
+    return JNIHandles::make_local(THREAD, VMToCompiler::createUnresolvedJavaMethod(name, signature, type, THREAD));
+  }
+C2V_END
+
+C2V_VMENTRY(jobject, lookupTypeInPool, (JNIEnv *env, jobject, jobject type, jint index))
+
+  ConstantPool* cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants();
+  Handle result = GraalCompiler::get_JavaType(cp, index, cp->pool_holder(), CHECK_NULL);
+  return JNIHandles::make_local(THREAD, result());
+C2V_END
+
+C2V_VMENTRY(void, lookupReferencedTypeInPool, (JNIEnv *env, jobject, jobject type, jint index, jbyte op))
+  ConstantPool* cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants();
+  int opcode = (op & 0xFF);
+  if (opcode != Bytecodes::_checkcast && opcode != Bytecodes::_instanceof && opcode != Bytecodes::_new && opcode != Bytecodes::_anewarray
+      && opcode != Bytecodes::_multianewarray && opcode != Bytecodes::_ldc && opcode != Bytecodes::_ldc_w && opcode != Bytecodes::_ldc2_w)
+  {
+    index = cp->remap_instruction_operand_from_cache(GraalCompiler::to_cp_index_u2(index));
+  }
+  constantTag tag = cp->tag_at(index);
+  if (tag.is_field_or_method()) {
+    index = cp->uncached_klass_ref_index_at(index);
+    tag = cp->tag_at(index);
+  }
+
+  if (tag.is_unresolved_klass() || tag.is_klass()) {
+    Klass* klass = cp->klass_at(index, CHECK);
+    if (klass->oop_is_instance()) {
+      InstanceKlass::cast(klass)->initialize(CHECK);
+    }
+  }
+C2V_END
+
+C2V_VMENTRY(jobject, lookupFieldInPool, (JNIEnv *env, jobject, jobject constantPoolHolder, jint index, jbyte opcode))
+  ResourceMark rm;
+
+  index = GraalCompiler::to_cp_index_u2(index);
+  constantPoolHandle cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(constantPoolHolder)))->constants();
+
+  int nt_index = cp->name_and_type_ref_index_at(index);
+  int sig_index = cp->signature_ref_index_at(nt_index);
+  Symbol* signature = cp->symbol_at(sig_index);
+  int name_index = cp->name_ref_index_at(nt_index);
+  Symbol* name = cp->symbol_at(name_index);
+  int holder_index = cp->klass_ref_index_at(index);
+  Handle holder = GraalCompiler::get_JavaType(cp, holder_index, cp->pool_holder(), CHECK_NULL);
+  instanceKlassHandle holder_klass;
+  
+  Bytecodes::Code code = (Bytecodes::Code)(((int) opcode) & 0xFF);
+  int offset = -1;
+  AccessFlags flags;
+  BasicType basic_type;
+  if (holder->klass() == SystemDictionary::HotSpotResolvedObjectType_klass()) {
+    FieldAccessInfo result;
+    LinkResolver::resolve_field(result, cp, index,
+                                Bytecodes::java_code(code),
+                                true, false, Thread::current());
+    if (HAS_PENDING_EXCEPTION) {
+      CLEAR_PENDING_EXCEPTION;
+    } else {
+      offset = result.field_offset();
+      flags = result.access_flags();
+      holder_klass = result.klass()();
+      basic_type = result.field_type();
+      holder = GraalCompiler::get_JavaType(holder_klass, CHECK_NULL);
+    }
+  }
+  
+  Handle type = GraalCompiler::get_JavaTypeFromSignature(signature, cp->pool_holder(), CHECK_NULL);
+  Handle field_handle = GraalCompiler::get_JavaField(offset, flags.as_int(), name, holder, type, THREAD);
+
+  return JNIHandles::make_local(THREAD, field_handle());
+C2V_END
+
+C2V_VMENTRY(jobject, resolveMethod, (JNIEnv *, jobject, jobject resolved_type, jstring name, jstring signature))
+
+  assert(JNIHandles::resolve(resolved_type) != NULL, "");
+  Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(resolved_type));
+  Symbol* name_symbol = VmIds::toSymbol(name);
+  Symbol* signature_symbol = VmIds::toSymbol(signature);
+  methodHandle method = klass->lookup_method(name_symbol, signature_symbol);
+  if (method.is_null()) {
+    if (TraceGraal >= 3) {
+      ResourceMark rm;
+      tty->print_cr("Could not resolve method %s %s on klass %s", name_symbol->as_C_string(), signature_symbol->as_C_string(), klass->name()->as_C_string());
+    }
+    return NULL;
+  }
+  Handle holder = GraalCompiler::get_JavaType(method->method_holder(), CHECK_NULL);
+  return JNIHandles::make_local(THREAD, VMToCompiler::createResolvedJavaMethod(holder, method(), THREAD));
+C2V_END
+
+C2V_VMENTRY(jboolean, isTypeInitialized,(JNIEnv *, jobject, jobject hotspot_klass))
+  Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(hotspot_klass));
+  assert(klass != NULL, "method must not be called for primitive types");
+  return InstanceKlass::cast(klass)->is_initialized();
+C2V_END
+
+C2V_VMENTRY(void, initializeType, (JNIEnv *, jobject, jobject hotspot_klass))
+  Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(hotspot_klass));
+  assert(klass != NULL, "method must not be called for primitive types");
+  InstanceKlass::cast(klass)->initialize(JavaThread::current());
+C2V_END
+
+C2V_VMENTRY(jobject, getInstanceFields, (JNIEnv *, jobject, jobject klass))
+  ResourceMark rm;
+
+  instanceKlassHandle k = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(klass));
+  GrowableArray<Handle> fields(k->java_fields_count());
+
+  for (AllFieldStream fs(k()); !fs.done(); fs.next()) {
+    if (!fs.access_flags().is_static()) {
+      Handle type = GraalCompiler::get_JavaTypeFromSignature(fs.signature(), k, Thread::current());
+      int flags = fs.access_flags().as_int();
+      bool internal = fs.access_flags().is_internal();
+      Handle name = VmIds::toString<Handle>(fs.name(), Thread::current());
+      Handle field = VMToCompiler::createJavaField(JNIHandles::resolve(klass), name, type, fs.offset(), flags, internal, Thread::current());
+      fields.append(field());
+    }
+  }
+  objArrayHandle field_array = oopFactory::new_objArray(SystemDictionary::HotSpotResolvedJavaField_klass(), fields.length(), CHECK_NULL);
+  for (int i = 0; i < fields.length(); ++i) {
+    field_array->obj_at_put(i, fields.at(i)());
+  }
+  return JNIHandles::make_local(field_array());
+C2V_END
+
+C2V_VMENTRY(jlong, getMaxCallTargetOffset, (JNIEnv *env, jobject, jlong stub))
+  address target_addr = (address) stub;
+  if (target_addr != 0x0) {
+    int64_t off_low = (int64_t)target_addr - ((int64_t)CodeCache::low_bound() + sizeof(int));
+    int64_t off_high = (int64_t)target_addr - ((int64_t)CodeCache::high_bound() + sizeof(int));
+    return MAX2(ABS(off_low), ABS(off_high));
+  }
+  return -1;
+C2V_END
+
+C2V_VMENTRY(jobject, getResolvedType, (JNIEnv *env, jobject, jobject javaClass))
+  oop java_mirror = JNIHandles::resolve(javaClass);
+  assert(java_mirror != NULL, "argument to CompilerToVM.getResolvedType must not be NULL");
+  Handle type = GraalCompiler::get_JavaTypeFromClass(java_mirror, CHECK_NULL);
+  return JNIHandles::make_local(THREAD, type());
+C2V_END
+
+
+// helpers used to set fields in the HotSpotVMConfig object
+jfieldID getFieldID(JNIEnv* env, jobject obj, const char* name, const char* sig) {
+  jfieldID id = env->GetFieldID(env->GetObjectClass(obj), name, sig);
+  if (id == NULL) {
+    fatal(err_msg("field not found: %s (%s)", name, sig));
+  }
+  return id;
+}
+
+BasicType basicTypes[] = { T_BOOLEAN, T_BYTE, T_SHORT, T_CHAR, T_INT, T_FLOAT, T_LONG, T_DOUBLE, T_OBJECT };
+int basicTypeCount = sizeof(basicTypes) / sizeof(BasicType);
+
+C2V_ENTRY(void, initializeConfiguration, (JNIEnv *env, jobject, jobject config))
+
+#define set_boolean(name, value) do { env->SetBooleanField(config, getFieldID(env, config, name, "Z"), value); } while (0)
+#define set_int(name, value) do { env->SetIntField(config, getFieldID(env, config, name, "I"), value); } while (0)
+#define set_long(name, value) do { env->SetLongField(config, getFieldID(env, config, name, "J"), value); } while (0)
+#define set_object(name, value) do { env->SetObjectField(config, getFieldID(env, config, name, "Ljava/lang/Object;"), value); } while (0)
+#define set_int_array(name, value) do { env->SetObjectField(config, getFieldID(env, config, name, "[I"), value); } while (0)
+
+  guarantee(HeapWordSize == sizeof(char*), "Graal assumption that HeadWordSize == machine word size is wrong");
+#ifdef _WIN64
+  set_boolean(env, config, "windowsOs", true);
+#else
+  set_boolean("windowsOs", false);
+#endif
+  set_boolean("verifyOops", VerifyOops);
+  set_boolean("useFastLocking", UseFastLocking);
+  set_boolean("useFastNewObjectArray", UseFastNewObjectArray);
+  set_boolean("useBiasedLocking", UseBiasedLocking);
+  set_boolean("useFastNewTypeArray", UseFastNewTypeArray);
+  set_boolean("useTLAB", UseTLAB);
+  set_int("codeEntryAlignment", CodeEntryAlignment);
+  set_int("vmPageSize", os::vm_page_size());
+  set_int("stackShadowPages", StackShadowPages);
+  set_int("hubOffset", oopDesc::klass_offset_in_bytes());
+  set_int("markOffset", oopDesc::mark_offset_in_bytes());
+  set_int("prototypeMarkWordOffset", in_bytes(Klass::prototype_header_offset()));
+  set_int("superCheckOffsetOffset", in_bytes(Klass::super_check_offset_offset()));
+  set_int("secondarySuperCacheOffset", in_bytes(Klass::secondary_super_cache_offset()));
+  set_int("secondarySupersOffset", in_bytes(Klass::secondary_supers_offset()));
+  set_int("subklassOffset", in_bytes(Klass::subklass_offset()));
+  set_int("nextSiblingOffset", in_bytes(Klass::next_sibling_offset()));
+  set_int("arrayLengthOffset", arrayOopDesc::length_offset_in_bytes());
+  set_int("klassStateOffset", in_bytes(InstanceKlass::init_state_offset()));
+  set_int("klassStateFullyInitialized", (int)InstanceKlass::fully_initialized);
+  set_int("threadTlabTopOffset", in_bytes(JavaThread::tlab_top_offset()));
+  set_int("threadTlabEndOffset", in_bytes(JavaThread::tlab_end_offset()));
+  set_int("threadObjectOffset", in_bytes(JavaThread::threadObj_offset()));
+  set_int("osThreadOffset", in_bytes(JavaThread::osthread_offset()));
+  set_int("osThreadInterruptedOffset", in_bytes(OSThread::interrupted_offset()));
+  set_int("unlockedMask", (int) markOopDesc::unlocked_value);
+  set_int("biasedLockMaskInPlace", (int) markOopDesc::biased_lock_mask_in_place);
+  set_int("ageMaskInPlace", (int) markOopDesc::age_mask_in_place);
+  set_int("epochMaskInPlace", (int) markOopDesc::epoch_mask_in_place);
+  set_int("biasedLockPattern", (int) markOopDesc::biased_lock_pattern);
+  set_int("methodMaxLocalsOffset", in_bytes(Method::size_of_locals_offset()));
+  set_int("methodMaxStackOffset", in_bytes(Method::max_stack_offset()));
+  set_int("extraStackEntries", Method::extra_stack_entries());
+  set_int("methodAccessFlagsOffset", in_bytes(Method::access_flags_offset()));
+  set_int("klassHasFinalizerFlag", JVM_ACC_HAS_FINALIZER);
+  set_int("threadExceptionOopOffset", in_bytes(JavaThread::exception_oop_offset()));
+  set_int("threadExceptionPcOffset", in_bytes(JavaThread::exception_pc_offset()));
+  set_long("safepointPollingAddress", (jlong)(os::get_polling_page() + (SafepointPollOffset % os::vm_page_size())));
+  set_boolean("isPollingPageFar", Assembler::is_polling_page_far());
+  set_int("classMirrorOffset", in_bytes(Klass::java_mirror_offset()));
+  set_int("runtimeCallStackSize", (jint)frame::arg_reg_save_area_bytes);
+  set_int("klassModifierFlagsOffset", in_bytes(Klass::modifier_flags_offset()));
+  set_int("klassAccessFlagsOffset", in_bytes(Klass::access_flags_offset()));
+  set_int("klassOffset", java_lang_Class::klass_offset_in_bytes());
+  set_int("graalMirrorInClassOffset", java_lang_Class::graal_mirror_offset_in_bytes());
+  set_int("klassLayoutHelperOffset", in_bytes(Klass::layout_helper_offset()));
+  set_int("klassSuperKlassOffset", in_bytes(Klass::super_offset()));
+  set_int("methodDataOffset", in_bytes(Method::method_data_offset()));
+  set_int("nmethodEntryOffset", nmethod::verified_entry_point_offset());
+  set_int("methodCompiledEntryOffset", in_bytes(Method::from_compiled_offset()));
+  set_int("basicLockSize", sizeof(BasicLock));
+  set_int("basicLockDisplacedHeaderOffset", BasicLock::displaced_header_offset_in_bytes());
+  set_int("uninitializedIdentityHashCodeValue", markOopDesc::no_hash);
+  set_int("identityHashCodeShift", markOopDesc::hash_shift);
+
+  set_int("arrayKlassLayoutHelperIdentifier", 0x80000000);
+  assert((Klass::_lh_array_tag_obj_value & Klass::_lh_array_tag_type_value & 0x80000000) != 0, "obj_array and type_array must have first bit set");
+  set_int("arrayKlassComponentMirrorOffset", in_bytes(ArrayKlass::component_mirror_offset()));
+  
+  set_int("metaspaceArrayLengthOffset", Array<Klass*>::length_offset_in_bytes());
+  set_int("metaspaceArrayBaseOffset", Array<Klass*>::base_offset_in_bytes());
+  set_int("methodDataOopDataOffset", in_bytes(MethodData::data_offset()));
+  set_int("methodDataOopTrapHistoryOffset", in_bytes(MethodData::trap_history_offset()));
+  set_int("dataLayoutHeaderSize", DataLayout::header_size_in_bytes());
+  set_int("dataLayoutTagOffset", in_bytes(DataLayout::tag_offset()));
+  set_int("dataLayoutFlagsOffset", in_bytes(DataLayout::flags_offset()));
+  set_int("dataLayoutBCIOffset", in_bytes(DataLayout::bci_offset()));
+  set_int("dataLayoutCellsOffset", in_bytes(DataLayout::cell_offset(0)));
+  set_int("dataLayoutCellSize", DataLayout::cell_size);
+  set_int("bciProfileWidth", BciProfileWidth);
+  set_int("typeProfileWidth", TypeProfileWidth);
+
+  set_int("tlabAlignmentReserve", (int32_t)ThreadLocalAllocBuffer::alignment_reserve());
+  set_long("tlabIntArrayMarkWord", (intptr_t)markOopDesc::prototype()->copy_set_hash(0x2));
+  set_long("heapTopAddress", (jlong)(address) Universe::heap()->top_addr());
+  set_long("heapEndAddress", (jlong)(address) Universe::heap()->end_addr());
+  set_int("threadTlabStartOffset", in_bytes(JavaThread::tlab_start_offset()));
+  set_int("threadTlabSizeOffset", in_bytes(JavaThread::tlab_size_offset()));
+  set_int("threadAllocatedBytesOffset", in_bytes(JavaThread::allocated_bytes_offset()));
+  set_int("tlabSlowAllocationsOffset", in_bytes(JavaThread::tlab_slow_allocations_offset()));
+  set_int("tlabFastRefillWasteOffset", in_bytes(JavaThread::tlab_fast_refill_waste_offset()));
+  set_int("tlabNumberOfRefillsOffset", in_bytes(JavaThread::tlab_number_of_refills_offset()));
+  set_int("tlabRefillWasteLimitOffset", in_bytes(JavaThread::tlab_refill_waste_limit_offset()));
+  set_int("tlabRefillWasteIncrement", (int32_t) ThreadLocalAllocBuffer::refill_waste_limit_increment());
+  set_int("klassInstanceSizeOffset", in_bytes(Klass::layout_helper_offset()));
+  set_boolean("tlabStats", TLABStats);
+  set_boolean("inlineContiguousAllocationSupported", !CMSIncrementalMode && Universe::heap()->supports_inline_contig_alloc());
+
+  set_long("arrayPrototypeMarkWord", (intptr_t)markOopDesc::prototype());
+  set_int("layoutHelperLog2ElementSizeShift", Klass::_lh_log2_element_size_shift);
+  set_int("layoutHelperLog2ElementSizeMask", Klass::_lh_log2_element_size_mask);
+  set_int("layoutHelperElementTypeShift", Klass::_lh_element_type_shift);
+  set_int("layoutHelperElementTypeMask", Klass::_lh_element_type_mask);
+  set_int("layoutHelperHeaderSizeShift", Klass::_lh_header_size_shift);
+  set_int("layoutHelperHeaderSizeMask", Klass::_lh_header_size_mask);
+  set_int("layoutHelperOffset", in_bytes(Klass::layout_helper_offset()));
+
+  set_long("debugStub", VmIds::addStub((address)warning));
+  set_long("instanceofStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_slow_subtype_check_id)));
+  set_long("newInstanceStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_new_instance_id)));
+  set_long("newArrayStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_new_array_id)));
+  set_long("newMultiArrayStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_new_multi_array_id)));
+  set_long("identityHashCodeStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_identity_hash_code_id)));
+  set_long("threadIsInterruptedStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_thread_is_interrupted_id)));
+  set_long("inlineCacheMissStub", VmIds::addStub(SharedRuntime::get_ic_miss_stub()));
+  set_long("handleExceptionStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_handle_exception_nofpu_id)));
+  set_long("handleDeoptStub", VmIds::addStub(SharedRuntime::deopt_blob()->unpack()));
+  set_long("monitorEnterStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_monitorenter_id)));
+  set_long("monitorExitStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_monitorexit_id)));
+  set_long("verifyOopStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_verify_oop_id)));
+  set_long("vmErrorStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_vm_error_id)));
+  set_long("deoptimizeStub", VmIds::addStub(SharedRuntime::deopt_blob()->uncommon_trap()));
+  set_long("unwindExceptionStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_unwind_exception_call_id)));
+  set_long("osrMigrationEndStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_OSR_migration_end_id)));
+  set_long("registerFinalizerStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_register_finalizer_id)));
+  set_long("setDeoptInfoStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_set_deopt_info_id)));
+  set_long("createNullPointerExceptionStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_create_null_pointer_exception_id)));
+  set_long("createOutOfBoundsExceptionStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_create_out_of_bounds_exception_id)));
+  set_long("javaTimeMillisStub", VmIds::addStub(CAST_FROM_FN_PTR(address, os::javaTimeMillis)));
+  set_long("javaTimeNanosStub", VmIds::addStub(CAST_FROM_FN_PTR(address, os::javaTimeNanos)));
+  set_long("arithmeticFremStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_arithmetic_frem_id)));
+  set_long("arithmeticDremStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_arithmetic_drem_id)));
+  set_long("arithmeticSinStub", VmIds::addStub(CAST_FROM_FN_PTR(address, SharedRuntime::dsin)));
+  set_long("arithmeticCosStub", VmIds::addStub(CAST_FROM_FN_PTR(address, SharedRuntime::dcos)));
+  set_long("arithmeticTanStub", VmIds::addStub(CAST_FROM_FN_PTR(address, SharedRuntime::dtan)));
+  set_long("logPrimitiveStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_log_primitive_id)));
+  set_long("logObjectStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_log_object_id)));
+  set_long("logPrintfStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_log_printf_id)));
+
+
+  BarrierSet* bs = Universe::heap()->barrier_set();
+  switch (bs->kind()) {
+    case BarrierSet::CardTableModRef:
+    case BarrierSet::CardTableExtension: {
+      jlong base = (jlong)((CardTableModRefBS*)bs)->byte_map_base;
+      assert(base != 0, "unexpected byte_map_base");
+      set_long("cardtableStartAddress", base);
+      set_int("cardtableShift", CardTableModRefBS::card_shift);
+      break;
+    }
+    case BarrierSet::ModRef:
+    case BarrierSet::Other:
+      set_long("cardtableStartAddress", 0);
+      set_int("cardtableShift", 0);
+      // No post barriers
+      break;
+#ifndef SERIALGC
+    case BarrierSet::G1SATBCT:
+    case BarrierSet::G1SATBCTLogging:
+#endif // SERIALGC
+    default:
+      ShouldNotReachHere();
+      break;
+    }
+
+  set_int("arrayClassElementOffset", in_bytes(ObjArrayKlass::element_klass_offset()));
+
+#undef set_boolean
+#undef set_int
+#undef set_long
+#undef set_object
+#undef set_int_array
+
+C2V_END
+
+C2V_VMENTRY(jint, installCode0, (JNIEnv *jniEnv, jobject, jobject compResult, jobject installed_code, jobject info))
+  ResourceMark rm;
+  HandleMark hm;
+  Handle compResultHandle = JNIHandles::resolve(compResult);
+  nmethod* nm = NULL;
+  methodHandle method = getMethodFromHotSpotMethod(HotSpotCompilationResult::method(compResult));
+  Handle installed_code_handle = JNIHandles::resolve(installed_code);
+  GraalEnv::CodeInstallResult result;
+  CodeInstaller installer(compResultHandle, method, result, nm, installed_code_handle);
+
+  if (result != GraalEnv::ok) {
+    assert(nm == NULL, "should be");
+  } else {
+    if (info != NULL) {
+      arrayOop codeCopy = oopFactory::new_byteArray(nm->code_size(), CHECK_0);
+      memcpy(codeCopy->base(T_BYTE), nm->code_begin(), nm->code_size());
+      HotSpotCodeInfo::set_code(info, codeCopy);
+      HotSpotCodeInfo::set_start(info, (jlong) nm->code_begin());
+    }
+
+    if (!installed_code_handle.is_null()) {
+      assert(installed_code_handle->is_a(HotSpotInstalledCode::klass()), "wrong type");
+      HotSpotInstalledCode::set_nmethod(installed_code_handle, (jlong) nm);
+      HotSpotInstalledCode::set_method(installed_code_handle, HotSpotCompilationResult::method(compResult));
+      assert(nm == NULL || !installed_code_handle->is_scavengable() || nm->on_scavenge_root_list(), "nm should be scavengable if installed_code is scavengable");
+    }
+  }
+  return result;
+C2V_END
+
+C2V_VMENTRY(jobject, disassembleNative, (JNIEnv *jniEnv, jobject, jbyteArray code, jlong start_address))
+  ResourceMark rm;
+  HandleMark hm;
+
+  stringStream(st);
+  arrayOop code_oop = (arrayOop) JNIHandles::resolve(code);
+  int len = code_oop->length();
+  address begin = (address) code_oop->base(T_BYTE);
+  address end = begin + len;
+  Disassembler::decode(begin, end, &st);
+
+  Handle result = java_lang_String::create_from_platform_dependent_str(st.as_string(), CHECK_NULL);
+  return JNIHandles::make_local(result());
+C2V_END
+
+C2V_VMENTRY(jobject, getStackTraceElement, (JNIEnv *env, jobject, jlong metaspace_method, int bci))
+  ResourceMark rm;
+  HandleMark hm;
+
+  methodHandle method = asMethod(metaspace_method);
+  oop element = java_lang_StackTraceElement::create(method, bci, CHECK_NULL);
+  return JNIHandles::make_local(element);
+C2V_END
+
+C2V_VMENTRY(jobject, executeCompiledMethodVarargs, (JNIEnv *env, jobject, jlong metaspace_method, jlong metaspace_nmethod, jobject args))
+  ResourceMark rm;
+  HandleMark hm;
+
+  assert(metaspace_method != 0, "just checking");
+  methodHandle mh = asMethod(metaspace_method);
+  Symbol* signature = mh->signature();
+  JavaCallArguments jca;
+
+  JavaArgumentUnboxer jap(signature, &jca, (arrayOop) JNIHandles::resolve(args), mh->is_static());
+  JavaValue result(jap.get_ret_type());
+
+  nmethod* nm = (nmethod*) (address) metaspace_nmethod;
+  if (nm == NULL || !nm->is_alive()) {
+    THROW_0(vmSymbols::MethodInvalidatedException());
+  }
+
+  JavaCalls::call(&result, mh, nm, &jca, CHECK_NULL);
+
+  if (jap.get_ret_type() == T_VOID) {
+    return NULL;
+  } else if (jap.get_ret_type() == T_OBJECT || jap.get_ret_type() == T_ARRAY) {
+    return JNIHandles::make_local((oop) result.get_jobject());
+  } else {
+    oop o = java_lang_boxing_object::create(jap.get_ret_type(), (jvalue *) result.get_value_addr(), CHECK_NULL);
+    return JNIHandles::make_local(o);
+  }
+C2V_END
+
+C2V_VMENTRY(jobject, executeCompiledMethod, (JNIEnv *env, jobject, jlong metaspace_method, jlong metaspace_nmethod, jobject arg1, jobject arg2, jobject arg3))
+  ResourceMark rm;
+  HandleMark hm;
+
+  methodHandle method = asMethod(metaspace_method);
+  assert(!method.is_null(), "just checking");
+  JavaValue result(T_OBJECT);
+  JavaCallArguments args;
+  args.push_oop(JNIHandles::resolve(arg1));
+  args.push_oop(JNIHandles::resolve(arg2));
+  args.push_oop(JNIHandles::resolve(arg3));
+
+  nmethod* nm = (nmethod*) (address) metaspace_nmethod;
+  if (nm == NULL || !nm->is_alive()) {
+    THROW_0(vmSymbols::MethodInvalidatedException());
+  }
+
+  JavaCalls::call(&result, method, nm, &args, CHECK_NULL);
+
+  return JNIHandles::make_local((oop) result.get_jobject());
+C2V_END
+
+C2V_VMENTRY(jint, getVtableEntryOffset, (JNIEnv *, jobject, jlong metaspace_method))
+
+  Method* method = asMethod(metaspace_method);
+  assert(!InstanceKlass::cast(method->method_holder())->is_interface(), "vtableEntryOffset cannot be called for interface methods");
+  assert(InstanceKlass::cast(method->method_holder())->is_linked(), "vtableEntryOffset cannot be called is holder is not linked");
+
+  // get entry offset in words
+  int vtable_entry_offset = InstanceKlass::vtable_start_offset() + method->vtable_index() * vtableEntry::size();
+  // convert to bytes
+  vtable_entry_offset = vtable_entry_offset * wordSize + vtableEntry::method_offset_in_bytes();
+
+  return vtable_entry_offset;
+C2V_END
+
+C2V_VMENTRY(jobject, getDeoptedLeafGraphIds, (JNIEnv *, jobject))
+
+  // the contract for this method is as follows:
+  // returning null: no deopted leaf graphs
+  // returning array (size > 0): the ids of the deopted leaf graphs
+  // returning array (size == 0): there was an overflow, the compiler needs to clear its cache completely
+
+  oop array = GraalCompiler::instance()->dump_deopted_leaf_graphs(CHECK_NULL);
+  return JNIHandles::make_local(array);
+C2V_END
+
+C2V_VMENTRY(jobject, decodePC, (JNIEnv *, jobject, jlong pc))
+  stringStream(st);
+  CodeBlob* blob = CodeCache::find_blob_unsafe((void*) pc);
+  if (blob == NULL) {
+    st.print("[unidentified pc]");
+  } else {
+    st.print(blob->name());
+
+    nmethod* nm = blob->as_nmethod_or_null();
+    if (nm != NULL && nm->method() != NULL) {
+      st.print(" %s.", nm->method()->method_holder()->external_name());
+      nm->method()->name()->print_symbol_on(&st);
+      st.print("  @ %d", pc - (jlong) nm->entry_point());
+    }
+  }
+  Handle result = java_lang_String::create_from_platform_dependent_str(st.as_string(), CHECK_NULL);
+  return JNIHandles::make_local(result());
+C2V_END
+
+
+#define CC (char*)  /*cast a literal from (const char*)*/
+#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f))
+
+#define RESOLVED_TYPE         "Lcom/oracle/graal/api/meta/ResolvedJavaType;"
+#define TYPE                  "Lcom/oracle/graal/api/meta/JavaType;"
+#define METHOD                "Lcom/oracle/graal/api/meta/JavaMethod;"
+#define FIELD                 "Lcom/oracle/graal/api/meta/JavaField;"
+#define SIGNATURE             "Lcom/oracle/graal/api/meta/Signature;"
+#define CONSTANT_POOL         "Lcom/oracle/graal/api/meta/ConstantPool;"
+#define CONSTANT              "Lcom/oracle/graal/api/meta/Constant;"
+#define KIND                  "Lcom/oracle/graal/api/meta/Kind;"
+#define RUNTIME_CALL          "Lcom/oracle/graal/api/code/RuntimeCall;"
+#define EXCEPTION_HANDLERS    "[Lcom/oracle/graal/api/meta/ExceptionHandler;"
+#define REFLECT_METHOD        "Ljava/lang/reflect/Method;"
+#define REFLECT_CONSTRUCTOR   "Ljava/lang/reflect/Constructor;"
+#define REFLECT_FIELD         "Ljava/lang/reflect/Field;"
+#define STRING                "Ljava/lang/String;"
+#define OBJECT                "Ljava/lang/Object;"
+#define CLASS                 "Ljava/lang/Class;"
+#define STACK_TRACE_ELEMENT   "Ljava/lang/StackTraceElement;"
+#define HS_RESOLVED_TYPE      "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedObjectType;"
+#define HS_RESOLVED_METHOD    "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;"
+#define HS_RESOLVED_FIELD     "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaField;"
+#define HS_COMP_RESULT        "Lcom/oracle/graal/hotspot/HotSpotCompilationResult;"
+#define HS_CONFIG             "Lcom/oracle/graal/hotspot/HotSpotVMConfig;"
+#define HS_METHOD             "Lcom/oracle/graal/hotspot/meta/HotSpotMethod;"
+#define HS_INSTALLED_CODE     "Lcom/oracle/graal/hotspot/meta/HotSpotInstalledCode;"
+#define HS_CODE_INFO          "Lcom/oracle/graal/hotspot/meta/HotSpotCodeInfo;"
+#define METHOD_DATA           "Lcom/oracle/graal/hotspot/meta/HotSpotMethodData;"
+#define METASPACE_METHOD      "J"
+#define METASPACE_METHOD_DATA "J"
+#define NMETHOD               "J"
+
+JNINativeMethod CompilerToVM_methods[] = {
+  {CC"initializeBytecode",            CC"("METASPACE_METHOD"[B)[B",                                     FN_PTR(initializeBytecode)},
+  {CC"getSignature",                  CC"("METASPACE_METHOD")"STRING,                                   FN_PTR(getSignature)},
+  {CC"initializeExceptionHandlers",   CC"("METASPACE_METHOD EXCEPTION_HANDLERS")"EXCEPTION_HANDLERS,    FN_PTR(initializeExceptionHandlers)},
+  {CC"hasBalancedMonitors",           CC"("METASPACE_METHOD")Z",                                        FN_PTR(hasBalancedMonitors)},
+  {CC"getUniqueConcreteMethod",       CC"("METASPACE_METHOD"["HS_RESOLVED_TYPE")"METASPACE_METHOD,      FN_PTR(getUniqueConcreteMethod)},
+  {CC"getStackTraceElement",          CC"("METASPACE_METHOD"I)"STACK_TRACE_ELEMENT,                     FN_PTR(getStackTraceElement)},
+  {CC"initializeMethod",              CC"("METASPACE_METHOD HS_RESOLVED_METHOD")V",                     FN_PTR(initializeMethod)},
+  {CC"initializeMethodData",          CC"("METASPACE_METHOD_DATA METHOD_DATA")V",                       FN_PTR(initializeMethodData)},
+  {CC"isMethodCompilable",            CC"("METASPACE_METHOD")Z",                                        FN_PTR(isMethodCompilable)},
+  {CC"getInvocationCount",            CC"("METASPACE_METHOD")I",                                        FN_PTR(getInvocationCount)},
+  {CC"getCompiledCodeSize",           CC"("METASPACE_METHOD")I",                                        FN_PTR(getCompiledCodeSize)},
+  {CC"getVtableEntryOffset",          CC"("METASPACE_METHOD")I",                                        FN_PTR(getVtableEntryOffset)},
+  {CC"lookupType",                    CC"("STRING HS_RESOLVED_TYPE"Z)"TYPE,                             FN_PTR(lookupType)},
+  {CC"lookupConstantInPool",          CC"("HS_RESOLVED_TYPE"I)"OBJECT,                                  FN_PTR(lookupConstantInPool)},
+  {CC"lookupMethodInPool",            CC"("HS_RESOLVED_TYPE"IB)"METHOD,                                 FN_PTR(lookupMethodInPool)},
+  {CC"lookupTypeInPool",              CC"("HS_RESOLVED_TYPE"I)"TYPE,                                    FN_PTR(lookupTypeInPool)},
+  {CC"lookupReferencedTypeInPool",    CC"("HS_RESOLVED_TYPE"IB)V",                                      FN_PTR(lookupReferencedTypeInPool)},
+  {CC"lookupFieldInPool",             CC"("HS_RESOLVED_TYPE"IB)"FIELD,                                  FN_PTR(lookupFieldInPool)},
+  {CC"resolveMethod",                 CC"("HS_RESOLVED_TYPE STRING STRING")"METHOD,                     FN_PTR(resolveMethod)},
+  {CC"getInstanceFields",             CC"("HS_RESOLVED_TYPE")["HS_RESOLVED_FIELD,                       FN_PTR(getInstanceFields)},
+  {CC"isTypeInitialized",             CC"("HS_RESOLVED_TYPE")Z",                                        FN_PTR(isTypeInitialized)},
+  {CC"initializeType",                CC"("HS_RESOLVED_TYPE")V",                                        FN_PTR(initializeType)},
+  {CC"getMaxCallTargetOffset",        CC"(J)J",                                                         FN_PTR(getMaxCallTargetOffset)},
+  {CC"getResolvedType",               CC"("CLASS")"RESOLVED_TYPE,                                       FN_PTR(getResolvedType)},
+  {CC"getMetaspaceMethod",            CC"("REFLECT_METHOD"["HS_RESOLVED_TYPE")"METASPACE_METHOD,        FN_PTR(getMetaspaceMethod)},
+  {CC"getMetaspaceConstructor",       CC"("REFLECT_CONSTRUCTOR"["HS_RESOLVED_TYPE")"METASPACE_METHOD,   FN_PTR(getMetaspaceConstructor)},
+  {CC"getJavaField",                  CC"("REFLECT_FIELD")"HS_RESOLVED_FIELD,                           FN_PTR(getJavaField)},
+  {CC"initializeConfiguration",       CC"("HS_CONFIG")V",                                               FN_PTR(initializeConfiguration)},
+  {CC"installCode0",                  CC"("HS_COMP_RESULT HS_INSTALLED_CODE HS_CODE_INFO")I",           FN_PTR(installCode0)},
+  {CC"disassembleNative",             CC"([BJ)"STRING,                                                  FN_PTR(disassembleNative)},
+  {CC"executeCompiledMethod",         CC"("METASPACE_METHOD NMETHOD OBJECT OBJECT OBJECT")"OBJECT,      FN_PTR(executeCompiledMethod)},
+  {CC"executeCompiledMethodVarargs",  CC"("METASPACE_METHOD NMETHOD "["OBJECT")"OBJECT,                 FN_PTR(executeCompiledMethodVarargs)},
+  {CC"getDeoptedLeafGraphIds",        CC"()[J",                                                         FN_PTR(getDeoptedLeafGraphIds)},
+  {CC"decodePC",                      CC"(J)"STRING,                                                    FN_PTR(decodePC)},
+};
+
+int CompilerToVM_methods_count() {
+  return sizeof(CompilerToVM_methods) / sizeof(JNINativeMethod);
+}
+
--- a/src/share/vm/graal/graalGlobals.hpp	Mon Dec 10 22:19:07 2012 +0100
+++ b/src/share/vm/graal/graalGlobals.hpp	Tue Dec 11 08:48:12 2012 +0100
@@ -51,7 +51,7 @@
           "Bootstrap Graal before running Java main method")                \
                                                                             \
   product(ccstr, GraalClassPath, NULL,                                      \
-          "Use the class path for Graal classes")                           \
+          "Use this path, zip, or jar, to locate Graal-specific classes")   \
                                                                             \
   product(intx, TraceGraal, 0,                                              \
           "Trace level for Graal")                                          \
@@ -62,9 +62,6 @@
   product_pd(intx, SafepointPollOffset,                                     \
           "Offset added to polling address (Intel only)")                   \
                                                                             \
-  develop(bool, UseFastNewInstance, true,                                   \
-          "Use fast inlined instance allocation")                           \
-                                                                            \
   develop(bool, UseFastNewTypeArray, true,                                  \
           "Use fast inlined type array allocation")                         \
                                                                             \
--- a/src/share/vm/graal/graalRuntime.cpp	Mon Dec 10 22:19:07 2012 +0100
+++ b/src/share/vm/graal/graalRuntime.cpp	Tue Dec 11 08:48:12 2012 +0100
@@ -1,586 +1,606 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include "precompiled.hpp"
-#include "runtime/interfaceSupport.hpp"
-#include "prims/jvm.h"
-#include "graal/graalRuntime.hpp"
-#include "graal/graalVMToCompiler.hpp"
-#include "asm/codeBuffer.hpp"
-#include "runtime/biasedLocking.hpp"
-
-// Implementation of GraalStubAssembler
-
-GraalStubAssembler::GraalStubAssembler(CodeBuffer* code, const char * name, int stub_id) : MacroAssembler(code) {
-  _name = name;
-  _must_gc_arguments = false;
-  _frame_size = no_frame_size;
-  _num_rt_args = 0;
-  _stub_id = stub_id;
-}
-
-
-void GraalStubAssembler::set_info(const char* name, bool must_gc_arguments) {
-  _name = name;
-  _must_gc_arguments = must_gc_arguments;
-}
-
-
-void GraalStubAssembler::set_frame_size(int size) {
-  if (_frame_size == no_frame_size) {
-    _frame_size = size;
-  }
-  assert(_frame_size == size, "can't change the frame size");
-}
-
-
-void GraalStubAssembler::set_num_rt_args(int args) {
-  if (_num_rt_args == 0) {
-    _num_rt_args = args;
-  }
-  assert(_num_rt_args == args, "can't change the number of args");
-}
-
-// Implementation of GraalRuntime
-
-CodeBlob* GraalRuntime::_blobs[GraalRuntime::number_of_ids];
-const char *GraalRuntime::_blob_names[] = {
-  GRAAL_STUBS(STUB_NAME, LAST_STUB_NAME)
-};
-
-// Simple helper to see if the caller of a runtime stub which
-// entered the VM has been deoptimized
-
-static bool caller_is_deopted() {
-  JavaThread* thread = JavaThread::current();
-  RegisterMap reg_map(thread, false);
-  frame runtime_frame = thread->last_frame();
-  frame caller_frame = runtime_frame.sender(&reg_map);
-  assert(caller_frame.is_compiled_frame(), "must be compiled");
-  return caller_frame.is_deoptimized_frame();
-}
-
-// Stress deoptimization
-static void deopt_caller() {
-  if ( !caller_is_deopted()) {
-    JavaThread* thread = JavaThread::current();
-    RegisterMap reg_map(thread, false);
-    frame runtime_frame = thread->last_frame();
-    frame caller_frame = runtime_frame.sender(&reg_map);
-    Deoptimization::deoptimize_frame(thread, caller_frame.id(), Deoptimization::Reason_constraint);
-    assert(caller_is_deopted(), "Must be deoptimized");
-  }
-}
-
-static bool setup_code_buffer(CodeBuffer* code) {
-  // Preinitialize the consts section to some large size:
-  int locs_buffer_size = 1 * (relocInfo::length_limit + sizeof(relocInfo));
-  char* locs_buffer = NEW_RESOURCE_ARRAY(char, locs_buffer_size);
-  code->insts()->initialize_shared_locs((relocInfo*)locs_buffer,
-                                        locs_buffer_size / sizeof(relocInfo));
-
-  // Global stubs have neither constants nor local stubs
-  code->initialize_consts_size(0);
-  code->initialize_stubs_size(0);
-
-  return true;
-}
-
-void GraalRuntime::generate_blob_for(BufferBlob* buffer_blob, StubID id) {
-  assert(0 <= id && id < number_of_ids, "illegal stub id");
-  ResourceMark rm;
-  // create code buffer for code storage
-  CodeBuffer code(buffer_blob);
-
-  setup_code_buffer(&code);
-
-  // create assembler for code generation
-  GraalStubAssembler* sasm = new GraalStubAssembler(&code, name_for(id), id);
-  // generate code for runtime stub
-  OopMapSet* oop_maps;
-  oop_maps = generate_code_for(id, sasm);
-  assert(oop_maps == NULL || sasm->frame_size() != no_frame_size,
-         "if stub has an oop map it must have a valid frame size");
-
-#ifdef ASSERT
-  // Make sure that stubs that need oopmaps have them
-  switch (id) {
-    // These stubs don't need to have an oopmap
-    case graal_slow_subtype_check_id:
-#if defined(SPARC) || defined(PPC)
-    case handle_exception_nofpu_id:  // Unused on sparc
-#endif
-#ifdef GRAAL
-    case graal_verify_oop_id:
-    case graal_unwind_exception_call_id:
-    case graal_OSR_migration_end_id:
-    case graal_arithmetic_frem_id:
-    case graal_arithmetic_drem_id:
-    case graal_set_deopt_info_id:
-#endif
-      break;
-
-    // All other stubs should have oopmaps
-    default:
-      assert(oop_maps != NULL, "must have an oopmap");
-  }
-#endif
-
-  // align so printing shows nop's instead of random code at the end (SimpleStubs are aligned)
-  sasm->align(BytesPerWord);
-  // make sure all code is in code buffer
-  sasm->flush();
-  // create blob - distinguish a few special cases
-  CodeBlob* blob = RuntimeStub::new_runtime_stub(name_for(id),
-                                                 &code,
-                                                 CodeOffsets::frame_never_safe,
-                                                 sasm->frame_size(),
-                                                 oop_maps,
-                                                 sasm->must_gc_arguments());
-  // install blob
-  assert(blob != NULL, "blob must exist");
-  _blobs[id] = blob;
-}
-
-
-void GraalRuntime::initialize(BufferBlob* blob) {
-  // generate stubs
-  for (int id = 0; id < number_of_ids; id++) generate_blob_for(blob, (StubID)id);
-  // printing
-#ifndef PRODUCT
-  if (PrintSimpleStubs) {
-    ResourceMark rm;
-    for (int id = 0; id < number_of_ids; id++) {
-      _blobs[id]->print();
-      if (_blobs[id]->oop_maps() != NULL) {
-        _blobs[id]->oop_maps()->print();
-      }
-    }
-  }
-#endif
-}
-
-
-CodeBlob* GraalRuntime::blob_for(StubID id) {
-  assert(0 <= id && id < number_of_ids, "illegal stub id");
-  return _blobs[id];
-}
-
-
-const char* GraalRuntime::name_for(StubID id) {
-  assert(0 <= id && id < number_of_ids, "illegal stub id");
-  return _blob_names[id];
-}
-
-const char* GraalRuntime::name_for_address(address entry) {
-  for (int id = 0; id < number_of_ids; id++) {
-    if (entry == entry_for((StubID)id)) return name_for((StubID)id);
-  }
-
-#define FUNCTION_CASE(a, f) \
-  if ((intptr_t)a == CAST_FROM_FN_PTR(intptr_t, f))  return #f
-
-  FUNCTION_CASE(entry, os::javaTimeMillis);
-  FUNCTION_CASE(entry, os::javaTimeNanos);
-  FUNCTION_CASE(entry, SharedRuntime::OSR_migration_end);
-  FUNCTION_CASE(entry, SharedRuntime::d2f);
-  FUNCTION_CASE(entry, SharedRuntime::d2i);
-  FUNCTION_CASE(entry, SharedRuntime::d2l);
-  FUNCTION_CASE(entry, SharedRuntime::dcos);
-  FUNCTION_CASE(entry, SharedRuntime::dexp);
-  FUNCTION_CASE(entry, SharedRuntime::dlog);
-  FUNCTION_CASE(entry, SharedRuntime::dlog10);
-  FUNCTION_CASE(entry, SharedRuntime::dpow);
-  FUNCTION_CASE(entry, SharedRuntime::drem);
-  FUNCTION_CASE(entry, SharedRuntime::dsin);
-  FUNCTION_CASE(entry, SharedRuntime::dtan);
-  FUNCTION_CASE(entry, SharedRuntime::f2i);
-  FUNCTION_CASE(entry, SharedRuntime::f2l);
-  FUNCTION_CASE(entry, SharedRuntime::frem);
-  FUNCTION_CASE(entry, SharedRuntime::l2d);
-  FUNCTION_CASE(entry, SharedRuntime::l2f);
-  FUNCTION_CASE(entry, SharedRuntime::ldiv);
-  FUNCTION_CASE(entry, SharedRuntime::lmul);
-  FUNCTION_CASE(entry, SharedRuntime::lrem);
-  FUNCTION_CASE(entry, SharedRuntime::lrem);
-  FUNCTION_CASE(entry, SharedRuntime::dtrace_method_entry);
-  FUNCTION_CASE(entry, SharedRuntime::dtrace_method_exit);
-#ifdef TRACE_HAVE_INTRINSICS
-  FUNCTION_CASE(entry, TRACE_TIME_METHOD);
-#endif
-
-#undef FUNCTION_CASE
-}
-
-
-JRT_ENTRY(void, GraalRuntime::new_instance(JavaThread* thread, Klass* klass))
-  assert(klass->is_klass(), "not a class");
-  instanceKlassHandle h(thread, klass);
-  h->check_valid_for_instantiation(true, CHECK);
-  // make sure klass is initialized
-  h->initialize(CHECK);
-  // allocate instance and return via TLS
-  oop obj = h->allocate_instance(CHECK);
-  thread->set_vm_result(obj);
-JRT_END
-
-JRT_ENTRY(void, GraalRuntime::new_array(JavaThread* thread, Klass* array_klass, jint length))
-  // Note: no handle for klass needed since they are not used
-  //       anymore after new_objArray() and no GC can happen before.
-  //       (This may have to change if this code changes!)
-  assert(array_klass->is_klass(), "not a class");
-  oop obj;
-  if (array_klass->oop_is_typeArray()) {
-    BasicType elt_type = TypeArrayKlass::cast(array_klass)->element_type();
-    obj = oopFactory::new_typeArray(elt_type, length, CHECK);
-  } else {
-    Klass* elem_klass = ObjArrayKlass::cast(array_klass)->element_klass();
-    obj = oopFactory::new_objArray(elem_klass, length, CHECK);
-  }
-  thread->set_vm_result(obj);
-  // This is pretty rare but this runtime patch is stressful to deoptimization
-  // if we deoptimize here so force a deopt to stress the path.
-  if (DeoptimizeALot) {
-    deopt_caller();
-  }
-JRT_END
-
-
-JRT_ENTRY(void, GraalRuntime::new_multi_array(JavaThread* thread, Klass* klass, int rank, jint* dims))
-  assert(klass->is_klass(), "not a class");
-  assert(rank >= 1, "rank must be nonzero");
-  oop obj = ArrayKlass::cast(klass)->multi_allocate(rank, dims, CHECK);
-  thread->set_vm_result(obj);
-JRT_END
-
-JRT_ENTRY(void, GraalRuntime::unimplemented_entry(JavaThread* thread, StubID id))
-  tty->print_cr("GraalRuntime::entry_for(%d) returned unimplemented entry point", id);
-JRT_END
-
-extern void vm_exit(int code);
-
-// Enter this method from compiled code handler below. This is where we transition
-// to VM mode. This is done as a helper routine so that the method called directly
-// from compiled code does not have to transition to VM. This allows the entry
-// method to see if the nmethod that we have just looked up a handler for has
-// been deoptimized while we were in the vm. This simplifies the assembly code
-// cpu directories.
-//
-// We are entering here from exception stub (via the entry method below)
-// If there is a compiled exception handler in this method, we will continue there;
-// otherwise we will unwind the stack and continue at the caller of top frame method
-// Note: we enter in Java using a special JRT wrapper. This wrapper allows us to
-// control the area where we can allow a safepoint. After we exit the safepoint area we can
-// check to see if the handler we are going to return is now in a nmethod that has
-// been deoptimized. If that is the case we return the deopt blob
-// unpack_with_exception entry instead. This makes life for the exception blob easier
-// because making that same check and diverting is painful from assembly language.
-JRT_ENTRY_NO_ASYNC(static address, exception_handler_for_pc_helper(JavaThread* thread, oopDesc* ex, address pc, nmethod*& nm))
-  // Reset method handle flag.
-  thread->set_is_method_handle_return(false);
-
-  Handle exception(thread, ex);
-  nm = CodeCache::find_nmethod(pc);
-  assert(nm != NULL, "this is not an nmethod");
-  // Adjust the pc as needed/
-  if (nm->is_deopt_pc(pc)) {
-    RegisterMap map(thread, false);
-    frame exception_frame = thread->last_frame().sender(&map);
-    // if the frame isn't deopted then pc must not correspond to the caller of last_frame
-    assert(exception_frame.is_deoptimized_frame(), "must be deopted");
-    pc = exception_frame.pc();
-  }
-#ifdef ASSERT
-  assert(exception.not_null(), "NULL exceptions should be handled by throw_exception");
-  assert(exception->is_oop(), "just checking");
-  // Check that exception is a subclass of Throwable, otherwise we have a VerifyError
-  if (!(exception->is_a(SystemDictionary::Throwable_klass()))) {
-    if (ExitVMOnVerifyError) vm_exit(-1);
-    ShouldNotReachHere();
-  }
-#endif
-
-  // Check the stack guard pages and reenable them if necessary and there is
-  // enough space on the stack to do so.  Use fast exceptions only if the guard
-  // pages are enabled.
-  bool guard_pages_enabled = thread->stack_yellow_zone_enabled();
-  if (!guard_pages_enabled) guard_pages_enabled = thread->reguard_stack();
-
-  if (JvmtiExport::can_post_on_exceptions()) {
-    // To ensure correct notification of exception catches and throws
-    // we have to deoptimize here.  If we attempted to notify the
-    // catches and throws during this exception lookup it's possible
-    // we could deoptimize on the way out of the VM and end back in
-    // the interpreter at the throw site.  This would result in double
-    // notifications since the interpreter would also notify about
-    // these same catches and throws as it unwound the frame.
-
-    RegisterMap reg_map(thread);
-    frame stub_frame = thread->last_frame();
-    frame caller_frame = stub_frame.sender(&reg_map);
-
-    // We don't really want to deoptimize the nmethod itself since we
-    // can actually continue in the exception handler ourselves but I
-    // don't see an easy way to have the desired effect.
-    Deoptimization::deoptimize_frame(thread, caller_frame.id(), Deoptimization::Reason_constraint);
-    assert(caller_is_deopted(), "Must be deoptimized");
-
-    return SharedRuntime::deopt_blob()->unpack_with_exception_in_tls();
-  }
-
-  // ExceptionCache is used only for exceptions at call sites and not for implicit exceptions
-  if (guard_pages_enabled) {
-    address fast_continuation = nm->handler_for_exception_and_pc(exception, pc);
-    if (fast_continuation != NULL) {
-      // Set flag if return address is a method handle call site.
-      thread->set_is_method_handle_return(nm->is_method_handle_return(pc));
-      return fast_continuation;
-    }
-  }
-
-  // If the stack guard pages are enabled, check whether there is a handler in
-  // the current method.  Otherwise (guard pages disabled), force an unwind and
-  // skip the exception cache update (i.e., just leave continuation==NULL).
-  address continuation = NULL;
-  if (guard_pages_enabled) {
-
-    // New exception handling mechanism can support inlined methods
-    // with exception handlers since the mappings are from PC to PC
-
-    // debugging support
-    // tracing
-    if (TraceExceptions) {
-      ttyLocker ttyl;
-      ResourceMark rm;
-      int offset = pc - nm->code_begin();
-      tty->print_cr("Exception <%s> (0x%x) thrown in compiled method <%s> at PC " PTR_FORMAT " [" PTR_FORMAT "+%d] for thread 0x%x",
-                    exception->print_value_string(), (address)exception(), nm->method()->print_value_string(), pc, nm->code_begin(), offset, thread);
-    }
-    // for AbortVMOnException flag
-    NOT_PRODUCT(Exceptions::debug_check_abort(exception));
-
-    // Clear out the exception oop and pc since looking up an
-    // exception handler can cause class loading, which might throw an
-    // exception and those fields are expected to be clear during
-    // normal bytecode execution.
-    thread->set_exception_oop(NULL);
-    thread->set_exception_pc(NULL);
-
-    continuation = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, false, false);
-    // If an exception was thrown during exception dispatch, the exception oop may have changed
-    thread->set_exception_oop(exception());
-    thread->set_exception_pc(pc);
-
-    // the exception cache is used only by non-implicit exceptions
-    if (continuation != NULL && !SharedRuntime::deopt_blob()->contains(continuation)) {
-      nm->add_handler_for_exception_and_pc(exception, pc, continuation);
-    }
-  }
-
-  thread->set_vm_result(exception());
-  // Set flag if return address is a method handle call site.
-  thread->set_is_method_handle_return(nm->is_method_handle_return(pc));
-
-  if (TraceExceptions) {
-    ttyLocker ttyl;
-    ResourceMark rm;
-    tty->print_cr("Thread " PTR_FORMAT " continuing at PC " PTR_FORMAT " for exception thrown at PC " PTR_FORMAT,
-                  thread, continuation, pc);
-  }
-
-  return continuation;
-JRT_END
-
-// Enter this method from compiled code only if there is a Java exception handler
-// in the method handling the exception.
-// We are entering here from exception stub. We don't do a normal VM transition here.
-// We do it in a helper. This is so we can check to see if the nmethod we have just
-// searched for an exception handler has been deoptimized in the meantime.
-address GraalRuntime::exception_handler_for_pc(JavaThread* thread) {
-  oop exception = thread->exception_oop();
-  address pc = thread->exception_pc();
-  // Still in Java mode
-  DEBUG_ONLY(ResetNoHandleMark rnhm);
-  nmethod* nm = NULL;
-  address continuation = NULL;
-  {
-    // Enter VM mode by calling the helper
-    ResetNoHandleMark rnhm;
-    continuation = exception_handler_for_pc_helper(thread, exception, pc, nm);
-  }
-  // Back in JAVA, use no oops DON'T safepoint
-
-  // Now check to see if the nmethod we were called from is now deoptimized.
-  // If so we must return to the deopt blob and deoptimize the nmethod
-  if (nm != NULL && caller_is_deopted()) {
-    continuation = SharedRuntime::deopt_blob()->unpack_with_exception_in_tls();
-  }
-
-  assert(continuation != NULL, "no handler found");
-  return continuation;
-}
-
-JRT_ENTRY(void, GraalRuntime::graal_create_null_exception(JavaThread* thread))
-  thread->set_vm_result(Exceptions::new_exception(thread, vmSymbols::java_lang_NullPointerException(), NULL)());
-JRT_END
-
-JRT_ENTRY(void, GraalRuntime::graal_create_out_of_bounds_exception(JavaThread* thread, jint index))
-  char message[jintAsStringSize];
-  sprintf(message, "%d", index);
-  thread->set_vm_result(Exceptions::new_exception(thread, vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), message)());
-JRT_END
-
-JRT_ENTRY_NO_ASYNC(void, GraalRuntime::graal_monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock))
-  if (TraceGraal >= 3) {
-    char type[O_BUFLEN];
-    obj->klass()->name()->as_C_string(type, O_BUFLEN);
-    markOop mark = obj->mark();
-    tty->print_cr("%s: entered locking slow case with obj=" INTPTR_FORMAT ", type=%s, mark=" INTPTR_FORMAT ", lock=" INTPTR_FORMAT, thread->name(), obj, type, mark, lock);
-    tty->flush();
-  }
-#ifdef ASSERT
-  if (PrintBiasedLockingStatistics) {
-    Atomic::inc(BiasedLocking::slow_path_entry_count_addr());
-  }
-#endif
-  Handle h_obj(thread, obj);
-  assert(h_obj()->is_oop(), "must be NULL or an object");
-  if (UseBiasedLocking) {
-    // Retry fast entry if bias is revoked to avoid unnecessary inflation
-    ObjectSynchronizer::fast_enter(h_obj, lock, true, CHECK);
-  } else {
-    if (UseFastLocking) {
-      // When using fast locking, the compiled code has already tried the fast case
-      ObjectSynchronizer::slow_enter(h_obj, lock, THREAD);
-    } else {
-      ObjectSynchronizer::fast_enter(h_obj, lock, false, THREAD);
-    }
-  }
-  if (TraceGraal >= 3) {
-    tty->print_cr("%s: exiting locking slow with obj=" INTPTR_FORMAT, thread->name(), obj);
-  }
-JRT_END
-
-
-JRT_LEAF(void, GraalRuntime::graal_monitorexit(JavaThread* thread, oopDesc* obj, BasicLock* lock))
-  assert(thread == JavaThread::current(), "threads must correspond");
-  assert(thread->last_Java_sp(), "last_Java_sp must be set");
-  // monitorexit is non-blocking (leaf routine) => no exceptions can be thrown
-  EXCEPTION_MARK;
-
-#ifdef DEBUG
-  if (!obj->is_oop()) {
-    ResetNoHandleMark rhm;
-    nmethod* method = thread->last_frame().cb()->as_nmethod_or_null();
-    if (method != NULL) {
-      tty->print_cr("ERROR in monitorexit in method %s wrong obj " INTPTR_FORMAT, method->name(), obj);
-    }
-    thread->print_stack_on(tty);
-    assert(false, "invalid lock object pointer dected");
-  }
-#endif
-
-  if (UseFastLocking) {
-    // When using fast locking, the compiled code has already tried the fast case
-    ObjectSynchronizer::slow_exit(obj, lock, THREAD);
-  } else {
-    ObjectSynchronizer::fast_exit(obj, lock, THREAD);
-  }
-  if (TraceGraal >= 3) {
-    char type[O_BUFLEN];
-    obj->klass()->name()->as_C_string(type, O_BUFLEN);
-    tty->print_cr("%s: exited locking slow case with obj=" INTPTR_FORMAT ", type=%s, mark=" INTPTR_FORMAT ", lock=" INTPTR_FORMAT, thread->name(), obj, type, obj->mark(), lock);
-    tty->flush();
-  }
-JRT_END
-
-JRT_ENTRY(void, GraalRuntime::graal_log_object(JavaThread* thread, oop obj, jint flags))
-  bool string =  mask_bits_are_true(flags, LOG_OBJECT_STRING);
-  bool address = mask_bits_are_true(flags, LOG_OBJECT_ADDRESS);
-  bool newline = mask_bits_are_true(flags, LOG_OBJECT_NEWLINE);
-  if (!string) {
-    if (!address && obj->is_oop_or_null(true)) {
-      char buf[O_BUFLEN];
-      tty->print("%s@%p", obj->klass()->name()->as_C_string(buf, O_BUFLEN), obj);
-    } else {
-      tty->print("%p", obj);
-    }
-  } else {
-    ResourceMark rm;
-    assert(obj != NULL && java_lang_String::is_instance(obj), "must be");
-    char *buf = java_lang_String::as_utf8_string(obj);
-    tty->print(buf);
-  }
-  if (newline) {
-    tty->cr();
-  }
-JRT_END
-
-JRT_ENTRY(void, GraalRuntime::graal_vm_error(JavaThread* thread, oop where, oop format, jlong value))
-  ResourceMark rm;
-  assert(where == NULL || java_lang_String::is_instance(where), "must be");
-  const char *error_msg = where == NULL ? "<internal Graal error>" : java_lang_String::as_utf8_string(where);
-  char *detail_msg = NULL;
-  if (format != NULL) {
-    const char* buf = java_lang_String::as_utf8_string(format);
-    size_t detail_msg_length = strlen(buf) * 2;
-    detail_msg = (char *) NEW_RESOURCE_ARRAY(u_char, detail_msg_length);
-    jio_snprintf(detail_msg, detail_msg_length, buf, value);
-  }
-  report_vm_error(__FILE__, __LINE__, error_msg, detail_msg);
-JRT_END
-
-JRT_ENTRY(void, GraalRuntime::graal_log_printf(JavaThread* thread, oop format, jlong val))
-  ResourceMark rm;
-  assert(format != NULL && java_lang_String::is_instance(format), "must be");
-  char *buf = java_lang_String::as_utf8_string(format);
-  tty->print(buf, val);
-JRT_END
-
-JRT_ENTRY(void, GraalRuntime::graal_log_primitive(JavaThread* thread, jchar typeChar, jlong value, jboolean newline))
-  union {
-      jlong l;
-      jdouble d;
-      jfloat f;
-  } uu;
-  uu.l = value;
-  switch (typeChar) {
-    case 'z': tty->print(value == 0 ? "false" : "true"); break;
-    case 'b': tty->print("%d", (jbyte) value); break;
-    case 'c': tty->print("%c", (jchar) value); break;
-    case 's': tty->print("%d", (jshort) value); break;
-    case 'i': tty->print("%d", (jint) value); break;
-    case 'f': tty->print("%f", uu.f); break;
-    case 'j': tty->print(INT64_FORMAT, value); break;
-    case 'd': tty->print("%lf", uu.d); break;
-    default: assert(false, "unknown typeChar"); break;
-  }
-  if (newline) {
-    tty->cr();
-  }
-JRT_END
-
-// JVM_InitializeGraalRuntime
-JVM_ENTRY(jobject, JVM_InitializeGraalRuntime(JNIEnv *env, jclass graalclass))
-  return VMToCompiler::graalRuntimePermObject();
-JVM_END
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+#include "runtime/interfaceSupport.hpp"
+#include "prims/jvm.h"
+#include "graal/graalRuntime.hpp"
+#include "graal/graalVMToCompiler.hpp"
+#include "asm/codeBuffer.hpp"
+#include "runtime/biasedLocking.hpp"
+
+// Implementation of GraalStubAssembler
+
+GraalStubAssembler::GraalStubAssembler(CodeBuffer* code, const char * name, int stub_id) : MacroAssembler(code) {
+  _name = name;
+  _must_gc_arguments = false;
+  _frame_size = no_frame_size;
+  _num_rt_args = 0;
+  _stub_id = stub_id;
+}
+
+
+void GraalStubAssembler::set_info(const char* name, bool must_gc_arguments) {
+  _name = name;
+  _must_gc_arguments = must_gc_arguments;
+}
+
+
+void GraalStubAssembler::set_frame_size(int size) {
+  if (_frame_size == no_frame_size) {
+    _frame_size = size;
+  }
+  assert(_frame_size == size, "can't change the frame size");
+}
+
+
+void GraalStubAssembler::set_num_rt_args(int args) {
+  if (_num_rt_args == 0) {
+    _num_rt_args = args;
+  }
+  assert(_num_rt_args == args, "can't change the number of args");
+}
+
+// Implementation of GraalRuntime
+
+CodeBlob* GraalRuntime::_blobs[GraalRuntime::number_of_ids];
+const char *GraalRuntime::_blob_names[] = {
+  GRAAL_STUBS(STUB_NAME, LAST_STUB_NAME)
+};
+
+// Simple helper to see if the caller of a runtime stub which
+// entered the VM has been deoptimized
+
+static bool caller_is_deopted() {
+  JavaThread* thread = JavaThread::current();
+  RegisterMap reg_map(thread, false);
+  frame runtime_frame = thread->last_frame();
+  frame caller_frame = runtime_frame.sender(&reg_map);
+  assert(caller_frame.is_compiled_frame(), "must be compiled");
+  return caller_frame.is_deoptimized_frame();
+}
+
+// Stress deoptimization
+static void deopt_caller() {
+  if ( !caller_is_deopted()) {
+    JavaThread* thread = JavaThread::current();
+    RegisterMap reg_map(thread, false);
+    frame runtime_frame = thread->last_frame();
+    frame caller_frame = runtime_frame.sender(&reg_map);
+    Deoptimization::deoptimize_frame(thread, caller_frame.id(), Deoptimization::Reason_constraint);
+    assert(caller_is_deopted(), "Must be deoptimized");
+  }
+}
+
+static bool setup_code_buffer(CodeBuffer* code) {
+  // Preinitialize the consts section to some large size:
+  int locs_buffer_size = 1 * (relocInfo::length_limit + sizeof(relocInfo));
+  char* locs_buffer = NEW_RESOURCE_ARRAY(char, locs_buffer_size);
+  code->insts()->initialize_shared_locs((relocInfo*)locs_buffer,
+                                        locs_buffer_size / sizeof(relocInfo));
+
+  // Global stubs have neither constants nor local stubs
+  code->initialize_consts_size(0);
+  code->initialize_stubs_size(0);
+
+  return true;
+}
+
+void GraalRuntime::generate_blob_for(BufferBlob* buffer_blob, StubID id) {
+  assert(0 <= id && id < number_of_ids, "illegal stub id");
+  ResourceMark rm;
+  // create code buffer for code storage
+  CodeBuffer code(buffer_blob);
+
+  setup_code_buffer(&code);
+
+  // create assembler for code generation
+  GraalStubAssembler* sasm = new GraalStubAssembler(&code, name_for(id), id);
+  // generate code for runtime stub
+  OopMapSet* oop_maps;
+  oop_maps = generate_code_for(id, sasm);
+  assert(oop_maps == NULL || sasm->frame_size() != no_frame_size,
+         "if stub has an oop map it must have a valid frame size");
+
+#ifdef ASSERT
+  // Make sure that stubs that need oopmaps have them
+  switch (id) {
+    // These stubs don't need to have an oopmap
+    case graal_slow_subtype_check_id:
+#if defined(SPARC) || defined(PPC)
+    case handle_exception_nofpu_id:  // Unused on sparc
+#endif
+#ifdef GRAAL
+    case graal_verify_oop_id:
+    case graal_unwind_exception_call_id:
+    case graal_OSR_migration_end_id:
+    case graal_arithmetic_frem_id:
+    case graal_arithmetic_drem_id:
+    case graal_set_deopt_info_id:
+#endif
+      break;
+
+    // All other stubs should have oopmaps
+    default:
+      assert(oop_maps != NULL, "must have an oopmap");
+  }
+#endif
+
+  // align so printing shows nop's instead of random code at the end (SimpleStubs are aligned)
+  sasm->align(BytesPerWord);
+  // make sure all code is in code buffer
+  sasm->flush();
+  // create blob - distinguish a few special cases
+  CodeBlob* blob = RuntimeStub::new_runtime_stub(name_for(id),
+                                                 &code,
+                                                 CodeOffsets::frame_never_safe,
+                                                 sasm->frame_size(),
+                                                 oop_maps,
+                                                 sasm->must_gc_arguments());
+  // install blob
+  assert(blob != NULL, "blob must exist");
+  _blobs[id] = blob;
+}
+
+
+void GraalRuntime::initialize(BufferBlob* blob) {
+  // generate stubs
+  for (int id = 0; id < number_of_ids; id++) generate_blob_for(blob, (StubID)id);
+  // printing
+#ifndef PRODUCT
+  if (PrintSimpleStubs) {
+    ResourceMark rm;
+    for (int id = 0; id < number_of_ids; id++) {
+      _blobs[id]->print();
+      if (_blobs[id]->oop_maps() != NULL) {
+        _blobs[id]->oop_maps()->print();
+      }
+    }
+  }
+#endif
+}
+
+
+CodeBlob* GraalRuntime::blob_for(StubID id) {
+  assert(0 <= id && id < number_of_ids, "illegal stub id");
+  return _blobs[id];
+}
+
+
+const char* GraalRuntime::name_for(StubID id) {
+  assert(0 <= id && id < number_of_ids, "illegal stub id");
+  return _blob_names[id];
+}
+
+const char* GraalRuntime::name_for_address(address entry) {
+  for (int id = 0; id < number_of_ids; id++) {
+    if (entry == entry_for((StubID)id)) return name_for((StubID)id);
+  }
+
+#define FUNCTION_CASE(a, f) \
+  if ((intptr_t)a == CAST_FROM_FN_PTR(intptr_t, f))  return #f
+
+  FUNCTION_CASE(entry, os::javaTimeMillis);
+  FUNCTION_CASE(entry, os::javaTimeNanos);
+  FUNCTION_CASE(entry, SharedRuntime::OSR_migration_end);
+  FUNCTION_CASE(entry, SharedRuntime::d2f);
+  FUNCTION_CASE(entry, SharedRuntime::d2i);
+  FUNCTION_CASE(entry, SharedRuntime::d2l);
+  FUNCTION_CASE(entry, SharedRuntime::dcos);
+  FUNCTION_CASE(entry, SharedRuntime::dexp);
+  FUNCTION_CASE(entry, SharedRuntime::dlog);
+  FUNCTION_CASE(entry, SharedRuntime::dlog10);
+  FUNCTION_CASE(entry, SharedRuntime::dpow);
+  FUNCTION_CASE(entry, SharedRuntime::drem);
+  FUNCTION_CASE(entry, SharedRuntime::dsin);
+  FUNCTION_CASE(entry, SharedRuntime::dtan);
+  FUNCTION_CASE(entry, SharedRuntime::f2i);
+  FUNCTION_CASE(entry, SharedRuntime::f2l);
+  FUNCTION_CASE(entry, SharedRuntime::frem);
+  FUNCTION_CASE(entry, SharedRuntime::l2d);
+  FUNCTION_CASE(entry, SharedRuntime::l2f);
+  FUNCTION_CASE(entry, SharedRuntime::ldiv);
+  FUNCTION_CASE(entry, SharedRuntime::lmul);
+  FUNCTION_CASE(entry, SharedRuntime::lrem);
+  FUNCTION_CASE(entry, SharedRuntime::lrem);
+  FUNCTION_CASE(entry, SharedRuntime::dtrace_method_entry);
+  FUNCTION_CASE(entry, SharedRuntime::dtrace_method_exit);
+#ifdef TRACE_HAVE_INTRINSICS
+  FUNCTION_CASE(entry, TRACE_TIME_METHOD);
+#endif
+
+  ShouldNotReachHere();
+  return NULL;
+
+#undef FUNCTION_CASE
+}
+
+
+JRT_ENTRY(void, GraalRuntime::new_instance(JavaThread* thread, Klass* klass))
+  assert(klass->is_klass(), "not a class");
+  instanceKlassHandle h(thread, klass);
+  h->check_valid_for_instantiation(true, CHECK);
+  // make sure klass is initialized
+  h->initialize(CHECK);
+  // allocate instance and return via TLS
+  oop obj = h->allocate_instance(CHECK);
+  thread->set_vm_result(obj);
+JRT_END
+
+JRT_ENTRY(void, GraalRuntime::new_array(JavaThread* thread, Klass* array_klass, jint length))
+  // Note: no handle for klass needed since they are not used
+  //       anymore after new_objArray() and no GC can happen before.
+  //       (This may have to change if this code changes!)
+  assert(array_klass->is_klass(), "not a class");
+  oop obj;
+  if (array_klass->oop_is_typeArray()) {
+    BasicType elt_type = TypeArrayKlass::cast(array_klass)->element_type();
+    obj = oopFactory::new_typeArray(elt_type, length, CHECK);
+  } else {
+    Klass* elem_klass = ObjArrayKlass::cast(array_klass)->element_klass();
+    obj = oopFactory::new_objArray(elem_klass, length, CHECK);
+  }
+  thread->set_vm_result(obj);
+  // This is pretty rare but this runtime patch is stressful to deoptimization
+  // if we deoptimize here so force a deopt to stress the path.
+  if (DeoptimizeALot) {
+    deopt_caller();
+  }
+JRT_END
+
+
+JRT_ENTRY(void, GraalRuntime::new_multi_array(JavaThread* thread, Klass* klass, int rank, jint* dims))
+  assert(klass->is_klass(), "not a class");
+  assert(rank >= 1, "rank must be nonzero");
+  oop obj = ArrayKlass::cast(klass)->multi_allocate(rank, dims, CHECK);
+  thread->set_vm_result(obj);
+JRT_END
+
+JRT_ENTRY(void, GraalRuntime::unimplemented_entry(JavaThread* thread, StubID id))
+  tty->print_cr("GraalRuntime::entry_for(%d) returned unimplemented entry point", id);
+JRT_END
+
+extern void vm_exit(int code);
+
+// Enter this method from compiled code handler below. This is where we transition
+// to VM mode. This is done as a helper routine so that the method called directly
+// from compiled code does not have to transition to VM. This allows the entry
+// method to see if the nmethod that we have just looked up a handler for has
+// been deoptimized while we were in the vm. This simplifies the assembly code
+// cpu directories.
+//
+// We are entering here from exception stub (via the entry method below)
+// If there is a compiled exception handler in this method, we will continue there;
+// otherwise we will unwind the stack and continue at the caller of top frame method
+// Note: we enter in Java using a special JRT wrapper. This wrapper allows us to
+// control the area where we can allow a safepoint. After we exit the safepoint area we can
+// check to see if the handler we are going to return is now in a nmethod that has
+// been deoptimized. If that is the case we return the deopt blob
+// unpack_with_exception entry instead. This makes life for the exception blob easier
+// because making that same check and diverting is painful from assembly language.
+JRT_ENTRY_NO_ASYNC(static address, exception_handler_for_pc_helper(JavaThread* thread, oopDesc* ex, address pc, nmethod*& nm))
+  // Reset method handle flag.
+  thread->set_is_method_handle_return(false);
+
+  Handle exception(thread, ex);
+  nm = CodeCache::find_nmethod(pc);
+  assert(nm != NULL, "this is not an nmethod");
+  // Adjust the pc as needed/
+  if (nm->is_deopt_pc(pc)) {
+    RegisterMap map(thread, false);
+    frame exception_frame = thread->last_frame().sender(&map);
+    // if the frame isn't deopted then pc must not correspond to the caller of last_frame
+    assert(exception_frame.is_deoptimized_frame(), "must be deopted");
+    pc = exception_frame.pc();
+  }
+#ifdef ASSERT
+  assert(exception.not_null(), "NULL exceptions should be handled by throw_exception");
+  assert(exception->is_oop(), "just checking");
+  // Check that exception is a subclass of Throwable, otherwise we have a VerifyError
+  if (!(exception->is_a(SystemDictionary::Throwable_klass()))) {
+    if (ExitVMOnVerifyError) vm_exit(-1);
+    ShouldNotReachHere();
+  }
+#endif
+
+  // Check the stack guard pages and reenable them if necessary and there is
+  // enough space on the stack to do so.  Use fast exceptions only if the guard
+  // pages are enabled.
+  bool guard_pages_enabled = thread->stack_yellow_zone_enabled();
+  if (!guard_pages_enabled) guard_pages_enabled = thread->reguard_stack();
+
+  if (JvmtiExport::can_post_on_exceptions()) {
+    // To ensure correct notification of exception catches and throws
+    // we have to deoptimize here.  If we attempted to notify the
+    // catches and throws during this exception lookup it's possible
+    // we could deoptimize on the way out of the VM and end back in
+    // the interpreter at the throw site.  This would result in double
+    // notifications since the interpreter would also notify about
+    // these same catches and throws as it unwound the frame.
+
+    RegisterMap reg_map(thread);
+    frame stub_frame = thread->last_frame();
+    frame caller_frame = stub_frame.sender(&reg_map);
+
+    // We don't really want to deoptimize the nmethod itself since we
+    // can actually continue in the exception handler ourselves but I
+    // don't see an easy way to have the desired effect.
+    Deoptimization::deoptimize_frame(thread, caller_frame.id(), Deoptimization::Reason_constraint);
+    assert(caller_is_deopted(), "Must be deoptimized");
+
+    return SharedRuntime::deopt_blob()->unpack_with_exception_in_tls();
+  }
+
+  // ExceptionCache is used only for exceptions at call sites and not for implicit exceptions
+  if (guard_pages_enabled) {
+    address fast_continuation = nm->handler_for_exception_and_pc(exception, pc);
+    if (fast_continuation != NULL) {
+      // Set flag if return address is a method handle call site.
+      thread->set_is_method_handle_return(nm->is_method_handle_return(pc));
+      return fast_continuation;
+    }
+  }
+
+  // If the stack guard pages are enabled, check whether there is a handler in
+  // the current method.  Otherwise (guard pages disabled), force an unwind and
+  // skip the exception cache update (i.e., just leave continuation==NULL).
+  address continuation = NULL;
+  if (guard_pages_enabled) {
+
+    // New exception handling mechanism can support inlined methods
+    // with exception handlers since the mappings are from PC to PC
+
+    // debugging support
+    // tracing
+    if (TraceExceptions) {
+      ttyLocker ttyl;
+      ResourceMark rm;
+      int offset = pc - nm->code_begin();
+      tty->print_cr("Exception <%s> (0x%x) thrown in compiled method <%s> at PC " PTR_FORMAT " [" PTR_FORMAT "+%d] for thread 0x%x",
+                    exception->print_value_string(), (address)exception(), nm->method()->print_value_string(), pc, nm->code_begin(), offset, thread);
+    }
+    // for AbortVMOnException flag
+    NOT_PRODUCT(Exceptions::debug_check_abort(exception));
+
+    // Clear out the exception oop and pc since looking up an
+    // exception handler can cause class loading, which might throw an
+    // exception and those fields are expected to be clear during
+    // normal bytecode execution.
+    thread->set_exception_oop(NULL);
+    thread->set_exception_pc(NULL);
+
+    continuation = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, false, false);
+    // If an exception was thrown during exception dispatch, the exception oop may have changed
+    thread->set_exception_oop(exception());
+    thread->set_exception_pc(pc);
+
+    // the exception cache is used only by non-implicit exceptions
+    if (continuation != NULL && !SharedRuntime::deopt_blob()->contains(continuation)) {
+      nm->add_handler_for_exception_and_pc(exception, pc, continuation);
+    }
+  }
+
+  thread->set_vm_result(exception());
+  // Set flag if return address is a method handle call site.
+  thread->set_is_method_handle_return(nm->is_method_handle_return(pc));
+
+  if (TraceExceptions) {
+    ttyLocker ttyl;
+    ResourceMark rm;
+    tty->print_cr("Thread " PTR_FORMAT " continuing at PC " PTR_FORMAT " for exception thrown at PC " PTR_FORMAT,
+                  thread, continuation, pc);
+  }
+
+  return continuation;
+JRT_END
+
+// Enter this method from compiled code only if there is a Java exception handler
+// in the method handling the exception.
+// We are entering here from exception stub. We don't do a normal VM transition here.
+// We do it in a helper. This is so we can check to see if the nmethod we have just
+// searched for an exception handler has been deoptimized in the meantime.
+address GraalRuntime::exception_handler_for_pc(JavaThread* thread) {
+  oop exception = thread->exception_oop();
+  address pc = thread->exception_pc();
+  // Still in Java mode
+  DEBUG_ONLY(ResetNoHandleMark rnhm);
+  nmethod* nm = NULL;
+  address continuation = NULL;
+  {
+    // Enter VM mode by calling the helper
+    ResetNoHandleMark rnhm;
+    continuation = exception_handler_for_pc_helper(thread, exception, pc, nm);
+  }
+  // Back in JAVA, use no oops DON'T safepoint
+
+  // Now check to see if the nmethod we were called from is now deoptimized.
+  // If so we must return to the deopt blob and deoptimize the nmethod
+  if (nm != NULL && caller_is_deopted()) {
+    continuation = SharedRuntime::deopt_blob()->unpack_with_exception_in_tls();
+  }
+
+  assert(continuation != NULL, "no handler found");
+  return continuation;
+}
+
+JRT_ENTRY(void, GraalRuntime::graal_create_null_exception(JavaThread* thread))
+  thread->set_vm_result(Exceptions::new_exception(thread, vmSymbols::java_lang_NullPointerException(), NULL)());
+JRT_END
+
+JRT_ENTRY(void, GraalRuntime::graal_create_out_of_bounds_exception(JavaThread* thread, jint index))
+  char message[jintAsStringSize];
+  sprintf(message, "%d", index);
+  thread->set_vm_result(Exceptions::new_exception(thread, vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), message)());
+JRT_END
+
+JRT_ENTRY_NO_ASYNC(void, GraalRuntime::graal_monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock))
+  if (TraceGraal >= 3) {
+    char type[O_BUFLEN];
+    obj->klass()->name()->as_C_string(type, O_BUFLEN);
+    markOop mark = obj->mark();
+    tty->print_cr("%s: entered locking slow case with obj=" INTPTR_FORMAT ", type=%s, mark=" INTPTR_FORMAT ", lock=" INTPTR_FORMAT, thread->name(), obj, type, mark, lock);
+    tty->flush();
+  }
+#ifdef ASSERT
+  if (PrintBiasedLockingStatistics) {
+    Atomic::inc(BiasedLocking::slow_path_entry_count_addr());
+  }
+#endif
+  Handle h_obj(thread, obj);
+  assert(h_obj()->is_oop(), "must be NULL or an object");
+  if (UseBiasedLocking) {
+    // Retry fast entry if bias is revoked to avoid unnecessary inflation
+    ObjectSynchronizer::fast_enter(h_obj, lock, true, CHECK);
+  } else {
+    if (UseFastLocking) {
+      // When using fast locking, the compiled code has already tried the fast case
+      ObjectSynchronizer::slow_enter(h_obj, lock, THREAD);
+    } else {
+      ObjectSynchronizer::fast_enter(h_obj, lock, false, THREAD);
+    }
+  }
+  if (TraceGraal >= 3) {
+    tty->print_cr("%s: exiting locking slow with obj=" INTPTR_FORMAT, thread->name(), obj);
+  }
+JRT_END
+
+
+JRT_LEAF(void, GraalRuntime::graal_monitorexit(JavaThread* thread, oopDesc* obj, BasicLock* lock))
+  assert(thread == JavaThread::current(), "threads must correspond");
+  assert(thread->last_Java_sp(), "last_Java_sp must be set");
+  // monitorexit is non-blocking (leaf routine) => no exceptions can be thrown
+  EXCEPTION_MARK;
+
+#ifdef DEBUG
+  if (!obj->is_oop()) {
+    ResetNoHandleMark rhm;
+    nmethod* method = thread->last_frame().cb()->as_nmethod_or_null();
+    if (method != NULL) {
+      tty->print_cr("ERROR in monitorexit in method %s wrong obj " INTPTR_FORMAT, method->name(), obj);
+    }
+    thread->print_stack_on(tty);
+    assert(false, "invalid lock object pointer dected");
+  }
+#endif
+
+  if (UseFastLocking) {
+    // When using fast locking, the compiled code has already tried the fast case
+    ObjectSynchronizer::slow_exit(obj, lock, THREAD);
+  } else {
+    ObjectSynchronizer::fast_exit(obj, lock, THREAD);
+  }
+  if (TraceGraal >= 3) {
+    char type[O_BUFLEN];
+    obj->klass()->name()->as_C_string(type, O_BUFLEN);
+    tty->print_cr("%s: exited locking slow case with obj=" INTPTR_FORMAT ", type=%s, mark=" INTPTR_FORMAT ", lock=" INTPTR_FORMAT, thread->name(), obj, type, obj->mark(), lock);
+    tty->flush();
+  }
+JRT_END
+
+JRT_ENTRY(void, GraalRuntime::graal_log_object(JavaThread* thread, oop obj, jint flags))
+  bool string =  mask_bits_are_true(flags, LOG_OBJECT_STRING);
+  bool address = mask_bits_are_true(flags, LOG_OBJECT_ADDRESS);
+  bool newline = mask_bits_are_true(flags, LOG_OBJECT_NEWLINE);
+  if (!string) {
+    if (!address && obj->is_oop_or_null(true)) {
+      char buf[O_BUFLEN];
+      tty->print("%s@%p", obj->klass()->name()->as_C_string(buf, O_BUFLEN), obj);
+    } else {
+      tty->print("%p", obj);
+    }
+  } else {
+    ResourceMark rm;
+    assert(obj != NULL && java_lang_String::is_instance(obj), "must be");
+    char *buf = java_lang_String::as_utf8_string(obj);
+    tty->print(buf);
+  }
+  if (newline) {
+    tty->cr();
+  }
+JRT_END
+
+JRT_ENTRY(void, GraalRuntime::graal_vm_error(JavaThread* thread, oop where, oop format, jlong value))
+  ResourceMark rm;
+  assert(where == NULL || java_lang_String::is_instance(where), "must be");
+  const char *error_msg = where == NULL ? "<internal Graal error>" : java_lang_String::as_utf8_string(where);
+  char *detail_msg = NULL;
+  if (format != NULL) {
+    const char* buf = java_lang_String::as_utf8_string(format);
+    size_t detail_msg_length = strlen(buf) * 2;
+    detail_msg = (char *) NEW_RESOURCE_ARRAY(u_char, detail_msg_length);
+    jio_snprintf(detail_msg, detail_msg_length, buf, value);
+  }
+  report_vm_error(__FILE__, __LINE__, error_msg, detail_msg);
+JRT_END
+
+JRT_ENTRY(void, GraalRuntime::graal_log_printf(JavaThread* thread, oop format, jlong val))
+  ResourceMark rm;
+  assert(format != NULL && java_lang_String::is_instance(format), "must be");
+  char *buf = java_lang_String::as_utf8_string(format);
+  tty->print(buf, val);
+JRT_END
+
+JRT_ENTRY(void, GraalRuntime::graal_log_primitive(JavaThread* thread, jchar typeChar, jlong value, jboolean newline))
+  union {
+      jlong l;
+      jdouble d;
+      jfloat f;
+  } uu;
+  uu.l = value;
+  switch (typeChar) {
+    case 'z': tty->print(value == 0 ? "false" : "true"); break;
+    case 'b': tty->print("%d", (jbyte) value); break;
+    case 'c': tty->print("%c", (jchar) value); break;
+    case 's': tty->print("%d", (jshort) value); break;
+    case 'i': tty->print("%d", (jint) value); break;
+    case 'f': tty->print("%f", uu.f); break;
+    case 'j': tty->print(INT64_FORMAT, value); break;
+    case 'd': tty->print("%lf", uu.d); break;
+    default: assert(false, "unknown typeChar"); break;
+  }
+  if (newline) {
+    tty->cr();
+  }
+JRT_END
+
+JRT_ENTRY(jint, GraalRuntime::graal_identity_hash_code(JavaThread* thread, oop obj))
+  return (jint) obj->identity_hash();
+JRT_END
+
+JRT_ENTRY(jboolean, GraalRuntime::graal_thread_is_interrupted(JavaThread* thread, oop receiver, jboolean clear_interrupted))
+  // TEMP:
+  tty->print_cr("ThreadIsInterruptedSlowCase");
+
+  // Ensure that the C++ Thread and OSThread structures aren't freed before we operate
+  Handle receiverHandle(thread, receiver);
+  JRT_BLOCK
+    MutexLockerEx ml(thread->threadObj() == receiver ? NULL : Threads_lock);
+    JavaThread* receiverThread = java_lang_Thread::thread(receiverHandle());
+    return (jint) Thread::is_interrupted(receiverThread, clear_interrupted != 0);
+  JRT_BLOCK_END
+JRT_END
+
+// JVM_InitializeGraalRuntime
+JVM_ENTRY(jobject, JVM_InitializeGraalRuntime(JNIEnv *env, jclass graalclass))
+  return VMToCompiler::graalRuntimePermObject();
+JVM_END
--- a/src/share/vm/graal/graalRuntime.hpp	Mon Dec 10 22:19:07 2012 +0100
+++ b/src/share/vm/graal/graalRuntime.hpp	Tue Dec 11 08:48:12 2012 +0100
@@ -98,6 +98,8 @@
   stub(graal_log_object)              \
   stub(graal_log_printf)              \
   stub(graal_log_primitive)           \
+  stub(graal_identity_hash_code)      \
+  stub(graal_thread_is_interrupted)   \
   last_entry(number_of_ids)
 
 #define DECLARE_STUB_ID(x)       x ## _id ,
@@ -142,6 +144,9 @@
   static void graal_vm_error(JavaThread* thread, oop where, oop format, jlong value);
   static void graal_log_printf(JavaThread* thread, oop format, jlong value);
   static void graal_log_primitive(JavaThread* thread, jchar typeChar, jlong value, jboolean newline);
+  
+  static jint graal_identity_hash_code(JavaThread* thread, oopDesc* objd);
+  static jboolean graal_thread_is_interrupted(JavaThread* thread, oopDesc* obj, jboolean clear_interrupte);
 
   // Note: Must be kept in sync with constants in com.oracle.graal.snippets.Log
   enum {
--- a/src/share/vm/runtime/globals.hpp	Mon Dec 10 22:19:07 2012 +0100
+++ b/src/share/vm/runtime/globals.hpp	Tue Dec 11 08:48:12 2012 +0100
@@ -2924,7 +2924,7 @@
           "if non-zero, start verifying C heap after Nth call to "          \
           "malloc/realloc/free")                                            \
                                                                             \
-  product(intx, TypeProfileWidth,     2,                                   \
+  product_pd(intx, TypeProfileWidth,                                        \
           "number of receiver types to record in call/cast profile")        \
                                                                             \
   develop(intx, BciProfileWidth,      2,                                    \
--- a/src/share/vm/runtime/vframeArray.cpp	Mon Dec 10 22:19:07 2012 +0100
+++ b/src/share/vm/runtime/vframeArray.cpp	Tue Dec 11 08:48:12 2012 +0100
@@ -311,6 +311,10 @@
     }
   }
 
+  if (PrintDeoptimizationDetails) {
+    tty->print_cr("Expressions size: %d", expressions()->size());
+  }
+
   // Unpack expression stack
   // If this is an intermediate frame (i.e. not top frame) then this
   // only unpacks the part of the expression stack not used by callee
@@ -323,9 +327,25 @@
     switch(value->type()) {
       case T_INT:
         *addr = value->get_int();
+#ifndef PRODUCT
+        if (PrintDeoptimizationDetails) {
+          tty->print_cr("Reconstructed expression %d (INT): %d", i, (int)(*addr));
+        }
+#endif
         break;
       case T_OBJECT:
         *addr = value->get_int(T_OBJECT);
+#ifndef PRODUCT
+        if (PrintDeoptimizationDetails) {
+          tty->print("Reconstructed expression %d (OBJECT): ", i);
+          oop o = (oop)(*addr);
+          if (o == NULL) {
+            tty->print_cr("NULL");
+          } else {
+            tty->print_cr(err_msg("%s", o->klass()->name()->as_C_string()));
+          }
+        }
+#endif
         break;
       case T_CONFLICT:
         // A dead stack slot.  Initialize to null in case it is an oop.
@@ -344,9 +364,25 @@
     switch(value->type()) {
       case T_INT:
         *addr = value->get_int();
+#ifndef PRODUCT
+        if (PrintDeoptimizationDetails) {
+          tty->print_cr("Reconstructed local %d (INT): %d", i, (int)(*addr));
+        }
+#endif
         break;
       case T_OBJECT:
         *addr = value->get_int(T_OBJECT);
+#ifndef PRODUCT
+        if (PrintDeoptimizationDetails) {
+          tty->print("Reconstructed local %d (OBJECT): ", i);
+          oop o = (oop)(*addr);
+          if (o == NULL) {
+            tty->print_cr("NULL");
+          } else {
+            tty->print_cr(err_msg("%s", o->klass()->name()->as_C_string()));
+          }
+        }
+#endif
         break;
       case T_CONFLICT:
         // A dead location. If it is an oop then we need a NULL to prevent GC from following it
@@ -388,18 +424,13 @@
   }
 
 #ifndef PRODUCT
-  if (TraceDeoptimization && Verbose) {
+  if (PrintDeoptimizationDetails) {
     ttyLocker ttyl;
     tty->print_cr("[%d Interpreted Frame]", ++unpack_counter);
     iframe()->print_on(tty);
     RegisterMap map(thread);
     vframe* f = vframe::new_vframe(iframe(), &map, thread);
     f->print();
-
-    tty->print_cr("locals size     %d", locals()->size());
-    tty->print_cr("expression size %d", expressions()->size());
-
-    method()->print_value();
     tty->cr();
     // method()->print_codes();
   } else if (TraceDeoptimization) {