Skip to content

Commit 8faf4bb

Browse files
committed
Ensure elements that should not be reflectively accessible are not constant folded in the ReflectionPlugins
1 parent 08e4f8d commit 8faf4bb

File tree

6 files changed

+86
-72
lines changed

6 files changed

+86
-72
lines changed

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/RuntimeMetadataEncoderImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -405,11 +405,11 @@ private static Class<?>[] filterDeletedClasses(MetaAccessProvider metaAccess, Cl
405405
if (classes == null) {
406406
return null;
407407
}
408-
AnalysisMetaAccess aMetaAccess = (AnalysisMetaAccess) ((HostedMetaAccess) metaAccess).getWrapped();
408+
SubstitutionReflectivityFilter reflectivityFilter = SubstitutionReflectivityFilter.singleton();
409409
Set<Class<?>> reachableClasses = new HashSet<>();
410410
for (Class<?> clazz : classes) {
411411
try {
412-
if (!SubstitutionReflectivityFilter.shouldExclude(clazz, aMetaAccess, aMetaAccess.getUniverse())) {
412+
if (!reflectivityFilter.shouldExclude(clazz)) {
413413
metaAccess.lookupJavaType(clazz);
414414
reachableClasses.add(clazz);
415415
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIAccessFeature.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ static final class JNICallableJavaMethod {
175175

176176
private int loadedConfigurations;
177177

178+
private SubstitutionReflectivityFilter reflectivityFilter;
179+
178180
private final Set<Class<?>> newClasses = Collections.newSetFromMap(new ConcurrentHashMap<>());
179181
private final Set<String> newNegativeClassLookups = Collections.newSetFromMap(new ConcurrentHashMap<>());
180182
private final Set<Executable> newMethods = Collections.newSetFromMap(new ConcurrentHashMap<>());
@@ -214,6 +216,8 @@ public void afterRegistration(AfterRegistrationAccess arg) {
214216
access.getImageClassLoader());
215217
loadedConfigurations += ConfigurationParserUtils.parseAndRegisterConfigurations(legacyParser, access.getImageClassLoader(), "JNI",
216218
ConfigurationFiles.Options.JNIConfigurationFiles, ConfigurationFiles.Options.JNIConfigurationResources, ConfigurationFile.JNI.getFileName());
219+
220+
reflectivityFilter = SubstitutionReflectivityFilter.singleton();
217221
}
218222

219223
private final class JNIRuntimeAccessibilitySupportImpl extends ConditionalConfigurationRegistry
@@ -410,11 +414,11 @@ public void duringAnalysis(DuringAnalysisAccess a) {
410414
access.requireAnalysisIteration();
411415
}
412416

413-
private static JNIAccessibleClass addClass(Class<?> classObj, DuringAnalysisAccessImpl access) {
417+
private JNIAccessibleClass addClass(Class<?> classObj, DuringAnalysisAccessImpl access) {
414418
if (classObj.isPrimitive()) {
415419
return null; // primitives cannot be looked up by name and have no methods or fields
416420
}
417-
if (SubstitutionReflectivityFilter.shouldExclude(classObj, access.getMetaAccess(), access.getUniverse())) {
421+
if (reflectivityFilter.shouldExclude(classObj)) {
418422
return null;
419423
}
420424
return JNIReflectionDictionary.currentLayer().addClassIfAbsent(classObj, c -> {
@@ -429,7 +433,7 @@ private static void addNegativeClassLookup(String className) {
429433
}
430434

431435
public void addMethod(Executable method, DuringAnalysisAccessImpl access) {
432-
if (SubstitutionReflectivityFilter.shouldExclude(method, access.getMetaAccess(), access.getUniverse())) {
436+
if (reflectivityFilter.shouldExclude(method)) {
433437
return;
434438
}
435439
JNIAccessibleClass jniClass = addClass(method.getDeclaringClass(), access);
@@ -473,7 +477,7 @@ public void addMethod(Executable method, DuringAnalysisAccessImpl access) {
473477
});
474478
}
475479

476-
private static void addNegativeMethodLookup(Class<?> declaringClass, String methodName, Class<?>[] parameterTypes, DuringAnalysisAccessImpl access) {
480+
private void addNegativeMethodLookup(Class<?> declaringClass, String methodName, Class<?>[] parameterTypes, DuringAnalysisAccessImpl access) {
477481
JNIAccessibleClass jniClass = addClass(declaringClass, access);
478482
JNIAccessibleMethodDescriptor descriptor = JNIAccessibleMethodDescriptor.of(methodName, parameterTypes);
479483
jniClass.addMethodIfAbsent(descriptor, d -> JNIAccessibleMethod.negativeMethodQuery(jniClass));
@@ -499,8 +503,8 @@ private JNIJavaCallVariantWrapperGroup createJavaCallVariantWrappers(DuringAnaly
499503
});
500504
}
501505

502-
private static void addField(Field reflField, boolean writable, DuringAnalysisAccessImpl access) {
503-
if (SubstitutionReflectivityFilter.shouldExclude(reflField, access.getMetaAccess(), access.getUniverse())) {
506+
private void addField(Field reflField, boolean writable, DuringAnalysisAccessImpl access) {
507+
if (reflectivityFilter.shouldExclude(reflField)) {
504508
return;
505509
}
506510
JNIAccessibleClass jniClass = addClass(reflField.getDeclaringClass(), access);
@@ -525,7 +529,7 @@ private static void addField(Field reflField, boolean writable, DuringAnalysisAc
525529
bb.registerAsJNIAccessed(field, writable);
526530
}
527531

528-
private static void addNegativeFieldLookup(Class<?> declaringClass, String fieldName, DuringAnalysisAccessImpl access) {
532+
private void addNegativeFieldLookup(Class<?> declaringClass, String fieldName, DuringAnalysisAccessImpl access) {
529533
JNIAccessibleClass jniClass = addClass(declaringClass, access);
530534
jniClass.addFieldIfAbsent(fieldName, d -> JNIAccessibleField.negativeFieldQuery(jniClass));
531535
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionDataBuilder.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ public class ReflectionDataBuilder extends ConditionalConfigurationRegistry impl
123123
private BeforeAnalysisAccessImpl analysisAccess;
124124
private final ClassForNameSupport classForNameSupport;
125125
private LayeredReflectionDataBuilder layeredReflectionDataBuilder;
126+
private SubstitutionReflectivityFilter reflectivityFilter;
126127

127128
// Reflection data
128129
private final Map<Class<?>, RecordComponent[]> registeredRecordComponents = new ConcurrentHashMap<>();
@@ -177,6 +178,7 @@ public void duringSetup(AnalysisMetaAccess analysisMetaAccess, AnalysisUniverse
177178
if (ImageLayerBuildingSupport.buildingImageLayer()) {
178179
layeredReflectionDataBuilder = LayeredReflectionDataBuilder.singleton();
179180
}
181+
reflectivityFilter = SubstitutionReflectivityFilter.singleton();
180182
}
181183

182184
public void beforeAnalysis(BeforeAnalysisAccessImpl beforeAnalysisAccess) {
@@ -438,7 +440,7 @@ private void registerMethods(ConfigurationCondition cnd, boolean queriedOnly, Ex
438440
}
439441

440442
private void registerMethod(ConfigurationCondition cnd, boolean queriedOnly, Executable reflectExecutable) {
441-
if (SubstitutionReflectivityFilter.shouldExclude(reflectExecutable, metaAccess, universe)) {
443+
if (reflectivityFilter.shouldExclude(reflectExecutable)) {
442444
return;
443445
}
444446

@@ -605,7 +607,7 @@ private void registerFields(ConfigurationCondition cnd, boolean queriedOnly, Fie
605607
}
606608

607609
private void registerField(ConfigurationCondition cnd, boolean queriedOnly, Field reflectField) {
608-
if (SubstitutionReflectivityFilter.shouldExclude(reflectField, metaAccess, universe)) {
610+
if (reflectivityFilter.shouldExclude(reflectField)) {
609611
return;
610612
}
611613

@@ -1056,7 +1058,7 @@ private boolean includeAnnotation(AnnotationValue annotationValue) {
10561058
return false;
10571059
}
10581060
for (Class<?> type : annotationValue.getTypes()) {
1059-
if (type == null || SubstitutionReflectivityFilter.shouldExclude(type, metaAccess, universe)) {
1061+
if (type == null || reflectivityFilter.shouldExclude(type)) {
10601062
return false;
10611063
}
10621064
}
@@ -1097,7 +1099,7 @@ private boolean shouldExcludeClass(Class<?> clazz) {
10971099
if (clazz.isPrimitive()) {
10981100
return true; // primitives cannot be looked up by name and have no methods or fields
10991101
}
1100-
return SubstitutionReflectivityFilter.shouldExclude(clazz, metaAccess, universe);
1102+
return reflectivityFilter.shouldExclude(clazz);
11011103
}
11021104

11031105
private static <T> T queryGenericInfo(Callable<T> callable) {
@@ -1131,7 +1133,7 @@ private void maybeRegisterRecordComponents(Class<?> clazz) {
11311133
Method[] accessors = RecordUtils.getRecordComponentAccessorMethods(clazz);
11321134
Set<Method> unregisteredAccessors = ConcurrentHashMap.newKeySet();
11331135
for (Method accessor : accessors) {
1134-
if (SubstitutionReflectivityFilter.shouldExclude(accessor, metaAccess, universe)) {
1136+
if (reflectivityFilter.shouldExclude(accessor)) {
11351137
return;
11361138
}
11371139
unregisteredAccessors.add(accessor);
@@ -1241,7 +1243,7 @@ public void registerHeapDynamicHub(Object object, ScanReason reason) {
12411243
if (isSealed()) {
12421244
throw new UnsupportedFeatureException("Registering new class for reflection when the image heap is already sealed: " + javaClass);
12431245
}
1244-
if (!SubstitutionReflectivityFilter.shouldExclude(javaClass, metaAccess, universe)) {
1246+
if (!reflectivityFilter.shouldExclude(javaClass)) {
12451247
registerTypesForClass(metaAccess.lookupJavaType(javaClass), javaClass);
12461248
}
12471249
}
@@ -1260,7 +1262,7 @@ public void registerHeapReflectionField(Field reflectField, ScanReason reason) {
12601262
if (isSealed()) {
12611263
throw new UnsupportedFeatureException("Registering new field for reflection when the image heap is already sealed: " + reflectField);
12621264
}
1263-
if (!SubstitutionReflectivityFilter.shouldExclude(reflectField, metaAccess, universe)) {
1265+
if (!reflectivityFilter.shouldExclude(reflectField)) {
12641266
registerTypesForField(analysisField, reflectField, false);
12651267
if (analysisField.getDeclaringClass().isAnnotation()) {
12661268
processAnnotationField(ConfigurationCondition.alwaysTrue(), reflectField);
@@ -1285,7 +1287,7 @@ public void registerHeapReflectionExecutable(Executable reflectExecutable, ScanR
12851287
if (isSealed()) {
12861288
throw new UnsupportedFeatureException("Registering new method for reflection when the image heap is already sealed: " + reflectExecutable);
12871289
}
1288-
if (!SubstitutionReflectivityFilter.shouldExclude(reflectExecutable, metaAccess, universe)) {
1290+
if (!reflectivityFilter.shouldExclude(reflectExecutable)) {
12891291
registerTypesForMethod(analysisMethod, reflectExecutable);
12901292
if (reflectExecutable instanceof Method && reflectExecutable.getDeclaringClass().isAnnotation()) {
12911293
processAnnotationMethod(false, (Method) reflectExecutable);

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/ReflectionPlugins.java

Lines changed: 12 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import java.lang.invoke.VarHandle;
3131
import java.lang.reflect.AnnotatedElement;
3232
import java.lang.reflect.Constructor;
33-
import java.lang.reflect.Executable;
3433
import java.lang.reflect.Field;
3534
import java.lang.reflect.InvocationTargetException;
3635
import java.lang.reflect.Method;
@@ -47,9 +46,6 @@
4746
import java.util.stream.Collectors;
4847
import java.util.stream.Stream;
4948

50-
import com.oracle.svm.core.TrackDynamicAccessEnabled;
51-
import com.oracle.svm.hosted.DynamicAccessDetectionFeature;
52-
import com.oracle.svm.hosted.NativeImageSystemClassLoader;
5349
import org.graalvm.nativeimage.ImageSingletons;
5450
import org.graalvm.nativeimage.hosted.RuntimeReflection;
5551
import org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport;
@@ -58,22 +54,24 @@
5854
import com.oracle.graal.pointsto.meta.AnalysisUniverse;
5955
import com.oracle.svm.core.MissingRegistrationUtils;
6056
import com.oracle.svm.core.ParsingReason;
61-
import com.oracle.svm.core.annotate.Delete;
57+
import com.oracle.svm.core.TrackDynamicAccessEnabled;
6258
import com.oracle.svm.core.hub.ClassForNameSupport;
6359
import com.oracle.svm.core.hub.PredefinedClassesSupport;
6460
import com.oracle.svm.core.hub.RuntimeClassLoading;
6561
import com.oracle.svm.core.jdk.StackTraceUtils;
6662
import com.oracle.svm.core.option.HostedOptionKey;
6763
import com.oracle.svm.core.util.VMError;
64+
import com.oracle.svm.hosted.DynamicAccessDetectionFeature;
6865
import com.oracle.svm.hosted.ExceptionSynthesizer;
6966
import com.oracle.svm.hosted.FallbackFeature;
7067
import com.oracle.svm.hosted.ImageClassLoader;
68+
import com.oracle.svm.hosted.NativeImageSystemClassLoader;
7169
import com.oracle.svm.hosted.ReachabilityRegistrationNode;
7270
import com.oracle.svm.hosted.classinitialization.ClassInitializationSupport;
7371
import com.oracle.svm.hosted.dynamicaccessinference.DynamicAccessInferenceLog;
7472
import com.oracle.svm.hosted.dynamicaccessinference.StrictDynamicAccessInferenceFeature;
7573
import com.oracle.svm.hosted.substitute.AnnotationSubstitutionProcessor;
76-
import com.oracle.svm.hosted.substitute.DeletedElementException;
74+
import com.oracle.svm.hosted.substitute.SubstitutionReflectivityFilter;
7775
import com.oracle.svm.util.ModuleSupport;
7876
import com.oracle.svm.util.ReflectionUtil;
7977
import com.oracle.svm.util.TypeResult;
@@ -91,7 +89,6 @@
9189
import jdk.graal.compiler.options.Option;
9290
import jdk.vm.ci.meta.JavaConstant;
9391
import jdk.vm.ci.meta.JavaKind;
94-
import jdk.vm.ci.meta.MetaAccessProvider;
9592
import jdk.vm.ci.meta.ResolvedJavaField;
9693
import jdk.vm.ci.meta.ResolvedJavaMethod;
9794
import jdk.vm.ci.meta.ResolvedJavaType;
@@ -129,6 +126,7 @@ static class Options {
129126
private final boolean trackDynamicAccess;
130127
private final DynamicAccessDetectionFeature dynamicAccessDetectionFeature;
131128
private final DynamicAccessInferenceLog inferenceLog;
129+
private final SubstitutionReflectivityFilter reflectivityFilter;
132130

133131
private ReflectionPlugins(ImageClassLoader imageClassLoader, AnnotationSubstitutionProcessor annotationSubstitutions,
134132
ClassInitializationPlugin classInitializationPlugin, AnalysisUniverse aUniverse, ParsingReason reason, FallbackFeature fallbackFeature) {
@@ -145,6 +143,8 @@ private ReflectionPlugins(ImageClassLoader imageClassLoader, AnnotationSubstitut
145143
this.classInitializationSupport = (ClassInitializationSupport) ImageSingletons.lookup(RuntimeClassInitializationSupport.class);
146144

147145
this.inferenceLog = DynamicAccessInferenceLog.singletonOrNull();
146+
147+
this.reflectivityFilter = SubstitutionReflectivityFilter.singleton();
148148
}
149149

150150
public static void registerInvocationPlugins(ImageClassLoader imageClassLoader, AnnotationSubstitutionProcessor annotationSubstitutions,
@@ -737,12 +737,12 @@ private static boolean isAllowedConstant(Class<?> clazz) {
737737
* compilation, not a lossy copy of it.
738738
*/
739739
@SuppressWarnings("unchecked")
740-
private <T> T getIntrinsic(GraphBuilderContext context, T element) {
740+
private <T> T getIntrinsic(T element) {
741741
if (reason == ParsingReason.AutomaticUnsafeTransformation || reason == ParsingReason.EarlyClassInitializerAnalysis) {
742742
/* We are analyzing the static initializers and should always intrinsify. */
743743
return element;
744744
}
745-
if (isDeleted(element, context.getMetaAccess())) {
745+
if (element instanceof AnnotatedElement annotatedElement && reflectivityFilter.shouldExcludeElement(annotatedElement)) {
746746
/*
747747
* Should not intrinsify. Will fail during the reflective lookup at runtime. @Delete-ed
748748
* elements are ignored by the reflection plugins regardless of the value of
@@ -761,7 +761,7 @@ private JavaConstant getIntrinsicConstant(GraphBuilderContext context, Object el
761761
/* We are analyzing the static initializers and should always intrinsify. */
762762
return context.getSnippetReflection().forObject(element);
763763
}
764-
if (isDeleted(element, context.getMetaAccess())) {
764+
if (element instanceof AnnotatedElement annotatedElement && reflectivityFilter.shouldExcludeElement(annotatedElement)) {
765765
/*
766766
* Should not intrinsify. Will fail during the reflective lookup at runtime. @Delete-ed
767767
* elements are ignored by the reflection plugins regardless of the value of
@@ -772,31 +772,9 @@ private JavaConstant getIntrinsicConstant(GraphBuilderContext context, Object el
772772
return aUniverse.replaceObjectWithConstant(element, context.getSnippetReflection()::forObject);
773773
}
774774

775-
private static <T> boolean isDeleted(T element, MetaAccessProvider metaAccess) {
776-
AnnotatedElement annotated = null;
777-
try {
778-
if (element instanceof Executable) {
779-
annotated = metaAccess.lookupJavaMethod((Executable) element);
780-
} else if (element instanceof Field) {
781-
annotated = metaAccess.lookupJavaField((Field) element);
782-
}
783-
} catch (DeletedElementException ex) {
784-
/*
785-
* If ReportUnsupportedElementsAtRuntime is *not* set looking up a @Delete-ed element
786-
* will result in a DeletedElementException.
787-
*/
788-
return true;
789-
}
790-
/*
791-
* If ReportUnsupportedElementsAtRuntime is set looking up a @Delete-ed element will return
792-
* a substitution method that has the @Delete annotation.
793-
*/
794-
return annotated != null && annotated.isAnnotationPresent(Delete.class);
795-
}
796-
797775
private JavaConstant pushConstant(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Object receiver, Object[] arguments, JavaKind returnKind, Object returnValue,
798776
boolean allowNullReturnValue, boolean subjectToStrictDynamicAccessInference) {
799-
Object intrinsicValue = getIntrinsic(b, returnValue == null && allowNullReturnValue ? NULL_MARKER : returnValue);
777+
Object intrinsicValue = getIntrinsic(returnValue == null && allowNullReturnValue ? NULL_MARKER : returnValue);
800778
if (intrinsicValue == null) {
801779
return null;
802780
}
@@ -822,7 +800,7 @@ private boolean throwException(GraphBuilderContext b, ResolvedJavaMethod targetM
822800
if (exceptionMethod == null) {
823801
return false;
824802
}
825-
Method intrinsic = getIntrinsic(b, exceptionMethod);
803+
Method intrinsic = getIntrinsic(exceptionMethod);
826804
if (intrinsic == null) {
827805
return false;
828806
}

0 commit comments

Comments
 (0)