changeset 23144:043cb31c85cd

defer InvocationPlugin registration until first plugin lookup or plugins are closed
author Doug Simon <doug.simon@oracle.com>
date Tue, 08 Dec 2015 18:00:31 +0100
parents 930372a4cbca
children 5eb7281c661c
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/graphbuilderconf/InvocationPlugins.java graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64GraphBuilderPlugins.java graal/com.oracle.graal.replacements.sparc/src/com/oracle/graal/replacements/sparc/SPARCGraphBuilderPlugins.java
diffstat 4 files changed, 71 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java	Tue Dec 08 18:00:22 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java	Tue Dec 08 18:00:31 2015 +0100
@@ -116,21 +116,26 @@
             plugins.appendInlineInvokePlugin(new InlineDuringParsingPlugin());
         }
 
-        registerObjectPlugins(invocationPlugins);
-        registerClassPlugins(plugins);
-        registerSystemPlugins(invocationPlugins, foreignCalls);
-        registerThreadPlugins(invocationPlugins, metaAccess, wordTypes, config);
-        registerCallSitePlugins(invocationPlugins);
-        registerReflectionPlugins(invocationPlugins);
-        registerStableOptionPlugins(invocationPlugins, snippetReflection);
-        registerAESPlugins(invocationPlugins, config);
-        registerCRC32Plugins(invocationPlugins, config);
-        StandardGraphBuilderPlugins.registerInvocationPlugins(metaAccess, invocationPlugins, true);
+        invocationPlugins.defer(new Runnable() {
 
-        for (NodeIntrinsicPluginFactory factory : Services.load(NodeIntrinsicPluginFactory.class)) {
-            factory.registerPlugin(invocationPlugins, nodeIntrinsificationProvider);
-        }
+            public void run() {
+                registerObjectPlugins(invocationPlugins);
+                registerClassPlugins(plugins);
+                registerSystemPlugins(invocationPlugins, foreignCalls);
+                registerThreadPlugins(invocationPlugins, metaAccess, wordTypes, config);
+                registerCallSitePlugins(invocationPlugins);
+                registerReflectionPlugins(invocationPlugins);
+                registerStableOptionPlugins(invocationPlugins, snippetReflection);
+                registerAESPlugins(invocationPlugins, config);
+                registerCRC32Plugins(invocationPlugins, config);
+                StandardGraphBuilderPlugins.registerInvocationPlugins(metaAccess, invocationPlugins, true);
 
+                for (NodeIntrinsicPluginFactory factory : Services.load(NodeIntrinsicPluginFactory.class)) {
+                    factory.registerPlugin(invocationPlugins, nodeIntrinsificationProvider);
+                }
+
+            }
+        });
         return plugins;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/graphbuilderconf/InvocationPlugins.java	Tue Dec 08 18:00:22 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/graphbuilderconf/InvocationPlugins.java	Tue Dec 08 18:00:31 2015 +0100
@@ -371,11 +371,24 @@
     private final List<MethodKey> registrations = new ArrayList<>(INITIAL_CAPACITY);
 
     /**
-     * Entry map that is initialized upon first call to {@link #get(ResolvedJavaMethod)}.
-     *
-     * Note: this must be volatile since double-checked locking is used to initialize it
+     * Deferred registrations as well as guard for initialization of {@link #entries}. The guard
+     * uses double-checked locking which is why this field is {@code volatile}.
+     */
+    private volatile List<Runnable> deferredRegistrations = new ArrayList<>();
+
+    /**
+     * Adds a {@link Runnable} for doing registration deferred until the first time
+     * {@link #get(ResolvedJavaMethod)} or {@link #closeRegistration()} is called on this object.
      */
-    private volatile Map<ResolvedJavaMethod, InvocationPlugin> entries;
+    public void defer(Runnable deferrable) {
+        assert entries == null && deferredRegistrations != null : "registration is closed";
+        deferredRegistrations.add(deferrable);
+    }
+
+    /**
+     * Entry map that is initialized by {@link #initializeMap()}.
+     */
+    private Map<ResolvedJavaMethod, InvocationPlugin> entries;
 
     private static final int INITIAL_CAPACITY = 64;
 
@@ -408,10 +421,9 @@
     }
 
     InvocationPlugin get(ResolvedJavaMethod method) {
-        if (entries == null) {
+        if (deferredRegistrations != null) {
             initializeMap();
         }
-
         return entries.get(method);
     }
 
@@ -420,21 +432,32 @@
      * lookup.
      */
     public void closeRegistration() {
-        if (entries == null) {
+        if (deferredRegistrations != null) {
             initializeMap();
         }
     }
 
     void initializeMap() {
-        if (registrations.isEmpty()) {
-            entries = Collections.emptyMap();
-        } else {
-            Map<ResolvedJavaMethod, InvocationPlugin> newEntries = new HashMap<>();
-            for (MethodKey methodKey : registrations) {
-                ResolvedJavaMethod m = methodKey.resolve(metaAccess);
-                newEntries.put(m, methodKey.value);
+        if (deferredRegistrations != null) {
+            synchronized (this) {
+                if (deferredRegistrations != null) {
+                    List<Runnable> localDeferredRegistrations = deferredRegistrations;
+                    for (Runnable deferrable : localDeferredRegistrations) {
+                        deferrable.run();
+                    }
+                    if (registrations.isEmpty()) {
+                        entries = Collections.emptyMap();
+                    } else {
+                        Map<ResolvedJavaMethod, InvocationPlugin> newEntries = new HashMap<>();
+                        for (MethodKey methodKey : registrations) {
+                            ResolvedJavaMethod m = methodKey.resolve(metaAccess);
+                            newEntries.put(m, methodKey.value);
+                        }
+                        entries = newEntries;
+                    }
+                    deferredRegistrations = null;
+                }
             }
-            entries = newEntries;
         }
     }
 
--- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64GraphBuilderPlugins.java	Tue Dec 08 18:00:22 2015 +0100
+++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64GraphBuilderPlugins.java	Tue Dec 08 18:00:31 2015 +0100
@@ -54,10 +54,14 @@
 
     public static void register(Plugins plugins, ForeignCallsProvider foreignCalls, AMD64 arch) {
         InvocationPlugins invocationPlugins = plugins.getInvocationPlugins();
-        registerIntegerLongPlugins(invocationPlugins, IntegerSubstitutions.class, JavaKind.Int, arch);
-        registerIntegerLongPlugins(invocationPlugins, LongSubstitutions.class, JavaKind.Long, arch);
-        registerUnsafePlugins(invocationPlugins);
-        registerMathPlugins(invocationPlugins, foreignCalls);
+        invocationPlugins.defer(new Runnable() {
+            public void run() {
+                registerIntegerLongPlugins(invocationPlugins, IntegerSubstitutions.class, JavaKind.Int, arch);
+                registerIntegerLongPlugins(invocationPlugins, LongSubstitutions.class, JavaKind.Long, arch);
+                registerUnsafePlugins(invocationPlugins);
+                registerMathPlugins(invocationPlugins, foreignCalls);
+            }
+        });
     }
 
     private static void registerIntegerLongPlugins(InvocationPlugins plugins, Class<?> substituteDeclaringClass, JavaKind kind, AMD64 arch) {
--- a/graal/com.oracle.graal.replacements.sparc/src/com/oracle/graal/replacements/sparc/SPARCGraphBuilderPlugins.java	Tue Dec 08 18:00:22 2015 +0100
+++ b/graal/com.oracle.graal.replacements.sparc/src/com/oracle/graal/replacements/sparc/SPARCGraphBuilderPlugins.java	Tue Dec 08 18:00:31 2015 +0100
@@ -48,9 +48,13 @@
 
     public static void register(Plugins plugins, ForeignCallsProvider foreignCalls) {
         InvocationPlugins invocationPlugins = plugins.getInvocationPlugins();
-        registerIntegerLongPlugins(invocationPlugins, IntegerSubstitutions.class, JavaKind.Int);
-        registerIntegerLongPlugins(invocationPlugins, LongSubstitutions.class, JavaKind.Long);
-        registerMathPlugins(invocationPlugins, foreignCalls);
+        invocationPlugins.defer(new Runnable() {
+            public void run() {
+                registerIntegerLongPlugins(invocationPlugins, IntegerSubstitutions.class, JavaKind.Int);
+                registerIntegerLongPlugins(invocationPlugins, LongSubstitutions.class, JavaKind.Long);
+                registerMathPlugins(invocationPlugins, foreignCalls);
+            }
+        });
     }
 
     private static void registerIntegerLongPlugins(InvocationPlugins plugins, Class<?> substituteDeclaringClass, JavaKind kind) {