annotate graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/MethodIdMap.java @ 21376:739d9d9bd2fc

Allow closing of invocation plugin registry to prevent future modifications
author Christian Wimmer <christian.wimmer@oracle.com>
date Thu, 14 May 2015 16:00:20 -0700
parents dc58f4ca21c9
children 93c50cefb9e8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
20887
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
1 /*
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
4 *
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
7 * published by the Free Software Foundation.
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
8 *
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
13 * accompanied this code).
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
14 *
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
18 *
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
21 * questions.
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
22 */
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
23 package com.oracle.graal.graphbuilderconf;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
24
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
25 import java.lang.reflect.*;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
26 import java.util.*;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
27 import java.util.function.*;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
28 import java.util.stream.*;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
29
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
30 import com.oracle.graal.api.meta.*;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
31 import com.oracle.graal.compiler.common.*;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
32 import com.oracle.graal.graphbuilderconf.MethodIdHolder.MethodIdAllocator;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
33 import com.oracle.graal.nodes.*;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
34 import com.oracle.graal.nodes.type.*;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
35
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
36 /**
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
37 * A map whose keys are {@link MethodIdHolder}s that doesn't require eager resolution of
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
38 * {@link ResolvedJavaMethod}s and has retrieval as fast as array indexing. The constraints on using
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
39 * such a map are:
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
40 * <ul>
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
41 * <li>at most one value can be added for any key</li>
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
42 * <li>no more entries can be added after the first {@linkplain #get(MethodIdHolder) retrieval}</li>
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
43 * </ul>
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
44 *
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
45 * @param <V> the type of the values in the map
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
46 */
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
47 public class MethodIdMap<V> {
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
48
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
49 /**
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
50 * The receiver in a non-static method. The class literal for this interface must be used with
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
51 * {@link MethodIdMap#put(Object, Class, String, Class...)} to denote the receiver argument for
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
52 * such a non-static method.
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
53 */
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
54 public interface Receiver {
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
55 /**
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
56 * Gets the receiver value, null checking it first if necessary.
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
57 *
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
58 * @return the receiver value with a {@linkplain StampTool#isPointerNonNull(ValueNode)
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
59 * non-null} stamp
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
60 */
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
61 ValueNode get();
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
62
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
63 /**
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
64 * Determines if the receiver is constant.
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
65 */
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
66 default boolean isConstant() {
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
67 return false;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
68 }
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
69 }
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
70
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
71 /**
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
72 * Key for a method.
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
73 */
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
74 public static class MethodKey<T> {
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
75 final boolean isStatic;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
76 final Class<?> declaringClass;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
77 final String name;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
78 final Class<?>[] argumentTypes;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
79 final T value;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
80 int id;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
81
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
82 MethodKey(T data, Class<?> declaringClass, String name, Class<?>... argumentTypes) {
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
83 this.value = data;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
84 this.isStatic = argumentTypes.length == 0 || argumentTypes[0] != Receiver.class;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
85 this.declaringClass = declaringClass;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
86 this.name = name;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
87 this.argumentTypes = argumentTypes;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
88 if (!isStatic) {
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
89 argumentTypes[0] = declaringClass;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
90 }
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
91 assert resolveJava() != null;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
92 }
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
93
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
94 @Override
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
95 public boolean equals(Object obj) {
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
96 if (obj instanceof MethodKey) {
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
97 MethodKey<?> that = (MethodKey<?>) obj;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
98 boolean res = this.name.equals(that.name) && this.declaringClass.equals(that.declaringClass) && Arrays.equals(this.argumentTypes, that.argumentTypes);
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
99 assert !res || this.isStatic == that.isStatic;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
100 return res;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
101 }
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
102 return false;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
103 }
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
104
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
105 @Override
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
106 public int hashCode() {
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
107 // Replay compilation mandates use of stable hash codes
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
108 return declaringClass.getName().hashCode() ^ name.hashCode();
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
109 }
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
110
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
111 private MethodIdHolder resolve(MetaAccessProvider metaAccess) {
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
112 return (MethodIdHolder) metaAccess.lookupJavaMethod(resolveJava());
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
113 }
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
114
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
115 private Executable resolveJava() {
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
116 try {
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
117 Executable res;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
118 Class<?>[] parameterTypes = isStatic ? argumentTypes : Arrays.copyOfRange(argumentTypes, 1, argumentTypes.length);
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
119 if (name.equals("<init>")) {
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
120 res = declaringClass.getDeclaredConstructor(parameterTypes);
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
121 } else {
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
122 res = declaringClass.getDeclaredMethod(name, parameterTypes);
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
123 }
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
124 assert Modifier.isStatic(res.getModifiers()) == isStatic;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
125 return res;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
126 } catch (NoSuchMethodException | SecurityException e) {
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
127 throw new GraalInternalError(e);
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
128 }
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
129 }
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
130
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
131 @Override
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
132 public String toString() {
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
133 StringBuilder sb = new StringBuilder(declaringClass.getName()).append('.').append(name).append('(');
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
134 for (Class<?> p : argumentTypes) {
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
135 if (sb.charAt(sb.length() - 1) != '(') {
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
136 sb.append(", ");
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
137 }
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
138 sb.append(p.getSimpleName());
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
139 }
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
140 return sb.append(')').toString();
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
141 }
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
142 }
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
143
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
144 private final MetaAccessProvider metaAccess;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
145
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
146 /**
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
147 * Initial list of entries.
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
148 */
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
149 private final List<MethodKey<V>> registrations;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
150
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
151 /**
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
152 * Entry array that is initialized upon first call to {@link #get(MethodIdHolder)}.
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
153 *
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
154 * Note: this must be volatile since double-checked locking is used to initialize it
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
155 */
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
156 private volatile V[] entries;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
157
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
158 /**
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
159 * The minimum {@linkplain MethodIdHolder#getMethodId() id} for a key in this map.
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
160 */
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
161 private int minId = Integer.MAX_VALUE;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
162
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
163 public MethodIdMap(MetaAccessProvider metaAccess) {
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
164 this.metaAccess = metaAccess;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
165 this.registrations = new ArrayList<>(INITIAL_CAPACITY);
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
166 }
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
167
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
168 private static final int INITIAL_CAPACITY = 64;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
169
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
170 /**
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
171 * Adds an entry to this map for a specified method.
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
172 *
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
173 * @param value value to be associated with the specified method
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
174 * @param declaringClass the class declaring the method
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
175 * @param name the name of the method
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
176 * @param argumentTypes the argument types of the method. Element 0 of this array must be the
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
177 * {@link Class} value for {@link Receiver} iff the method is non-static.
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
178 * @return an object representing the method
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
179 */
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
180 public MethodKey<V> put(V value, Class<?> declaringClass, String name, Class<?>... argumentTypes) {
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
181 MethodKey<V> methodKey = new MethodKey<>(value, declaringClass, name, argumentTypes);
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
182 assert entries == null : "registration is closed";
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
183 assert !registrations.contains(methodKey) : "a value is already registered for " + methodKey;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
184 registrations.add(methodKey);
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
185 return methodKey;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
186 }
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
187
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
188 @SuppressWarnings("unchecked")
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
189 protected V[] allocateEntries(int length) {
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
190 return (V[]) new Object[length];
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
191 }
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
192
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
193 /**
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
194 * Determines if a method denoted by a given {@link MethodKey} is in this map.
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
195 */
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
196 public boolean containsKey(MethodKey<V> key) {
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
197 return registrations.contains(key);
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
198 }
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
199
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
200 public V get(MethodIdHolder method) {
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
201 if (entries == null) {
21376
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
202 createEntries();
20887
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
203 }
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
204
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
205 int id = method.getMethodId();
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
206 int index = id - minId;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
207 return index >= 0 && index < entries.length ? entries[index] : null;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
208 }
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
209
21376
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
210 public void createEntries() {
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
211 // 'assignIds' synchronizes on a global lock which ensures thread safe
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
212 // allocation of identifiers across all MethodIdHolder objects
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
213 MethodIdHolder.assignIds(new Consumer<MethodIdAllocator>() {
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
214
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
215 public void accept(MethodIdAllocator idAllocator) {
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
216 if (entries == null) {
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
217 if (registrations.isEmpty()) {
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
218 entries = allocateEntries(0);
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
219 } else {
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
220 int max = Integer.MIN_VALUE;
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
221 for (MethodKey<V> methodKey : registrations) {
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
222 MethodIdHolder m = methodKey.resolve(metaAccess);
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
223 int id = idAllocator.assignId(m);
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
224 if (id < minId) {
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
225 minId = id;
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
226 }
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
227 if (id > max) {
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
228 max = id;
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
229 }
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
230 methodKey.id = id;
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
231 }
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
232
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
233 int length = (max - minId) + 1;
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
234 entries = allocateEntries(length);
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
235 for (MethodKey<V> m : registrations) {
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
236 int index = m.id - minId;
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
237 entries[index] = m.value;
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
238 }
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
239 }
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
240 }
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
241 }
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
242 });
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
243 }
739d9d9bd2fc Allow closing of invocation plugin registry to prevent future modifications
Christian Wimmer <christian.wimmer@oracle.com>
parents: 20887
diff changeset
244
20887
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
245 @Override
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
246 public String toString() {
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
247 return registrations.stream().map(MethodKey::toString).collect(Collectors.joining(", "));
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
248 }
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
249
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
250 public MetaAccessProvider getMetaAccess() {
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
251 return metaAccess;
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
252 }
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
253
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
254 public int size() {
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
255 return registrations.size();
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
256 }
dc58f4ca21c9 generalized map in InvocationPlugins to MethodIdMap
Doug Simon <doug.simon@oracle.com>
parents:
diff changeset
257 }