3636import static com .oracle .svm .interpreter .metadata .InterpreterUniverseImpl .toHexString ;
3737
3838import java .io .IOException ;
39- import java .lang .reflect .Constructor ;
40- import java .lang .reflect .Field ;
41- import java .lang .reflect .Method ;
4239import java .lang .reflect .Modifier ;
4340import java .nio .charset .StandardCharsets ;
4441import java .nio .file .FileSystems ;
6764import com .oracle .graal .pointsto .ObjectScanner .ScanReason ;
6865import com .oracle .graal .pointsto .constraints .UnsupportedFeatureException ;
6966import com .oracle .graal .pointsto .heap .ImageHeapConstant ;
70- import com .oracle .svm .util .OriginalClassProvider ;
7167import com .oracle .graal .pointsto .meta .AnalysisField ;
68+ import com .oracle .graal .pointsto .meta .AnalysisMetaAccess ;
7269import com .oracle .graal .pointsto .meta .AnalysisMethod ;
7370import com .oracle .graal .pointsto .meta .AnalysisType ;
7471import com .oracle .svm .core .BuildArtifacts ;
111108import com .oracle .svm .interpreter .metadata .ReferenceConstant ;
112109import com .oracle .svm .interpreter .metadata .serialization .SerializationContext ;
113110import com .oracle .svm .interpreter .metadata .serialization .Serializers ;
114- import com .oracle .svm .util .ReflectionUtil ;
111+ import com .oracle .svm .util .JVMCIReflectionUtil ;
115112
116113import jdk .graal .compiler .api .replacements .SnippetReflectionProvider ;
117114import jdk .graal .compiler .core .common .SuppressFBWarnings ;
130127import jdk .vm .ci .meta .PrimitiveConstant ;
131128import jdk .vm .ci .meta .ResolvedJavaField ;
132129import jdk .vm .ci .meta .ResolvedJavaMethod ;
130+ import jdk .vm .ci .meta .ResolvedJavaType ;
133131import jdk .vm .ci .meta .UnresolvedJavaMethod ;
134132
135133/**
144142@ Platforms (Platform .HOSTED_ONLY .class )
145143@ AutomaticallyRegisteredFeature
146144public class DebuggerFeature implements InternalFeature {
147- private Method enterInterpreterMethod ;
145+ private AnalysisMethod enterInterpreterMethod ;
148146 private InterpreterStubTable enterStubTable = null ;
149- private final List <Class <?> > classesUsedByInterpreter = new ArrayList <>();
147+ private final List <ResolvedJavaType > classesUsedByInterpreter = new ArrayList <>();
150148 private Set <AnalysisMethod > methodsProcessedDuringAnalysis ;
151149 private InvocationPlugins invocationPlugins ;
152150 private static final String SYNTHETIC_ASSERTIONS_DISABLED_FIELD_NAME = "$assertionsDisabled" ;
@@ -165,9 +163,9 @@ public List<Class<? extends Feature>> getRequiredFeatures() {
165163 SymbolsFeature .class );
166164 }
167165
168- private static Class <?> getArgumentClass (GraphBuilderContext b , ResolvedJavaMethod targetMethod , int parameterIndex , ValueNode arg ) {
166+ private static ResolvedJavaType getArgumentType (GraphBuilderContext b , ResolvedJavaMethod targetMethod , int parameterIndex , ValueNode arg ) {
169167 SubstrateGraphBuilderPlugins .checkParameterUsage (arg .isConstant (), b , targetMethod , parameterIndex , "parameter is not a compile time constant" );
170- return OriginalClassProvider . getJavaClass ( b .getConstantReflection ().asJavaType (arg .asJavaConstant () ));
168+ return b .getConstantReflection ().asJavaType (arg .asJavaConstant ());
171169 }
172170
173171 @ Override
@@ -178,9 +176,9 @@ public void registerInvocationPlugins(Providers providers, GraphBuilderConfigura
178176 r .register (new InvocationPlugin .RequiredInvocationPlugin ("markKlass" , Class .class ) {
179177 @ Override
180178 public boolean apply (GraphBuilderContext b , ResolvedJavaMethod targetMethod , Receiver receiver , ValueNode arg1 ) {
181- Class <?> targetKlass = getArgumentClass (b , targetMethod , 1 , arg1 );
182- InterpreterUtil .log ("[invocation plugin] Adding %s" , targetKlass );
183- classesUsedByInterpreter .add (targetKlass );
179+ ResolvedJavaType targetType = getArgumentType (b , targetMethod , 1 , arg1 );
180+ InterpreterUtil .log ("[invocation plugin] Adding %s" , targetType . getUnqualifiedName () );
181+ classesUsedByInterpreter .add (targetType );
184182
185183 /* no-op in compiled code */
186184 return true ;
@@ -198,33 +196,32 @@ public void afterRegistration(AfterRegistrationAccess access) {
198196 @ Override
199197 public void beforeAnalysis (BeforeAnalysisAccess access ) {
200198 FeatureImpl .BeforeAnalysisAccessImpl accessImpl = (FeatureImpl .BeforeAnalysisAccessImpl ) access ;
199+ AnalysisMetaAccess metaAccess = accessImpl .getMetaAccess ();
201200
202- try {
203- enterInterpreterMethod = InterpreterStubSection . class . getMethod ( "enterMethodInterpreterStub" , int .class , Pointer .class );
204- accessImpl .registerAsRoot (enterInterpreterMethod , true , "stub for interpreter" );
201+ AnalysisType aInterpreterStubSection = metaAccess . lookupJavaType ( InterpreterStubSection . class );
202+ enterInterpreterMethod = ( AnalysisMethod ) JVMCIReflectionUtil . getDeclaredMethod ( metaAccess , aInterpreterStubSection , "enterMethodInterpreterStub" , int .class , Pointer .class );
203+ accessImpl .registerAsRoot (enterInterpreterMethod , true , "stub for interpreter" );
205204
206- // Holds references that must be kept alive in the image heap.
207- access .registerAsAccessed (DebuggerSupport .class .getDeclaredField ("referencesInImage" ));
208- access .registerAsAccessed (DebuggerSupport .class .getDeclaredField ("methodPointersInImage" ));
205+ // Holds references that must be kept alive in the image heap.
206+ AnalysisType aDebuggerSupport = metaAccess .lookupJavaType (DebuggerSupport .class );
207+ accessImpl .registerAsAccessed ((AnalysisField ) JVMCIReflectionUtil .getDeclaredField (aDebuggerSupport , "referencesInImage" ),
208+ "Holds references that must be kept alive in the image heap." );
209+ accessImpl .registerAsAccessed ((AnalysisField ) JVMCIReflectionUtil .getDeclaredField (aDebuggerSupport , "methodPointersInImage" ),
210+ "Holds references that must be kept alive in the image heap." );
209211
210- accessImpl .registerAsRoot (System .class .getDeclaredMethod ("arraycopy" , Object .class , int .class , Object .class , int .class , int .class ), true ,
211- "Allow interpreting methods that call System.arraycopy" );
212- } catch (NoSuchMethodException | NoSuchFieldException e ) {
213- throw VMError .shouldNotReachHere (e );
214- }
212+ AnalysisType aSystem = metaAccess .lookupJavaType (System .class );
213+ accessImpl .registerAsRoot ((AnalysisMethod ) JVMCIReflectionUtil .getDeclaredMethod (metaAccess , aSystem , "arraycopy" , Object .class , int .class , Object .class , int .class , int .class ),
214+ true , "Allow interpreting methods that call System.arraycopy" );
215215
216216 registerStringConcatenation (accessImpl );
217217
218218 // GR-53734: Known issues around reachability
219- try {
220- // JDK code introduced a new optional intrinsic:
221- // https://github.com/openjdk/jdk22u/commit/a4e9168bab1c2872ce2dbc7971a45c259270271f
222- // consider DualPivotQuicksort.java:268, int.class is not needed if the sort helper
223- // is inlined, therefore it's not needed. Still needed for interpreter execution.
224- access .registerAsAccessed (Integer .class .getField ("TYPE" ));
225- } catch (NoSuchFieldException e ) {
226- throw VMError .shouldNotReachHere (e );
227- }
219+ // JDK code introduced a new optional intrinsic:
220+ // https://github.com/openjdk/jdk22u/commit/a4e9168bab1c2872ce2dbc7971a45c259270271f
221+ // consider DualPivotQuicksort.java:268, int.class is not needed if the sort helper
222+ // is inlined, therefore it's not needed. Still needed for interpreter execution.
223+ AnalysisType aInteger = metaAccess .lookupJavaType (Integer .class );
224+ accessImpl .registerAsAccessed ((AnalysisField ) JVMCIReflectionUtil .getDeclaredField (aInteger , "TYPE" ), "Read by the interpreter" );
228225
229226 methodsProcessedDuringAnalysis = new HashSet <>();
230227
@@ -247,20 +244,18 @@ private static void registerStringConcatenation(FeatureImpl.BeforeAnalysisAccess
247244 * These registrations enable the interpreter to "interpret" StringBuilder-based String
248245 * concatenation optimized away by the compiler.
249246 */
250- try {
251- List <Method > appendMethods = Arrays .stream (StringBuilder .class .getDeclaredMethods ())
252- .filter (m -> "append" .equals (m .getName ()))
253- .collect (Collectors .toList ());
254- for (Method m : appendMethods ) {
255- accessImpl .registerAsRoot (m , false , "string concat in interpreter" );
256- }
257- for (Constructor <?> c : StringBuilder .class .getDeclaredConstructors ()) {
258- accessImpl .registerAsRoot (c , true , "string concat in interpreter" );
259- }
260- accessImpl .registerAsRoot (StringBuilder .class .getConstructor (), true , "string concat in interpreter" );
261- } catch (NoSuchMethodException e ) {
262- throw new RuntimeException (e );
247+ AnalysisMetaAccess metaAccess = accessImpl .getMetaAccess ();
248+ AnalysisType aStringBuilder = metaAccess .lookupJavaType (StringBuilder .class );
249+ List <AnalysisMethod > appendMethods = Arrays .stream (aStringBuilder .getDeclaredMethods (false ))
250+ .filter (m -> "append" .equals (m .getName ())).toList ();
251+ for (AnalysisMethod m : appendMethods ) {
252+ accessImpl .registerAsRoot (m , false , "string concat in interpreter" );
253+ }
254+ for (AnalysisMethod c : aStringBuilder .getDeclaredConstructors (false )) {
255+ accessImpl .registerAsRoot (c , true , "string concat in interpreter" );
263256 }
257+ AnalysisMethod aMethod = (AnalysisMethod ) JVMCIReflectionUtil .getDeclaredConstructor (metaAccess , aStringBuilder );
258+ accessImpl .registerAsRoot (aMethod , true , "string concat in interpreter" );
264259 }
265260
266261 static boolean isReachable (AnalysisMethod m ) {
@@ -299,13 +294,13 @@ public void duringAnalysis(DuringAnalysisAccess access) {
299294
300295 if (!classesUsedByInterpreter .isEmpty ()) {
301296 access .requireAnalysisIteration ();
302- for (Class <?> k : classesUsedByInterpreter ) {
303- accessImpl .registerAsUsed (k );
304- Arrays . stream ( k . getDeclaredMethods ()). filter ( m -> m . getName (). startsWith ( "test" )). forEach ( m -> {
305- AnalysisMethod aMethod = accessImpl . getMetaAccess ().lookupJavaMethod ( m );
297+ for (ResolvedJavaType k : classesUsedByInterpreter ) {
298+ AnalysisType aType = k instanceof AnalysisType analysisType ? analysisType : accessImpl .getUniverse (). lookup (k );
299+ accessImpl . registerAsUsed ( aType , "used by interpreter" );
300+ Arrays . stream ( aType . getDeclaredMethods ( false )). filter ( m -> m . getName ().startsWith ( "test" )). forEach ( aMethod -> {
306301 VMError .guarantee (!aMethod .isConstructor ());
307302 accessImpl .registerAsRoot (aMethod , aMethod .isConstructor (), "reached due to interpreter directive" );
308- InterpreterUtil .log ("[during analysis] Adding method %s" , m );
303+ InterpreterUtil .log ("[during analysis] Adding method %s" , aMethod );
309304 });
310305 }
311306 classesUsedByInterpreter .clear ();
@@ -440,7 +435,7 @@ public void beforeCompilation(BeforeCompilationAccess access) {
440435 FeatureImpl .BeforeCompilationAccessImpl accessImpl = (FeatureImpl .BeforeCompilationAccessImpl ) access ;
441436 HostedUniverse hUniverse = accessImpl .getUniverse ();
442437 HostedMetaAccess hMetaAccess = accessImpl .getMetaAccess ();
443- MetaAccessProvider aMetaAccess = hMetaAccess .getWrapped ();
438+ AnalysisMetaAccess aMetaAccess = ( AnalysisMetaAccess ) hMetaAccess .getWrapped ();
444439 BuildTimeInterpreterUniverse iUniverse = BuildTimeInterpreterUniverse .singleton ();
445440
446441 for (HostedType hType : hUniverse .getTypes ()) {
@@ -501,20 +496,18 @@ public void beforeCompilation(BeforeCompilationAccess access) {
501496
502497 iUniverse .purgeUnreachable (hMetaAccess );
503498
504- Field vtableHolderField = ReflectionUtil . lookupField ( InterpreterResolvedObjectType .class , "vtableHolder" );
499+ AnalysisField vtableHolderField = ( AnalysisField ) JVMCIReflectionUtil . getDeclaredField ( aMetaAccess . lookupJavaType ( InterpreterResolvedObjectType .class ) , "vtableHolder" );
505500 ScanReason reason = new OtherReason ("Manual rescan triggered before compilation from " + DebuggerFeature .class );
506501 for (HostedType hostedType : hUniverse .getTypes ()) {
507502 iUniverse .mirrorSVMVTable (hostedType , objectType -> accessImpl .getHeapScanner ().rescanField (objectType , vtableHolderField , reason ));
508503 }
509504
510505 // Allow methods that call System.arraycopy to be interpreted.
511- try {
512- HostedMethod arraycopy = hMetaAccess .lookupJavaMethod (
513- System .class .getDeclaredMethod ("arraycopy" , Object .class , int .class , Object .class , int .class , int .class ));
514- SubstrateCompilationDirectives .singleton ().registerForcedCompilation (arraycopy );
515- } catch (NoSuchMethodException e ) {
516- throw new RuntimeException (e );
517- }
506+
507+ HostedType systemClass = hMetaAccess .lookupJavaType (System .class );
508+ AnalysisMethod arraycopy = (AnalysisMethod ) JVMCIReflectionUtil .getDeclaredMethod (aMetaAccess ,
509+ systemClass .getWrapped (), "arraycopy" , Object .class , int .class , Object .class , int .class , int .class );
510+ SubstrateCompilationDirectives .singleton ().registerForcedCompilation (arraycopy );
518511 }
519512
520513 @ Override
@@ -768,7 +761,7 @@ public void beforeImageWrite(BeforeImageWriteAccess access) {
768761
769762 InterpreterStubSection stubSection = ImageSingletons .lookup (InterpreterStubSection .class );
770763
771- stubSection .markEnterStubPatch (accessImpl .getHostedMetaAccess ().lookupJavaMethod (enterInterpreterMethod ));
764+ stubSection .markEnterStubPatch (accessImpl .getHostedUniverse ().lookup (enterInterpreterMethod ));
772765 enterStubTable .writeMetadataHashString (hashString .getBytes (StandardCharsets .UTF_8 ));
773766 }
774767
0 commit comments