32
32
import jdk .graal .compiler .nodes .java .MethodCallTargetNode ;
33
33
import jdk .graal .compiler .nodes .spi .CoreProviders ;
34
34
import jdk .graal .compiler .phases .BasePhase ;
35
- import jdk .internal .loader .BuiltinClassLoader ;
36
- import jdk .internal .loader .Loader ;
37
- import jdk .vm .ci .meta .ResolvedJavaType ;
38
- import sun .invoke .util .ValueConversions ;
39
- import sun .invoke .util .VerifyAccess ;
40
- import sun .security .x509 .X500Name ;
41
- import sun .util .locale .provider .LocaleProviderAdapter ;
35
+ import jdk .vm .ci .meta .JavaType ;
36
+ import jdk .vm .ci .meta .Signature ;
42
37
43
38
import java .io .ObjectInputStream ;
44
39
import java .io .ObjectOutputStream ;
45
40
import java .io .ObjectStreamClass ;
46
41
import java .lang .invoke .ConstantBootstraps ;
42
+ import java .lang .invoke .MethodHandle ;
47
43
import java .lang .invoke .MethodHandleProxies ;
48
44
import java .lang .invoke .MethodHandles ;
45
+ import java .lang .invoke .MethodType ;
49
46
import java .lang .invoke .VarHandle ;
50
47
import java .lang .reflect .Array ;
51
48
import java .lang .reflect .Constructor ;
49
+ import java .lang .reflect .Field ;
50
+ import java .lang .reflect .InvocationHandler ;
52
51
import java .lang .reflect .Method ;
53
52
import java .lang .reflect .Proxy ;
54
53
import java .net .URISyntaxException ;
55
54
import java .net .URL ;
56
- import java .net .URLClassLoader ;
57
55
import java .security .CodeSource ;
56
+ import java .util .ArrayList ;
57
+ import java .util .Arrays ;
58
58
import java .util .HashMap ;
59
59
import java .util .List ;
60
+ import java .util .Locale ;
60
61
import java .util .Map ;
62
+ import java .util .Objects ;
61
63
import java .util .ResourceBundle ;
62
64
import java .util .Set ;
63
65
import java .util .random .RandomGeneratorFactory ;
@@ -83,96 +85,134 @@ public enum DynamicAccessKind {
83
85
}
84
86
}
85
87
86
- public record MethodInfo (DynamicAccessKind accessKind , String name ) {
88
+ public record MethodInfo (DynamicAccessKind accessKind , String signature ) {
87
89
}
88
90
89
- private static final Map <Class <?>, Set <String >> reflectionMethodNames = new HashMap <>();
90
- private static final Map <Class <?>, Set <String >> resourceMethodNames = new HashMap <>();
91
+ private static final Map <Class <?>, Set <MethodSignature >> reflectionMethodSignatures = new HashMap <>();
92
+ private static final Map <Class <?>, Set <MethodSignature >> resourceMethodSignatures = new HashMap <>();
91
93
92
94
private final DynamicAccessDetectionFeature dynamicAccessDetectionFeature ;
93
95
94
96
static {
95
- reflectionMethodNames .put (Class .class , Set .of (
96
- "forName" ,
97
- "getClasses" ,
98
- "getDeclaredClasses" ,
99
- "getConstructor" ,
100
- "getConstructors" ,
101
- "getDeclaredConstructor" ,
102
- "getDeclaredConstructors" ,
103
- "getField" ,
104
- "getFields" ,
105
- "getDeclaredField" ,
106
- "getDeclaredFields" ,
107
- "getMethod" ,
108
- "getMethods" ,
109
- "getDeclaredMethod" ,
110
- "getDeclaredMethods" ,
111
- "getNestMembers" ,
112
- "getPermittedSubclasses" ,
113
- "getRecordComponents" ,
114
- "getSigners" ,
115
- "arrayType" ,
116
- "newInstance" ));
117
- reflectionMethodNames .put (Method .class , Set .of ("invoke" ));
118
- reflectionMethodNames .put (MethodHandles .Lookup .class , Set .of (
119
- "findClass" ,
120
- "findVirtual" ,
121
- "findStatic" ,
122
- "findConstructor" ,
123
- "findSpecial" ,
124
- "findGetter" ,
125
- "findSetter" ,
126
- "findStaticGetter" ,
127
- "findStaticSetter" ,
128
- "findVarHandle" ,
129
- "findStaticVarHandle" ,
130
- "unreflect" ,
131
- "unreflectSpecial" ,
132
- "unreflectConstructor" ,
133
- "unreflectGetter" ,
134
- "unreflectSetter" ,
135
- "unreflectVarHandle" ));
136
- reflectionMethodNames .put (ClassLoader .class , Set .of (
137
- "loadClass" ,
138
- "findBootstrapClassOrNull" ,
139
- "findLoadedClass" ,
140
- "findSystemClass" ));
141
- reflectionMethodNames .put (URLClassLoader .class , Set .of ("loadClass" ));
142
- reflectionMethodNames .put (Array .class , Set .of ("newInstance" ));
143
- reflectionMethodNames .put (Constructor .class , Set .of ("newInstance" ));
144
- reflectionMethodNames .put (VerifyAccess .class , Set .of ("isTypeVisible" ));
145
- reflectionMethodNames .put (LocaleProviderAdapter .class , Set .of ("forType" ));
146
- reflectionMethodNames .put (ValueConversions .class , Set .of ("boxExact" ));
147
- reflectionMethodNames .put (ConstantBootstraps .class , Set .of (
148
- "getStaticFinal" ,
149
- "staticFieldVarHandle" ,
150
- "fieldVarHandle" ));
151
- reflectionMethodNames .put (VarHandle .VarHandleDesc .class , Set .of ("resolveConstantDesc" ));
152
- reflectionMethodNames .put (RandomGeneratorFactory .class , Set .of ("create" ));
153
- reflectionMethodNames .put (X500Name .class , Set .of ("asX500Principal" ));
154
- reflectionMethodNames .put (MethodHandleProxies .class , Set .of ("asInterfaceInstance" ));
97
+ reflectionMethodSignatures .put (Class .class , Set .of (
98
+ new MethodSignature ("forName" , String .class ),
99
+ new MethodSignature ("forName" , String .class , boolean .class , ClassLoader .class ),
100
+ new MethodSignature ("forName" , Module .class , String .class ),
101
+ new MethodSignature ("getClasses" ),
102
+ new MethodSignature ("getDeclaredClasses" ),
103
+ new MethodSignature ("getConstructor" , Class [].class ),
104
+ new MethodSignature ("getConstructors" ),
105
+ new MethodSignature ("getDeclaredConstructor" , Class [].class ),
106
+ new MethodSignature ("getDeclaredConstructors" ),
107
+ new MethodSignature ("getField" , String .class ),
108
+ new MethodSignature ("getFields" ),
109
+ new MethodSignature ("getDeclaredField" , String .class ),
110
+ new MethodSignature ("getDeclaredFields" ),
111
+ new MethodSignature ("getMethod" , String .class , Class [].class ),
112
+ new MethodSignature ("getMethods" ),
113
+ new MethodSignature ("getDeclaredMethod" , String .class , Class [].class ),
114
+ new MethodSignature ("getDeclaredMethods" ),
115
+ new MethodSignature ("getNestMembers" ),
116
+ new MethodSignature ("getPermittedSubclasses" ),
117
+ new MethodSignature ("getRecordComponents" ),
118
+ new MethodSignature ("getSigners" ),
119
+ new MethodSignature ("arrayType" ),
120
+ new MethodSignature ("newInstance" )
121
+ ));
122
+ reflectionMethodSignatures .put (Method .class , Set .of (
123
+ new MethodSignature ("invoke" , Object .class , Object [].class )
124
+ ));
125
+ reflectionMethodSignatures .put (MethodHandles .Lookup .class , Set .of (
126
+ new MethodSignature ("findClass" , String .class ),
127
+ new MethodSignature ("findVirtual" , Class .class , String .class , MethodType .class ),
128
+ new MethodSignature ("findStatic" , Class .class , String .class , MethodType .class ),
129
+ new MethodSignature ("findConstructor" , Class .class , MethodType .class ),
130
+ new MethodSignature ("findSpecial" , Class .class , String .class , MethodType .class , Class .class ),
131
+ new MethodSignature ("findGetter" , Class .class , String .class , Class .class ),
132
+ new MethodSignature ("findSetter" , Class .class , String .class , Class .class ),
133
+ new MethodSignature ("findStaticGetter" , Class .class , String .class , Class .class ),
134
+ new MethodSignature ("findStaticSetter" , Class .class , String .class , Class .class ),
135
+ new MethodSignature ("findVarHandle" , Class .class , String .class , Class .class ),
136
+ new MethodSignature ("findStaticVarHandle" , Class .class , String .class , Class .class ),
137
+ new MethodSignature ("unreflect" , Method .class ),
138
+ new MethodSignature ("unreflectSpecial" , Method .class , Class .class ),
139
+ new MethodSignature ("unreflectConstructor" , Constructor .class ),
140
+ new MethodSignature ("unreflectGetter" , Field .class ),
141
+ new MethodSignature ("unreflectSetter" , Field .class ),
142
+ new MethodSignature ("unreflectVarHandle" , Field .class )
143
+ ));
144
+ reflectionMethodSignatures .put (ClassLoader .class , Set .of (
145
+ new MethodSignature ("loadClass" , String .class ),
146
+ new MethodSignature ("findLoadedClass" , String .class ),
147
+ new MethodSignature ("findSystemClass" , String .class )
148
+ ));
149
+ reflectionMethodSignatures .put (Array .class , Set .of (
150
+ new MethodSignature ("newInstance" , Class .class , int .class ),
151
+ new MethodSignature ("newInstance" , Class .class , int [].class )
152
+ ));
153
+ reflectionMethodSignatures .put (Constructor .class , Set .of (
154
+ new MethodSignature ("newInstance" , Object [].class )
155
+ ));
156
+ reflectionMethodSignatures .put (ConstantBootstraps .class , Set .of (
157
+ new MethodSignature ("getStaticFinal" , MethodHandles .Lookup .class , String .class , Class .class , Class .class ),
158
+ new MethodSignature ("getStaticFinal" , MethodHandles .Lookup .class , String .class , Class .class ),
159
+ new MethodSignature ("fieldVarHandle" , MethodHandles .Lookup .class , String .class , Class .class , Class .class , Class .class ),
160
+ new MethodSignature ("staticFieldVarHandle" , MethodHandles .Lookup .class , String .class , Class .class , Class .class , Class .class )
161
+ ));
162
+ reflectionMethodSignatures .put (VarHandle .VarHandleDesc .class , Set .of (
163
+ new MethodSignature ("resolveConstantDesc" , MethodHandles .Lookup .class )
164
+ ));
165
+ reflectionMethodSignatures .put (RandomGeneratorFactory .class , Set .of (
166
+ new MethodSignature ("create" ),
167
+ new MethodSignature ("create" , long .class ),
168
+ new MethodSignature ("create" , byte [].class )
169
+ ));
170
+ reflectionMethodSignatures .put (MethodHandleProxies .class , Set .of (
171
+ new MethodSignature ("asInterfaceInstance" , Class .class , MethodHandle .class )
172
+ ));
155
173
156
- reflectionMethodNames .put (ObjectOutputStream .class , Set .of ("writeObject" , "writeUnshared" ));
157
- reflectionMethodNames .put (ObjectInputStream .class , Set .of (
158
- "resolveClass" ,
159
- "resolveProxyClass" ,
160
- "readObject" ,
161
- "readUnshared" ));
162
- reflectionMethodNames .put (ObjectStreamClass .class , Set .of ("lookup" ));
174
+ reflectionMethodSignatures .put (ObjectOutputStream .class , Set .of (
175
+ new MethodSignature ("writeObject" , Object .class ),
176
+ new MethodSignature ("writeUnshared" , Object .class )
177
+ ));
178
+ reflectionMethodSignatures .put (ObjectInputStream .class , Set .of (
179
+ new MethodSignature ("resolveClass" , ObjectStreamClass .class ),
180
+ new MethodSignature ("resolveProxyClass" , String [].class ),
181
+ new MethodSignature ("readObject" ),
182
+ new MethodSignature ("readUnshared" )
183
+ ));
184
+ reflectionMethodSignatures .put (ObjectStreamClass .class , Set .of (
185
+ new MethodSignature ("lookup" , Class .class )
186
+ ));
163
187
164
- reflectionMethodNames .put (Proxy .class , Set .of ("getProxyClass" , "newProxyInstance" ));
188
+ reflectionMethodSignatures .put (Proxy .class , Set .of (
189
+ new MethodSignature ("getProxyClass" , ClassLoader .class , Class [].class ),
190
+ new MethodSignature ("newProxyInstance" , ClassLoader .class , Class [].class , InvocationHandler .class )
191
+ ));
165
192
166
- resourceMethodNames .put (ClassLoader .class , Set .of (
167
- "getResource" ,
168
- "getResources" ,
169
- "getSystemResource" ,
170
- "getSystemResources" ));
171
- resourceMethodNames .put (BuiltinClassLoader .class , Set .of ("findResource" , "findResourceAsStream" ));
172
- resourceMethodNames .put (Loader .class , Set .of ("findResource" ));
173
- resourceMethodNames .put (ResourceBundle .class , Set .of ("getBundleImpl" ));
174
- resourceMethodNames .put (Module .class , Set .of ("getResourceAsStream" ));
175
- resourceMethodNames .put (Class .class , Set .of ("getResource" , "getResourceAsStream" ));
193
+ resourceMethodSignatures .put (ClassLoader .class , Set .of (
194
+ new MethodSignature ("getResource" , String .class ),
195
+ new MethodSignature ("getResources" , String .class ),
196
+ new MethodSignature ("getSystemResource" , String .class ),
197
+ new MethodSignature ("getSystemResources" , String .class )
198
+ ));
199
+ resourceMethodSignatures .put (Module .class , Set .of (
200
+ new MethodSignature ("getResourceAsStream" , String .class )
201
+ ));
202
+ resourceMethodSignatures .put (Class .class , Set .of (
203
+ new MethodSignature ("getResource" , String .class ),
204
+ new MethodSignature ("getResourceAsStream" , String .class )
205
+ ));
206
+ resourceMethodSignatures .put (ResourceBundle .class , Set .of (
207
+ new MethodSignature ("getBundle" , String .class ),
208
+ new MethodSignature ("getBundle" , String .class , ResourceBundle .Control .class ),
209
+ new MethodSignature ("getBundle" , String .class , Locale .class ),
210
+ new MethodSignature ("getBundle" , String .class , Module .class ),
211
+ new MethodSignature ("getBundle" , String .class , Locale .class , Module .class ),
212
+ new MethodSignature ("getBundle" , String .class , Locale .class , ResourceBundle .Control .class ),
213
+ new MethodSignature ("getBundle" , String .class , Locale .class , ClassLoader .class ),
214
+ new MethodSignature ("getBundle" , String .class , Locale .class , ClassLoader .class , ResourceBundle .Control .class )
215
+ ));
176
216
}
177
217
178
218
public DynamicAccessDetectionPhase () {
@@ -185,11 +225,11 @@ protected void run(StructuredGraph graph, CoreProviders context) {
185
225
for (MethodCallTargetNode callTarget : callTargetNodes ) {
186
226
AnalysisType callerClass = (AnalysisType ) graph .method ().getDeclaringClass ();
187
227
String sourceEntry = getSourceEntry (callerClass );
188
- MethodInfo methodInfo = getMethod (callTarget );
228
+ MethodInfo methodInfo = getMethodInfo (callTarget );
189
229
190
230
if (methodInfo != null && sourceEntry != null ) {
191
231
DynamicAccessKind accessKind = methodInfo .accessKind ();
192
- String methodName = methodInfo .name ();
232
+ String methodName = methodInfo .signature ();
193
233
194
234
NodeSourcePosition nspToShow = callTarget .getNodeSourcePosition ();
195
235
if (nspToShow != null ) {
@@ -207,24 +247,32 @@ protected void run(StructuredGraph graph, CoreProviders context) {
207
247
}
208
248
209
249
/*
210
- * Returns the name and dynamic access kind (reflective or resource) of a
250
+ * Returns the signature, parameter types and dynamic access kind (reflective or resource) of a
211
251
* method if it exists in the predetermined set, based on its graph and MethodCallTargetNode;
212
252
* otherwise, returns null.
213
253
*/
214
- private static MethodInfo getMethod (MethodCallTargetNode callTarget ) {
254
+ private MethodInfo getMethodInfo (MethodCallTargetNode callTarget ) {
215
255
String methodName = callTarget .targetMethod ().getName ();
216
256
Class <?> declaringClass = OriginalClassProvider .getJavaClass (callTarget .targetMethod ().getDeclaringClass ());
257
+ List <Class <?>> paramList = new ArrayList <>();
258
+ Signature signature = callTarget .targetMethod ().getSignature ();
259
+ for (int i = 0 ; i < signature .getParameterCount (false ); i ++) {
260
+ JavaType type = signature .getParameterType (i , callTarget .targetMethod ().getDeclaringClass ());
261
+ paramList .add (OriginalClassProvider .getJavaClass (type ));
262
+ }
263
+ Class <?>[] paramTypes = paramList .toArray (new Class <?>[0 ]);
264
+ MethodSignature methodSignature = new MethodSignature (methodName , paramTypes );
217
265
218
- if (reflectionMethodNames .containsKey (declaringClass ) && reflectionMethodNames .get (declaringClass ).contains (methodName )) {
219
- return new MethodInfo (DynamicAccessKind .Reflection , declaringClass .getName () + "#" + methodName );
220
- } else if (resourceMethodNames .containsKey (declaringClass ) && resourceMethodNames .get (declaringClass ).contains (methodName )) {
221
- return new MethodInfo (DynamicAccessKind .Resource , declaringClass .getName () + "#" + methodName );
266
+ if (reflectionMethodSignatures .containsKey (declaringClass ) && reflectionMethodSignatures .get (declaringClass ).contains (methodSignature )) {
267
+ return new MethodInfo (DynamicAccessKind .Reflection , declaringClass .getName () + "#" + methodSignature );
268
+ } else if (resourceMethodSignatures .containsKey (declaringClass ) && resourceMethodSignatures .get (declaringClass ).contains (methodSignature )) {
269
+ return new MethodInfo (DynamicAccessKind .Resource , declaringClass .getName () + "#" + methodSignature );
222
270
}
223
271
return null ;
224
272
}
225
273
226
274
/*
227
- * Returns the class path entry, module or package name of the caller class if it is included in the value
275
+ * Returns the class path entry, module or package signature of the caller class if it is included in the value
228
276
* specified by the option, otherwise returns null.
229
277
*/
230
278
private static String getSourceEntry (AnalysisType callerClass ) {
@@ -249,7 +297,7 @@ private static String getSourceEntry(AnalysisType callerClass) {
249
297
}
250
298
251
299
String moduleName = callerClass .getJavaClass ().getModule ().getName ();
252
- if (sourceEntries .contains (moduleName )) {
300
+ if (moduleName != null && sourceEntries .contains (moduleName )) {
253
301
return moduleName ;
254
302
}
255
303
@@ -262,4 +310,46 @@ private static String getSourceEntry(AnalysisType callerClass) {
262
310
throw new RuntimeException (e );
263
311
}
264
312
}
313
+
314
+ private static class MethodSignature {
315
+ private final String name ;
316
+ private final Class <?>[] paramTypes ;
317
+
318
+ public MethodSignature (String name , Class <?>... paramTypes ) {
319
+ this .name = name ;
320
+ this .paramTypes = paramTypes ;
321
+ }
322
+
323
+ @ Override
324
+ public boolean equals (Object o ) {
325
+ if (this == o ) return true ;
326
+ if (!(o instanceof MethodSignature that )) return false ;
327
+ return name .equals (that .name ) && Arrays .equals (paramTypes , that .paramTypes );
328
+ }
329
+
330
+ @ Override
331
+ public int hashCode () {
332
+ return Objects .hash (name , Arrays .hashCode (paramTypes ));
333
+ }
334
+
335
+ @ Override
336
+ public String toString () {
337
+ StringBuilder sb = new StringBuilder ();
338
+ sb .append (name ).append ("(" );
339
+ for (int i = 0 ; i < paramTypes .length ; i ++) {
340
+ if (i > 0 ) sb .append (", " );
341
+ Class <?> param = paramTypes [i ];
342
+ if (param .isArray ()) {
343
+ sb .append (param .getComponentType ().getName ()).append ("[]" );
344
+ } else {
345
+ sb .append (param .getName ());
346
+ }
347
+ if (param .getTypeName ().contains ("?" )) {
348
+ sb .append ("<?>" );
349
+ }
350
+ }
351
+ sb .append (")" );
352
+ return sb .toString ();
353
+ }
354
+ }
265
355
}
0 commit comments