# HG changeset patch # User Doug Simon # Date 1428676188 -7200 # Node ID 7cc48e7e6bfeb694baa74287ff65c1cd1793b642 # Parent c4691265275a430a2f766a852ef13b7415628cdc generalized InvocationPluginIdHolder to MethodIdHolder diff -r c4691265275a -r 7cc48e7e6bfe graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPluginIdHolder.java --- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPluginIdHolder.java Fri Apr 10 13:21:33 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2015, 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.graphbuilderconf; - -import com.oracle.graal.api.meta.*; - -/** - * {@link ResolvedJavaMethod}s that can assign themselves an identifier for use in a side table - * mapping methods to {@link InvocationPlugin}s. - */ -public interface InvocationPluginIdHolder extends ResolvedJavaMethod { - /** - * Sets the unique, positive, non-zero identifier for this method. - */ - void setInvocationPluginId(int id); - - /** - * Gets the identifier set by {@link #setInvocationPluginId(int)} or 0 if no - * {@link InvocationPlugin} identifier was assigned to this method. - */ - int getInvocationPluginId(); -} diff -r c4691265275a -r 7cc48e7e6bfe graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugins.java --- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugins.java Fri Apr 10 13:21:33 2015 +0200 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugins.java Fri Apr 10 16:29:48 2015 +0200 @@ -26,12 +26,14 @@ import java.lang.reflect.*; import java.util.*; +import java.util.function.*; import java.util.stream.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.graph.Node; import com.oracle.graal.graph.iterators.*; +import com.oracle.graal.graphbuilderconf.MethodIdHolder.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.type.*; @@ -270,14 +272,14 @@ private final List registrations; /** - * The minimum {@linkplain InvocationPluginIdHolder#getInvocationPluginId() id} for a method - * associated with a plugin in {@link #plugins}. + * The minimum {@linkplain MethodIdHolder#getMethodId() id} for a method associated with a + * plugin in {@link #plugins}. */ private int minId = Integer.MAX_VALUE; /** * Resolved methods to plugins map. The keys (i.e., indexes) are derived from - * {@link InvocationPluginIdHolder#getInvocationPluginId()}. + * {@link MethodIdHolder#getMethodId()}. */ private volatile InvocationPlugin[] plugins; @@ -322,8 +324,6 @@ registrations.add(methodInfo); } - private static int nextInvocationPluginId = 1; - /** * Gets the plugin for a given method. * @@ -331,52 +331,49 @@ * @return the plugin associated with {@code method} or {@code null} if none exists */ public InvocationPlugin lookupInvocation(ResolvedJavaMethod method) { - assert method instanceof InvocationPluginIdHolder; + assert method instanceof MethodIdHolder; if (parent != null) { InvocationPlugin plugin = parent.lookupInvocation(method); if (plugin != null) { return plugin; } } - InvocationPluginIdHolder pluggable = (InvocationPluginIdHolder) method; + MethodIdHolder pluggable = (MethodIdHolder) method; if (plugins == null) { - // Must synchronize across all InvocationPlugins objects to ensure thread safe - // allocation of InvocationPlugin identifiers - synchronized (InvocationPlugins.class) { - if (plugins == null) { - if (registrations.isEmpty()) { - plugins = new InvocationPlugin[0]; - } else { - int max = Integer.MIN_VALUE; - for (MethodInfo methodInfo : registrations) { - InvocationPluginIdHolder p = (InvocationPluginIdHolder) methodInfo.resolve(metaAccess); - int id = p.getInvocationPluginId(); - if (id == 0) { - id = nextInvocationPluginId++; - p.setInvocationPluginId(id); + // 'assignIds' synchronizes on a global lock which ensures thread safe + // allocation of identifiers across all InvocationPlugins objects + MethodIdHolder.assignIds(new Consumer() { + public void accept(MethodIdAllocator idAllocator) { + if (plugins == null) { + if (registrations.isEmpty()) { + plugins = new InvocationPlugin[0]; + } else { + int max = Integer.MIN_VALUE; + for (MethodInfo methodInfo : registrations) { + MethodIdHolder p = (MethodIdHolder) methodInfo.resolve(metaAccess); + int id = idAllocator.assignId(p); + if (id < minId) { + minId = id; + } + if (id > max) { + max = id; + } + methodInfo.id = id; } - if (id < minId) { - minId = id; - } - if (id > max) { - max = id; + int length = (max - minId) + 1; + plugins = new InvocationPlugin[length]; + for (MethodInfo m : registrations) { + int index = m.id - minId; + plugins[index] = m.plugin; } - methodInfo.id = id; - } - - int length = (max - minId) + 1; - plugins = new InvocationPlugin[length]; - for (MethodInfo m : registrations) { - int index = m.id - minId; - plugins[index] = m.plugin; } } } - } + }); } - int id = pluggable.getInvocationPluginId(); + int id = pluggable.getMethodId(); int index = id - minId; return index >= 0 && index < plugins.length ? plugins[index] : null; } diff -r c4691265275a -r 7cc48e7e6bfe graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/MethodIdHolder.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/MethodIdHolder.java Fri Apr 10 16:29:48 2015 +0200 @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2015, 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.graphbuilderconf; + +import java.util.*; +import java.util.function.*; + +import com.oracle.graal.api.meta.*; + +/** + * {@link ResolvedJavaMethod}s that can be assigned a globally unique identifier for use as keys in + * an array based map. This should only be used where the cost of a {@link Map} with + * {@link ResolvedJavaMethod}s as keys is too high. + */ +public interface MethodIdHolder extends ResolvedJavaMethod { + /** + * Sets the unique, positive, non-zero identifier for this method. + */ + void setMethodId(int id); + + /** + * Gets the identifier set by {@link #setMethodId(int)} or 0 if no identifier was assigned to + * this method. + */ + int getMethodId(); + + /** + * A singleton class for allocating globally unique method identifiers. + */ + static final class MethodIdAllocator { + + /** + * Ensures a given method has a unique identifier. + */ + public int assignId(MethodIdHolder holder) { + assert Thread.holdsLock(instance) : "must only be called from within MethodIdHolder.allocateIds"; + int id = holder.getMethodId(); + if (id == 0) { + id = nextId++; + holder.setMethodId(id); + if (idVerifierMap != null) { + idVerifierMap.put(holder, id); + } + } else { + assert idVerifierMap.get(holder) == id; + } + return id; + } + + private int nextId = 1; + private final Map idVerifierMap; + + @SuppressWarnings("all") + private MethodIdAllocator() { + boolean assertionsEnabled = false; + assert assertionsEnabled = true; + idVerifierMap = assertionsEnabled ? new HashMap<>() : null; + } + + /** + * Singleton instance. + */ + private static final MethodIdAllocator instance = new MethodIdAllocator(); + } + + /** + * Executes some given code that ensures some set of {@link ResolvedJavaMethod}s have unique ids + * {@linkplain MethodIdHolder#setMethodId(int) assigned} to them. The + * {@link Consumer#accept(Object)} method of the given object is called under a global lock. + */ + static void assignIds(Consumer methodIdConsumer) { + synchronized (MethodIdAllocator.instance) { + methodIdConsumer.accept(MethodIdAllocator.instance); + } + } +} diff -r c4691265275a -r 7cc48e7e6bfe graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl.java Fri Apr 10 13:21:33 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl.java Fri Apr 10 16:29:48 2015 +0200 @@ -42,7 +42,7 @@ /** * Implementation of {@link JavaMethod} for resolved HotSpot methods. */ -public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod, HotSpotProxified, InvocationPluginIdHolder { +public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod, HotSpotProxified, MethodIdHolder { private static final long serialVersionUID = -5486975070147586588L; @@ -742,14 +742,14 @@ return runtime().getCompilerToVM().hasCompiledCodeForOSR(metaspaceMethod, entryBCI, level); } - private int invocationPluginId; + private int methodId; - public void setInvocationPluginId(int id) { - assert invocationPluginId == 0; - invocationPluginId = id; + public void setMethodId(int id) { + assert methodId == 0; + methodId = id; } - public int getInvocationPluginId() { - return invocationPluginId; + public int getMethodId() { + return methodId; } }