3030import java .lang .reflect .Array ;
3131import java .lang .reflect .Field ;
3232import java .lang .reflect .InvocationTargetException ;
33+ import java .lang .reflect .Member ;
3334import java .lang .reflect .Method ;
3435import java .util .Iterator ;
3536import java .util .Optional ;
3940
4041import com .oracle .graal .pointsto .meta .AnalysisMetaAccess ;
4142import com .oracle .graal .pointsto .meta .AnalysisType ;
42- import com .oracle .svm .core .BuildPhaseProvider ;
4343import com .oracle .svm .core .feature .AutomaticallyRegisteredFeature ;
4444import com .oracle .svm .core .feature .InternalFeature ;
4545import com .oracle .svm .core .fieldvaluetransformer .FieldValueTransformerWithAvailability ;
8181@ SuppressWarnings ("unused" )
8282public class MethodHandleFeature implements InternalFeature {
8383
84- private Class <?> memberNameClass ;
85- private Method memberNameGetDeclaringClass ;
86- private Method memberNameGetName ;
8784 private Method memberNameIsMethod ;
8885 private Method memberNameIsConstructor ;
8986 private Method memberNameIsField ;
@@ -106,9 +103,7 @@ public class MethodHandleFeature implements InternalFeature {
106103
107104 @ Override
108105 public void duringSetup (DuringSetupAccess access ) {
109- memberNameClass = access .findClassByName ("java.lang.invoke.MemberName" );
110- memberNameGetDeclaringClass = ReflectionUtil .lookupMethod (memberNameClass , "getDeclaringClass" );
111- memberNameGetName = ReflectionUtil .lookupMethod (memberNameClass , "getName" );
106+ Class <?> memberNameClass = access .findClassByName ("java.lang.invoke.MemberName" );
112107 memberNameIsMethod = ReflectionUtil .lookupMethod (memberNameClass , "isMethod" );
113108 memberNameIsConstructor = ReflectionUtil .lookupMethod (memberNameClass , "isConstructor" );
114109 memberNameIsField = ReflectionUtil .lookupMethod (memberNameClass , "isField" );
@@ -126,8 +121,6 @@ public void duringSetup(DuringSetupAccess access) {
126121 Class <?> concurrentWeakInternSetClass = access .findClassByName ("java.lang.invoke.MethodType$ConcurrentWeakInternSet" );
127122 runtimeMethodTypeInternTable = ReflectionUtil .newInstance (concurrentWeakInternSetClass );
128123 concurrentWeakInternSetAdd = ReflectionUtil .lookupMethod (concurrentWeakInternSetClass , "add" , Object .class );
129-
130- access .registerObjectReplacer (this ::registerSeenObject );
131124 }
132125
133126 @ Override
@@ -313,39 +306,28 @@ private static void registerVarHandleMethodsForReflection(FeatureAccess access,
313306 }
314307 }
315308
316- private Object registerSeenObject (Object obj ) {
317- if (!BuildPhaseProvider .isAnalysisFinished ()) {
318- if (obj instanceof MethodType mt ) {
319- registerMethodType (mt );
320- } else if (memberNameClass .isInstance (obj )) {
321- /*
322- * We used to register only MemberName instances which are reachable from a
323- * MethodHandle, but optimizations can eliminate a MethodHandle object in code which
324- * we might never see otherwise and leave a MemberName object behind which is still
325- * used for a call. Therefore, we register all MemberName instances in the image
326- * heap, which should only be reachable via MethodHandle objects, in any case.
327- */
328- registerMemberName (obj );
329- }
330- }
331- return obj ;
332- }
333-
334- private void registerMethodType (MethodType methodType ) {
309+ public void registerHeapMethodType (MethodType methodType ) {
335310 try {
336311 concurrentWeakInternSetAdd .invoke (runtimeMethodTypeInternTable , methodType );
337312 } catch (ReflectiveOperationException e ) {
338313 throw VMError .shouldNotReachHere (e );
339314 }
340315 }
341316
342- private void registerMemberName (Object memberName ) {
317+ public void registerHeapMemberName (Member memberName ) {
318+ /*
319+ * We used to register only MemberName instances which are reachable from MethodHandle
320+ * objects, but code optimizations can eliminate a MethodHandle object which might never
321+ * become reachable otherwise and leave a MemberName object behind which is still used for a
322+ * call or field access. Therefore, we register all MemberName instances in the image heap,
323+ * which should only come into existence via MethodHandle objects, in any case.
324+ */
343325 try {
344- Class <?> declaringClass = ( Class <?>) memberNameGetDeclaringClass . invoke ( memberName );
326+ Class <?> declaringClass = memberName . getDeclaringClass ( );
345327 boolean isMethod = (boolean ) memberNameIsMethod .invoke (memberName );
346328 boolean isConstructor = (boolean ) memberNameIsConstructor .invoke (memberName );
347329 boolean isField = (boolean ) memberNameIsField .invoke (memberName );
348- String name = (isMethod || isField ) ? ( String ) memberNameGetName . invoke ( memberName ) : null ;
330+ String name = (isMethod || isField ) ? memberName . getName ( ) : null ;
349331 Class <?>[] paramTypes = null ;
350332 if (isMethod || isConstructor ) {
351333 MethodType methodType = (MethodType ) memberNameGetMethodType .invoke (memberName );
0 commit comments