Skip to content

Commit 0001744

Browse files
committed
[GR-67368] Registering function descriptors for runtime foreign access via API during Feature#afterRegistration
PullRequest: graal/21545
2 parents cdf3cdc + 72396b1 commit 0001744

File tree

3 files changed

+42
-31
lines changed

3 files changed

+42
-31
lines changed

substratevm/src/com.oracle.svm.hosted.foreign/src/com/oracle/svm/hosted/foreign/ForeignFunctionsFeature.java

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
import org.graalvm.nativeimage.hosted.RuntimeReflection;
6060
import org.graalvm.nativeimage.impl.ConfigurationCondition;
6161
import org.graalvm.nativeimage.impl.RuntimeForeignAccessSupport;
62+
import org.graalvm.nativeimage.impl.RuntimeReflectionSupport;
6263
import org.graalvm.word.Pointer;
6364
import org.graalvm.word.UnsignedWord;
6465

@@ -206,12 +207,14 @@ private final class RuntimeForeignAccessSupportImpl extends ConditionalConfigura
206207

207208
private final Lookup implLookup = ReflectionUtil.readStaticField(MethodHandles.Lookup.class, "IMPL_LOOKUP");
208209

209-
private final AnalysisMetaAccess analysisMetaAccess;
210-
private final AnalysisUniverse universe;
210+
private AnalysisMetaAccess analysisMetaAccess;
211211

212-
RuntimeForeignAccessSupportImpl(AnalysisMetaAccess analysisMetaAccess, AnalysisUniverse analysisUniverse) {
213-
this.analysisMetaAccess = analysisMetaAccess;
214-
this.universe = analysisUniverse;
212+
RuntimeForeignAccessSupportImpl() {
213+
}
214+
215+
void duringSetup(AnalysisMetaAccess metaAccess, AnalysisUniverse analysisUniverse) {
216+
this.analysisMetaAccess = metaAccess;
217+
setUniverse(analysisUniverse);
215218
}
216219

217220
@Override
@@ -220,7 +223,7 @@ public void registerForDowncall(ConfigurationCondition condition, FunctionDescri
220223
try {
221224
LinkerOptions linkerOptions = LinkerOptions.forDowncall(desc, options);
222225
SharedDesc sharedDesc = new SharedDesc(desc, linkerOptions);
223-
registerConditionalConfiguration(condition, _ -> universe.getBigbang().postTask(_ -> createStub(DowncallStubFactory.INSTANCE, sharedDesc)));
226+
runConditionalTask(condition, _ -> createStub(DowncallStubFactory.INSTANCE, sharedDesc));
224227
} catch (IllegalArgumentException e) {
225228
throw UserError.abort(e, "Could not register downcall");
226229
}
@@ -232,7 +235,7 @@ public void registerForUpcall(ConfigurationCondition condition, FunctionDescript
232235
try {
233236
LinkerOptions linkerOptions = LinkerOptions.forUpcall(desc, options);
234237
SharedDesc sharedDesc = new SharedDesc(desc, linkerOptions);
235-
registerConditionalConfiguration(condition, _ -> universe.getBigbang().postTask(_ -> createStub(UpcallStubFactory.INSTANCE, sharedDesc)));
238+
runConditionalTask(condition, _ -> createStub(UpcallStubFactory.INSTANCE, sharedDesc));
236239
} catch (IllegalArgumentException e) {
237240
throw UserError.abort(e, "Could not register upcall");
238241
}
@@ -256,11 +259,11 @@ public void registerForDirectUpcall(ConfigurationCondition condition, MethodHand
256259
try {
257260
LinkerOptions linkerOptions = LinkerOptions.forUpcall(desc, options);
258261
DirectUpcallDesc directUpcallDesc = new DirectUpcallDesc(target, directMethodHandleDesc, desc, linkerOptions);
259-
registerConditionalConfiguration(condition, _ -> universe.getBigbang().postTask(_ -> {
260-
RuntimeReflection.register(method);
262+
runConditionalTask(condition, _ -> {
263+
ImageSingletons.lookup(RuntimeReflectionSupport.class).register(ConfigurationCondition.alwaysTrue(), false, method);
261264
createStub(UpcallStubFactory.INSTANCE, directUpcallDesc.toSharedDesc());
262265
createStub(DirectUpcallStubFactory.INSTANCE, directUpcallDesc);
263-
}));
266+
});
264267
} catch (IllegalArgumentException e) {
265268
throw UserError.abort(e, "Could not register direct upcall");
266269
}
@@ -383,7 +386,8 @@ public boolean isInConfiguration(IsInConfigurationAccess access) {
383386
public void afterRegistration(AfterRegistrationAccess access) {
384387
abiUtils = AbiUtils.create();
385388
foreignFunctionsRuntime = new ForeignFunctionsRuntime(abiUtils);
386-
389+
accessSupport = new RuntimeForeignAccessSupportImpl();
390+
ImageSingletons.add(RuntimeForeignAccessSupport.class, accessSupport);
387391
ImageSingletons.add(AbiUtils.class, abiUtils);
388392
ImageSingletons.add(ForeignSupport.class, foreignFunctionsRuntime);
389393
ImageSingletons.add(ForeignFunctionsRuntime.class, foreignFunctionsRuntime);
@@ -392,8 +396,7 @@ public void afterRegistration(AfterRegistrationAccess access) {
392396
@Override
393397
public void duringSetup(DuringSetupAccess a) {
394398
var access = (FeatureImpl.DuringSetupAccessImpl) a;
395-
accessSupport = new RuntimeForeignAccessSupportImpl(access.getMetaAccess(), access.getUniverse());
396-
ImageSingletons.add(RuntimeForeignAccessSupport.class, accessSupport);
399+
accessSupport.duringSetup(access.getMetaAccess(), access.getUniverse());
397400
if (SubstrateOptions.isSharedArenaSupportEnabled()) {
398401
ImageSingletons.add(SharedArenaSupport.class, new SharedArenaSupportImpl());
399402
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ConditionalConfigurationRegistry.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@
2727
import java.util.Collection;
2828
import java.util.Map;
2929
import java.util.Objects;
30+
import java.util.Set;
3031
import java.util.concurrent.ConcurrentHashMap;
3132
import java.util.concurrent.ConcurrentLinkedQueue;
3233
import java.util.function.Consumer;
3334

35+
import com.oracle.graal.pointsto.meta.AnalysisUniverse;
3436
import org.graalvm.nativeimage.hosted.Feature;
3537
import org.graalvm.nativeimage.impl.ConfigurationCondition;
3638

@@ -40,7 +42,29 @@
4042
public abstract class ConditionalConfigurationRegistry {
4143
private Feature.BeforeAnalysisAccess beforeAnalysisAccess;
4244
private SVMHost hostVM;
45+
protected AnalysisUniverse universe;
4346
private final Map<Class<?>, Collection<Runnable>> pendingReachabilityHandlers = new ConcurrentHashMap<>();
47+
private final Set<ConditionalTask> pendingConditionalTasks = ConcurrentHashMap.newKeySet();
48+
49+
record ConditionalTask(ConfigurationCondition condition, Consumer<ConfigurationCondition> task) {
50+
}
51+
52+
protected void runConditionalTask(ConfigurationCondition condition, Consumer<ConfigurationCondition> task) {
53+
if (universe != null) {
54+
registerConditionalConfiguration(condition, (cnd) -> universe.getBigbang().postTask(debugContext -> task.accept(cnd)));
55+
} else {
56+
pendingConditionalTasks.add(new ConditionalTask(condition, task));
57+
VMError.guarantee(universe == null, "There shouldn't be a race condition on Feature.duringSetup.");
58+
}
59+
}
60+
61+
protected void setUniverse(AnalysisUniverse analysisUniverse) {
62+
this.universe = analysisUniverse;
63+
for (var conditionalTask : pendingConditionalTasks) {
64+
registerConditionalConfiguration(conditionalTask.condition, (cnd) -> universe.getBigbang().postTask(debug -> conditionalTask.task.accept(cnd)));
65+
}
66+
pendingConditionalTasks.clear();
67+
}
4468

4569
protected void registerConditionalConfiguration(ConfigurationCondition condition, Consumer<ConfigurationCondition> consumer) {
4670
Objects.requireNonNull(condition, "Cannot use null value as condition for conditional configuration. Please ensure that you register a non-null condition.");

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

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@
119119

120120
public class ReflectionDataBuilder extends ConditionalConfigurationRegistry implements RuntimeReflectionSupport, ReflectionHostedSupport {
121121
private AnalysisMetaAccess metaAccess;
122-
private AnalysisUniverse universe;
123122
private final SubstrateAnnotationExtractor annotationExtractor;
124123
private BeforeAnalysisAccessImpl analysisAccess;
125124
private final ClassForNameSupport classForNameSupport;
@@ -163,11 +162,6 @@ public class ReflectionDataBuilder extends ConditionalConfigurationRegistry impl
163162
private Map<Type, Set<Integer>> processedTypes = new ConcurrentHashMap<>();
164163
private Map<Class<?>, Set<Method>> pendingRecordClasses;
165164

166-
record ConditionalTask(ConfigurationCondition condition, Consumer<ConfigurationCondition> task) {
167-
}
168-
169-
private final Set<ConditionalTask> pendingConditionalTasks = ConcurrentHashMap.newKeySet();
170-
171165
// Annotations handling
172166
private final Map<AnnotatedElement, AnnotationValue[]> filteredAnnotations = new ConcurrentHashMap<>();
173167
private final Map<AnalysisMethod, AnnotationValue[][]> filteredParameterAnnotations = new ConcurrentHashMap<>();
@@ -181,11 +175,7 @@ record ConditionalTask(ConfigurationCondition condition, Consumer<ConfigurationC
181175

182176
public void duringSetup(AnalysisMetaAccess analysisMetaAccess, AnalysisUniverse analysisUniverse) {
183177
this.metaAccess = analysisMetaAccess;
184-
this.universe = analysisUniverse;
185-
for (var conditionalTask : pendingConditionalTasks) {
186-
registerConditionalConfiguration(conditionalTask.condition, (cnd) -> universe.getBigbang().postTask(debug -> conditionalTask.task.accept(cnd)));
187-
}
188-
pendingConditionalTasks.clear();
178+
setUniverse(analysisUniverse);
189179
if (ImageLayerBuildingSupport.buildingImageLayer()) {
190180
layeredReflectionDataBuilder = LayeredReflectionDataBuilder.singleton();
191181
}
@@ -199,13 +189,7 @@ private void runConditionalInAnalysisTask(ConfigurationCondition condition, Cons
199189
if (sealed) {
200190
throw new UnsupportedFeatureException("Too late to add classes, methods, and fields for reflective access. Registration must happen in a Feature before the analysis has finished.");
201191
}
202-
203-
if (universe != null) {
204-
registerConditionalConfiguration(condition, (cnd) -> universe.getBigbang().postTask(debug -> task.accept(cnd)));
205-
} else {
206-
pendingConditionalTasks.add(new ConditionalTask(condition, task));
207-
VMError.guarantee(universe == null, "There shouldn't be a race condition on Feature.duringSetup.");
208-
}
192+
runConditionalTask(condition, task);
209193
}
210194

211195
private void setQueryFlag(Class<?> clazz, int flag) {

0 commit comments

Comments
 (0)