Skip to content

Commit cad8fc3

Browse files
committed
Use predicated configuration in NI
1 parent 474ad8b commit cad8fc3

File tree

4 files changed

+46
-3
lines changed

4 files changed

+46
-3
lines changed

sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/ConfigurationPredicate.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
import java.util.Objects;
2828

2929
public class ConfigurationPredicate {
30-
private String typeReachability;
30+
private final String typeReachability;
3131
public static ConfigurationPredicate DEFAULT_CONFIGRATION_PREDICATE = new ConfigurationPredicate("java.lang.Object");
3232

3333
public static ConfigurationPredicate create(String typeReachability) {
@@ -41,6 +41,10 @@ private ConfigurationPredicate(String typeReachability) {
4141
this.typeReachability = typeReachability;
4242
}
4343

44+
public String getTypeReachability() {
45+
return typeReachability;
46+
}
47+
4448
@Override
4549
public boolean equals(Object o) {
4650
if (this == o)

substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/trace/JniProcessor.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
import com.oracle.svm.configure.config.TypeConfiguration;
3737

3838
import jdk.vm.ci.meta.MetaUtil;
39-
import org.graalvm.nativeimage.impl.ConfigurationPredicate;
4039

4140
class JniProcessor extends AbstractProcessor {
4241
private final TypeConfiguration configuration;

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,22 +35,26 @@
3535
import java.util.Collections;
3636
import java.util.HashSet;
3737
import java.util.List;
38+
import java.util.Map;
3839
import java.util.Set;
3940
import java.util.concurrent.Callable;
4041
import java.util.concurrent.ConcurrentHashMap;
4142
import java.util.function.Predicate;
4243
import java.util.stream.Collectors;
4344

45+
import org.graalvm.nativeimage.hosted.Feature;
4446
import org.graalvm.nativeimage.hosted.Feature.DuringAnalysisAccess;
4547
import org.graalvm.nativeimage.impl.ConfigurationPredicate;
4648
import org.graalvm.nativeimage.impl.RuntimeReflectionSupport;
4749

4850
import com.oracle.graal.pointsto.meta.AnalysisType;
51+
import com.oracle.svm.core.TypeResult;
4952
import com.oracle.svm.core.hub.ClassForNameSupport;
5053
import com.oracle.svm.core.hub.DynamicHub;
5154
import com.oracle.svm.core.jdk.RecordSupport;
5255
import com.oracle.svm.core.util.UserError;
5356
import com.oracle.svm.core.util.VMError;
57+
import com.oracle.svm.hosted.FeatureImpl;
5458
import com.oracle.svm.hosted.FeatureImpl.DuringAnalysisAccessImpl;
5559
import com.oracle.svm.hosted.FeatureImpl.FeatureAccessImpl;
5660
import com.oracle.svm.hosted.substitute.SubstitutionReflectivityFilter;
@@ -72,6 +76,7 @@ public class ReflectionDataBuilder implements RuntimeReflectionSupport {
7276
private final Set<Field> reflectionFields = Collections.newSetFromMap(new ConcurrentHashMap<>());
7377

7478
/* Keep track of classes already processed for reflection. */
79+
private final Map<String, List<Runnable>> reachabilityHandlers = new ConcurrentHashMap<>();
7580
private final Set<Class<?>> processedClasses = new HashSet<>();
7681

7782
private final ReflectionDataAccessors accessors;
@@ -111,6 +116,19 @@ private static DynamicHub.ReflectionData getArrayReflectionData() {
111116
@Override
112117
public void register(ConfigurationPredicate predicate, Class<?>... classes) {
113118
checkNotSealed();
119+
registerPredicated(predicate, () -> registerClasses(classes));
120+
}
121+
122+
private void registerPredicated(ConfigurationPredicate predicate, Runnable runnable) {
123+
if (ConfigurationPredicate.DEFAULT_CONFIGRATION_PREDICATE.equals(predicate)) {
124+
runnable.run();
125+
} else {
126+
List<Runnable> handlers = reachabilityHandlers.computeIfAbsent(predicate.getTypeReachability(), key -> new ArrayList<>());
127+
handlers.add(runnable);
128+
}
129+
}
130+
131+
private void registerClasses(Class<?>[] classes) {
114132
for (Class<?> clazz : classes) {
115133
if (reflectionClasses.add(clazz)) {
116134
modifiedClasses.add(clazz);
@@ -121,6 +139,10 @@ public void register(ConfigurationPredicate predicate, Class<?>... classes) {
121139
@Override
122140
public void register(ConfigurationPredicate predicate, Executable... methods) {
123141
checkNotSealed();
142+
registerPredicated(predicate, () -> registerMethods(methods));
143+
}
144+
145+
private void registerMethods(Executable[] methods) {
124146
for (Executable method : methods) {
125147
if (reflectionMethods.add(method)) {
126148
modifiedClasses.add(method.getDeclaringClass());
@@ -131,6 +153,10 @@ public void register(ConfigurationPredicate predicate, Executable... methods) {
131153
@Override
132154
public void register(ConfigurationPredicate predicate, boolean finalIsWritable, Field... fields) {
133155
checkNotSealed();
156+
registerPredicated(predicate, () -> registerFields(fields));
157+
}
158+
159+
private void registerFields(Field[] fields) {
134160
// Unsafe and write accesses are always enabled for fields because accessors use Unsafe.
135161
for (Field field : fields) {
136162
if (reflectionFields.add(field)) {
@@ -145,8 +171,17 @@ private void checkNotSealed() {
145171
}
146172
}
147173

174+
void registerPredicatedConfig(Feature.BeforeAnalysisAccess b) {
175+
for (Map.Entry<String, List<Runnable>> stringListEntry : reachabilityHandlers.entrySet()) {
176+
TypeResult<Class<?>> typeResult = ((FeatureImpl.BeforeAnalysisAccessImpl) b).getImageClassLoader().findClass(stringListEntry.getKey());
177+
b.registerReachabilityHandler(access -> stringListEntry.getValue().forEach(Runnable::run), typeResult.get());
178+
}
179+
reachabilityHandlers.clear();
180+
}
181+
148182
protected void duringAnalysis(DuringAnalysisAccess a) {
149183
DuringAnalysisAccessImpl access = (DuringAnalysisAccessImpl) a;
184+
registerPredicatedConfig(a);
150185
processReachableTypes(access);
151186
processRegisteredElements(access);
152187
}

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
*/
2525
package com.oracle.svm.reflect.hosted;
2626

27-
import com.oracle.svm.core.configure.ConfigurationFile;
2827
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
2928
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
3029
import org.graalvm.compiler.phases.util.Providers;
@@ -34,6 +33,7 @@
3433
import com.oracle.graal.pointsto.meta.AnalysisUniverse;
3534
import com.oracle.svm.core.ParsingReason;
3635
import com.oracle.svm.core.annotate.AutomaticFeature;
36+
import com.oracle.svm.core.configure.ConfigurationFile;
3737
import com.oracle.svm.core.configure.ConfigurationFiles;
3838
import com.oracle.svm.core.configure.ReflectionConfigurationParser;
3939
import com.oracle.svm.core.graal.GraalFeature;
@@ -91,6 +91,11 @@ public void duringSetup(DuringSetupAccess a) {
9191
annotationSubstitutions = ((Inflation) access.getBigBang()).getAnnotationSubstitutionProcessor();
9292
}
9393

94+
@Override
95+
public void beforeAnalysis(BeforeAnalysisAccess access) {
96+
reflectionData.registerPredicatedConfig(access);
97+
}
98+
9499
@Override
95100
public void duringAnalysis(DuringAnalysisAccess access) {
96101
reflectionData.duringAnalysis(access);

0 commit comments

Comments
 (0)