From fd494f375166094e167f7b26a38c2fb624fb816d Mon Sep 17 00:00:00 2001 From: Gilles Duboscq Date: Fri, 3 May 2024 18:10:26 +0200 Subject: [PATCH 01/16] Generate the espresso runtime resources The goal is to later be able to tweak the resource ID based on JDK version etc. --- .../espresso_runtime_resource.template | 53 +++++ espresso/mx.espresso/mx_espresso.py | 184 ++++++++++++++---- espresso/mx.espresso/suite.py | 32 --- 3 files changed, 203 insertions(+), 66 deletions(-) create mode 100644 espresso/mx.espresso/espresso_runtime_resource.template diff --git a/espresso/mx.espresso/espresso_runtime_resource.template b/espresso/mx.espresso/espresso_runtime_resource.template new file mode 100644 index 000000000000..0d79ece54150 --- /dev/null +++ b/espresso/mx.espresso/espresso_runtime_resource.template @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024, 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. + * + * 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 ; + +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.InternalResource; + +import java.io.IOException; +import java.nio.file.Path; + +@InternalResource.Id(value = "", componentId = "java", optional = true) +public final class EspressoRuntimeResource implements InternalResource { + + private static Path basePath(Env env) { + return Path.of("META-INF", "resources", "java", "", env.getOS().toString(), env.getCPUArchitecture().toString()); + } + + @Override + public void unpackFiles(Env env, Path targetDirectory) throws IOException { + Path base = basePath(env); + env.unpackResourceFiles(base.resolve("files"), targetDirectory, base); + } + + @Override + public String versionHash(Env env) { + try { + Path hashResource = basePath(env).resolve("sha256"); + return env.readResourceLines(hashResource).get(0); + } catch (IOException ioe) { + throw CompilerDirectives.shouldNotReachHere(ioe); + } + } +} diff --git a/espresso/mx.espresso/mx_espresso.py b/espresso/mx.espresso/mx_espresso.py index c86e83de391a..f2bc1aa3c8ae 100644 --- a/espresso/mx.espresso/mx_espresso.py +++ b/espresso/mx.espresso/mx_espresso.py @@ -28,13 +28,15 @@ import subprocess import mx +import mx_jardistribution +import mx_subst import mx_util import mx_espresso_benchmarks # pylint: disable=unused-import import mx_sdk_vm import mx_sdk_vm_impl from mx_gate import Task, add_gate_runner from mx_jackpot import jackpot -from os.path import join, isabs, exists +from os.path import join, isabs, exists, dirname, relpath _suite = mx.suite('espresso') @@ -185,7 +187,7 @@ def _espresso_gate_runner(args, tasks): To fix the issue, run this gate locally: {instructions} And adapt the code to the modified headers in '{committed}'. -""".format(committed=os.path.relpath(mokapot_dir, _suite.vc_dir), generated=os.path.relpath(libjavavm_dir, _suite.vc_dir), instructions=run_instructions)) +""".format(committed=relpath(mokapot_dir, _suite.vc_dir), generated=relpath(libjavavm_dir, _suite.vc_dir), instructions=run_instructions)) class EspressoLegacyNativeImageProperties(mx.Project): @@ -418,38 +420,67 @@ def mx_register_dynamic_suite_constituents(register_project, register_distributi "lib/", "man", ] - register_distribution(mx.LayoutDirDistribution(_suite, "ESPRESSO_RUNTIME_DIR", - deps=[], - layout={ - "META-INF/resources/java/espresso-runtime///": { - "source_type": "dependency", - "dependency": "JAVA_HOME", - "path": "*", - "exclude": [ - "include", - "jmods", - "lib/ct.sym", - "lib/jfr", - "lib/jvm.cfg", - "lib/src.zip", - "lib/static", - ] + platform_specific_excludes, - }, - "META-INF/resources/java/espresso-runtime///lib/llvm/": llvm_runtime_dir, - }, - path=None, - platformDependent=True, - platforms=[ - "linux-amd64", - "linux-aarch64", - "darwin-amd64", - "darwin-aarch64", - "windows-amd64", - ], - theLicense=None, - hashEntry="META-INF/resources/java/espresso-runtime///sha256", - fileListEntry="META-INF/resources/java/espresso-runtime///files", - maven=False)) + register_distribution(mx.LayoutDirDistribution( + _suite, "ESPRESSO_RUNTIME_DIR", + deps=[], + layout={ + "META-INF/resources/java/espresso-runtime///": { + "source_type": "dependency", + "dependency": "JAVA_HOME", + "path": "*", + "exclude": [ + "include", + "jmods", + "lib/ct.sym", + "lib/jfr", + "lib/jvm.cfg", + "lib/src.zip", + "lib/static", + ] + platform_specific_excludes, + }, + "META-INF/resources/java/espresso-runtime///lib/llvm/": llvm_runtime_dir, + }, + path=None, + platformDependent=True, + platforms=[ + "linux-amd64", + "linux-aarch64", + "darwin-amd64", + "darwin-aarch64", + "windows-amd64", + ], + theLicense=None, # TODO + hashEntry="META-INF/resources/java/espresso-runtime///sha256", + fileListEntry="META-INF/resources/java/espresso-runtime///files", + maven=False)) + + if register_project: + # com.oracle.truffle.espresso.resources.runtime + register_project(EspressoRuntimeResourceProject(_suite, 'src', '?', _suite.defaultLicense)) # TODO theLicense + + runtime_resources_jar = mx_jardistribution.JARDistribution( + _suite, "ESPRESSO_RUNTIME_RESOURCES", None, None, None, + moduleInfo={ + "name": "org.graalvm.espresso.resources.runtime", + }, + deps=[ + "com.oracle.truffle.espresso.resources.runtime", + "ESPRESSO_RUNTIME_DIR", + ], + mainClass=None, + excludedLibs=[], + distDependencies=["truffle:TRUFFLE_API"], + javaCompliance=None, + platformDependent=True, + theLicense=None, # TODO + compress=True, + useModulePath=True, + description="Runtime environment used by the Java on Truffle (aka Espresso) implementation", + maven={ + "artifactId": "espresso-runtime-resources", + "tag": ["default", "public"], + }) + register_distribution(runtime_resources_jar) class JavaHomeDependency(mx.ArchivableProject): @@ -468,6 +499,91 @@ def getResults(self): return JavaHomeDependency.walk(self.java_home) +class EspressoRuntimeResourceProject(mx.JavaProject): + def __init__(self, suite, subDir, runtime_type, theLicense): + name = f'com.oracle.truffle.espresso.resources.runtime' + project_dir = join(suite.dir, subDir, name) + deps = ['truffle:TRUFFLE_API'] + super().__init__(suite, name, subDir=subDir, srcDirs=[], deps=deps, + javaCompliance='17+', workingSets='Truffle', d=project_dir, + theLicense=theLicense) + self.declaredAnnotationProcessors = ['truffle:TRUFFLE_DSL_PROCESSOR'] + self.resource_id = "espresso-runtime" + self.checkstyleProj = name + self.checkPackagePrefix = False + + def getBuildTask(self, args): + jdk = mx.get_jdk(self.javaCompliance, tag=mx.DEFAULT_JDK_TAG, purpose='building ' + self.name) + return EspressoRuntimeResourceBuildTask(args, self, jdk) + + +class EspressoRuntimeResourceBuildTask(mx.JavaBuildTask): + def __str__(self): + return f'Generating {self.subject.name} internal resource and compiling it with {self._getCompiler().name()}' + + @staticmethod + def _template_file(): + return join(_suite.mxDir, 'espresso_runtime_resource.template') + + def needsBuild(self, newestInput): + is_needed, reason = mx.ProjectBuildTask.needsBuild(self, newestInput) + if is_needed: + return True, reason + proj = self.subject + for outDir in [proj.output_dir(), proj.source_gen_dir()]: + if not os.path.exists(outDir): + return True, f"{outDir} does not exist" + template_ts = mx.TimeStampFile.newest([ + EspressoRuntimeResourceBuildTask._template_file(), + __file__ + ]) + if newestInput is None or newestInput.isOlderThan(template_ts): + newestInput = template_ts + return super().needsBuild(newestInput) + + @staticmethod + def _target_file(root, pkg_name): + target_folder = join(root, pkg_name.replace('.', os.sep)) + target_file = join(target_folder, 'EspressoRuntimeResource.java') + return target_file + + + def _collect_files(self): + if self._javafiles is not None: + # already collected + return self + # collect project files first, then extend with generated resource + super(EspressoRuntimeResourceBuildTask, self)._collect_files() + javafiles = self._javafiles + prj = self.subject + gen_src_dir = prj.source_gen_dir() + pkg_name = prj.name + target_file = EspressoRuntimeResourceBuildTask._target_file(gen_src_dir, pkg_name) + if not target_file in javafiles: + bin_dir = prj.output_dir() + target_class = join(bin_dir, relpath(target_file, gen_src_dir)[:-len('.java')] + '.class') + javafiles[target_file] = target_class + # Remove annotation processor generated files. + javafiles = {k: v for k, v in javafiles.items() if k == target_file} + self._javafiles = javafiles + return self + + def build(self): + prj = self.subject + pkg_name = prj.name + with open(EspressoRuntimeResourceBuildTask._template_file(), 'r', encoding='utf-8') as f: + file_content = f.read() + subst_eng = mx_subst.SubstitutionEngine() + subst_eng.register_no_arg('package', pkg_name) + subst_eng.register_no_arg('resourceId', prj.resource_id) + file_content = subst_eng.substitute(file_content) + target_file = EspressoRuntimeResourceBuildTask._target_file(prj.source_gen_dir(), pkg_name) + mx_util.ensure_dir_exists(dirname(target_file)) + with mx_util.SafeFileCreation(target_file) as sfc, open(sfc.tmpPath, 'w', encoding='utf-8') as f: + f.write(file_content) + super(EspressoRuntimeResourceBuildTask, self).build() + + mx_sdk_vm.register_graalvm_component(mx_sdk_vm.GraalVmJreComponent( suite=_suite, name='Espresso libjvm', diff --git a/espresso/mx.espresso/suite.py b/espresso/mx.espresso/suite.py index c5ab29d6997a..d86468be8537 100644 --- a/espresso/mx.espresso/suite.py +++ b/espresso/mx.espresso/suite.py @@ -140,17 +140,6 @@ "checkstyle": "com.oracle.truffle.espresso", }, - "com.oracle.truffle.espresso.resources.runtime": { - "subDir": "src", - "sourceDirs": ["src"], - "dependencies": [ - "truffle:TRUFFLE_API", - ], - "annotationProcessors": ["truffle:TRUFFLE_DSL_PROCESSOR"], - "javaCompliance": "17+", - "checkstyle": "com.oracle.truffle.espresso", - }, - "com.oracle.truffle.espresso.processor": { "subDir": "src", "sourceDirs": ["src"], @@ -525,27 +514,6 @@ "maven": False, }, - "ESPRESSO_RUNTIME_RESOURCES": { - "platformDependent": True, - "moduleInfo": { - "name": "org.graalvm.espresso.resources.runtime", - }, - "distDependencies": [ - "truffle:TRUFFLE_API", - ], - "dependencies": [ - "com.oracle.truffle.espresso.resources.runtime", - "ESPRESSO_RUNTIME_DIR", - ], - "compress": True, - "useModulePath": True, - "description": "Runtime environment used by the Java on Truffle (aka Espresso) implementation", - "maven" : { - "artifactId": "espresso-runtime-resources", - "tag": ["default", "public"], - }, - }, - "ESPRESSO_SUPPORT": { "native": True, "description": "Espresso support distribution for the GraalVM (in espresso home)", From 4a5f4258331fa7918fcc5ef498a54823622cfa22 Mon Sep 17 00:00:00 2001 From: Gilles Duboscq Date: Fri, 17 May 2024 14:55:31 +0200 Subject: [PATCH 02/16] Improve assertion message --- .../truffle/espresso/runtime/EspressoThreadLocalState.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/EspressoThreadLocalState.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/EspressoThreadLocalState.java index 5507216be427..aee481fb2205 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/EspressoThreadLocalState.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/EspressoThreadLocalState.java @@ -67,9 +67,9 @@ public void clearPendingException() { } public void setCurrentPlatformThread(StaticObject t) { - assert currentPlatformThread == null || currentPlatformThread == t; assert t != null && StaticObject.notNull(t); assert t.getKlass().getContext().getThreadAccess().getHost(t) == Thread.currentThread() : "Current thread fast access set by non-current thread"; + assert currentPlatformThread == null || currentPlatformThread == t : currentPlatformThread + " vs " + t; currentPlatformThread = t; } From 1cdcc7191b0ed7b85a03d6f2139efa5e8fa411a3 Mon Sep 17 00:00:00 2001 From: Gilles Duboscq Date: Fri, 17 May 2024 15:07:54 +0200 Subject: [PATCH 03/16] Make sure the implementor of java_home and llvm_java_home match --- espresso/mx.espresso/mx_espresso.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/espresso/mx.espresso/mx_espresso.py b/espresso/mx.espresso/mx_espresso.py index f2bc1aa3c8ae..9e32fe038d38 100644 --- a/espresso/mx.espresso/mx_espresso.py +++ b/espresso/mx.espresso/mx_espresso.py @@ -366,12 +366,15 @@ def mx_register_dynamic_suite_constituents(register_project, register_distributi :type register_project: (mx.Project) -> None :type register_distribution: (mx.Distribution) -> None """ + java_home_dep = JavaHomeDependency(_suite, "JAVA_HOME", _espresso_input_jdk().home) + register_project(java_home_dep) if espresso_llvm_java_home: # Conditionally creates the ESPRESSO_LLVM_SUPPORT distribution if a Java home with LLVM bitcode is provided. lib_prefix = mx.add_lib_prefix('') lib_suffix = mx.add_lib_suffix('') jdk_lib_dir = 'bin' if mx.is_windows() else 'lib' + llvm_java_home_dep = JavaHomeDependency(_suite, "LLVM_JAVA_HOME", espresso_llvm_java_home) if mx.get_env("SKIP_ESPRESSO_LLVM_CHECK", 'false').lower() in ('false', '0', 'no'): libjava = join(espresso_llvm_java_home, jdk_lib_dir, f'{lib_prefix}java{lib_suffix}') @@ -391,6 +394,8 @@ def mx_register_dynamic_suite_constituents(register_project, register_distributi raise mx.abort(f"Cannot find LLVM bitcode in provided Espresso LLVM JAVA_HOME ({libjava})") elif mx.is_continuous_integration(): raise mx.abort("otool not found on the PATH. It is required to verify the Espresso LLVM JAVA_HOME") + if java_home_dep.is_ee_implementor != llvm_java_home_dep.is_ee_implementor: + raise mx.abort("The implementors for ESPRESSO's JAVA_HOME and LLVM JAVA_HOME don't match") register_distribution(mx.LayoutTARDistribution(_suite, 'ESPRESSO_LLVM_SUPPORT', [], { "lib/llvm/default/": [ @@ -403,11 +408,10 @@ def mx_register_dynamic_suite_constituents(register_project, register_distributi "dependency": "LLVM_JAVA_HOME", "path": f"{jdk_lib_dir}/", } - register_project(JavaHomeDependency(_suite, "LLVM_JAVA_HOME", espresso_llvm_java_home)) + register_project(llvm_java_home_dep) else: llvm_runtime_dir = [] - register_project(JavaHomeDependency(_suite, "JAVA_HOME", _espresso_input_jdk().home)) if mx.is_windows(): platform_specific_excludes = [ "bin/", @@ -485,9 +489,14 @@ def mx_register_dynamic_suite_constituents(register_project, register_distributi class JavaHomeDependency(mx.ArchivableProject): def __init__(self, suite, name, java_home): - super().__init__(suite, name, deps=[], workingSets=[], theLicense=_jdk_license(java_home)) assert isabs(java_home) self.java_home = java_home + self.is_ee_implementor = mx_sdk_vm.ee_implementor(java_home) + if self.is_ee_implementor: + the_license = "Oracle Proprietary" + else: + the_license = "GPLv2-CPE" + super().__init__(suite, name, deps=[], workingSets=[], theLicense=the_license) def output_dir(self): return self.java_home From 20d70fa986cadce68af7979608c3dd8689ab59bc Mon Sep 17 00:00:00 2001 From: Gilles Duboscq Date: Fri, 17 May 2024 15:25:49 +0200 Subject: [PATCH 04/16] Set the espresso resource name depending on jdk type --- espresso/mx.espresso/mx_espresso.py | 44 +++++++++++-------- .../truffle/espresso/EspressoLanguage.java | 17 +++++-- 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/espresso/mx.espresso/mx_espresso.py b/espresso/mx.espresso/mx_espresso.py index 9e32fe038d38..ff9aa1007c63 100644 --- a/espresso/mx.espresso/mx_espresso.py +++ b/espresso/mx.espresso/mx_espresso.py @@ -340,9 +340,9 @@ def build(self): )) -def _jdk_license(home): - if mx_sdk_vm.ee_implementor(home): - return "Oracle Proprietary" +def _resource_license(ee_implementor): + if ee_implementor: + return "GFTC" else: return "GPLv2-CPE" @@ -402,7 +402,7 @@ def mx_register_dynamic_suite_constituents(register_project, register_distributi f"dependency:LLVM_JAVA_HOME/{jdk_lib_dir}/{lib_prefix}*{lib_suffix}", "dependency:LLVM_JAVA_HOME/release" ], - }, None, True, _jdk_license(espresso_llvm_java_home))) + }, None, True, _resource_license(llvm_java_home_dep.is_ee_implementor))) llvm_runtime_dir = { "source_type": "dependency", "dependency": "LLVM_JAVA_HOME", @@ -424,11 +424,15 @@ def mx_register_dynamic_suite_constituents(register_project, register_distributi "lib/", "man", ] + if java_home_dep.is_ee_implementor: + espresso_runtime_resource_name = "jdk" + str(java_home_dep.major_version) + else: + espresso_runtime_resource_name = "openjdk" + str(java_home_dep.major_version) register_distribution(mx.LayoutDirDistribution( _suite, "ESPRESSO_RUNTIME_DIR", deps=[], layout={ - "META-INF/resources/java/espresso-runtime///": { + f"META-INF/resources/java/espresso-runtime-{espresso_runtime_resource_name}///": { "source_type": "dependency", "dependency": "JAVA_HOME", "path": "*", @@ -442,7 +446,7 @@ def mx_register_dynamic_suite_constituents(register_project, register_distributi "lib/static", ] + platform_specific_excludes, }, - "META-INF/resources/java/espresso-runtime///lib/llvm/": llvm_runtime_dir, + f"META-INF/resources/java/espresso-runtime-{espresso_runtime_resource_name}///lib/llvm/": llvm_runtime_dir, }, path=None, platformDependent=True, @@ -453,16 +457,15 @@ def mx_register_dynamic_suite_constituents(register_project, register_distributi "darwin-aarch64", "windows-amd64", ], - theLicense=None, # TODO - hashEntry="META-INF/resources/java/espresso-runtime///sha256", - fileListEntry="META-INF/resources/java/espresso-runtime///files", + theLicense=_resource_license(java_home_dep.is_ee_implementor), + hashEntry=f"META-INF/resources/java/espresso-runtime-{espresso_runtime_resource_name}///sha256", + fileListEntry=f"META-INF/resources/java/espresso-runtime-{espresso_runtime_resource_name}///files", maven=False)) - if register_project: # com.oracle.truffle.espresso.resources.runtime - register_project(EspressoRuntimeResourceProject(_suite, 'src', '?', _suite.defaultLicense)) # TODO theLicense + register_project(EspressoRuntimeResourceProject(_suite, 'src', espresso_runtime_resource_name, _suite.defaultLicense)) # TODO theLicense - runtime_resources_jar = mx_jardistribution.JARDistribution( + register_distribution(mx_jardistribution.JARDistribution( _suite, "ESPRESSO_RUNTIME_RESOURCES", None, None, None, moduleInfo={ "name": "org.graalvm.espresso.resources.runtime", @@ -476,22 +479,25 @@ def mx_register_dynamic_suite_constituents(register_project, register_distributi distDependencies=["truffle:TRUFFLE_API"], javaCompliance=None, platformDependent=True, - theLicense=None, # TODO + theLicense=_resource_license(java_home_dep.is_ee_implementor), compress=True, useModulePath=True, description="Runtime environment used by the Java on Truffle (aka Espresso) implementation", maven={ - "artifactId": "espresso-runtime-resources", + "groupId": "org.graalvm.espresso", + "artifactId": "espresso-runtime-resources-" + espresso_runtime_resource_name, "tag": ["default", "public"], - }) - register_distribution(runtime_resources_jar) + })) class JavaHomeDependency(mx.ArchivableProject): def __init__(self, suite, name, java_home): assert isabs(java_home) self.java_home = java_home - self.is_ee_implementor = mx_sdk_vm.ee_implementor(java_home) + release_dict = mx_sdk_vm.parse_release_file(join(java_home, 'release')) + self.is_ee_implementor = release_dict.get('IMPLEMENTOR') == 'Oracle Corporation' + self.version = mx.VersionSpec(release_dict.get('JAVA_VERSION')) + self.major_version = self.version.parts[1] if self.version.parts[0] == 1 else self.version.parts[0] if self.is_ee_implementor: the_license = "Oracle Proprietary" else: @@ -509,7 +515,7 @@ def getResults(self): class EspressoRuntimeResourceProject(mx.JavaProject): - def __init__(self, suite, subDir, runtime_type, theLicense): + def __init__(self, suite, subDir, runtime_name, theLicense): name = f'com.oracle.truffle.espresso.resources.runtime' project_dir = join(suite.dir, subDir, name) deps = ['truffle:TRUFFLE_API'] @@ -517,7 +523,7 @@ def __init__(self, suite, subDir, runtime_type, theLicense): javaCompliance='17+', workingSets='Truffle', d=project_dir, theLicense=theLicense) self.declaredAnnotationProcessors = ['truffle:TRUFFLE_DSL_PROCESSOR'] - self.resource_id = "espresso-runtime" + self.resource_id = "espresso-runtime-" + runtime_name self.checkstyleProj = name self.checkPackagePrefix = False diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoLanguage.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoLanguage.java index 32131ddab5c4..f2e4ceff9ddb 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoLanguage.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoLanguage.java @@ -44,6 +44,7 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.ContextThreadLocal; import com.oracle.truffle.api.TruffleContext; +import com.oracle.truffle.api.TruffleFile; import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.TruffleLanguage.Registration; import com.oracle.truffle.api.TruffleSafepoint; @@ -592,6 +593,8 @@ public static Path getEspressoLibs(TruffleLanguage.Env env) { } } + private static final String[] KNOWN_ESPRESSO_RUNTIMES = {"jdk21", "openjdk21"}; + public static Path getEspressoRuntime(TruffleLanguage.Env env) { // If --java.JavaHome is not specified, Espresso tries to use the same (jars and native) // libraries bundled with GraalVM. @@ -612,9 +615,17 @@ public static Path getEspressoRuntime(TruffleLanguage.Env env) { } } try { - Path resources = Path.of(env.getInternalResource("espresso-runtime").getAbsoluteFile().toString()); - assert Files.isDirectory(resources); - return resources; + for (String runtimeName : KNOWN_ESPRESSO_RUNTIMES) { + TruffleFile resource = env.getInternalResource("espresso-runtime-" + runtimeName); + if (resource != null) { + Path resources = Path.of(resource.getAbsoluteFile().toString()); + assert Files.isDirectory(resources); + env.getLogger(EspressoContext.class).info(() -> "Selected " + runtimeName + " runtime"); + return resources; + } + } + // TODO add potential remedies + throw EspressoError.fatal("Couldn't find suitable runtime libraries for espresso"); } catch (IOException e) { throw EspressoError.shouldNotReachHere(e); } From 51911f6003730f1e789fe2de619e075ed5d0da1e Mon Sep 17 00:00:00 2001 From: Gilles Duboscq Date: Fri, 17 May 2024 16:03:57 +0200 Subject: [PATCH 05/16] Define JAVA_COMMUNITY dynamically --- espresso/mx.espresso/mx_espresso.py | 19 +++++++++++++++++++ espresso/mx.espresso/suite.py | 18 ------------------ 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/espresso/mx.espresso/mx_espresso.py b/espresso/mx.espresso/mx_espresso.py index ff9aa1007c63..53f894a38bf6 100644 --- a/espresso/mx.espresso/mx_espresso.py +++ b/espresso/mx.espresso/mx_espresso.py @@ -29,6 +29,7 @@ import mx import mx_jardistribution +import mx_pomdistribution import mx_subst import mx_util import mx_espresso_benchmarks # pylint: disable=unused-import @@ -488,6 +489,24 @@ def mx_register_dynamic_suite_constituents(register_project, register_distributi "artifactId": "espresso-runtime-resources-" + espresso_runtime_resource_name, "tag": ["default", "public"], })) + register_distribution(mx_pomdistribution.POMDistribution( + _suite, "JAVA_COMMUNITY", [], + [ + "ESPRESSO", + "ESPRESSO_LIBS_RESOURCES", + "ESPRESSO_RUNTIME_RESOURCES", + "truffle:TRUFFLE_NFI_LIBFFI", + "truffle:TRUFFLE_RUNTIME", + # sulong is not strictly required but it'll work out of the box in more cases if it's there + "sulong:LLVM_NATIVE_COMMUNITY", + ], + None, + description="Java on Truffle (aka Espresso): a Java bytecode interpreter", + maven={ + "artifactId": "java-community", + "tag": ["default", "public"], + }, + )) class JavaHomeDependency(mx.ArchivableProject): diff --git a/espresso/mx.espresso/suite.py b/espresso/mx.espresso/suite.py index d86468be8537..3a047ee14951 100644 --- a/espresso/mx.espresso/suite.py +++ b/espresso/mx.espresso/suite.py @@ -380,24 +380,6 @@ "noMavenJavadoc": True, }, - "JAVA_COMMUNITY": { - "type": "pom", - "runtimeDependencies": [ - "ESPRESSO", - "ESPRESSO_LIBS_RESOURCES", - "ESPRESSO_RUNTIME_RESOURCES", - "truffle:TRUFFLE_NFI_LIBFFI", - "truffle:TRUFFLE_RUNTIME", - # sulong is not strictly required but it'll work out of the box in more cases if it's there - "sulong:LLVM_NATIVE_COMMUNITY", - ], - "description": "Java on Truffle (aka Espresso): a Java bytecode interpreter", - "maven": { - "artifactId": "java-community", - "tag": ["default", "public"], - }, - }, - "ESPRESSO_LAUNCHER": { "subDir": "src", "dependencies": [ From 29fc11394f84a4395deffd9bb80b16c063149535 Mon Sep 17 00:00:00 2001 From: Gilles Duboscq Date: Fri, 17 May 2024 17:30:46 +0200 Subject: [PATCH 06/16] Only declare espresso runtime resources if they are from OpenJDK the java-community pom also only depends on those resources if they are from OpenJDK --- espresso/mx.espresso/mx_espresso.py | 124 ++++++++++++++++++---------- 1 file changed, 81 insertions(+), 43 deletions(-) diff --git a/espresso/mx.espresso/mx_espresso.py b/espresso/mx.espresso/mx_espresso.py index 53f894a38bf6..0bd004b73d1c 100644 --- a/espresso/mx.espresso/mx_espresso.py +++ b/espresso/mx.espresso/mx_espresso.py @@ -37,7 +37,7 @@ import mx_sdk_vm_impl from mx_gate import Task, add_gate_runner from mx_jackpot import jackpot -from os.path import join, isabs, exists, dirname, relpath +from os.path import join, isabs, exists, dirname, relpath, basename _suite = mx.suite('espresso') @@ -349,6 +349,8 @@ def _resource_license(ee_implementor): _espresso_input_jdk_value = None +_java_home_dep = None +_llvm_java_home_dep = None def _espresso_input_jdk(): @@ -362,23 +364,72 @@ def _espresso_input_jdk(): return _espresso_input_jdk_value +def get_java_home_dep(): + global _java_home_dep + if _java_home_dep is None: + _java_home_dep = JavaHomeDependency(_suite, "JAVA_HOME", _espresso_input_jdk().home) + return _java_home_dep + + +def get_llvm_java_home_dep(): + global _llvm_java_home_dep + if _llvm_java_home_dep is None and espresso_llvm_java_home: + _llvm_java_home_dep = JavaHomeDependency(_suite, "LLVM_JAVA_HOME", espresso_llvm_java_home) + return _llvm_java_home_dep + + def mx_register_dynamic_suite_constituents(register_project, register_distribution): """ :type register_project: (mx.Project) -> None :type register_distribution: (mx.Distribution) -> None """ - java_home_dep = JavaHomeDependency(_suite, "JAVA_HOME", _espresso_input_jdk().home) + java_home_dep = get_java_home_dep() register_project(java_home_dep) - if espresso_llvm_java_home: + llvm_java_home_dep = get_llvm_java_home_dep() + if llvm_java_home_dep: # Conditionally creates the ESPRESSO_LLVM_SUPPORT distribution if a Java home with LLVM bitcode is provided. lib_prefix = mx.add_lib_prefix('') lib_suffix = mx.add_lib_suffix('') jdk_lib_dir = 'bin' if mx.is_windows() else 'lib' - llvm_java_home_dep = JavaHomeDependency(_suite, "LLVM_JAVA_HOME", espresso_llvm_java_home) + register_project(llvm_java_home_dep) + register_distribution(mx.LayoutTARDistribution(_suite, 'ESPRESSO_LLVM_SUPPORT', [], { + "lib/llvm/default/": [ + f"dependency:LLVM_JAVA_HOME/{jdk_lib_dir}/{lib_prefix}*{lib_suffix}", + "dependency:LLVM_JAVA_HOME/release" + ], + }, None, True, _resource_license(llvm_java_home_dep.is_ee_implementor))) + + if not java_home_dep.is_ee_implementor: + register_espresso_runtime_resources(register_project, register_distribution, _suite, java_home_dep, llvm_java_home_dep) + + register_distribution(mx_pomdistribution.POMDistribution( + _suite, "JAVA_COMMUNITY", [], + [ + "ESPRESSO", + "ESPRESSO_LIBS_RESOURCES", + "truffle:TRUFFLE_NFI_LIBFFI", + "truffle:TRUFFLE_RUNTIME", + # sulong is not strictly required, but it'll work out of the box in more cases if it's there + "sulong:LLVM_NATIVE_COMMUNITY", + ] + ([] if java_home_dep.is_ee_implementor else ["ESPRESSO_RUNTIME_RESOURCES"]), + None, + description="Java on Truffle (aka Espresso): a Java bytecode interpreter", + maven={ + "artifactId": "java-community", + "tag": ["default", "public"], + }, + )) + + +def register_espresso_runtime_resources(register_project, register_distribution, suite, java_home_dep, llvm_java_home_dep): + if llvm_java_home_dep: + lib_prefix = mx.add_lib_prefix('') + lib_suffix = mx.add_lib_suffix('') + jdk_lib_dir = 'bin' if mx.is_windows() else 'lib' if mx.get_env("SKIP_ESPRESSO_LLVM_CHECK", 'false').lower() in ('false', '0', 'no'): - libjava = join(espresso_llvm_java_home, jdk_lib_dir, f'{lib_prefix}java{lib_suffix}') + libjava = join(llvm_java_home_dep.java_home, jdk_lib_dir, f'{lib_prefix}java{lib_suffix}') if mx.is_linux(): objdump = shutil.which('objdump') if objdump: @@ -397,19 +448,11 @@ def mx_register_dynamic_suite_constituents(register_project, register_distributi raise mx.abort("otool not found on the PATH. It is required to verify the Espresso LLVM JAVA_HOME") if java_home_dep.is_ee_implementor != llvm_java_home_dep.is_ee_implementor: raise mx.abort("The implementors for ESPRESSO's JAVA_HOME and LLVM JAVA_HOME don't match") - - register_distribution(mx.LayoutTARDistribution(_suite, 'ESPRESSO_LLVM_SUPPORT', [], { - "lib/llvm/default/": [ - f"dependency:LLVM_JAVA_HOME/{jdk_lib_dir}/{lib_prefix}*{lib_suffix}", - "dependency:LLVM_JAVA_HOME/release" - ], - }, None, True, _resource_license(llvm_java_home_dep.is_ee_implementor))) llvm_runtime_dir = { "source_type": "dependency", - "dependency": "LLVM_JAVA_HOME", + "dependency": "espresso:LLVM_JAVA_HOME", "path": f"{jdk_lib_dir}/", } - register_project(llvm_java_home_dep) else: llvm_runtime_dir = [] @@ -430,12 +473,12 @@ def mx_register_dynamic_suite_constituents(register_project, register_distributi else: espresso_runtime_resource_name = "openjdk" + str(java_home_dep.major_version) register_distribution(mx.LayoutDirDistribution( - _suite, "ESPRESSO_RUNTIME_DIR", + suite, "ESPRESSO_RUNTIME_DIR", deps=[], layout={ f"META-INF/resources/java/espresso-runtime-{espresso_runtime_resource_name}///": { "source_type": "dependency", - "dependency": "JAVA_HOME", + "dependency": "espresso:JAVA_HOME", "path": "*", "exclude": [ "include", @@ -464,10 +507,10 @@ def mx_register_dynamic_suite_constituents(register_project, register_distributi maven=False)) if register_project: # com.oracle.truffle.espresso.resources.runtime - register_project(EspressoRuntimeResourceProject(_suite, 'src', espresso_runtime_resource_name, _suite.defaultLicense)) # TODO theLicense + register_project(EspressoRuntimeResourceProject(suite, 'src', espresso_runtime_resource_name, suite.defaultLicense)) register_distribution(mx_jardistribution.JARDistribution( - _suite, "ESPRESSO_RUNTIME_RESOURCES", None, None, None, + suite, "ESPRESSO_RUNTIME_RESOURCES", None, None, None, moduleInfo={ "name": "org.graalvm.espresso.resources.runtime", }, @@ -489,27 +532,9 @@ def mx_register_dynamic_suite_constituents(register_project, register_distributi "artifactId": "espresso-runtime-resources-" + espresso_runtime_resource_name, "tag": ["default", "public"], })) - register_distribution(mx_pomdistribution.POMDistribution( - _suite, "JAVA_COMMUNITY", [], - [ - "ESPRESSO", - "ESPRESSO_LIBS_RESOURCES", - "ESPRESSO_RUNTIME_RESOURCES", - "truffle:TRUFFLE_NFI_LIBFFI", - "truffle:TRUFFLE_RUNTIME", - # sulong is not strictly required but it'll work out of the box in more cases if it's there - "sulong:LLVM_NATIVE_COMMUNITY", - ], - None, - description="Java on Truffle (aka Espresso): a Java bytecode interpreter", - maven={ - "artifactId": "java-community", - "tag": ["default", "public"], - }, - )) -class JavaHomeDependency(mx.ArchivableProject): +class JavaHomeDependency(mx.BaseLibrary): def __init__(self, suite, name, java_home): assert isabs(java_home) self.java_home = java_home @@ -521,16 +546,29 @@ def __init__(self, suite, name, java_home): the_license = "Oracle Proprietary" else: the_license = "GPLv2-CPE" - super().__init__(suite, name, deps=[], workingSets=[], theLicense=the_license) + super().__init__(suite, name, optional=False, theLicense=the_license) + self.deps = [] - def output_dir(self): - return self.java_home + def is_available(self): + return True - def archive_prefix(self): - return "" + def getBuildTask(self, args): + return mx.ArchivableBuildTask(self, args, 1) def getResults(self): - return JavaHomeDependency.walk(self.java_home) + for root, _, files in os.walk(self.java_home): + for name in files: + yield join(root, name) + + def getArchivableResults(self, use_relpath=True, single=False): + if single: + raise ValueError("single not supported") + for path in self.getResults(): + if use_relpath: + arcname = relpath(path, self.java_home) + else: + arcname = basename(path) + yield path, arcname class EspressoRuntimeResourceProject(mx.JavaProject): From e31260d2731ab8de211d8e6822efe15706c1c7f3 Mon Sep 17 00:00:00 2001 From: Gilles Duboscq Date: Fri, 17 May 2024 17:58:42 +0200 Subject: [PATCH 07/16] Try to use the host's runtime library on hotspot on linux Also let the use specify some JavaHome --- .../oracle/truffle/espresso/EspressoLanguage.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoLanguage.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoLanguage.java index f2e4ceff9ddb..29be6a74e12d 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoLanguage.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoLanguage.java @@ -27,10 +27,12 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Objects; import java.util.concurrent.TimeUnit; import java.util.logging.Level; +import com.oracle.truffle.espresso.runtime.OS; import org.graalvm.home.HomeFinder; import org.graalvm.home.Version; import org.graalvm.options.OptionDescriptors; @@ -624,6 +626,17 @@ public static Path getEspressoRuntime(TruffleLanguage.Env env) { return resources; } } + if (env.getOptions().hasBeenSet(EspressoOptions.JavaHome)) { + // This option's value will be used, no need to guess + return null; + } + if (OS.getCurrent() == OS.Linux && JavaVersion.HOST_VERSION.compareTo(JavaVersion.latestSupported()) <= 0) { + if (!EspressoOptions.RUNNING_ON_SVM || (boolean) env.getConfig().getOrDefault("preinit", false)) { + // we might be able to use the host runtime libraries + env.getLogger(EspressoContext.class).info("Trying to use the host's runtime libraries"); + return Paths.get(System.getProperty("java.home")); + } + } // TODO add potential remedies throw EspressoError.fatal("Couldn't find suitable runtime libraries for espresso"); } catch (IOException e) { From 0b3b7e2d09c7d4a871279fa825a67ece81fcfc78 Mon Sep 17 00:00:00 2001 From: Gilles Duboscq Date: Fri, 17 May 2024 18:15:53 +0200 Subject: [PATCH 08/16] Allow specifing the espresso runtime resource id explicitly --- .../truffle/espresso/EspressoLanguage.java | 29 +++++++++++++++---- .../truffle/espresso/EspressoOptions.java | 6 ++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoLanguage.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoLanguage.java index 29be6a74e12d..6356d74a809f 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoLanguage.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoLanguage.java @@ -31,8 +31,8 @@ import java.util.Objects; import java.util.concurrent.TimeUnit; import java.util.logging.Level; +import java.util.regex.Pattern; -import com.oracle.truffle.espresso.runtime.OS; import org.graalvm.home.HomeFinder; import org.graalvm.home.Version; import org.graalvm.options.OptionDescriptors; @@ -80,6 +80,7 @@ import com.oracle.truffle.espresso.runtime.EspressoThreadLocalState; import com.oracle.truffle.espresso.runtime.GuestAllocator; import com.oracle.truffle.espresso.runtime.JavaVersion; +import com.oracle.truffle.espresso.runtime.OS; import com.oracle.truffle.espresso.runtime.staticobject.StaticObject; import com.oracle.truffle.espresso.runtime.staticobject.StaticObject.StaticObjectFactory; import com.oracle.truffle.espresso.substitutions.JImageExtensions; @@ -596,6 +597,7 @@ public static Path getEspressoLibs(TruffleLanguage.Env env) { } private static final String[] KNOWN_ESPRESSO_RUNTIMES = {"jdk21", "openjdk21"}; + private static final Pattern VALID_RESOURCE_ID = Pattern.compile("[0-9a-z\\-]+"); public static Path getEspressoRuntime(TruffleLanguage.Env env) { // If --java.JavaHome is not specified, Espresso tries to use the same (jars and native) @@ -617,6 +619,27 @@ public static Path getEspressoRuntime(TruffleLanguage.Env env) { } } try { + if (env.getOptions().hasBeenSet(EspressoOptions.JavaHome)) { + // This option's value will be used, no need to guess + if (env.getOptions().hasBeenSet(EspressoOptions.RuntimeResourceId)) { + env.getLogger(EspressoContext.class).warning("Both java.JavaHome and java.RuntimeResourceId are set. RuntimeResourceId will be ignored."); + } + return null; + } + if (env.getOptions().hasBeenSet(EspressoOptions.RuntimeResourceId)) { + String runtimeName = env.getOptions().get(EspressoOptions.RuntimeResourceId); + if (!VALID_RESOURCE_ID.matcher(runtimeName).matches()) { + throw EspressoError.fatal("Invalid RuntimeResourceId: " + runtimeName); + } + TruffleFile resource = env.getInternalResource("espresso-runtime-" + runtimeName); + if (resource == null) { + throw EspressoError.fatal("Couldn't find: espresso-runtime-" + runtimeName + " internal resource.\n" + + "Did you add the appropriate jar to the classpath?"); + } + Path resources = Path.of(resource.getAbsoluteFile().toString()); + assert Files.isDirectory(resources); + return resources; + } for (String runtimeName : KNOWN_ESPRESSO_RUNTIMES) { TruffleFile resource = env.getInternalResource("espresso-runtime-" + runtimeName); if (resource != null) { @@ -626,10 +649,6 @@ public static Path getEspressoRuntime(TruffleLanguage.Env env) { return resources; } } - if (env.getOptions().hasBeenSet(EspressoOptions.JavaHome)) { - // This option's value will be used, no need to guess - return null; - } if (OS.getCurrent() == OS.Linux && JavaVersion.HOST_VERSION.compareTo(JavaVersion.latestSupported()) <= 0) { if (!EspressoOptions.RUNNING_ON_SVM || (boolean) env.getConfig().getOrDefault("preinit", false)) { // we might be able to use the host runtime libraries diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoOptions.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoOptions.java index 042aed3f7278..83e8db24792b 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoOptions.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoOptions.java @@ -680,6 +680,12 @@ public enum GuestFieldOffsetStrategyEnum { usageSyntax = "safety|compact|graal") // public static final OptionKey GuestFieldOffsetStrategy = new OptionKey<>(GuestFieldOffsetStrategyEnum.safety); + @Option(help = "Selects a specific runtime resource id (espresso-runtime-resource-).", // + category = OptionCategory.EXPERT, // + stability = OptionStability.EXPERIMENTAL, // + usageSyntax = "jdk21|openjdk21|...") // + public static final OptionKey RuntimeResourceId = new OptionKey<>(""); + // These are host properties e.g. use --vm.Despresso.DebugCounters=true . public static final boolean DebugCounters = booleanProperty("espresso.DebugCounters", false); public static final boolean DumpDebugCounters = booleanProperty("espresso.DumpDebugCounters", true); From e75a289649a961302964f77de19172b351a8e3e6 Mon Sep 17 00:00:00 2001 From: Gilles Duboscq Date: Sat, 18 May 2024 11:08:37 +0200 Subject: [PATCH 09/16] Style fix espresso jsonnet --- espresso/ci/ci_common/common.jsonnet | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/espresso/ci/ci_common/common.jsonnet b/espresso/ci/ci_common/common.jsonnet index 98d4908dce53..94b2d3fdb07d 100644 --- a/espresso/ci/ci_common/common.jsonnet +++ b/espresso/ci/ci_common/common.jsonnet @@ -88,7 +88,7 @@ local benchmark_suites = ['dacapo', 'renaissance', 'scala-dacapo']; dailyBench: {targets+: ['bench', 'daily'], notify_groups:: ['espresso']}, daily: {targets+: ['daily'], notify_groups:: ['espresso']}, weekly: {targets+: ['weekly'], notify_groups:: ['espresso']}, - monthly: {targets+: ['monthly'], notify_groups:: ['espresso']}, + monthly: {targets+: ['monthly'], notify_groups:: ['espresso']}, weeklyBench: {targets+: ['bench', 'weekly'], notify_groups:: ['espresso']}, onDemand: {targets+: ['on-demand']}, onDemandBench: {targets+: ['bench', 'on-demand']}, From 797537cada520f0376fd9f37686f99b3e92186e2 Mon Sep 17 00:00:00 2001 From: Gilles Duboscq Date: Thu, 23 May 2024 09:53:14 +0200 Subject: [PATCH 10/16] Avoid license issue on espresso llvm supprt --- espresso/mx.espresso/mx_espresso.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/espresso/mx.espresso/mx_espresso.py b/espresso/mx.espresso/mx_espresso.py index 0bd004b73d1c..3f5137431949 100644 --- a/espresso/mx.espresso/mx_espresso.py +++ b/espresso/mx.espresso/mx_espresso.py @@ -398,7 +398,7 @@ def mx_register_dynamic_suite_constituents(register_project, register_distributi f"dependency:LLVM_JAVA_HOME/{jdk_lib_dir}/{lib_prefix}*{lib_suffix}", "dependency:LLVM_JAVA_HOME/release" ], - }, None, True, _resource_license(llvm_java_home_dep.is_ee_implementor))) + }, None, True, None)) if not java_home_dep.is_ee_implementor: register_espresso_runtime_resources(register_project, register_distribution, _suite, java_home_dep, llvm_java_home_dep) From e9c796bc9ce6284d2d78c64a798e5ca915f1e325 Mon Sep 17 00:00:00 2001 From: Gilles Duboscq Date: Thu, 23 May 2024 09:55:49 +0200 Subject: [PATCH 11/16] Ensure labsjdk-ee is used for JDK21 espresso resources --- vm/ci/ci_common/common.jsonnet | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vm/ci/ci_common/common.jsonnet b/vm/ci/ci_common/common.jsonnet index 435702f1fc10..f503ab6b23d9 100644 --- a/vm/ci/ci_common/common.jsonnet +++ b/vm/ci/ci_common/common.jsonnet @@ -177,10 +177,10 @@ local devkits = graal_common.devkits; local java_deps(edition) = { downloads+: { JAVA_HOME: graal_common.jdks_data['labsjdk-' + edition + '-' + java_version], - ESPRESSO_JAVA_HOME: graal_common.jdks_data['labsjdk-' + edition + '-21'], + ESPRESSO_JAVA_HOME: graal_common.jdks_data['labsjdk-ee-21'], } + ( if (os == 'linux' || os == 'darwin') && (arch == 'amd64') then { - ESPRESSO_LLVM_JAVA_HOME: graal_common.jdks_data['labsjdk-' + edition + '-21-llvm'], + ESPRESSO_LLVM_JAVA_HOME: graal_common.jdks_data['labsjdk-ee-21-llvm'], } else { } ) + ( From ba077a9c980c7f51ba71579c1f22685578f1d208 Mon Sep 17 00:00:00 2001 From: Gilles Duboscq Date: Thu, 23 May 2024 17:42:44 +0200 Subject: [PATCH 12/16] Use register_distribution for JavaHomeDependency --- espresso/mx.espresso/mx_espresso.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/espresso/mx.espresso/mx_espresso.py b/espresso/mx.espresso/mx_espresso.py index 3f5137431949..79c32767d190 100644 --- a/espresso/mx.espresso/mx_espresso.py +++ b/espresso/mx.espresso/mx_espresso.py @@ -384,7 +384,7 @@ def mx_register_dynamic_suite_constituents(register_project, register_distributi :type register_distribution: (mx.Distribution) -> None """ java_home_dep = get_java_home_dep() - register_project(java_home_dep) + register_distribution(java_home_dep) # a "library" registered as a distribution is not ideal llvm_java_home_dep = get_llvm_java_home_dep() if llvm_java_home_dep: @@ -392,7 +392,7 @@ def mx_register_dynamic_suite_constituents(register_project, register_distributi lib_prefix = mx.add_lib_prefix('') lib_suffix = mx.add_lib_suffix('') jdk_lib_dir = 'bin' if mx.is_windows() else 'lib' - register_project(llvm_java_home_dep) + register_distribution(llvm_java_home_dep) register_distribution(mx.LayoutTARDistribution(_suite, 'ESPRESSO_LLVM_SUPPORT', [], { "lib/llvm/default/": [ f"dependency:LLVM_JAVA_HOME/{jdk_lib_dir}/{lib_prefix}*{lib_suffix}", @@ -570,6 +570,12 @@ def getArchivableResults(self, use_relpath=True, single=False): arcname = basename(path) yield path, arcname + def post_init(self): + pass + + def archived_deps(self): + return [] + class EspressoRuntimeResourceProject(mx.JavaProject): def __init__(self, suite, subDir, runtime_name, theLicense): From 360bf9706f8e3888a51762353f261e12aad3dbff Mon Sep 17 00:00:00 2001 From: Gilles Duboscq Date: Thu, 23 May 2024 19:59:56 +0200 Subject: [PATCH 13/16] Formatting --- .../src/com/oracle/truffle/espresso/vm/VM.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/vm/VM.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/vm/VM.java index d437ba24aab5..200c6655a71f 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/vm/VM.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/vm/VM.java @@ -3732,13 +3732,13 @@ public static long JVM_GetRandomSeedForDumping() { private static final long ONE_BILLION = 1_000_000_000; private static final long MAX_DIFF = 0x0100000000L; - @VmImpl(isJni = true) - @SuppressWarnings("unused") - @TruffleBoundary /** * Instant.now() uses System.currentTimeMillis() on a host Java 8. This might produce some loss * of precision. */ + @VmImpl(isJni = true) + @SuppressWarnings("unused") + @TruffleBoundary public static long JVM_GetNanoTimeAdjustment(@JavaType(Class.class) StaticObject ignored, long offset) { // Instant.now() uses System.currentTimeMillis() on a host Java 8. This might produce some // loss of precision. From 1eceb619bdeaeeede26b5332e1ec74fdfcea308d Mon Sep 17 00:00:00 2001 From: Gilles Duboscq Date: Fri, 24 May 2024 15:22:33 +0200 Subject: [PATCH 14/16] Be more robust when searching and matching inner classes during redefinition * If the debugger sends the same class multiple times, ignore duplicates * When looking for unknown inner classes, only look for direct anonymous inner classes to avoid skyping levels in the hierarchy. --- .../espresso/impl/ConstantPoolPatcher.java | 51 +++++++++----- .../redefinition/HotSwapClassInfo.java | 9 ++- .../redefinition/InnerClassRedefiner.java | 69 +++++++++++-------- 3 files changed, 79 insertions(+), 50 deletions(-) diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/ConstantPoolPatcher.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/ConstantPoolPatcher.java index 2b7cb7c1ecc2..4e3bc44b5aa8 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/ConstantPoolPatcher.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/ConstantPoolPatcher.java @@ -22,22 +22,22 @@ */ package com.oracle.truffle.espresso.impl; +import java.util.Arrays; +import java.util.Map; +import java.util.Set; + import com.oracle.truffle.espresso.classfile.ClassfileStream; import com.oracle.truffle.espresso.classfile.ConstantPool; import com.oracle.truffle.espresso.descriptors.ByteSequence; import com.oracle.truffle.espresso.descriptors.Symbol; +import com.oracle.truffle.espresso.descriptors.Symbol.Name; import com.oracle.truffle.espresso.redefinition.InnerClassRedefiner; import com.oracle.truffle.espresso.runtime.EspressoContext; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Map; - public class ConstantPoolPatcher { - public static void getDirectInnerClassNames(Symbol fileSystemName, byte[] bytes, ArrayList> innerNames, EspressoContext context) + public static void getDirectInnerAnonymousClassNames(Symbol fileSystemName, byte[] bytes, Set> innerNames, EspressoContext context) throws ClassFormatError { ClassfileStream stream = new ClassfileStream(bytes, null); - ByteSequence fileNameBytes = fileSystemName.subSequence(0, fileSystemName.length()); // skip magic and version - 8 bytes stream.skip(8); final int length = stream.readU2(); @@ -50,10 +50,9 @@ public static void getDirectInnerClassNames(Symbol fileSystemName, switch (tag) { case UTF8: ByteSequence byteSequence = stream.readByteSequenceUTF(); - if (byteSequence.contentStartsWith(fileNameBytes) && !byteSequence.contentEquals(fileNameBytes)) { - if (InnerClassRedefiner.ANON_INNER_CLASS_PATTERN.matcher(byteSequence.toString()).matches()) { - innerNames.add(context.getNames().getOrCreate(byteSequence)); - } + if (isDirectAnonymousInnerClass(fileSystemName, byteSequence)) { + assert InnerClassRedefiner.ANON_INNER_CLASS_PATTERN.matcher(byteSequence.toString()).matches(); + innerNames.add(context.getNames().getOrCreate(byteSequence)); } break; case CLASS: @@ -95,7 +94,27 @@ public static void getDirectInnerClassNames(Symbol fileSystemName, } } - public static byte[] patchConstantPool(byte[] bytes, Map, Symbol> rules, EspressoContext context) throws ClassFormatError { + private static boolean isDirectAnonymousInnerClass(ByteSequence outer, ByteSequence inner) { + if (!inner.contentStartsWith(outer) || inner.length() < outer.length() + 2) { + return false; + } + int i = outer.length(); + if (inner.byteAt(i++) != '$') { + return false; + } + do { + if (!isDecimalDigit(inner.byteAt(i++))) { + return false; + } + } while (i < inner.length()); + return true; + } + + private static boolean isDecimalDigit(byte c) { + return '0' <= c && c <= '9'; + } + + public static byte[] patchConstantPool(byte[] bytes, Map, Symbol> rules, EspressoContext context) throws ClassFormatError { byte[] result = Arrays.copyOf(bytes, bytes.length); ClassfileStream stream = new ClassfileStream(bytes, null); @@ -113,15 +132,15 @@ public static byte[] patchConstantPool(byte[] bytes, Map, Sy case UTF8: int position = stream.getPosition() + 2; // utfLength is first two bytes ByteSequence byteSequence = stream.readByteSequenceUTF(); - Symbol asSymbol = context.getNames().getOrCreate(byteSequence); + Symbol asSymbol = context.getNames().getOrCreate(byteSequence); if (rules.containsKey(asSymbol)) { - int originalLegth = byteSequence.length(); - Symbol replacedSymbol = rules.get(asSymbol); - if (originalLegth == replacedSymbol.length()) { + int originalLength = byteSequence.length(); + Symbol replacedSymbol = rules.get(asSymbol); + if (originalLength == replacedSymbol.length()) { replacedSymbol.writeTo(result, position + byteArrayGrowth); } else { - int diff = replacedSymbol.length() - originalLegth; + int diff = replacedSymbol.length() - originalLength; byteArrayGrowth += diff; // make room for the longer class name diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/redefinition/HotSwapClassInfo.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/redefinition/HotSwapClassInfo.java index 2fda4016235f..7a74b432b545 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/redefinition/HotSwapClassInfo.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/redefinition/HotSwapClassInfo.java @@ -22,7 +22,6 @@ */ package com.oracle.truffle.espresso.redefinition; -import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; @@ -33,7 +32,7 @@ // Represents ClassInfo instances for classes about to be hotswapped public final class HotSwapClassInfo extends ClassInfo { - private WeakReference thisKlass; + private ObjectKlass thisKlass; private byte[] bytes; private byte[] patchedBytes; private final StaticObject classLoader; @@ -59,7 +58,7 @@ public final class HotSwapClassInfo extends ClassInfo { String enclosingMethodFingerprint, ArrayList inners, byte[] bytes, boolean isEnumSwitchmapHelper, boolean isNewInnerTestKlass) { super(isEnumSwitchmapHelper, isNewInnerTestKlass); - this.thisKlass = new WeakReference<>(klass); + this.thisKlass = klass; this.originalName = originalName; this.classLoader = classLoader; this.classFingerprint = classFingerprint; @@ -81,11 +80,11 @@ public static HotSwapClassInfo createForSuperClassChanged(ObjectKlass klass) { @Override public ObjectKlass getKlass() { - return thisKlass.get(); + return thisKlass; } public void setKlass(ObjectKlass klass) { - thisKlass = new WeakReference<>(klass); + thisKlass = klass; } @Override diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/redefinition/InnerClassRedefiner.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/redefinition/InnerClassRedefiner.java index bf7053406cc5..4d75c76a4314 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/redefinition/InnerClassRedefiner.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/redefinition/InnerClassRedefiner.java @@ -36,8 +36,11 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.oracle.truffle.api.TruffleLogger; +import com.oracle.truffle.espresso.EspressoLanguage; import com.oracle.truffle.espresso.classfile.ClassfileParser; import com.oracle.truffle.espresso.descriptors.Symbol; +import com.oracle.truffle.espresso.descriptors.Symbol.Name; import com.oracle.truffle.espresso.impl.ClassRegistry; import com.oracle.truffle.espresso.impl.ConstantPoolPatcher; import com.oracle.truffle.espresso.impl.Klass; @@ -48,6 +51,7 @@ import com.oracle.truffle.espresso.runtime.staticobject.StaticObject; public final class InnerClassRedefiner { + private static final TruffleLogger LOGGER = TruffleLogger.getLogger(EspressoLanguage.ID, InnerClassRedefiner.class); public static final Pattern ANON_INNER_CLASS_PATTERN = Pattern.compile(".*\\$\\d+.*"); public static final int METHOD_FINGERPRINT_EQUALS = 8; @@ -61,13 +65,13 @@ public final class InnerClassRedefiner { private final EspressoContext context; // map from classloader to a map of class names to inner class infos - private final Map, ImmutableClassInfo>> innerClassInfoMap = new WeakHashMap<>(); + private final Map, ImmutableClassInfo>> innerClassInfoMap = new WeakHashMap<>(); // map from classloader to a map of Type to private final Map, Set>> innerKlassCache = new WeakHashMap<>(); // list of class info for all top-level classed about to be redefined - private final Map, HotSwapClassInfo> hotswapState = new HashMap<>(); + private final Map, HotSwapClassInfo> hotswapState = new HashMap<>(); public InnerClassRedefiner(EspressoContext context) { this.context = context; @@ -77,7 +81,7 @@ public HotSwapClassInfo[] matchAnonymousInnerClasses(List redefine hotswapState.clear(); ArrayList unhandled = new ArrayList<>(redefineInfos); - Map, HotSwapClassInfo> handled = new HashMap<>(redefineInfos.size()); + Map, HotSwapClassInfo> handled = new HashMap<>(redefineInfos.size()); // build inner/outer relationship from top-level to leaf class in order // each round below handles classes where the outer class was previously // handled @@ -87,7 +91,12 @@ public HotSwapClassInfo[] matchAnonymousInnerClasses(List redefine Iterator it = unhandled.iterator(); while (it.hasNext()) { RedefineInfo redefineInfo = it.next(); - Symbol klassName = ClassfileParser.getClassName(context.getClassLoadingEnv(), redefineInfo.getClassBytes()); + Symbol klassName = ClassfileParser.getClassName(context.getClassLoadingEnv(), redefineInfo.getClassBytes()); + if (handled.containsKey(klassName)) { + LOGGER.warning(() -> "Ignoring duplicate redefinition requests for name " + klassName); + it.remove(); + continue; + } Matcher matcher = ANON_INNER_CLASS_PATTERN.matcher(klassName.toString()); if (matcher.matches()) { // don't assume that associated old klass instance represents this redefineInfo @@ -117,7 +126,7 @@ public HotSwapClassInfo[] matchAnonymousInnerClasses(List redefine } // store renaming rules to be used for constant pool patching when class renaming happens - Map, Symbol>> renamingRules = new HashMap<>(0); + Map, Symbol>> renamingRules = new HashMap<>(0); // begin matching from collected top-level classes for (HotSwapClassInfo info : hotswapState.values()) { matchClassInfo(info, removedInnerClasses, renamingRules); @@ -130,7 +139,7 @@ public HotSwapClassInfo[] matchAnonymousInnerClasses(List redefine // now, do the constant pool patching for (HotSwapClassInfo classInfo : result) { if (classInfo.getBytes() != null) { - Map, Symbol> rules = renamingRules.get(classInfo.getClassLoader()); + Map, Symbol> rules = renamingRules.get(classInfo.getClassLoader()); if (rules != null && !rules.isEmpty()) { try { classInfo.patchBytes(ConstantPoolPatcher.patchConstantPool(classInfo.getBytes(), rules, context)); @@ -155,15 +164,15 @@ private static void collectAllHotswapClasses(Collection infos, private void fetchMissingInnerClasses(HotSwapClassInfo hotswapInfo) throws RedefinitionNotSupportedException { StaticObject definingLoader = hotswapInfo.getClassLoader(); - ArrayList> innerNames = new ArrayList<>(1); + Set> innerNames = new HashSet<>(1); try { - searchConstantPoolForInnerClassNames(hotswapInfo, innerNames); + searchConstantPoolForDirectInnerAnonymousClassNames(hotswapInfo, innerNames); } catch (ClassFormatError ex) { throw new RedefinitionNotSupportedException(ErrorCodes.INVALID_CLASS_FORMAT); } // poke the defining guest classloader for the resources - for (Symbol innerName : innerNames) { + for (Symbol innerName : innerNames) { if (!hotswapInfo.knowsInnerClass(innerName)) { byte[] classBytes = null; StaticObject resourceGuestString = context.getMeta().toGuestString(innerName + ".class"); @@ -206,20 +215,20 @@ private byte[] readAllBytes(StaticObject inputStream) { } } - private void searchConstantPoolForInnerClassNames(ClassInfo classInfo, ArrayList> innerNames) throws ClassFormatError { + private void searchConstantPoolForDirectInnerAnonymousClassNames(ClassInfo classInfo, Set> innerNames) throws ClassFormatError { byte[] bytes = classInfo.getBytes(); assert bytes != null; - ConstantPoolPatcher.getDirectInnerClassNames(classInfo.getName(), bytes, innerNames, context); + ConstantPoolPatcher.getDirectInnerAnonymousClassNames(classInfo.getName(), bytes, innerNames, context); } - private Symbol getOuterClassName(Symbol innerName) { + private Symbol getOuterClassName(Symbol innerName) { String strName = innerName.toString(); assert strName.contains("$"); return context.getNames().getOrCreate(strName.substring(0, strName.lastIndexOf('$'))); } - private void matchClassInfo(HotSwapClassInfo hotSwapInfo, List removedInnerClasses, Map, Symbol>> renamingRules) + private void matchClassInfo(HotSwapClassInfo hotSwapInfo, List removedInnerClasses, Map, Symbol>> renamingRules) throws RedefinitionNotSupportedException { Klass klass = hotSwapInfo.getKlass(); // try to fetch all direct inner classes @@ -285,29 +294,31 @@ private void matchClassInfo(HotSwapClassInfo hotSwapInfo, List remo } } - private static void addRenamingRule(Map, Symbol>> renamingRules, StaticObject classLoader, Symbol originalName, - Symbol newName, EspressoContext context) { - Map, Symbol> classLoaderRules = renamingRules.get(classLoader); - if (classLoaderRules == null) { - classLoaderRules = new HashMap<>(4); - renamingRules.put(classLoader, classLoaderRules); - } + private static void addRenamingRule(Map, Symbol>> renamingRules, StaticObject classLoader, Symbol originalName, + Symbol newName, EspressoContext context) { + Map, Symbol> classLoaderRules = renamingRules.computeIfAbsent(classLoader, k -> new HashMap<>(4)); context.getClassRedefinition().getController().fine(() -> "Renaming inner class: " + originalName + " to: " + newName); + assert classLoaderRules.getOrDefault(originalName, newName).equals(newName) : "rules already contain " + originalName + " -> " + classLoaderRules.get(originalName) + ", cannot map to " + + newName; // add simple class names classLoaderRules.put(originalName, newName); // add type names - Symbol origTypeName = context.getNames().getOrCreate("L" + originalName + ";"); - Symbol newTypeName = context.getNames().getOrCreate("L" + newName + ";"); + Symbol origTypeName = context.getNames().getOrCreate("L" + originalName + ";"); + Symbol newTypeName = context.getNames().getOrCreate("L" + newName + ";"); + assert classLoaderRules.getOrDefault(origTypeName, newTypeName).equals(newTypeName) : "rules already contain " + origTypeName + " -> " + classLoaderRules.get(origTypeName) + + ", cannot map to " + newTypeName; classLoaderRules.put(origTypeName, newTypeName); // add signature names - Symbol origSigName = context.getNames().getOrCreate("(L" + originalName + ";)V"); - Symbol newSigName = context.getNames().getOrCreate("(L" + newName + ";)V"); + Symbol origSigName = context.getNames().getOrCreate("(L" + originalName + ";)V"); + Symbol newSigName = context.getNames().getOrCreate("(L" + newName + ";)V"); + assert classLoaderRules.getOrDefault(origSigName, newSigName).equals(newSigName) : "rules already contain " + origSigName + " -> " + classLoaderRules.get(origSigName) + ", cannot map to " + + newSigName; classLoaderRules.put(origSigName, newSigName); } public ImmutableClassInfo getGlobalClassInfo(Klass klass) { StaticObject classLoader = klass.getDefiningClassLoader(); - Map, ImmutableClassInfo> infos = innerClassInfoMap.get(classLoader); + Map, ImmutableClassInfo> infos = innerClassInfoMap.get(classLoader); if (infos == null) { infos = new HashMap<>(1); @@ -346,7 +357,7 @@ public void onKlassDefined(ObjectKlass objectKlass) { ObjectKlass objectKlass = (ObjectKlass) loadedKlass; Matcher matcher = ANON_INNER_CLASS_PATTERN.matcher(loadedKlass.getNameAsString()); if (matcher.matches()) { - Symbol outerClassName = getOuterClassName(loadedKlass.getName()); + Symbol outerClassName = getOuterClassName(loadedKlass.getName()); if (outerClassName != null && outerClassName.length() > 0) { Symbol outerType = context.getTypes().fromName(outerClassName); Set innerKlasses = classLoaderMap.get(outerType); @@ -372,7 +383,7 @@ private void onKlassDefined(ObjectKlass klass) { if (matcher.matches()) { Map, Set> classLoaderMap = innerKlassCache.get(klass.getDefiningClassLoader()); // found inner class, now hunt down the outer - Symbol outerName = getOuterClassName(klass.getName()); + Symbol outerName = getOuterClassName(klass.getName()); Symbol outerType = context.getTypes().fromName(outerName); Set innerKlasses = classLoaderMap.get(outerType); @@ -388,14 +399,14 @@ public void commit(HotSwapClassInfo[] infos) { // first remove the previous info for (HotSwapClassInfo info : infos) { StaticObject classLoader = info.getClassLoader(); - Map, ImmutableClassInfo> classLoaderMap = innerClassInfoMap.get(classLoader); + Map, ImmutableClassInfo> classLoaderMap = innerClassInfoMap.get(classLoader); if (classLoaderMap != null) { classLoaderMap.remove(info.getNewName()); } } for (HotSwapClassInfo hotSwapInfo : infos) { StaticObject classLoader = hotSwapInfo.getClassLoader(); - Map, ImmutableClassInfo> classLoaderMap = innerClassInfoMap.get(classLoader); + Map, ImmutableClassInfo> classLoaderMap = innerClassInfoMap.get(classLoader); if (classLoaderMap == null) { classLoaderMap = new HashMap<>(1); innerClassInfoMap.put(classLoader, classLoaderMap); From 5ff47dd5b587195b1918a62cdfe8e2fb81e7a869 Mon Sep 17 00:00:00 2001 From: Gilles Duboscq Date: Mon, 27 May 2024 17:26:20 +0200 Subject: [PATCH 15/16] Add comments and changelog --- espresso/CHANGELOG.md | 7 +++++++ espresso/mx.espresso/mx_espresso.py | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/espresso/CHANGELOG.md b/espresso/CHANGELOG.md index 7025f874eaed..ee035e768fe5 100644 --- a/espresso/CHANGELOG.md +++ b/espresso/CHANGELOG.md @@ -1,5 +1,12 @@ # Espresso Changelog +## Version 24.1.0 +* Added `java.RuntimeResourceId` to allow customizing the truffle resource used to locate the java standard library used by espresso. + The resource called "espresso-runtime-" will be used. By default, "jdk21" then "openjdk21" are attempted. +* Espresso can now use TRegex to execute java.util.regex patterns. TRegex offers better performance than the standard implementation. Use `java.UseTRegex` to enable this engine. +* The interop `readBuffer` method can now be used from the guest Interop API and guest ByteBuffer objects implement this interop message. +* Many issues with espresso's JDWP implementation were fixed, improving the user experience when debugging with a Java IDE. + ## Version 24.0.0 ### User-visible changes * Added support for transparently converting common JDK exception types that flow from host to an embedded Espresso context. diff --git a/espresso/mx.espresso/mx_espresso.py b/espresso/mx.espresso/mx_espresso.py index 79c32767d190..f2493e9f1dbb 100644 --- a/espresso/mx.espresso/mx_espresso.py +++ b/espresso/mx.espresso/mx_espresso.py @@ -571,10 +571,10 @@ def getArchivableResults(self, use_relpath=True, single=False): yield path, arcname def post_init(self): - pass + pass # help act like a distribution since this is registered as a distribution def archived_deps(self): - return [] + return [] # help act like a distribution since this is registered as a distribution class EspressoRuntimeResourceProject(mx.JavaProject): From 8eae7a28f62cd9147e181aba9732152d936d3fd0 Mon Sep 17 00:00:00 2001 From: Gilles Duboscq Date: Thu, 30 May 2024 10:24:06 +0200 Subject: [PATCH 16/16] Add some hints in error messages --- .../src/com/oracle/truffle/espresso/EspressoLanguage.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoLanguage.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoLanguage.java index 6356d74a809f..fed0f9c3124c 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoLanguage.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoLanguage.java @@ -634,7 +634,7 @@ public static Path getEspressoRuntime(TruffleLanguage.Env env) { TruffleFile resource = env.getInternalResource("espresso-runtime-" + runtimeName); if (resource == null) { throw EspressoError.fatal("Couldn't find: espresso-runtime-" + runtimeName + " internal resource.\n" + - "Did you add the appropriate jar to the classpath?"); + "Did you add the corresponding jar to the class or module path?"); } Path resources = Path.of(resource.getAbsoluteFile().toString()); assert Files.isDirectory(resources); @@ -656,8 +656,9 @@ public static Path getEspressoRuntime(TruffleLanguage.Env env) { return Paths.get(System.getProperty("java.home")); } } - // TODO add potential remedies - throw EspressoError.fatal("Couldn't find suitable runtime libraries for espresso"); + throw EspressoError.fatal("Couldn't find suitable runtime libraries for espresso. You can try to\n" + + "add a jar with the necessary resources such as org.graalvm.espresso:espresso-runtime-resources-*,\n" + + "or set java.JavaHome explicitly."); } catch (IOException e) { throw EspressoError.shouldNotReachHere(e); }