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,30 @@ 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
+ if (type == null ) {
740
+ return ;
741
+ }
742
+ // TODO (GR-64765): We over-approximate member accessibility here because we don't trace
743
+ // accesses. Once we trace accesses, it will suffice to register the class for reflection.
744
+ switch (mask ) {
745
+ case ALL_FIELDS_FLAG -> type .setAllPublicFields (ConfigurationMemberAccessibility .ACCESSED );
746
+ case ALL_DECLARED_FIELDS_FLAG -> type .setAllDeclaredFields (ConfigurationMemberAccessibility .ACCESSED );
747
+ case ALL_METHODS_FLAG -> type .setAllPublicMethods (ConfigurationMemberAccessibility .ACCESSED );
748
+ case ALL_DECLARED_METHODS_FLAG -> type .setAllDeclaredMethods (ConfigurationMemberAccessibility .ACCESSED );
749
+ case ALL_CONSTRUCTORS_FLAG -> type .setAllPublicConstructors (ConfigurationMemberAccessibility .ACCESSED );
750
+ case ALL_DECLARED_CONSTRUCTORS_FLAG -> type .setAllDeclaredConstructors (ConfigurationMemberAccessibility .ACCESSED );
751
+ case ALL_CLASSES_FLAG -> type .setAllPublicClasses ();
752
+ case ALL_DECLARED_CLASSES_FLAG -> type .setAllDeclaredClasses ();
753
+ case ALL_RECORD_COMPONENTS_FLAG -> type .setAllRecordComponents ();
754
+ case ALL_PERMITTED_SUBCLASSES_FLAG -> type .setAllPermittedSubclasses ();
755
+ case ALL_NEST_MEMBERS_FLAG -> type .setAllNestMembers ();
756
+ case ALL_SIGNERS_FLAG -> type .setAllSigners ();
757
+ default -> throw VMError .shouldNotReachHere ("unknown class flag " + mask );
758
+ }
759
+ }
760
+
729
761
/** Executed at runtime. */
730
762
private static Object initEnumConstantsAtRuntime (Method values ) {
731
763
try {
@@ -1282,6 +1314,11 @@ public Field getField(String fieldName) throws NoSuchFieldException, SecurityExc
1282
1314
private void checkField (String fieldName , Field field , boolean publicOnly ) throws NoSuchFieldException {
1283
1315
boolean throwMissingErrors = throwMissingRegistrationErrors ();
1284
1316
Class <?> clazz = DynamicHub .toClass (this );
1317
+
1318
+ if (MetadataTracer .Options .MetadataTracingSupport .getValue () && MetadataTracer .singleton ().enabled ()) {
1319
+ traceFieldLookup (fieldName , field , publicOnly );
1320
+ }
1321
+
1285
1322
if (field == null ) {
1286
1323
if (throwMissingErrors && !allElementsRegistered (publicOnly , ALL_DECLARED_FIELDS_FLAG , ALL_FIELDS_FLAG )) {
1287
1324
MissingReflectionRegistrationUtils .forField (clazz , fieldName );
@@ -1305,6 +1342,25 @@ private void checkField(String fieldName, Field field, boolean publicOnly) throw
1305
1342
}
1306
1343
}
1307
1344
1345
+ private void traceFieldLookup (String fieldName , Field field , boolean publicOnly ) {
1346
+ ConfigurationMemberDeclaration declaration = publicOnly ? ConfigurationMemberDeclaration .PRESENT : ConfigurationMemberDeclaration .DECLARED ;
1347
+ if (field != null ) {
1348
+ // register declaring type and field
1349
+ ConfigurationType declaringType = MetadataTracer .singleton ().traceReflectionType (field .getDeclaringClass ().getName ());
1350
+ if (declaringType != null ) {
1351
+ declaringType .addField (fieldName , declaration , false );
1352
+ }
1353
+ // register receiver type
1354
+ MetadataTracer .singleton ().traceReflectionType (getName ());
1355
+ } else {
1356
+ // register receiver type and negative field query
1357
+ ConfigurationType receiverType = MetadataTracer .singleton ().traceReflectionType (getName ());
1358
+ if (receiverType != null ) {
1359
+ receiverType .addField (fieldName , declaration , false );
1360
+ }
1361
+ }
1362
+ }
1363
+
1308
1364
@ Substitute
1309
1365
private Method getMethod (String methodName , Class <?>... parameterTypes ) throws NoSuchMethodException {
1310
1366
Objects .requireNonNull (methodName );
@@ -1340,6 +1396,11 @@ private void checkConstructor(Class<?>[] parameterTypes, Constructor<?> construc
1340
1396
private boolean checkExecutableExists (String methodName , Class <?>[] parameterTypes , Executable method , boolean publicOnly ) {
1341
1397
boolean throwMissingErrors = throwMissingRegistrationErrors ();
1342
1398
Class <?> clazz = DynamicHub .toClass (this );
1399
+
1400
+ if (MetadataTracer .Options .MetadataTracingSupport .getValue () && MetadataTracer .singleton ().enabled ()) {
1401
+ traceMethodLookup (methodName , parameterTypes , method , publicOnly );
1402
+ }
1403
+
1343
1404
if (method == null ) {
1344
1405
boolean isConstructor = methodName .equals (CONSTRUCTOR_NAME );
1345
1406
int allDeclaredFlag = isConstructor ? ALL_DECLARED_CONSTRUCTORS_FLAG : ALL_DECLARED_METHODS_FLAG ;
@@ -1366,6 +1427,38 @@ private boolean checkExecutableExists(String methodName, Class<?>[] parameterTyp
1366
1427
}
1367
1428
}
1368
1429
1430
+ private void traceMethodLookup (String methodName , Class <?>[] parameterTypes , Executable method , boolean publicOnly ) {
1431
+ ConfigurationMemberDeclaration declaration = publicOnly ? ConfigurationMemberDeclaration .PRESENT : ConfigurationMemberDeclaration .DECLARED ;
1432
+ if (method != null ) {
1433
+ // register declaring type and method
1434
+ ConfigurationType declaringType = MetadataTracer .singleton ().traceReflectionType (method .getDeclaringClass ().getName ());
1435
+ if (declaringType != null ) {
1436
+ declaringType .addMethod (methodName , toInternalSignature (parameterTypes ), declaration );
1437
+ }
1438
+ // register receiver type
1439
+ MetadataTracer .singleton ().traceReflectionType (getName ());
1440
+ } else {
1441
+ // register receiver type and negative method query
1442
+ ConfigurationType receiverType = MetadataTracer .singleton ().traceReflectionType (getName ());
1443
+ if (receiverType != null ) {
1444
+ receiverType .addMethod (methodName , toInternalSignature (parameterTypes ), declaration , ConfigurationMemberAccessibility .QUERIED );
1445
+ }
1446
+ }
1447
+ }
1448
+
1449
+ private static String toInternalSignature (Class <?>[] classes ) {
1450
+ List <String > names ;
1451
+ if (classes == null ) {
1452
+ names = List .of ();
1453
+ } else {
1454
+ names = new ArrayList <>(classes .length );
1455
+ for (Class <?> aClass : classes ) {
1456
+ names .add (aClass .getName ());
1457
+ }
1458
+ }
1459
+ return SignatureUtil .toInternalSignature (names );
1460
+ }
1461
+
1369
1462
private boolean allElementsRegistered (boolean publicOnly , int allDeclaredElementsFlag , int allPublicElementsFlag ) {
1370
1463
return isClassFlagSet (allDeclaredElementsFlag ) || (publicOnly && isClassFlagSet (allPublicElementsFlag ));
1371
1464
}
@@ -1882,6 +1975,8 @@ public DynamicHub arrayType() {
1882
1975
}
1883
1976
if (companion .arrayHub == null ) {
1884
1977
MissingReflectionRegistrationUtils .forClass (getTypeName () + "[]" );
1978
+ } else if (MetadataTracer .Options .MetadataTracingSupport .getValue () && MetadataTracer .singleton ().enabled ()) {
1979
+ MetadataTracer .singleton ().traceReflectionType (companion .arrayHub .getTypeName ());
1885
1980
}
1886
1981
return companion .arrayHub ;
1887
1982
}
0 commit comments