changeset 15054:d4a9d6f6e57d

Merge.
author Doug Simon <doug.simon@oracle.com>
date Thu, 10 Apr 2014 09:14:35 +0200
parents 04f1723150b4 (diff) d8b9e3761e52 (current diff)
children 3090f1254aa3
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java src/share/vm/graal/graalCompilerToVM.cpp
diffstat 22 files changed, 365 insertions(+), 119 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotNodeClassSubstitutionsTest.java	Thu Apr 10 09:14:35 2014 +0200
@@ -0,0 +1,44 @@
+/*
+ * 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.test;
+
+import org.junit.*;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.replacements.test.*;
+
+/**
+ * Tests HotSpot specific substitutions for {@link NodeClass}.
+ */
+public class HotSpotNodeClassSubstitutionsTest extends MethodSubstitutionTest {
+
+    @Test
+    public void test() {
+        test("get", ValueNode.class);
+    }
+
+    public static NodeClass get(Class<?> c) {
+        return NodeClass.get(c);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotNodeSubstitutionsTest.java	Thu Apr 10 09:14:35 2014 +0200
@@ -0,0 +1,45 @@
+/*
+ * 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.test;
+
+import org.junit.*;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.replacements.test.*;
+
+/**
+ * Tests HotSpot specific substitutions for {@link Node}.
+ */
+public class HotSpotNodeSubstitutionsTest extends MethodSubstitutionTest {
+
+    @Test
+    public void test() {
+        StructuredGraph graph = new StructuredGraph();
+        test("getNodeClass", ConstantNode.forInt(42, graph));
+    }
+
+    public static NodeClass getNodeClass(Node n) {
+        return n.getNodeClass();
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Wed Apr 09 22:45:27 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Thu Apr 10 09:14:35 2014 +0200
@@ -857,6 +857,7 @@
     @HotSpotVMField(name = "Array<Klass*>::_length", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int metaspaceArrayLengthOffset;
     @HotSpotVMField(name = "Array<Klass*>::_data[0]", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int metaspaceArrayBaseOffset;
 
+    @HotSpotVMField(name = "InstanceKlass::_graal_node_class", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int klassNodeClassOffset;
     @HotSpotVMField(name = "InstanceKlass::_source_file_name_index", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int klassSourceFileNameIndexOffset;
     @HotSpotVMField(name = "InstanceKlass::_init_state", type = "u1", get = HotSpotVMField.Type.OFFSET) @Stable public int klassStateOffset;
     @HotSpotVMField(name = "InstanceKlass::_constants", type = "ConstantPool*", get = HotSpotVMField.Type.OFFSET) @Stable public int instanceKlassConstantsOffset;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Wed Apr 09 22:45:27 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Thu Apr 10 09:14:35 2014 +0200
@@ -282,7 +282,11 @@
 
     String getFileName(HotSpotResolvedJavaType method);
 
-    Object readUnsafeUncompressedPointer(Object o, long displacement);
+    Class<?> getJavaMirror(long metaspaceKlass);
+
+    NodeClass getNodeClass(Class<?> c);
+
+    void setNodeClass(Class<?> c, NodeClass nodeClass);
 
     long readUnsafeKlassPointer(Object o);
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Wed Apr 09 22:45:27 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Thu Apr 10 09:14:35 2014 +0200
@@ -24,6 +24,7 @@
 package com.oracle.graal.hotspot.bridge;
 
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
 
@@ -141,7 +142,13 @@
     public native void invalidateInstalledCode(HotSpotInstalledCode hotspotInstalledCode);
 
     @Override
-    public native Object readUnsafeUncompressedPointer(Object o, long displacement);
+    public native Class<?> getJavaMirror(long metaspaceKlass);
+
+    @Override
+    public native NodeClass getNodeClass(Class<?> c);
+
+    @Override
+    public native void setNodeClass(Class<?> c, NodeClass nodeClass);
 
     @Override
     public native long readUnsafeKlassPointer(Object o);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/FastNodeClassRegistry.java	Wed Apr 09 22:45:27 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/FastNodeClassRegistry.java	Thu Apr 10 09:14:35 2014 +0200
@@ -23,29 +23,30 @@
 package com.oracle.graal.hotspot.bridge;
 
 import com.oracle.graal.graph.*;
-import com.oracle.graal.hotspot.meta.*;
 
 /**
- * A fast-path for {@link NodeClass} retrieval using {@link HotSpotResolvedObjectType}.
+ * Direct access to the {@code InstanceKlass::_graal_node_class} field.
  */
 class FastNodeClassRegistry extends NodeClass.Registry {
 
-    @SuppressWarnings("unused")
-    static void initialize() {
-        new FastNodeClassRegistry();
+    private final CompilerToVM vm;
+
+    public FastNodeClassRegistry(CompilerToVM vm) {
+        this.vm = vm;
     }
 
-    private static HotSpotResolvedObjectType type(Class<? extends Node> key) {
-        return (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromClass(key);
+    @SuppressWarnings("unused")
+    static void initialize(CompilerToVM vm) {
+        new FastNodeClassRegistry(vm);
     }
 
     @Override
     public NodeClass get(Class<? extends Node> key) {
-        return type(key).getNodeClass();
+        return vm.getNodeClass(key);
     }
 
     @Override
     protected void registered(Class<? extends Node> key, NodeClass value) {
-        type(key).setNodeClass(value);
+        vm.setNodeClass(key, value);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Wed Apr 09 22:45:27 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Thu Apr 10 09:14:35 2014 +0200
@@ -144,7 +144,7 @@
 
     public void startCompiler(boolean bootstrapEnabled) throws Throwable {
 
-        FastNodeClassRegistry.initialize();
+        FastNodeClassRegistry.initialize(runtime.getCompilerToVM());
 
         bootstrapRunning = bootstrapEnabled;
 
@@ -250,7 +250,7 @@
 
     /**
      * Take action related to entering a new execution phase.
-     * 
+     *
      * @param phase the execution phase being entered
      */
     protected void phaseTransition(String phase) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java	Wed Apr 09 22:45:27 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java	Thu Apr 10 09:14:35 2014 +0200
@@ -105,8 +105,15 @@
                 Object o = null;
                 if (baseConstant.getKind() == Kind.Object) {
                     o = unsafe.getObject(base, displacement);
+                } else if (baseConstant instanceof HotSpotMetaspaceConstant) {
+                    Object metaspaceObject = HotSpotMetaspaceConstant.getMetaspaceObject(baseConstant);
+                    if (metaspaceObject instanceof HotSpotResolvedObjectType && initialDisplacement == runtime.getConfig().classMirrorOffset) {
+                        o = ((HotSpotResolvedObjectType) metaspaceObject).mirror();
+                    } else {
+                        throw GraalInternalError.shouldNotReachHere();
+                    }
                 } else {
-                    o = runtime.getCompilerToVM().readUnsafeUncompressedPointer(base, displacement);
+                    throw GraalInternalError.shouldNotReachHere();
                 }
                 return HotSpotObjectConstant.forObject(o);
             }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Wed Apr 09 22:45:27 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Thu Apr 10 09:14:35 2014 +0200
@@ -48,11 +48,6 @@
      */
     private final Class<?> javaClass;
 
-    /**
-     * Used for implemented a lazy binding from a {@link Node} type to a {@link NodeClass} value.
-     */
-    private NodeClass nodeClass;
-
     private HashMap<Long, HotSpotResolvedJavaField> fieldCache;
     private HashMap<Long, HotSpotResolvedJavaMethod> methodCache;
     private HotSpotResolvedJavaField[] instanceFields;
@@ -79,7 +74,7 @@
      */
     public static ResolvedJavaType fromMetaspaceKlass(long metaspaceKlass) {
         assert metaspaceKlass != 0;
-        Class<?> javaClass = (Class<?>) runtime().getCompilerToVM().readUnsafeUncompressedPointer(null, metaspaceKlass + runtime().getConfig().classMirrorOffset);
+        Class<?> javaClass = runtime().getCompilerToVM().getJavaMirror(metaspaceKlass);
         assert javaClass != null;
         return fromClass(javaClass);
     }
@@ -750,20 +745,6 @@
         return HotSpotObjectConstant.forObject(Array.newInstance(mirror(), length));
     }
 
-    /**
-     * @return the {@link NodeClass} value (which may be {@code null}) associated with this type
-     */
-    public NodeClass getNodeClass() {
-        return nodeClass;
-    }
-
-    /**
-     * Sets the {@link NodeClass} value associated with this type.
-     */
-    public void setNodeClass(NodeClass nodeClass) {
-        this.nodeClass = nodeClass;
-    }
-
     @Override
     public String toString() {
         String simpleName;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNodeClassSubstitutions.java	Thu Apr 10 09:14:35 2014 +0200
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+package com.oracle.graal.hotspot.replacements;
+
+import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
+import static com.oracle.graal.nodes.PiNode.*;
+import static com.oracle.graal.phases.GraalOptions.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.replacements.nodes.*;
+import com.oracle.graal.word.*;
+
+/**
+ * Substitutions for improving the performance of {@link NodeClass#get}.
+ */
+@ClassSubstitution(NodeClass.class)
+public class HotSpotNodeClassSubstitutions {
+
+    /**
+     * A macro node for calls to {@link NodeClass#get(Class)}. It can use the compiler's knowledge
+     * about node classes to replace itself with a constant value for a constant {@link Class}
+     * parameter.
+     */
+    public static class NodeClassGetNode extends PureFunctionMacroNode {
+
+        public NodeClassGetNode(Invoke invoke) {
+            super(invoke);
+        }
+
+        @Override
+        protected Constant evaluate(Constant param, MetaAccessProvider metaAccess) {
+            if (param.isNull() || ImmutableCode.getValue()) {
+                return null;
+            }
+            return HotSpotObjectConstant.forObject(NodeClass.get((Class<?>) HotSpotObjectConstant.asObject(param)));
+        }
+    }
+
+    @MacroSubstitution(isStatic = true, forced = true, macro = NodeClassGetNode.class)
+    @MethodSubstitution(isStatic = true)
+    public static NodeClass get(Class<?> c) {
+        Word klass = loadWordFromObject(c, klassOffset());
+        NodeClass nc = piCastExact(klass.readObject(Word.signed(klassNodeClassOffset()), KLASS_NODE_CLASS), NodeClass.class);
+        if (nc != null) {
+            return nc;
+        }
+        return get(c);
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNodeSubstitutions.java	Thu Apr 10 09:14:35 2014 +0200
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+package com.oracle.graal.hotspot.replacements;
+
+import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
+import static com.oracle.graal.nodes.PiNode.*;
+
+import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.word.*;
+
+@ClassSubstitution(Node.class)
+public class HotSpotNodeSubstitutions {
+
+    /**
+     * Partial substitution of {@link Node#getNodeClass()} that returns the value of the
+     * InstanceKlass::_graal_node_class C++ field if it is non-null.
+     */
+    @MethodSubstitution(isStatic = false)
+    public static NodeClass getNodeClass(final Node thisObj) {
+        Word klass = loadHub(thisObj);
+        NodeClass nc = piCastExact(klass.readObject(Word.signed(klassNodeClassOffset()), KLASS_NODE_CLASS), NodeClass.class);
+        if (nc != null) {
+            return nc;
+        }
+        return getNodeClass(thisObj);
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Wed Apr 09 22:45:27 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Thu Apr 10 09:14:35 2014 +0200
@@ -556,6 +556,13 @@
         return config().arrayKlassOffset;
     }
 
+    public static final LocationIdentity KLASS_NODE_CLASS = new NamedLocationIdentity("KlassNodeClass");
+
+    @Fold
+    public static int klassNodeClassOffset() {
+        return config().klassNodeClassOffset;
+    }
+
     @Fold
     public static int classMirrorOffset() {
         return config().classMirrorOffset;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSubstitutions.java	Wed Apr 09 22:45:27 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSubstitutions.java	Thu Apr 10 09:14:35 2014 +0200
@@ -42,7 +42,8 @@
         replacements.registerSubstitutions(CipherBlockChainingSubstitutions.class);
         replacements.registerSubstitutions(CRC32Substitutions.class);
         replacements.registerSubstitutions(ReflectionSubstitutions.class);
-        replacements.registerSubstitutions(NodeClassSubstitutions.class);
+        replacements.registerSubstitutions(HotSpotNodeClassSubstitutions.class);
+        replacements.registerSubstitutions(HotSpotNodeSubstitutions.class);
         replacements.registerSubstitutions(CompositeValueClassSubstitutions.class);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NodeClassSubstitutions.java	Wed Apr 09 22:45:27 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * 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.
- */
-package com.oracle.graal.hotspot.replacements;
-
-import static com.oracle.graal.phases.GraalOptions.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.replacements.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.replacements.nodes.*;
-
-/**
- * Substitutions for improving the performance of some critical methods in {@link NodeClass}
- * methods.
- */
-@ClassSubstitution(NodeClass.class)
-public class NodeClassSubstitutions {
-
-    /**
-     * A macro node for calls to {@link NodeClass#get(Class)}. It can use the compiler's knowledge
-     * about node classes to replace itself with a constant value for a constant {@link Class}
-     * parameter.
-     */
-    public static class NodeClassGetNode extends PureFunctionMacroNode {
-
-        public NodeClassGetNode(Invoke invoke) {
-            super(invoke);
-        }
-
-        @Override
-        protected Constant evaluate(Constant param, MetaAccessProvider metaAccess) {
-            if (param.isNull() || ImmutableCode.getValue()) {
-                return null;
-            }
-            return HotSpotObjectConstant.forObject(NodeClass.get((Class<?>) HotSpotObjectConstant.asObject(param)));
-        }
-    }
-
-    @MacroSubstitution(isStatic = true, forced = true, macro = NodeClassGetNode.class)
-    private static native NodeClass get(Class<?> c);
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java	Wed Apr 09 22:45:27 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java	Thu Apr 10 09:14:35 2014 +0200
@@ -108,6 +108,10 @@
         return piCast(object, toType, true, true);
     }
 
+    public static <T> T piCastExact(Object object, @ConstantNodeParameter Class<T> toType) {
+        return piCast(object, toType, true, false);
+    }
+
     public static <T> T piCast(Object object, @ConstantNodeParameter Class<T> toType) {
         return piCast(object, toType, false, false);
     }
--- a/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/MethodSubstitutionVerifier.java	Wed Apr 09 22:45:27 2014 -0700
+++ b/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/MethodSubstitutionVerifier.java	Thu Apr 10 09:14:35 2014 +0200
@@ -89,17 +89,17 @@
         }
 
         String originalName = originalName(substitutionMethod, annotation);
-        TypeMirror[] originalSignature = originalSignature(substitutionMethod, annotation);
+        TypeMirror[] originalSignature = originalSignature(originalType, substitutionMethod, annotation);
         if (originalSignature == null) {
             return;
         }
         ExecutableElement originalMethod = originalMethod(substitutionMethod, annotation, originalType, originalName, originalSignature);
         if (DEBUG && originalMethod != null) {
-            env.getMessager().printMessage(Kind.ERROR, String.format("Found original method %s in type %s.", originalMethod, findEnclosingClass(originalMethod)));
+            env.getMessager().printMessage(Kind.NOTE, String.format("Found original method %s in type %s.", originalMethod, findEnclosingClass(originalMethod)));
         }
     }
 
-    private TypeMirror[] originalSignature(ExecutableElement method, AnnotationMirror annotation) {
+    private TypeMirror[] originalSignature(TypeElement originalType, ExecutableElement method, AnnotationMirror annotation) {
         boolean isStatic = resolveAnnotationValue(Boolean.class, findAnnotationValue(annotation, ORIGINAL_IS_STATIC));
         AnnotationValue signatureValue = findAnnotationValue(annotation, ORIGINAL_SIGNATURE);
         String signatureString = resolveAnnotationValue(String.class, signatureValue);
@@ -113,7 +113,11 @@
                     env.getMessager().printMessage(Kind.ERROR, "Method signature must be a static method with the 'this' object as its first parameter", method, annotation);
                     return null;
                 } else {
-                    parameters.remove(0);
+                    TypeMirror thisParam = parameters.remove(0);
+                    if (!isSubtype(originalType.asType(), thisParam)) {
+                        Name thisName = method.getParameters().get(0).getSimpleName();
+                        env.getMessager().printMessage(Kind.ERROR, String.format("The type of %s must assignable from %s", thisName, originalType), method, annotation);
+                    }
                 }
             }
             parameters.add(0, method.getReturnType());
@@ -201,6 +205,26 @@
         return env.getTypeUtils().isSameType(original, substitution);
     }
 
+    /**
+     * Tests whether one type is a subtype of another. Any type is considered to be a subtype of
+     * itself.
+     *
+     * @param t1 the first type
+     * @param t2 the second type
+     * @return {@code true} if and only if the first type is a subtype of the second
+     */
+    private boolean isSubtype(TypeMirror t1, TypeMirror t2) {
+        TypeMirror t1Erased = t1;
+        TypeMirror t2Erased = t2;
+        if (needsErasure(t1Erased)) {
+            t1Erased = env.getTypeUtils().erasure(t1Erased);
+        }
+        if (needsErasure(t2Erased)) {
+            t2Erased = env.getTypeUtils().erasure(t2Erased);
+        }
+        return env.getTypeUtils().isSubtype(t1Erased, t2Erased);
+    }
+
     private static boolean needsErasure(TypeMirror typeMirror) {
         return typeMirror.getKind() != TypeKind.NONE && typeMirror.getKind() != TypeKind.VOID && !typeMirror.getKind().isPrimitive() && typeMirror.getKind() != TypeKind.OTHER &&
                         typeMirror.getKind() != TypeKind.NULL;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Wed Apr 09 22:45:27 2014 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Thu Apr 10 09:14:35 2014 +0200
@@ -39,6 +39,7 @@
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.Graph.Mark;
 import com.oracle.graal.java.*;
 import com.oracle.graal.java.GraphBuilderPhase.Instance;
 import com.oracle.graal.nodes.*;
@@ -460,17 +461,30 @@
 
         private StructuredGraph buildGraph(final ResolvedJavaMethod methodToParse, final SnippetInliningPolicy policy, int inliningDepth) {
             assert inliningDepth < MAX_GRAPH_INLINING_DEPTH : "inlining limit exceeded";
-            assert isInlinableSnippet(methodToParse) : methodToParse;
+            assert isInlinable(methodToParse) : methodToParse;
             final StructuredGraph graph = buildInitialGraph(methodToParse);
             try (Scope s = Debug.scope("buildGraph", graph)) {
-
+                Set<MethodCallTargetNode> doNotInline = null;
                 for (MethodCallTargetNode callTarget : graph.getNodes(MethodCallTargetNode.class)) {
+                    if (doNotInline != null && doNotInline.contains(callTarget)) {
+                        continue;
+                    }
                     ResolvedJavaMethod callee = callTarget.targetMethod();
                     if (callee.equals(recursiveEntry)) {
-                        if (isInlinableSnippet(substitutedMethod)) {
+                        if (isInlinable(substitutedMethod)) {
                             final StructuredGraph originalGraph = buildInitialGraph(substitutedMethod);
+                            Mark mark = graph.getMark();
                             InliningUtil.inline(callTarget.invoke(), originalGraph, true);
-
+                            for (MethodCallTargetNode inlinedCallTarget : graph.getNewNodes(mark).filter(MethodCallTargetNode.class)) {
+                                if (doNotInline == null) {
+                                    doNotInline = new HashSet<>();
+                                }
+                                // We do not want to do further inlining (now) for calls
+                                // in the original method as this can cause unlimited
+                                // recursive inlining given an eager inlining policy such
+                                // as DefaultSnippetInliningPolicy.
+                                doNotInline.add(inlinedCallTarget);
+                            }
                             Debug.dump(graph, "after inlining %s", callee);
                             afterInline(graph, originalGraph, null);
                         }
@@ -516,8 +530,8 @@
         }
     }
 
-    private static boolean isInlinableSnippet(final ResolvedJavaMethod methodToParse) {
-        return !Modifier.isAbstract(methodToParse.getModifiers()) && !Modifier.isNative(methodToParse.getModifiers());
+    private static boolean isInlinable(final ResolvedJavaMethod method) {
+        return !Modifier.isAbstract(method.getModifiers()) && !Modifier.isNative(method.getModifiers());
     }
 
     private static String originalName(Method substituteMethod, String methodSubstitution) {
--- a/mx/mx_graal.py	Wed Apr 09 22:45:27 2014 -0700
+++ b/mx/mx_graal.py	Thu Apr 10 09:14:35 2014 +0200
@@ -1356,6 +1356,7 @@
     jmhArgJsons = [b for b in benchmarksAndJsons if b.startswith('{')]
 
     jmhArgs = {
+        '-v' : 'EXTRA' if mx._opts.verbose else 'NORMAL',
         '-f' : '1',
         '-i' : '10',
         '-wi' : '10'}
@@ -1363,7 +1364,11 @@
     # e.g. '{"-wi" : 20}'
     for j in jmhArgJsons:
         try:
-            jmhArgs.update(json.loads(j))
+            for n, v in json.loads(j).iteritems():
+                if v is None:
+                    del jmhArgs[n]
+                else:
+                    jmhArgs[n] = v
         except ValueError as e:
             mx.abort('error parsing JSON input: {}"\n{}'.format(j, e))
 
@@ -1430,7 +1435,8 @@
                     '--jvmArgs', ' '.join(["-" + vm] + forkedVmArgs)]
         for k, v in jmhArgs.iteritems():
             javaArgs.append(k)
-            javaArgs.append(str(v))
+            if len(str(v)):
+                javaArgs.append(str(v))
         mx.run_java(javaArgs + regex, addDefaultArgs=False, cwd=jmhPath)
 
 
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Wed Apr 09 22:45:27 2014 -0700
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Thu Apr 10 09:14:35 2014 +0200
@@ -727,11 +727,21 @@
   HotSpotInstalledCode::set_codeBlob(hotspotInstalledCode, 0);
 C2V_END
 
+C2V_VMENTRY(jobject, getJavaMirror, (JNIEnv *env, jobject, jlong metaspace_klass))
+  Klass* klass = asKlass(metaspace_klass);
+  return JNIHandles::make_local(klass->java_mirror());
+C2V_END
 
-C2V_VMENTRY(jobject, readUnsafeUncompressedPointer, (JNIEnv *env, jobject, jobject o, jlong offset))
-  oop resolved_o = JNIHandles::resolve(o);
-  address addr = ((address)resolved_o) + offset;
-  return JNIHandles::make_local(*((oop*)addr));
+C2V_VMENTRY(jobject, getNodeClass, (JNIEnv *env, jobject, jobject java_class_handle))
+  oop java_class = JNIHandles::resolve(java_class_handle);
+  InstanceKlass* iklass = (InstanceKlass*) java_lang_Class::as_Klass(java_class);
+  return JNIHandles::make_local(iklass->graal_node_class());
+C2V_END
+
+C2V_VMENTRY(void, setNodeClass, (JNIEnv *env, jobject, jobject java_class_handle, jobject value))
+  oop java_class = JNIHandles::resolve(java_class_handle);
+  InstanceKlass* iklass = (InstanceKlass*) java_lang_Class::as_Klass(java_class);
+  iklass->set_graal_node_class(JNIHandles::resolve(value));
 C2V_END
 
 C2V_VMENTRY(jlong, readUnsafeKlassPointer, (JNIEnv *env, jobject, jobject o))
@@ -793,6 +803,7 @@
 #define HS_COMPILED_CODE      "Lcom/oracle/graal/hotspot/HotSpotCompiledCode;"
 #define HS_CONFIG             "Lcom/oracle/graal/hotspot/HotSpotVMConfig;"
 #define HS_INSTALLED_CODE     "Lcom/oracle/graal/hotspot/meta/HotSpotInstalledCode;"
+#define NODE_CLASS            "Lcom/oracle/graal/graph/NodeClass;"
 #define METASPACE_KLASS       "J"
 #define METASPACE_METHOD      "J"
 #define METASPACE_METHOD_DATA "J"
@@ -841,7 +852,9 @@
   {CC"getLocalVariableTableLength",                  CC"("METASPACE_METHOD")I",                                        FN_PTR(getLocalVariableTableLength)},
   {CC"reprofile",                                    CC"("METASPACE_METHOD")V",                                        FN_PTR(reprofile)},
   {CC"invalidateInstalledCode",                      CC"("HS_INSTALLED_CODE")V",                                       FN_PTR(invalidateInstalledCode)},
-  {CC"readUnsafeUncompressedPointer",                CC"("OBJECT"J)"OBJECT,                                            FN_PTR(readUnsafeUncompressedPointer)},
+  {CC"getJavaMirror",                                CC"("METASPACE_KLASS")"CLASS,                                     FN_PTR(getJavaMirror)},
+  {CC"getNodeClass",                                 CC"("CLASS")"NODE_CLASS,                                          FN_PTR(getNodeClass)},
+  {CC"setNodeClass",                                 CC"("CLASS NODE_CLASS")V",                                        FN_PTR(setNodeClass)},
   {CC"readUnsafeKlassPointer",                       CC"("OBJECT")J",                                                  FN_PTR(readUnsafeKlassPointer)},
   {CC"collectCounters",                              CC"()[J",                                                         FN_PTR(collectCounters)},
   {CC"getGPUs",                                      CC"()"STRING,                                                     FN_PTR(getGPUs)},
--- a/src/share/vm/graal/vmStructs_graal.hpp	Wed Apr 09 22:45:27 2014 -0700
+++ b/src/share/vm/graal/vmStructs_graal.hpp	Thu Apr 10 09:14:35 2014 +0200
@@ -31,9 +31,10 @@
 #include "graal/graalEnv.hpp"
 
 #define VM_STRUCTS_GRAAL(nonstatic_field, static_field)                       \
-  nonstatic_field(ThreadShadow, _pending_deoptimization, int)                 \
-  nonstatic_field(ThreadShadow, _pending_failed_speculation, oop)             \
-  nonstatic_field(MethodData,   _graal_node_count, int)                       \
+  nonstatic_field(InstanceKlass, _graal_node_class, oop)                      \
+  nonstatic_field(ThreadShadow,  _pending_deoptimization, int)                \
+  nonstatic_field(ThreadShadow,  _pending_failed_speculation, oop)            \
+  nonstatic_field(MethodData,    _graal_node_count, int)                      \
 
 #define VM_TYPES_GRAAL(declare_type, declare_toplevel_type)                   \
 
--- a/src/share/vm/oops/instanceKlass.cpp	Wed Apr 09 22:45:27 2014 -0700
+++ b/src/share/vm/oops/instanceKlass.cpp	Thu Apr 10 09:14:35 2014 +0200
@@ -288,6 +288,9 @@
   set_init_state(InstanceKlass::allocated);
   set_init_thread(NULL);
   set_reference_type(rt);
+#ifdef GRAAL
+  set_graal_node_class(NULL);
+#endif
   set_oop_map_cache(NULL);
   set_jni_ids(NULL);
   set_osr_nmethods_head(NULL);
@@ -317,6 +320,12 @@
   set_layout_helper(Klass::instance_layout_helper(0, true));
 }
 
+#ifdef GRAAL
+void InstanceKlass::oops_do(OopClosure* cl) {
+  Klass::oops_do(cl);
+  cl->do_oop(adr_graal_node_class());
+}
+#endif
 
 void InstanceKlass::deallocate_methods(ClassLoaderData* loader_data,
                                        Array<Method*>* methods) {
@@ -2254,6 +2263,10 @@
   }
   init_implementor();
 
+#ifdef GRAAL
+  set_graal_node_class(NULL);
+#endif
+
   constants()->remove_unshareable_info();
 
   for (int i = 0; i < methods()->length(); i++) {
--- a/src/share/vm/oops/instanceKlass.hpp	Wed Apr 09 22:45:27 2014 -0700
+++ b/src/share/vm/oops/instanceKlass.hpp	Thu Apr 10 09:14:35 2014 +0200
@@ -241,6 +241,10 @@
   Thread*         _init_thread;          // Pointer to current thread doing initialization (to handle recusive initialization)
   int             _vtable_len;           // length of Java vtable (in words)
   int             _itable_len;           // length of Java itable (in words)
+#ifdef GRAAL
+  // com/oracle/graal/graph/NodeClass instance mirroring this class
+  oop             _graal_node_class;
+#endif
   OopMapCache*    volatile _oop_map_cache;   // OopMapCache for all methods in the klass (allocated lazily)
   MemberNameTable* _member_names;        // Member names
   JNIid*          _jni_ids;              // First JNI identifier for static fields in this class
@@ -745,6 +749,16 @@
   void call_class_initializer(TRAPS);
   void set_initialization_state_and_notify(ClassState state, TRAPS);
 
+#ifdef GRAAL
+  // Graal com.oracle.graal.graph.NodeClass mirror
+  oop graal_node_class()           { return _graal_node_class;               }
+  void set_graal_node_class(oop m) { klass_oop_store(&_graal_node_class, m); }
+  oop* adr_graal_node_class()      { return (oop*)&this->_graal_node_class;  }
+
+  // GC support
+  virtual void oops_do(OopClosure* cl);
+#endif
+
   // OopMapCache support
   OopMapCache* oop_map_cache()               { return _oop_map_cache; }
   void set_oop_map_cache(OopMapCache *cache) { _oop_map_cache = cache; }