# HG changeset patch # User Tom Rodriguez # Date 1439489421 25200 # Node ID 2b9729c833ab645fab78e75768935c35d74ccae8 # Parent e3d9e0f9b50c9b2b16357fad779af00acc4cefb9 Remove MethodIdMap diff -r e3d9e0f9b50c -r 2b9729c833ab jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotResolvedJavaMethodImpl.java --- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotResolvedJavaMethodImpl.java Wed Aug 12 17:46:38 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotResolvedJavaMethodImpl.java Thu Aug 13 11:10:21 2015 -0700 @@ -37,7 +37,7 @@ /** * Implementation of {@link JavaMethod} for resolved HotSpot methods. */ -public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod, HotSpotProxified, MethodIdHolder { +public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod, HotSpotProxified { public static class Options { // @formatter:off @@ -729,15 +729,4 @@ } return runtime().getCompilerToVM().hasCompiledCodeForOSR(metaspaceMethod, entryBCI, level); } - - private int methodId; - - public void setMethodId(int id) { - assert methodId == 0; - methodId = id; - } - - public int getMethodId() { - return methodId; - } } diff -r e3d9e0f9b50c -r 2b9729c833ab jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/MethodIdHolder.java --- a/jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/MethodIdHolder.java Wed Aug 12 17:46:38 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +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 jdk.internal.jvmci.meta; - -import java.util.*; -import java.util.function.*; - -/** - * An object that can be assigned a globally unique identifier for use as a key in a - * {@link MethodIdMap}. - */ -public interface MethodIdHolder { - /** - * 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.containsKey(holder) || 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 e3d9e0f9b50c -r 2b9729c833ab jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/MethodIdMap.java --- a/jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/MethodIdMap.java Wed Aug 12 17:46:38 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,261 +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 jdk.internal.jvmci.meta; - -import java.lang.reflect.*; -import java.util.*; -import java.util.function.*; -import java.util.stream.*; - -import jdk.internal.jvmci.meta.MethodIdHolder.*; - -/** - * A map whose keys are {@link MethodIdHolder}s. This data structure can be used for mapping - * identifiers to methods without requiring eager resolution of the latter (e.g., to - * {@link ResolvedJavaMethod}s) and has retrieval as fast as array indexing. The constraints on - * using such a map are: - *
    - *
  • at most one value can be added for any key
  • - *
  • no more entries can be added after the first {@linkplain #get(MethodIdHolder) retrieval}
  • - *
- * - * @param the type of the values in the map - */ -public class MethodIdMap { - - /** - * Key for a method. - */ - public static class MethodKey { - final boolean isStatic; - - /** - * This method is optional. This is used for new API methods not present in previous JDK - * versions. - */ - final boolean isOptional; - - final Class declaringClass; - final String name; - final Class[] argumentTypes; - final T value; - int id; - - MethodKey(T data, boolean isStatic, boolean isOptional, Class declaringClass, String name, Class... argumentTypes) { - assert isStatic || argumentTypes[0] == declaringClass; - this.value = data; - this.isStatic = isStatic; - this.isOptional = isOptional; - this.declaringClass = declaringClass; - this.name = name; - this.argumentTypes = argumentTypes; - assert isOptional || resolveJava() != null; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof MethodKey) { - MethodKey that = (MethodKey) obj; - boolean res = this.name.equals(that.name) && this.declaringClass.equals(that.declaringClass) && Arrays.equals(this.argumentTypes, that.argumentTypes); - assert !res || this.isStatic == that.isStatic; - return res; - } - return false; - } - - public int getDeclaredParameterCount() { - return isStatic ? argumentTypes.length : argumentTypes.length - 1; - } - - @Override - public int hashCode() { - // Replay compilation mandates use of stable hash codes - return declaringClass.getName().hashCode() ^ name.hashCode(); - } - - private MethodIdHolder resolve(MetaAccessProvider metaAccess) { - Executable method = resolveJava(); - if (method == null) { - return null; - } - return (MethodIdHolder) metaAccess.lookupJavaMethod(method); - } - - private Executable resolveJava() { - try { - Executable res; - Class[] parameterTypes = isStatic ? argumentTypes : Arrays.copyOfRange(argumentTypes, 1, argumentTypes.length); - if (name.equals("")) { - res = declaringClass.getDeclaredConstructor(parameterTypes); - } else { - res = declaringClass.getDeclaredMethod(name, parameterTypes); - } - assert Modifier.isStatic(res.getModifiers()) == isStatic; - return res; - } catch (NoSuchMethodException | SecurityException e) { - if (isOptional) { - return null; - } - throw new InternalError(e); - } - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(declaringClass.getName()).append('.').append(name).append('('); - for (Class p : argumentTypes) { - if (sb.charAt(sb.length() - 1) != '(') { - sb.append(", "); - } - sb.append(p.getSimpleName()); - } - return sb.append(')').toString(); - } - } - - private final MetaAccessProvider metaAccess; - - /** - * Initial list of entries. - */ - private final List> registrations; - - /** - * Entry array that is initialized upon first call to {@link #get(MethodIdHolder)}. - * - * Note: this must be volatile since double-checked locking is used to initialize it - */ - private volatile V[] entries; - - /** - * The minimum {@linkplain MethodIdHolder#getMethodId() id} for a key in this map. - */ - private int minId = Integer.MAX_VALUE; - - public MethodIdMap(MetaAccessProvider metaAccess) { - this.metaAccess = metaAccess; - this.registrations = new ArrayList<>(INITIAL_CAPACITY); - } - - private static final int INITIAL_CAPACITY = 64; - - /** - * Adds an entry to this map for a specified method. - * - * @param value value to be associated with the specified method - * @param isStatic specifies if the method is static - * @param isOptional specifies if the method is optional - * @param declaringClass the class declaring the method - * @param name the name of the method - * @param argumentTypes the argument types of the method. Element 0 of this array must be - * {@code declaringClass} iff the method is non-static. - * @return an object representing the method - */ - public MethodKey put(V value, boolean isStatic, boolean isOptional, Class declaringClass, String name, Class... argumentTypes) { - assert isStatic || argumentTypes[0] == declaringClass; - MethodKey methodKey = new MethodKey<>(value, isStatic, isOptional, declaringClass, name, argumentTypes); - assert entries == null : "registration is closed"; - assert !registrations.contains(methodKey) : "a value is already registered for " + methodKey; - registrations.add(methodKey); - return methodKey; - } - - @SuppressWarnings("unchecked") - protected V[] allocateEntries(int length) { - return (V[]) new Object[length]; - } - - /** - * Determines if a method denoted by a given {@link MethodKey} is in this map. - */ - public boolean containsKey(MethodKey key) { - return registrations.contains(key); - } - - public V get(MethodIdHolder method) { - if (entries == null) { - createEntries(); - } - - int id = method.getMethodId(); - int index = id - minId; - return index >= 0 && index < entries.length ? entries[index] : null; - } - - public void createEntries() { - // 'assignIds' synchronizes on a global lock which ensures thread safe - // allocation of identifiers across all MethodIdHolder objects - MethodIdHolder.assignIds(new Consumer() { - - public void accept(MethodIdAllocator idAllocator) { - if (entries == null) { - if (registrations.isEmpty()) { - entries = allocateEntries(0); - } else { - int max = Integer.MIN_VALUE; - for (MethodKey methodKey : registrations) { - MethodIdHolder m = methodKey.resolve(metaAccess); - if (m == null) { - assert methodKey.isOptional; - methodKey.id = -1; - } else { - int id = idAllocator.assignId(m); - if (id < minId) { - minId = id; - } - if (id > max) { - max = id; - } - methodKey.id = id; - } - } - - int length = (max - minId) + 1; - entries = allocateEntries(length); - for (MethodKey methodKey : registrations) { - if (methodKey.id == -1) { - assert methodKey.isOptional; - } else { - int index = methodKey.id - minId; - entries[index] = methodKey.value; - } - } - } - } - } - }); - } - - @Override - public String toString() { - return registrations.stream().map(MethodKey::toString).collect(Collectors.joining(", ")); - } - - public MetaAccessProvider getMetaAccess() { - return metaAccess; - } - - public int size() { - return registrations.size(); - } -}