25
25
package com .oracle .svm .hosted .methodhandles ;
26
26
27
27
import java .lang .invoke .CallSite ;
28
- import java .lang .invoke .MethodHandle ;
29
28
import java .lang .invoke .MethodType ;
30
- import java .lang .reflect . Array ;
29
+ import java .lang .invoke . VarHandle ;
31
30
import java .lang .reflect .Field ;
32
31
import java .lang .reflect .InvocationTargetException ;
33
32
import java .lang .reflect .Member ;
34
33
import java .lang .reflect .Method ;
35
- import java .util .Iterator ;
36
34
import java .util .Optional ;
37
35
import java .util .concurrent .ConcurrentHashMap ;
38
36
import java .util .function .Supplier ;
@@ -109,24 +107,24 @@ public class MethodHandleFeature implements InternalFeature {
109
107
110
108
@ Override
111
109
public void duringSetup (DuringSetupAccess access ) {
112
- Class <?> memberNameClass = access . findClassByName ( "java.lang.invoke.MemberName" );
110
+ Class <?> memberNameClass = ReflectionUtil . lookupClass ( false , "java.lang.invoke.MemberName" );
113
111
memberNameIsMethod = ReflectionUtil .lookupMethod (memberNameClass , "isMethod" );
114
112
memberNameIsConstructor = ReflectionUtil .lookupMethod (memberNameClass , "isConstructor" );
115
113
memberNameIsField = ReflectionUtil .lookupMethod (memberNameClass , "isField" );
116
114
memberNameGetMethodType = ReflectionUtil .lookupMethod (memberNameClass , "getMethodType" );
117
115
118
- Class <?> lambdaFormClass = access . findClassByName ( "java.lang.invoke.LambdaForm" );
116
+ Class <?> lambdaFormClass = ReflectionUtil . lookupClass ( false , "java.lang.invoke.LambdaForm" );
119
117
lambdaFormLFIdentity = ReflectionUtil .lookupField (lambdaFormClass , "LF_identity" );
120
118
lambdaFormLFZero = ReflectionUtil .lookupField (lambdaFormClass , "LF_zero" );
121
119
lambdaFormNFIdentity = ReflectionUtil .lookupField (lambdaFormClass , "NF_identity" );
122
120
lambdaFormNFZero = ReflectionUtil .lookupField (lambdaFormClass , "NF_zero" );
123
121
124
- Class <?> arrayAccessorClass = access . findClassByName ( "java.lang.invoke.MethodHandleImpl$ArrayAccessor" );
122
+ Class <?> arrayAccessorClass = ReflectionUtil . lookupClass ( false , "java.lang.invoke.MethodHandleImpl$ArrayAccessor" );
125
123
typedAccessors = ReflectionUtil .lookupField (arrayAccessorClass , "TYPED_ACCESSORS" );
126
124
127
125
if (JDK21u4OrLater .jdk21u4OrLater ) {
128
126
try {
129
- Class <?> referencedKeySetClass = access . findClassByName ( "jdk.internal.util.ReferencedKeySet" );
127
+ Class <?> referencedKeySetClass = ReflectionUtil . lookupClass ( false , "jdk.internal.util.ReferencedKeySet" );
130
128
Method create = ReflectionUtil .lookupMethod (referencedKeySetClass , "create" , boolean .class , boolean .class , Supplier .class );
131
129
// The following call must match the static initializer of MethodType#internTable.
132
130
runtimeMethodTypeInternTable = create .invoke (null ,
@@ -136,7 +134,7 @@ public void duringSetup(DuringSetupAccess access) {
136
134
throw VMError .shouldNotReachHere (e );
137
135
}
138
136
} else {
139
- Class <?> concurrentWeakInternSetClass = access . findClassByName ( "java.lang.invoke.MethodType$ConcurrentWeakInternSet" );
137
+ Class <?> concurrentWeakInternSetClass = ReflectionUtil . lookupClass ( false , "java.lang.invoke.MethodType$ConcurrentWeakInternSet" );
140
138
runtimeMethodTypeInternTable = ReflectionUtil .newInstance (concurrentWeakInternSetClass );
141
139
referencedKeySetAdd = ReflectionUtil .lookupMethod (concurrentWeakInternSetClass , "add" , Object .class );
142
140
}
@@ -154,43 +152,20 @@ public void duringSetup(DuringSetupAccess access) {
154
152
155
153
@ Override
156
154
public void beforeAnalysis (BeforeAnalysisAccess access ) {
157
- /* java.lang.invoke functions called through reflection */
158
- Class <?> mhImplClazz = access .findClassByName ("java.lang.invoke.MethodHandleImpl" );
159
-
160
- access .registerReachabilityHandler (MethodHandleFeature ::registerMHImplFunctionsForReflection ,
161
- ReflectionUtil .lookupMethod (mhImplClazz , "getFunction" , byte .class ));
162
-
163
- access .registerReachabilityHandler (MethodHandleFeature ::registerMHImplConstantHandlesForReflection ,
164
- ReflectionUtil .lookupMethod (mhImplClazz , "makeConstantHandle" , int .class ));
165
-
166
- access .registerReachabilityHandler (MethodHandleFeature ::registerMHImplCountingWrapperFunctionsForReflection ,
167
- access .findClassByName ("java.lang.invoke.MethodHandleImpl$CountingWrapper" ));
168
-
169
- access .registerReachabilityHandler (MethodHandleFeature ::registerInvokersFunctionsForReflection ,
170
- ReflectionUtil .lookupMethod (access .findClassByName ("java.lang.invoke.Invokers" ), "getFunction" , byte .class ));
171
-
155
+ eagerlyInitializeMHImplFunctions ();
156
+ eagerlyInitializeMHImplConstantHandles ();
157
+ eagerlyInitializeInvokersFunctions ();
172
158
eagerlyInitializeValueConversionsCaches ();
159
+ eagerlyInitializeCallSite ();
173
160
174
- access .registerClassInitializerReachabilityHandler (MethodHandleFeature ::registerDelegatingMHFunctionsForReflection ,
175
- access .findClassByName ("java.lang.invoke.DelegatingMethodHandle" ));
176
-
177
- access .registerReachabilityHandler (MethodHandleFeature ::registerCallSiteGetTargetForReflection ,
178
- ReflectionUtil .lookupMethod (CallSite .class , "getTargetHandle" ));
179
-
180
- access .registerReachabilityHandler (MethodHandleFeature ::registerUninitializedCallSiteForReflection ,
181
- ReflectionUtil .lookupMethod (CallSite .class , "uninitializedCallSiteHandle" ));
182
-
183
- access .registerSubtypeReachabilityHandler (MethodHandleFeature ::registerVarHandleMethodsForReflection ,
184
- access .findClassByName ("java.lang.invoke.VarHandle" ));
185
-
186
- access .registerSubtypeReachabilityHandler (MethodHandleFeature ::scanBoundMethodHandle ,
187
- access .findClassByName ("java.lang.invoke.BoundMethodHandle" ));
161
+ access .registerSubtypeReachabilityHandler (MethodHandleFeature ::registerVarHandleMethodsForReflection , VarHandle .class );
162
+ access .registerSubtypeReachabilityHandler (MethodHandleFeature ::scanBoundMethodHandle , ReflectionUtil .lookupClass (false , "java.lang.invoke.BoundMethodHandle" ));
188
163
189
164
AnalysisMetaAccess metaAccess = ((FeatureImpl .BeforeAnalysisAccessImpl ) access ).getMetaAccess ();
190
165
access .registerFieldValueTransformer (
191
166
ReflectionUtil .lookupField (ReflectionUtil .lookupClass (false , "java.lang.invoke.ClassSpecializer" ), "cache" ),
192
167
new FieldValueTransformerWithAvailability () {
193
- private static final Class <?> speciesDataClass = ReflectionUtil .lookupClass (false , "java.lang.invoke.ClassSpecializer$SpeciesData" );
168
+ private static final Class <?> SPECIES_DATA_CLASS = ReflectionUtil .lookupClass (false , "java.lang.invoke.ClassSpecializer$SpeciesData" );
194
169
195
170
/*
196
171
* The value of the ClassSpecializer.cache is not seen by the analysis
@@ -219,7 +194,7 @@ public Object transform(Object receiver, Object originalValue) {
219
194
}
220
195
221
196
private boolean isSpeciesReachable (Object speciesData ) {
222
- Class <?> speciesClass = ReflectionUtil .readField (speciesDataClass , "speciesCode" , speciesData );
197
+ Class <?> speciesClass = ReflectionUtil .readField (SPECIES_DATA_CLASS , "speciesCode" , speciesData );
223
198
Optional <AnalysisType > analysisType = metaAccess .optionalLookupJavaType (speciesClass );
224
199
return analysisType .isPresent () && analysisType .get ().isReachable ();
225
200
}
@@ -229,43 +204,31 @@ private boolean isSpeciesReachable(Object speciesData) {
229
204
(receiver , originalValue ) -> runtimeMethodTypeInternTable );
230
205
}
231
206
232
- private static void registerMHImplFunctionsForReflection (DuringAnalysisAccess access ) {
233
- Class <?> mhImplClazz = access .findClassByName ("java.lang.invoke.MethodHandleImpl" );
234
- RuntimeReflection .register (ReflectionUtil .lookupMethod (mhImplClazz , "checkSpreadArgument" , Object .class , int .class ));
235
- RuntimeReflection .register (ReflectionUtil .lookupMethod (mhImplClazz , "guardWithCatch" , MethodHandle .class , Class .class , MethodHandle .class , Object [].class ));
236
- RuntimeReflection .register (ReflectionUtil .lookupMethod (mhImplClazz , "tryFinally" , MethodHandle .class , MethodHandle .class , Object [].class ));
237
- RuntimeReflection .register (ReflectionUtil .lookupMethod (mhImplClazz , "loop" , access .findClassByName ("[Ljava.lang.invoke.LambdaForm$BasicType;" ),
238
- access .findClassByName ("java.lang.invoke.MethodHandleImpl$LoopClauses" ), Object [].class ));
239
- RuntimeReflection .register (ReflectionUtil .lookupMethod (mhImplClazz , "throwException" , Throwable .class ));
240
- RuntimeReflection .register (ReflectionUtil .lookupMethod (mhImplClazz , "profileBoolean" , boolean .class , int [].class ));
241
- }
242
-
243
- private static void registerMHImplConstantHandlesForReflection (DuringAnalysisAccess access ) {
244
- Class <?> mhImplClazz = access .findClassByName ("java.lang.invoke.MethodHandleImpl" );
245
- RuntimeReflection .register (ReflectionUtil .lookupMethod (mhImplClazz , "selectAlternative" , boolean .class , MethodHandle .class , MethodHandle .class ));
246
- RuntimeReflection .register (ReflectionUtil .lookupMethod (mhImplClazz , "countedLoopPredicate" , int .class , int .class ));
247
- RuntimeReflection .register (ReflectionUtil .lookupMethod (mhImplClazz , "countedLoopStep" , int .class , int .class ));
248
- RuntimeReflection .register (ReflectionUtil .lookupMethod (mhImplClazz , "initIterator" , Iterable .class ));
249
- RuntimeReflection .register (ReflectionUtil .lookupMethod (mhImplClazz , "iteratePredicate" , Iterator .class ));
250
- RuntimeReflection .register (ReflectionUtil .lookupMethod (mhImplClazz , "iterateNext" , Iterator .class ));
251
- RuntimeReflection .register (ReflectionUtil .lookupMethod (Array .class , "newInstance" , Class .class , int .class ));
207
+ private static void eagerlyInitializeMHImplFunctions () {
208
+ var methodHandleImplClass = ReflectionUtil .lookupClass (false , "java.lang.invoke.MethodHandleImpl" );
209
+ int count = ((Object []) ReflectionUtil .readStaticField (methodHandleImplClass , "NFS" )).length ;
210
+ var getFunctionMethod = ReflectionUtil .lookupMethod (methodHandleImplClass , "getFunction" , byte .class );
211
+ for (int i = 0 ; i < count ; i ++) {
212
+ ReflectionUtil .invokeMethod (getFunctionMethod , null , (byte ) i );
213
+ }
252
214
}
253
215
254
- private static void registerMHImplCountingWrapperFunctionsForReflection (DuringAnalysisAccess access ) {
255
- RuntimeReflection .register (ReflectionUtil .lookupMethod (access .findClassByName ("java.lang.invoke.MethodHandleImpl$CountingWrapper" ), "maybeStopCounting" , Object .class ));
216
+ private static void eagerlyInitializeMHImplConstantHandles () {
217
+ var methodHandleImplClass = ReflectionUtil .lookupClass (false , "java.lang.invoke.MethodHandleImpl" );
218
+ int count = ((Object []) ReflectionUtil .readStaticField (methodHandleImplClass , "HANDLES" )).length ;
219
+ var getConstantHandleMethod = ReflectionUtil .lookupMethod (methodHandleImplClass , "getConstantHandle" , int .class );
220
+ for (int i = 0 ; i < count ; i ++) {
221
+ ReflectionUtil .invokeMethod (getConstantHandleMethod , null , i );
222
+ }
256
223
}
257
224
258
- private static void registerInvokersFunctionsForReflection (DuringAnalysisAccess access ) {
259
- Class <?> invokersClazz = access .findClassByName ("java.lang.invoke.Invokers" );
260
- RuntimeReflection .register (ReflectionUtil .lookupMethod (invokersClazz , "checkExactType" , MethodHandle .class , MethodType .class ));
261
- RuntimeReflection .register (ReflectionUtil .lookupMethod (invokersClazz , "checkGenericType" , MethodHandle .class , MethodType .class ));
262
- RuntimeReflection .register (ReflectionUtil .lookupMethod (invokersClazz , "getCallSiteTarget" , CallSite .class ));
263
- RuntimeReflection .register (ReflectionUtil .lookupMethod (invokersClazz , "checkCustomized" , MethodHandle .class ));
264
- RuntimeReflection .register (ReflectionUtil .lookupMethod (invokersClazz , "checkVarHandleGenericType" , access .findClassByName ("java.lang.invoke.VarHandle" ),
265
- access .findClassByName ("java.lang.invoke.VarHandle$AccessDescriptor" )));
266
- RuntimeReflection .register (ReflectionUtil .lookupMethod (invokersClazz , "checkVarHandleExactType" , access .findClassByName ("java.lang.invoke.VarHandle" ),
267
- access .findClassByName ("java.lang.invoke.VarHandle$AccessDescriptor" )));
268
- RuntimeReflection .register (ReflectionUtil .lookupMethod (invokersClazz , "directVarHandleTarget" , access .findClassByName ("java.lang.invoke.VarHandle" )));
225
+ private static void eagerlyInitializeInvokersFunctions () {
226
+ var invokerksClass = ReflectionUtil .lookupClass (false , "java.lang.invoke.Invokers" );
227
+ int count = ((Object []) ReflectionUtil .readStaticField (invokerksClass , "NFS" )).length ;
228
+ var getFunctionMethod = ReflectionUtil .lookupMethod (invokerksClass , "getFunction" , byte .class );
229
+ for (int i = 0 ; i < count ; i ++) {
230
+ ReflectionUtil .invokeMethod (getFunctionMethod , null , (byte ) i );
231
+ }
269
232
}
270
233
271
234
/**
@@ -294,21 +257,13 @@ private static void eagerlyInitializeValueConversionsCaches() {
294
257
}
295
258
}
296
259
297
- private static void registerDelegatingMHFunctionsForReflection (DuringAnalysisAccess access ) {
298
- Class <?> delegatingMHClazz = access .findClassByName ("java.lang.invoke.DelegatingMethodHandle" );
299
- RuntimeReflection .register (ReflectionUtil .lookupMethod (delegatingMHClazz , "getTarget" ));
300
- }
301
-
302
- private static void registerCallSiteGetTargetForReflection (DuringAnalysisAccess access ) {
303
- RuntimeReflection .register (ReflectionUtil .lookupMethod (CallSite .class , "getTarget" ));
304
- }
305
-
306
- private static void registerUninitializedCallSiteForReflection (DuringAnalysisAccess access ) {
307
- RuntimeReflection .register (ReflectionUtil .lookupMethod (CallSite .class , "uninitializedCallSite" , Object [].class ));
260
+ private static void eagerlyInitializeCallSite () {
261
+ ReflectionUtil .invokeMethod (ReflectionUtil .lookupMethod (CallSite .class , "getTargetHandle" ), null );
262
+ ReflectionUtil .invokeMethod (ReflectionUtil .lookupMethod (CallSite .class , "uninitializedCallSiteHandle" ), null );
308
263
}
309
264
310
265
private static void registerVarHandleMethodsForReflection (FeatureAccess access , Class <?> subtype ) {
311
- if (subtype .getPackage ().getName ().equals ("java.lang.invoke" ) && subtype != access . findClassByName ( "java.lang.invoke. VarHandle" ) ) {
266
+ if (subtype .getPackage ().getName ().equals ("java.lang.invoke" ) && subtype != VarHandle . class ) {
312
267
RuntimeReflection .register (subtype .getDeclaredMethods ());
313
268
}
314
269
}
0 commit comments