Skip to content

Commit

Permalink
Replace ImageIncludeBuiltinModules special handling with generic per-…
Browse files Browse the repository at this point in the history
…module class-init
  • Loading branch information
olpaw committed Jun 2, 2021
1 parent bd34f5a commit 198457a
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 129 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,6 @@ private void applyEnabled(MacroOption.EnabledOption enabledOption, String argume
BuildConfiguration config = nativeImage.config;
if (!config.useJavaModules()) {
enabledOption.forEachPropertyValue(config, "ImageBuilderBootClasspath8", entry -> nativeImage.addImageBuilderBootClasspath(ClasspathUtils.stringToClasspath(entry)), PATH_SEPARATOR_REGEX);
} else {
enabledOption.forEachPropertyValue(config, "ImageIncludeBuiltinModules", entry -> nativeImage.addImageIncludeBuiltinModules(entry), ",");
}

if (!enabledOption.forEachPropertyValue(config, "ImageBuilderClasspath", entry -> nativeImage.addImageBuilderClasspath(ClasspathUtils.stringToClasspath(entry)), PATH_SEPARATOR_REGEX)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@
import com.oracle.svm.driver.MacroOption.EnabledOption;
import com.oracle.svm.driver.MacroOption.MacroOptionKind;
import com.oracle.svm.driver.MacroOption.Registry;
import com.oracle.svm.hosted.AbstractNativeImageClassLoaderSupport;
import com.oracle.svm.hosted.NativeImageGeneratorRunner;
import com.oracle.svm.hosted.NativeImageSystemClassLoader;
import com.oracle.svm.util.ModuleSupport;
Expand Down Expand Up @@ -239,7 +238,6 @@ private static <T> String oR(OptionKey<T> option) {
private final ArrayList<String> imageBuilderArgs = new ArrayList<>();
private final LinkedHashSet<Path> imageBuilderClasspath = new LinkedHashSet<>();
private final LinkedHashSet<Path> imageBuilderBootClasspath = new LinkedHashSet<>();
private final LinkedHashSet<String> imageIncludeBuiltinModules = new LinkedHashSet<>();
private final ArrayList<String> imageBuilderJavaArgs = new ArrayList<>();
private final LinkedHashSet<Path> imageClasspath = new LinkedHashSet<>();
private final LinkedHashSet<Path> imageProvidedClasspath = new LinkedHashSet<>();
Expand Down Expand Up @@ -1193,9 +1191,6 @@ private int completeImageBuild() {
// The following two are for backwards compatibility reasons. They should be removed.
imageBuilderJavaArgs.add("-Djdk.internal.lambda.eagerlyInitialize=false");
imageBuilderJavaArgs.add("-Djava.lang.invoke.InnerClassLambdaMetafactory.initializeLambdas=false");
if (!imageIncludeBuiltinModules.isEmpty()) {
imageBuilderJavaArgs.add("-D" + AbstractNativeImageClassLoaderSupport.PROPERTY_IMAGEINCLUDEBUILTINMODULES + "=" + String.join(",", imageIncludeBuiltinModules));
}

/* After JavaArgs consolidation add the user provided JavaArgs */
boolean afterOption = false;
Expand Down Expand Up @@ -1622,10 +1617,6 @@ void addImageBuilderBootClasspath(Path classpath) {
imageBuilderBootClasspath.add(canonicalize(classpath));
}

public void addImageIncludeBuiltinModules(String moduleName) {
imageIncludeBuiltinModules.add(moduleName);
}

void addImageBuilderJavaArgs(String... javaArgs) {
addImageBuilderJavaArgs(Arrays.asList(javaArgs));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,20 @@
package com.oracle.svm.hosted;

import java.io.File;
import java.io.IOException;
import java.lang.module.Configuration;
import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReader;
import java.lang.module.ModuleReference;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
Expand All @@ -48,7 +53,6 @@
import com.oracle.svm.core.option.SubstrateOptionsParser;
import com.oracle.svm.core.util.UserError;
import com.oracle.svm.core.util.VMError;
import com.oracle.svm.util.ModuleSupport;

import jdk.internal.module.Modules;

Expand All @@ -59,10 +63,13 @@ public class NativeImageClassLoaderSupport extends AbstractNativeImageClassLoade

private final ClassLoader classLoader;
private final ModuleLayer moduleLayerForImageBuild;
private final Map<String, Set<String>> packageToModuleNames;

NativeImageClassLoaderSupport(ClassLoader defaultSystemClassLoader, String[] classpath, String[] modulePath) {
super(defaultSystemClassLoader, classpath);

packageToModuleNames = new HashMap<>();

imagemp = Arrays.stream(modulePath).map(Paths::get).collect(Collectors.toUnmodifiableList());
buildmp = Arrays.stream(System.getProperty("jdk.module.path", "").split(File.pathSeparator)).map(Paths::get).collect(Collectors.toUnmodifiableList());

Expand Down Expand Up @@ -143,6 +150,11 @@ public Optional<Module> findModule(String moduleName) {
return moduleLayerForImageBuild.findModule(moduleName);
}

@Override
Set<String> findModuleNamesForPackage(String packageName) {
return packageToModuleNames.getOrDefault(packageName, Collections.emptySet());
}

@Override
void processAddExportsAndAddOpens(OptionValues parsedHostedOptions) {
LocatableMultiOptionValue.Strings addExports = NativeImageClassLoaderOptions.AddExports.getValue(parsedHostedOptions);
Expand Down Expand Up @@ -254,52 +266,69 @@ ClassLoader getClassLoader() {
return classLoader;
}

private static class ClassInitWithModules extends ClassInit {
private class ClassInitWithModules extends ClassInit {

ClassInitWithModules(ForkJoinPool executor, ImageClassLoader imageClassLoader, AbstractNativeImageClassLoaderSupport nativeImageClassLoader) {
super(executor, imageClassLoader, nativeImageClassLoader);
ClassInitWithModules(ForkJoinPool executor, ImageClassLoader imageClassLoader) {
super(executor, imageClassLoader);
}

@Override
protected void init() {
Set<String> modules = new HashSet<>();
modules.add("jdk.internal.vm.ci");

addOptionalModule(modules, "org.graalvm.sdk");
addOptionalModule(modules, "jdk.internal.vm.compiler");
addOptionalModule(modules, "com.oracle.graal.graal_enterprise");

String includeModulesStr = System.getProperty(PROPERTY_IMAGEINCLUDEBUILTINMODULES);
if (includeModulesStr != null) {
modules.addAll(Arrays.asList(includeModulesStr.split(",")));
}

for (String moduleResource : ModuleSupport.getSystemModuleResources(modules)) {
handleClassInModuleResource(moduleResource);
}

for (String moduleResource : ModuleSupport.getModuleResources(nativeImageClassLoader.modulepath())) {
handleClassInModuleResource(moduleResource);
ModuleFinder finder = ModuleFinder.compose(ModuleFinder.ofSystem(), ModuleFinder.of(modulepath().toArray(Path[]::new)));
for (ModuleReference moduleReference : finder.findAll()) {
try (ModuleReader moduleReader = moduleReference.open()) {
moduleReader.list().forEach(moduleResource -> {
handleModuleResource(moduleReference.descriptor().name(), moduleResource);
});
} catch (IOException e) {
throw new RuntimeException("Unable get list of resources in module" + moduleReference.descriptor().name(), e);
}
}

super.init();
}

private void handleClassInModuleResource(String moduleResource) {
private void handleModuleResource(String moduleName, String moduleResource) {
if (!moduleResource.startsWith("META-INF/")) {
addToPackageNameModules(moduleName, moduleResource);
}
if (moduleResource.endsWith(CLASS_EXTENSION)) {
executor.execute(() -> handleClassFileName(classFileWithoutSuffix(moduleResource), '/'));
}
}

private static void addOptionalModule(Set<String> modules, String name) {
if (ModuleSupport.hasSystemModule(name)) {
modules.add(name);
private void addToPackageNameModules(String moduleName, String moduleResource) {
int packageSep = moduleResource.lastIndexOf('/');
String packageName = packageSep > 0 ? moduleResource.substring(0, packageSep).replace('/', '.') : "";
Set<String> prevValue = packageToModuleNames.get(packageName);
if (prevValue == null) {
/* Mostly packageName is only used in a single module */
packageToModuleNames.put(packageName, Collections.singleton(moduleName));
} else if (prevValue.size() == 1) {
/* Transition to HashSet - happens rarely */
HashSet<String> newValue = new HashSet<>();
newValue.add(prevValue.iterator().next());
newValue.add(moduleName);
packageToModuleNames.put(packageName, newValue);
} else if (prevValue.size() > 1) {
/* Add to exiting HashSet - happens rarely */
prevValue.add(moduleName);
}
}
}

@Override
public void initAllClasses(ForkJoinPool executor, ImageClassLoader imageClassLoader) {
new ClassInitWithModules(executor, imageClassLoader, this).init();
new ClassInitWithModules(executor, imageClassLoader).init();
// dumpPackageNameModulesMapping();
}

public void dumpPackageNameModulesMapping() {
packageToModuleNames.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.map(e -> e.getKey() + " -> " + e.getValue().stream()
.map(mn -> (findModule(mn).isEmpty() ? "*" : "") + mn)
.collect(Collectors.joining(", ")))
.forEach(System.out::println);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,6 @@

public abstract class AbstractNativeImageClassLoaderSupport {

/*
* This cannot be a HostedOption because all Subclasses of OptionDescriptors from inside builtin
* modules need to be initialized prior to option parsing so that they can be found.
*/
public static final String PROPERTY_IMAGEINCLUDEBUILTINMODULES = "substratevm.ImageIncludeBuiltinModules";

final List<Path> imagecp;
private final List<Path> buildcp;

Expand Down Expand Up @@ -113,6 +107,8 @@ ClassLoader getClassLoader() {

abstract Optional<? extends Object> findModule(String moduleName);

abstract Set<String> findModuleNamesForPackage(String packageName);

abstract void processAddExportsAndAddOpens(OptionValues parsedHostedOptions);

abstract void initAllClasses(ForkJoinPool executor, ImageClassLoader imageClassLoader);
Expand Down Expand Up @@ -154,35 +150,33 @@ static Path urlToPath(URL url) {
}
}

protected static class ClassInit {
protected class ClassInit {

protected final ForkJoinPool executor;
protected final ImageClassLoader imageClassLoader;
protected final AbstractNativeImageClassLoaderSupport nativeImageClassLoader;

ClassInit(ForkJoinPool executor, ImageClassLoader imageClassLoader, AbstractNativeImageClassLoaderSupport nativeImageClassLoader) {
ClassInit(ForkJoinPool executor, ImageClassLoader imageClassLoader) {
this.executor = executor;
this.imageClassLoader = imageClassLoader;
this.nativeImageClassLoader = nativeImageClassLoader;
}

protected void init() {
Set<Path> uniquePaths = new TreeSet<>(Comparator.comparing(ClassInit::toRealPath));
uniquePaths.addAll(nativeImageClassLoader.classpath());
Set<Path> uniquePaths = new TreeSet<>(Comparator.comparing(this::toRealPath));
uniquePaths.addAll(classpath());
uniquePaths.parallelStream().forEach(path -> loadClassesFromPath(path));
}

private static Path toRealPath(Path p) {
private Path toRealPath(Path p) {
try {
return p.toRealPath();
} catch (IOException e) {
throw VMError.shouldNotReachHere("Path.toRealPath failed for " + p, e);
}
}

private static final Set<Path> excludeDirectories = getExcludeDirectories();
private final Set<Path> excludeDirectories = getExcludeDirectories();

private static Set<Path> getExcludeDirectories() {
private Set<Path> getExcludeDirectories() {
Path root = Paths.get("/");
return Stream.of("dev", "sys", "proc", "etc", "var", "tmp", "boot", "lost+found")
.map(root::resolve).collect(Collectors.toSet());
Expand Down Expand Up @@ -278,7 +272,7 @@ private String unversionedFileName(String fileName) {
}
}

static String classFileWithoutSuffix(String result) {
String classFileWithoutSuffix(String result) {
return result.substring(0, result.length() - CLASS_EXTENSION.length());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
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;
Expand Down Expand Up @@ -418,10 +419,14 @@ public Class<?> loadClassFromModule(Object module, String className) throws Clas
return classLoaderSupport.loadClassFromModule(module, className);
}

public Optional<Object> findModule(String moduleName) {
public Optional<? extends Object> findModule(String moduleName) {
return classLoaderSupport.findModule(moduleName);
}

public Set<String> findModuleNamesForPackage(String packageName) {
return classLoaderSupport.findModuleNamesForPackage(packageName);
}

public void processAddExportsAndAddOpens(OptionValues parsedHostedOptions) {
classLoaderSupport.processAddExportsAndAddOpens(parsedHostedOptions);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ForkJoinPool;

import org.graalvm.compiler.options.OptionValues;
Expand All @@ -53,6 +54,11 @@ public Optional<Object> findModule(String moduleName) {
return Optional.empty();
}

@Override
public Set<String> findModuleNamesForPackage(String packageName) {
return Collections.emptySet();
}

@Override
void processAddExportsAndAddOpens(OptionValues parsedHostedOptions) {
/* Nothing to do for Java 8 */
Expand All @@ -69,6 +75,6 @@ Class<?> loadClassFromModule(Object module, String className) throws ClassNotFou

@Override
public void initAllClasses(ForkJoinPool executor, ImageClassLoader imageClassLoader) {
new ClassInit(executor, imageClassLoader, this).init();
new ClassInit(executor, imageClassLoader).init();
}
}
Loading

0 comments on commit 198457a

Please sign in to comment.