From a906ed31ae509ecc3621a5fa673930a585cb36d2 Mon Sep 17 00:00:00 2001 From: ivan-ristovic Date: Wed, 26 Apr 2023 13:53:18 +0200 Subject: [PATCH 1/6] Change module storage key pair to use the module object instead of module name --- .../src/com/oracle/svm/core/jdk/Resources.java | 15 +++++++++------ .../resources/NativeImageResourceFileSystem.java | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) 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 bcdebcc4c7f2..36b5c68b117f 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 @@ -71,7 +71,7 @@ public static Resources singleton() { * resourceName) provides implementations for {@code hashCode()} and {@code equals()} needed for * the map keys. */ - private final EconomicMap, ResourceStorageEntry> resources = ImageHeapMap.create(); + private final EconomicMap, ResourceStorageEntry> resources = ImageHeapMap.create(); /** * Embedding a resource into an image is counted as a modification. Since all resources are @@ -83,7 +83,7 @@ public static Resources singleton() { Resources() { } - public EconomicMap, ResourceStorageEntry> getResourceStorage() { + public EconomicMap, ResourceStorageEntry> getResourceStorage() { return resources; } @@ -103,6 +103,11 @@ public static String moduleName(Module module) { return module == null ? null : module.getName(); } + public static Pair createStorageKey(Module module, String resourceName) { + Module m = module != null && module.isNamed() ? module : null; + return Pair.create(m, resourceName); + } + public static byte[] inputStreamToByteArray(InputStream is) { try { return is.readAllBytes(); @@ -112,10 +117,9 @@ public static byte[] inputStreamToByteArray(InputStream is) { } private static void addEntry(Module module, String resourceName, boolean isDirectory, byte[] data, boolean fromJar) { - String moduleName = moduleName(module); var resources = singleton().resources; synchronized (resources) { - Pair key = Pair.create(moduleName, resourceName); + Pair key = createStorageKey(module, resourceName); ResourceStorageEntry entry = resources.get(key); if (entry == null) { if (singleton().lastModifiedTime == INVALID_TIMESTAMP) { @@ -205,8 +209,7 @@ public static ResourceStorageEntry get(String name) { public static ResourceStorageEntry get(Module module, String resourceName) { String canonicalResourceName = toCanonicalForm(resourceName); - String moduleName = moduleName(module); - ResourceStorageEntry entry = singleton().resources.get(Pair.create(moduleName, canonicalResourceName)); + ResourceStorageEntry entry = singleton().resources.get(createStorageKey(module, canonicalResourceName)); if (entry == null) { return null; } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/resources/NativeImageResourceFileSystem.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/resources/NativeImageResourceFileSystem.java index ea7043f2768b..514125345f20 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/resources/NativeImageResourceFileSystem.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/resources/NativeImageResourceFileSystem.java @@ -651,7 +651,7 @@ private void update(Entry e) { } private void readAllEntries() { - MapCursor, ResourceStorageEntry> entries = Resources.singleton().getResourceStorage().getEntries(); + MapCursor, ResourceStorageEntry> entries = Resources.singleton().getResourceStorage().getEntries(); while (entries.advance()) { byte[] name = getBytes(entries.getKey().getRight()); IndexNode newIndexNode = new IndexNode(name, entries.getValue().isDirectory()); From 2e98947d58d81cfb441d6cfec950a536e1e2fb2c Mon Sep 17 00:00:00 2001 From: ivan-ristovic Date: Thu, 27 Apr 2023 16:10:31 +0200 Subject: [PATCH 2/6] Replace hosted module instances with runtime module instances in the resource storage --- .../com/oracle/svm/core/jdk/Resources.java | 24 +++++++++++++++++-- .../oracle/svm/hosted/ModuleLayerFeature.java | 10 +++++++- 2 files changed, 31 insertions(+), 3 deletions(-) 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 36b5c68b117f..0918bb0626e1 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 @@ -31,10 +31,15 @@ import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; +import java.util.stream.StreamSupport; import org.graalvm.collections.EconomicMap; import org.graalvm.collections.Pair; @@ -67,9 +72,10 @@ public static Resources singleton() { } /** - * The hosted map used to collect registered resources. Using a {@link Pair} of (moduleName, + * The hosted map used to collect registered resources. Using a {@link Pair} of (module, * resourceName) provides implementations for {@code hashCode()} and {@code equals()} needed for - * the map keys. + * the map keys. Hosted module instances differ to runtime instances, so the map that ends up in the image heap + * is computed after the runtime module instances have been computed {see com.oracle.svm.hosted.ModuleLayerFeature}. */ private final EconomicMap, ResourceStorageEntry> resources = ImageHeapMap.create(); @@ -83,6 +89,20 @@ public static Resources singleton() { Resources() { } + public static void replaceHostedModuleWithRuntimeModule(Module hostedModule, Module runtimeModule) { + var resources = singleton().resources; + synchronized (resources) { + var keysToUpdate = StreamSupport.stream(resources.getKeys().spliterator(), false) + .filter(k -> hostedModule.equals(k.getLeft())) + .toList(); + for (var oldKey : keysToUpdate) { + ResourceStorageEntry entry = resources.removeKey(oldKey); + var newKey = createStorageKey(runtimeModule, oldKey.getRight()); + resources.put(newKey, entry); + } + } + } + public EconomicMap, ResourceStorageEntry> getResourceStorage() { return resources; } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ModuleLayerFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ModuleLayerFeature.java index 5ae2bbabef65..6562dae766c3 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ModuleLayerFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ModuleLayerFeature.java @@ -54,6 +54,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import com.oracle.svm.core.jdk.Resources; import jdk.internal.module.DefaultRoots; import jdk.internal.module.ModuleBootstrap; import jdk.internal.module.SystemModuleFinders; @@ -138,7 +139,14 @@ public void duringSetup(DuringSetupAccess access) { private Object replaceHostedModules(Object source) { if (source instanceof Module) { Module module = (Module) source; - return moduleLayerFeatureUtils.getOrCreateRuntimeModuleForHostedModule(module, module.getDescriptor()); + Module runtimeModule = moduleLayerFeatureUtils.getOrCreateRuntimeModuleForHostedModule(module, module.getDescriptor()); + + /* + * Ensure that resources are using the synthesized runtime module instances + */ + Resources.replaceHostedModuleWithRuntimeModule(module, runtimeModule); + + return runtimeModule; } return source; } From 60dbdf5b96032e8a2f30b011e95a0e9ec075026c Mon Sep 17 00:00:00 2001 From: ivan-ristovic Date: Fri, 28 Apr 2023 11:16:40 +0200 Subject: [PATCH 3/6] Make sure resources are not added after analysis --- .../src/com/oracle/svm/core/jdk/Resources.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) 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 0918bb0626e1..bf2c1956c7b3 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 @@ -31,16 +31,13 @@ import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Function; import java.util.stream.StreamSupport; +import com.oracle.svm.core.BuildPhaseProvider; import org.graalvm.collections.EconomicMap; import org.graalvm.collections.Pair; import org.graalvm.nativeimage.ImageSingletons; @@ -74,8 +71,9 @@ public static Resources singleton() { /** * The hosted map used to collect registered resources. Using a {@link Pair} of (module, * resourceName) provides implementations for {@code hashCode()} and {@code equals()} needed for - * the map keys. Hosted module instances differ to runtime instances, so the map that ends up in the image heap - * is computed after the runtime module instances have been computed {see com.oracle.svm.hosted.ModuleLayerFeature}. + * the map keys. Hosted module instances differ to runtime instances, so the map that ends up in + * the image heap is computed after the runtime module instances have been computed {see + * com.oracle.svm.hosted.ModuleLayerFeature}. */ private final EconomicMap, ResourceStorageEntry> resources = ImageHeapMap.create(); @@ -93,8 +91,8 @@ public static void replaceHostedModuleWithRuntimeModule(Module hostedModule, Mod var resources = singleton().resources; synchronized (resources) { var keysToUpdate = StreamSupport.stream(resources.getKeys().spliterator(), false) - .filter(k -> hostedModule.equals(k.getLeft())) - .toList(); + .filter(k -> hostedModule.equals(k.getLeft())) + .toList(); for (var oldKey : keysToUpdate) { ResourceStorageEntry entry = resources.removeKey(oldKey); var newKey = createStorageKey(runtimeModule, oldKey.getRight()); @@ -137,6 +135,7 @@ public static byte[] inputStreamToByteArray(InputStream is) { } private static void addEntry(Module module, String resourceName, boolean isDirectory, byte[] data, boolean fromJar) { + VMError.guarantee(!BuildPhaseProvider.isAnalysisFinished(), "Trying to add a resource entry after analysis."); var resources = singleton().resources; synchronized (resources) { Pair key = createStorageKey(module, resourceName); From 99195add564449f3c71dbf764a46309721dc44b6 Mon Sep 17 00:00:00 2001 From: ivan-ristovic Date: Thu, 11 May 2023 10:56:29 +0200 Subject: [PATCH 4/6] Mark Resources.addEntry as HOSTED_ONLY --- .../src/com/oracle/svm/core/jdk/Resources.java | 1 + 1 file changed, 1 insertion(+) 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 bf2c1956c7b3..8dc9472837a9 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 @@ -134,6 +134,7 @@ public static byte[] inputStreamToByteArray(InputStream is) { } } + @Platforms(Platform.HOSTED_ONLY.class) private static void addEntry(Module module, String resourceName, boolean isDirectory, byte[] data, boolean fromJar) { VMError.guarantee(!BuildPhaseProvider.isAnalysisFinished(), "Trying to add a resource entry after analysis."); var resources = singleton().resources; From 585ccd5c8cf6ed6d5910f1141304670fba1e7536 Mon Sep 17 00:00:00 2001 From: ivan-ristovic Date: Thu, 11 May 2023 13:18:16 +0200 Subject: [PATCH 5/6] Replace hosted modules before modifying the resource storage --- .../com/oracle/svm/core/jdk/Resources.java | 25 +++++----------- ...Support.java => RuntimeModuleSupport.java} | 23 +++++++++++--- .../jdk/Target_java_lang_ModuleLayer.java | 2 +- .../oracle/svm/hosted/ModuleLayerFeature.java | 30 +++++++------------ 4 files changed, 38 insertions(+), 42 deletions(-) rename substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/{BootModuleLayerSupport.java => RuntimeModuleSupport.java} (69%) 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 8dc9472837a9..733f75e6dd22 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 @@ -35,7 +35,6 @@ import java.util.Date; import java.util.Enumeration; import java.util.List; -import java.util.stream.StreamSupport; import com.oracle.svm.core.BuildPhaseProvider; import org.graalvm.collections.EconomicMap; @@ -87,20 +86,6 @@ public static Resources singleton() { Resources() { } - public static void replaceHostedModuleWithRuntimeModule(Module hostedModule, Module runtimeModule) { - var resources = singleton().resources; - synchronized (resources) { - var keysToUpdate = StreamSupport.stream(resources.getKeys().spliterator(), false) - .filter(k -> hostedModule.equals(k.getLeft())) - .toList(); - for (var oldKey : keysToUpdate) { - ResourceStorageEntry entry = resources.removeKey(oldKey); - var newKey = createStorageKey(runtimeModule, oldKey.getRight()); - resources.put(newKey, entry); - } - } - } - public EconomicMap, ResourceStorageEntry> getResourceStorage() { return resources; } @@ -137,9 +122,13 @@ public static byte[] inputStreamToByteArray(InputStream is) { @Platforms(Platform.HOSTED_ONLY.class) private static void addEntry(Module module, String resourceName, boolean isDirectory, byte[] data, boolean fromJar) { VMError.guarantee(!BuildPhaseProvider.isAnalysisFinished(), "Trying to add a resource entry after analysis."); + Module m = module != null && module.isNamed() ? module : null; + if (m != null) { + m = RuntimeModuleSupport.instance().getRuntimeModuleForHostedModule(m); + } var resources = singleton().resources; synchronized (resources) { - Pair key = createStorageKey(module, resourceName); + Pair key = createStorageKey(m, resourceName); ResourceStorageEntry entry = resources.get(key); if (entry == null) { if (singleton().lastModifiedTime == INVALID_TIMESTAMP) { @@ -290,7 +279,7 @@ public static InputStream createInputStream(Module module, String resourceName) * If module is not specified or is an unnamed module and entry was not found as * classpath-resource we have to search for the resource in all modules in the image. */ - for (Module m : BootModuleLayerSupport.instance().getBootLayer().modules()) { + for (Module m : RuntimeModuleSupport.instance().getBootLayer().modules()) { entry = Resources.get(m, resourceName); if (entry != null) { break; @@ -319,7 +308,7 @@ public static Enumeration createURLs(Module module, String resourceName) { boolean shouldAppendTrailingSlash = hasTrailingSlash(resourceName); /* If module was unspecified or unnamed, we have to consider all modules in the image */ if (moduleName(module) == null) { - for (Module m : BootModuleLayerSupport.instance().getBootLayer().modules()) { + for (Module m : RuntimeModuleSupport.instance().getBootLayer().modules()) { ResourceStorageEntry entry = Resources.get(m, resourceName); addURLEntries(resourcesURLs, entry, m, shouldAppendTrailingSlash ? canonicalResourceName + '/' : canonicalResourceName); } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/BootModuleLayerSupport.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RuntimeModuleSupport.java similarity index 69% rename from substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/BootModuleLayerSupport.java rename to substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RuntimeModuleSupport.java index cd397cc50d5f..0c90464fb5f1 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/BootModuleLayerSupport.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RuntimeModuleSupport.java @@ -30,15 +30,20 @@ import com.oracle.svm.core.heap.UnknownObjectField; -public final class BootModuleLayerSupport { +import java.util.function.Function; - public static BootModuleLayerSupport instance() { - return ImageSingletons.lookup(BootModuleLayerSupport.class); +public final class RuntimeModuleSupport { + + public static RuntimeModuleSupport instance() { + return ImageSingletons.lookup(RuntimeModuleSupport.class); } @UnknownObjectField private ModuleLayer bootLayer; - @Platforms(Platform.HOSTED_ONLY.class) + @Platforms(Platform.HOSTED_ONLY.class) // + private Function hostedToRuntimeModuleMapper; + + @Platforms(Platform.HOSTED_ONLY.class) // public void setBootLayer(ModuleLayer bootLayer) { this.bootLayer = bootLayer; } @@ -46,4 +51,14 @@ public void setBootLayer(ModuleLayer bootLayer) { public ModuleLayer getBootLayer() { return bootLayer; } + + @Platforms(Platform.HOSTED_ONLY.class) // + public void setHostedToRuntimeModuleMapper(Function hostedToRuntimeModuleMapper) { + this.hostedToRuntimeModuleMapper = hostedToRuntimeModuleMapper; + } + + public Module getRuntimeModuleForHostedModule(Module hostedModule) { + return hostedToRuntimeModuleMapper.apply(hostedModule); + } + } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/Target_java_lang_ModuleLayer.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/Target_java_lang_ModuleLayer.java index 9f091def7d90..25d1e4dff325 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/Target_java_lang_ModuleLayer.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/Target_java_lang_ModuleLayer.java @@ -34,6 +34,6 @@ final class Target_java_lang_ModuleLayer { @SuppressWarnings("unused") @Substitute public static ModuleLayer boot() { - return BootModuleLayerSupport.instance().getBootLayer(); + return RuntimeModuleSupport.instance().getBootLayer(); } } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ModuleLayerFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ModuleLayerFeature.java index 6562dae766c3..e6eb5bd5463e 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ModuleLayerFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ModuleLayerFeature.java @@ -54,7 +54,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import com.oracle.svm.core.jdk.Resources; import jdk.internal.module.DefaultRoots; import jdk.internal.module.ModuleBootstrap; import jdk.internal.module.SystemModuleFinders; @@ -64,7 +63,7 @@ import com.oracle.svm.core.SubstrateOptions; import com.oracle.svm.core.SubstrateUtil; import com.oracle.svm.core.feature.InternalFeature; -import com.oracle.svm.core.jdk.BootModuleLayerSupport; +import com.oracle.svm.core.jdk.RuntimeModuleSupport; import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; import com.oracle.svm.core.util.VMError; import com.oracle.svm.util.ModuleSupport; @@ -127,7 +126,8 @@ public void duringSetup(DuringSetupAccess access) { .collect(Collectors.toSet()); Function clf = moduleLayerFeatureUtils::getClassLoaderForBootLayerModule; ModuleLayer runtimeBootLayer = synthesizeRuntimeModuleLayer(new ArrayList<>(List.of(ModuleLayer.empty())), accessImpl.imageClassLoader, baseModules, Set.of(), clf, null); - BootModuleLayerSupport.instance().setBootLayer(runtimeBootLayer); + RuntimeModuleSupport.instance().setBootLayer(runtimeBootLayer); + RuntimeModuleSupport.instance().setHostedToRuntimeModuleMapper(moduleLayerFeatureUtils::getOrCreateRuntimeModuleForHostedModule); /* * Register an object replacer that will ensure all references to hosted module instances @@ -137,28 +137,20 @@ public void duringSetup(DuringSetupAccess access) { } private Object replaceHostedModules(Object source) { - if (source instanceof Module) { - Module module = (Module) source; - Module runtimeModule = moduleLayerFeatureUtils.getOrCreateRuntimeModuleForHostedModule(module, module.getDescriptor()); - - /* - * Ensure that resources are using the synthesized runtime module instances - */ - Resources.replaceHostedModuleWithRuntimeModule(module, runtimeModule); - - return runtimeModule; + if (source instanceof Module module) { + return moduleLayerFeatureUtils.getOrCreateRuntimeModuleForHostedModule(module); } return source; } @Override public void afterRegistration(AfterRegistrationAccess access) { - ImageSingletons.add(BootModuleLayerSupport.class, new BootModuleLayerSupport()); + ImageSingletons.add(RuntimeModuleSupport.class, new RuntimeModuleSupport()); List bootLayerAutomaticModules = ModuleLayer.boot().modules() .stream() .filter(m -> m.isNamed() && m.getDescriptor().isAutomatic()) - .collect(Collectors.toList()); + .toList(); if (!bootLayerAutomaticModules.isEmpty()) { System.out.println("Warning: Detected automatic module(s) on the module-path of the image builder:" + System.lineSeparator() + bootLayerAutomaticModules.stream().map(ModuleLayerFeatureUtils::formatModule).collect(Collectors.joining(System.lineSeparator())) + @@ -227,7 +219,7 @@ public void afterAnalysis(AfterAnalysisAccess access) { Set rootModules = calculateRootModules(extraModules); List runtimeModuleLayers = synthesizeRuntimeModuleLayers(accessImpl, reachableModuleLayers, runtimeImageNamedModules, analysisReachableSyntheticModules, rootModules); ModuleLayer runtimeBootLayer = runtimeModuleLayers.get(0); - BootModuleLayerSupport.instance().setBootLayer(runtimeBootLayer); + RuntimeModuleSupport.instance().setBootLayer(runtimeBootLayer); /* * Ensure that runtime modules have the same relations (i.e., reads, opens and exports) as @@ -424,7 +416,7 @@ private ModuleLayer synthesizeRuntimeModuleLayer(List parentLayers, runtimeModuleLayer = moduleLayerFeatureUtils.createNewModuleLayerInstance(runtimeModuleLayerConfiguration); Map nameToModule = moduleLayerFeatureUtils.synthesizeNameToModule(runtimeModuleLayer, clf); for (Module syntheticModule : syntheticModules) { - Module runtimeSyntheticModule = moduleLayerFeatureUtils.getOrCreateRuntimeModuleForHostedModule(syntheticModule, syntheticModule.getDescriptor()); + Module runtimeSyntheticModule = moduleLayerFeatureUtils.getOrCreateRuntimeModuleForHostedModule(syntheticModule); nameToModule.putIfAbsent(runtimeSyntheticModule.getName(), runtimeSyntheticModule); moduleLayerFeatureUtils.patchModuleLayerField(runtimeSyntheticModule, runtimeModuleLayer); } @@ -739,9 +731,9 @@ public Module getRuntimeModuleForHostedModule(ClassLoader loader, String hostedM } } - public Module getOrCreateRuntimeModuleForHostedModule(Module hostedModule, ModuleDescriptor runtimeModuleDescriptor) { + public Module getOrCreateRuntimeModuleForHostedModule(Module hostedModule) { if (hostedModule.isNamed()) { - return getOrCreateRuntimeModuleForHostedModule(hostedModule.getClassLoader(), hostedModule.getName(), runtimeModuleDescriptor); + return getOrCreateRuntimeModuleForHostedModule(hostedModule.getClassLoader(), hostedModule.getName(), hostedModule.getDescriptor()); } else { return hostedModule == everyoneModule ? everyoneModule : allUnnamedModule; } From 571df36eb5b4062fc5fdcafc33b1a497140becf9 Mon Sep 17 00:00:00 2001 From: ivan-ristovic Date: Tue, 16 May 2023 16:45:15 +0200 Subject: [PATCH 6/6] Remove includedResourcesModules bookkeeping --- .../com/oracle/svm/core/jdk/Resources.java | 14 ++++++++++++- .../oracle/svm/hosted/ModuleLayerFeature.java | 11 +++++----- .../oracle/svm/hosted/ResourcesFeature.java | 21 +++---------------- 3 files changed, 21 insertions(+), 25 deletions(-) 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 733f75e6dd22..a2eae0e04215 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 @@ -35,6 +35,10 @@ import java.util.Date; import java.util.Enumeration; import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; import com.oracle.svm.core.BuildPhaseProvider; import org.graalvm.collections.EconomicMap; @@ -106,11 +110,19 @@ public static String moduleName(Module module) { return module == null ? null : module.getName(); } - public static Pair createStorageKey(Module module, String resourceName) { + private static Pair createStorageKey(Module module, String resourceName) { Module m = module != null && module.isNamed() ? module : null; return Pair.create(m, resourceName); } + public static Set getIncludedResourcesModules() { + return StreamSupport.stream(singleton().resources.getKeys().spliterator(), false) + .map(Pair::getLeft) + .filter(Objects::nonNull) + .map(Module::getName) + .collect(Collectors.toSet()); + } + public static byte[] inputStreamToByteArray(InputStream is) { try { return is.readAllBytes(); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ModuleLayerFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ModuleLayerFeature.java index e6eb5bd5463e..a2bafe9a29dd 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ModuleLayerFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ModuleLayerFeature.java @@ -54,6 +54,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import com.oracle.svm.core.jdk.Resources; import jdk.internal.module.DefaultRoots; import jdk.internal.module.ModuleBootstrap; import jdk.internal.module.SystemModuleFinders; @@ -68,6 +69,8 @@ import com.oracle.svm.core.util.VMError; import com.oracle.svm.util.ModuleSupport; import com.oracle.svm.util.ReflectionUtil; +import org.graalvm.nativeimage.Platform; +import org.graalvm.nativeimage.Platforms; /** * This feature: @@ -176,12 +179,7 @@ public void afterAnalysis(AfterAnalysisAccess access) { * is required when filtering the analysis reachable module set. */ Set extraModules = ModuleLayerFeatureUtils.parseModuleSetModifierProperty(ModuleSupport.PROPERTY_IMAGE_EXPLICITLY_ADDED_MODULES); - Set includedResourceModules = ImageSingletons.lookup(ResourcesFeature.class).includedResourcesModules - .stream() - .map(Module::getName) - .filter(Objects::nonNull) - .collect(Collectors.toSet()); - extraModules.addAll(includedResourceModules); + extraModules.addAll(Resources.getIncludedResourcesModules()); extraModules.stream().filter(Predicate.not(ModuleSupport.nonExplicitModules::contains)).forEach(moduleName -> { Optional module = accessImpl.imageClassLoader.findModule(moduleName); if (module.isEmpty()) { @@ -540,6 +538,7 @@ private void patchRuntimeModuleLayer(ModuleLayer runtimeModuleLayer, Map> runtimeModules; private final ImageClassLoader imageClassLoader; diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ResourcesFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ResourcesFeature.java index 45d3860b6e26..4bb60370b7d1 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ResourcesFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ResourcesFeature.java @@ -37,7 +37,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Set; @@ -47,7 +46,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.LongAdder; import java.util.regex.Pattern; -import java.util.stream.Collectors; import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; import org.graalvm.compiler.debug.DebugContext; @@ -137,8 +135,6 @@ public static class Options { private int loadedConfigurations; private ImageClassLoader imageClassLoader; - public final Set includedResourcesModules = new HashSet<>(); - private class ResourcesRegistryImpl extends ConditionalConfigurationRegistry implements ResourcesRegistry { private final ConfigurationTypeResolver configurationTypeResolver; @@ -228,7 +224,6 @@ private static final class ResourceCollectorImpl implements ResourceCollector { private final DebugContext debugContext; private final ResourcePattern[] includePatterns; private final ResourcePattern[] excludePatterns; - private final Set includedResourcesModules; private static final int WATCHDOG_RESET_AFTER_EVERY_N_RESOURCES = 1000; private static final int WATCHDOG_INITIAL_WARNING_AFTER_N_SECONDS = 60; @@ -239,12 +234,10 @@ private static final class ResourceCollectorImpl implements ResourceCollector { private volatile String currentlyProcessedEntry; ScheduledExecutorService scheduledExecutor; - private ResourceCollectorImpl(DebugContext debugContext, ResourcePattern[] includePatterns, ResourcePattern[] excludePatterns, Set includedResourcesModules, - Runnable heartbeatCallback) { + private ResourceCollectorImpl(DebugContext debugContext, ResourcePattern[] includePatterns, ResourcePattern[] excludePatterns, Runnable heartbeatCallback) { this.debugContext = debugContext; this.includePatterns = includePatterns; this.excludePatterns = excludePatterns; - this.includedResourcesModules = includedResourcesModules; this.heartbeatCallback = heartbeatCallback; this.reachedResourceEntries = new LongAdder(); @@ -307,21 +300,13 @@ public boolean isIncluded(Module module, String resourceName, URI resource) { @Override public void addResource(Module module, String resourceName, InputStream resourceStream, boolean fromJar) { - collectModule(module); registerResource(debugContext, module, resourceName, resourceStream, fromJar); } @Override public void addDirectoryResource(Module module, String dir, String content, boolean fromJar) { - collectModule(module); registerDirectoryResource(debugContext, module, dir, content, fromJar); } - - private void collectModule(Module module) { - if (module != null && module.isNamed()) { - includedResourcesModules.add(module); - } - } } @Override @@ -337,7 +322,7 @@ public void duringAnalysis(DuringAnalysisAccess access) { ResourcePattern[] includePatterns = compilePatterns(resourcePatternWorkSet); ResourcePattern[] excludePatterns = compilePatterns(excludedResourcePatterns); DebugContext debugContext = duringAnalysisAccess.getDebugContext(); - ResourceCollectorImpl collector = new ResourceCollectorImpl(debugContext, includePatterns, excludePatterns, includedResourcesModules, duringAnalysisAccess.bb.getHeartbeatCallback()); + ResourceCollectorImpl collector = new ResourceCollectorImpl(debugContext, includePatterns, excludePatterns, duringAnalysisAccess.bb.getHeartbeatCallback()); try { collector.prepareProgressReporter(); ImageSingletons.lookup(ClassLoaderSupport.class).collectResources(collector); @@ -351,7 +336,7 @@ private ResourcePattern[] compilePatterns(Set patterns) { return patterns.stream() .filter(s -> s.length() > 0) .map(this::makeResourcePattern) - .collect(Collectors.toList()) + .toList() .toArray(new ResourcePattern[]{}); }