@@ -446,50 +446,58 @@ public void registerConstructorLookup(ConfigurationCondition condition, Class<?>
446446 public void register (ConfigurationCondition condition , boolean finalIsWritable , Field ... fields ) {
447447 requireNonNull (fields , "field" );
448448 checkNotSealed ();
449- registerInternal (condition , fields );
449+ registerInternal (condition , false , fields );
450450 }
451451
452- private void registerInternal (ConfigurationCondition condition , Field ... fields ) {
452+ private void registerInternal (ConfigurationCondition condition , boolean queriedOnly , Field ... fields ) {
453453 register (analysisUniverse -> registerConditionalConfiguration (condition , (cnd ) -> {
454454 for (Field field : fields ) {
455- analysisUniverse .getBigbang ().postTask (debug -> registerField (field ));
455+ analysisUniverse .getBigbang ().postTask (debug -> registerField (queriedOnly , field ));
456456 }
457457 }));
458458 }
459459
460460 @ Override
461461 public void registerAllFieldsQuery (ConfigurationCondition condition , Class <?> clazz ) {
462+ registerAllFieldsQuery (condition , false , clazz );
463+ }
464+
465+ private void registerAllFieldsQuery (ConfigurationCondition condition , boolean queriedOnly , Class <?> clazz ) {
462466 checkNotSealed ();
463467 for (Class <?> current = clazz ; current != null ; current = current .getSuperclass ()) {
464468 final Class <?> currentLambda = current ;
465469 registerConditionalConfiguration (condition , (cnd ) -> setQueryFlag (currentLambda , ALL_FIELDS_FLAG ));
466470 }
467471 try {
468- registerInternal (condition , clazz .getFields ());
472+ registerInternal (condition , queriedOnly , clazz .getFields ());
469473 } catch (LinkageError e ) {
470474 registerLinkageError (clazz , e , fieldLookupExceptions );
471475 }
472476 }
473477
474478 @ Override
475479 public void registerAllDeclaredFieldsQuery (ConfigurationCondition condition , Class <?> clazz ) {
480+ registerAllDeclaredFieldsQuery (condition , false , clazz );
481+ }
482+
483+ private void registerAllDeclaredFieldsQuery (ConfigurationCondition condition , boolean queriedOnly , Class <?> clazz ) {
476484 checkNotSealed ();
477485 registerConditionalConfiguration (condition , (cnd ) -> setQueryFlag (clazz , ALL_DECLARED_FIELDS_FLAG ));
478486 try {
479- registerInternal (condition , clazz .getDeclaredFields ());
487+ registerInternal (condition , queriedOnly , clazz .getDeclaredFields ());
480488 } catch (LinkageError e ) {
481489 registerLinkageError (clazz , e , fieldLookupExceptions );
482490 }
483491 }
484492
485- private void registerField (Field reflectField ) {
493+ private void registerField (boolean queriedOnly , Field reflectField ) {
486494 if (SubstitutionReflectivityFilter .shouldExclude (reflectField , metaAccess , universe )) {
487495 return ;
488496 }
489497
490498 AnalysisField analysisField = metaAccess .lookupJavaField (reflectField );
491499 if (registeredFields .put (analysisField , reflectField ) == null ) {
492- registerTypesForField (analysisField , reflectField );
500+ registerTypesForField (analysisField , reflectField , true );
493501 AnalysisType declaringClass = analysisField .getDeclaringClass ();
494502
495503 /*
@@ -504,13 +512,21 @@ private void registerField(Field reflectField) {
504512 processAnnotationField (reflectField );
505513 }
506514 }
515+
516+ /*
517+ * We need to run this even if the method has already been registered, in case it was only
518+ * registered as queried.
519+ */
520+ if (!queriedOnly ) {
521+ registerTypesForField (analysisField , reflectField , false );
522+ }
507523 }
508524
509525 @ Override
510526 public void registerFieldLookup (ConfigurationCondition condition , Class <?> declaringClass , String fieldName ) {
511527 checkNotSealed ();
512528 try {
513- registerInternal (condition , declaringClass .getDeclaredField (fieldName ));
529+ registerInternal (condition , false , declaringClass .getDeclaredField (fieldName ));
514530 } catch (NoSuchFieldException e ) {
515531 registerConditionalConfiguration (condition ,
516532 (cnd ) -> negativeFieldLookups .computeIfAbsent (metaAccess .lookupJavaType (declaringClass ), (key ) -> ConcurrentHashMap .newKeySet ()).add (fieldName ));
@@ -680,13 +696,15 @@ private Object[] getEnclosingMethodInfo(Class<?> clazz) {
680696 }
681697 }
682698
683- private void registerTypesForField (AnalysisField analysisField , Field reflectField ) {
684- /*
685- * Reflection accessors use Unsafe, so ensure that all reflectively accessible fields are
686- * registered as unsafe-accessible, whether they have been explicitly registered or their
687- * Field object is reachable in the image heap.
688- */
689- analysisField .registerAsUnsafeAccessed ("is registered for reflection." );
699+ private void registerTypesForField (AnalysisField analysisField , Field reflectField , boolean queriedOnly ) {
700+ if (!queriedOnly ) {
701+ /*
702+ * Reflection accessors use Unsafe, so ensure that all reflectively accessible fields
703+ * are registered as unsafe-accessible, whether they have been explicitly registered or
704+ * their Field object is reachable in the image heap.
705+ */
706+ analysisField .registerAsUnsafeAccessed ("is registered for reflection." );
707+ }
690708
691709 /*
692710 * The generic signature is parsed at run time, so we need to make all the types necessary
@@ -1045,7 +1063,7 @@ public void registerHeapReflectionField(Field reflectField, ScanReason reason) {
10451063 assert !sealed ;
10461064 AnalysisField analysisField = metaAccess .lookupJavaField (reflectField );
10471065 if (heapFields .put (analysisField , reflectField ) == null && !SubstitutionReflectivityFilter .shouldExclude (reflectField , metaAccess , universe )) {
1048- registerTypesForField (analysisField , reflectField );
1066+ registerTypesForField (analysisField , reflectField , false );
10491067 if (analysisField .getDeclaringClass ().isAnnotation ()) {
10501068 processAnnotationField (reflectField );
10511069 }
@@ -1155,4 +1173,10 @@ private static void requireNonNull(Object[] values, String kind) {
11551173 private static String nullErrorMessage (String kind ) {
11561174 return "Cannot register null value as " + kind + " for reflection. Please ensure that all values you register are not null." ;
11571175 }
1176+
1177+ public static class TestBackdoor {
1178+ public static void registerField (ReflectionDataBuilder reflectionDataBuilder , boolean queriedOnly , Field field ) {
1179+ reflectionDataBuilder .registerInternal (ConfigurationCondition .alwaysTrue (), queriedOnly , field );
1180+ }
1181+ }
11581182}
0 commit comments