From 51fa66dcb48975461b9e2c6bbc0fea21eb978883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Tue, 5 Sep 2023 15:32:22 +0200 Subject: [PATCH 01/18] Use ModuleFinder to collect names of application modules --- .../com/oracle/svm/driver/NativeImage.java | 116 ++++-------------- 1 file changed, 26 insertions(+), 90 deletions(-) diff --git a/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java b/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java index cfa4f4f15caa..04339766cce7 100644 --- a/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java +++ b/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java @@ -48,12 +48,10 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.ListIterator; import java.util.Map; -import java.util.Objects; import java.util.Optional; import java.util.Properties; import java.util.Set; @@ -62,7 +60,6 @@ import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Function; -import java.util.function.Predicate; import java.util.jar.Attributes; import java.util.jar.JarFile; import java.util.jar.Manifest; @@ -1534,8 +1531,6 @@ protected int buildImage(List javaArgs, LinkedHashSet cp, LinkedHa arguments.addAll(strings); } - String javaExecutable = canonicalize(config.getJavaExecutable()).toString(); - if (useBundle()) { LogUtils.warning("Native Image Bundles are an experimental feature."); } @@ -1548,20 +1543,24 @@ protected int buildImage(List javaArgs, LinkedHashSet cp, LinkedHa List finalImageClassPath = imagecp.stream().map(substituteClassPath).collect(Collectors.toList()); Function substituteModulePath = useBundle() ? bundleSupport::substituteModulePath : Function.identity(); - List substitutedImageModulePath = imagemp.stream().map(substituteModulePath).toList(); + List finalImageModulePath = imagemp.stream().map(substituteModulePath).toList(); - Map modules = listModulesFromPath(javaExecutable, Stream.concat(mp.stream(), imagemp.stream()).distinct().toList()); + Map applicationModules = getApplicationModules(finalImageModulePath); if (!addModules.isEmpty()) { arguments.add("-D" + ModuleSupport.PROPERTY_IMAGE_EXPLICITLY_ADDED_MODULES + "=" + String.join(",", addModules)); List addModulesForBuilderVM = new ArrayList<>(); - for (String module : addModules) { - Path jarPath = modules.get(module); - if (jarPath == null) { - // boot module - addModulesForBuilderVM.add(module); + for (String moduleNameInAddModules : addModules) { + if (!applicationModules.containsKey(moduleNameInAddModules)) { + /* + * Module names given to native-image --add-modules that are not referring + * modules that are passed to native-image via -p/--module-path are considered + * to be part of the module-layer that contains the builder itself. Those module + * names need to be passed as --add-modules arguments to the builder VM. + */ + addModulesForBuilderVM.add(moduleNameInAddModules); } } @@ -1580,43 +1579,20 @@ protected int buildImage(List javaArgs, LinkedHashSet cp, LinkedHa arguments.addAll(Arrays.asList(SubstrateOptions.WATCHPID_PREFIX, "" + ProcessProperties.getProcessID())); } - /* - * Workaround for GR-47186: Native image cannot handle modules on the image module path, - * that are also already installed in the JDK as boot module. As a workaround we filter all - * modules from the module-path that are either already installed in the JDK as boot module, - * or were explicitly added to the builder module-path. - * - * First compute all module-jar paths that are not on the builder module-path. - */ - Set nonBuilderModulePaths = modules.values().stream() - .filter(Objects::nonNull) - .filter(Predicate.not(mp::contains)) - .collect(Collectors.toSet()); - - /* - * Now we need to filter the substituted module path list for all the modules that may - * remain on the module-path. - * - * This should normally not be necessary, as the nonBuilderModulePaths should already be the - * set of jar files for the image module path. Nevertheless, we use the original definition - * of the module path to preserve the order of the original module path and as a precaution - * to protect against --list-modules returning too many modules. - */ - List finalImageModulePath = substitutedImageModulePath.stream() - .filter(nonBuilderModulePaths::contains) - .toList(); - List finalImageBuilderArgs = createImageBuilderArgs(finalImageArgs, finalImageClassPath, finalImageModulePath); /* Construct ProcessBuilder command from final arguments */ List command = new ArrayList<>(); List completeCommandList = new ArrayList<>(); + String javaExecutable; if (useBundle() && bundleSupport.useContainer) { ContainerSupport.replacePaths(arguments, config.getJavaHome(), bundleSupport.rootDir); ContainerSupport.replacePaths(finalImageBuilderArgs, config.getJavaHome(), bundleSupport.rootDir); Path binJava = Paths.get("bin", "java"); javaExecutable = ContainerSupport.GRAAL_VM_HOME.resolve(binJava).toString(); + } else { + javaExecutable = canonicalize(config.getJavaExecutable()).toString(); } Path argFile = createVMInvocationArgumentFile(arguments); @@ -1718,65 +1694,25 @@ protected int buildImage(List javaArgs, LinkedHashSet cp, LinkedHa } } - /** - * Resolves and lists all modules given a module path. - * - * @see #callListModules(String, List) - */ - private Map listModulesFromPath(String javaExecutable, Collection modulePath) { - if (modulePath.isEmpty() || !config.modulePathBuild) { + private Map getApplicationModules(Collection modulePath) { + if (!config.modulePathBuild || modulePath.isEmpty()) { return Map.of(); } - String modulePathEntries = modulePath.stream() - .map(Path::toString) - .collect(Collectors.joining(File.pathSeparator)); - return callListModules(javaExecutable, List.of("-p", modulePathEntries)); - } - /** - * Calls java $arguments --list-modules to list all modules and parse the output. - * The output consists of a map with module name as key and {@link Path} to jar file if the - * module is not installed as part of the JDK. If the module is installed as part of the - * jdk/boot-layer then a null path will be returned. - *

- * This is a much more robust solution then trying to parse the JDK file structure manually. - */ - private static Map callListModules(String javaExecutable, List arguments) { - Process listModulesProcess = null; - Map result = new LinkedHashMap<>(); + Map applicationModules = new HashMap<>(); try { - var pb = new ProcessBuilder(javaExecutable); - pb.command().addAll(arguments); - pb.command().add("--list-modules"); - pb.environment().clear(); - listModulesProcess = pb.start(); - - List lines; - try (var br = new BufferedReader(new InputStreamReader(listModulesProcess.getInputStream()))) { - lines = br.lines().toList(); - } - int exitStatus = listModulesProcess.waitFor(); - if (exitStatus != 0) { - throw showError("Determining image-builder observable modules failed (Exit status %d). Process output: %n%s".formatted(exitStatus, String.join(System.lineSeparator(), lines))); - } - for (String line : lines) { - String[] splitString = StringUtil.split(line, " ", 3); - String[] splitModuleNameAndVersion = StringUtil.split(splitString[0], "@", 2); - Path externalPath = null; - if (splitString.length > 1) { - String pathURI = splitString[1]; // url: file://path/to/file - externalPath = Path.of(URI.create(pathURI)).toAbsolutePath(); + ModuleFinder finder = ModuleFinder.of(modulePath.toArray(Path[]::new)); + for (ModuleReference mref : finder.findAll()) { + Optional optionalURI = mref.location(); + if (optionalURI.isEmpty()) { + continue; } - result.put(splitModuleNameAndVersion[0], externalPath); - } - } catch (IOException | InterruptedException e) { - throw showError(e.getMessage()); - } finally { - if (listModulesProcess != null) { - listModulesProcess.destroy(); + applicationModules.put(mref.descriptor().name(), Path.of(optionalURI.get())); } + } catch (FindException e) { + throw showError("Failed to collect ModuleReferences for module-path entries " + modulePath, e); } - return result; + return applicationModules; } /** From 4711d66a430463f21bcdab6b101f76820fca544c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Wed, 6 Sep 2023 11:17:11 +0200 Subject: [PATCH 02/18] Remove pre-python 3 support code --- substratevm/mx.substratevm/mx_substratevm.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/substratevm/mx.substratevm/mx_substratevm.py b/substratevm/mx.substratevm/mx_substratevm.py index 9d118dd13a28..16a1c1c2f5fd 100644 --- a/substratevm/mx.substratevm/mx_substratevm.py +++ b/substratevm/mx.substratevm/mx_substratevm.py @@ -26,8 +26,6 @@ # # ---------------------------------------------------------------------------------------------------- -from __future__ import print_function - import os import re import tempfile @@ -38,6 +36,7 @@ from argparse import ArgumentParser import fnmatch import collections +from io import StringIO import mx import mx_compiler @@ -56,10 +55,6 @@ import sys -if sys.version_info[0] < 3: - from StringIO import StringIO -else: - from io import StringIO suite = mx.suite('substratevm') svmSuites = [suite] From ee34fb4781b0ab10e5560216f49c466212b0cfbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Thu, 14 Sep 2023 15:47:45 +0200 Subject: [PATCH 03/18] Fix SyntaxWarning: invalid escape sequence '\.' --- java-benchmarks/mx.java-benchmarks/mx_java_benchmarks.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/java-benchmarks/mx.java-benchmarks/mx_java_benchmarks.py b/java-benchmarks/mx.java-benchmarks/mx_java_benchmarks.py index a5ffcf16a7b1..954ec4d9db6b 100644 --- a/java-benchmarks/mx.java-benchmarks/mx_java_benchmarks.py +++ b/java-benchmarks/mx.java-benchmarks/mx_java_benchmarks.py @@ -535,11 +535,11 @@ def extra_image_build_argument(self, benchmark, args): '-J--add-exports=org.graalvm.nativeimage/org.graalvm.nativeimage.impl=ALL-UNNAMED', '-J--add-exports=org.graalvm.nativeimage.builder/com.oracle.svm.core.jdk=ALL-UNNAMED', '--exclude-config' , - 'io\.netty\.netty-codec', - '/META-INF/native-image/io\.netty/netty-codec/generated/handlers/reflect-config\.json', + 'io\\.netty\\.netty-codec', + '/META-INF/native-image/io\\.netty/netty-codec/generated/handlers/reflect-config\\.json', '--exclude-config', - 'io\.netty\.netty-handler', - '/META-INF/native-image/io\.netty/netty-handler/generated/handlers/reflect-config\.json', + 'io\\.netty\\.netty-handler', + '/META-INF/native-image/io\\.netty/netty-handler/generated/handlers/reflect-config\\.json', '-H:-AddAllCharsets', '-H:+ReportExceptionStackTraces', ] + mx_sdk_vm_impl.svm_experimental_options([ From 77deacbc5f7713d70c743f1c685233cb3c5506ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Thu, 14 Sep 2023 18:06:55 +0200 Subject: [PATCH 04/18] Remove modules from -imagemp that are already provided by other means --- substratevm/mx.substratevm/suite.py | 5 +++ .../com/oracle/svm/core/jdk/JRTSupport.java | 2 +- .../com/oracle/svm/driver/NativeImage.java | 42 ++++++++++++++----- 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/substratevm/mx.substratevm/suite.py b/substratevm/mx.substratevm/suite.py index c2bd3225190b..98b8deb1e711 100644 --- a/substratevm/mx.substratevm/suite.py +++ b/substratevm/mx.substratevm/suite.py @@ -853,6 +853,11 @@ "requires" : [ "jdk.management", ], + "requiresConcealed" : { + "java.base" : [ + "jdk.internal.jimage", + ], + }, "checkstyle": "com.oracle.svm.hosted", "workingSets": "SVM", "annotationProcessors": [ diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JRTSupport.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JRTSupport.java index 795cd42e1cd9..63650cd6ec21 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JRTSupport.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JRTSupport.java @@ -98,7 +98,7 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { // region Enable jimage/jrtfs -@TargetClass(className = "jdk.internal.jimage.ImageReader", innerClass = "SharedImageReader", onlyWith = JRTEnabled.class) +@TargetClass(className = "jdk.internal.jimage.ImageReader", innerClass = "SharedImageReader") final class Target_jdk_internal_jimage_ImageReader_SharedImageReader_JRTEnabled { @Alias // @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.NewInstance, declClass = HashMap.class, isFinal = true) // diff --git a/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java b/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java index 04339766cce7..6b48005c1ab0 100644 --- a/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java +++ b/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java @@ -48,6 +48,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.ListIterator; @@ -103,6 +104,8 @@ import com.oracle.svm.util.ReflectionUtil; import com.oracle.svm.util.StringUtil; +import jdk.internal.jimage.ImageReader; + public class NativeImage { private static final String DEFAULT_GENERATOR_CLASS_NAME = NativeImageGeneratorRunner.class.getName(); @@ -1543,9 +1546,15 @@ protected int buildImage(List javaArgs, LinkedHashSet cp, LinkedHa List finalImageClassPath = imagecp.stream().map(substituteClassPath).collect(Collectors.toList()); Function substituteModulePath = useBundle() ? bundleSupport::substituteModulePath : Function.identity(); - List finalImageModulePath = imagemp.stream().map(substituteModulePath).toList(); + List imageModulePath = imagemp.stream().map(substituteModulePath).collect(Collectors.toList()); + Map applicationModules = getModulesFromPath(imageModulePath); + + // Remove modules that we already have built-in + applicationModules.keySet().removeAll(getBuiltInModules()); + // Remove modules that we get from the builder + applicationModules.keySet().removeAll(getModulesFromPath(mp).keySet()); + List finalImageModulePath = applicationModules.values().stream().toList(); - Map applicationModules = getApplicationModules(finalImageModulePath); if (!addModules.isEmpty()) { arguments.add("-D" + ModuleSupport.PROPERTY_IMAGE_EXPLICITLY_ADDED_MODULES + "=" + @@ -1555,7 +1564,7 @@ protected int buildImage(List javaArgs, LinkedHashSet cp, LinkedHa for (String moduleNameInAddModules : addModules) { if (!applicationModules.containsKey(moduleNameInAddModules)) { /* - * Module names given to native-image --add-modules that are not referring + * Module names given to native-image --add-modules that are not referring to * modules that are passed to native-image via -p/--module-path are considered * to be part of the module-layer that contains the builder itself. Those module * names need to be passed as --add-modules arguments to the builder VM. @@ -1694,25 +1703,36 @@ protected int buildImage(List javaArgs, LinkedHashSet cp, LinkedHa } } - private Map getApplicationModules(Collection modulePath) { + private Set getBuiltInModules() { + Path jdkRoot = config.rootDir; + try { + var reader = ImageReader.open(jdkRoot.resolve("lib/modules")); + System.out.println("Modules from " + jdkRoot.resolve("lib/modules") + ":"); + System.out.println(String.join("\n", reader.getModuleNames())); + return new LinkedHashSet<>(List.of(reader.getModuleNames())); + } catch (IOException e) { + throw showError("Unable to determine builtin modules of JDK in " + jdkRoot, e); + } + } + + private Map getModulesFromPath(Collection modulePath) { if (!config.modulePathBuild || modulePath.isEmpty()) { return Map.of(); } - Map applicationModules = new HashMap<>(); + LinkedHashMap mrefs = new LinkedHashMap<>(); try { ModuleFinder finder = ModuleFinder.of(modulePath.toArray(Path[]::new)); for (ModuleReference mref : finder.findAll()) { - Optional optionalURI = mref.location(); - if (optionalURI.isEmpty()) { - continue; - } - applicationModules.put(mref.descriptor().name(), Path.of(optionalURI.get())); + String moduleName = mref.descriptor().name(); + VMError.guarantee(moduleName != null && !moduleName.isEmpty(), "Unnamed module on modulePath"); + URI moduleLocation = mref.location().orElseThrow(() -> VMError.shouldNotReachHere("ModuleReference for module " + moduleName + " has no location.")); + mrefs.put(moduleName, Path.of(moduleLocation)); } } catch (FindException e) { throw showError("Failed to collect ModuleReferences for module-path entries " + modulePath, e); } - return applicationModules; + return mrefs; } /** From 8882a7c56a6a90a43da3dcac75be174de004f57b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Tue, 19 Sep 2023 11:31:14 +0200 Subject: [PATCH 05/18] Remove debug code --- .../src/com/oracle/svm/driver/NativeImage.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java b/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java index 6b48005c1ab0..4faf976d6ef0 100644 --- a/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java +++ b/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java @@ -1707,8 +1707,6 @@ private Set getBuiltInModules() { Path jdkRoot = config.rootDir; try { var reader = ImageReader.open(jdkRoot.resolve("lib/modules")); - System.out.println("Modules from " + jdkRoot.resolve("lib/modules") + ":"); - System.out.println(String.join("\n", reader.getModuleNames())); return new LinkedHashSet<>(List.of(reader.getModuleNames())); } catch (IOException e) { throw showError("Unable to determine builtin modules of JDK in " + jdkRoot, e); From f8978ee1a0f52e7b82a60f438106079784279e51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Tue, 19 Sep 2023 15:34:55 +0200 Subject: [PATCH 06/18] On Windows jdk native library jimage does not depend on stdc++ --- .../src/com/oracle/svm/hosted/jdk/JRTFeature.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JRTFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JRTFeature.java index 425aab252ba1..0efa8ce18fa5 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JRTFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JRTFeature.java @@ -24,8 +24,10 @@ */ package com.oracle.svm.hosted.jdk; -import com.oracle.svm.core.feature.InternalFeature; +import org.graalvm.nativeimage.Platform; + import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; +import com.oracle.svm.core.feature.InternalFeature; import com.oracle.svm.hosted.FeatureImpl; @AutomaticallyRegisteredFeature @@ -36,7 +38,9 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { access.registerReachabilityHandler(duringAnalysisAccess -> { FeatureImpl.BeforeAnalysisAccessImpl beforeAnalysisAccess = (FeatureImpl.BeforeAnalysisAccessImpl) access; beforeAnalysisAccess.getNativeLibraries().addStaticJniLibrary("jimage"); - beforeAnalysisAccess.getNativeLibraries().addDynamicNonJniLibrary("stdc++"); + if (!Platform.includedIn(Platform.WINDOWS.class)) { + beforeAnalysisAccess.getNativeLibraries().addDynamicNonJniLibrary("stdc++"); + } }, access.findClassByName("jdk.internal.jimage.NativeImageBuffer")); } } From d38dd40e01cbf90503ef2a5a3505a3ab03bae1d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Tue, 19 Sep 2023 15:35:39 +0200 Subject: [PATCH 07/18] Building driver into image requires JRTFileSystem support --- substratevm/mx.substratevm/mx_substratevm.py | 1 + .../src/com/oracle/svm/core/jdk/JRTSupport.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/substratevm/mx.substratevm/mx_substratevm.py b/substratevm/mx.substratevm/mx_substratevm.py index 16a1c1c2f5fd..ddef1ad8f578 100644 --- a/substratevm/mx.substratevm/mx_substratevm.py +++ b/substratevm/mx.substratevm/mx_substratevm.py @@ -1012,6 +1012,7 @@ def _native_image_launcher_extra_jvm_args(): '--initialize-at-build-time=com.oracle.svm.driver', '--link-at-build-time=com.oracle.svm.driver,com.oracle.svm.driver.metainf', ] + svm_experimental_options([ + '-H:+AllowJRTFileSystem', '-H:IncludeResources=com/oracle/svm/driver/launcher/.*', '-H:-ParseRuntimeOptions', f'-R:MaxHeapSize={256 * 1024 * 1024}', diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JRTSupport.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JRTSupport.java index 63650cd6ec21..795cd42e1cd9 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JRTSupport.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JRTSupport.java @@ -98,7 +98,7 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { // region Enable jimage/jrtfs -@TargetClass(className = "jdk.internal.jimage.ImageReader", innerClass = "SharedImageReader") +@TargetClass(className = "jdk.internal.jimage.ImageReader", innerClass = "SharedImageReader", onlyWith = JRTEnabled.class) final class Target_jdk_internal_jimage_ImageReader_SharedImageReader_JRTEnabled { @Alias // @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.NewInstance, declClass = HashMap.class, isFinal = true) // From 38eb6dfeb3c153849d979d54695113a9211bb8dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Tue, 19 Sep 2023 16:00:50 +0200 Subject: [PATCH 08/18] Fix return type of substituted method --- .../src/com/oracle/svm/core/jdk/JRTSupport.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JRTSupport.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JRTSupport.java index 795cd42e1cd9..9d4134828395 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JRTSupport.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JRTSupport.java @@ -115,7 +115,7 @@ final class Target_jdk_internal_module_SystemModuleFinders_SystemImage_JRTEnable static volatile Target_jdk_internal_jimage_ImageReader_JRTEnabled READER; @Substitute - static Object reader() { + static Target_jdk_internal_jimage_ImageReader_JRTEnabled reader() { Target_jdk_internal_jimage_ImageReader_JRTEnabled localRef = READER; if (localRef == null) { synchronized (Target_jdk_internal_module_SystemModuleFinders_SystemImage_JRTEnabled.class) { From a9686e243bef9a23308a0c2f77e7371c8559e39b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Wed, 20 Sep 2023 15:17:49 +0200 Subject: [PATCH 09/18] Ensure libstdc++ gets statically linked into agents --- substratevm/mx.substratevm/mx_substratevm.py | 8 ++++++-- .../src/com/oracle/svm/core/SubstrateOptions.java | 8 +------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/substratevm/mx.substratevm/mx_substratevm.py b/substratevm/mx.substratevm/mx_substratevm.py index ddef1ad8f578..b4873a0aaad8 100644 --- a/substratevm/mx.substratevm/mx_substratevm.py +++ b/substratevm/mx.substratevm/mx_substratevm.py @@ -1072,7 +1072,9 @@ def _native_image_launcher_extra_jvm_args(): build_args=driver_build_args + [ '--features=com.oracle.svm.agent.NativeImageAgent$RegistrationFeature', '--enable-url-protocols=jar', - ], + ] + svm_experimental_options([ + '-H:+StaticExecutableWithDynamicLibC', + ]), headers=False, home_finder=False, ), @@ -1086,7 +1088,9 @@ def _native_image_launcher_extra_jvm_args(): ], build_args=driver_build_args + [ '--features=com.oracle.svm.diagnosticsagent.NativeImageDiagnosticsAgent$RegistrationFeature', - ], + ] + svm_experimental_options([ + '-H:+StaticExecutableWithDynamicLibC', + ]), headers=False, home_finder=False, ), diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java index a9dd1be14e2a..76a899b51cc5 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java @@ -154,13 +154,7 @@ protected void onValueUpdate(EconomicMap, Object> values, String ol }; @Option(help = "Builds a statically linked executable with libc dynamically linked", type = Expert, stability = OptionStability.EXPERIMENTAL)// - public static final HostedOptionKey StaticExecutableWithDynamicLibC = new HostedOptionKey<>(false) { - @Override - protected void onValueUpdate(EconomicMap, Object> values, Boolean oldValue, Boolean newValue) { - StaticExecutable.update(values, true); - super.onValueUpdate(values, oldValue, newValue); - } - }; + public static final HostedOptionKey StaticExecutableWithDynamicLibC = new HostedOptionKey<>(false); public static final int ForceFallback = 10; public static final int Automatic = 5; From f8e965013527d5e16be4365320e6bdbbfaaba05b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Wed, 20 Sep 2023 17:00:29 +0200 Subject: [PATCH 10/18] Implement -H:+StaticLibStdCpp and use if for building the agents --- substratevm/mx.substratevm/mx_substratevm.py | 4 +-- .../com/oracle/svm/core/SubstrateOptions.java | 3 ++ .../svm/hosted/image/CCLinkerInvocation.java | 30 ++++++++++++------- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/substratevm/mx.substratevm/mx_substratevm.py b/substratevm/mx.substratevm/mx_substratevm.py index b4873a0aaad8..feccebadce7e 100644 --- a/substratevm/mx.substratevm/mx_substratevm.py +++ b/substratevm/mx.substratevm/mx_substratevm.py @@ -1073,7 +1073,7 @@ def _native_image_launcher_extra_jvm_args(): '--features=com.oracle.svm.agent.NativeImageAgent$RegistrationFeature', '--enable-url-protocols=jar', ] + svm_experimental_options([ - '-H:+StaticExecutableWithDynamicLibC', + '-H:+StaticLibStdCpp', ]), headers=False, home_finder=False, @@ -1089,7 +1089,7 @@ def _native_image_launcher_extra_jvm_args(): build_args=driver_build_args + [ '--features=com.oracle.svm.diagnosticsagent.NativeImageDiagnosticsAgent$RegistrationFeature', ] + svm_experimental_options([ - '-H:+StaticExecutableWithDynamicLibC', + '-H:+StaticLibStdCpp', ]), headers=False, home_finder=False, diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java index 76a899b51cc5..ea509ef9291f 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java @@ -156,6 +156,9 @@ protected void onValueUpdate(EconomicMap, Object> values, String ol @Option(help = "Builds a statically linked executable with libc dynamically linked", type = Expert, stability = OptionStability.EXPERIMENTAL)// public static final HostedOptionKey StaticExecutableWithDynamicLibC = new HostedOptionKey<>(false); + @Option(help = "Builds image with libstdc++ statically linked into the image (if needed)", type = Expert, stability = OptionStability.EXPERIMENTAL)// + public static final HostedOptionKey StaticLibStdCpp = new HostedOptionKey<>(false); + public static final int ForceFallback = 10; public static final int Automatic = 5; public static final int NoFallback = 0; diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/CCLinkerInvocation.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/CCLinkerInvocation.java index af8a0291451c..a982109e5cb0 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/CCLinkerInvocation.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/CCLinkerInvocation.java @@ -31,13 +31,11 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; -import com.oracle.svm.core.BuildDirectoryProvider; import org.graalvm.compiler.options.Option; import org.graalvm.compiler.options.OptionStability; import org.graalvm.nativeimage.ImageSingletons; @@ -45,6 +43,7 @@ import com.oracle.objectfile.ObjectFile; import com.oracle.objectfile.macho.MachOSymtab; +import com.oracle.svm.core.BuildDirectoryProvider; import com.oracle.svm.core.LinkerInvocation; import com.oracle.svm.core.OS; import com.oracle.svm.core.SubstrateOptions; @@ -250,8 +249,8 @@ protected List getNativeLinkerOptions() { private static class BinutilsCCLinkerInvocation extends CCLinkerInvocation { - private final boolean staticExecWithDynamicallyLinkLibC = SubstrateOptions.StaticExecutableWithDynamicLibC.getValue(); - private final Set libCLibaries = new HashSet<>(Arrays.asList("pthread", "dl", "rt", "m")); + private final boolean dynamicLibC = SubstrateOptions.StaticExecutableWithDynamicLibC.getValue(); + private final boolean staticLibCpp = SubstrateOptions.StaticLibStdCpp.getValue(); BinutilsCCLinkerInvocation(AbstractImage.NativeImageKind imageKind, NativeLibraries nativeLibs, List symbols) { super(imageKind, nativeLibs, symbols); @@ -314,7 +313,7 @@ protected void setOutputKind(List cmd) { cmd.add("-Wl,--export-dynamic"); break; case STATIC_EXECUTABLE: - if (!staticExecWithDynamicallyLinkLibC) { + if (!dynamicLibC && !staticLibCpp) { cmd.add("-static"); } break; @@ -326,21 +325,32 @@ protected void setOutputKind(List cmd) { } } + private static final Set LIB_C_NAMES = Set.of("pthread", "dl", "rt", "m"); + @Override protected List getLibrariesCommand() { List cmd = new ArrayList<>(); + if (dynamicLibC || staticLibCpp) { + cmd.add("-Wl,--push-state"); + } for (String lib : libs) { - if (staticExecWithDynamicallyLinkLibC) { - String linkingMode = libCLibaries.contains(lib) - ? "dynamic" - : "static"; + String linkingMode = null; + if (dynamicLibC) { + linkingMode = LIB_C_NAMES.contains(lib) ? "dynamic" : "static"; + } else if (staticLibCpp) { + linkingMode = lib.equals("stdc++") ? "static" : "dynamic"; + } + if (linkingMode != null) { cmd.add("-Wl,-B" + linkingMode); } cmd.add("-l" + lib); } + if (dynamicLibC || staticLibCpp) { + cmd.add("-Wl,--pop-state"); + } // Make sure libgcc gets statically linked - if (staticExecWithDynamicallyLinkLibC) { + if (dynamicLibC || staticLibCpp) { cmd.add("-static-libgcc"); } return cmd; From ffdd704c3881dc691bf22b9fc8b5a55c7eb9212d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Thu, 21 Sep 2023 11:25:18 +0200 Subject: [PATCH 11/18] Ensure `ModuleFinder.of` and `ImageReader.open` are not used when imageModulePath is empty --- .../src/com/oracle/svm/driver/NativeImage.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java b/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java index 4faf976d6ef0..ad389aacf8f2 100644 --- a/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java +++ b/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java @@ -1549,10 +1549,12 @@ protected int buildImage(List javaArgs, LinkedHashSet cp, LinkedHa List imageModulePath = imagemp.stream().map(substituteModulePath).collect(Collectors.toList()); Map applicationModules = getModulesFromPath(imageModulePath); - // Remove modules that we already have built-in - applicationModules.keySet().removeAll(getBuiltInModules()); - // Remove modules that we get from the builder - applicationModules.keySet().removeAll(getModulesFromPath(mp).keySet()); + if (!applicationModules.isEmpty()) { + // Remove modules that we already have built-in + applicationModules.keySet().removeAll(getBuiltInModules()); + // Remove modules that we get from the builder + applicationModules.keySet().removeAll(getModulesFromPath(mp).keySet()); + } List finalImageModulePath = applicationModules.values().stream().toList(); if (!addModules.isEmpty()) { From 04a68cad0a1e2139a7ef50988824063405dad25d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Thu, 21 Sep 2023 11:36:29 +0200 Subject: [PATCH 12/18] Only use full driver build args when building the driver image --- substratevm/mx.substratevm/mx_substratevm.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/substratevm/mx.substratevm/mx_substratevm.py b/substratevm/mx.substratevm/mx_substratevm.py index feccebadce7e..87e35f107020 100644 --- a/substratevm/mx.substratevm/mx_substratevm.py +++ b/substratevm/mx.substratevm/mx_substratevm.py @@ -1011,7 +1011,9 @@ def _native_image_launcher_extra_jvm_args(): '--features=com.oracle.svm.driver.APIOptionFeature', '--initialize-at-build-time=com.oracle.svm.driver', '--link-at-build-time=com.oracle.svm.driver,com.oracle.svm.driver.metainf', -] + svm_experimental_options([ +] + +driver_exe_build_args = driver_build_args + svm_experimental_options([ '-H:+AllowJRTFileSystem', '-H:IncludeResources=com/oracle/svm/driver/launcher/.*', '-H:-ParseRuntimeOptions', @@ -1054,7 +1056,7 @@ def _native_image_launcher_extra_jvm_args(): destination="bin/", jar_distributions=["substratevm:SVM_DRIVER"], main_class=_native_image_launcher_main_class(), - build_args=driver_build_args, + build_args=driver_exe_build_args, extra_jvm_args=_native_image_launcher_extra_jvm_args(), home_finder=False, ), @@ -1072,9 +1074,7 @@ def _native_image_launcher_extra_jvm_args(): build_args=driver_build_args + [ '--features=com.oracle.svm.agent.NativeImageAgent$RegistrationFeature', '--enable-url-protocols=jar', - ] + svm_experimental_options([ - '-H:+StaticLibStdCpp', - ]), + ], headers=False, home_finder=False, ), @@ -1088,9 +1088,7 @@ def _native_image_launcher_extra_jvm_args(): ], build_args=driver_build_args + [ '--features=com.oracle.svm.diagnosticsagent.NativeImageDiagnosticsAgent$RegistrationFeature', - ] + svm_experimental_options([ - '-H:+StaticLibStdCpp', - ]), + ], headers=False, home_finder=False, ), From 8ce7298bd6e3a6a21006063c0f8482e80fa4dfb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Mon, 25 Sep 2023 14:43:05 +0200 Subject: [PATCH 13/18] Remove obsolete agent-based image build code. --- .../oracle/svm/agent/NativeImageAgent.java | 58 +------------------ .../com/oracle/svm/driver/NativeImage.java | 8 --- 2 files changed, 2 insertions(+), 64 deletions(-) diff --git a/substratevm/src/com.oracle.svm.agent/src/com/oracle/svm/agent/NativeImageAgent.java b/substratevm/src/com.oracle.svm.agent/src/com/oracle/svm/agent/NativeImageAgent.java index 19bbbb5e4d89..1de088372e64 100644 --- a/substratevm/src/com.oracle.svm.agent/src/com/oracle/svm/agent/NativeImageAgent.java +++ b/substratevm/src/com.oracle.svm.agent/src/com/oracle/svm/agent/NativeImageAgent.java @@ -38,7 +38,6 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Arrays; import java.util.ConcurrentModificationException; import java.util.Date; import java.util.List; @@ -76,12 +75,10 @@ import com.oracle.svm.configure.filters.HierarchyFilterNode; import com.oracle.svm.configure.trace.AccessAdvisor; import com.oracle.svm.configure.trace.TraceProcessor; -import com.oracle.svm.core.SubstrateUtil; import com.oracle.svm.core.configure.ConfigurationFile; import com.oracle.svm.core.jni.headers.JNIEnvironment; import com.oracle.svm.core.jni.headers.JNIJavaVM; import com.oracle.svm.core.jni.headers.JNIObjectHandle; -import com.oracle.svm.driver.NativeImage; import com.oracle.svm.driver.metainf.NativeImageMetaInfWalker; import com.oracle.svm.jvmtiagentbase.JNIHandleSet; import com.oracle.svm.jvmtiagentbase.JvmtiAgentBase; @@ -143,7 +140,6 @@ protected int onLoadCallback(JNIJavaVM vm, JvmtiEnv jvmti, JvmtiEventCallbacks c boolean experimentalClassDefineSupport = false; boolean experimentalUnsafeAllocationSupport = false; boolean experimentalOmitClasspathConfig = false; - boolean build = false; boolean configurationWithOrigins = false; List conditionalConfigUserPackageFilterFiles = new ArrayList<>(); List conditionalConfigClassNameFilterFiles = new ArrayList<>(); @@ -206,8 +202,6 @@ protected int onLoadCallback(JNIJavaVM vm, JvmtiEnv jvmti, JvmtiEventCallbacks c if (configWritePeriodInitialDelay < 0) { return usage(1, "config-write-initial-delay-secs must be an integer greater or equal to 0"); } - } else if (isBooleanOption(token, "build")) { - build = getBooleanTokenValue(token); } else if (isBooleanOption(token, "experimental-configuration-with-origins")) { configurationWithOrigins = getBooleanTokenValue(token); } else if (token.startsWith("experimental-conditional-config-filter-file=")) { @@ -223,9 +217,9 @@ protected int onLoadCallback(JNIJavaVM vm, JvmtiEnv jvmti, JvmtiEventCallbacks c } } - if (traceOutputFile == null && configOutputDir == null && !build) { + if (traceOutputFile == null && configOutputDir == null) { configOutputDir = transformPath(AGENT_NAME + "_config-pid{pid}-{datetime}/"); - inform("no output/build options provided, tracking dynamic accesses and writing configuration to directory: " + configOutputDir); + inform("no output options provided, tracking dynamic accesses and writing configuration to directory: " + configOutputDir); } if (configurationWithOrigins && !conditionalConfigUserPackageFilterFiles.isEmpty()) { @@ -377,14 +371,6 @@ protected int onLoadCallback(JNIJavaVM vm, JvmtiEnv jvmti, JvmtiEventCallbacks c } } - if (build) { - int status = buildImage(jvmti); - if (status == 0) { - System.exit(status); - } - return status; - } - try { BreakpointInterceptor.onLoad(jvmti, callbacks, tracer, this, interceptedStateSupplier, experimentalClassLoaderSupport, experimentalClassDefineSupport, experimentalUnsafeAllocationSupport, trackReflectionMetadata); @@ -504,46 +490,6 @@ private static void ignoreConfigFromClasspath(JvmtiEnv jvmti, ConfigurationFileC private static final Pattern propertyBlacklist = Pattern.compile("(java\\..*)|(sun\\..*)|(jvmci\\..*)"); private static final Pattern propertyWhitelist = Pattern.compile("(java\\.library\\.path)|(java\\.io\\.tmpdir)"); - private static int buildImage(JvmtiEnv jvmti) { - System.out.println("Building native image ..."); - String classpath = Support.getSystemProperty(jvmti, "java.class.path"); - if (classpath == null) { - return usage(1, "Build mode could not determine classpath."); - } - String javaCommand = Support.getSystemProperty(jvmti, "sun.java.command"); - String mainClassMissing = "Build mode could not determine main class."; - if (javaCommand == null) { - return usage(1, mainClassMissing); - } - String mainClass = SubstrateUtil.split(javaCommand, " ")[0]; - if (mainClass.isEmpty()) { - return usage(1, mainClassMissing); - } - List buildArgs = new ArrayList<>(); - // buildArgs.add("--verbose"); - String[] keys = Support.getSystemProperties(jvmti); - for (String key : keys) { - boolean whitelisted = propertyWhitelist.matcher(key).matches(); - boolean blacklisted = !whitelisted && propertyBlacklist.matcher(key).matches(); - if (blacklisted) { - continue; - } - buildArgs.add("-D" + key + "=" + Support.getSystemProperty(jvmti, key)); - } - if (mainClass.toLowerCase().endsWith(".jar")) { - buildArgs.add("-jar"); - } else { - buildArgs.addAll(Arrays.asList("-cp", classpath)); - } - buildArgs.add(mainClass); - buildArgs.add(AGENT_NAME + ".build"); - // System.out.println(String.join("\n", buildArgs)); - Path javaHome = Paths.get(Support.getSystemProperty(jvmti, "java.home")); - String userDirStr = Support.getSystemProperty(jvmti, "user.dir"); - NativeImage.agentBuild(javaHome, userDirStr == null ? null : Paths.get(userDirStr), buildArgs); - return 0; - } - private static String transformPath(String path) { String result = path; if (result.contains("{pid}")) { diff --git a/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java b/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java index ad389aacf8f2..98407ad3f4d0 100644 --- a/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java +++ b/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java @@ -1814,14 +1814,6 @@ public static void main(String[] args) { performBuild(new BuildConfiguration(Arrays.asList(args)), defaultNativeImageProvider); } - public static void build(BuildConfiguration config) { - build(config, defaultNativeImageProvider); - } - - public static void agentBuild(Path javaHome, Path workDir, List buildArgs) { - performBuild(new BuildConfiguration(javaHome, workDir, buildArgs), NativeImage::new); - } - public static List translateAPIOptions(List arguments) { var handler = new APIOptionHandler(new NativeImage(new BuildConfiguration(arguments))); var argumentQueue = new ArgumentQueue(OptionOrigin.originDriver); From c629a5c75dc88499bcacf3fea2104db8a4816e22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Tue, 3 Oct 2023 14:07:48 +0200 Subject: [PATCH 14/18] Ensure jimage static jdk library get statically linked --- .../src/com/oracle/svm/hosted/jdk/JRTFeature.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JRTFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JRTFeature.java index 0efa8ce18fa5..1aece66a616e 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JRTFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JRTFeature.java @@ -28,6 +28,7 @@ import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; import com.oracle.svm.core.feature.InternalFeature; +import com.oracle.svm.core.jdk.NativeLibrarySupport; import com.oracle.svm.hosted.FeatureImpl; @AutomaticallyRegisteredFeature @@ -37,6 +38,7 @@ public class JRTFeature implements InternalFeature { public void beforeAnalysis(BeforeAnalysisAccess access) { access.registerReachabilityHandler(duringAnalysisAccess -> { FeatureImpl.BeforeAnalysisAccessImpl beforeAnalysisAccess = (FeatureImpl.BeforeAnalysisAccessImpl) access; + NativeLibrarySupport.singleton().preregisterUninitializedBuiltinLibrary("jimage"); beforeAnalysisAccess.getNativeLibraries().addStaticJniLibrary("jimage"); if (!Platform.includedIn(Platform.WINDOWS.class)) { beforeAnalysisAccess.getNativeLibraries().addDynamicNonJniLibrary("stdc++"); From 744bafbd5bd56c49edb00924d64d5b65684d38df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Wed, 4 Oct 2023 16:50:05 +0200 Subject: [PATCH 15/18] Do not allow jdk.internal.jimage.NativeImageBuffer at image-runtime --- .../com/oracle/svm/core/jdk/JRTSupport.java | 18 +++++++ .../com/oracle/svm/hosted/jdk/JRTFeature.java | 48 ------------------- 2 files changed, 18 insertions(+), 48 deletions(-) delete mode 100644 substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JRTFeature.java diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JRTSupport.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JRTSupport.java index 9d4134828395..1596cf19ff15 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JRTSupport.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JRTSupport.java @@ -28,6 +28,7 @@ import java.io.IOException; import java.net.URL; import java.net.URLConnection; +import java.nio.ByteBuffer; import java.nio.file.Path; import java.util.Arrays; import java.util.HashMap; @@ -178,3 +179,20 @@ final class Target_jdk_internal_jrtfs_JrtFileSystemProvider_JRTDisabled { } // endregion Disable jimage/jrtfs + +@TargetClass(className = "jdk.internal.jimage.BasicImageReader") +final class Target_jdk_internal_jimage_BasicImageReader { + /* Ensure NativeImageBuffer never gets used as part of using BasicImageReader */ + @Alias // + @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.FromAlias, isFinal = true) // + static boolean USE_JVM_MAP = false; +} + +@TargetClass(className = "jdk.internal.jimage.NativeImageBuffer") +@Substitute +final class Target_jdk_internal_jimage_NativeImageBuffer { + @Substitute + static ByteBuffer getNativeMap(String imagePath) { + throw VMError.unsupportedFeature("Using jdk.internal.jimage.NativeImageBuffer is not supported"); + } +} diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JRTFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JRTFeature.java deleted file mode 100644 index 1aece66a616e..000000000000 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JRTFeature.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2021, 2021, 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.hosted.jdk; - -import org.graalvm.nativeimage.Platform; - -import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; -import com.oracle.svm.core.feature.InternalFeature; -import com.oracle.svm.core.jdk.NativeLibrarySupport; -import com.oracle.svm.hosted.FeatureImpl; - -@AutomaticallyRegisteredFeature -public class JRTFeature implements InternalFeature { - - @Override - public void beforeAnalysis(BeforeAnalysisAccess access) { - access.registerReachabilityHandler(duringAnalysisAccess -> { - FeatureImpl.BeforeAnalysisAccessImpl beforeAnalysisAccess = (FeatureImpl.BeforeAnalysisAccessImpl) access; - NativeLibrarySupport.singleton().preregisterUninitializedBuiltinLibrary("jimage"); - beforeAnalysisAccess.getNativeLibraries().addStaticJniLibrary("jimage"); - if (!Platform.includedIn(Platform.WINDOWS.class)) { - beforeAnalysisAccess.getNativeLibraries().addDynamicNonJniLibrary("stdc++"); - } - }, access.findClassByName("jdk.internal.jimage.NativeImageBuffer")); - } -} From b764ee762af8c452f90f82b814b117f9c7c36c18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Wed, 4 Oct 2023 17:08:28 +0200 Subject: [PATCH 16/18] Checkstyle fix --- .../src/com/oracle/svm/core/jdk/JRTSupport.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JRTSupport.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JRTSupport.java index 1596cf19ff15..a17bbd2e0abd 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JRTSupport.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JRTSupport.java @@ -185,7 +185,9 @@ final class Target_jdk_internal_jimage_BasicImageReader { /* Ensure NativeImageBuffer never gets used as part of using BasicImageReader */ @Alias // @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.FromAlias, isFinal = true) // + // Checkstyle: stop static boolean USE_JVM_MAP = false; + // Checkstyle: resume } @TargetClass(className = "jdk.internal.jimage.NativeImageBuffer") From 4b6d8b811585479f95cb8ed4ed3ccbbe13bbe33a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Tue, 10 Oct 2023 15:47:02 +0200 Subject: [PATCH 17/18] Factor out common use of `dynamicLibC || staticLibCpp` --- .../com/oracle/svm/hosted/image/CCLinkerInvocation.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/CCLinkerInvocation.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/CCLinkerInvocation.java index a982109e5cb0..14de7653ec1b 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/CCLinkerInvocation.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/CCLinkerInvocation.java @@ -251,6 +251,7 @@ private static class BinutilsCCLinkerInvocation extends CCLinkerInvocation { private final boolean dynamicLibC = SubstrateOptions.StaticExecutableWithDynamicLibC.getValue(); private final boolean staticLibCpp = SubstrateOptions.StaticLibStdCpp.getValue(); + private final boolean customStaticLibs = dynamicLibC || staticLibCpp; BinutilsCCLinkerInvocation(AbstractImage.NativeImageKind imageKind, NativeLibraries nativeLibs, List symbols) { super(imageKind, nativeLibs, symbols); @@ -313,7 +314,7 @@ protected void setOutputKind(List cmd) { cmd.add("-Wl,--export-dynamic"); break; case STATIC_EXECUTABLE: - if (!dynamicLibC && !staticLibCpp) { + if (!customStaticLibs) { cmd.add("-static"); } break; @@ -330,7 +331,7 @@ protected void setOutputKind(List cmd) { @Override protected List getLibrariesCommand() { List cmd = new ArrayList<>(); - if (dynamicLibC || staticLibCpp) { + if (customStaticLibs) { cmd.add("-Wl,--push-state"); } for (String lib : libs) { @@ -345,12 +346,12 @@ protected List getLibrariesCommand() { } cmd.add("-l" + lib); } - if (dynamicLibC || staticLibCpp) { + if (customStaticLibs) { cmd.add("-Wl,--pop-state"); } // Make sure libgcc gets statically linked - if (dynamicLibC || staticLibCpp) { + if (customStaticLibs) { cmd.add("-static-libgcc"); } return cmd; From 5f35fcaf3f850fa43f0adeb4ad6c18a6c895f106 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Tue, 10 Oct 2023 15:51:15 +0200 Subject: [PATCH 18/18] Note removal of native-image-agent `build`-option in CHANGELOG --- substratevm/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/substratevm/CHANGELOG.md b/substratevm/CHANGELOG.md index a925c670defb..e7a6a40047b0 100644 --- a/substratevm/CHANGELOG.md +++ b/substratevm/CHANGELOG.md @@ -6,6 +6,7 @@ This changelog summarizes major changes to GraalVM Native Image. * (GR-48304) Red Hat added support for the JFR event ThreadAllocationStatistics. * (GR-48343) Red Hat added support for the JFR events AllocationRequiringGC and SystemGC. * (GR-48612) Enable `--strict-image-heap` by default. The option is now deprecated and can be removed from your argument list. A blog post with more information will follow shortly. +* (GR-48354) Remove native-image-agent legacy `build`-option ## GraalVM for JDK 21 (Internal Version 23.1.0) * (GR-35746) Lower the default aligned chunk size from 1 MB to 512 KB for the serial and epsilon GCs, reducing memory usage and image size in many cases.