24
24
*/
25
25
package com .oracle .svm .core .hub ;
26
26
27
+ import static com .oracle .svm .configure .config .ConfigurationMemberInfo .ConfigurationMemberAccessibility ;
28
+ import static com .oracle .svm .configure .config .ConfigurationMemberInfo .ConfigurationMemberDeclaration ;
27
29
import static com .oracle .svm .core .MissingRegistrationUtils .throwMissingRegistrationErrors ;
28
30
import static com .oracle .svm .core .Uninterruptible .CALLED_FROM_UNINTERRUPTIBLE_CODE ;
29
31
import static com .oracle .svm .core .annotate .TargetElement .CONSTRUCTOR_NAME ;
84
86
import java .util .function .BiFunction ;
85
87
import java .util .function .IntFunction ;
86
88
87
- import com .oracle .svm .core .TrackDynamicAccessEnabled ;
88
89
import org .graalvm .nativeimage .AnnotationAccess ;
89
90
import org .graalvm .nativeimage .ImageSingletons ;
90
91
import org .graalvm .nativeimage .Platform ;
91
92
import org .graalvm .nativeimage .Platforms ;
92
93
import org .graalvm .word .WordBase ;
93
94
95
+ import com .oracle .svm .configure .config .ConfigurationType ;
96
+ import com .oracle .svm .configure .config .SignatureUtil ;
94
97
import com .oracle .svm .core .BuildPhaseProvider .AfterHostedUniverse ;
95
98
import com .oracle .svm .core .BuildPhaseProvider .CompileQueueFinished ;
96
99
import com .oracle .svm .core .NeverInline ;
97
100
import com .oracle .svm .core .NeverInlineTrivial ;
98
101
import com .oracle .svm .core .RuntimeAssertionsSupport ;
99
102
import com .oracle .svm .core .SubstrateUtil ;
103
+ import com .oracle .svm .core .TrackDynamicAccessEnabled ;
100
104
import com .oracle .svm .core .Uninterruptible ;
101
105
import com .oracle .svm .core .annotate .Alias ;
102
106
import com .oracle .svm .core .annotate .Delete ;
121
125
import com .oracle .svm .core .jdk .ProtectionDomainSupport ;
122
126
import com .oracle .svm .core .jdk .Resources ;
123
127
import com .oracle .svm .core .meta .SharedType ;
128
+ import com .oracle .svm .core .metadata .MetadataTracer ;
124
129
import com .oracle .svm .core .reflect .MissingReflectionRegistrationUtils ;
125
130
import com .oracle .svm .core .reflect .RuntimeMetadataDecoder ;
126
131
import com .oracle .svm .core .reflect .RuntimeMetadataDecoder .ConstructorDescriptor ;
@@ -704,6 +709,9 @@ private ReflectionMetadata reflectionMetadata() {
704
709
}
705
710
706
711
private void checkClassFlag (int mask , String methodName ) {
712
+ if (MetadataTracer .Options .MetadataTracingSupport .getValue () && MetadataTracer .singleton ().enabled ()) {
713
+ traceClassFlagQuery (mask );
714
+ }
707
715
if (throwMissingRegistrationErrors () && !(isClassFlagSet (mask ) && getConditions ().satisfied ())) {
708
716
MissingReflectionRegistrationUtils .forBulkQuery (DynamicHub .toClass (this ), methodName );
709
717
}
@@ -726,6 +734,27 @@ private static boolean isClassFlagSet(int mask, ReflectionMetadata reflectionMet
726
734
return reflectionMetadata != null && (reflectionMetadata .classFlags & mask ) != 0 ;
727
735
}
728
736
737
+ private void traceClassFlagQuery (int mask ) {
738
+ ConfigurationType type = MetadataTracer .singleton ().traceReflectionType (getName ());
739
+ // TODO (GR-64765): We over-approximate member accessibility here because we don't trace
740
+ // accesses. Once we trace accesses, it will suffice to register the class for reflection.
741
+ switch (mask ) {
742
+ case ALL_FIELDS_FLAG -> type .setAllPublicFields (ConfigurationMemberAccessibility .ACCESSED );
743
+ case ALL_DECLARED_FIELDS_FLAG -> type .setAllDeclaredFields (ConfigurationMemberAccessibility .ACCESSED );
744
+ case ALL_METHODS_FLAG -> type .setAllPublicMethods (ConfigurationMemberAccessibility .ACCESSED );
745
+ case ALL_DECLARED_METHODS_FLAG -> type .setAllDeclaredMethods (ConfigurationMemberAccessibility .ACCESSED );
746
+ case ALL_CONSTRUCTORS_FLAG -> type .setAllPublicConstructors (ConfigurationMemberAccessibility .ACCESSED );
747
+ case ALL_DECLARED_CONSTRUCTORS_FLAG -> type .setAllDeclaredConstructors (ConfigurationMemberAccessibility .ACCESSED );
748
+ case ALL_CLASSES_FLAG -> type .setAllPublicClasses ();
749
+ case ALL_DECLARED_CLASSES_FLAG -> type .setAllDeclaredClasses ();
750
+ case ALL_RECORD_COMPONENTS_FLAG -> type .setAllRecordComponents ();
751
+ case ALL_PERMITTED_SUBCLASSES_FLAG -> type .setAllPermittedSubclasses ();
752
+ case ALL_NEST_MEMBERS_FLAG -> type .setAllNestMembers ();
753
+ case ALL_SIGNERS_FLAG -> type .setAllSigners ();
754
+ default -> throw VMError .shouldNotReachHere ("unknown class flag " + mask );
755
+ }
756
+ }
757
+
729
758
/** Executed at runtime. */
730
759
private static Object initEnumConstantsAtRuntime (Method values ) {
731
760
try {
@@ -1282,6 +1311,11 @@ public Field getField(String fieldName) throws NoSuchFieldException, SecurityExc
1282
1311
private void checkField (String fieldName , Field field , boolean publicOnly ) throws NoSuchFieldException {
1283
1312
boolean throwMissingErrors = throwMissingRegistrationErrors ();
1284
1313
Class <?> clazz = DynamicHub .toClass (this );
1314
+
1315
+ if (MetadataTracer .Options .MetadataTracingSupport .getValue () && MetadataTracer .singleton ().enabled ()) {
1316
+ traceFieldLookup (fieldName , field , publicOnly );
1317
+ }
1318
+
1285
1319
if (field == null ) {
1286
1320
if (throwMissingErrors && !allElementsRegistered (publicOnly , ALL_DECLARED_FIELDS_FLAG , ALL_FIELDS_FLAG )) {
1287
1321
MissingReflectionRegistrationUtils .forField (clazz , fieldName );
@@ -1305,6 +1339,21 @@ private void checkField(String fieldName, Field field, boolean publicOnly) throw
1305
1339
}
1306
1340
}
1307
1341
1342
+ private void traceFieldLookup (String fieldName , Field field , boolean publicOnly ) {
1343
+ ConfigurationMemberDeclaration declaration = publicOnly ? ConfigurationMemberDeclaration .PRESENT : ConfigurationMemberDeclaration .DECLARED ;
1344
+ if (field != null ) {
1345
+ // register declaring type and field
1346
+ ConfigurationType declaringType = MetadataTracer .singleton ().traceReflectionType (field .getDeclaringClass ().getName ());
1347
+ declaringType .addField (fieldName , declaration , false );
1348
+ // register receiver type
1349
+ MetadataTracer .singleton ().traceReflectionType (getName ());
1350
+ } else {
1351
+ // register receiver type and negative field query
1352
+ ConfigurationType receiverType = MetadataTracer .singleton ().traceReflectionType (getName ());
1353
+ receiverType .addField (fieldName , declaration , false );
1354
+ }
1355
+ }
1356
+
1308
1357
@ Substitute
1309
1358
private Method getMethod (String methodName , Class <?>... parameterTypes ) throws NoSuchMethodException {
1310
1359
Objects .requireNonNull (methodName );
@@ -1340,6 +1389,11 @@ private void checkConstructor(Class<?>[] parameterTypes, Constructor<?> construc
1340
1389
private boolean checkExecutableExists (String methodName , Class <?>[] parameterTypes , Executable method , boolean publicOnly ) {
1341
1390
boolean throwMissingErrors = throwMissingRegistrationErrors ();
1342
1391
Class <?> clazz = DynamicHub .toClass (this );
1392
+
1393
+ if (MetadataTracer .Options .MetadataTracingSupport .getValue () && MetadataTracer .singleton ().enabled ()) {
1394
+ traceMethodLookup (methodName , parameterTypes , method , publicOnly );
1395
+ }
1396
+
1343
1397
if (method == null ) {
1344
1398
boolean isConstructor = methodName .equals (CONSTRUCTOR_NAME );
1345
1399
int allDeclaredFlag = isConstructor ? ALL_DECLARED_CONSTRUCTORS_FLAG : ALL_DECLARED_METHODS_FLAG ;
@@ -1366,6 +1420,34 @@ private boolean checkExecutableExists(String methodName, Class<?>[] parameterTyp
1366
1420
}
1367
1421
}
1368
1422
1423
+ private void traceMethodLookup (String methodName , Class <?>[] parameterTypes , Executable method , boolean publicOnly ) {
1424
+ ConfigurationMemberDeclaration declaration = publicOnly ? ConfigurationMemberDeclaration .PRESENT : ConfigurationMemberDeclaration .DECLARED ;
1425
+ if (method != null ) {
1426
+ // register declaring type and method
1427
+ ConfigurationType declaringType = MetadataTracer .singleton ().traceReflectionType (method .getDeclaringClass ().getName ());
1428
+ declaringType .addMethod (methodName , toInternalSignature (parameterTypes ), declaration );
1429
+ // register receiver type
1430
+ MetadataTracer .singleton ().traceReflectionType (getName ());
1431
+ } else {
1432
+ // register receiver type and negative method query
1433
+ ConfigurationType receiverType = MetadataTracer .singleton ().traceReflectionType (getName ());
1434
+ receiverType .addMethod (methodName , toInternalSignature (parameterTypes ), declaration , ConfigurationMemberAccessibility .QUERIED );
1435
+ }
1436
+ }
1437
+
1438
+ private static String toInternalSignature (Class <?>[] classes ) {
1439
+ List <String > names ;
1440
+ if (classes == null ) {
1441
+ names = List .of ();
1442
+ } else {
1443
+ names = new ArrayList <>(classes .length );
1444
+ for (Class <?> aClass : classes ) {
1445
+ names .add (aClass .getName ());
1446
+ }
1447
+ }
1448
+ return SignatureUtil .toInternalSignature (names );
1449
+ }
1450
+
1369
1451
private boolean allElementsRegistered (boolean publicOnly , int allDeclaredElementsFlag , int allPublicElementsFlag ) {
1370
1452
return isClassFlagSet (allDeclaredElementsFlag ) || (publicOnly && isClassFlagSet (allPublicElementsFlag ));
1371
1453
}
@@ -1882,6 +1964,8 @@ public DynamicHub arrayType() {
1882
1964
}
1883
1965
if (companion .arrayHub == null ) {
1884
1966
MissingReflectionRegistrationUtils .forClass (getTypeName () + "[]" );
1967
+ } else if (MetadataTracer .Options .MetadataTracingSupport .getValue () && MetadataTracer .singleton ().enabled ()) {
1968
+ MetadataTracer .singleton ().traceReflectionType (companion .arrayHub .getTypeName ());
1885
1969
}
1886
1970
return companion .arrayHub ;
1887
1971
}
0 commit comments