From 41c8156add1ecd3794231de398664216a9c7e286 Mon Sep 17 00:00:00 2001 From: Codrut Stancu Date: Fri, 17 Jan 2025 18:43:40 +0100 Subject: [PATCH] Refactor field inclusion policy in base layer and improve name checks mechanism. --- .../graal/pointsto/meta/AnalysisField.java | 13 +++++ .../svm/common/meta/GuaranteeFolded.java | 40 +++++++++++++ .../svm/common/option/CommonOptionParser.java | 10 +++- .../com/oracle/svm/core/SubstrateUtil.java | 3 +- .../svm/core/jdk/SystemPropertiesSupport.java | 1 + .../core/option/SubstrateOptionsParser.java | 1 + .../oracle/svm/hosted/ImageClassLoader.java | 19 +++++++ .../svm/hosted/NativeImageGenerator.java | 56 ++++++++++++------- .../svm/hosted/OpenTypeWorldFeature.java | 6 -- .../src/com/oracle/svm/hosted/SVMHost.java | 44 ++++++++++----- .../LayeredDispatchTableSupport.java | 7 ++- .../oracle/svm/hosted/meta/HostedField.java | 1 + 12 files changed, 154 insertions(+), 47 deletions(-) create mode 100644 substratevm/src/com.oracle.svm.common/src/com/oracle/svm/common/meta/GuaranteeFolded.java diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisField.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisField.java index 616fd47c55c4..46357c43ccf7 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisField.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisField.java @@ -40,6 +40,7 @@ import com.oracle.graal.pointsto.util.AnalysisError; import com.oracle.graal.pointsto.util.AnalysisFuture; import com.oracle.graal.pointsto.util.AtomicUtils; +import com.oracle.svm.common.meta.GuaranteeFolded; import jdk.graal.compiler.debug.GraalError; import jdk.vm.ci.code.BytecodePosition; @@ -217,6 +218,7 @@ public void cleanupAfterAnalysis() { } public boolean registerAsAccessed(Object reason) { + checkGuaranteeFolded(); getDeclaringClass().registerAsReachable(this); assert isValidReason(reason) : "Registering a field as accessed needs to provide a valid reason."; @@ -231,6 +233,7 @@ public boolean registerAsAccessed(Object reason) { * @param reason the reason why this field is read, non-null */ public boolean registerAsRead(Object reason) { + checkGuaranteeFolded(); getDeclaringClass().registerAsReachable(this); assert isValidReason(reason) : "Registering a field as read needs to provide a valid reason."; @@ -250,6 +253,7 @@ public boolean registerAsRead(Object reason) { * @param reason the reason why this field is written, non-null */ public boolean registerAsWritten(Object reason) { + checkGuaranteeFolded(); getDeclaringClass().registerAsReachable(this); assert isValidReason(reason) : "Registering a field as written needs to provide a valid reason."; @@ -264,6 +268,14 @@ public boolean registerAsWritten(Object reason) { }); } + public boolean isGuaranteeFolded() { + return getAnnotation(GuaranteeFolded.class) != null; + } + + public void checkGuaranteeFolded() { + AnalysisError.guarantee(!isGuaranteeFolded(), "A field that is guaranteed to always be folded is seen as accessed: %s. ", this); + } + public void registerAsFolded(Object reason) { getDeclaringClass().registerAsReachable(this); @@ -275,6 +287,7 @@ public void registerAsFolded(Object reason) { } public boolean registerAsUnsafeAccessed(Object reason) { + checkGuaranteeFolded(); assert isValidReason(reason) : "Registering a field as unsafe accessed needs to provide a valid reason."; registerAsAccessed(reason); /* diff --git a/substratevm/src/com.oracle.svm.common/src/com/oracle/svm/common/meta/GuaranteeFolded.java b/substratevm/src/com.oracle.svm.common/src/com/oracle/svm/common/meta/GuaranteeFolded.java new file mode 100644 index 000000000000..658250efa446 --- /dev/null +++ b/substratevm/src/com.oracle.svm.common/src/com/oracle/svm/common/meta/GuaranteeFolded.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2025, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.svm.common.meta; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Verifies that loads of the annotated field are always folded in run time code. This annotation + * doesn't influence the folding logic itself, it just ensures that the annotated fields are not + * present in the image. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD}) +public @interface GuaranteeFolded { +} diff --git a/substratevm/src/com.oracle.svm.common/src/com/oracle/svm/common/option/CommonOptionParser.java b/substratevm/src/com.oracle.svm.common/src/com/oracle/svm/common/option/CommonOptionParser.java index 6fbe0e4c27f9..98efb5ee0afd 100644 --- a/substratevm/src/com.oracle.svm.common/src/com/oracle/svm/common/option/CommonOptionParser.java +++ b/substratevm/src/com.oracle.svm.common/src/com/oracle/svm/common/option/CommonOptionParser.java @@ -41,6 +41,12 @@ import org.graalvm.collections.EconomicMap; import org.graalvm.collections.EconomicSet; +import org.graalvm.nativeimage.Platform; +import org.graalvm.nativeimage.Platforms; + +import com.oracle.svm.util.ClassUtil; +import com.oracle.svm.util.StringUtil; + import jdk.graal.compiler.options.EnumMultiOptionKey; import jdk.graal.compiler.options.OptionDescriptor; import jdk.graal.compiler.options.OptionDescriptors; @@ -48,10 +54,8 @@ import jdk.graal.compiler.options.OptionType; import jdk.graal.compiler.options.OptionsParser; -import com.oracle.svm.util.ClassUtil; -import com.oracle.svm.util.StringUtil; - public class CommonOptionParser { + @Platforms(Platform.HOSTED_ONLY.class) // public static final String HOSTED_OPTION_PREFIX = "-H:"; public static final String RUNTIME_OPTION_PREFIX = "-R:"; diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateUtil.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateUtil.java index 513897f69ff7..570f45d2ebec 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateUtil.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateUtil.java @@ -46,6 +46,7 @@ import org.graalvm.word.Pointer; import org.graalvm.word.UnsignedWord; +import com.oracle.svm.common.meta.GuaranteeFolded; import com.oracle.svm.core.annotate.Alias; import com.oracle.svm.core.annotate.RecomputeFieldValue; import com.oracle.svm.core.annotate.RecomputeFieldValue.Kind; @@ -69,7 +70,7 @@ public class SubstrateUtil { /** * Field that is true during native image generation, but false at run time. */ - public static final boolean HOSTED; + @GuaranteeFolded public static final boolean HOSTED; static { /* diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/SystemPropertiesSupport.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/SystemPropertiesSupport.java index 1bff154f0bf3..ee5d90398c97 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/SystemPropertiesSupport.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/SystemPropertiesSupport.java @@ -63,6 +63,7 @@ public abstract class SystemPropertiesSupport implements RuntimeSystemPropertiesSupport { /** System properties that are taken from the VM hosting the image generator. */ + @Platforms(Platform.HOSTED_ONLY.class) // private static final String[] HOSTED_PROPERTIES = { "java.version", "java.version.date", diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/option/SubstrateOptionsParser.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/option/SubstrateOptionsParser.java index ba9a1991e850..4fe66dba5417 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/option/SubstrateOptionsParser.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/option/SubstrateOptionsParser.java @@ -54,6 +54,7 @@ */ public class SubstrateOptionsParser { + @Platforms(Platform.HOSTED_ONLY.class) // public static final String HOSTED_OPTION_PREFIX = CommonOptionParser.HOSTED_OPTION_PREFIX; public static final String RUNTIME_OPTION_PREFIX = CommonOptionParser.RUNTIME_OPTION_PREFIX; diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ImageClassLoader.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ImageClassLoader.java index 2a87905dd2d0..1076e9460e9f 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ImageClassLoader.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ImageClassLoader.java @@ -37,16 +37,20 @@ import java.util.Enumeration; import java.util.List; import java.util.Optional; +import java.util.Set; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import org.graalvm.collections.EconomicSet; +import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; +import com.oracle.svm.core.BuildPhaseProvider; import com.oracle.svm.core.SubstrateOptions; import com.oracle.svm.core.TypeResult; +import com.oracle.svm.core.util.VMError; import com.oracle.svm.util.LogUtils; import com.oracle.svm.util.ReflectionUtil; @@ -62,6 +66,8 @@ public final class ImageClassLoader { private final EconomicSet> hostedOnlyClasses = EconomicSet.create(); private final EconomicSet systemMethods = EconomicSet.create(); private final EconomicSet systemFields = EconomicSet.create(); + /** Modules containing all {@code svm.core} and {@code svm.hosted} classes. */ + private Set builderModules; ImageClassLoader(Platform platform, NativeImageClassLoaderSupport classLoaderSupport) { this.platform = platform; @@ -430,4 +436,17 @@ public EconomicSet packages(URI container) { public boolean noEntryForURI(EconomicSet set) { return classLoaderSupport.noEntryForURI(set); } + + public Set getBuilderModules() { + assert builderModules != null : "Builder modules not yet initialized."; + return builderModules; + } + + public void initBuilderModules() { + VMError.guarantee(BuildPhaseProvider.isFeatureRegistrationFinished() && ImageSingletons.contains(VMFeature.class), + "Querying builder modules is only possible after feature registration is finished."); + Module m0 = ImageSingletons.lookup(VMFeature.class).getClass().getModule(); + Module m1 = SVMHost.class.getModule(); + builderModules = m0.equals(m1) ? Set.of(m0) : Set.of(m0, m1); + } } 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 4cbeea644a0c..fae47d9fe170 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,7 @@ import java.io.IOException; import java.lang.annotation.Annotation; +import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.nio.file.FileSystems; @@ -941,6 +942,8 @@ protected void setupNativeImage(String imageName, OptionValues options, Map feature.afterRegistration(access)); setDefaultLibCIfMissing(); @@ -1656,17 +1659,17 @@ private void checkUniverse() { if (SubstrateOptions.VerifyNamingConventions.getValue()) { for (AnalysisMethod method : aUniverse.getMethods()) { if ((method.isInvoked() || method.isReachable()) && method.getAnnotation(Fold.class) == null) { - checkName(method.format("%H.%n(%p)"), method, bb); + checkName(bb, method); } } for (AnalysisField field : aUniverse.getFields()) { if (field.isAccessed()) { - checkName(field.format("%H.%n"), null, bb); + checkName(bb, field); } } for (AnalysisType type : aUniverse.getTypes()) { if (type.isReachable()) { - checkName(type.toJavaName(true), null, bb); + checkName(bb, type); } } } @@ -1698,32 +1701,47 @@ protected void checkForInvalidCallsToEntryPoints() { // the unsupported features are reported after checkUniverse is invoked } - public static void checkName(String name, AnalysisMethod method, BigBang bb) { + public static void checkName(BigBang bb, AnalysisMethod method) { + String format = method.format("%H.%n(%p)"); + checkName(bb, method, format); + } + + public static void checkName(BigBang bb, AnalysisField field) { + String format = field.format("%H.%n"); + checkName(bb, null, format); + } + + public static void checkName(BigBang bb, Field field) { + String format = field.getType().getName() + "." + field.getName(); + checkName(bb, null, format); + } + + public static void checkName(BigBang bb, AnalysisType type) { + String format = type.toJavaName(true); + checkName(bb, null, format); + } + + private static void checkName(BigBang bb, AnalysisMethod method, String format) { /* * We do not want any parts of the native image generator in the generated image. Therefore, * no element whose name contains "hosted" must be seen as reachable by the static analysis. * The same holds for "host VM" elements, which come from the hosting VM, unless they are * JDK internal types. */ - String message = checkName(name); - if (message != null) { - if (bb != null) { - bb.getUnsupportedFeatures().addMessage(name, method, message); - } else { - throw new UnsupportedFeatureException(message); - } + String lformat = format.toLowerCase(Locale.ROOT); + if (lformat.contains("hosted")) { + report(bb, format, method, "Hosted element used at run time: " + format + "."); + } else if (!lformat.startsWith("jdk.internal") && lformat.contains("hotspot")) { + report(bb, format, method, "HotSpot element used at run time: " + format + "."); } } - public static String checkName(String name) { - String lname = name.toLowerCase(Locale.ROOT); - String message = null; - if (lname.contains("hosted")) { - message = "Hosted element used at run time: " + name; - } else if (!name.startsWith("jdk.internal") && lname.contains("hotspot")) { - message = "HotSpot element used at run time: " + name; + private static void report(BigBang bb, String key, AnalysisMethod method, String message) { + if (bb != null) { + bb.getUnsupportedFeatures().addMessage(key, method, message); + } else { + throw new UnsupportedFeatureException(message); } - return message; } @SuppressWarnings("try") 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 7bea88352544..cd8fb533cad7 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 @@ -69,12 +69,6 @@ public void beforeUniverseBuilding(BeforeUniverseBuildingAccess access) { } } - public Set getBuilderModules() { - Module m0 = ImageSingletons.lookup(VMFeature.class).getClass().getModule(); - Module m1 = SVMHost.class.getModule(); - return m0.equals(m1) ? Set.of(m0) : Set.of(m0, m1); - } - private final Set triggeredTypes = new HashSet<>(); private final Set triggeredMethods = new HashSet<>(); 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 611911f1d277..eb99c352c3f2 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 @@ -68,6 +68,7 @@ import com.oracle.graal.pointsto.phases.InlineBeforeAnalysisGraphDecoder; import com.oracle.graal.pointsto.phases.InlineBeforeAnalysisPolicy; import com.oracle.graal.pointsto.util.GraalAccess; +import com.oracle.svm.common.meta.GuaranteeFolded; import com.oracle.svm.common.meta.MultiMethod; import com.oracle.svm.core.BuildPhaseProvider; import com.oracle.svm.core.MissingRegistrationSupport; @@ -171,6 +172,7 @@ public enum UsageKind { private final Map> forbiddenTypes; private final Platform platform; + private final ImageClassLoader loader; private final ClassInitializationSupport classInitializationSupport; private final LinkAtBuildTimeSupport linkAtBuildTimeSupport; private final HostedStringDeduplication stringTable; @@ -207,13 +209,11 @@ public enum UsageKind { private final boolean enableTrackAcrossLayers; private final boolean enableReachableInCurrentLayer; - /** Modules containing all {@code svm.core} and {@code svm.hosted} classes. */ - private final Set builderModules; - @SuppressWarnings("this-escape") public SVMHost(OptionValues options, ImageClassLoader loader, ClassInitializationSupport classInitializationSupport, AnnotationSubstitutionProcessor annotationSubstitutions, MissingRegistrationSupport missingRegistrationSupport) { super(options, loader.getClassLoader()); + this.loader = loader; this.classInitializationSupport = classInitializationSupport; this.missingRegistrationSupport = missingRegistrationSupport; this.stringTable = HostedStringDeduplication.singleton(); @@ -244,7 +244,6 @@ public SVMHost(OptionValues options, ImageClassLoader loader, ClassInitializatio enableTrackAcrossLayers = ImageLayerBuildingSupport.buildingSharedLayer(); enableReachableInCurrentLayer = ImageLayerBuildingSupport.buildingExtensionLayer(); - builderModules = ImageSingletons.contains(OpenTypeWorldFeature.class) ? ImageSingletons.lookup(OpenTypeWorldFeature.class).getBuilderModules() : null; } /** @@ -254,7 +253,7 @@ public SVMHost(OptionValues options, ImageClassLoader loader, ClassInitializatio */ @Override public boolean isCoreType(AnalysisType type) { - return builderModules.contains(type.getJavaClass().getModule()); + return loader.getBuilderModules().contains(type.getJavaClass().getModule()); } @Override @@ -311,7 +310,7 @@ private static Map> setupForbiddenTypes(OptionValues opti private void checkForbidden(AnalysisType type, UsageKind kind) { if (SubstrateOptions.VerifyNamingConventions.getValue()) { - NativeImageGenerator.checkName(type.getWrapped().toJavaName(), null, null); + NativeImageGenerator.checkName(null, type); } if (forbiddenTypes == null) { @@ -949,15 +948,16 @@ public boolean isFieldIncluded(BigBang bb, Field field) { if (excludedFields.contains(field)) { return false; } - - /* Fields with those names are not allowed in the image */ - if (NativeImageGenerator.checkName(field.getType().getName() + "." + field.getName()) != null) { - return false; - } /* Options should not be in the image */ if (OptionKey.class.isAssignableFrom(field.getType())) { return false; } + + /* Fields that are always folded don't need to be included. */ + if (field.getAnnotation(GuaranteeFolded.class) != null) { + return false; + } + /* Fields from this package should not be in the image */ if (field.getDeclaringClass().getName().startsWith("jdk.graal.compiler")) { return false; @@ -970,6 +970,12 @@ public boolean isFieldIncluded(BigBang bb, Field field) { return false; } } + + /* Remaining fields should match the naming conventions. */ + if (SubstrateOptions.VerifyNamingConventions.getValue()) { + NativeImageGenerator.checkName(bb, field); + } + return super.isFieldIncluded(bb, field); } @@ -993,10 +999,6 @@ public boolean isFieldIncluded(BigBang bb, AnalysisField field) { return false; } - /* Fields with those names are not allowed in the image */ - if (NativeImageGenerator.checkName(field.getType().toJavaName() + "." + field.getName()) != null) { - return false; - } /* Options should not be in the image */ if (optionKey == null) { optionKey = bb.getMetaAccess().lookupJavaType(OptionKey.class); @@ -1004,6 +1006,12 @@ public boolean isFieldIncluded(BigBang bb, AnalysisField field) { if (optionKey.isAssignableFrom(field.getType())) { return false; } + + /* Fields that are always folded don't need to be included. */ + if (field.isGuaranteeFolded()) { + return false; + } + /* Fields from this package should not be in the image */ if (field.getDeclaringClass().toJavaName().startsWith("jdk.graal.compiler")) { return false; @@ -1013,6 +1021,12 @@ public boolean isFieldIncluded(BigBang bb, AnalysisField field) { if (!included) { return false; } + + /* Remaining fields should match the naming conventions. */ + if (SubstrateOptions.VerifyNamingConventions.getValue()) { + NativeImageGenerator.checkName(bb, field); + } + return super.isFieldIncluded(bb, field); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/LayeredDispatchTableSupport.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/LayeredDispatchTableSupport.java index 4488e54e5c85..f6ded55bfc7a 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/LayeredDispatchTableSupport.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/LayeredDispatchTableSupport.java @@ -61,7 +61,7 @@ import com.oracle.svm.core.option.HostedOptionKey; import com.oracle.svm.core.util.VMError; import com.oracle.svm.hosted.FeatureImpl; -import com.oracle.svm.hosted.OpenTypeWorldFeature; +import com.oracle.svm.hosted.FeatureImpl.BeforeCompilationAccessImpl; import com.oracle.svm.hosted.SVMHost; import com.oracle.svm.hosted.image.NativeImage; import com.oracle.svm.hosted.image.NativeImageCodeCache; @@ -772,7 +772,8 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { } @Override - public void beforeCompilation(BeforeCompilationAccess access) { - LayeredDispatchTableSupport.singleton().installBuilderModules(ImageSingletons.lookup(OpenTypeWorldFeature.class).getBuilderModules()); + public void beforeCompilation(BeforeCompilationAccess a) { + BeforeCompilationAccessImpl access = (BeforeCompilationAccessImpl) a; + LayeredDispatchTableSupport.singleton().installBuilderModules(access.getImageClassLoader().getBuilderModules()); } } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedField.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedField.java index 79023003e7e8..446e09f3b5b0 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedField.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedField.java @@ -65,6 +65,7 @@ public AnalysisField getWrapped() { } protected void setLocation(int location) { + wrapped.checkGuaranteeFolded(); assert this.location == LOC_UNINITIALIZED; assert location >= 0; this.location = location;