Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -405,11 +405,11 @@ private static Class<?>[] filterDeletedClasses(MetaAccessProvider metaAccess, Cl
if (classes == null) {
return null;
}
AnalysisMetaAccess aMetaAccess = (AnalysisMetaAccess) ((HostedMetaAccess) metaAccess).getWrapped();
SubstitutionReflectivityFilter reflectivityFilter = SubstitutionReflectivityFilter.singleton();
Set<Class<?>> reachableClasses = new HashSet<>();
for (Class<?> clazz : classes) {
try {
if (!SubstitutionReflectivityFilter.shouldExclude(clazz, aMetaAccess, aMetaAccess.getUniverse())) {
if (!reflectivityFilter.shouldExclude(clazz)) {
metaAccess.lookupJavaType(clazz);
reachableClasses.add(clazz);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ static final class JNICallableJavaMethod {

private int loadedConfigurations;

private SubstitutionReflectivityFilter reflectivityFilter;

private final Set<Class<?>> newClasses = Collections.newSetFromMap(new ConcurrentHashMap<>());
private final Set<String> newNegativeClassLookups = Collections.newSetFromMap(new ConcurrentHashMap<>());
private final Set<Executable> newMethods = Collections.newSetFromMap(new ConcurrentHashMap<>());
Expand Down Expand Up @@ -214,6 +216,8 @@ public void afterRegistration(AfterRegistrationAccess arg) {
access.getImageClassLoader());
loadedConfigurations += ConfigurationParserUtils.parseAndRegisterConfigurations(legacyParser, access.getImageClassLoader(), "JNI",
ConfigurationFiles.Options.JNIConfigurationFiles, ConfigurationFiles.Options.JNIConfigurationResources, ConfigurationFile.JNI.getFileName());

reflectivityFilter = SubstitutionReflectivityFilter.singleton();
}

private final class JNIRuntimeAccessibilitySupportImpl extends ConditionalConfigurationRegistry
Expand Down Expand Up @@ -410,11 +414,11 @@ public void duringAnalysis(DuringAnalysisAccess a) {
access.requireAnalysisIteration();
}

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

public void addMethod(Executable method, DuringAnalysisAccessImpl access) {
if (SubstitutionReflectivityFilter.shouldExclude(method, access.getMetaAccess(), access.getUniverse())) {
if (reflectivityFilter.shouldExclude(method)) {
return;
}
JNIAccessibleClass jniClass = addClass(method.getDeclaringClass(), access);
Expand Down Expand Up @@ -473,7 +477,7 @@ public void addMethod(Executable method, DuringAnalysisAccessImpl access) {
});
}

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

private static void addField(Field reflField, boolean writable, DuringAnalysisAccessImpl access) {
if (SubstitutionReflectivityFilter.shouldExclude(reflField, access.getMetaAccess(), access.getUniverse())) {
private void addField(Field reflField, boolean writable, DuringAnalysisAccessImpl access) {
if (reflectivityFilter.shouldExclude(reflField)) {
return;
}
JNIAccessibleClass jniClass = addClass(reflField.getDeclaringClass(), access);
Expand All @@ -525,7 +529,7 @@ private static void addField(Field reflField, boolean writable, DuringAnalysisAc
bb.registerAsJNIAccessed(field, writable);
}

private static void addNegativeFieldLookup(Class<?> declaringClass, String fieldName, DuringAnalysisAccessImpl access) {
private void addNegativeFieldLookup(Class<?> declaringClass, String fieldName, DuringAnalysisAccessImpl access) {
JNIAccessibleClass jniClass = addClass(declaringClass, access);
jniClass.addFieldIfAbsent(fieldName, d -> JNIAccessibleField.negativeFieldQuery(jniClass));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ public class ReflectionDataBuilder extends ConditionalConfigurationRegistry impl
private BeforeAnalysisAccessImpl analysisAccess;
private final ClassForNameSupport classForNameSupport;
private LayeredReflectionDataBuilder layeredReflectionDataBuilder;
private SubstitutionReflectivityFilter reflectivityFilter;

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

public void beforeAnalysis(BeforeAnalysisAccessImpl beforeAnalysisAccess) {
Expand Down Expand Up @@ -438,7 +440,7 @@ private void registerMethods(ConfigurationCondition cnd, boolean queriedOnly, Ex
}

private void registerMethod(ConfigurationCondition cnd, boolean queriedOnly, Executable reflectExecutable) {
if (SubstitutionReflectivityFilter.shouldExclude(reflectExecutable, metaAccess, universe)) {
if (reflectivityFilter.shouldExclude(reflectExecutable)) {
return;
}

Expand Down Expand Up @@ -605,7 +607,7 @@ private void registerFields(ConfigurationCondition cnd, boolean queriedOnly, Fie
}

private void registerField(ConfigurationCondition cnd, boolean queriedOnly, Field reflectField) {
if (SubstitutionReflectivityFilter.shouldExclude(reflectField, metaAccess, universe)) {
if (reflectivityFilter.shouldExclude(reflectField)) {
return;
}

Expand Down Expand Up @@ -1056,7 +1058,7 @@ private boolean includeAnnotation(AnnotationValue annotationValue) {
return false;
}
for (Class<?> type : annotationValue.getTypes()) {
if (type == null || SubstitutionReflectivityFilter.shouldExclude(type, metaAccess, universe)) {
if (type == null || reflectivityFilter.shouldExclude(type)) {
return false;
}
}
Expand Down Expand Up @@ -1097,7 +1099,7 @@ private boolean shouldExcludeClass(Class<?> clazz) {
if (clazz.isPrimitive()) {
return true; // primitives cannot be looked up by name and have no methods or fields
}
return SubstitutionReflectivityFilter.shouldExclude(clazz, metaAccess, universe);
return reflectivityFilter.shouldExclude(clazz);
}

private static <T> T queryGenericInfo(Callable<T> callable) {
Expand Down Expand Up @@ -1131,7 +1133,7 @@ private void maybeRegisterRecordComponents(Class<?> clazz) {
Method[] accessors = RecordUtils.getRecordComponentAccessorMethods(clazz);
Set<Method> unregisteredAccessors = ConcurrentHashMap.newKeySet();
for (Method accessor : accessors) {
if (SubstitutionReflectivityFilter.shouldExclude(accessor, metaAccess, universe)) {
if (reflectivityFilter.shouldExclude(accessor)) {
return;
}
unregisteredAccessors.add(accessor);
Expand Down Expand Up @@ -1241,7 +1243,7 @@ public void registerHeapDynamicHub(Object object, ScanReason reason) {
if (isSealed()) {
throw new UnsupportedFeatureException("Registering new class for reflection when the image heap is already sealed: " + javaClass);
}
if (!SubstitutionReflectivityFilter.shouldExclude(javaClass, metaAccess, universe)) {
if (!reflectivityFilter.shouldExclude(javaClass)) {
registerTypesForClass(metaAccess.lookupJavaType(javaClass), javaClass);
}
}
Expand All @@ -1260,7 +1262,7 @@ public void registerHeapReflectionField(Field reflectField, ScanReason reason) {
if (isSealed()) {
throw new UnsupportedFeatureException("Registering new field for reflection when the image heap is already sealed: " + reflectField);
}
if (!SubstitutionReflectivityFilter.shouldExclude(reflectField, metaAccess, universe)) {
if (!reflectivityFilter.shouldExclude(reflectField)) {
registerTypesForField(analysisField, reflectField, false);
if (analysisField.getDeclaringClass().isAnnotation()) {
processAnnotationField(ConfigurationCondition.alwaysTrue(), reflectField);
Expand All @@ -1285,7 +1287,7 @@ public void registerHeapReflectionExecutable(Executable reflectExecutable, ScanR
if (isSealed()) {
throw new UnsupportedFeatureException("Registering new method for reflection when the image heap is already sealed: " + reflectExecutable);
}
if (!SubstitutionReflectivityFilter.shouldExclude(reflectExecutable, metaAccess, universe)) {
if (!reflectivityFilter.shouldExclude(reflectExecutable)) {
registerTypesForMethod(analysisMethod, reflectExecutable);
if (reflectExecutable instanceof Method && reflectExecutable.getDeclaringClass().isAnnotation()) {
processAnnotationMethod(false, (Method) reflectExecutable);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import java.lang.invoke.VarHandle;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
Expand All @@ -47,9 +46,6 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.oracle.svm.core.TrackDynamicAccessEnabled;
import com.oracle.svm.hosted.DynamicAccessDetectionFeature;
import com.oracle.svm.hosted.NativeImageSystemClassLoader;
import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.hosted.RuntimeReflection;
import org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport;
Expand All @@ -58,22 +54,24 @@
import com.oracle.graal.pointsto.meta.AnalysisUniverse;
import com.oracle.svm.core.MissingRegistrationUtils;
import com.oracle.svm.core.ParsingReason;
import com.oracle.svm.core.annotate.Delete;
import com.oracle.svm.core.TrackDynamicAccessEnabled;
import com.oracle.svm.core.hub.ClassForNameSupport;
import com.oracle.svm.core.hub.PredefinedClassesSupport;
import com.oracle.svm.core.hub.RuntimeClassLoading;
import com.oracle.svm.core.jdk.StackTraceUtils;
import com.oracle.svm.core.option.HostedOptionKey;
import com.oracle.svm.core.util.VMError;
import com.oracle.svm.hosted.DynamicAccessDetectionFeature;
import com.oracle.svm.hosted.ExceptionSynthesizer;
import com.oracle.svm.hosted.FallbackFeature;
import com.oracle.svm.hosted.ImageClassLoader;
import com.oracle.svm.hosted.NativeImageSystemClassLoader;
import com.oracle.svm.hosted.ReachabilityRegistrationNode;
import com.oracle.svm.hosted.classinitialization.ClassInitializationSupport;
import com.oracle.svm.hosted.dynamicaccessinference.DynamicAccessInferenceLog;
import com.oracle.svm.hosted.dynamicaccessinference.StrictDynamicAccessInferenceFeature;
import com.oracle.svm.hosted.substitute.AnnotationSubstitutionProcessor;
import com.oracle.svm.hosted.substitute.DeletedElementException;
import com.oracle.svm.hosted.substitute.SubstitutionReflectivityFilter;
import com.oracle.svm.util.ModuleSupport;
import com.oracle.svm.util.ReflectionUtil;
import com.oracle.svm.util.TypeResult;
Expand All @@ -91,7 +89,6 @@
import jdk.graal.compiler.options.Option;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
Expand Down Expand Up @@ -129,6 +126,7 @@ static class Options {
private final boolean trackDynamicAccess;
private final DynamicAccessDetectionFeature dynamicAccessDetectionFeature;
private final DynamicAccessInferenceLog inferenceLog;
private final SubstitutionReflectivityFilter reflectivityFilter;

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

this.inferenceLog = DynamicAccessInferenceLog.singletonOrNull();

this.reflectivityFilter = SubstitutionReflectivityFilter.singleton();
}

public static void registerInvocationPlugins(ImageClassLoader imageClassLoader, AnnotationSubstitutionProcessor annotationSubstitutions,
Expand Down Expand Up @@ -737,12 +737,12 @@ private static boolean isAllowedConstant(Class<?> clazz) {
* compilation, not a lossy copy of it.
*/
@SuppressWarnings("unchecked")
private <T> T getIntrinsic(GraphBuilderContext context, T element) {
private <T> T getIntrinsic(T element) {
if (reason == ParsingReason.AutomaticUnsafeTransformation || reason == ParsingReason.EarlyClassInitializerAnalysis) {
/* We are analyzing the static initializers and should always intrinsify. */
return element;
}
if (isDeleted(element, context.getMetaAccess())) {
if (element instanceof AnnotatedElement annotatedElement && reflectivityFilter.shouldExcludeElement(annotatedElement)) {
/*
* Should not intrinsify. Will fail during the reflective lookup at runtime. @Delete-ed
* elements are ignored by the reflection plugins regardless of the value of
Expand All @@ -761,7 +761,7 @@ private JavaConstant getIntrinsicConstant(GraphBuilderContext context, Object el
/* We are analyzing the static initializers and should always intrinsify. */
return context.getSnippetReflection().forObject(element);
}
if (isDeleted(element, context.getMetaAccess())) {
if (element instanceof AnnotatedElement annotatedElement && reflectivityFilter.shouldExcludeElement(annotatedElement)) {
/*
* Should not intrinsify. Will fail during the reflective lookup at runtime. @Delete-ed
* elements are ignored by the reflection plugins regardless of the value of
Expand All @@ -772,31 +772,9 @@ private JavaConstant getIntrinsicConstant(GraphBuilderContext context, Object el
return aUniverse.replaceObjectWithConstant(element, context.getSnippetReflection()::forObject);
}

private static <T> boolean isDeleted(T element, MetaAccessProvider metaAccess) {
AnnotatedElement annotated = null;
try {
if (element instanceof Executable) {
annotated = metaAccess.lookupJavaMethod((Executable) element);
} else if (element instanceof Field) {
annotated = metaAccess.lookupJavaField((Field) element);
}
} catch (DeletedElementException ex) {
/*
* If ReportUnsupportedElementsAtRuntime is *not* set looking up a @Delete-ed element
* will result in a DeletedElementException.
*/
return true;
}
/*
* If ReportUnsupportedElementsAtRuntime is set looking up a @Delete-ed element will return
* a substitution method that has the @Delete annotation.
*/
return annotated != null && annotated.isAnnotationPresent(Delete.class);
}

private JavaConstant pushConstant(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Object receiver, Object[] arguments, JavaKind returnKind, Object returnValue,
boolean allowNullReturnValue, boolean subjectToStrictDynamicAccessInference) {
Object intrinsicValue = getIntrinsic(b, returnValue == null && allowNullReturnValue ? NULL_MARKER : returnValue);
Object intrinsicValue = getIntrinsic(returnValue == null && allowNullReturnValue ? NULL_MARKER : returnValue);
if (intrinsicValue == null) {
return null;
}
Expand All @@ -822,7 +800,7 @@ private boolean throwException(GraphBuilderContext b, ResolvedJavaMethod targetM
if (exceptionMethod == null) {
return false;
}
Method intrinsic = getIntrinsic(b, exceptionMethod);
Method intrinsic = getIntrinsic(exceptionMethod);
if (intrinsic == null) {
return false;
}
Expand Down
Loading