Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JDK-8340655] [GR-58466] Fix source launcher regression. #9773

Merged
merged 9 commits into from
Sep 28, 2024
5 changes: 5 additions & 0 deletions compiler/mx.compiler/mx_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,11 @@ def apply(self, config):
if limited_modules is None or jmd.name in limited_modules:
mainClassArgs.extend(['-JUnitOpenPackages', jmd.name + '/*'])
vmArgs.append('--add-modules=' + jmd.name)
for dependency, packages in jmd.concealedRequires.items():
if dependency != "jdk.internal.vm.ci":
# JVMCI exporting is done dynamically
for p in packages:
vmArgs.append(f'--add-exports={dependency}/{p}={jmd.name}')

vmArgs.append('-Djdk.graal.TrackNodeSourcePosition=true')
vmArgs.append('-esa')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,9 @@ static class Options {

@Override
public HotSpotGraalCompiler createCompiler(JVMCIRuntime runtime) {
ensureInitialized();
HotSpotJVMCIRuntime hsRuntime = (HotSpotJVMCIRuntime) runtime;
checkUnsafeAccess(hsRuntime);
ensureInitialized();
if (optionsFailure != null) {
System.err.printf("Error parsing Graal options: %s%nError: A fatal exception has occurred. Program will exit.%n", optionsFailure.getMessage());
HotSpotGraalServices.exit(1, hsRuntime);
Expand All @@ -195,6 +196,28 @@ public HotSpotGraalCompiler createCompiler(JVMCIRuntime runtime) {
return compiler;
}

/**
* Exit the VM now if {@code jdk.internal.misc.Unsafe} is not accessible.
*/
private void checkUnsafeAccess(HotSpotJVMCIRuntime hsRuntime) {
if (Services.IS_IN_NATIVE_IMAGE) {
// Access checks were performed when building libgraal.
return;
}
try {
jdk.internal.misc.Unsafe.getUnsafe();
} catch (IllegalAccessError e) {
Module module = getClass().getModule();
String targets = module.getName();
String ee = "com.oracle.graal.graal_enterprise";
if (module.getDescriptor().exports().stream().anyMatch(export -> export.targets().contains(ee))) {
targets += "," + ee;
}
System.err.printf("Error: jargraal requires --add-exports=java.base/jdk.internal.misc=%s to be specified to the launcher.%n", targets);
HotSpotGraalServices.exit(1, hsRuntime);
}
}

/**
* Creates a new {@link HotSpotGraalRuntime} object and a new {@link HotSpotGraalCompiler} and
* returns the latter.
Expand Down
6 changes: 5 additions & 1 deletion sdk/mx.sdk/mx_sdk_vm.py
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,11 @@ def _get_image_vm_options(jdk, use_upgrade_module_path, modules, synthetic_modul
if default_to_jvmci == 'lib':
vm_options.append('-XX:+UseJVMCINativeLibrary')
vm_options.extend(['-XX:-UnlockExperimentalVMOptions'])
if 'jdk.graal.compiler' in non_synthetic_modules:
import mx_sdk_vm_impl
if 'jdk.graal.compiler' in non_synthetic_modules and mx_sdk_vm_impl._get_libgraal_component() is None:
# If libgraal is absent, jargraal is used by default.
# Use of jargraal requires exporting jdk.internal.misc to
# Graal as it uses jdk.internal.misc.Unsafe.
if 'com.oracle.graal.graal_enterprise' in non_synthetic_modules:
vm_options.extend(['--add-exports=java.base/jdk.internal.misc=jdk.graal.compiler,com.oracle.graal.graal_enterprise'])
else:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
*/
package com.oracle.svm.graal.hotspot;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
Expand Down Expand Up @@ -65,6 +67,35 @@ public class GetCompilerConfig {
public record Result(String encodedConfig, Map<String, Set<String>> opens) {
}

/**
* Tests whether {@code module} is in the boot layer.
*
* @param javaExe java executable
* @param module name of the module to test
*/
private static boolean isInBootLayer(Path javaExe, String module) {
String search = "jrt:/" + module;
String[] command = {javaExe.toString(), "--show-module-resolution", "--version"};
try {
Process p = new ProcessBuilder(command).start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
boolean found = false;
while ((line = reader.readLine()) != null) {
if (line.contains(search)) {
found = true;
}
}
int exitValue = p.waitFor();
if (exitValue != 0) {
throw new GraalError("Command finished with exit value %d: %s", exitValue, String.join(" ", command));
}
return found;
} catch (Exception e) {
throw new GraalError(e, "Error running command: %s", String.join(" ", command));
}
}

/**
* Launches the JVM in {@code javaHome} to run {@link CompilerConfig}.
*
Expand All @@ -81,11 +112,18 @@ public static Result from(Path javaHome, OptionValues options) {
// java.util.ImmutableCollections.EMPTY
"java.base", Set.of("java.util"));

// Only modules in the boot layer can be the target of --add-exports
String addExports = "--add-exports=java.base/jdk.internal.misc=jdk.graal.compiler";
if (isInBootLayer(javaExe, "com.oracle.graal.graal_enterprise")) {
addExports += ",com.oracle.graal.graal_enterprise";
}

List<String> command = new ArrayList<>(List.of(
javaExe.toFile().getAbsolutePath(),
"-XX:+UnlockExperimentalVMOptions",
"-XX:+EnableJVMCI",
"-XX:-UseJVMCICompiler", // avoid deadlock with jargraal
addExports,
"-Djdk.vm.ci.services.aot=true"));

Module module = ObjectCopier.class.getModule();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
*/
package com.oracle.svm.hosted.image;

import static com.oracle.svm.core.SubstrateOptions.DeleteLocalSymbols;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
Expand Down Expand Up @@ -127,7 +129,7 @@ private static void stripLinux(AfterImageWriteAccessImpl accessImpl) {

private static Path createKeepSymbolsListFile(AfterImageWriteAccessImpl accessImpl) throws IOException {
Path exportedSymbolsPath = accessImpl.getTempDirectory().resolve("keep-symbols.list").toAbsolutePath();
Files.write(exportedSymbolsPath, accessImpl.getImageSymbols(true));
Files.write(exportedSymbolsPath, accessImpl.getImageSymbols(DeleteLocalSymbols.getValue()));
return exportedSymbolsPath;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,8 @@ protected List<Class<?>> findTargetClasses() {
protected void handleClass(Class<?> annotatedClass) {
guarantee(Modifier.isFinal(annotatedClass.getModifiers()) || annotatedClass.isInterface(), "Annotated class must be final: %s", annotatedClass);
guarantee(annotatedClass.getSuperclass() == Object.class || annotatedClass.isInterface(), "Annotated class must inherit directly from Object: %s", annotatedClass);
guarantee(annotatedClass.getDeclaringClass() == null || Modifier.isStatic(annotatedClass.getModifiers()),
"Annotated class must be a static inner class, or a top-level class: %s", annotatedClass);

if (!NativeImageGenerator.includedIn(ImageSingletons.lookup(Platform.class), lookupAnnotation(annotatedClass, Platforms.class))) {
return;
Expand Down
9 changes: 9 additions & 0 deletions vm/mx.vm/mx_vm_gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,15 @@ def _test_libgraal_fatal_error_handling(extra_vm_arguments):
pass
else:
mx.abort('Expected "Fatal error in JVMCI" to be in contents of ' + hs_err + ':' + linesep + contents)
# check that the hs_err contains libgraal symbols on supported platforms
symbol_patterns = {
'linux' : 'com.oracle.svm.core.jdk.VMErrorSubstitutions::doShutdown',
'darwin' : 'VMErrorSubstitutions_doShutdown',
'windows' : None
}
pattern = symbol_patterns[mx.get_os()]
if pattern and pattern not in contents:
mx.abort('Expected "' + pattern + '" to be in contents of ' + hs_err + ':' + linesep + contents)

if 'JVMCINativeLibraryErrorFile' in out.data and not seen_libjvmci_log:
mx.abort('Expected a file matching "hs_err_pid*_libjvmci.log" in test directory. Entries found=' + str(listdir(scratch_dir)))
Expand Down