diff --git a/ci/ci_common/common.jsonnet b/ci/ci_common/common.jsonnet index e5f79c6b8ae4..08e56beec1a4 100644 --- a/ci/ci_common/common.jsonnet +++ b/ci/ci_common/common.jsonnet @@ -71,6 +71,10 @@ common + common.frequencies + { labsjdk21Debug:: self["labsjdk-" + repo_config.graalvm_edition + "-21Debug"], labsjdk21LLVM:: self["labsjdk-" + repo_config.graalvm_edition + "-21-llvm"], + labsjdkLatest:: self["labsjdk-" + repo_config.graalvm_edition + "-22"], + labsjdkLatestDebug:: self["labsjdk-" + repo_config.graalvm_edition + "-22Debug"], + labsjdkLatestLLVM:: self["labsjdk-" + repo_config.graalvm_edition + "-22-llvm"], + // Hardware definitions // ******************** local graal_common_extras = common.deps.pylint + { diff --git a/ci/ci_common/run-spec-examples.libsonnet b/ci/ci_common/run-spec-examples.libsonnet index c7e111551bd2..d3cf79e0b56c 100644 --- a/ci/ci_common/run-spec-examples.libsonnet +++ b/ci/ci_common/run-spec-examples.libsonnet @@ -84,7 +84,7 @@ local r = import "run-spec.libsonnet"; "jdk21": r.task_spec({ "target": "gate", }), - "jdk22": r.task_spec({ + "jdk-latest": r.task_spec({ "target": "gate", }), }, @@ -109,7 +109,7 @@ local r = import "run-spec.libsonnet"; "jdk19": {}, "jdk20": {}, "jdk21": {}, - "jdk22": {}, + "jdk-latest": {}, }, }, }; diff --git a/ci/ci_common/run-spec.libsonnet b/ci/ci_common/run-spec.libsonnet index e8fb18b552f2..23f2cfd0644d 100644 --- a/ci/ci_common/run-spec.libsonnet +++ b/ci/ci_common/run-spec.libsonnet @@ -8,7 +8,7 @@ local examples = (import "run-spec-examples.libsonnet").examples; // Supported platforms supported_oss_names:: ["linux", "darwin", "windows"], supported_archs_names:: ["amd64", "aarch64"], - supported_jdks_names:: ["jdk17", "jdk19", "jdk20", "jdk21", "jdk22"], + supported_jdks_names:: ["jdk17", "jdk19", "jdk20", "jdk21", "jdk-latest"], // This will turn a task dictionary into a list of build objects. process(task_dict):: diff --git a/ci/common.jsonnet b/ci/common.jsonnet index d7a92fef9179..c15b0a8b42dc 100644 --- a/ci/common.jsonnet +++ b/ci/common.jsonnet @@ -25,7 +25,7 @@ local common_json = import "../common.json"; for name in ["oraclejdk21"] + variants("labsjdk-ce-21") + variants("labsjdk-ee-21") } + { [name]: common_json.jdks[name] + { jdk_version:: 22 } - for name in ["oraclejdk22"] + for name in variants("labsjdk-ce-22") + variants("labsjdk-ee-22") }, assert std.assertEqual(std.objectFields(common_json.jdks), std.objectFields(jdks_data)), @@ -59,7 +59,7 @@ local common_json = import "../common.json"; "windows-jdk19": { packages+: { "devkit:VS2022-17.1.0+1": "==0" }}, "windows-jdk20": { packages+: { "devkit:VS2022-17.1.0+1": "==0" }}, "windows-jdk21": { packages+: { "devkit:VS2022-17.1.0+1": "==1" }}, - "windows-jdk22": { packages+: { "devkit:VS2022-17.1.0+1": "==1" }}, + "windows-jdkLatest": { packages+: { "devkit:VS2022-17.1.0+1": "==1" }}, "linux-jdk17": { packages+: { "devkit:gcc11.2.0-OL6.4+1": "==0" }}, "linux-jdk19": { packages+: { "devkit:gcc11.2.0-OL6.4+1": "==0" }}, "linux-jdk20": { packages+: { "devkit:gcc11.2.0-OL6.4+1": "==0" }}, diff --git a/common.json b/common.json index e2af625d77e1..3a6f83fdbaa3 100644 --- a/common.json +++ b/common.json @@ -42,7 +42,12 @@ "labsjdk-ee-21Debug": {"name": "labsjdk", "version": "ee-21+35-jvmci-23.1-b15-debug", "platformspecific": true }, "labsjdk-ee-21-llvm": {"name": "labsjdk", "version": "ee-21+35-jvmci-23.1-b15-sulong", "platformspecific": true }, - "oraclejdk22": {"name": "jpg-jdk", "version": "22", "build_id": "11", "release": true, "platformspecific": true, "extrabundles": ["static-libs"]} + "labsjdk-ce-22": {"name": "labsjdk", "version": "ce-22+13-jvmci-b01", "platformspecific": true }, + "labsjdk-ce-22Debug": {"name": "labsjdk", "version": "ce-22+13-jvmci-b01-debug", "platformspecific": true }, + "labsjdk-ce-22-llvm": {"name": "labsjdk", "version": "ce-22+13-jvmci-b01-sulong", "platformspecific": true }, + "labsjdk-ee-22": {"name": "labsjdk", "version": "ee-22+13-jvmci-b01", "platformspecific": true }, + "labsjdk-ee-22Debug": {"name": "labsjdk", "version": "ee-22+13-jvmci-b01-debug", "platformspecific": true }, + "labsjdk-ee-22-llvm": {"name": "labsjdk", "version": "ee-22+13-jvmci-b01-sulong", "platformspecific": true } }, "eclipse": { diff --git a/compiler/ci/ci_common/gate.jsonnet b/compiler/ci/ci_common/gate.jsonnet index c690acd67a80..93bd08495d78 100644 --- a/compiler/ci/ci_common/gate.jsonnet +++ b/compiler/ci/ci_common/gate.jsonnet @@ -206,6 +206,7 @@ "gate-compiler-test_zgc-labsjdk-21-darwin-aarch64": t("1:00:00"), "gate-compiler-style-labsjdk-21-linux-amd64": t("45:00"), + "gate-compiler-build-labsjdk-latest-linux-amd64": t("25:00"), "gate-compiler-ctw-labsjdk-21-linux-amd64": c.mach5_target, "gate-compiler-ctw-labsjdk-21-windows-amd64": t("1:50:00"), @@ -295,7 +296,7 @@ dailies_manifest=dailies, weeklies_manifest=weeklies, monthlies_manifest=monthlies):: { - local base_name = "%s-%s-%s-%s-%s" % [suite, task, jdk_name, jdk, os_arch], + local base_name = "%s-%s-%s-%s-%s" % [suite, task, jdk_name, if std.startsWith(jdk, "Latest") then "l" + jdk[1:] else jdk, os_arch], local gate_name = "gate-" + base_name, local daily_name = "daily-" + base_name, local weekly_name = "weekly-" + base_name, @@ -435,7 +436,18 @@ ] ], - local style_builds = [self.make_build("21", "linux-amd64", "style").build], + local style_builds = [self.make_build("21", "linux-amd64", "style").build + { + environment+: { + # Run the strict JVMCI version check, i.e., that JVMCIVersionCheck.JVMCI_MIN_VERSION matches the versions in common.json. + JVMCI_VERSION_CHECK: "strict", + }, + }], + local jdk_latest_version_check_builds = [self.make_build("Latest", "linux-amd64", "build", extra_tasks={build:: s.base("build"),}).build + { + environment+: { + # Run the strict JVMCI version check, i.e., that JVMCIVersionCheck.JVMCI_MIN_VERSION matches the versions in common.json. + JVMCI_VERSION_CHECK: "strict", + }, + }], # Builds run on only on linux-amd64-jdk21Debug local linux_amd64_jdk21Debug_builds = [self.make_build("21Debug", "linux-amd64", task).build @@ -450,6 +462,7 @@ all_zgc_builds + all_serialgc_builds + style_builds + + jdk_latest_version_check_builds + linux_amd64_jdk21_builds + linux_amd64_jdk21Debug_builds, diff --git a/compiler/mx.compiler/mx_compiler.py b/compiler/mx.compiler/mx_compiler.py index d1f95d7234bf..bde0c8d3f888 100644 --- a/compiler/mx.compiler/mx_compiler.py +++ b/compiler/mx.compiler/mx_compiler.py @@ -78,26 +78,92 @@ def get_vm_prefix(asList=True): #: The JDK used to build and run Graal. jdk = mx.get_jdk(tag='default') -#: 3-tuple (major, minor, build) of JVMCI version, if any, denoted by `jdk` + +class JavaLangRuntimeVersion(mx.Comparable): + """Wrapper for by java.lang.Runtime.Version""" + + _cmp_cache = {} + _feature_re = re.compile('[1-9][0-9]*') + + def __init__(self, version, jdk=None): + self.version = version + self.jdk = jdk or mx.get_jdk() + + def __str__(self): + return self.version + + def __cmp__(self, other): + if not isinstance(other, JavaLangRuntimeVersion): + raise TypeError(f'Cannot compare {JavaLangRuntimeVersion.__name__} to {type(other).__name__}') + this_version = self.version + other_version = other.version + if this_version == other_version: + return 0 + if self.feature() == 21 and other.feature() == 21: + # JDK 21 uses the legacy version scheme where the jdkVersion is irrelevant (and imprecise). + # Thus, we do not perform a full version check. + return 0 + return JavaLangRuntimeVersion.compare(this_version, other_version, jdk) + + @staticmethod + def compare(this_version, other_version, jdk): + key = (this_version, other_version) + cached = JavaLangRuntimeVersion._cmp_cache.get(key, None) + if cached is not None: + return cached + source_path = join(_suite.dir, 'src', 'jdk.internal.vm.compiler', 'src', 'org', 'graalvm', 'compiler', + 'hotspot', + 'JVMCIVersionCompare.java') + out = mx.OutputCapture() + mx.run([jdk.java, '-Xlog:disable', source_path, this_version, other_version], out=out) + ret = int(out.data) + JavaLangRuntimeVersion._cmp_cache[key] = ret + return ret + + def feature(self): + if not hasattr(self, '_feature'): + self._feature = int(JavaLangRuntimeVersion._feature_re.match(self.version).group(0)) + return self._feature + + +#: 4-tuple (jdk_version, jvmci_major, jvmci_minor, jvmci_build) of JVMCI version, if any, denoted by `jdk` +# jdk_version is a JavaLangRuntimeVersion +# jvmci_major and jvmci_minor might be 0 if not needed (JDK 22+) _jdk_jvmci_version = None +_jdk_min_jvmci_version = None -if os.environ.get('JDK_VERSION_CHECK', None) != 'ignore' and jdk.javaCompliance < '17': - mx.abort('Graal requires JDK17 or later, got ' + str(jdk) + +if os.environ.get('JDK_VERSION_CHECK', None) != 'ignore' and jdk.javaCompliance < '21': + mx.abort('Graal requires JDK21 or later, got ' + str(jdk) + '. This check can be bypassed by setting env var JDK_VERSION_CHECK=ignore') def _check_jvmci_version(jdk): """ Runs a Java utility to check that `jdk` supports the minimum JVMCI API required by Graal. """ - source_path = join(_suite.dir, 'src', 'jdk.internal.vm.compiler', 'src', 'org', 'graalvm', 'compiler', 'hotspot', 'JVMCIVersionCheck.java') - out = mx.OutputCapture() - mx.run([jdk.java, '-Xlog:disable', source_path], out=out) + def _capture_jvmci_version(args=None): + out = mx.OutputCapture() + _run_jvmci_version_check(args, jdk=jdk, out=out) + if out.data: + try: + (jdk_version, jvmci_major, jvmci_minor, jvmci_build) = out.data.split(',') + return (JavaLangRuntimeVersion(jdk_version), int(jvmci_major), int(jvmci_minor), int(jvmci_build)) + except ValueError: + mx.warn(f'Could not parse jvmci version from JVMCIVersionCheck output:\n{out.data}') + return None + global _jdk_jvmci_version - if out.data: - try: - _jdk_jvmci_version = tuple((int(n) for n in out.data.split(','))) - except ValueError: - mx.warn(f'Could not parse jvmci version from JVMCIVersionCheck output:\n{out.data}') + _jdk_jvmci_version = _capture_jvmci_version() + global _jdk_min_jvmci_version + _jdk_min_jvmci_version = _capture_jvmci_version(['--min-version']) + + + +@mx.command(_suite.name, 'jvmci-version-check') +def _run_jvmci_version_check(args=None, jdk=jdk, **kwargs): + source_path = join(_suite.dir, 'src', 'jdk.internal.vm.compiler', 'src', 'org', 'graalvm', 'compiler', 'hotspot', + 'JVMCIVersionCheck.java') + return mx.run([jdk.java, '-Xlog:disable', source_path] + (args or []), **kwargs) + if os.environ.get('JVMCI_VERSION_CHECK', None) != 'ignore': _check_jvmci_version(jdk) @@ -1085,7 +1151,7 @@ def _check_latest_jvmci_version(): the JVMCI version of the JVMCI JDKs in the "jdks" section of the ``common.json`` file and issues a warning if not. """ - jvmci_re = re.compile(r'.*-jvmci-(\d+)\.(\d+)-b(\d+)') + jvmci_re = re.compile(r'(?:ce|ee)-(?P.+)-jvmci(?:-(?P\d+)\.(?P\d+))?-b(?P\d+)') common_path = join(_suite.dir, '..', 'common.json') if _jdk_jvmci_version is None: @@ -1096,35 +1162,64 @@ def get_latest_jvmci_version(): with open(common_path) as common_file: common_cfg = json.load(common_file) - latest = None + latest = 'not found' for distribution in common_cfg['jdks']: version = common_cfg['jdks'][distribution].get('version', None) if version and '-jvmci-' in version: - current = tuple(int(n) for n in jvmci_re.match(version).group(1, 2, 3)) - if latest is None: - latest = current - elif latest != current: - # All JVMCI JDKs in common.json are expected to have the same JVMCI version. - # If they don't then the repo is in some transitionary state - # (e.g. making a JVMCI release) so skip the check. - return None - return latest + match = jvmci_re.match(version) + if not match: + mx.abort(f'Cannot parse version {version}') + (jdk_version, jvmci_major, jvmci_minor, jvmci_build) = match.groups(default=0) + current = (JavaLangRuntimeVersion(jdk_version), int(jvmci_major), int(jvmci_minor), int(jvmci_build)) + if current[0].feature() == _jdk_jvmci_version[0].feature(): + # only compare the same major versions + if latest == 'not found': + latest = current + elif latest != current: + # All JVMCI JDKs in common.json with the same major version + # are expected to have the same JVMCI version. + # If they don't then the repo is in some transitionary state + # (e.g. making a JVMCI release) so skip the check. + return False, distribution + return not isinstance(latest, str), latest def jvmci_version_str(version): - major, minor, build = version - return 'jvmci-{}.{}-b{:02d}'.format(major, minor, build) + jdk_version, jvmci_major, jvmci_minor, jvmci_build = version + if jvmci_major == 0: + return f'labsjdk-(ce|ee)-{jdk_version}-jvmci-b{jvmci_build:02d}' + else: + return f'labsjdk-(ce|ee)-{jdk_version}-jvmci-{jvmci_major}.{jvmci_minor}-b{jvmci_build:02d}' + + version_check_setting = os.environ.get('JVMCI_VERSION_CHECK', None) + + success, latest = get_latest_jvmci_version() + + if version_check_setting == 'strict' and _jdk_jvmci_version != _jdk_min_jvmci_version: + msg = f'JVMCI_MIN_VERSION specified in JVMCIVersionCheck.java is older than in {common_path}:' + msg += os.linesep + f'{jvmci_version_str(_jdk_min_jvmci_version)} < {jvmci_version_str(_jdk_jvmci_version)} ' + msg += os.linesep + f'Did you forget to update JVMCI_MIN_VERSION after updating {common_path}?' + msg += os.linesep + 'Set the JVMCI_VERSION_CHECK environment variable to something else then "strict" to' + msg += ' suppress this error.' + mx.abort(msg) + + if version_check_setting == 'strict' and not success: + if latest == 'not found': + msg = f'No JVMCI JDK found in {common_path} that matches {jvmci_version_str(_jdk_jvmci_version)}.' + msg += os.linesep + f'Check that {latest} matches the versions of the other JVMCI JDKs.' + else: + msg = f'Version mismatch in {common_path}:' + msg += os.linesep + f'Check that {latest} matches the versions of the other JVMCI JDKs.' + msg += os.linesep + 'Set the JVMCI_VERSION_CHECK environment variable to something else then "strict" to' + msg += ' suppress this error.' + mx.abort(msg) - latest = get_latest_jvmci_version() - if latest is not None and _jdk_jvmci_version < latest: + if success and _jdk_jvmci_version < latest: common_path = os.path.normpath(common_path) - msg = 'JVMCI version of JAVA_HOME is older than in {}: {} < {} '.format( - common_path, - jvmci_version_str(_jdk_jvmci_version), - jvmci_version_str(latest)) + msg = f'JVMCI version of JAVA_HOME is older than in {common_path}: {jvmci_version_str(_jdk_jvmci_version)} < {jvmci_version_str(latest)} ' msg += os.linesep + 'This poses the risk of hitting JVMCI bugs that have already been fixed.' - msg += os.linesep + 'Consider using {}, which you can get via:'.format(jvmci_version_str(latest)) - msg += os.linesep + 'mx fetch-jdk --configuration {}'.format(common_path) - mx.warn(msg) + msg += os.linesep + f'Consider using {jvmci_version_str(latest)}, which you can get via:' + msg += os.linesep + f'mx fetch-jdk --configuration {common_path}' + mx.abort_or_warn(msg, version_check_setting == 'strict') class GraalArchiveParticipant: providersRE = re.compile(r'(?:META-INF/versions/([1-9][0-9]*)/)?META-INF/providers/(.+)') diff --git a/compiler/src/jdk.internal.vm.compiler.test/src/org/graalvm/compiler/hotspot/test/JVMCIVersionCheckMaxValueTest.java b/compiler/src/jdk.internal.vm.compiler.test/src/org/graalvm/compiler/hotspot/test/JVMCIVersionCheckMaxValueTest.java new file mode 100644 index 000000000000..180386e26739 --- /dev/null +++ b/compiler/src/jdk.internal.vm.compiler.test/src/org/graalvm/compiler/hotspot/test/JVMCIVersionCheckMaxValueTest.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2019, 2023, 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 org.graalvm.compiler.hotspot.test; + +import org.graalvm.compiler.core.test.GraalCompilerTest; +import org.graalvm.compiler.hotspot.JVMCIVersionCheck; +import org.junit.Assert; +import org.junit.Test; + +/** + * Test handling of version components bigger than Integer.MAX_VALUE. + */ +public class JVMCIVersionCheckMaxValueTest extends GraalCompilerTest { + + public static final String EXPECTED_MSG = "Cannot read JVMCI version from java.vm.version property"; + + @Test + public void testLegacyVersion() { + for (String version : new String[]{"20.0-b" + Long.MAX_VALUE, "20." + Long.MAX_VALUE + "-b1", Long.MAX_VALUE + ".0-b1"}) { + testVersion(String.format("prefix-jvmci-%s-suffix", version)); + } + } + + @Test + public void testNewVersion() { + // We only want to test jvmciBuild, not Runtime.Version, so we use a fixed jdkVersion string + testVersion(String.format("99.0.1-jvmci-b%s-suffix", Long.MAX_VALUE)); + } + + private static void testVersion(String javaVmVersion) { + try { + JVMCIVersionCheck.Version minVersion = new JVMCIVersionCheck.Version(20, 0, 1); + // Use a javaSpecVersion that will likely not fail in the near future + JVMCIVersionCheck.check(JVMCIVersionCheckTest.props, minVersion, "99", javaVmVersion, false); + Assert.fail("expected to fail checking " + javaVmVersion + " against " + minVersion); + } catch (InternalError e) { + if (!e.getMessage().contains(EXPECTED_MSG)) { + throw new AssertionError("Unexpected exception message. Expected: " + EXPECTED_MSG, e); + } + } + } +} diff --git a/compiler/src/jdk.internal.vm.compiler.test/src/org/graalvm/compiler/hotspot/test/JVMCIVersionCheckTest.java b/compiler/src/jdk.internal.vm.compiler.test/src/org/graalvm/compiler/hotspot/test/JVMCIVersionCheckTest.java index aba76cdebdbf..234f2e655c91 100644 --- a/compiler/src/jdk.internal.vm.compiler.test/src/org/graalvm/compiler/hotspot/test/JVMCIVersionCheckTest.java +++ b/compiler/src/jdk.internal.vm.compiler.test/src/org/graalvm/compiler/hotspot/test/JVMCIVersionCheckTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, 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 @@ -24,7 +24,10 @@ */ package org.graalvm.compiler.hotspot.test; +import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Random; @@ -34,59 +37,90 @@ import org.graalvm.compiler.hotspot.JVMCIVersionCheck.Version; import org.junit.Assert; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; +@RunWith(Parameterized.class) public class JVMCIVersionCheckTest extends GraalCompilerTest { - @Test - public void test01() { + private static final String[] JDK_VERSIONS = { + null, + "21", + "21+3", + "21.0.1+3", + "21-ea+11-790" + }; + + static final Map props; + static { Properties sprops = System.getProperties(); - Map props = new HashMap<>(sprops.size()); + props = new HashMap<>(sprops.size()); for (String name : sprops.stringPropertyNames()) { props.put(name, sprops.getProperty(name)); } - long seed = Long.getLong("test.seed", System.nanoTime()); - Random random = new Random(seed); + } - for (int i = 0; i < 50; i++) { - int minMajor = i; - int minMinor = 50 - i; - for (int j = 0; j < 50; j++) { - int major = j; - int minor = 50 - j; + private static final long SEED = Long.getLong("test.seed", System.nanoTime()); - for (int k = 0; k < 30; k++) { - int minBuild = random.nextInt(100); - int build = random.nextInt(100); + @Parameters(name = "{0} vs {1}") + public static Collection data() { + List ret = new ArrayList<>(); + Random random = new Random(SEED); - Version version = new Version(major, minor, build); - Version minVersion = new Version(minMajor, minMinor, minBuild); - String javaVmVersion = String.format("prefix-jvmci-%s-suffix", version); - if (!version.isLessThan(minVersion)) { - try { - JVMCIVersionCheck.check(props, minVersion, "17", javaVmVersion, false); - } catch (InternalError e) { - throw new AssertionError("Failed " + JVMCIVersionCheckTest.class.getSimpleName() + " with -Dtest.seed=" + seed, e); - } - } else { - try { - JVMCIVersionCheck.check(props, minVersion, "17", javaVmVersion, false); - Assert.fail("expected to fail checking " + javaVmVersion + " against " + minVersion + " (-Dtest.seed=" + seed + ")"); - } catch (InternalError e) { - // pass + for (String minJdkVersion : JDK_VERSIONS) { + for (String jdkVersion : JDK_VERSIONS) { + for (int i = 0; i < (minJdkVersion == null ? 50 : 1); i++) { + int minMajor = i; + int minMinor = 50 - i; + for (int j = 0; j < (jdkVersion == null ? 50 : 1); j++) { + int major = j; + int minor = 50 - j; + + for (int k = 0; k < 30; k++) { + int minBuild = random.nextInt(100); + int build = random.nextInt(100); + + Version version = getVersion(jdkVersion, major, minor, build); + Version minVersion = getVersion(minJdkVersion, minMajor, minMinor, minBuild); + ret.add(new Object[]{version, minVersion}); } } } } } + return ret; + } - // Test handling of version components bigger than Integer.MAX_VALUE - for (String version : new String[]{"20.0." + Long.MAX_VALUE, "20." + Long.MAX_VALUE + ".0", Long.MAX_VALUE + ".0.0"}) { - String javaVmVersion = String.format("prefix-jvmci-%s-suffix", version); + private static Version getVersion(String jdkVersion, int major, int minor, int build) { + if (jdkVersion != null) { + // new version scheme + return new Version(jdkVersion, build); + } else { + // legacy version scheme + return new Version(major, minor, build); + } + } + + @Parameter(value = 0) public Version version; + @Parameter(value = 1) public Version minVersion; + + @Test + public void test01() { + String legacyPrefix = version.toString().startsWith("jvmci") ? "prefix-" : ""; + String javaVmVersion = legacyPrefix + version.toString() + "Suffix"; + if (!version.isLessThan(minVersion)) { + try { + JVMCIVersionCheck.check(props, minVersion, "21", javaVmVersion, false); + } catch (InternalError e) { + throw new AssertionError("Failed " + JVMCIVersionCheckTest.class.getSimpleName() + " with -Dtest.seed=" + SEED, e); + } + } else { try { - Version minVersion = new Version(20, 0, 1); - JVMCIVersionCheck.check(props, minVersion, "1.8", javaVmVersion, false); - Assert.fail("expected to fail checking " + javaVmVersion + " against " + minVersion); + JVMCIVersionCheck.check(props, minVersion, "21", javaVmVersion, false); + Assert.fail("expected to fail checking " + javaVmVersion + " against " + minVersion + " (-Dtest.seed=" + SEED + ")"); } catch (InternalError e) { // pass } diff --git a/compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java b/compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java index ab4a646e979f..77b1fcfdf655 100644 --- a/compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java +++ b/compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java @@ -501,7 +501,7 @@ private static String markWordField(String simpleName) { public final long verifyOopMask = getFieldValue("CompilerToVM::Data::Universe_verify_oop_mask", Long.class, "uintptr_t"); public final long verifyOopBits = getFieldValue("CompilerToVM::Data::Universe_verify_oop_bits", Long.class, "uintptr_t"); - public final int logOfHRGrainBytes = getFieldValue("HeapRegion::LogOfHRGrainBytes", Integer.class, "int"); + public final int logOfHRGrainBytes = getFieldValue("HeapRegion::LogOfHRGrainBytes", Integer.class, JDK >= 22 ? "uint" : "int"); public final int cardtableShift = getFieldValue("CompilerToVM::Data::cardtable_shift", Integer.class, "int"); public final long cardtableStartAddress; diff --git a/compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java b/compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java index 91a348dfad7f..1b5ca3474055 100644 --- a/compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java +++ b/compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java @@ -46,26 +46,39 @@ public final class JVMCIVersionCheck { /** * Minimum JVMCI version supported by Graal. */ - private static final Version JVMCI_MIN_VERSION = new Version(23, 1, 15); + private static final Map JVMCI_MIN_VERSIONS = Map.of( + "21", new Version(23, 1, 15), + "22", new Version("22+13", 1)); + private static final int NA = 0; /** * Minimum Java release supported by Graal. */ - private static final int JAVA_MIN_RELEASE = 17; + private static final int JAVA_MIN_RELEASE = 21; public static class Version { - private final int major; - private final int minor; - private final int build; + private final Runtime.Version jdkVersion; + private final int jvmciMajor; + private final int jvmciMinor; + private final int jvmciBuild; + private final boolean legacy; static Version parse(String vmVersion) { - Matcher m = Pattern.compile(".*-jvmci-(\\d+)\\.(\\d+)-b(\\d+).*").matcher(vmVersion); + Matcher m = Pattern.compile("(.+)-jvmci(-(\\d+)\\.(\\d+))?-b(\\d+).*").matcher(vmVersion); if (m.matches()) { try { - int major = Integer.parseInt(m.group(1)); - int minor = Integer.parseInt(m.group(2)); - int build = Integer.parseInt(m.group(3)); - return new Version(major, minor, build); + if (m.group(3) == null) { + assert m.group(4) == null : "if jvmciMajor is null jvmciMinor must also be null"; + String jdkVersion = m.group(1); + int jvmciBuild = Integer.parseInt(m.group(5)); + return new Version(jdkVersion, jvmciBuild); + } else { + int jvmciMajor = Integer.parseInt(m.group(3)); + int jvmciMinor = Integer.parseInt(m.group(4)); + int jvmciBuild = Integer.parseInt(m.group(5)); + return new Version(jvmciMajor, jvmciMinor, jvmciBuild); + } + } catch (NumberFormatException e) { // ignore } @@ -73,10 +86,32 @@ static Version parse(String vmVersion) { return null; } - public Version(int major, int minor, int build) { - this.major = major; - this.minor = minor; - this.build = build; + /** + * Convenience constructor for the current version scheme that only uses the JDK version and + * the JVMCI build number. + */ + public Version(String jdkVersionString, int jvmciBuild) { + this(jdkVersionString, NA, NA, jvmciBuild, false); + } + + /** + * Legacy construction for versions without JDK version. This force sets {@link #jdkVersion} + * to {@code 21}. While this is not entirely correct, it works for our purposes. + */ + public Version(int jvmciMajor, int jvmciMinor, int jvmciBuild) { + this("21", jvmciMajor, jvmciMinor, jvmciBuild, true); + } + + private Version(String jdkVersionString, int jvmciMajor, int jvmciMinor, int jvmciBuild, boolean legacy) { + this(Runtime.Version.parse(jdkVersionString), jvmciMajor, jvmciMinor, jvmciBuild, legacy); + } + + private Version(Runtime.Version jdkVersion, int jvmciMajor, int jvmciMinor, int jvmciBuild, boolean legacy) { + this.jdkVersion = jdkVersion; + this.jvmciMajor = jvmciMajor; + this.jvmciMinor = jvmciMinor; + this.jvmciBuild = jvmciBuild; + this.legacy = legacy; } boolean isGreaterThan(Version other) { @@ -87,15 +122,26 @@ boolean isGreaterThan(Version other) { } public boolean isLessThan(Version other) { - if (this.major < other.major) { + if (this.legacy && !other.legacy) { return true; } - if (this.major == other.major) { - if (this.minor < other.minor) { + if (this.legacy == other.legacy) { + int compareTo = this.legacy ? 0 : this.jdkVersion.compareTo(other.jdkVersion); + if (compareTo < 0) { return true; } - if (this.minor == other.minor && this.build < other.build) { - return true; + if (compareTo == 0) { + if (this.jvmciMajor < other.jvmciMajor) { + return true; + } + if (this.jvmciMajor == other.jvmciMajor) { + if (this.jvmciMinor < other.jvmciMinor) { + return true; + } + if (this.jvmciMinor == other.jvmciMinor && this.jvmciBuild < other.jvmciBuild) { + return true; + } + } } } return false; @@ -103,23 +149,34 @@ public boolean isLessThan(Version other) { @Override public boolean equals(Object obj) { - if (obj instanceof Version) { - Version that = (Version) obj; - return this.major == that.major && this.minor == that.minor && this.build == that.build; + if (obj instanceof Version that) { + return this.jdkVersion.equals(that.jdkVersion) && this.jvmciMajor == that.jvmciMajor && this.jvmciMinor == that.jvmciMinor && this.jvmciBuild == that.jvmciBuild; } return false; } @Override public int hashCode() { - return this.major ^ this.minor ^ this.build; + return this.jdkVersion.hashCode() ^ this.jvmciMajor ^ this.jvmciMinor ^ this.jvmciBuild; } - public static final String AS_TAG_FORMAT = "jvmci-%d.%d-b%02d"; + public static final String AS_TAG_FORMAT_22_AND_LATER = "%s-jvmci-b%02d"; + public static final String AS_TAG_FORMAT_21_AND_EARLIER = "jvmci-%d.%d-b%02d"; @Override public String toString() { - return String.format(AS_TAG_FORMAT, major, minor, build); + if (!legacy) { + return String.format(AS_TAG_FORMAT_22_AND_LATER, jdkVersion, jvmciBuild); + } else { + return String.format(AS_TAG_FORMAT_21_AND_EARLIER, jvmciMajor, jvmciMinor, jvmciBuild); + } + } + + public String printFormat(PrintFormat format) { + return switch (format) { + case TUPLE -> String.format("%s,%d,%d,%d", jdkVersion, jvmciMajor, jvmciMinor, jvmciBuild); + case AS_TAG -> toString(); + }; } } @@ -161,9 +218,15 @@ private JVMCIVersionCheck(Map props, String javaSpecVersion, Str this.vmVersion = vmVersion; } - static void check(Map props, boolean exitOnFailure, String format) { - JVMCIVersionCheck checker = new JVMCIVersionCheck(props, props.get("java.specification.version"), props.get("java.vm.version")); - checker.run(exitOnFailure, JVMCI_MIN_VERSION, format); + enum PrintFormat { + TUPLE, + AS_TAG + } + + static void check(Map props, boolean exitOnFailure, PrintFormat format) { + String javaSpecVersion = props.get("java.specification.version"); + JVMCIVersionCheck checker = new JVMCIVersionCheck(props, javaSpecVersion, props.get("java.vm.version")); + checker.run(exitOnFailure, JVMCI_MIN_VERSIONS.get(javaSpecVersion), format); } /** @@ -177,7 +240,7 @@ public static void check(Map props, checker.run(exitOnFailure, minVersion, null); } - private void run(boolean exitOnFailure, Version minVersion, String format) { + private void run(boolean exitOnFailure, Version minVersion, PrintFormat format) { if (javaSpecVersion.compareTo(Integer.toString(JAVA_MIN_RELEASE)) < 0) { failVersionCheck(exitOnFailure, "Graal requires JDK " + JAVA_MIN_RELEASE + " or later.%n"); } else { @@ -190,18 +253,16 @@ private void run(boolean exitOnFailure, Version minVersion, String format) { } if (vmVersion.contains("-jvmci-")) { // A "labsjdk" + if (minVersion == null) { + failVersionCheck(exitOnFailure, "No minimum JVMCI version specified for JDK version %s.%n", javaSpecVersion); + } Version v = Version.parse(vmVersion); if (v != null) { if (format != null) { - System.out.printf(format + "%n", v.major, v.minor, v.build); + System.out.println(v.printFormat(format)); } - Version actualMinVersion = minVersion; - if (javaSpecVersion.equals("19")) { - // Last JVMCI update for JDK 19 - actualMinVersion = new Version(23, 0, 5); - } - if (v.isLessThan(actualMinVersion)) { - failVersionCheck(exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal: %s < %s.%n", v, actualMinVersion); + if (v.isLessThan(minVersion)) { + failVersionCheck(exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal: %s < %s.%n", v, minVersion); } return; } @@ -222,14 +283,27 @@ public static void main(String[] args) { for (String name : sprops.stringPropertyNames()) { props.put(name, sprops.getProperty(name)); } - String format = "%d,%d,%d"; + PrintFormat format = PrintFormat.TUPLE; + boolean minVersion = false; for (String arg : args) { if (arg.equals("--as-tag")) { - format = Version.AS_TAG_FORMAT; + format = PrintFormat.AS_TAG; + } else if (arg.equals("--min-version")) { + minVersion = true; } else { throw new IllegalArgumentException("Unknown argument: " + arg); } } - check(props, true, format); + if (minVersion) { + String javaSpecVersion = props.get("java.specification.version"); + Version v = JVMCI_MIN_VERSIONS.get(javaSpecVersion); + if (v == null) { + System.out.printf("No minimum JVMCI version specified for JDK version %s.%n", javaSpecVersion); + } else { + System.out.println(v.printFormat(format)); + } + } else { + check(props, true, format); + } } } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNIHeaderDirectivesJDK19OrLater.java b/compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/hotspot/JVMCIVersionCompare.java similarity index 70% rename from substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNIHeaderDirectivesJDK19OrLater.java rename to compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/hotspot/JVMCIVersionCompare.java index 18f3e031f553..35803f542d92 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNIHeaderDirectivesJDK19OrLater.java +++ b/compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/hotspot/JVMCIVersionCompare.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 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 @@ -22,14 +22,17 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.svm.core.jni.headers; +package org.graalvm.compiler.hotspot; -import org.graalvm.compiler.serviceprovider.JavaVersionUtil; +public final class JVMCIVersionCompare { -public class JNIHeaderDirectivesJDK19OrLater extends JNIHeaderDirectives { - - @Override - public boolean isInConfiguration() { - return JavaVersionUtil.JAVA_SPEC >= 19; + public static void main(String[] args) { + if (args.length != 2) { + System.err.println("Expected two arguments"); + System.exit(1); + } + Runtime.Version a = Runtime.Version.parse(args[0]); + Runtime.Version b = Runtime.Version.parse(args[1]); + System.out.print(a.compareTo(b)); } } diff --git a/compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/java/LambdaUtils.java b/compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/java/LambdaUtils.java index fbda3673e36a..43f6706b5e7b 100644 --- a/compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/java/LambdaUtils.java +++ b/compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/java/LambdaUtils.java @@ -51,26 +51,13 @@ public final class LambdaUtils { - private static final Pattern LAMBDA_PATTERN; + private static final Pattern LAMBDA_PATTERN = Pattern.compile("\\$\\$Lambda[/.][^/]+;"); private static final char[] HEX = "0123456789abcdef".toCharArray(); - public static final String LAMBDA_SPLIT_PATTERN; - public static final String LAMBDA_CLASS_NAME_SUBSTRING; + public static final String LAMBDA_SPLIT_PATTERN = "\\$\\$Lambda"; + public static final String LAMBDA_CLASS_NAME_SUBSTRING = "$$Lambda"; public static final String SERIALIZATION_TEST_LAMBDA_CLASS_SUBSTRING = "$$Lambda"; public static final String SERIALIZATION_TEST_LAMBDA_CLASS_SPLIT_PATTERN = "\\$\\$Lambda"; - static { - if (Runtime.version().feature() < 21) { - LAMBDA_PATTERN = Pattern.compile("\\$\\$Lambda\\$\\d+[/.][^/]+;"); - LAMBDA_SPLIT_PATTERN = "\\$\\$Lambda\\$"; - LAMBDA_CLASS_NAME_SUBSTRING = "$$Lambda$"; - } else { - // JDK-8292914 - LAMBDA_PATTERN = Pattern.compile("\\$\\$Lambda[/.][^/]+;"); - LAMBDA_SPLIT_PATTERN = "\\$\\$Lambda"; - LAMBDA_CLASS_NAME_SUBSTRING = "$$Lambda"; - } - } - private static GraphBuilderConfiguration buildLambdaParserConfig(ClassInitializationPlugin cip) { GraphBuilderConfiguration.Plugins plugins = new GraphBuilderConfiguration.Plugins(new InvocationPlugins()); plugins.setClassInitializationPlugin(cip); diff --git a/compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java b/compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java index 3d727ec1fdcc..4568eb705c02 100644 --- a/compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java +++ b/compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java @@ -442,7 +442,7 @@ public AddressNode createFieldAddress(StructuredGraph graph, ValueNode object, R if (offset >= 0) { return createOffsetAddress(graph, object, offset); } else { - return null; + throw GraalError.shouldNotReachHere("Field is missing: " + field.getDeclaringClass().toJavaName(true) + "." + field.getName()); } } @@ -463,7 +463,6 @@ protected void lowerLoadFieldNode(LoadFieldNode loadField, LoweringTool tool) { Stamp loadStamp = loadStamp(loadField.stamp(NodeView.DEFAULT), getStorageKind(field)); AddressNode address = createFieldAddress(graph, object, field); - assert address != null : "Field that is loaded must not be eliminated: " + field.getDeclaringClass().toJavaName(true) + "." + field.getName(); BarrierType barrierType = barrierSet.fieldReadBarrierType(field, getStorageKind(field)); ReadNode memoryRead = graph.add(new ReadNode(address, overrideFieldLocationIdentity(loadField.getLocationIdentity()), loadStamp, barrierType, loadField.getMemoryOrder())); @@ -479,7 +478,6 @@ protected void lowerStoreFieldNode(StoreFieldNode storeField, LoweringTool tool) object = createNullCheckedValue(object, storeField, tool); ValueNode value = implicitStoreConvert(graph, getStorageKind(storeField.field()), storeField.value()); AddressNode address = createFieldAddress(graph, object, field); - assert address != null; BarrierType barrierType = barrierSet.fieldWriteBarrierType(field, getStorageKind(field)); WriteNode memoryWrite = graph.add(new WriteNode(address, overrideFieldLocationIdentity(storeField.getLocationIdentity()), value, barrierType, storeField.getMemoryOrder())); @@ -976,13 +974,15 @@ protected void lowerCommitAllocationNode(CommitAllocationNode commit, LoweringTo ValueNode allocValue = allocations[commit.getVirtualObjects().indexOf(value)]; if (!(allocValue.isConstant() && allocValue.asConstant().isDefaultForKind())) { assert virtual.entryKind(metaAccessExtensionProvider, i) == JavaKind.Object && allocValue.getStackKind() == JavaKind.Object; - AddressNode address; - BarrierType barrierType; + AddressNode address = null; + BarrierType barrierType = null; if (virtual instanceof VirtualInstanceNode) { VirtualInstanceNode virtualInstance = (VirtualInstanceNode) virtual; ResolvedJavaField field = virtualInstance.field(i); - address = createFieldAddress(graph, newObject, field); - barrierType = barrierSet.fieldWriteBarrierType(field, getStorageKind(field)); + if (fieldOffset(field) >= 0) { + address = createFieldAddress(graph, newObject, field); + barrierType = barrierSet.fieldWriteBarrierType(field, getStorageKind(field)); + } } else { assert virtual instanceof VirtualArrayNode; address = createArrayAddress(graph, newObject, virtual.entryKind(metaAccessExtensionProvider, i), ConstantNode.forInt(i, graph)); diff --git a/substratevm/ci/ci_common/svm-gate.libsonnet b/substratevm/ci/ci_common/svm-gate.libsonnet index 3c06acd8d20e..3f54c02ada5a 100644 --- a/substratevm/ci/ci_common/svm-gate.libsonnet +++ b/substratevm/ci/ci_common/svm-gate.libsonnet @@ -42,7 +42,7 @@ for f in _fields ], mxgate_name:: outer.task_name, - name: std.join("-", [outer.target, suite_short, self.mxgate_name] + config + ["jdk" + outer.jdk_version] + target_arch_suffix + [outer.os, outer.arch]) + batch_suffix, + name: std.join("-", [outer.target, suite_short, self.mxgate_name] + config + [outer.jdk] + target_arch_suffix + [outer.os, outer.arch]) + batch_suffix, run+: [["mx", "--kill-with-sigquit", "--strict-compliance"] + dynamic_imports + ["gate", "--strict-mode", "--tags", std.join(",", outer.mxgate_tags)] + outer.mxgate_extra_args], } })), diff --git a/substratevm/mx.substratevm/mx_substratevm.py b/substratevm/mx.substratevm/mx_substratevm.py index 1bdcc849370e..c2a54537272b 100644 --- a/substratevm/mx.substratevm/mx_substratevm.py +++ b/substratevm/mx.substratevm/mx_substratevm.py @@ -1884,30 +1884,14 @@ def config_file_update(self, file_path, lines, file_paths): # com.oracle.svm.driver.NativeImage.BuildConfiguration.getBuilderJavaArgs(). def compute_graal_compiler_flags_map(self): graal_compiler_flags_map = dict() - graal_compiler_flags_map['8'] = [ - '-d64', - '-XX:-UseJVMCIClassLoader' - ] - - graal_compiler_flags_map['11'] = [ - # Disable the check for JDK-8 graal version. - '-Dsubstratevm.IgnoreGraalVersionCheck=true', - ] # Packages to add-export distributions_transitive = mx.classpath_entries(self.buildDependencies) required_exports = mx_javamodules.requiredExports(distributions_transitive, get_jdk()) exports_flags = mx_sdk_vm.AbstractNativeImageConfig.get_add_exports_list(required_exports) - graal_compiler_flags_map['11'].extend(exports_flags) - # Currently JDK 17 and JDK 11 have the same flags - graal_compiler_flags_map['17'] = graal_compiler_flags_map['11'] - # Currently JDK 19 and JDK 17 have the same flags - graal_compiler_flags_map['19'] = graal_compiler_flags_map['17'] - graal_compiler_flags_map['19-ea'] = graal_compiler_flags_map['19'] - # Currently JDK 20 and JDK 19 have the same flags - graal_compiler_flags_map['20'] = graal_compiler_flags_map['19'] - # Currently JDK 22, JDK 21 and JDK 20 have the same flags - graal_compiler_flags_map['21'] = graal_compiler_flags_map['20'] + + graal_compiler_flags_map['21'] = exports_flags + # Currently JDK 22 has the same flags graal_compiler_flags_map['22'] = graal_compiler_flags_map['21'] # DO NOT ADD ANY NEW ADD-OPENS OR ADD-EXPORTS HERE! # diff --git a/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/SubstrateAMD64Backend.java b/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/SubstrateAMD64Backend.java index 0c971310952f..81874c919158 100644 --- a/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/SubstrateAMD64Backend.java +++ b/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/SubstrateAMD64Backend.java @@ -181,6 +181,7 @@ import com.oracle.svm.core.util.VMError; import jdk.vm.ci.amd64.AMD64; +import jdk.vm.ci.amd64.AMD64.CPUFeature; import jdk.vm.ci.amd64.AMD64Kind; import jdk.vm.ci.code.CallingConvention; import jdk.vm.ci.code.CodeCacheProvider; @@ -754,8 +755,7 @@ public void emitConvertZeroToNull(AllocatableValue result, Value value) { @Override public void emitProcid(AllocatableValue dst) { - // GR-43733: Replace string by feature when we remove support for Java 17 - if (supportsCPUFeature("RDPID")) { + if (supportsCPUFeature(CPUFeature.RDPID)) { append(new AMD64ReadProcid(dst)); } else { AMD64ReadTimestampCounterWithProcid procid = new AMD64ReadTimestampCounterWithProcid(); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JDK17OrEarlier.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JDK17OrEarlier.java index 48d8487b98f0..3cfec6ed9238 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JDK17OrEarlier.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JDK17OrEarlier.java @@ -28,6 +28,7 @@ import org.graalvm.compiler.serviceprovider.JavaVersionUtil; +@Deprecated(since = "24.0.0", forRemoval = true) public class JDK17OrEarlier implements BooleanSupplier { @Override public boolean getAsBoolean() { diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/management/ManagementSupport.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/management/ManagementSupport.java index 5d9de38d6944..0369dcfad367 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/management/ManagementSupport.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/management/ManagementSupport.java @@ -104,20 +104,26 @@ */ public final class ManagementSupport implements ThreadListener { - private static final boolean isJdkManagementJfrModulePresent; + private static final Class FLIGHT_RECORDER_MX_BEAN_CLASS; static { - var loggingModule = ModuleLayer.boot().findModule("jdk.management.jfr"); - if (loggingModule.isPresent()) { - ManagementSupport.class.getModule().addReads(loggingModule.get()); + var jfrModule = ModuleLayer.boot().findModule("jdk.management.jfr"); + if (jfrModule.isPresent()) { + ManagementSupport.class.getModule().addReads(jfrModule.get()); + try { + FLIGHT_RECORDER_MX_BEAN_CLASS = Class.forName("jdk.management.jfr.FlightRecorderMXBean", false, Object.class.getClassLoader()); + } catch (ClassNotFoundException ex) { + throw VMError.shouldNotReachHere(ex); + } + } else { + FLIGHT_RECORDER_MX_BEAN_CLASS = null; } - isJdkManagementJfrModulePresent = loggingModule.isPresent(); } static class JdkManagementJfrModulePresent implements BooleanSupplier { @Override public boolean getAsBoolean() { - return isJdkManagementJfrModulePresent; + return FLIGHT_RECORDER_MX_BEAN_CLASS != null; } } @@ -166,7 +172,9 @@ public boolean getAsBoolean() { * run time. */ doAddPlatformManagedObjectSingleton(getOsMXBeanInterface(), (PlatformManagedObjectSupplier) this::getOsMXBean); - doAddPlatformManagedObjectSingleton(PlatformManagedObject.class, (PlatformManagedObjectSupplier) this::getFlightRecorderMXBean); + if (FLIGHT_RECORDER_MX_BEAN_CLASS != null) { + doAddPlatformManagedObjectSingleton(FLIGHT_RECORDER_MX_BEAN_CLASS, (PlatformManagedObjectSupplier) this::getFlightRecorderMXBean); + } } private static Class getOsMXBeanInterface() { diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/functions/JNIFunctionTables.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/functions/JNIFunctionTables.java index a79695eae0c4..33bb0c7201fb 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/functions/JNIFunctionTables.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/functions/JNIFunctionTables.java @@ -24,7 +24,6 @@ */ package com.oracle.svm.core.jni.functions; -import org.graalvm.compiler.serviceprovider.JavaVersionUtil; import org.graalvm.compiler.word.Word; import org.graalvm.nativeimage.CurrentIsolate; import org.graalvm.nativeimage.ImageSingletons; @@ -38,8 +37,6 @@ import org.graalvm.word.UnsignedWord; import org.graalvm.word.WordBase; -import jdk.internal.misc.Unsafe; - import com.oracle.svm.core.FrameAccess; import com.oracle.svm.core.c.CIsolateData; import com.oracle.svm.core.c.CIsolateDataFactory; @@ -48,9 +45,10 @@ import com.oracle.svm.core.jni.headers.JNIInvokeInterface; import com.oracle.svm.core.jni.headers.JNIJavaVM; import com.oracle.svm.core.jni.headers.JNINativeInterface; -import com.oracle.svm.core.jni.headers.JNINativeInterfaceJDK19OrLater; import com.oracle.svm.core.util.VMError; +import jdk.internal.misc.Unsafe; + /** * Performs the initialization of the JNI function table structures at runtime. */ @@ -75,7 +73,7 @@ public static JNIFunctionTables singleton() { private final CIsolateData jniJavaVM = CIsolateDataFactory.createStruct("jniJavaVM", JNIJavaVM.class); private static int getFunctionTableSize() { - return JavaVersionUtil.JAVA_SPEC <= 17 ? SizeOf.get(JNINativeInterface.class) : SizeOf.get(JNINativeInterfaceJDK19OrLater.class); + return SizeOf.get(JNINativeInterface.class); } @Platforms(Platform.HOSTED_ONLY.class) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/functions/JNIFunctions.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/functions/JNIFunctions.java index 7525f826e297..a8a2f40b8dc8 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/functions/JNIFunctions.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/functions/JNIFunctions.java @@ -106,15 +106,14 @@ import com.oracle.svm.core.jni.headers.JNIObjectRefType; import com.oracle.svm.core.jni.headers.JNIValue; import com.oracle.svm.core.jni.headers.JNIVersion; -import com.oracle.svm.core.jni.headers.JNIVersionJDK19OrLater; -import com.oracle.svm.core.jni.headers.JNIVersionJDK20OrLater; -import com.oracle.svm.core.jni.headers.JNIVersionJDK21OrLater; +import com.oracle.svm.core.jni.headers.JNIVersionJDK22OrLater; import com.oracle.svm.core.log.Log; import com.oracle.svm.core.monitor.MonitorInflationCause; import com.oracle.svm.core.monitor.MonitorSupport; import com.oracle.svm.core.snippets.KnownIntrinsics; import com.oracle.svm.core.stack.StackOverflowCheck; import com.oracle.svm.core.thread.JavaThreads; +import com.oracle.svm.core.thread.Target_java_lang_BaseVirtualThread; import com.oracle.svm.core.thread.VMThreads.SafepointBehavior; import com.oracle.svm.core.thread.VirtualThreads; import com.oracle.svm.core.util.Utf8; @@ -159,10 +158,14 @@ public final class JNIFunctions { @CEntryPointOptions(prologue = CEntryPointOptions.NoPrologue.class, epilogue = CEntryPointOptions.NoEpilogue.class) @Uninterruptible(reason = "No need to enter the isolate and also no way to report errors if unable to.") static int GetVersion(JNIEnvironment env) { - return JavaVersionUtil.JAVA_SPEC >= 21 ? JNIVersionJDK21OrLater.JNI_VERSION_21() - : JavaVersionUtil.JAVA_SPEC >= 20 ? JNIVersionJDK20OrLater.JNI_VERSION_20() - : JavaVersionUtil.JAVA_SPEC >= 19 ? JNIVersionJDK19OrLater.JNI_VERSION_19() - : JNIVersion.JNI_VERSION_10(); + switch (JavaVersionUtil.JAVA_SPEC) { + case 21: + return JNIVersion.JNI_VERSION_21(); + case 22: + return JNIVersionJDK22OrLater.JNI_VERSION_22(); + default: + throw VMError.shouldNotReachHere("Unsupported Java version " + JavaVersionUtil.JAVA_SPEC); + } } /* @@ -1122,6 +1125,16 @@ static JNIObjectHandle DefineClass(JNIEnvironment env, CCharPointer cname, JNIOb return JNIObjectHandles.createLocal(clazz); } + /* + * jboolean (JNICALL *IsVirtualThread) (JNIEnv *env, jobject obj); + */ + @CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnFalse.class, include = CEntryPoint.NotIncludedAutomatically.class, publishAs = Publish.NotPublished) + @CEntryPointOptions(prologue = JNIEnvEnterFatalOnFailurePrologue.class) + static boolean IsVirtualThread(JNIEnvironment env, JNIObjectHandle handle) { + Object obj = JNIObjectHandles.getObject(handle); + return obj instanceof Target_java_lang_BaseVirtualThread; + } + // Checkstyle: resume /** diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/functions/JNIFunctionsJDK19OrLater.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/functions/JNIFunctionsJDK19OrLater.java deleted file mode 100644 index 8a01df0657ec..000000000000 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/functions/JNIFunctionsJDK19OrLater.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2022, 2022, 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.core.jni.functions; - -import org.graalvm.nativeimage.c.function.CEntryPoint; -import org.graalvm.nativeimage.c.function.CEntryPoint.Publish; - -import com.oracle.svm.core.c.function.CEntryPointOptions; -import com.oracle.svm.core.jni.JNIObjectHandles; -import com.oracle.svm.core.jni.functions.JNIFunctions.Support.JNIEnvEnterFatalOnFailurePrologue; -import com.oracle.svm.core.jni.functions.JNIFunctions.Support.JNIExceptionHandlerReturnFalse; -import com.oracle.svm.core.jni.headers.JNIEnvironment; -import com.oracle.svm.core.jni.headers.JNIObjectHandle; -import com.oracle.svm.core.thread.Target_java_lang_BaseVirtualThread; - -@SuppressWarnings("unused") -public final class JNIFunctionsJDK19OrLater { - - // Checkstyle: stop - - /* - * jboolean (JNICALL *IsVirtualThread) (JNIEnv *env, jobject obj); - */ - @CEntryPoint(exceptionHandler = JNIExceptionHandlerReturnFalse.class, include = CEntryPoint.NotIncludedAutomatically.class, publishAs = Publish.NotPublished) - @CEntryPointOptions(prologue = JNIEnvEnterFatalOnFailurePrologue.class) - static boolean IsVirtualThread(JNIEnvironment env, JNIObjectHandle handle) { - Object obj = JNIObjectHandles.getObject(handle); - return obj instanceof Target_java_lang_BaseVirtualThread; - } -} diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNINativeInterface.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNINativeInterface.java index 5882fe50d8b3..42444829db92 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNINativeInterface.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNINativeInterface.java @@ -1470,4 +1470,9 @@ public interface JNINativeInterface extends PointerBase { @CField void setGetModule(CFunctionPointer p); + + // Virtual threads + + @CField + void setIsVirtualThread(CFunctionPointer p); } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNINativeInterfaceJDK19OrLater.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNINativeInterfaceJDK19OrLater.java deleted file mode 100644 index a433b4a14211..000000000000 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNINativeInterfaceJDK19OrLater.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2022, 2022, 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.core.jni.headers; - -import org.graalvm.nativeimage.c.CContext; -import org.graalvm.nativeimage.c.function.CFunctionPointer; -import org.graalvm.nativeimage.c.struct.CField; -import org.graalvm.nativeimage.c.struct.CStruct; - -@CContext(JNIHeaderDirectivesJDK19OrLater.class) -@CStruct(value = "JNINativeInterface_", addStructKeyword = true) -public interface JNINativeInterfaceJDK19OrLater extends JNINativeInterface { - - // Virtual threads - - @CField - void setIsVirtualThread(CFunctionPointer p); -} diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNIVersion.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNIVersion.java index 932bccf718c6..163d3de47765 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNIVersion.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNIVersion.java @@ -34,9 +34,10 @@ public final class JNIVersion { @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) public static boolean isSupported(int version) { - return (JavaVersionUtil.JAVA_SPEC >= 21 && version == JNIVersionJDK21OrLater.JNI_VERSION_21()) || - (JavaVersionUtil.JAVA_SPEC >= 20 && version == JNIVersionJDK20OrLater.JNI_VERSION_20()) || - (JavaVersionUtil.JAVA_SPEC >= 19 && version == JNIVersionJDK19OrLater.JNI_VERSION_19()) || + return (JavaVersionUtil.JAVA_SPEC >= 22 && version == JNIVersionJDK22OrLater.JNI_VERSION_22()) || + version == JNI_VERSION_21() || + version == JNI_VERSION_20() || + version == JNI_VERSION_19() || version == JNI_VERSION_10() || version == JNI_VERSION_9() || version == JNI_VERSION_1_8() || @@ -69,6 +70,15 @@ public static boolean isSupported(int version) { @CConstant public static native int JNI_VERSION_10(); + @CConstant + public static native int JNI_VERSION_19(); + + @CConstant + public static native int JNI_VERSION_20(); + + @CConstant + public static native int JNI_VERSION_21(); + // Checkstyle: resume private JNIVersion() { diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNIVersionJDK19OrLater.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNIVersionJDK19OrLater.java deleted file mode 100644 index 8317a35f6bdf..000000000000 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNIVersionJDK19OrLater.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2022, 2022, 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.core.jni.headers; - -import org.graalvm.nativeimage.c.CContext; -import org.graalvm.nativeimage.c.constant.CConstant; - -@CContext(JNIHeaderDirectivesJDK19OrLater.class) -public final class JNIVersionJDK19OrLater { - - // Checkstyle: stop - - @CConstant - public static native int JNI_VERSION_19(); - - // Checkstyle: resume - - private JNIVersionJDK19OrLater() { - } -} diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNIVersionJDK21OrLater.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNIVersionJDK21OrLater.java deleted file mode 100644 index 1795d46c1be4..000000000000 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNIVersionJDK21OrLater.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2023, 2023, 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.core.jni.headers; - -import org.graalvm.compiler.serviceprovider.JavaVersionUtil; -import org.graalvm.nativeimage.c.CContext; -import org.graalvm.nativeimage.c.constant.CConstant; - -final class JNIHeaderDirectivesJDK21OrLater extends JNIHeaderDirectives { - @Override - public boolean isInConfiguration() { - return JavaVersionUtil.JAVA_SPEC >= 21; - } -} - -@CContext(JNIHeaderDirectivesJDK21OrLater.class) -public final class JNIVersionJDK21OrLater { - - // Checkstyle: stop - - @CConstant - public static native int JNI_VERSION_21(); - - // Checkstyle: resume - - private JNIVersionJDK21OrLater() { - } -} diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNIVersionJDK20OrLater.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNIVersionJDK22OrLater.java similarity index 74% rename from substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNIVersionJDK20OrLater.java rename to substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNIVersionJDK22OrLater.java index a697cd4f8a22..29f1aed99692 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNIVersionJDK20OrLater.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNIVersionJDK22OrLater.java @@ -28,23 +28,27 @@ import org.graalvm.nativeimage.c.CContext; import org.graalvm.nativeimage.c.constant.CConstant; -final class JNIHeaderDirectivesJDK20OrLater extends JNIHeaderDirectives { +final class JNIHeaderDirectivesJDK22OrLater extends JNIHeaderDirectives { @Override public boolean isInConfiguration() { - return JavaVersionUtil.JAVA_SPEC >= 20; + return JavaVersionUtil.JAVA_SPEC >= 22; } } -@CContext(JNIHeaderDirectivesJDK20OrLater.class) -public final class JNIVersionJDK20OrLater { +@CContext(JNIHeaderDirectivesJDK22OrLater.class) +public final class JNIVersionJDK22OrLater { // Checkstyle: stop - @CConstant - public static native int JNI_VERSION_20(); + /* + * GR-48572: there is not yet a JNI_VERSION_22 constant defined. As soon as it gets available, + * the "value" property of the CConstant annotation below must be removed. + */ + @CConstant(value = "JNI_VERSION_21") + public static native int JNI_VERSION_22(); // Checkstyle: resume - private JNIVersionJDK20OrLater() { + private JNIVersionJDK22OrLater() { } } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/ContinuationsFeature.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/ContinuationsFeature.java index 91d7a0ab0010..667712446f67 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/ContinuationsFeature.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/ContinuationsFeature.java @@ -28,9 +28,7 @@ import org.graalvm.compiler.serviceprovider.JavaVersionUtil; import org.graalvm.nativeimage.ImageSingletons; -import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.hosted.RuntimeClassInitialization; -import org.graalvm.nativeimage.impl.InternalPlatform; import com.oracle.svm.core.SubstrateControlFlowIntegrity; import com.oracle.svm.core.SubstrateOptions; @@ -54,7 +52,7 @@ public void afterRegistration(AfterRegistrationAccess access) { boolean supportLoom = false; if (JavaVersionUtil.JAVA_SPEC >= firstLoomPreviewVersion) { boolean haveLoom; - if (JavaVersionUtil.JAVA_SPEC > lastLoomPreviewVersion && Platform.includedIn(InternalPlatform.NATIVE_ONLY.class)) { + if (JavaVersionUtil.JAVA_SPEC > lastLoomPreviewVersion) { haveLoom = true; } else { try { diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Package_jdk_incubator_concurrent_helper.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Package_jdk_incubator_concurrent_helper.java deleted file mode 100644 index 18a08dd5faf0..000000000000 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Package_jdk_incubator_concurrent_helper.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2023, 2023, 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.core.thread; - -import java.util.function.Function; - -import org.graalvm.compiler.serviceprovider.JavaVersionUtil; -import org.graalvm.nativeimage.Platform; -import org.graalvm.nativeimage.Platforms; - -import com.oracle.svm.core.annotate.TargetClass; - -@Platforms(Platform.HOSTED_ONLY.class) -public class Package_jdk_incubator_concurrent_helper implements Function { - - @Override - public String apply(TargetClass annotation) { - if (JavaVersionUtil.JAVA_SPEC >= 21) { - return "java.lang." + annotation.className(); - } else { - return "jdk.incubator.concurrent." + annotation.className(); - } - } -} diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Package_jdk_internal_vm_helper.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Package_jdk_internal_vm_helper.java deleted file mode 100644 index 31673f297175..000000000000 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Package_jdk_internal_vm_helper.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2022, 2022, 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.core.thread; - -import java.util.function.Function; - -import org.graalvm.compiler.serviceprovider.JavaVersionUtil; -import org.graalvm.nativeimage.Platform; -import org.graalvm.nativeimage.Platforms; - -import com.oracle.svm.core.annotate.TargetClass; - -@Platforms(Platform.HOSTED_ONLY.class) -public class Package_jdk_internal_vm_helper implements Function { - - @Override - public String apply(TargetClass annotation) { - if (JavaVersionUtil.JAVA_SPEC >= 19) { - return "jdk.internal.vm." + annotation.className(); - } else { - return "java.lang." + annotation.className(); - } - } -} diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_ScopedValue.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_ScopedValue.java index 5cfa65bd553b..0da2c3124d0f 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_ScopedValue.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_ScopedValue.java @@ -45,7 +45,7 @@ public boolean getAsBoolean() { } } -@TargetClass(className = "ScopedValue", classNameProvider = Package_jdk_incubator_concurrent_helper.class, onlyWith = ScopedValuesEnabled.class) +@TargetClass(className = "java.lang.ScopedValue", onlyWith = ScopedValuesEnabled.class) final class Target_java_lang_ScopedValue { @Substitute static Target_java_lang_ScopedValue_Snapshot scopedValueBindings() { @@ -62,7 +62,7 @@ static Target_java_lang_ScopedValue_Snapshot scopedValueBindings() { * Substituted to directly call {@link Target_java_lang_Thread#setScopedValueBindings} for forced * inlining. */ -@TargetClass(className = "ScopedValue", classNameProvider = Package_jdk_incubator_concurrent_helper.class, innerClass = "Carrier", onlyWith = ScopedValuesEnabled.class) +@TargetClass(className = "java.lang.ScopedValue", innerClass = "Carrier", onlyWith = ScopedValuesEnabled.class) final class Target_java_lang_ScopedValue_Carrier { @Alias int bitmask; @@ -100,7 +100,7 @@ final class Target_jdk_internal_vm_ScopedValueContainer { static native void run(Runnable op); } -@TargetClass(className = "ScopedValue", classNameProvider = Package_jdk_incubator_concurrent_helper.class, innerClass = "Snapshot", onlyWith = ScopedValuesEnabled.class) +@TargetClass(className = "java.lang.ScopedValue", innerClass = "Snapshot", onlyWith = ScopedValuesEnabled.class) final class Target_java_lang_ScopedValue_Snapshot { // Checkstyle: stop @Alias // @@ -111,7 +111,7 @@ final class Target_java_lang_ScopedValue_Snapshot { Target_java_lang_ScopedValue_Snapshot prev; } -@TargetClass(className = "ScopedValue", classNameProvider = Package_jdk_incubator_concurrent_helper.class, innerClass = "Cache", onlyWith = ScopedValuesEnabled.class) +@TargetClass(className = "java.lang.ScopedValue", innerClass = "Cache", onlyWith = ScopedValuesEnabled.class) final class Target_java_lang_ScopedValue_Cache { @Alias static native void invalidate(int toClearBits); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_jdk_internal_vm_Continuation.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_jdk_internal_vm_Continuation.java index 78ddc4b0d1e6..406fb1ee935e 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_jdk_internal_vm_Continuation.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_jdk_internal_vm_Continuation.java @@ -39,7 +39,7 @@ import com.oracle.svm.core.stack.JavaFrameAnchors; import com.oracle.svm.core.util.VMError; -@TargetClass(className = "Continuation", classNameProvider = Package_jdk_internal_vm_helper.class, onlyWith = NotLoomJDK.class) +@TargetClass(className = "jdk.internal.vm.Continuation", onlyWith = NotLoomJDK.class) @Substitute @SuppressWarnings("unused") final class Target_jdk_internal_vm_Continuation__WithoutLoom { @@ -59,7 +59,7 @@ static void unpin() { } } -@TargetClass(className = "Continuation", classNameProvider = Package_jdk_internal_vm_helper.class, onlyWith = LoomJDK.class) +@TargetClass(className = "jdk.internal.vm.Continuation", onlyWith = LoomJDK.class) public final class Target_jdk_internal_vm_Continuation { @Substitute private static void registerNatives() { diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_jdk_internal_vm_ContinuationScope.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_jdk_internal_vm_ContinuationScope.java index 8cd20f6da792..865761b9e42c 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_jdk_internal_vm_ContinuationScope.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_jdk_internal_vm_ContinuationScope.java @@ -26,6 +26,6 @@ import com.oracle.svm.core.annotate.TargetClass; -@TargetClass(className = "ContinuationScope", classNameProvider = Package_jdk_internal_vm_helper.class) +@TargetClass(className = "jdk.internal.vm.ContinuationScope") public final class Target_jdk_internal_vm_ContinuationScope { } diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/RuntimeCompilationFeature.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/RuntimeCompilationFeature.java index 666ddc23f09e..84d065b8f155 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/RuntimeCompilationFeature.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/RuntimeCompilationFeature.java @@ -122,7 +122,6 @@ import jdk.vm.ci.meta.ResolvedJavaField; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; -import jdk.vm.ci.services.Services; /** * The main handler for running the Graal compiler in the Substrate VM at run time. This feature @@ -367,10 +366,11 @@ public GraalGraphObjectReplacer getObjectReplacer() { } protected static List> getRequiredFeaturesHelper() { - if (Services.IS_BUILDING_NATIVE_IMAGE) { + if (SubstrateUtil.isBuildingLibgraal()) { return List.of(FieldsOffsetsFeature.class); + } else { + return List.of(RuntimeCompilationCanaryFeature.class, DeoptimizationFeature.class, FieldsOffsetsFeature.class); } - return List.of(RuntimeCompilationCanaryFeature.class, DeoptimizationFeature.class, FieldsOffsetsFeature.class); } public void setUniverseFactory(SubstrateUniverseFactory universeFactory) { @@ -475,6 +475,12 @@ protected final void beforeAnalysisHelper(BeforeAnalysisAccess c) { for (NodeClass nodeClass : replacements.getSnippetNodeClasses()) { config.getMetaAccess().lookupJavaType(nodeClass.getClazz()).registerAsAllocated("All " + NodeClass.class.getName() + " classes are marked as instantiated eagerly."); } + /* + * Ensure runtime snippet graphs are analyzed. + */ + if (!SubstrateUtil.isBuildingLibgraal()) { + NativeImageGenerator.performSnippetGraphAnalysis(config.getBigBang(), replacements, config.getBigBang().getOptions()); + } /* * Ensure that all snippet methods have their SubstrateMethod object created by the object diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java index 2247ba11c1f9..27b8860661cb 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java @@ -139,7 +139,6 @@ import com.oracle.graal.pointsto.AnalysisPolicy; import com.oracle.graal.pointsto.BigBang; import com.oracle.graal.pointsto.ObjectScanningObserver; -import com.oracle.graal.pointsto.PointsToAnalysis; import com.oracle.graal.pointsto.api.PointstoOptions; import com.oracle.graal.pointsto.constraints.UnsupportedFeatureException; import com.oracle.graal.pointsto.flow.context.bytecode.BytecodeSensitiveAnalysisPolicy; @@ -1123,19 +1122,22 @@ public static void initializeBigBang(Inflation bb, OptionValues options, Feature bb.getAnnotationSubstitutionProcessor(), classInitializationPlugin, ConfigurationValues.getTarget(), supportsStubBasedPlugins); registerReplacements(debug, featureHandler, null, aProviders, true, initForeignCalls); - Collection snippetGraphs = aReplacements.getSnippetGraphs(GraalOptions.TrackNodeSourcePosition.getValue(options), options); - if (bb instanceof NativeImagePointsToAnalysis) { - for (StructuredGraph graph : snippetGraphs) { - HostedConfiguration.instance().registerUsedElements((PointsToAnalysis) bb, graph, false); - } - } else if (bb instanceof NativeImageReachabilityAnalysisEngine) { - NativeImageReachabilityAnalysisEngine reachabilityAnalysis = (NativeImageReachabilityAnalysisEngine) bb; - for (StructuredGraph graph : snippetGraphs) { - reachabilityAnalysis.processGraph(graph); - } - } else { - throw VMError.shouldNotReachHere("Unknown analysis type - please specify how to handle snippets"); + performSnippetGraphAnalysis(bb, aReplacements, options); + } + } + + public static void performSnippetGraphAnalysis(BigBang bb, SubstrateReplacements replacements, OptionValues options) { + Collection snippetGraphs = replacements.getSnippetGraphs(GraalOptions.TrackNodeSourcePosition.getValue(options), options); + if (bb instanceof NativeImagePointsToAnalysis pointsToAnalysis) { + for (StructuredGraph graph : snippetGraphs) { + HostedConfiguration.instance().registerUsedElements(pointsToAnalysis, graph, false); } + } else if (bb instanceof NativeImageReachabilityAnalysisEngine reachabilityAnalysis) { + for (StructuredGraph graph : snippetGraphs) { + reachabilityAnalysis.processGraph(graph); + } + } else { + throw VMError.shouldNotReachHere("Unknown analysis type - please specify how to handle snippets"); } } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SecurityServicesFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SecurityServicesFeature.java index 0a7b66da9b40..1f3fbd56ea58 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SecurityServicesFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SecurityServicesFeature.java @@ -31,6 +31,7 @@ import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; +import java.lang.ref.WeakReference; import java.lang.reflect.Executable; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -67,7 +68,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiConsumer; import java.util.function.Function; -import java.util.function.Predicate; import javax.crypto.Cipher; import javax.crypto.KeyAgreement; @@ -81,7 +81,6 @@ import javax.security.auth.login.Configuration; import org.graalvm.compiler.options.Option; -import org.graalvm.compiler.serviceprovider.JavaVersionUtil; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.hosted.RuntimeJNIAccess; import org.graalvm.nativeimage.hosted.RuntimeReflection; @@ -197,9 +196,6 @@ public static class Options { /** Providers marked as used by the user. */ private final Set manuallyMarkedUsedProviderClassNames = new HashSet<>(); - /** Provider verification cache cleaner that removes unused providers from the cache. */ - private Function verificationCacheCleaner; - /** Provider verification cache that contains only used providers. */ private Object filteredVerificationCache; @@ -307,7 +303,6 @@ public void beforeAnalysis(BeforeAnalysisAccess a) { BeforeAnalysisAccessImpl access = (BeforeAnalysisAccessImpl) a; loader = access.getImageClassLoader(); jceSecurityClass = loader.findClassOrFail("javax.crypto.JceSecurity"); - verificationCacheCleaner = constructVerificationCacheCleaner(); /* Ensure sun.security.provider.certpath.CertPathHelper.instance is initialized. */ access.ensureInitialized("java.security.cert.TrustAnchor"); @@ -366,6 +361,9 @@ private void addManuallyConfiguredUsedProviders(DuringSetupAccess access) { } public boolean shouldRemoveProvider(Provider p) { + if (p == null) { + return true; + } if (usedProviders.contains(p)) { return false; } @@ -373,9 +371,17 @@ public boolean shouldRemoveProvider(Provider p) { } @Override + @SuppressWarnings("unchecked") public Object cleanVerificationCache(Object cache) { if (shouldFilterProviders) { - Object cleanedCache = verificationCacheCleaner.apply(cache); + /* + * The verification cache is an WeakIdentityWrapper -> Verification result + * ConcurrentHashMap. We do not care about the private WeakIdentityWrapper class, it + * extends WeakReference and so using WeakReference.get() is sufficient for us. + */ + var cleanedCache = new ConcurrentHashMap<>((ConcurrentHashMap, Object>) cache); + cleanedCache.keySet().removeIf(key -> shouldRemoveProvider(key.get())); + if (filteredVerificationCache == null || !filteredVerificationCache.equals(cleanedCache)) { filteredVerificationCache = cleanedCache; } @@ -829,44 +835,6 @@ private static void registerForReflection(Class clazz) { RuntimeReflection.register(clazz.getConstructors()); } - @SuppressWarnings("unchecked") - private Function constructVerificationCacheCleaner() { - /* - * The verification cache is an IdentityWrapper -> Verification result ConcurrentHashMap. - * The IdentityWrapper contains the actual provider in the 'obj' field. - */ - String className; - String fieldName; - if (JavaVersionUtil.JAVA_SPEC <= 20) { - className = "javax.crypto.JceSecurity$IdentityWrapper"; - fieldName = "obj"; - } else { - // JDK-8168469 - className = "java.lang.ref.Reference"; - fieldName = "referent"; - } - Class identityWrapper = loader.findClassOrFail(className); - Field providerField = ReflectionUtil.lookupField(identityWrapper, fieldName); - - Predicate listRemovalPredicate = wrapper -> { - try { - return shouldRemoveProvider((Provider) providerField.get(wrapper)); - } catch (IllegalAccessException e) { - throw VMError.shouldNotReachHere(e); - } - }; - - return obj -> { - Map original = (Map) obj; - Map verificationResults = new ConcurrentHashMap<>(original); - - verificationResults.keySet().removeIf(listRemovalPredicate); - - return verificationResults; - }; - - } - private static boolean isSignature(Service s) { return s.getType().equals(SIGNATURE_SERVICE); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIFunctionTablesFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIFunctionTablesFeature.java index 9d1b1b42a33d..ee420f5a973b 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIFunctionTablesFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIFunctionTablesFeature.java @@ -30,7 +30,6 @@ import java.util.List; import java.util.stream.Stream; -import org.graalvm.compiler.serviceprovider.JavaVersionUtil; import org.graalvm.nativeimage.AnnotationAccess; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.c.function.CEntryPoint; @@ -47,11 +46,9 @@ import com.oracle.svm.core.jni.functions.JNIFunctions; import com.oracle.svm.core.jni.functions.JNIFunctions.UnimplementedWithJNIEnvArgument; import com.oracle.svm.core.jni.functions.JNIFunctions.UnimplementedWithJavaVMArgument; -import com.oracle.svm.core.jni.functions.JNIFunctionsJDK19OrLater; import com.oracle.svm.core.jni.functions.JNIInvocationInterface; import com.oracle.svm.core.jni.headers.JNIInvokeInterface; import com.oracle.svm.core.jni.headers.JNINativeInterface; -import com.oracle.svm.core.jni.headers.JNINativeInterfaceJDK19OrLater; import com.oracle.svm.core.meta.MethodPointer; import com.oracle.svm.core.util.VMError; import com.oracle.svm.hosted.FeatureImpl.BeforeAnalysisAccessImpl; @@ -90,7 +87,6 @@ public class JNIFunctionTablesFeature implements Feature { * for the Interface Function Table */ private StructInfo functionTableMetadata; - private StructInfo functionTableMetadataJDK19OrLater; /** * Metadata about the table pointed to by the {@code JavaVM*} C pointer. @@ -120,16 +116,12 @@ public void beforeAnalysis(BeforeAnalysisAccess arg) { invokeInterfaceMetadata = (StructInfo) nativeLibraries.findElementInfo(invokeInterface); AnalysisType functionTable = metaAccess.lookupJavaType(JNINativeInterface.class); functionTableMetadata = (StructInfo) nativeLibraries.findElementInfo(functionTable); - if (JavaVersionUtil.JAVA_SPEC > 17) { - functionTableMetadataJDK19OrLater = (StructInfo) nativeLibraries.findElementInfo(metaAccess.lookupJavaType(JNINativeInterfaceJDK19OrLater.class)); - } // Manually add functions as entry points so this is only done when JNI features are enabled AnalysisType invokes = metaAccess.lookupJavaType(JNIInvocationInterface.class); AnalysisType exports = metaAccess.lookupJavaType(JNIInvocationInterface.Exports.class); AnalysisType functions = metaAccess.lookupJavaType(JNIFunctions.class); - AnalysisType functionsJDK19OrLater = JavaVersionUtil.JAVA_SPEC <= 17 ? null : metaAccess.lookupJavaType(JNIFunctionsJDK19OrLater.class); - Stream analysisMethods = Stream.of(invokes, functions, functionsJDK19OrLater, exports).filter(type -> type != null).flatMap(type -> Stream.of(type.getDeclaredMethods(false))); + Stream analysisMethods = Stream.of(invokes, functions, exports).filter(type -> type != null).flatMap(type -> Stream.of(type.getDeclaredMethods(false))); Stream unimplementedMethods = Stream.of((AnalysisMethod) getSingleMethod(metaAccess, UnimplementedWithJNIEnvArgument.class), (AnalysisMethod) getSingleMethod(metaAccess, UnimplementedWithJavaVMArgument.class)); Stream.concat(analysisMethods, unimplementedMethods).forEach(method -> { @@ -229,14 +221,6 @@ private void fillJNIFunctionsTable(CompilationAccessImpl access) { int offset = field.getOffsetInfo().getProperty(); tables.initFunctionEntry(offset, getStubFunctionPointer(access, method)); } - if (JavaVersionUtil.JAVA_SPEC > 17) { - HostedType functionsJDK19OrLater = access.getMetaAccess().lookupJavaType(JNIFunctionsJDK19OrLater.class); - for (HostedMethod method : functionsJDK19OrLater.getDeclaredMethods(false)) { - StructFieldInfo field = findFieldFor(functionTableMetadataJDK19OrLater, method.getName()); - int offset = field.getOffsetInfo().getProperty(); - tables.initFunctionEntry(offset, getStubFunctionPointer(access, method)); - } - } for (ResolvedJavaMethod accessor : generatedMethods) { StructFieldInfo field = findFieldFor(functionTableMetadata, accessor.getName()); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/util/CPUTypeAMD64.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/util/CPUTypeAMD64.java index a6dcd66f8242..00fea87390ca 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/util/CPUTypeAMD64.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/util/CPUTypeAMD64.java @@ -40,11 +40,13 @@ import static jdk.vm.ci.amd64.AMD64.CPUFeature.CLWB; import static jdk.vm.ci.amd64.AMD64.CPUFeature.CMOV; import static jdk.vm.ci.amd64.AMD64.CPUFeature.CX8; +import static jdk.vm.ci.amd64.AMD64.CPUFeature.F16C; import static jdk.vm.ci.amd64.AMD64.CPUFeature.FLUSHOPT; import static jdk.vm.ci.amd64.AMD64.CPUFeature.FMA; import static jdk.vm.ci.amd64.AMD64.CPUFeature.FXSR; import static jdk.vm.ci.amd64.AMD64.CPUFeature.LZCNT; import static jdk.vm.ci.amd64.AMD64.CPUFeature.MMX; +import static jdk.vm.ci.amd64.AMD64.CPUFeature.PKU; import static jdk.vm.ci.amd64.AMD64.CPUFeature.POPCNT; import static jdk.vm.ci.amd64.AMD64.CPUFeature.SSE; import static jdk.vm.ci.amd64.AMD64.CPUFeature.SSE2; @@ -62,7 +64,6 @@ import org.graalvm.nativeimage.Platforms; import com.oracle.graal.pointsto.util.GraalAccess; -import com.oracle.svm.core.jdk.JDK17OrEarlier; import com.oracle.svm.core.option.SubstrateOptionsParser; import com.oracle.svm.core.util.UserError; import com.oracle.svm.hosted.NativeImageOptions; @@ -90,22 +91,13 @@ public enum CPUTypeAMD64 implements CPUType { X86_64("x86-64", CMOV, CX8, FXSR, MMX, SSE, SSE2), X86_64_V1("x86-64-v1", X86_64), X86_64_V2("x86-64-v2", X86_64_V1, POPCNT, SSE3, SSE4_1, SSE4_2, SSSE3), - /** - * F16C are not in {@link JDK17OrEarlier}. Leaving link here for cleanup purposes. - */ - X86_64_V3("x86-64-v3", X86_64_V2, AVX, AVX2, BMI1, BMI2, /* F16C, */ FMA, LZCNT), + X86_64_V3("x86-64-v3", X86_64_V2, AVX, AVX2, BMI1, BMI2, F16C, FMA, LZCNT), X86_64_V4("x86-64-v4", X86_64_V3, AVX512F, AVX512BW, AVX512CD, AVX512DQ, AVX512VL), // Intel selection - /** - * F16C are not in {@link JDK17OrEarlier}. Leaving link here for cleanup purposes. - */ - HASWELL("haswell", X86_64, AES, SSE3, SSSE3, SSE4_1, SSE4_2, POPCNT, CLMUL, AVX, /* F16C, */ AVX2, BMI1, BMI2, LZCNT, FMA), + HASWELL("haswell", X86_64, AES, SSE3, SSSE3, SSE4_1, SSE4_2, POPCNT, CLMUL, AVX, F16C, AVX2, BMI1, BMI2, LZCNT, FMA), SKYLAKE("skylake", HASWELL, ADX, AMD_3DNOW_PREFETCH, FLUSHOPT), - /** - * PKU are not in {@link JDK17OrEarlier}. Leaving link here for cleanup purposes. - */ - SKYLAKE_AVX512("skylake-avx512", SKYLAKE, /* PKU, */ AVX512F, AVX512CD, AVX512VL, AVX512BW, AVX512DQ, CLWB), + SKYLAKE_AVX512("skylake-avx512", SKYLAKE, PKU, AVX512F, AVX512CD, AVX512VL, AVX512BW, AVX512DQ, CLWB), // Special symbols COMPATIBILITY(NativeImageOptions.MICRO_ARCHITECTURE_COMPATIBILITY, X86_64), diff --git a/substratevm/src/com.oracle.svm.truffle.tck/src/com/oracle/svm/truffle/tck/PermissionsFeature.java b/substratevm/src/com.oracle.svm.truffle.tck/src/com/oracle/svm/truffle/tck/PermissionsFeature.java index feadbaa5e7d8..93e412e233a3 100644 --- a/substratevm/src/com.oracle.svm.truffle.tck/src/com/oracle/svm/truffle/tck/PermissionsFeature.java +++ b/substratevm/src/com.oracle.svm.truffle.tck/src/com/oracle/svm/truffle/tck/PermissionsFeature.java @@ -75,7 +75,6 @@ import com.oracle.svm.core.option.HostedOptionKey; import com.oracle.svm.core.option.LocatableMultiOptionValue; import com.oracle.svm.core.util.UserError; -import com.oracle.svm.core.util.VMError; import com.oracle.svm.hosted.FeatureImpl; import com.oracle.svm.hosted.ImageClassLoader; import com.oracle.svm.hosted.SVMHost; @@ -166,7 +165,6 @@ public boolean getAsBoolean() { /** * Classes for reflective accesses which are opaque for permission analysis. */ - private AnalysisType reflectionFieldAccessorFactory; private InlinedUnsafeMethodNode inlinedUnsafeCall; @@ -218,8 +216,6 @@ public void afterAnalysis(AfterAnalysisAccess access) { Options.TruffleTCKPermissionsExcludeFiles, new ResourceAsOptionDecorator(getClass().getPackage().getName().replace('.', '/') + "/resources/jre.json"), CONFIG); - reflectionFieldAccessorFactory = bb.getMetaAccess().lookupJavaType(loadClassOrFail("jdk.internal.reflect.UnsafeFieldAccessorFactory")); - VMError.guarantee(reflectionFieldAccessorFactory != null, "Cannot load one or several reflection types"); whiteList = parser.getLoadedWhiteList(); Set deniedMethods = new HashSet<>(); deniedMethods.addAll(findMethods(bb, SecurityManager.class, (m) -> m.getName().startsWith("check"))); @@ -459,7 +455,7 @@ private int collectViolations( } else { nextCaller: for (BaseMethodNode caller : callers) { for (CallGraphFilter filter : contextFilters) { - if (isReflectionFieldAccessorFactory(caller) || filter.test(mNode, caller, visited)) { + if (filter.test(mNode, caller, visited)) { continue nextCaller; } } @@ -473,14 +469,6 @@ private int collectViolations( return useNoReports; } - /** - * Tests if the given {@link BaseMethodNode} is part of the factory of field accessors. - */ - private boolean isReflectionFieldAccessorFactory(BaseMethodNode methodNode) { - AnalysisMethod method = methodNode.getMethod(); - return method != null && reflectionFieldAccessorFactory.isAssignableFrom(method.getDeclaringClass()); - } - /** * Tests if method represented by given {@link BaseMethodNode} is loaded by a system * {@link ClassLoader}. @@ -648,7 +636,7 @@ public boolean test(BaseMethodNode methodNode, BaseMethodNode callerNode, Linked /** * Filters out {@code AccessController#doPrivileged} done by JRE. */ - private final class SafePrivilegedRecognizer implements CallGraphFilter { + private static final class SafePrivilegedRecognizer implements CallGraphFilter { private final SVMHost hostVM; private final Set doPrivileged; diff --git a/vm/ci/ci_common/common.jsonnet b/vm/ci/ci_common/common.jsonnet index 7b97196500c7..7e58cbea6c61 100644 --- a/vm/ci/ci_common/common.jsonnet +++ b/vm/ci/ci_common/common.jsonnet @@ -457,10 +457,12 @@ local devkits = graal_common.devkits; if (edition == 'ce') then { downloads+: { + # We still need to run on JDK 17 until doclet work on JDK 21 (GR-48400) JAVA_HOME: graal_common.jdks_data['labsjdk-' + edition + '-17'], EXTRA_JAVA_HOMES: graal_common.jdks_data['labsjdk-' + edition + '-21'], }, environment+: { + JDK_VERSION_CHECK: 'ignore', JVMCI_VERSION_CHECK: 'ignore', }, } diff --git a/vm/ci/ci_common/libgraal.jsonnet b/vm/ci/ci_common/libgraal.jsonnet index afe564d06070..4d780c1c53fd 100644 --- a/vm/ci/ci_common/libgraal.jsonnet +++ b/vm/ci/ci_common/libgraal.jsonnet @@ -77,7 +77,7 @@ local utils = import '../../../ci/ci_common/common-utils.libsonnet'; "gate-vm-libgraal_compiler_zgc-labsjdk-21-linux-amd64": {}, "gate-vm-libgraal_compiler_quickbuild-labsjdk-21-linux-amd64": {}, "gate-vm-libgraal_truffle_quickbuild-labsjdk-21-linux-amd64": t("1:10:00"), - "gate-vm-libgraal_compiler-oraclejdk-22-linux-amd64": {}, + "gate-vm-libgraal_compiler-labsjdk-latest-linux-amd64": {}, }, # See definition of `dailies` local variable in ../../compiler/ci_common/gate.jsonnet @@ -112,14 +112,15 @@ local utils = import '../../../ci/ci_common/common-utils.libsonnet'; vm["custom_vm_" + os(os_arch)] + g.make_build(jdk, os_arch, task, extra_tasks=self, suite="vm", include_common_os_arch=false, - jdk_name = if jdk == "22" then "oraclejdk" else "labsjdk", + jdk_name = "labsjdk", gates_manifest=gates, dailies_manifest=dailies, weeklies_manifest=weeklies, monthlies_manifest=monthlies).build + vm["vm_java_" + jdk] for jdk in [ - "21" + "21", + "Latest" ] for os_arch in all_os_arches for task in [ @@ -130,28 +131,6 @@ local utils = import '../../../ci/ci_common/common-utils.libsonnet'; ] ], - # Builds run on OracleJDK22 - local oraclejdk22_builds = [ - c["gate_vm_" + underscore(os_arch)] + - svm_common(os_arch, jdk) + - vm["custom_vm_" + os(os_arch)] + - g.make_build(jdk, os_arch, task, extra_tasks=self, suite="vm", - include_common_os_arch=false, - jdk_name="oraclejdk", - gates_manifest=gates, - dailies_manifest=dailies, - weeklies_manifest=weeklies, - monthlies_manifest=monthlies).build + - vm["vm_java_" + jdk] - for jdk in [ - "22" - ] - for os_arch in all_os_arches - for task in [ - "libgraal_compiler", - ] - ], - local adjust_windows_version(gate) = ( # replace 2016 with 2019 gate + { capabilities: [ if x == "windows_server_2016" then "windows_server_2019" else x for x in gate.capabilities ] } @@ -207,7 +186,6 @@ local utils = import '../../../ci/ci_common/common-utils.libsonnet'; # Complete set of builds defined in this file local all_builds = all_platforms_builds + - oraclejdk22_builds + all_platforms_zgc_builds + coverage_jdk21_builds, diff --git a/vm/ci/ci_includes/vm.jsonnet b/vm/ci/ci_includes/vm.jsonnet index 472d0566c549..a4038b07bf48 100644 --- a/vm/ci/ci_includes/vm.jsonnet +++ b/vm/ci/ci_includes/vm.jsonnet @@ -8,7 +8,9 @@ local graal_common = import '../../../ci/ci_common/common.jsonnet'; { vm_java_21:: graal_common.labsjdk21 + vm_common.vm_env_mixin('21'), - vm_java_22:: graal_common.oraclejdk22 + vm_common.vm_env_mixin('22'), + vm_java_Latest:: + local jdk = graal_common.labsjdkLatest; + jdk + vm_common.vm_env_mixin(std.toString(jdk.jdk_version)), vm_java_21_llvm:: self.vm_java_21 + graal_common['labsjdk-ce-21-llvm'], diff --git a/vm/mx.vm/suite.py b/vm/mx.vm/suite.py index 6458447ece27..9b5e994eacf8 100644 --- a/vm/mx.vm/suite.py +++ b/vm/mx.vm/suite.py @@ -49,7 +49,7 @@ }, { "name": "truffleruby", - "version": "1459478a3d067d2c6fc81226d6cf4df6ae9e21d0", + "version": "260d07b79a5c825e2ca39d0241c0cea64641be5d", "dynamic": True, "urls": [ {"url": "https://github.com/oracle/truffleruby.git", "kind": "git"},