diff --git a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/RuntimeReflection.java b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/RuntimeReflection.java index 07ef05fedfffa..809194c588921 100644 --- a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/RuntimeReflection.java +++ b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/RuntimeReflection.java @@ -201,7 +201,7 @@ public static void registerAllDeclaredMethods(Class declaringClass) { * @since 23.0 */ public static void registerAllConstructors(Class declaringClass) { - ImageSingletons.lookup(RuntimeReflectionSupport.class).registerAllConstructorsQuery(ConfigurationCondition.alwaysTrue(), true, declaringClass); + ImageSingletons.lookup(RuntimeReflectionSupport.class).registerAllConstructorsQuery(ConfigurationCondition.alwaysTrue(), false, declaringClass); } /** @@ -211,7 +211,7 @@ public static void registerAllConstructors(Class declaringClass) { * @since 23.0 */ public static void registerAllDeclaredConstructors(Class declaringClass) { - ImageSingletons.lookup(RuntimeReflectionSupport.class).registerAllDeclaredConstructorsQuery(ConfigurationCondition.alwaysTrue(), true, declaringClass); + ImageSingletons.lookup(RuntimeReflectionSupport.class).registerAllDeclaredConstructorsQuery(ConfigurationCondition.alwaysTrue(), false, declaringClass); } /** @@ -221,7 +221,7 @@ public static void registerAllDeclaredConstructors(Class declaringClass) { * @since 23.0 */ public static void registerAllFields(Class declaringClass) { - ImageSingletons.lookup(RuntimeReflectionSupport.class).registerAllFieldsQuery(ConfigurationCondition.alwaysTrue(), declaringClass); + ImageSingletons.lookup(RuntimeReflectionSupport.class).registerAllFields(ConfigurationCondition.alwaysTrue(), declaringClass); } /** @@ -231,7 +231,7 @@ public static void registerAllFields(Class declaringClass) { * @since 23.0 */ public static void registerAllDeclaredFields(Class declaringClass) { - ImageSingletons.lookup(RuntimeReflectionSupport.class).registerAllDeclaredFieldsQuery(ConfigurationCondition.alwaysTrue(), declaringClass); + ImageSingletons.lookup(RuntimeReflectionSupport.class).registerAllDeclaredFields(ConfigurationCondition.alwaysTrue(), declaringClass); } /** diff --git a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/ReflectionRegistry.java b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/ReflectionRegistry.java index 9d0534347cfbf..686d692c261ff 100644 --- a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/ReflectionRegistry.java +++ b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/ReflectionRegistry.java @@ -45,6 +45,7 @@ import java.util.Arrays; public interface ReflectionRegistry { + // TODO thread this true behind MRE flag default void register(ConfigurationCondition condition, Class... classes) { Arrays.stream(classes).forEach(clazz -> register(condition, false, clazz)); } diff --git a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/RuntimeReflectionSupport.java b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/RuntimeReflectionSupport.java index 68e78b2c975b5..6415b4753a78e 100644 --- a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/RuntimeReflectionSupport.java +++ b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/RuntimeReflectionSupport.java @@ -46,9 +46,9 @@ public interface RuntimeReflectionSupport extends ReflectionRegistry { void registerAllDeclaredMethodsQuery(ConfigurationCondition condition, boolean queriedOnly, Class clazz); - void registerAllFieldsQuery(ConfigurationCondition condition, Class clazz); + void registerAllFields(ConfigurationCondition condition, Class clazz); - void registerAllDeclaredFieldsQuery(ConfigurationCondition condition, Class clazz); + void registerAllDeclaredFields(ConfigurationCondition condition, Class clazz); void registerAllConstructorsQuery(ConfigurationCondition condition, boolean queriedOnly, Class clazz); diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/ClassInclusionPolicy.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/ClassInclusionPolicy.java index 34542248c3932..076d197df1f5e 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/ClassInclusionPolicy.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/ClassInclusionPolicy.java @@ -36,6 +36,7 @@ import com.oracle.graal.pointsto.meta.AnalysisField; import com.oracle.graal.pointsto.meta.AnalysisMethod; import com.oracle.svm.core.annotate.TargetClass; +import com.oracle.svm.util.ReflectionUtil; import jdk.graal.compiler.api.replacements.Fold; @@ -57,7 +58,7 @@ public void setBigBang(BigBang bb) { } public static boolean isClassIncludedBase(Class cls) { - Class enclosingClass = cls.getEnclosingClass(); + Class enclosingClass = ReflectionUtil.linkageSafeQuery(cls, null, Class::getEnclosingClass); return !Feature.class.isAssignableFrom(cls) && !AnnotationAccess.isAnnotationPresent(cls, TargetClass.class) && (enclosingClass == null || isClassIncludedBase(enclosingClass)); } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/PointsToAnalysis.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/PointsToAnalysis.java index 555f9afa26207..92c7c0d71aab1 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/PointsToAnalysis.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/PointsToAnalysis.java @@ -662,7 +662,7 @@ public void onTypeInstantiated(AnalysisType type) { /* Register the type as instantiated with all its super types. */ assert type.isInstantiated() : type; - AnalysisError.guarantee(type.isArray() || (type.isInstanceClass() && !type.isAbstract())); + AnalysisError.guarantee(type.isArray() || (type.isInstanceClass() && !type.isAbstract()), "Type %s must be either an array, or a non abstract instance class", type.getName()); TypeState typeState = TypeState.forExactType(this, type, true); TypeState typeStateNonNull = TypeState.forExactType(this, type, false); diff --git a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ParserConfigurationAdapter.java b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ParserConfigurationAdapter.java index 17258e8c07bea..cad179ec98223 100644 --- a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ParserConfigurationAdapter.java +++ b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ParserConfigurationAdapter.java @@ -55,7 +55,7 @@ public TypeResult resolveType(UnresolvedConfigurationConditio } @Override - public void registerType(UnresolvedConfigurationCondition condition, ConfigurationType type) { + public void registerType(UnresolvedConfigurationCondition condition, ConfigurationType type, boolean registerMetadata) { VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type"); configuration.add(type); } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java index 04bfd5aec5f00..98c5a8863d264 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java @@ -1302,7 +1302,7 @@ public enum ReportingMode { public static final HostedOptionKey IncludeAllFromModule = new HostedOptionKey<>(AccumulatingLocatableMultiOptionValue.Strings.build()); @Option(help = "Include all classes, methods, fields, and resources from a given module for dynamic access", type = OptionType.Debug) // - public static final HostedOptionKey IncludeAllMetadataForModule = new HostedOptionKey<>(AccumulatingLocatableMultiOptionValue.Strings.build()); + public static final HostedOptionKey EnableDynamicAccessForModule = new HostedOptionKey<>(AccumulatingLocatableMultiOptionValue.Strings.build()); @Option(help = "Include all classes, methods, fields, and resources from given paths", type = OptionType.Debug) // public static final HostedOptionKey IncludeAllFromPath = new HostedOptionKey<>(AccumulatingLocatableMultiOptionValue.Strings.build()); @@ -1312,17 +1312,17 @@ public enum ReportingMode { AccumulatingLocatableMultiOptionValue.Strings.buildWithCommaDelimiter()); @Option(help = "Include all classes, methods and fields from the given packages for dynamic access", type = OptionType.Debug) // - public static final HostedOptionKey IncludeAllMetadataFromPackage = new HostedOptionKey<>( + public static final HostedOptionKey EnableDynamicAccessForPackage = new HostedOptionKey<>( AccumulatingLocatableMultiOptionValue.Strings.buildWithCommaDelimiter()); @Option(help = "Include all classes, methods, fields, and resources from given paths for dynamic access", type = OptionType.Debug) // - public static final HostedOptionKey IncludeAllMetadataForClassPathEntry = new HostedOptionKey<>(AccumulatingLocatableMultiOptionValue.Strings.build()); + public static final HostedOptionKey EnableDynamicAccessForClassPathEntry = new HostedOptionKey<>(AccumulatingLocatableMultiOptionValue.Strings.build()); @Option(help = "Include all classes, methods, fields, and resources from the class path", type = OptionType.Debug) // public static final HostedOptionKey IncludeAllFromClassPath = new HostedOptionKey<>(false); @Option(help = "Include all classes, methods, fields, and resources for dynamic access for the whole classpath", type = OptionType.Debug) // - public static final HostedOptionKey IncludeAllMetadataForClassPath = new HostedOptionKey<>(false); + public static final HostedOptionKey EnableDynamicAccess = new HostedOptionKey<>(false); public static boolean includeAll() { return IncludeAllFromModule.hasBeenSet() || IncludeAllFromPath.hasBeenSet() || IncludeAllFromPackage.hasBeenSet() || IncludeAllFromClassPath.hasBeenSet(); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/LegacyReflectionConfigurationParser.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/LegacyReflectionConfigurationParser.java index 37cd6b903a535..cf72b3723f11b 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/LegacyReflectionConfigurationParser.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/LegacyReflectionConfigurationParser.java @@ -91,7 +91,7 @@ protected void parseClass(EconomicMap data) { C queryCondition = isType ? conditionResolver.alwaysTrue() : condition; T clazz = result.get(); - delegate.registerType(conditionResult.get(), clazz); + delegate.registerType(conditionResult.get(), clazz, false); registerIfNotDefault(data, false, clazz, "allDeclaredConstructors", () -> delegate.registerDeclaredConstructors(condition, false, clazz)); registerIfNotDefault(data, false, clazz, "allPublicConstructors", () -> delegate.registerPublicConstructors(condition, false, clazz)); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ReflectionConfigurationParserDelegate.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ReflectionConfigurationParserDelegate.java index 73463542d5db0..0ddce3d38e11a 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ReflectionConfigurationParserDelegate.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ReflectionConfigurationParserDelegate.java @@ -32,7 +32,7 @@ public interface ReflectionConfigurationParserDelegate { TypeResult resolveType(C condition, ConfigurationTypeDescriptor typeDescriptor, boolean allowPrimitives); - void registerType(C condition, T type); + void registerType(C condition, T type, boolean registerMetadata); void registerPublicClasses(C condition, T type); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ReflectionMetadataParser.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ReflectionMetadataParser.java index ffa54d572be1a..be08dc4b09640 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ReflectionMetadataParser.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ReflectionMetadataParser.java @@ -84,7 +84,7 @@ protected void parseClass(EconomicMap data) { C queryCondition = conditionResolver.alwaysTrue(); T clazz = result.get(); - delegate.registerType(conditionResult.get(), clazz); + delegate.registerType(conditionResult.get(), clazz, true); delegate.registerDeclaredClasses(queryCondition, clazz); delegate.registerRecordComponents(queryCondition, clazz); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/ClassForNameSupport.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/ClassForNameSupport.java index b78b746918e33..49862dcad3f12 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/ClassForNameSupport.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/ClassForNameSupport.java @@ -26,6 +26,7 @@ import static com.oracle.svm.core.MissingRegistrationUtils.throwMissingRegistrationErrors; +import java.lang.reflect.Modifier; import java.util.EnumSet; import java.util.Objects; @@ -154,7 +155,7 @@ public void registerNegativeQuery(ConfigurationCondition condition, String class @Platforms(Platform.HOSTED_ONLY.class) public void registerUnsafeAllocated(ConfigurationCondition condition, Class clazz) { - if (!clazz.isArray()) { + if (!clazz.isArray() && !clazz.isInterface() && !Modifier.isAbstract(clazz.getModifiers())) { var conditionSet = unsafeInstantiatedClasses.putIfAbsent(clazz, RuntimeConditionSet.createHosted(condition)); if (conditionSet != null) { conditionSet.addCondition(condition); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ClassLoaderSupportImpl.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ClassLoaderSupportImpl.java index 045c7e0c76224..0dcf1e2bd3044 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ClassLoaderSupportImpl.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ClassLoaderSupportImpl.java @@ -116,8 +116,8 @@ public void collectResources(ResourceCollector resourceCollector) { /* Collect remaining resources from classpath */ classLoaderSupport.classpath().stream().parallel().forEach(classpathFile -> { - boolean includeCurrent = classLoaderSupport.getJavaPathsToInclude().contains(classpathFile) || classLoaderSupport.includeAllFromClassPath() || - classLoaderSupport.getPathsToIncludeMetadata().contains(classpathFile) || classLoaderSupport.isIncludeAllMetadataFromClassPath(); + boolean includeCurrent = classLoaderSupport.getPathsToInclude().contains(classpathFile) || classLoaderSupport.includeAllFromClassPath() || + classLoaderSupport.getClassPathEntriesToEnableDynamicAccess().contains(classpathFile) || classLoaderSupport.isEnableDynamicAccessForClassPath(); try { if (Files.isDirectory(classpathFile)) { scanDirectory(classpathFile, resourceCollector, includeCurrent); @@ -134,7 +134,7 @@ private void collectResourceFromModule(ResourceCollector resourceCollector, Reso ModuleReference moduleReference = info.resolvedModule.reference(); try (ModuleReader moduleReader = moduleReference.open()) { boolean includeCurrent = classLoaderSupport.getModuleNamesToInclude().contains(info.resolvedModule().name()) || - classLoaderSupport.getModuleNamesToIncludeMetadata().contains(info.resolvedModule().name()); + classLoaderSupport.getModuleNamesToEnableDynamicAccess().contains(info.resolvedModule().name()); List resourcesFound = new ArrayList<>(); moduleReader.list().forEach(resourceName -> { var conditionsWithOrigins = shouldIncludeEntry(info.module, resourceCollector, resourceName, moduleReference.location().orElse(null), includeCurrent); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageClassLoaderSupport.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageClassLoaderSupport.java index 35ca92cf9da33..337b4101626c7 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageClassLoaderSupport.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageClassLoaderSupport.java @@ -24,14 +24,14 @@ */ package com.oracle.svm.hosted; +import static com.oracle.svm.core.SubstrateOptions.EnableDynamicAccess; +import static com.oracle.svm.core.SubstrateOptions.EnableDynamicAccessForClassPathEntry; +import static com.oracle.svm.core.SubstrateOptions.EnableDynamicAccessForModule; import static com.oracle.svm.core.SubstrateOptions.IncludeAllFromClassPath; import static com.oracle.svm.core.SubstrateOptions.IncludeAllFromModule; import static com.oracle.svm.core.SubstrateOptions.IncludeAllFromPackage; import static com.oracle.svm.core.SubstrateOptions.IncludeAllFromPath; -import static com.oracle.svm.core.SubstrateOptions.IncludeAllMetadataForClassPath; -import static com.oracle.svm.core.SubstrateOptions.IncludeAllMetadataForClassPathEntry; -import static com.oracle.svm.core.SubstrateOptions.IncludeAllMetadataForModule; -import static com.oracle.svm.core.SubstrateOptions.IncludeAllMetadataFromPackage; +import static com.oracle.svm.core.SubstrateOptions.EnableDynamicAccessForPackage; import static com.oracle.svm.core.util.VMError.guarantee; import static com.oracle.svm.core.util.VMError.shouldNotReachHere; @@ -133,17 +133,17 @@ public final class NativeImageClassLoaderSupport { public final AnnotationExtractor annotationExtractor; - private Set javaModuleNamesToInclude; - private Set moduleNamesToIncludeMetadata; + private Set moduleNamesToInclude; + private Set moduleNamesToEnableDynamicAccess; private Set javaPackagesToInclude; - private Set packagesToIncludeMetadata; + private Set packagesToEnableDynamicAccess; - private Set javaPathsToInclude; - private Set pathsToIncludeMetadata; + private Set pathsToInclude; + private Set classPathEntriesToEnableDynamicAccess; private boolean includeAllFromClassPath; - private boolean includeAllMetadataFromClassPath; + private boolean enableDynamicAccessForClassPath; private Optional libGraalLoader; private List classLoaders; @@ -260,19 +260,19 @@ private static Path stringToPath(String path) { } public void loadAllClasses(ForkJoinPool executor, ImageClassLoader imageClassLoader) { - guarantee(javaModuleNamesToInclude == null && javaPackagesToInclude == null, "This method should be executed only once."); + guarantee(moduleNamesToInclude == null && javaPackagesToInclude == null, "This method should be executed only once."); - javaModuleNamesToInclude = collectAndVerifyModulesFromOption(IncludeAllFromModule); - moduleNamesToIncludeMetadata = collectAndVerifyModulesFromOption(IncludeAllMetadataForModule); + moduleNamesToInclude = collectAndVerifyModulesFromOption(IncludeAllFromModule); + moduleNamesToEnableDynamicAccess = collectAndVerifyModulesFromOption(EnableDynamicAccessForModule); javaPackagesToInclude = Set.copyOf(IncludeAllFromPackage.getValue(parsedHostedOptions).values()); - packagesToIncludeMetadata = Set.copyOf(IncludeAllMetadataFromPackage.getValue(parsedHostedOptions).values()); + packagesToEnableDynamicAccess = Set.copyOf(EnableDynamicAccessForPackage.getValue(parsedHostedOptions).values()); - javaPathsToInclude = collectAndVerifyPathsFromOption(IncludeAllFromPath); - pathsToIncludeMetadata = collectAndVerifyPathsFromOption(IncludeAllMetadataForClassPathEntry); + pathsToInclude = collectAndVerifyPathsFromOption(IncludeAllFromPath); + classPathEntriesToEnableDynamicAccess = collectAndVerifyPathsFromOption(EnableDynamicAccessForClassPathEntry); includeAllFromClassPath = IncludeAllFromClassPath.getValue(parsedHostedOptions); - includeAllMetadataFromClassPath = IncludeAllMetadataForClassPath.getValue(parsedHostedOptions); + enableDynamicAccessForClassPath = EnableDynamicAccess.getValue(parsedHostedOptions); new LoadClassHandler(executor, imageClassLoader).run(); @@ -772,7 +772,7 @@ private void run() { Set additionalSystemModules = upgradeAndSystemModuleFinder.findAll().stream() .map(v -> v.descriptor().name()) - .filter(n -> getModuleNamesToInclude().contains(n) || getModuleNamesToIncludeMetadata().contains(n)) + .filter(n -> getModuleNamesToInclude().contains(n) || getModuleNamesToEnableDynamicAccess().contains(n)) .collect(Collectors.toSet()); requiresInit.addAll(additionalSystemModules); @@ -796,7 +796,7 @@ private void run() { /* Verify all package inclusion requests were successful */ verifyPackageInclusionSuccessful(NativeImageClassLoaderSupport.this.javaPackagesToInclude, IncludeAllFromPackage); - verifyPackageInclusionSuccessful(NativeImageClassLoaderSupport.this.packagesToIncludeMetadata, IncludeAllMetadataFromPackage); + verifyPackageInclusionSuccessful(NativeImageClassLoaderSupport.this.packagesToEnableDynamicAccess, EnableDynamicAccessForPackage); } private void initModule(ModuleReference moduleReference, boolean moduleRequiresInit) { @@ -808,8 +808,8 @@ private void initModule(ModuleReference moduleReference, boolean moduleRequiresI } try (ModuleReader moduleReader = moduleReference.open()) { Module module = optionalModule.get(); - final boolean includeUnconditionally = javaModuleNamesToInclude.contains(module.getName()); - final boolean includeForReflection = moduleNamesToIncludeMetadata.contains(module.getName()); + final boolean includeUnconditionally = moduleNamesToInclude.contains(module.getName()); + final boolean includeForReflection = moduleNamesToEnableDynamicAccess.contains(module.getName()); var container = moduleReference.location().orElseThrow(); if (ModuleLayer.boot().equals(module.getLayer())) { builderURILocations.add(container); @@ -829,8 +829,8 @@ private void initModule(ModuleReference moduleReference, boolean moduleRequiresI } private void loadClassesFromPath(Path path) { - final boolean includeUnconditionally = javaPathsToInclude.contains(path) || includeAllFromClassPath; - final boolean includeAllMetadata = pathsToIncludeMetadata.contains(path) || includeAllMetadataFromClassPath; + final boolean includeUnconditionally = pathsToInclude.contains(path) || includeAllFromClassPath; + final boolean includeAllMetadata = classPathEntriesToEnableDynamicAccess.contains(path) || enableDynamicAccessForClassPath; if (ClasspathUtils.isJar(path)) { try { URI container = path.toAbsolutePath().toUri(); @@ -1013,7 +1013,7 @@ private void handleClassFileName(URI container, Module module, String className, if (classRequiresInit) { imageClassLoader.handleClass(clazz); } - if (includeAllMetadata || packagesToIncludeMetadata.contains(packageName)) { + if (includeAllMetadata || packagesToEnableDynamicAccess.contains(packageName)) { classesToIncludeMetadata.add(clazz); } } @@ -1063,27 +1063,27 @@ public void reportBuilderClassesInApplication() { } public Set getModuleNamesToInclude() { - return javaModuleNamesToInclude; + return moduleNamesToInclude; } - public Set getModuleNamesToIncludeMetadata() { - return moduleNamesToIncludeMetadata; + public Set getModuleNamesToEnableDynamicAccess() { + return moduleNamesToEnableDynamicAccess; } - public Set getJavaPathsToInclude() { - return javaPathsToInclude; + public Set getPathsToInclude() { + return pathsToInclude; } - public Set getPathsToIncludeMetadata() { - return pathsToIncludeMetadata; + public Set getClassPathEntriesToEnableDynamicAccess() { + return classPathEntriesToEnableDynamicAccess; } public boolean includeAllFromClassPath() { return includeAllFromClassPath; } - public boolean isIncludeAllMetadataFromClassPath() { - return includeAllMetadataFromClassPath; + public boolean isEnableDynamicAccessForClassPath() { + return enableDynamicAccessForClassPath; } public List> getClassesToIncludeUnconditionally() { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java index baf3091aac80f..9caa34d46ba55 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java @@ -32,6 +32,8 @@ import java.io.IOException; import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.nio.file.FileSystems; @@ -75,7 +77,9 @@ import org.graalvm.nativeimage.hosted.RuntimeSerialization; import org.graalvm.nativeimage.impl.AnnotationExtractor; import org.graalvm.nativeimage.impl.CConstantValueSupport; +import org.graalvm.nativeimage.impl.ConfigurationCondition; import org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport; +import org.graalvm.nativeimage.impl.RuntimeReflectionSupport; import org.graalvm.nativeimage.impl.SizeOfSupport; import org.graalvm.word.PointerBase; @@ -1081,23 +1085,28 @@ protected void setupNativeImage(String imageName, OptionValues options, Map cls) { - RuntimeReflection.register(cls); - RuntimeJNIAccess.register(cls); - for (Method declaredMethod : cls.getDeclaredMethods()) { - RuntimeReflection.register(declaredMethod); + private static void registerClassFullyForReflection(Class clazz) { + RuntimeReflection.register(clazz); + + RuntimeReflection.registerAllDeclaredFields(clazz); + RuntimeReflection.registerAllDeclaredMethods(clazz); + RuntimeReflection.registerAllDeclaredConstructors(clazz); + + RuntimeJNIAccess.register(clazz); + for (Method declaredMethod : ReflectionUtil.linkageSafeQuery(clazz, new Method[0], Class::getDeclaredMethods)) { RuntimeJNIAccess.register(declaredMethod); } - RuntimeReflection.registerAllDeclaredFields(cls); - RuntimeReflection.registerAllFields(cls); - RuntimeReflection.registerAllMethods(cls); - RuntimeReflection.registerAllDeclaredMethods(cls); - - for (var declaredField : cls.getDeclaredFields()) { - RuntimeReflection.register(declaredField); + for (Constructor declaredConstructor : ReflectionUtil.linkageSafeQuery(clazz, new Constructor[0], Class::getDeclaredConstructors)) { + RuntimeJNIAccess.register(declaredConstructor); + } + for (var declaredField : ReflectionUtil.linkageSafeQuery(clazz, new Field[0], Class::getDeclaredFields)) { RuntimeJNIAccess.register(declaredField); } - RuntimeSerialization.register(cls); + + RuntimeSerialization.register(clazz); + if (!(clazz.isArray() || clazz.isInterface() || clazz.isPrimitive() || Modifier.isAbstract(clazz.getModifiers()))) { + ImageSingletons.lookup(RuntimeReflectionSupport.class).register(ConfigurationCondition.alwaysTrue(), true, clazz); + } } protected void registerEntryPointStubs(Map entryPoints) { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SVMHost.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SVMHost.java index bb1376886d4b6..59a3d32935308 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SVMHost.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SVMHost.java @@ -31,6 +31,7 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; +import java.lang.reflect.RecordComponent; import java.util.Comparator; import java.util.EnumSet; import java.util.HashMap; @@ -646,7 +647,7 @@ public void checkType(ResolvedJavaType type, AnalysisUniverse universe) { throw new UnsupportedFeatureException(message); } if (originalClass.isRecord()) { - for (var recordComponent : originalClass.getRecordComponents()) { + for (var recordComponent : ReflectionUtil.linkageSafeQuery(originalClass, new RecordComponent[0], Class::getRecordComponents)) { if (WordBase.class.isAssignableFrom(recordComponent.getType())) { throw UserError.abort("Records cannot use Word types. " + "The equals/hashCode/toString implementation of records uses method handles, and Word types are not supported as parameters of method handle invocations. " + diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/config/ReflectionRegistryAdapter.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/config/ReflectionRegistryAdapter.java index 58b71e955769d..e1cc222f2b933 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/config/ReflectionRegistryAdapter.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/config/ReflectionRegistryAdapter.java @@ -52,8 +52,8 @@ public class ReflectionRegistryAdapter extends RegistryAdapter { } @Override - public void registerType(ConfigurationCondition condition, Class type) { - super.registerType(condition, type); + public void registerType(ConfigurationCondition condition, Class type, boolean registerMetadata) { + super.registerType(condition, type, registerMetadata); if (Proxy.isProxyClass(type)) { proxyRegistry.accept(condition, Arrays.stream(type.getInterfaces()).map(Class::getTypeName).toList()); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/config/RegistryAdapter.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/config/RegistryAdapter.java index 6766d62d15935..1960c7cc7b4fd 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/config/RegistryAdapter.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/config/RegistryAdapter.java @@ -68,8 +68,8 @@ public static RegistryAdapter create(ReflectionRegistry registry, ProxyRegistry } @Override - public void registerType(ConfigurationCondition condition, Class type) { - registry.register(condition, type); + public void registerType(ConfigurationCondition condition, Class type, boolean registerMetadata) { + registry.register(condition, registerMetadata, type); } @Override diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/RecordUtils.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/RecordUtils.java index 1cfc6093df440..92052e9e85380 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/RecordUtils.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/RecordUtils.java @@ -31,18 +31,19 @@ import java.util.Objects; import com.oracle.svm.core.util.VMError; +import com.oracle.svm.util.ReflectionUtil; public final class RecordUtils { public static Method[] getRecordComponentAccessorMethods(Class clazz) { - return Arrays.stream(clazz.getRecordComponents()) + return Arrays.stream(ReflectionUtil.linkageSafeQuery(clazz, new RecordComponent[0], Class::getRecordComponents)) .map(RecordComponent::getAccessor) .filter(Objects::nonNull) .toArray(Method[]::new); } public static Constructor getCanonicalRecordConstructor(Class clazz) { - Class[] paramTypes = Arrays.stream(clazz.getRecordComponents()) + Class[] paramTypes = Arrays.stream(ReflectionUtil.linkageSafeQuery(clazz, new RecordComponent[0], Class::getRecordComponents)) .map(RecordComponent::getType) .toArray(Class[]::new); try { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionDataBuilder.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionDataBuilder.java index 5b6941dc6bf0d..d0d9ca7aeef2a 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionDataBuilder.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionDataBuilder.java @@ -64,9 +64,11 @@ import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; import java.util.stream.Collectors; +import com.oracle.svm.core.jdk.UninterruptibleUtils; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.hosted.RuntimeProxyCreation; import org.graalvm.nativeimage.hosted.RuntimeReflection; @@ -501,6 +503,8 @@ public void registerMethodLookup(ConfigurationCondition condition, Class decl } catch (NoSuchMethodException e) { negativeMethodLookups.computeIfAbsent(metaAccess.lookupJavaType(declaringClass), (key) -> ConcurrentHashMap.newKeySet()) .add(new AnalysisMethod.Signature(methodName, metaAccess.lookupJavaTypes(parameterTypes))); + } catch (LinkageError le) { + registerLinkageError(declaringClass, le, methodLookupExceptions); } }); } @@ -514,6 +518,8 @@ public void registerConstructorLookup(ConfigurationCondition condition, Class } catch (NoSuchMethodException e) { negativeConstructorLookups.computeIfAbsent(metaAccess.lookupJavaType(declaringClass), (key) -> ConcurrentHashMap.newKeySet()) .add(metaAccess.lookupJavaTypes(parameterTypes)); + } catch (LinkageError le) { + registerLinkageError(declaringClass, le, constructorLookupExceptions); } }); } @@ -525,7 +531,7 @@ public void register(ConfigurationCondition condition, boolean finalIsWritable, } @Override - public void registerAllFieldsQuery(ConfigurationCondition condition, Class clazz) { + public void registerAllFields(ConfigurationCondition condition, Class clazz) { registerAllFieldsQuery(condition, false, clazz); } @@ -544,7 +550,7 @@ public void registerAllFieldsQuery(ConfigurationCondition condition, boolean que } @Override - public void registerAllDeclaredFieldsQuery(ConfigurationCondition condition, Class clazz) { + public void registerAllDeclaredFields(ConfigurationCondition condition, Class clazz) { registerAllDeclaredFieldsQuery(condition, false, clazz); } @@ -575,16 +581,13 @@ private void registerField(ConfigurationCondition cnd, boolean queriedOnly, Fiel var classFields = registeredFields.computeIfAbsent(declaringClass, t -> new ConcurrentHashMap<>()); boolean exists = classFields.containsKey(analysisField); + // TODO open a ticket to disallow boolean shouldRegisterReachabilityHandler = classFields.isEmpty(); var cndValue = classFields.computeIfAbsent(analysisField, f -> new ConditionalRuntimeValue<>(RuntimeConditionSet.emptySet(), reflectField)); - if (!queriedOnly) { - /* queryOnly methods are conditioned by the type itself */ - cndValue.getConditions().addCondition(cnd); - } - if (!exists) { - registerTypesForField(analysisField, reflectField, true); + registerTypesForField(analysisField, reflectField, queriedOnly); + // TODO bulk it up /* * The image needs to know about subtypes shadowing fields registered for reflection to * ensure the correctness of run-time reflection queries. @@ -611,10 +614,12 @@ private void registerField(ConfigurationCondition cnd, boolean queriedOnly, Fiel } /* - * We need to run this even if the method has already been registered, in case it was only + * We need to run this even if the field has already been registered, in case it was only * registered as queried. */ if (!queriedOnly) { + /* queryOnly methods are conditioned on the type itself */ + cndValue.getConditions().addCondition(cnd); registerTypesForField(analysisField, reflectField, false); } } @@ -631,6 +636,8 @@ public void registerFieldLookup(ConfigurationCondition condition, Class decla * not necessary. */ negativeFieldLookups.computeIfAbsent(metaAccess.lookupJavaType(declaringClass), (key) -> ConcurrentHashMap.newKeySet()).add(fieldName); + } catch (LinkageError le) { + registerLinkageError(declaringClass, le, fieldLookupExceptions); } }); } @@ -752,7 +759,7 @@ private void registerTypesForClass(AnalysisType analysisType, Class clazz) { } private void registerRecordComponents(Class clazz) { - RecordComponent[] recordComponents = clazz.getRecordComponents(); + RecordComponent[] recordComponents = ReflectionUtil.linkageSafeQuery(clazz, null, Class::getRecordComponents); if (recordComponents == null) { return; } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/serialize/SerializationFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/serialize/SerializationFeature.java index 271f8268ac162..917be93682783 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/serialize/SerializationFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/serialize/SerializationFeature.java @@ -50,6 +50,10 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import com.oracle.svm.core.MissingRegistrationSupport; +import com.oracle.svm.core.MissingRegistrationUtils; +import com.oracle.svm.core.SubstrateOptions; +import com.oracle.svm.core.reflect.MissingReflectionRegistrationUtils; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.hosted.Feature; import org.graalvm.nativeimage.hosted.RuntimeReflection; @@ -504,7 +508,8 @@ private void registerForSerialization(ConfigurationCondition cnd, Class seria * serialization class consistency, so need to register all constructors, methods and * fields. */ - registerSerializationUIDElements(serializationTargetClass, true); // if MRE + boolean legacyFullyRegister = !MissingRegistrationSupport.singleton().reportMissingRegistrationErrors(serializationTargetClass); + registerSerializationUIDElements(serializationTargetClass, legacyFullyRegister); /* * Required by jdk.internal.reflect.ReflectionFactory.newConstructorForSerialization @@ -527,11 +532,17 @@ private void registerForSerialization(ConfigurationCondition cnd, Class seria Class iter = serializationTargetClass; while (iter != null) { - Arrays.stream(iter.getDeclaredFields()).map(Field::getType).forEach(type -> { - RuntimeReflection.registerAllDeclaredMethods(type); - RuntimeReflection.registerAllDeclaredFields(type); - RuntimeReflection.registerAllDeclaredConstructors(type); - }); + // TODO linkage error + Arrays.stream(ReflectionUtil.linkageSafeQuery(iter, new Field[0], Class::getDeclaredFields)) + .map(Field::getType).forEach(type -> { + if (legacyFullyRegister) { + RuntimeReflection.registerAllDeclaredMethods(type); + RuntimeReflection.registerAllDeclaredFields(type); + RuntimeReflection.registerAllDeclaredConstructors(type); + } else { + RuntimeReflection.register(type); + } + }); iter = iter.getSuperclass(); } } @@ -550,11 +561,12 @@ static void registerSerializationUIDElements(Class serializationTargetClass, RuntimeReflection.registerAllDeclaredFields(serializationTargetClass); if (fullyRegister) { /* This is here a legacy that we can't remove as it is a breaking change */ - RuntimeReflection.register(serializationTargetClass.getDeclaredConstructors()); - RuntimeReflection.register(serializationTargetClass.getDeclaredMethods()); - RuntimeReflection.register(serializationTargetClass.getDeclaredFields()); + RuntimeReflection.register(ReflectionUtil.linkageSafeQuery(serializationTargetClass, new Constructor[0], Class::getDeclaredConstructors)); + RuntimeReflection.register(ReflectionUtil.linkageSafeQuery(serializationTargetClass, new Method[0], Class::getDeclaredMethods)); + RuntimeReflection.register(ReflectionUtil.linkageSafeQuery(serializationTargetClass, new Field[0], Class::getDeclaredFields)); + + RuntimeReflection.registerFieldLookup(serializationTargetClass, "serialPersistentFields"); } - RuntimeReflection.registerFieldLookup(serializationTargetClass, "serialPersistentFields"); } public void afterAnalysis() { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/SubstitutionReflectivityFilter.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/SubstitutionReflectivityFilter.java index 8ae0b0b2225fa..5e8c0e7e1b41d 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/SubstitutionReflectivityFilter.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/SubstitutionReflectivityFilter.java @@ -36,6 +36,7 @@ import com.oracle.svm.core.annotate.InjectAccessors; import com.oracle.svm.core.annotate.TargetClass; +import jdk.graal.compiler.api.replacements.Fold; import jdk.vm.ci.meta.ResolvedJavaType; /** @@ -74,6 +75,8 @@ public static boolean shouldExclude(Executable method, AnalysisMetaAccess metaAc return true; } else if (aMethod.isAnnotationPresent(Delete.class)) { return true; // accesses would fail at runtime + } else if (aMethod.isAnnotationPresent(Fold.class)) { + return true; // accesses can contain hosted elements } else if (aMethod.isSynthetic() && aMethod.getDeclaringClass().isAnnotationPresent(TargetClass.class)) { /* * Synthetic methods are usually methods injected by javac to provide access to diff --git a/substratevm/src/com.oracle.svm.util/src/com/oracle/svm/util/ReflectionUtil.java b/substratevm/src/com.oracle.svm.util/src/com/oracle/svm/util/ReflectionUtil.java index f8a8c3c237f52..7b39d977c7aa4 100644 --- a/substratevm/src/com.oracle.svm.util/src/com/oracle/svm/util/ReflectionUtil.java +++ b/substratevm/src/com.oracle.svm.util/src/com/oracle/svm/util/ReflectionUtil.java @@ -30,6 +30,7 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.function.Function; /** * This class contains utility methods for commonly used reflection functionality. Note that lookups @@ -86,7 +87,7 @@ public static Method lookupMethod(boolean optional, Class declaringClass, Str openModule(declaringClass); result.setAccessible(true); return result; - } catch (ReflectiveOperationException ex) { + } catch (ReflectiveOperationException | LinkageError ex) { if (optional) { return null; } @@ -238,4 +239,17 @@ public static void writeField(Class declaringClass, String fieldName, Object public static void writeStaticField(Class declaringClass, String fieldName, Object value) { writeField(declaringClass, fieldName, null, value); } + + /** + * Query a class value without worrying if the class can be properly linked. + */ + public static T linkageSafeQuery(Class clazz, T defaultValue, Function, T> f) { + var result = defaultValue; + try { + result = f.apply(clazz); + } catch (LinkageError e) { + /* nothing we can do */ + } + return result; + } } diff --git a/vm/mx.vm/mx_vm_benchmark.py b/vm/mx.vm/mx_vm_benchmark.py index 11ac1f5359850..568643c2bcd52 100644 --- a/vm/mx.vm/mx_vm_benchmark.py +++ b/vm/mx.vm/mx_vm_benchmark.py @@ -238,10 +238,11 @@ def __init__(self, vm: NativeImageVM, bm_suite: BenchmarkSuite | NativeImageBenc base_image_build_args += ['--gc=' + vm.gc] + ['-H:+SpawnIsolates'] if vm.native_architecture: base_image_build_args += ['-march=native'] + if vm.dynamic_access: + base_image_build_args += ['-H:+EnableDynamicAccess', '-J-XX:+PrintGC', '--exact-reachability-metadata', '--parallelism=12', + '--initialize-at-build-time=com.sun.jmx.mbeanserver.DefaultMXBeanMappingFactory$CollectionMapping', '--initialize-at-build-time=com.sun.jmx.mbeanserver.DefaultMXBeanMappingFactory$ArrayMapping'] if vm.analysis_context_sensitivity: base_image_build_args += ['-H:AnalysisContextSensitivity=' + vm.analysis_context_sensitivity, '-H:-RemoveSaturatedTypeFlows', '-H:+AliasArrayTypeFlows'] - if vm.no_inlining_before_analysis: - base_image_build_args += ['-H:-InlineBeforeAnalysis'] if vm.optimization_level: base_image_build_args += ['-' + vm.optimization_level] if vm.async_sampler: @@ -530,6 +531,7 @@ def __init__(self, name, config_name, extra_java_args=None, extra_launcher_args= self.is_llvm = False self.gc = None self.native_architecture = False + self.dynamic_access = False self.use_upx = False self.use_open_type_world = False self.use_compacting_gc = False @@ -545,7 +547,6 @@ def __init__(self, name, config_name, extra_java_args=None, extra_launcher_args= self.force_profile_inference = False self.profile_inference_debug = False self.analysis_context_sensitivity = None - self.no_inlining_before_analysis = False self.optimization_level = None self._configure_comma_separated_configs(config_name) if ',' in config_name: @@ -567,6 +568,8 @@ def config_name(self): config = [] if self.native_architecture is True: config += ["native-architecture"] + if self.dynamic_access is True: + config += ["dynamic-access"] if self.use_string_inlining is True: config += ["string-inlining"] if self.use_open_type_world is True: @@ -601,8 +604,6 @@ def config_name(self): if sensitivity.startswith("_"): sensitivity = sensitivity[1:] config += [sensitivity] - if self.no_inlining_before_analysis is True: - config += ["no-inline"] if self.jdk_profiles_collect is True: config += ["jdk-profiles-collect"] if self.adopted_jdk_pgo is True: @@ -638,7 +639,8 @@ def _configure_from_name(self, config_name): mx.abort(f"config_name must be set. Use 'default' for the default {self.__class__.__name__} configuration.") # This defines the allowed config names for NativeImageVM. The ones registered will be available via --jvm-config - rule = r'^(?Pnative-architecture-)?(?Pstring-inlining-)?(?Potw-)?(?Pcompacting-gc-)?(?Pgate-)?(?Pupx-)?(?Pquickbuild-)?(?Pg1gc-)?' \ + rule = r'^(?Pnative-architecture-)?(?Pstring-inlining-)?(?Potw-)?(?Pcompacting-gc-)?(?Pdynamic-access-)?' \ + r'(?Pgate-)?(?Pupx-)?(?Pquickbuild-)?(?Pg1gc-)?' \ r'(?Pllvm-)?(?Ppgo-|pgo-sampler-)?(?Pinline-)?' \ r'(?Pinsens-|allocsens-|1obj-|2obj1h-|3obj2h-|4obj3h-)?(?Pno-inline-)?(?Pjdk-profiles-collect-|adopted-jdk-pgo-)?' \ r'(?Pprofile-inference-feature-extraction-|profile-inference-pgo-|profile-inference-debug-)?(?Psafepoint-sampler-|async-sampler-)?(?PO0-|O1-|O2-|O3-|Os-)?(default-)?(?Pce-|ee-)?$' @@ -653,6 +655,10 @@ def _configure_from_name(self, config_name): mx.logv(f"'native-architecture' is enabled for {config_name}") self.native_architecture = True + if matching.group("dynamic_access") is not None: + mx.logv(f"'dynamic-access' is enabled for {config_name}") + self.dynamic_access = True + if matching.group("string_inlining") is not None: mx.logv(f"'string-inlining' is enabled for {config_name}") self.use_string_inlining = True @@ -788,14 +794,6 @@ def generate_profiling_package_prefixes(): else: mx.abort(f"Unknown configuration for optimization level: {olevel}") - if matching.group("no_inlining_before_analysis") is not None: - option = matching.group("no_inlining_before_analysis")[:-1] - if option == "no-inline": - mx.logv(f"not doing inlining before analysis for {config_name}") - self.no_inlining_before_analysis = True - else: - mx.abort(f"Unknown configuration for no inlining before analysis: {option}") - if matching.group("analysis_context_sensitivity") is not None: context_sensitivity = matching.group("analysis_context_sensitivity")[:-1] if context_sensitivity in ["insens", "allocsens"]: @@ -1936,18 +1934,15 @@ def register_graalvm_vms(): mx_polybenchmarks_benchmark.rules = polybenchmark_rules optimization_levels = ['O0', 'O1', 'O2', 'O3', 'Os'] - - # Inlining before analysis is done by default analysis_context_sensitivity = ['insens', 'allocsens', '1obj', '2obj1h', '3obj2h', '4obj3h'] - analysis_context_sensitivity_no_inline = [f"{analysis_component}-no-inline" for analysis_component in analysis_context_sensitivity] for short_name, config_suffix in [('niee', 'ee'), ('ni', 'ce')]: if any(component.short_name == short_name for component in mx_sdk_vm_impl.registered_graalvm_components(stage1=False)): - for main_config in ['default', 'gate', 'llvm', 'native-architecture'] + analysis_context_sensitivity + analysis_context_sensitivity_no_inline: + for main_config in ['default', 'gate', 'llvm', 'native-architecture', 'dynamic-access'] + analysis_context_sensitivity: final_config_name = f'{main_config}-{config_suffix}' mx_benchmark.add_java_vm(NativeImageVM('native-image', final_config_name, ['--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED']), _suite, 10) # ' ' force the empty O<> configs as well - for main_config in ['llvm', 'native-architecture', 'g1gc', 'native-architecture-g1gc', ''] + analysis_context_sensitivity + analysis_context_sensitivity_no_inline: + for main_config in ['llvm', 'native-architecture', 'g1gc', 'native-architecture-g1gc', 'dynamic-access', ''] + analysis_context_sensitivity: for optimization_level in optimization_levels: if len(main_config) > 0: final_config_name = f'{main_config}-{optimization_level}-{config_suffix}'