From 52af79ee4fb9561214d699a095253020e4d2106b Mon Sep 17 00:00:00 2001 From: Tom Shull Date: Tue, 30 Sep 2025 18:51:52 +0200 Subject: [PATCH] Make SingletonLayeredCallbacks use generics. --- .../svm/core/IsolateArgumentParser.java | 15 ++++++------ .../svm/core/RuntimeAssertionsSupport.java | 24 +++++++++---------- .../svm/core/SubstrateTargetDescription.java | 12 ++++------ .../svm/core/c/locale/LocaleSupport.java | 12 ++++------ .../oracle/svm/core/config/ObjectLayout.java | 13 ++++------ .../src/com/oracle/svm/core/heap/GCCause.java | 10 ++++---- .../svm/core/hub/ClassForNameSupport.java | 19 +++++++-------- .../LayeredReflectionMetadataSingleton.java | 17 +++++++------ .../com/oracle/svm/core/jdk/Resources.java | 19 +++++++-------- .../oracle/svm/core/traits/BuiltinTraits.java | 4 ++-- .../InjectedSingletonLayeredCallbacks.java | 8 +++++-- .../traits/SingletonLayeredCallbacks.java | 12 +++++----- .../hosted/ImageSingletonsSupportImpl.java | 14 +++++++---- .../svm/hosted/OpenTypeWorldFeature.java | 8 +++---- .../CrossLayerFieldUpdaterFeature.java | 10 ++++---- .../LayeredFieldValueTransformerSupport.java | 11 ++++----- .../SVMImageLayerSingletonLoader.java | 2 +- .../imagelayer/SVMImageLayerWriter.java | 8 ++++--- .../thread/HostedJavaThreadsFeature.java | 12 +++++----- 19 files changed, 113 insertions(+), 117 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/IsolateArgumentParser.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/IsolateArgumentParser.java index 6408277806fb..dc3de7d0332c 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/IsolateArgumentParser.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/IsolateArgumentParser.java @@ -675,31 +675,30 @@ static class LayeredCallbacks extends SingletonLayeredCallbacksSupplier { @Override public SingletonTrait getLayeredCallbacksTrait() { - return new SingletonTrait(SingletonTraitKind.LAYERED_CALLBACKS, new SingletonLayeredCallbacks() { + return new SingletonTrait(SingletonTraitKind.LAYERED_CALLBACKS, new SingletonLayeredCallbacks() { @Override - public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, Object singleton) { + public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, LayeredOptionInfo singleton) { if (ImageLayerBuildingSupport.firstImageBuild()) { writer.writeInt("numOptions", IsolateArgumentParser.getOptionCount()); writer.writeStringList("optionNames", IsolateArgumentParser.getOptions().stream().map(OptionKey::getName).toList()); } else { - var metadata = (LayeredOptionInfo) singleton; - writer.writeInt("numOptions", metadata.getNumOptions()); - writer.writeStringList("optionNames", metadata.optionNames); + writer.writeInt("numOptions", singleton.getNumOptions()); + writer.writeStringList("optionNames", singleton.optionNames); } return LayeredImageSingleton.PersistFlags.CREATE; } @Override - public Class getSingletonInstantiator() { + public Class> getSingletonInstantiator() { return SingletonInstantiator.class; } }); } } - static class SingletonInstantiator implements SingletonLayeredCallbacks.LayeredSingletonInstantiator { + static class SingletonInstantiator implements SingletonLayeredCallbacks.LayeredSingletonInstantiator { @Override - public Object createFromLoader(ImageSingletonLoader loader) { + public LayeredOptionInfo createFromLoader(ImageSingletonLoader loader) { int numOptions = loader.readInt("numOptions"); var optionNames = Collections.unmodifiableList(loader.readStringList("optionNames")); return new LayeredOptionInfo(numOptions, optionNames); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/RuntimeAssertionsSupport.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/RuntimeAssertionsSupport.java index 00c64b32d7ae..111b4f507b24 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/RuntimeAssertionsSupport.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/RuntimeAssertionsSupport.java @@ -229,14 +229,13 @@ public boolean getDefaultSystemAssertionStatus() { static class LayeredCallbacks extends SingletonLayeredCallbacksSupplier { @Override public SingletonTrait getLayeredCallbacksTrait() { - SingletonLayeredCallbacks action = new SingletonLayeredCallbacks() { + var action = new SingletonLayeredCallbacks() { @Override - public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, Object singleton) { - RuntimeAssertionsSupport runtimeAssertionsSupport = (RuntimeAssertionsSupport) singleton; - persistAssertionStatus(writer, PACKAGE, runtimeAssertionsSupport.packageAssertionStatus); - persistAssertionStatus(writer, CLASS, runtimeAssertionsSupport.classAssertionStatus); - writer.writeInt(DEFAULT_ASSERTION_STATUS, runtimeAssertionsSupport.defaultAssertionStatus ? 1 : 0); - writer.writeInt(SYSTEM_ASSERTION_STATUS, runtimeAssertionsSupport.systemAssertionStatus ? 1 : 0); + public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, RuntimeAssertionsSupport singleton) { + persistAssertionStatus(writer, PACKAGE, singleton.packageAssertionStatus); + persistAssertionStatus(writer, CLASS, singleton.classAssertionStatus); + writer.writeInt(DEFAULT_ASSERTION_STATUS, singleton.defaultAssertionStatus ? 1 : 0); + writer.writeInt(SYSTEM_ASSERTION_STATUS, singleton.systemAssertionStatus ? 1 : 0); return PersistFlags.CALLBACK_ON_REGISTRATION; } @@ -252,12 +251,11 @@ private void persistAssertionStatus(ImageSingletonWriter writer, String type, Ma } @Override - public void onSingletonRegistration(ImageSingletonLoader loader, Object singleton) { - RuntimeAssertionsSupport runtimeAssertionsSupport = (RuntimeAssertionsSupport) singleton; - checkMaps(loadAssertionStatus(loader, PACKAGE), runtimeAssertionsSupport.packageAssertionStatus); - checkMaps(loadAssertionStatus(loader, CLASS), runtimeAssertionsSupport.classAssertionStatus); - checkBoolean(runtimeAssertionsSupport.defaultAssertionStatus, loader, DEFAULT_ASSERTION_STATUS); - checkBoolean(runtimeAssertionsSupport.systemAssertionStatus, loader, SYSTEM_ASSERTION_STATUS); + public void onSingletonRegistration(ImageSingletonLoader loader, RuntimeAssertionsSupport singleton) { + checkMaps(loadAssertionStatus(loader, PACKAGE), singleton.packageAssertionStatus); + checkMaps(loadAssertionStatus(loader, CLASS), singleton.classAssertionStatus); + checkBoolean(singleton.defaultAssertionStatus, loader, DEFAULT_ASSERTION_STATUS); + checkBoolean(singleton.systemAssertionStatus, loader, SYSTEM_ASSERTION_STATUS); } private void checkBoolean(boolean currentLayerAssertionStatus, ImageSingletonLoader loader, String assertionStatusKey) { diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateTargetDescription.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateTargetDescription.java index 462647dae63e..2459619008c9 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateTargetDescription.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateTargetDescription.java @@ -75,19 +75,17 @@ public EnumSet getRuntimeCheckedCPUFeatures() { static class LayeredCallbacks extends SingletonLayeredCallbacksSupplier { @Override public SingletonTrait getLayeredCallbacksTrait() { - SingletonLayeredCallbacks action = new SingletonLayeredCallbacks() { + var action = new SingletonLayeredCallbacks() { @Override - public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, Object singleton) { - SubstrateTargetDescription substrateTargetDescription = (SubstrateTargetDescription) singleton; - writer.writeStringList(RUNTIME_CHECKED_CPU_FEATURES, getCPUFeaturesList(substrateTargetDescription)); + public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, SubstrateTargetDescription singleton) { + writer.writeStringList(RUNTIME_CHECKED_CPU_FEATURES, getCPUFeaturesList(singleton)); return PersistFlags.CALLBACK_ON_REGISTRATION; } @Override - public void onSingletonRegistration(ImageSingletonLoader loader, Object singleton) { - SubstrateTargetDescription substrateTargetDescription = (SubstrateTargetDescription) singleton; + public void onSingletonRegistration(ImageSingletonLoader loader, SubstrateTargetDescription singleton) { List previousLayerRuntimeCheckedCPUFeatures = loader.readStringList(RUNTIME_CHECKED_CPU_FEATURES); - List currentLayerRuntimeCheckedCPUFeatures = getCPUFeaturesList(substrateTargetDescription); + List currentLayerRuntimeCheckedCPUFeatures = getCPUFeaturesList(singleton); VMError.guarantee(previousLayerRuntimeCheckedCPUFeatures.equals(currentLayerRuntimeCheckedCPUFeatures), "The runtime checked CPU Features should be consistent across layers. The previous layer CPU Features were %s, but the current layer are %s", previousLayerRuntimeCheckedCPUFeatures, currentLayerRuntimeCheckedCPUFeatures); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/c/locale/LocaleSupport.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/c/locale/LocaleSupport.java index 2e2b4046ca07..1b57b0e6b00d 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/c/locale/LocaleSupport.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/c/locale/LocaleSupport.java @@ -218,19 +218,17 @@ private static final class State { static class LayeredCallbacks extends SingletonLayeredCallbacksSupplier { @Override public SingletonTrait getLayeredCallbacksTrait() { - SingletonLayeredCallbacks action = new SingletonLayeredCallbacks() { + var action = new SingletonLayeredCallbacks() { @Override - public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, Object singleton) { - LocaleSupport localeSupport = (LocaleSupport) singleton; - writer.writeString(LOCALE, getLocaleString(localeSupport.locale)); + public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, LocaleSupport singleton) { + writer.writeString(LOCALE, getLocaleString(singleton.locale)); return PersistFlags.CALLBACK_ON_REGISTRATION; } @Override - public void onSingletonRegistration(ImageSingletonLoader loader, Object singleton) { - LocaleSupport localeSupport = (LocaleSupport) singleton; + public void onSingletonRegistration(ImageSingletonLoader loader, LocaleSupport singleton) { String previousLocale = loader.readString(LOCALE); - String currentLocale = getLocaleString(localeSupport.locale); + String currentLocale = getLocaleString(singleton.locale); VMError.guarantee(currentLocale.equals(previousLocale), "The locale data should be consistent across layers. The previous layer locale data were %s, but the locale data are %s", previousLocale, currentLocale); } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/config/ObjectLayout.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/config/ObjectLayout.java index 88c2ba9d118f..d8ae4af992e9 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/config/ObjectLayout.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/config/ObjectLayout.java @@ -340,20 +340,17 @@ public enum IdentityHashMode { static class LayeredCallbacks extends SingletonLayeredCallbacksSupplier { @Override public SingletonTrait getLayeredCallbacksTrait() { - SingletonLayeredCallbacks action = new SingletonLayeredCallbacks() { + var action = new SingletonLayeredCallbacks() { @Override - public PersistFlags doPersist(ImageSingletonWriter writer, Object singleton) { - ObjectLayout objectLayout = (ObjectLayout) singleton; - List currentValues = objectLayout.getCurrentValues(); + public PersistFlags doPersist(ImageSingletonWriter writer, ObjectLayout singleton) { + List currentValues = singleton.getCurrentValues(); writer.writeIntList("priorValues", currentValues); return PersistFlags.CALLBACK_ON_REGISTRATION; } @Override - public void onSingletonRegistration(ImageSingletonLoader loader, Object singleton) { - ObjectLayout objectLayout = (ObjectLayout) singleton; - - List currentValues = objectLayout.getCurrentValues(); + public void onSingletonRegistration(ImageSingletonLoader loader, ObjectLayout singleton) { + List currentValues = singleton.getCurrentValues(); List priorValues = loader.readIntList("priorValues"); var numFields = Arrays.stream(ObjectLayout.class.getDeclaredFields()).filter(Predicate.not(Field::isSynthetic)).count(); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/GCCause.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/GCCause.java index da4aa30eb4b1..5e235257ba55 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/GCCause.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/GCCause.java @@ -184,9 +184,9 @@ static class LayeredCallbacks extends SingletonLayeredCallbacksSupplier { @Override public SingletonTrait getLayeredCallbacksTrait() { - return new SingletonTrait(SingletonTraitKind.LAYERED_CALLBACKS, new SingletonLayeredCallbacks() { + return new SingletonTrait(SingletonTraitKind.LAYERED_CALLBACKS, new SingletonLayeredCallbacks() { @Override - public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, Object singleton) { + public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, GCCauseFeature singleton) { List gcCauses; if (ImageLayerBuildingSupport.buildingInitialLayer()) { gcCauses = GCCause.getGCCauses().stream().map(gcCause -> { @@ -198,7 +198,7 @@ public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, } }).toList(); } else { - gcCauses = ((GCCauseFeature) singleton).registeredGCCauses; + gcCauses = singleton.registeredGCCauses; } writer.writeStringList("registeredGCCauses", gcCauses); @@ -206,8 +206,8 @@ public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, } @Override - public void onSingletonRegistration(ImageSingletonLoader loader, Object singleton) { - ((GCCauseFeature) singleton).registeredGCCauses = Collections.unmodifiableList(loader.readStringList("registeredGCCauses")); + public void onSingletonRegistration(ImageSingletonLoader loader, GCCauseFeature singleton) { + singleton.registeredGCCauses = Collections.unmodifiableList(loader.readStringList("registeredGCCauses")); } }); } 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 645a3b751e38..1081acd1a355 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 @@ -511,23 +511,22 @@ public static boolean canUnsafeInstantiateAsInstance(DynamicHub hub) { static class LayeredCallbacks extends SingletonLayeredCallbacksSupplier { @Override public SingletonTrait getLayeredCallbacksTrait() { - return new SingletonTrait(SingletonTraitKind.LAYERED_CALLBACKS, new SingletonLayeredCallbacks() { + return new SingletonTrait(SingletonTraitKind.LAYERED_CALLBACKS, new SingletonLayeredCallbacks() { @Override - public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, Object singleton) { - ClassForNameSupport support = (ClassForNameSupport) singleton; + public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, ClassForNameSupport singleton) { List classNames = new ArrayList<>(); List classStates = new ArrayList<>(); - Set unsafeNames = new HashSet<>(support.previousLayerUnsafe); + Set unsafeNames = new HashSet<>(singleton.previousLayerUnsafe); - var cursor = support.knownClasses.getEntries(); + var cursor = singleton.knownClasses.getEntries(); while (cursor.advance()) { classNames.add(cursor.getKey()); boolean isNegativeQuery = cursor.getValue().getValueUnconditionally() == NEGATIVE_QUERY; classStates.add(!isNegativeQuery); } - for (var entry : support.previousLayerClasses.entrySet()) { + for (var entry : singleton.previousLayerClasses.entrySet()) { /* * If a complete entry overwrites a negative query from a previous layer, * the previousLayerClasses map entry needs to be skipped to register the @@ -539,7 +538,7 @@ public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, } } - support.unsafeInstantiatedClasses.getKeys().iterator().forEachRemaining(c -> unsafeNames.add(c.getName())); + singleton.unsafeInstantiatedClasses.getKeys().iterator().forEachRemaining(c -> unsafeNames.add(c.getName())); writer.writeStringList(CLASSES_REGISTERED, classNames); writer.writeBoolList(CLASSES_REGISTERED_STATES, classStates); @@ -554,16 +553,16 @@ public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, } @Override - public Class getSingletonInstantiator() { + public Class> getSingletonInstantiator() { return SingletonInstantiator.class; } }); } } - static class SingletonInstantiator implements SingletonLayeredCallbacks.LayeredSingletonInstantiator { + static class SingletonInstantiator implements SingletonLayeredCallbacks.LayeredSingletonInstantiator { @Override - public Object createFromLoader(ImageSingletonLoader loader) { + public ClassForNameSupport createFromLoader(ImageSingletonLoader loader) { List previousLayerClassKeys = loader.readStringList(CLASSES_REGISTERED); List previousLayerClassStates = loader.readBoolList(CLASSES_REGISTERED_STATES); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/LayeredReflectionMetadataSingleton.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/LayeredReflectionMetadataSingleton.java index e8c437f2ad03..c46e4f7ea217 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/LayeredReflectionMetadataSingleton.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/LayeredReflectionMetadataSingleton.java @@ -120,22 +120,21 @@ static class LayeredCallbacks extends SingletonLayeredCallbacksSupplier { @Override public SingletonTrait getLayeredCallbacksTrait() { - return new SingletonTrait(SingletonTraitKind.LAYERED_CALLBACKS, new SingletonLayeredCallbacks() { + return new SingletonTrait(SingletonTraitKind.LAYERED_CALLBACKS, new SingletonLayeredCallbacks() { @Override - public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, Object singleton) { - LayeredReflectionMetadataSingleton metadata = (LayeredReflectionMetadataSingleton) singleton; + public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, LayeredReflectionMetadataSingleton singleton) { List hubs = new ArrayList<>(); List classFlagsList = new ArrayList<>(); - var cursor = metadata.reflectionMetadataMap.getEntries(); + var cursor = singleton.reflectionMetadataMap.getEntries(); while (cursor.advance()) { int hub = cursor.getKey(); hubs.add(hub); - classFlagsList.add(getCombinedClassFlags(cursor.getValue(), metadata.previousLayerClassFlags.getOrDefault(hub, 0))); + classFlagsList.add(getCombinedClassFlags(cursor.getValue(), singleton.previousLayerClassFlags.getOrDefault(hub, 0))); } - for (var entry : metadata.previousLayerClassFlags.entrySet()) { + for (var entry : singleton.previousLayerClassFlags.entrySet()) { if (!hubs.contains(entry.getKey())) { /* * If new class flags were written in this layer, the class flags from @@ -153,16 +152,16 @@ public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, } @Override - public Class getSingletonInstantiator() { + public Class> getSingletonInstantiator() { return SingletonInstantiator.class; } }); } } - static class SingletonInstantiator implements SingletonLayeredCallbacks.LayeredSingletonInstantiator { + static class SingletonInstantiator implements SingletonLayeredCallbacks.LayeredSingletonInstantiator { @Override - public Object createFromLoader(ImageSingletonLoader loader) { + public LayeredReflectionMetadataSingleton createFromLoader(ImageSingletonLoader loader) { List hubs = loader.readIntList(LAYERED_REFLECTION_METADATA_HUBS); List previousLayerClassFlags = loader.readIntList(LAYERED_REFLECTION_METADATA_CLASS_FLAGS); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/Resources.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/Resources.java index 19f53124dd0d..3b7fcf75fd69 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/Resources.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/Resources.java @@ -752,23 +752,22 @@ static class LayeredCallbacks extends SingletonLayeredCallbacksSupplier { @Override public SingletonTrait getLayeredCallbacksTrait() { - return new SingletonTrait(SingletonTraitKind.LAYERED_CALLBACKS, new SingletonLayeredCallbacks() { + return new SingletonTrait(SingletonTraitKind.LAYERED_CALLBACKS, new SingletonLayeredCallbacks() { @Override - public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, Object singleton) { - Resources instance = (Resources) singleton; + public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, Resources singleton) { List resourceKeys = new ArrayList<>(); List resourceRegistrationStates = new ArrayList<>(); - Set patterns = new HashSet<>(instance.previousLayerPatterns); + Set patterns = new HashSet<>(singleton.previousLayerPatterns); - var cursor = instance.resources.getEntries(); + var cursor = singleton.resources.getEntries(); while (cursor.advance()) { resourceKeys.add(cursor.getKey().toString()); boolean isNegativeQuery = cursor.getValue().getValueUnconditionally() == NEGATIVE_QUERY_MARKER; resourceRegistrationStates.add(!isNegativeQuery); } - for (var entry : instance.previousLayerResources.entrySet()) { + for (var entry : singleton.previousLayerResources.entrySet()) { /* * If a complete entry overwrites a negative query from a previous layer, * the previousLayerResources map entry needs to be skipped to register the @@ -780,7 +779,7 @@ public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, } } - instance.requestedPatterns.getKeys().forEach(p -> patterns.add(p.toString())); + singleton.requestedPatterns.getKeys().forEach(p -> patterns.add(p.toString())); writer.writeStringList(RESOURCE_KEYS, resourceKeys); writer.writeBoolList(RESOURCE_REGISTRATION_STATES, resourceRegistrationStates); @@ -790,16 +789,16 @@ public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, } @Override - public Class getSingletonInstantiator() { + public Class> getSingletonInstantiator() { return SingletonInstantiator.class; } }); } } - static class SingletonInstantiator implements SingletonLayeredCallbacks.LayeredSingletonInstantiator { + static class SingletonInstantiator implements SingletonLayeredCallbacks.LayeredSingletonInstantiator { @Override - public Object createFromLoader(ImageSingletonLoader loader) { + public Resources createFromLoader(ImageSingletonLoader loader) { List previousLayerResourceKeys = loader.readStringList(RESOURCE_KEYS); List previousLayerRegistrationStates = loader.readBoolList(RESOURCE_REGISTRATION_STATES); Map previousLayerResources = new HashMap<>(); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/traits/BuiltinTraits.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/traits/BuiltinTraits.java index 3e513f4e9654..5e1306ac8820 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/traits/BuiltinTraits.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/traits/BuiltinTraits.java @@ -77,7 +77,7 @@ public SingletonTrait getAccessTrait() { /** * Trait indicating this singleton has no special callbacks needed during layered builds. */ - public static final SingletonTrait NO_LAYERED_CALLBACKS = new SingletonTrait(SingletonTraitKind.LAYERED_CALLBACKS, new SingletonLayeredCallbacks() { + public static final SingletonTrait NO_LAYERED_CALLBACKS = new SingletonTrait(SingletonTraitKind.LAYERED_CALLBACKS, new SingletonLayeredCallbacks<>() { @Override public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, Object singleton) { return LayeredImageSingleton.PersistFlags.NOTHING; @@ -96,7 +96,7 @@ public SingletonTrait getLayeredCallbacksTrait() { * be linked to this key in a subsequent image layer. This limits the singleton to being * installed in a single layer. */ - public static final SingletonTrait SINGLE_LAYER = new SingletonTrait(SingletonTraitKind.LAYERED_CALLBACKS, new SingletonLayeredCallbacks() { + public static final SingletonTrait SINGLE_LAYER = new SingletonTrait(SingletonTraitKind.LAYERED_CALLBACKS, new SingletonLayeredCallbacks<>() { @Override public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, Object singleton) { return LayeredImageSingleton.PersistFlags.FORBIDDEN; diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/traits/InjectedSingletonLayeredCallbacks.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/traits/InjectedSingletonLayeredCallbacks.java index 68e7e1fb8ad6..5c3ce69de1aa 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/traits/InjectedSingletonLayeredCallbacks.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/traits/InjectedSingletonLayeredCallbacks.java @@ -27,13 +27,15 @@ import com.oracle.svm.core.layeredimagesingleton.ImageSingletonWriter; import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingleton; +import jdk.graal.compiler.debug.Assertions; + // GR-66792 remove once no custom persist actions exist /** * Temporarily used to convert {@link LayeredImageSingleton} callbacks into {@link SingletonTrait} * information. */ -public final class InjectedSingletonLayeredCallbacks extends SingletonLayeredCallbacks { +public final class InjectedSingletonLayeredCallbacks extends SingletonLayeredCallbacks { final LayeredImageSingleton singleton; public InjectedSingletonLayeredCallbacks(LayeredImageSingleton singleton) { @@ -41,7 +43,9 @@ public InjectedSingletonLayeredCallbacks(LayeredImageSingleton singleton) { } @Override - public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, Object obj) { + public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, LayeredImageSingleton obj) { + assert singleton == obj : Assertions.errorMessage(singleton, obj); + return singleton.preparePersist(writer); } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/traits/SingletonLayeredCallbacks.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/traits/SingletonLayeredCallbacks.java index a3c028c9a75c..b6f9d0a7c35d 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/traits/SingletonLayeredCallbacks.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/traits/SingletonLayeredCallbacks.java @@ -37,7 +37,7 @@ * This class contains actions which can be called on singletons during a layered image build. */ @Platforms(Platform.HOSTED_ONLY.class) -public abstract class SingletonLayeredCallbacks { +public abstract class SingletonLayeredCallbacks { /** * Used to recreate a singleton across layers. @@ -54,8 +54,8 @@ public abstract class SingletonLayeredCallbacks { * will initialize LI and will then call {@link #createFromLoader} to attain the S to be used in * layer A. */ - public interface LayeredSingletonInstantiator { - Object createFromLoader(ImageSingletonLoader loader); + public interface LayeredSingletonInstantiator { + T createFromLoader(ImageSingletonLoader loader); } /** @@ -63,13 +63,13 @@ public interface LayeredSingletonInstantiator { * at the end of native image generation to perform any needed final actions. The method's * return value also specifies what actions should be taken at the startup of the next layer. */ - public abstract PersistFlags doPersist(ImageSingletonWriter writer, Object singleton); + public abstract PersistFlags doPersist(ImageSingletonWriter writer, T singleton); /** * If {@link #doPersist} returns {@link PersistFlags#CREATE}, then this method is called to * determine how to instantiate the singleton in the next layer. */ - public Class getSingletonInstantiator() { + public Class> getSingletonInstantiator() { throw VMError.shouldNotReachHere("getSingletonInstantiator is not implemented. This method must be implemented if doPersist returns PersistFlag.CREATE"); } @@ -78,7 +78,7 @@ public Class getSingletonInstantiator() * method will be called at most once for each registered singleton object. */ @SuppressWarnings("unused") - public void onSingletonRegistration(ImageSingletonLoader loader, Object singleton) { + public void onSingletonRegistration(ImageSingletonLoader loader, T singleton) { throw VMError.shouldNotReachHere("onSingletonRegistration is not implemented. This method must be implemented if doPersist returns PersistFlag.CALLBACK_ON_REGISTRATION"); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ImageSingletonsSupportImpl.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ImageSingletonsSupportImpl.java index 7fb733becaa1..1ef8cc4a78a8 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ImageSingletonsSupportImpl.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ImageSingletonsSupportImpl.java @@ -44,6 +44,7 @@ import org.graalvm.nativeimage.impl.AnnotationExtractor; import org.graalvm.nativeimage.impl.ImageSingletonsSupport; +import com.oracle.svm.core.SubstrateUtil; import com.oracle.svm.core.imagelayer.ImageLayerBuildingSupport; import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingleton; import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingleton.PersistFlags; @@ -437,7 +438,7 @@ private void injectLayeredInformation(Object singleton, SingletonTraitMap traitM } if (layeredBuild) { if (traitMap.getTrait(SingletonTraitKind.LAYERED_CALLBACKS).isEmpty()) { - SingletonLayeredCallbacks action = new InjectedSingletonLayeredCallbacks(layeredImageSingleton); + SingletonLayeredCallbacks action = new InjectedSingletonLayeredCallbacks(layeredImageSingleton); traitMap.addTrait(new SingletonTrait(SingletonTraitKind.LAYERED_CALLBACKS, action)); } } @@ -500,10 +501,13 @@ private void addSingletonToMap(Class key, Object value, SingletonTraitMap tra /* Run onSingletonRegistration hook if needed. */ if (extensionLayerBuild) { if (singletonLoader.hasRegistrationCallback(key)) { - synchronizeRegistrationCallbackExecution(value, () -> { - var trait = traitMap.getTrait(SingletonTraitKind.LAYERED_CALLBACKS).get(); - var callbacks = ((SingletonLayeredCallbacks) trait.metadata()); - callbacks.onSingletonRegistration(singletonLoader.getImageSingletonLoader(key), value); + synchronizeRegistrationCallbackExecution(value, new Runnable() { + @Override + @SuppressWarnings("unchecked") + public void run() { + var trait = traitMap.getTrait(SingletonTraitKind.LAYERED_CALLBACKS).get(); + SubstrateUtil.cast(trait.metadata(), SingletonLayeredCallbacks.class).onSingletonRegistration(singletonLoader.getImageSingletonLoader(key), value); + } }); } } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/OpenTypeWorldFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/OpenTypeWorldFeature.java index f4fae124375e..1a98202ae131 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/OpenTypeWorldFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/OpenTypeWorldFeature.java @@ -297,7 +297,7 @@ public TypeCheckBuilder.StartingTypeIDs loadTypeID(Collection types) static class LayeredCallbacks extends SingletonLayeredCallbacksSupplier { @Override public SingletonTrait getLayeredCallbacksTrait() { - return new SingletonTrait(SingletonTraitKind.LAYERED_CALLBACKS, new SingletonLayeredCallbacks() { + return new SingletonTrait(SingletonTraitKind.LAYERED_CALLBACKS, new SingletonLayeredCallbacks<>() { @Override public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, Object singleton) { writer.writeInt("maxTypeID", DynamicHubSupport.currentLayer().getMaxTypeId()); @@ -307,16 +307,16 @@ public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, } @Override - public Class getSingletonInstantiator() { + public Class> getSingletonInstantiator() { return SingletonInstantiator.class; } }); } } - static class SingletonInstantiator implements SingletonLayeredCallbacks.LayeredSingletonInstantiator { + static class SingletonInstantiator implements SingletonLayeredCallbacks.LayeredSingletonInstantiator { @Override - public Object createFromLoader(ImageSingletonLoader loader) { + public LayerTypeCheckInfo createFromLoader(ImageSingletonLoader loader) { return new LayerTypeCheckInfo(loader.readInt("maxTypeID"), loader.readInt("maxInterfaceID")); } } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/CrossLayerFieldUpdaterFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/CrossLayerFieldUpdaterFeature.java index 2f145b572d26..cadd5027fd61 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/CrossLayerFieldUpdaterFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/CrossLayerFieldUpdaterFeature.java @@ -368,10 +368,10 @@ int getHeaderSize() { static class LayeredCallbacks extends SingletonLayeredCallbacksSupplier { @Override public SingletonTrait getLayeredCallbacksTrait() { - return new SingletonTrait(SingletonTraitKind.LAYERED_CALLBACKS, new SingletonLayeredCallbacks() { + return new SingletonTrait(SingletonTraitKind.LAYERED_CALLBACKS, new SingletonLayeredCallbacks() { @Override - public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, Object singleton) { - var updateInfoMap = ((CrossLayerFieldUpdaterFeature) singleton).updateInfoMap; + public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, CrossLayerFieldUpdaterFeature singleton) { + var updateInfoMap = singleton.updateInfoMap; ArrayList fieldIds = new ArrayList<>(); ArrayList receiverIds = new ArrayList<>(); ArrayList offsets = new ArrayList<>(); @@ -390,7 +390,7 @@ public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, } @Override - public void onSingletonRegistration(ImageSingletonLoader loader, Object singleton) { + public void onSingletonRegistration(ImageSingletonLoader loader, CrossLayerFieldUpdaterFeature singleton) { Map map = new HashMap<>(); Iterator fieldIds = loader.readIntList("fieldIds").iterator(); Iterator receiverIds = loader.readIntList("receiverIds").iterator(); @@ -407,7 +407,7 @@ public void onSingletonRegistration(ImageSingletonLoader loader, Object singleto assert prev == null : prev; } assert !receiverIds.hasNext() && !offsets.hasNext() && !javaKindOrdinals.hasNext() : "information is not properly synced"; - ((CrossLayerFieldUpdaterFeature) singleton).updateInfoMap = Collections.unmodifiableMap(map); + singleton.updateInfoMap = Collections.unmodifiableMap(map); } }); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/LayeredFieldValueTransformerSupport.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/LayeredFieldValueTransformerSupport.java index d379a8ff3521..e601a1bf90a2 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/LayeredFieldValueTransformerSupport.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/LayeredFieldValueTransformerSupport.java @@ -270,11 +270,10 @@ public List getUpdatableReceivers(AnalysisField aField) { static class LayeredCallbacks extends SingletonLayeredCallbacksSupplier { @Override public SingletonTrait getLayeredCallbacksTrait() { - return new SingletonTrait(SingletonTraitKind.LAYERED_CALLBACKS, new SingletonLayeredCallbacks() { + return new SingletonTrait(SingletonTraitKind.LAYERED_CALLBACKS, new SingletonLayeredCallbacks() { @Override - public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, Object singleton) { - LayeredFieldValueTransformerSupport support = (LayeredFieldValueTransformerSupport) singleton; - var fieldsWithUpdatableValues = support.fieldToLayeredTransformer.entrySet().stream() + public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, LayeredFieldValueTransformerSupport singleton) { + var fieldsWithUpdatableValues = singleton.fieldToLayeredTransformer.entrySet().stream() .filter(e -> e.getValue().currentLayerHasUpdatableValues) .map(e -> e.getKey().getId()).toList(); writer.writeIntList("fieldsWithUpdatableValues", fieldsWithUpdatableValues); @@ -282,8 +281,8 @@ public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, } @Override - public void onSingletonRegistration(ImageSingletonLoader loader, Object singleton) { - ((LayeredFieldValueTransformerSupport) singleton).fieldsWithUpdatableValues = Set.copyOf(loader.readIntList("fieldsWithUpdatableValues")); + public void onSingletonRegistration(ImageSingletonLoader loader, LayeredFieldValueTransformerSupport singleton) { + singleton.fieldsWithUpdatableValues = Set.copyOf(loader.readIntList("fieldsWithUpdatableValues")); } }); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SVMImageLayerSingletonLoader.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SVMImageLayerSingletonLoader.java index c421a8793e80..ec3c04040b32 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SVMImageLayerSingletonLoader.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SVMImageLayerSingletonLoader.java @@ -100,7 +100,7 @@ public Map>> loadImageSingletons(Function clazz = imageLayerBuildingSupport.lookupClass(false, recreateClass); if (SingletonLayeredCallbacks.LayeredSingletonInstantiator.class.isAssignableFrom(clazz)) { - SingletonLayeredCallbacks.LayeredSingletonInstantiator instance = (SingletonLayeredCallbacks.LayeredSingletonInstantiator) ReflectionUtil.newInstance(clazz); + var instance = (SingletonLayeredCallbacks.LayeredSingletonInstantiator) ReflectionUtil.newInstance(clazz); result = instance.createFromLoader(imageSingletonLoader); } else { // GR-66792 remove once no custom persist actions exist diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SVMImageLayerWriter.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SVMImageLayerWriter.java index dffe63be6381..a6481b45f4ad 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SVMImageLayerWriter.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SVMImageLayerWriter.java @@ -97,6 +97,7 @@ import com.oracle.svm.core.FunctionPointerHolder; import com.oracle.svm.core.StaticFieldsSupport; import com.oracle.svm.core.SubstrateOptions; +import com.oracle.svm.core.SubstrateUtil; import com.oracle.svm.core.annotate.Delete; import com.oracle.svm.core.classinitialization.ClassInitializationInfo; import com.oracle.svm.core.graal.code.CGlobalDataBasePointer; @@ -1126,7 +1127,7 @@ record SingletonPersistInfo(LayeredImageSingleton.PersistFlags flags, int single record RecreateInfo(String clazz, String method) { } - RecreateInfo createRecreateInfo(SingletonLayeredCallbacks action) { + RecreateInfo createRecreateInfo(SingletonLayeredCallbacks action) { if (action instanceof InjectedSingletonLayeredCallbacks injectAction) { // GR-66792 remove once no custom persist actions exist Class singletonClass = injectAction.getSingletonClass(); @@ -1142,6 +1143,7 @@ RecreateInfo createRecreateInfo(SingletonLayeredCallbacks action) { } } + @SuppressWarnings("unchecked") public void writeImageSingletonInfo(List, ImageSingletonsSupportImpl.SingletonInfo>> layeredImageSingletons) { /* * First write the image singleton keys @@ -1158,8 +1160,8 @@ public void writeImageSingletonInfo(List, ImageSingletonsSupp boolean initialLayerOnly = initialLayerSingletons.contains(singleton); if (!singletonPersistInfoMap.containsKey(singleton)) { var writer = new ImageSingletonWriterImpl(snapshotBuilder, hUniverse); - SingletonLayeredCallbacks action = (SingletonLayeredCallbacks) singletonEntry.getValue().traitMap().getTrait(SingletonTraitKind.LAYERED_CALLBACKS).get().metadata(); - var flags = action.doPersist(writer, singleton); + var action = (SingletonLayeredCallbacks) singletonEntry.getValue().traitMap().getTrait(SingletonTraitKind.LAYERED_CALLBACKS).get().metadata(); + var flags = SubstrateUtil.cast(action, SingletonLayeredCallbacks.class).doPersist(writer, singleton); if (initialLayerOnly) { VMError.guarantee(flags == LayeredImageSingleton.PersistFlags.FORBIDDEN, "InitialLayer Singleton's persist action must return %s %s", LayeredImageSingleton.PersistFlags.FORBIDDEN, singleton); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/thread/HostedJavaThreadsFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/thread/HostedJavaThreadsFeature.java index 7b2278e5aeee..237a5a42de4e 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/thread/HostedJavaThreadsFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/thread/HostedJavaThreadsFeature.java @@ -274,14 +274,14 @@ public LayeredImageSingleton.PersistFlags preparePersist(ImageSingletonWriter wr static class LayeredCallbacks extends SingletonLayeredCallbacksSupplier { @Override public SingletonTrait getLayeredCallbacksTrait() { - SingletonLayeredCallbacks action = new SingletonLayeredCallbacks() { + SingletonLayeredCallbacks action = new SingletonLayeredCallbacks<>() { @Override - public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, Object singleton) { - return ((HostedJavaThreadsMetadata) singleton).preparePersist(writer); + public LayeredImageSingleton.PersistFlags doPersist(ImageSingletonWriter writer, HostedJavaThreadsMetadata singleton) { + return singleton.preparePersist(writer); } @Override - public Class getSingletonInstantiator() { + public Class> getSingletonInstantiator() { return SingletonInstantiator.class; } }; @@ -289,9 +289,9 @@ public Class getSingletonInstantiator() } } - static class SingletonInstantiator implements SingletonLayeredCallbacks.LayeredSingletonInstantiator { + static class SingletonInstantiator implements SingletonLayeredCallbacks.LayeredSingletonInstantiator { @Override - public Object createFromLoader(ImageSingletonLoader loader) { + public HostedJavaThreadsMetadata createFromLoader(ImageSingletonLoader loader) { long maxThreadId = loader.readLong("maxThreadId"); int maxAutonumber = loader.readInt("maxAutonumber");