# HG changeset patch # User Doug Simon # Date 1397114075 -7200 # Node ID d4a9d6f6e57d1cb4ef73957c1d2d31379742b2d4 # Parent 04f1723150b43388c913fbc61832aeaeaaf41e11# Parent d8b9e3761e52c4f49a53e65b0f7a6ec53a1a1a45 Merge. diff -r d8b9e3761e52 -r d4a9d6f6e57d graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotNodeClassSubstitutionsTest.java --- /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); + } +} diff -r d8b9e3761e52 -r d4a9d6f6e57d graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotNodeSubstitutionsTest.java --- /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(); + } +} diff -r d8b9e3761e52 -r d4a9d6f6e57d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- 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::_length", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int metaspaceArrayLengthOffset; @HotSpotVMField(name = "Array::_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; diff -r d8b9e3761e52 -r d4a9d6f6e57d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java --- 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); diff -r d8b9e3761e52 -r d4a9d6f6e57d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java --- 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); diff -r d8b9e3761e52 -r d4a9d6f6e57d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/FastNodeClassRegistry.java --- 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 key) { - return (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromClass(key); + @SuppressWarnings("unused") + static void initialize(CompilerToVM vm) { + new FastNodeClassRegistry(vm); } @Override public NodeClass get(Class key) { - return type(key).getNodeClass(); + return vm.getNodeClass(key); } @Override protected void registered(Class key, NodeClass value) { - type(key).setNodeClass(value); + vm.setNodeClass(key, value); } } diff -r d8b9e3761e52 -r d4a9d6f6e57d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java --- 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) { diff -r d8b9e3761e52 -r d4a9d6f6e57d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java --- 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); } diff -r d8b9e3761e52 -r d4a9d6f6e57d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java --- 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 fieldCache; private HashMap 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; diff -r d8b9e3761e52 -r d4a9d6f6e57d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNodeClassSubstitutions.java --- /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); + + } +} diff -r d8b9e3761e52 -r d4a9d6f6e57d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNodeSubstitutions.java --- /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); + } +} diff -r d8b9e3761e52 -r d4a9d6f6e57d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java --- 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; diff -r d8b9e3761e52 -r d4a9d6f6e57d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSubstitutions.java --- 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); } } diff -r d8b9e3761e52 -r d4a9d6f6e57d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NodeClassSubstitutions.java --- 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); -} diff -r d8b9e3761e52 -r d4a9d6f6e57d graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java --- 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 piCastExact(Object object, @ConstantNodeParameter Class toType) { + return piCast(object, toType, true, false); + } + public static T piCast(Object object, @ConstantNodeParameter Class toType) { return piCast(object, toType, false, false); } diff -r d8b9e3761e52 -r d4a9d6f6e57d graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/MethodSubstitutionVerifier.java --- 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; diff -r d8b9e3761e52 -r d4a9d6f6e57d graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java --- 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 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) { diff -r d8b9e3761e52 -r d4a9d6f6e57d mx/mx_graal.py --- 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) diff -r d8b9e3761e52 -r d4a9d6f6e57d src/share/vm/graal/graalCompilerToVM.cpp --- 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)}, diff -r d8b9e3761e52 -r d4a9d6f6e57d src/share/vm/graal/vmStructs_graal.hpp --- 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) \ diff -r d8b9e3761e52 -r d4a9d6f6e57d src/share/vm/oops/instanceKlass.cpp --- 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* 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++) { diff -r d8b9e3761e52 -r d4a9d6f6e57d src/share/vm/oops/instanceKlass.hpp --- 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; }