diff --git a/sdk/src/org.graalvm.nativeimage/snapshot.sigtest b/sdk/src/org.graalvm.nativeimage/snapshot.sigtest index 95f7d6e73bc7..ef23e446d560 100644 --- a/sdk/src/org.graalvm.nativeimage/snapshot.sigtest +++ b/sdk/src/org.graalvm.nativeimage/snapshot.sigtest @@ -1051,6 +1051,7 @@ CLSS public abstract interface static org.graalvm.nativeimage.hosted.Feature$Dur outer org.graalvm.nativeimage.hosted.Feature intf org.graalvm.nativeimage.hosted.Feature$FeatureAccess meth public abstract void registerObjectReplacer(java.util.function.Function) +meth public abstract void registerObjectReachabilityHandler(java.util.function.Consumer,java.lang.Class) CLSS public abstract interface static org.graalvm.nativeimage.hosted.Feature$FeatureAccess outer org.graalvm.nativeimage.hosted.Feature diff --git a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/Feature.java b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/Feature.java index 3222eb2c61d7..4b4dbf46daa8 100644 --- a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/Feature.java +++ b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/Feature.java @@ -191,6 +191,15 @@ interface DuringSetupAccess extends FeatureAccess { * @since 19.0 */ void registerObjectReplacer(Function replacer); + + /** + * Register a callback that is executed when an object of type {@code clazz}, or any of its + * subtypes, is marked as reachable during heap scanning. The callback may be executed for + * the same object by multiple worker threads concurrently. + * + * @since 24.2 + */ + void registerObjectReachabilityHandler(Consumer callback, Class clazz); } /** diff --git a/substratevm/CHANGELOG.md b/substratevm/CHANGELOG.md index 6fcfce6e8539..d1ab827a497c 100644 --- a/substratevm/CHANGELOG.md +++ b/substratevm/CHANGELOG.md @@ -3,6 +3,7 @@ This changelog summarizes major changes to GraalVM Native Image. ## GraalVM for JDK 24 (Internal Version 24.2.0) +* (GR-59717) Added `DuringSetupAccess.registerObjectReachabilityHandler` to allow registering a callback that is executed when an object of a specified type is marked as reachable during heap scanning. * (GR-55708) (Alibaba contribution) Support for running premain methods of Java agents at runtime as an experimental feature. At build time, `-H:PremainClasses` is used to set the premain classes. At runtime, premain runtime options are set along with main class' arguments in the format of `-XXpremain:[class]:[options]`. * (GR-54476): Issue a deprecation warning on first use of a legacy `graal.` prefix (see GR-49960 in [Compiler changelog](../compiler/CHANGELOG.md)). diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java index 77fec49a581f..3307c89bb58c 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java @@ -53,9 +53,7 @@ import org.graalvm.nativeimage.hosted.RuntimeReflection; import com.oracle.graal.pointsto.BigBang; -import com.oracle.graal.pointsto.ObjectScanner; import com.oracle.graal.pointsto.meta.AnalysisType; -import com.oracle.graal.pointsto.meta.ObjectReachableCallback; import com.oracle.graal.pointsto.reports.CallTreePrinter; import com.oracle.svm.core.SubstrateTargetDescription; import com.oracle.svm.core.hub.ClassForNameSupport; @@ -256,8 +254,8 @@ public void duringSetup(DuringSetupAccess access) { DuringSetupAccessImpl accessImpl = (DuringSetupAccessImpl) access; accessImpl.registerClassReachabilityListener(this::registerPhaseStatistics); optionCollector = new OptionCollector(LibGraalEntryPoints.vmOptionDescriptors); - accessImpl.registerObjectReachableCallback(OptionKey.class, optionCollector::doCallback); - accessImpl.registerObjectReachableCallback(loadClassOrFail(OptionKey.class.getName()), optionCollector::doCallback); + access.registerObjectReachabilityHandler(optionCollector::accept, OptionKey.class); + access.registerObjectReachabilityHandler(optionCollector::accept, loadClassOrFail(OptionKey.class.getName())); GetJNIConfig.register(loader); } @@ -270,7 +268,7 @@ public void duringSetup(DuringSetupAccess access) { * compiler options are instances of {@link OptionKey} loaded by the * {@code HostedLibGraalClassLoader}. */ - private class OptionCollector implements ObjectReachableCallback { + private class OptionCollector implements Consumer { private final Set options = Collections.newSetFromMap(new ConcurrentHashMap<>()); /** @@ -297,7 +295,7 @@ private class OptionCollector implements ObjectReachableCallback { } @Override - public void doCallback(DuringAnalysisAccess access, Object option, ObjectScanner.ScanReason reason) { + public void accept(Object option) { if (sealed) { VMError.guarantee(options.contains(option), "All options must have been discovered during static analysis: %s", option); } else { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/FeatureImpl.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/FeatureImpl.java index e8331c298511..f08787c42a03 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/FeatureImpl.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/FeatureImpl.java @@ -317,6 +317,12 @@ public void registerObjectReachableCallback(Class clazz, ObjectReachableC getMetaAccess().lookupJavaType(clazz).registerObjectReachableCallback(callback); } + @Override + public void registerObjectReachabilityHandler(Consumer callback, Class clazz) { + ObjectReachableCallback wrapper = (access, obj, reason) -> callback.accept(obj); + getMetaAccess().lookupJavaType(clazz).registerObjectReachableCallback(wrapper); + } + public void registerSubstitutionProcessor(SubstitutionProcessor substitution) { getUniverse().registerFeatureSubstitution(substitution); }