Mercurial > hg > graal-jvmci-8
changeset 15106:6876a4599b7e
create NodeClass for each Node subclass during class initialization of the latter
line wrap: on
line diff
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Tue Apr 15 12:20:43 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Tue Apr 15 13:34:29 2014 +0200 @@ -26,7 +26,6 @@ import java.lang.reflect.*; import java.util.*; -import java.util.concurrent.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.Graph.DuplicationReplacement; @@ -36,7 +35,7 @@ import com.oracle.graal.graph.spi.*; /** - * Lazily associated metadata for every {@link Node} type. The metadata includes: + * Metadata for every {@link Node} type. The metadata includes: * <ul> * <li>The offsets of fields annotated with {@link Input} and {@link Successor} as well as methods * for iterating over such fields.</li> @@ -45,72 +44,7 @@ */ public final class NodeClass extends FieldIntrospection { - /** - * Maps {@link Class} values (for {@link Node} types) to {@link NodeClass} values. - * - * Only a single Registry instance can be created. If a runtime creates a specialized registry, - * it must do so before the class initializer of {@link NodeClass} is executed. - */ - public static class Registry { - - private static Registry instance; - - /** - * Gets the singleton {@link Registry} instance, creating it first if necessary. - */ - static synchronized Registry instance() { - if (instance == null) { - return new Registry(); - } - return instance; - } - - protected Registry() { - assert instance == null : "exactly one registry can be created"; - instance = this; - } - - /** - * @return the {@link NodeClass} value for {@code key} or {@code null} if no such mapping - * exists - */ - protected NodeClass get(Class<? extends Node> key) { - return (NodeClass) allClasses.get(key); - } - - /** - * Same as {@link #get(Class)} except that a {@link NodeClass} is created if no such mapping - * exists. The creation of a {@link NodeClass} must be serialized as - * {@link NodeClass#NodeClass(Class)} accesses both {@link FieldIntrospection#allClasses} - * and {@link NodeClass#nextIterableId}. - * <p> - * The fact that {@link ConcurrentHashMap#put} {@link ConcurrentHashMap#get} are used should - * make the double-checked locking idiom work in the way {@link NodeClass#get(Class)} uses - * this method and {@link #get(Class)}. - */ - final synchronized NodeClass make(Class<? extends Node> key) { - NodeClass value = (NodeClass) allClasses.get(key); - if (value == null) { - value = new NodeClass(key); - Object old = allClasses.putIfAbsent(key, value); - assert old == null; - registered(key, value); - } - return value; - } - - /** - * Hook for a subclass to be notified of a new mapping added to the registry. - * - * @param key - * @param value - */ - protected void registered(Class<? extends Node> key, NodeClass value) { - - } - } - - private static final Registry registry = Registry.instance(); + private static final Object GetNodeClassLock = new Object(); /** * Gets the {@link NodeClass} associated with a given {@link Class}. @@ -118,11 +52,22 @@ @SuppressWarnings("unchecked") public static NodeClass get(Class<?> c) { Class<? extends Node> key = (Class<? extends Node>) c; - NodeClass value = registry.get(key); - if (value != null) { - return value; + NodeClass value = (NodeClass) allClasses.get(key); + // The fact that {@link ConcurrentHashMap#put} and {@link ConcurrentHashMap#get} + // are used makes the double-checked locking idiom work. + if (value == null) { + // The creation of a NodeClass must be serialized as the NodeClass constructor accesses + // both FieldIntrospection.allClasses and NodeClass.nextIterableId. + synchronized (GetNodeClassLock) { + value = (NodeClass) allClasses.get(key); + if (value == null) { + value = new NodeClass(key); + Object old = allClasses.putIfAbsent(key, value); + assert old == null : old + " " + key; + } + } } - return registry.make(key); + return value; } public static final int NOT_ITERABLE = -1;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Tue Apr 15 12:20:43 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Tue Apr 15 13:34:29 2014 +0200 @@ -284,8 +284,6 @@ Class<?> getJavaMirror(long metaspaceKlass); - void setNodeClass(Class<?> c, NodeClass nodeClass); - long readUnsafeKlassPointer(Object o); void doNotInlineOrCompile(long metaspaceMethod);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Tue Apr 15 12:20:43 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Tue Apr 15 13:34:29 2014 +0200 @@ -24,7 +24,6 @@ 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.*; @@ -145,9 +144,6 @@ public native Class<?> getJavaMirror(long metaspaceKlass); @Override - public native void setNodeClass(Class<?> c, NodeClass nodeClass); - - @Override public native long readUnsafeKlassPointer(Object o); @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/FastNodeClassRegistry.java Tue Apr 15 12:20:43 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2013, 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.bridge; - -import com.oracle.graal.graph.*; -import com.oracle.graal.hotspot.replacements.*; - -/** - * Updates the {@code InstanceKlass::_graal_node_class} field when a {@link NodeClass} is created so - * that the {@link HotSpotNodeClassSubstitutions} and {@link HotSpotNodeSubstitutions} - * intrinsifications can read it. - */ -class FastNodeClassRegistry extends NodeClass.Registry { - - private final CompilerToVM vm; - - public FastNodeClassRegistry(CompilerToVM vm) { - this.vm = vm; - } - - @SuppressWarnings("unused") - static void initialize(CompilerToVM vm) { - new FastNodeClassRegistry(vm); - } - - @Override - protected void registered(Class<? extends Node> key, NodeClass value) { - vm.setNodeClass(key, value); - } -}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java Tue Apr 15 12:20:43 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java Tue Apr 15 13:34:29 2014 +0200 @@ -38,11 +38,7 @@ void shutdownCompiler() throws Exception; - /** - * @param hostedOnly specifies if the Graal compiler is only being used in hosted mode (i.e., it - * will never compile itself) - */ - void startCompiler(boolean bootstrapEnabled, boolean hostedOnly) throws Throwable; + void startCompiler(boolean bootstrapEnabled) throws Throwable; void bootstrap() throws Throwable;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Tue Apr 15 12:20:43 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Tue Apr 15 13:34:29 2014 +0200 @@ -142,11 +142,7 @@ this.runtime = runtime; } - public void startCompiler(boolean bootstrapEnabled, boolean hostedOnly) throws Throwable { - - if (!hostedOnly) { - FastNodeClassRegistry.initialize(runtime.getCompilerToVM()); - } + public void startCompiler(boolean bootstrapEnabled) throws Throwable { bootstrapRunning = bootstrapEnabled;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Tue Apr 15 12:20:43 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Tue Apr 15 13:34:29 2014 +0200 @@ -174,8 +174,6 @@ fields.add(metaAccess.lookupJavaField(Throwable.class.getDeclaredField("UNASSIGNED_STACK"))); fields.add(metaAccess.lookupJavaField(Throwable.class.getDeclaredField("SUPPRESSED_SENTINEL"))); - - fields.add(metaAccess.lookupJavaField(NodeClass.class.getDeclaredField("registry"))); } catch (SecurityException | NoSuchFieldException e) { throw new GraalInternalError(e); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNodeClassSubstitutions.java Tue Apr 15 12:20:43 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNodeClassSubstitutions.java Tue Apr 15 13:34:29 2014 +0200 @@ -22,8 +22,6 @@ */ 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.*; @@ -33,7 +31,6 @@ 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}. @@ -61,15 +58,12 @@ } } + /** + * NOTE: A {@link MethodSubstitution} similar to + * {@link HotSpotNodeSubstitutions#getNodeClass(Node)} is not possible here because there is no + * guarantee that {@code c} is initialized (accessing a Class literal in Java is not a class + * initialization barrier). + */ @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); - - } + public static native NodeClass get(Class<?> c); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNodeSubstitutions.java Tue Apr 15 12:20:43 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNodeSubstitutions.java Tue Apr 15 13:34:29 2014 +0200 @@ -33,16 +33,15 @@ public class HotSpotNodeSubstitutions { /** - * Partial substitution of {@link Node#getNodeClass()} that returns the value of the - * {@code InstanceKlass::_graal_node_class} field if it is non-null. + * Gets the value of the {@code InstanceKlass::_graal_node_class} field from the InstanceKlass + * pointed to by {@code node}'s header. */ @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); + public static NodeClass getNodeClass(final Node node) { + // HotSpot creates the NodeClass for each Node subclass while initializing it + // so we are guaranteed to read a non-null value here. The fact that NodeClass + // is final will automatically make the stamp of the PiNode exact. + Word klass = loadHub(node); + return piCastNonNull(klass.readObject(Word.signed(klassNodeClassOffset()), KLASS_NODE_CLASS), NodeClass.class); } }
--- a/src/share/vm/classfile/systemDictionary.hpp Tue Apr 15 12:20:43 2014 +0200 +++ b/src/share/vm/classfile/systemDictionary.hpp Tue Apr 15 13:34:29 2014 +0200 @@ -186,6 +186,9 @@ /* Support for Graal */ \ do_klass(CompilerThread_klass, com_oracle_graal_compiler_CompilerThread, Opt) \ do_klass(BitSet_klass, java_util_BitSet, Opt) \ + /* graal.graph */ \ + do_klass(Node_klass, com_oracle_graal_graph_Node, Opt) \ + do_klass(NodeClass_klass, com_oracle_graal_graph_NodeClass, Opt) \ /* graal.hotspot */ \ do_klass(HotSpotCompiledCode_klass, com_oracle_graal_hotspot_HotSpotCompiledCode, Opt) \ do_klass(HotSpotCompiledCode_Comment_klass, com_oracle_graal_hotspot_HotSpotCompiledCode_Comment, Opt) \
--- a/src/share/vm/classfile/vmSymbols.hpp Tue Apr 15 12:20:43 2014 +0200 +++ b/src/share/vm/classfile/vmSymbols.hpp Tue Apr 15 13:34:29 2014 +0200 @@ -292,6 +292,9 @@ /* Support for Graal */ \ template(com_oracle_graal_compiler_CompilerThread, "com/oracle/graal/compiler/CompilerThread") \ template(java_util_BitSet, "java/util/BitSet") \ + /* graal.graph */ \ + template(com_oracle_graal_graph_Node, "com/oracle/graal/graph/Node") \ + template(com_oracle_graal_graph_NodeClass, "com/oracle/graal/graph/NodeClass") \ /* graal.hotspot */ \ template(com_oracle_graal_hotspot_HotSpotGraalRuntime, "com/oracle/graal/hotspot/HotSpotGraalRuntime") \ template(com_oracle_graal_hotspot_HotSpotKlassOop, "com/oracle/graal/hotspot/HotSpotKlassOop") \
--- a/src/share/vm/graal/graalCompiler.cpp Tue Apr 15 12:20:43 2014 +0200 +++ b/src/share/vm/graal/graalCompiler.cpp Tue Apr 15 13:34:29 2014 +0200 @@ -101,12 +101,10 @@ _external_deopt_i2c_entry = create_external_deopt_i2c(); #ifdef COMPILERGRAAL bool bootstrap = FLAG_IS_DEFAULT(BootstrapGraal) ? !TieredCompilation : BootstrapGraal; - bool hostedOnly = false; #else bool bootstrap = false; - bool hostedOnly = true; #endif - VMToCompiler::startCompiler(bootstrap, hostedOnly); + VMToCompiler::startCompiler(bootstrap); _initialized = true; CompilationPolicy::completed_vm_startup(); if (bootstrap) {
--- a/src/share/vm/graal/graalCompilerToVM.cpp Tue Apr 15 12:20:43 2014 +0200 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Tue Apr 15 13:34:29 2014 +0200 @@ -739,12 +739,6 @@ return JNIHandles::make_local(klass->java_mirror()); 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)) oop resolved_o = JNIHandles::resolve(o); jlong klass = (jlong)(address)resolved_o->klass(); @@ -1098,7 +1092,6 @@ {CC"reprofile", CC"("METASPACE_METHOD")V", FN_PTR(reprofile)}, {CC"invalidateInstalledCode", CC"("HS_INSTALLED_CODE")V", FN_PTR(invalidateInstalledCode)}, {CC"getJavaMirror", CC"("METASPACE_KLASS")"CLASS, FN_PTR(getJavaMirror)}, - {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/graalVMToCompiler.cpp Tue Apr 15 12:20:43 2014 +0200 +++ b/src/share/vm/graal/graalVMToCompiler.cpp Tue Apr 15 13:34:29 2014 +0200 @@ -144,15 +144,13 @@ } } -void VMToCompiler::startCompiler(jboolean bootstrap_enabled, jboolean hosted_only) { +void VMToCompiler::startCompiler(jboolean bootstrap_enabled) { JavaThread* THREAD = JavaThread::current(); JavaValue result(T_VOID); JavaCallArguments args; args.push_oop(instance()); args.push_int(bootstrap_enabled); - args.push_int(hosted_only); - TempNewSymbol bool_bool_void = SymbolTable::new_symbol("(ZZ)V", CHECK); - JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::startCompiler_name(), bool_bool_void, &args, THREAD); + JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::startCompiler_name(), vmSymbols::bool_void_signature(), &args, THREAD); check_pending_exception("Error while calling startCompiler"); }
--- a/src/share/vm/graal/graalVMToCompiler.hpp Tue Apr 15 12:20:43 2014 +0200 +++ b/src/share/vm/graal/graalVMToCompiler.hpp Tue Apr 15 13:34:29 2014 +0200 @@ -66,8 +66,8 @@ // public abstract void shutdownCompiler(); static void shutdownCompiler(); - // public abstract void startCompiler(boolean bootstrapEnabled, boolean hostedOnly); - static void startCompiler(jboolean bootstrap_enabled, jboolean hosted_only); + // public abstract void startCompiler(boolean bootstrapEnabled); + static void startCompiler(jboolean bootstrap_enabled); // public abstract void bootstrap(); static void bootstrap();
--- a/src/share/vm/oops/instanceKlass.cpp Tue Apr 15 12:20:43 2014 +0200 +++ b/src/share/vm/oops/instanceKlass.cpp Tue Apr 15 13:34:29 2014 +0200 @@ -1201,6 +1201,18 @@ JavaValue result(T_VOID); JavaCalls::call(&result, h_method, &args, CHECK); // Static call (no args) } + +#ifdef GRAAL + if (this_oop->class_loader() == NULL && this_oop->is_subtype_of(SystemDictionary::Node_klass())) { + if (this_oop() != SystemDictionary::Node_klass()) { + // Create the NodeClass for a Node subclass. + TempNewSymbol sig = SymbolTable::new_symbol("(Ljava/lang/Class;)Lcom/oracle/graal/graph/NodeClass;", CHECK); + JavaValue result(T_OBJECT); + JavaCalls::call_static(&result, SystemDictionary::NodeClass_klass(), vmSymbols::get_name(), sig, this_oop->java_mirror(), CHECK); + this_oop->set_graal_node_class((oop) result.get_jobject()); + } + } +#endif }