From mhaessig at openjdk.org Tue Jul 1 09:34:50 2025 From: mhaessig at openjdk.org (Manuel =?UTF-8?B?SMOkc3NpZw==?=) Date: Tue, 1 Jul 2025 09:34:50 GMT Subject: RFR: 8361086: JVMCIGlobals::check_jvmci_flags_are_consistent has incorrect format string In-Reply-To: References: Message-ID: <5kdHAQ86j5eDq6OgIb6Bn7HFWxgc24W8ywubudeGa-Q=.5d8b392a-de5c-49d7-a3f2-3ade541c6643@github.com> On Mon, 30 Jun 2025 16:14:08 GMT, Kim Barrett wrote: > Please review this trivial fix of a format string. The value being printed is > TieredStopAtLevel, which is of type intx, so "%zd" should be used instead of "%d". > > Testing: mach5 tier1 Looks good and trivial to me. ------------- Marked as reviewed by mhaessig (Committer). PR Review: https://git.openjdk.org/jdk/pull/26051#pullrequestreview-2974517185 From yzheng at openjdk.org Tue Jul 1 09:38:48 2025 From: yzheng at openjdk.org (Yudi Zheng) Date: Tue, 1 Jul 2025 09:38:48 GMT Subject: RFR: 8361086: JVMCIGlobals::check_jvmci_flags_are_consistent has incorrect format string In-Reply-To: References: Message-ID: On Mon, 30 Jun 2025 16:14:08 GMT, Kim Barrett wrote: > Please review this trivial fix of a format string. The value being printed is > TieredStopAtLevel, which is of type intx, so "%zd" should be used instead of "%d". > > Testing: mach5 tier1 LGTM ------------- Marked as reviewed by yzheng (Committer). PR Review: https://git.openjdk.org/jdk/pull/26051#pullrequestreview-2974540441 From duke at openjdk.org Tue Jul 1 15:09:12 2025 From: duke at openjdk.org (Anton Artemov) Date: Tue, 1 Jul 2025 15:09:12 GMT Subject: RFR: 8320353: Reenable stringop-overflow warnings Message-ID: Hi, please consider the following changes: this PR addresses the issue of stringop-overflow warnings produced by GCC. The compiler does think that the thread pointer returned by `JavaThread::current()` can be null, though it cant. The thread pointer ends up being an argument in `__atomic_load`, and the compiler reports the warning related to argument of that method. The patch adds a hint to the compiler by means of `__builtin_unreachable()` intrinsic, which tells the compiler that certain piece of code will never be reached (case of thread pointer being null). This solves the issue. Tested in tiers 1-3 and GHA. ------------- Commit messages: - 8320353: Fixed comment - 8320353: Fixed whitespace error - 8320353: Fiixed build problem - 8320353: Added debug only case - 8320353: More work - 8320353: More work - 8320353: Reenabled stringop-overflow warning for linux zero/fastdebug Changes: https://git.openjdk.org/jdk/pull/26067/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=26067&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8320353 Stats: 25 lines in 3 files changed: 20 ins; 4 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/26067.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26067/head:pull/26067 PR: https://git.openjdk.org/jdk/pull/26067 From mchevalier at openjdk.org Tue Jul 1 16:14:00 2025 From: mchevalier at openjdk.org (Marc Chevalier) Date: Tue, 1 Jul 2025 16:14:00 GMT Subject: RFR: 8359344: C2: Malformed control flow after intrinsic bailout [v2] In-Reply-To: References: Message-ID: <1cFRkcs5JmgnbWEIaEoT8I9RiUtNxgKieAdkSB2Fgmc=.1d97b5c4-b6ef-43c6-b721-1e52eee19d3a@github.com> > When intrinsic bailout, we assume that the control in the `LibraryCallKit` did not change: > > https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L137 > > This is enforced by restoring the old state, like in > > https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L1722-L1732 > > That is good, but not sufficient. First, the most obvious, one could have already built some structure without moving the control. For instance, we can obtain something such as: > > ![1 after-intrinsic-bailout-during-late-inlining](https://github.com/user-attachments/assets/2fd255cc-0bfc-4841-8dd1-f64d502e0ee1) > > > Here, during late inlining, the call `323` is candidate to be inline, but that bails out. Yet, a call to `make_unsafe_address` was made, which built nodes `354 If` and everything under. This is needed as tests are made on the resulting nodes (especially `366 AddP`) to know whether we should bail out or not. At the end, we get 2 control successor to `346 IfFalse`: the call that is not removed and the leftover of the intrinsic that will be cleanup much later, but not by RemoveUseless. > > Another situation is somewhat worse, when happening during parsing. It can lead to such cases: > > ![2 after-intrinsic-bailout-during-parsing](https://github.com/user-attachments/assets/4524c615-6521-4f0d-8f61-c426f9179035) > > The nodes `31 OpaqueNotNull`, `31 If`, `36 IfTrue`, `33 IfFalse`, `35 Halt`, `44 If`, `45 IfTrue`, `46 IfFalse` are leftover from a bailing out intrinsic. The replacement call `49 CallStaticJava` should come just under `5 Parm`, but the control was updated and the call is actually built under `36 If`. Then, why does the previous assert doesn't complain? > > This is because there is more than one control, or one map. In intrinsics that need to restore their state, the initial `SafePoint` map is cloned, the clone is kept aside, and if needed (bailing out), we set the current map to this saved clone. But there is another map from which the one of the `LibraryCallKit` comes, and that survives longer, it's the one that is contained in the `JVMState`: > > https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L101-L102 > > And here there is the challenge: > - the `JVMState jvms` contains a `SafePoint` map, this map must have `jvms` as `jvms` (pointer comparison) > - we can't really change the pointer, just the content > -... Marc Chevalier has updated the pull request incrementally with one additional commit since the last revision: Remove useless loop ------------- Changes: - all: https://git.openjdk.org/jdk/pull/25936/files - new: https://git.openjdk.org/jdk/pull/25936/files/54b07e94..d51853ca Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=25936&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=25936&range=00-01 Stats: 24 lines in 1 file changed: 0 ins; 2 del; 22 mod Patch: https://git.openjdk.org/jdk/pull/25936.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/25936/head:pull/25936 PR: https://git.openjdk.org/jdk/pull/25936 From ihse at openjdk.org Tue Jul 1 19:04:37 2025 From: ihse at openjdk.org (Magnus Ihse Bursie) Date: Tue, 1 Jul 2025 19:04:37 GMT Subject: RFR: 8320353: Reenable stringop-overflow warnings In-Reply-To: References: Message-ID: On Tue, 1 Jul 2025 12:25:04 GMT, Anton Artemov wrote: > Hi, please consider the following changes: > > this PR addresses the issue of stringop-overflow warnings produced by GCC. The compiler does think that the thread pointer returned by `JavaThread::current()` can be null, though it cant. The thread pointer ends up being an argument in `__atomic_load`, and the compiler reports the warning related to argument of that method. > > The patch adds a hint to the compiler by means of `__builtin_unreachable()` intrinsic, which tells the compiler that certain piece of code will never be reached (case of thread pointer being null). This solves the issue. > > Tested in tiers 1-3 and GHA. Build changes look good. Someone else will have to review the hotspot changes. ------------- Marked as reviewed by ihse (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/26067#pullrequestreview-2976656855 From kbarrett at openjdk.org Wed Jul 2 00:30:44 2025 From: kbarrett at openjdk.org (Kim Barrett) Date: Wed, 2 Jul 2025 00:30:44 GMT Subject: RFR: 8361086: JVMCIGlobals::check_jvmci_flags_are_consistent has incorrect format string In-Reply-To: References: Message-ID: On Mon, 30 Jun 2025 23:16:20 GMT, Vladimir Kozlov wrote: >> Please review this trivial fix of a format string. The value being printed is >> TieredStopAtLevel, which is of type intx, so "%zd" should be used instead of "%d". >> >> Testing: mach5 tier1 > > Thank you for checking other solutions. > > Current fix is good. Thanks for reviews @vnkozlov , @mhaessig , and @mur47x111 ------------- PR Comment: https://git.openjdk.org/jdk/pull/26051#issuecomment-3025913681 From kbarrett at openjdk.org Wed Jul 2 00:30:44 2025 From: kbarrett at openjdk.org (Kim Barrett) Date: Wed, 2 Jul 2025 00:30:44 GMT Subject: Integrated: 8361086: JVMCIGlobals::check_jvmci_flags_are_consistent has incorrect format string In-Reply-To: References: Message-ID: On Mon, 30 Jun 2025 16:14:08 GMT, Kim Barrett wrote: > Please review this trivial fix of a format string. The value being printed is > TieredStopAtLevel, which is of type intx, so "%zd" should be used instead of "%d". > > Testing: mach5 tier1 This pull request has now been integrated. Changeset: c6448dc3 Author: Kim Barrett URL: https://git.openjdk.org/jdk/commit/c6448dc3afb1da9d93bb94804aa1971a650b91b7 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod 8361086: JVMCIGlobals::check_jvmci_flags_are_consistent has incorrect format string Reviewed-by: kvn, mhaessig, yzheng ------------- PR: https://git.openjdk.org/jdk/pull/26051 From dholmes at openjdk.org Wed Jul 2 06:57:40 2025 From: dholmes at openjdk.org (David Holmes) Date: Wed, 2 Jul 2025 06:57:40 GMT Subject: RFR: 8320353: Reenable stringop-overflow warnings In-Reply-To: References: Message-ID: On Tue, 1 Jul 2025 12:25:04 GMT, Anton Artemov wrote: > Hi, please consider the following changes: > > this PR addresses the issue of stringop-overflow warnings produced by GCC. The compiler does think that the thread pointer returned by `JavaThread::current()` can be null, though it cant. The thread pointer ends up being an argument in `__atomic_load`, and the compiler reports the warning related to argument of that method. > > The patch adds a hint to the compiler by means of `__builtin_unreachable()` intrinsic, which tells the compiler that certain piece of code will never be reached (case of thread pointer being null). This solves the issue. > > Tested in tiers 1-3 and GHA. Sorry but I really dislike seeing this compiler-specific pollution in shared code. It is even worse that you have to put it in two places (what is so special about the jvmci code to require this?) just because gcc is "too dumb" keep track of things. Also IIUC from JBS the problem was only seen building Zero, so maybe we can do something there that is Zero specific? Sorry. ------------- PR Review: https://git.openjdk.org/jdk/pull/26067#pullrequestreview-2977963403 From yzheng at openjdk.org Wed Jul 2 07:22:29 2025 From: yzheng at openjdk.org (Yudi Zheng) Date: Wed, 2 Jul 2025 07:22:29 GMT Subject: RFR: 8357424: [JVMCI] Avoid incrementing decompilation count for hosted compiled nmethod [v9] In-Reply-To: References: Message-ID: <8HUFsVgvqriVdKkkm-tkU-_XisP9uFPzSlhBFiGd9i8=.ca3a9645-e01b-4072-bdc8-6c3fb2f7bb81@github.com> > Hosted Truffle compilations are installed on the OptimizedCallTarget#profiledPERoot method. Any deoptimization contributes to its decompile count, which can easily exceed the PerMethodRecompilationCutoff threshold, permanently preventing highest tier compilation on this method. This PR exempts hosted compilations from this cutoff by ensuring their decompile count is not incremented for hosted compiled nmethods. Yudi Zheng has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains 11 additional commits since the last revision: - address comments - Merge remote-tracking branch 'upstream/master' into JDK-8357424 - Merge tag 'jdk-26+3' into JDK-8357424 Added tag jdk-26+3 for changeset 08b1fa4c - Merge tag 'jdk-26+2' into JDK-8357424 Added tag jdk-26+2 for changeset d7aa3498 - fix compilation error - address comments - Merge remote-tracking branch 'upstream/master' into JDK-8357424 - address comments - address comments - update copyright - ... and 1 more: https://git.openjdk.org/jdk/compare/dcb21872...022546a0 ------------- Changes: - all: https://git.openjdk.org/jdk/pull/25356/files - new: https://git.openjdk.org/jdk/pull/25356/files/fb32a8c7..022546a0 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=25356&range=08 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=25356&range=07-08 Stats: 13776 lines in 672 files changed: 6912 ins; 3534 del; 3330 mod Patch: https://git.openjdk.org/jdk/pull/25356.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/25356/head:pull/25356 PR: https://git.openjdk.org/jdk/pull/25356 From yzheng at openjdk.org Wed Jul 2 07:24:42 2025 From: yzheng at openjdk.org (Yudi Zheng) Date: Wed, 2 Jul 2025 07:24:42 GMT Subject: RFR: 8357424: [JVMCI] Avoid incrementing decompilation count for hosted compiled nmethod [v7] In-Reply-To: References: Message-ID: On Fri, 13 Jun 2025 20:59:05 GMT, Doug Simon wrote: >> Yudi Zheng has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains eight additional commits since the last revision: >> >> - Merge tag 'jdk-26+2' into JDK-8357424 >> >> Added tag jdk-26+2 for changeset d7aa3498 >> - fix compilation error >> - address comments >> - Merge remote-tracking branch 'upstream/master' into JDK-8357424 >> - address comments >> - address comments >> - update copyright >> - [JVMCI] Avoid incrementing decompilation count for hosted compiled nmethod > > src/hotspot/share/code/nmethod.cpp line 1951: > >> 1949: // Could be gated by ProfileTraps, but do not bother... >> 1950: #if INCLUDE_JVMCI >> 1951: if (is_jvmci_hosted()) { > > Someone (like me!) is going to see this code a while from now and try remember why the decompilation count is not being decremented for JVMCI hosted nmethods. I think it's worth adding a comment. See https://github.com/openjdk/jdk/pull/25356/commits/022546a09ed9ca06898459df2f7b6ddc2877f69b ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25356#discussion_r2179317632 From yzheng at openjdk.org Wed Jul 2 07:24:43 2025 From: yzheng at openjdk.org (Yudi Zheng) Date: Wed, 2 Jul 2025 07:24:43 GMT Subject: RFR: 8357424: [JVMCI] Avoid incrementing decompilation count for hosted compiled nmethod [v7] In-Reply-To: References: Message-ID: On Tue, 17 Jun 2025 17:06:14 GMT, Cesar Soares Lucas wrote: >> Yudi Zheng has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains eight additional commits since the last revision: >> >> - Merge tag 'jdk-26+2' into JDK-8357424 >> >> Added tag jdk-26+2 for changeset d7aa3498 >> - fix compilation error >> - address comments >> - Merge remote-tracking branch 'upstream/master' into JDK-8357424 >> - address comments >> - address comments >> - update copyright >> - [JVMCI] Avoid incrementing decompilation count for hosted compiled nmethod > > src/hotspot/share/runtime/deoptimization.cpp line 2367: > >> 2365: >> 2366: #if INCLUDE_JVMCI >> 2367: if (nm->is_jvmci_hosted()) { > > A comment here will probably be helpful as well. See https://github.com/openjdk/jdk/pull/25356/commits/022546a09ed9ca06898459df2f7b6ddc2877f69b ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25356#discussion_r2179317776 From dnsimon at openjdk.org Wed Jul 2 08:58:41 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Wed, 2 Jul 2025 08:58:41 GMT Subject: RFR: 8320353: Reenable stringop-overflow warnings In-Reply-To: References: Message-ID: On Tue, 1 Jul 2025 12:25:04 GMT, Anton Artemov wrote: > Hi, please consider the following changes: > > this PR addresses the issue of stringop-overflow warnings produced by GCC. The compiler does think that the thread pointer returned by `JavaThread::current()` can be null, though it cant. The thread pointer ends up being an argument in `__atomic_load`, and the compiler reports the warning related to argument of that method. > > The patch adds a hint to the compiler by means of `__builtin_unreachable()` intrinsic, which tells the compiler that certain piece of code will never be reached (case of thread pointer being null). This solves the issue. > > Tested in tiers 1-3 and GHA. src/hotspot/share/jvmci/jvmciCodeInstaller.cpp line 929: > 927: if (thread == nullptr) { > 928: // This is to prevent --stringop-overflow warning from GCC on linux/fastdebug. > 929: // GCC does believe that JavaThread::current() can return nullptr, `does believe` -> `believes` ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26067#discussion_r2179510064 From jwaters at openjdk.org Wed Jul 2 09:07:44 2025 From: jwaters at openjdk.org (Julian Waters) Date: Wed, 2 Jul 2025 09:07:44 GMT Subject: RFR: 8320353: Reenable stringop-overflow warnings In-Reply-To: References: Message-ID: On Tue, 1 Jul 2025 12:25:04 GMT, Anton Artemov wrote: > Hi, please consider the following changes: > > this PR addresses the issue of stringop-overflow warnings produced by GCC. The compiler does think that the thread pointer returned by `JavaThread::current()` can be null, though it cant. The thread pointer ends up being an argument in `__atomic_load`, and the compiler reports the warning related to argument of that method. > > The patch adds a hint to the compiler by means of `__builtin_unreachable()` intrinsic, which tells the compiler that certain piece of code will never be reached (case of thread pointer being null). This solves the issue. > > Tested in tiers 1-3 and GHA. src/hotspot/share/runtime/javaThread.hpp line 1070: > 1068: // Returns the running thread as a JavaThread > 1069: static JavaThread* current() { > 1070: auto result = JavaThread::cast(Thread::current()); Why auto when the type is known? ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26067#discussion_r2179528150 From dnsimon at openjdk.org Wed Jul 2 09:10:45 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Wed, 2 Jul 2025 09:10:45 GMT Subject: RFR: 8357424: [JVMCI] Avoid incrementing decompilation count for hosted compiled nmethod [v9] In-Reply-To: <8HUFsVgvqriVdKkkm-tkU-_XisP9uFPzSlhBFiGd9i8=.ca3a9645-e01b-4072-bdc8-6c3fb2f7bb81@github.com> References: <8HUFsVgvqriVdKkkm-tkU-_XisP9uFPzSlhBFiGd9i8=.ca3a9645-e01b-4072-bdc8-6c3fb2f7bb81@github.com> Message-ID: On Wed, 2 Jul 2025 07:22:29 GMT, Yudi Zheng wrote: >> Hosted Truffle compilations are installed on the OptimizedCallTarget#profiledPERoot method. Any deoptimization contributes to its decompile count, which can easily exceed the PerMethodRecompilationCutoff threshold, permanently preventing highest tier compilation on this method. This PR exempts hosted compilations from this cutoff by ensuring their decompile count is not incremented for hosted compiled nmethods. > > Yudi Zheng has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains 11 additional commits since the last revision: > > - address comments > - Merge remote-tracking branch 'upstream/master' into JDK-8357424 > - Merge tag 'jdk-26+3' into JDK-8357424 > > Added tag jdk-26+3 for changeset 08b1fa4c > - Merge tag 'jdk-26+2' into JDK-8357424 > > Added tag jdk-26+2 for changeset d7aa3498 > - fix compilation error > - address comments > - Merge remote-tracking branch 'upstream/master' into JDK-8357424 > - address comments > - address comments > - update copyright > - ... and 1 more: https://git.openjdk.org/jdk/compare/f01309be...022546a0 src/hotspot/share/code/nmethod.cpp line 1939: > 1937: // Could be gated by ProfileTraps, but do not bother... > 1938: #if INCLUDE_JVMCI > 1939: // Deoptimizations from non-default (non-CompileBroker) compilations should not Suggestion: // Deoptimization count is used by the CompileBroker to reason about compilations // it requests so do not pollute the count for deoptimizations in non-default (i.e. // non-CompilerBroker) compilations. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25356#discussion_r2179536365 From jwaters at openjdk.org Wed Jul 2 09:12:40 2025 From: jwaters at openjdk.org (Julian Waters) Date: Wed, 2 Jul 2025 09:12:40 GMT Subject: RFR: 8320353: Reenable stringop-overflow warnings In-Reply-To: References: Message-ID: <0_bgDyCHArbkXPSDNQdNWLbrhY2AOJT_BjFTMD38tuY=.9ca01026-bf7e-4d59-8326-d5c4537acc17@github.com> On Tue, 1 Jul 2025 12:25:04 GMT, Anton Artemov wrote: > Hi, please consider the following changes: > > this PR addresses the issue of stringop-overflow warnings produced by GCC. The compiler does think that the thread pointer returned by `JavaThread::current()` can be null, though it cant. The thread pointer ends up being an argument in `__atomic_load`, and the compiler reports the warning related to argument of that method. > > The patch adds a hint to the compiler by means of `__builtin_unreachable()` intrinsic, which tells the compiler that certain piece of code will never be reached (case of thread pointer being null). This solves the issue. > > Tested in tiers 1-3 and GHA. A less messy solution could be to use PRAGMA_STRINGOP_OVERFLOW_IGNORED instead. The conditionals for the PRAGMA IGNORED macros are already all handled for you, so there's no need to put conditionalizations at the use sites. As an example, simply do the following: PRAGMA_DIAG_PUSH PRAGMA_STRINGOP_OVERFLOW_IGNORED // Problem code here PRAGMA_DIAG_POP The first 2 macros are placed directly in front of the problem code, and the last goes behind. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26067#issuecomment-3027075027 From yzheng at openjdk.org Wed Jul 2 11:27:25 2025 From: yzheng at openjdk.org (Yudi Zheng) Date: Wed, 2 Jul 2025 11:27:25 GMT Subject: RFR: 8357424: [JVMCI] Avoid incrementing decompilation count for hosted compiled nmethod [v10] In-Reply-To: References: Message-ID: > Hosted Truffle compilations are installed on the OptimizedCallTarget#profiledPERoot method. Any deoptimization contributes to its decompile count, which can easily exceed the PerMethodRecompilationCutoff threshold, permanently preventing highest tier compilation on this method. This PR exempts hosted compilations from this cutoff by ensuring their decompile count is not incremented for hosted compiled nmethods. Yudi Zheng has updated the pull request incrementally with one additional commit since the last revision: address comments ------------- Changes: - all: https://git.openjdk.org/jdk/pull/25356/files - new: https://git.openjdk.org/jdk/pull/25356/files/022546a0..d6221921 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=25356&range=09 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=25356&range=08-09 Stats: 6 lines in 2 files changed: 0 ins; 0 del; 6 mod Patch: https://git.openjdk.org/jdk/pull/25356.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/25356/head:pull/25356 PR: https://git.openjdk.org/jdk/pull/25356 From dnsimon at openjdk.org Wed Jul 2 11:47:41 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Wed, 2 Jul 2025 11:47:41 GMT Subject: RFR: 8357424: [JVMCI] Avoid incrementing decompilation count for hosted compiled nmethod [v10] In-Reply-To: References: Message-ID: On Wed, 2 Jul 2025 11:27:25 GMT, Yudi Zheng wrote: >> Hosted Truffle compilations are installed on the OptimizedCallTarget#profiledPERoot method. Any deoptimization contributes to its decompile count, which can easily exceed the PerMethodRecompilationCutoff threshold, permanently preventing highest tier compilation on this method. This PR exempts hosted compilations from this cutoff by ensuring their decompile count is not incremented for hosted compiled nmethods. > > Yudi Zheng has updated the pull request incrementally with one additional commit since the last revision: > > address comments Marked as reviewed by dnsimon (Reviewer). ------------- PR Review: https://git.openjdk.org/jdk/pull/25356#pullrequestreview-2978826504 From kbarrett at openjdk.org Wed Jul 2 14:01:41 2025 From: kbarrett at openjdk.org (Kim Barrett) Date: Wed, 2 Jul 2025 14:01:41 GMT Subject: RFR: 8320353: Reenable stringop-overflow warnings In-Reply-To: References: Message-ID: On Tue, 1 Jul 2025 12:25:04 GMT, Anton Artemov wrote: > Hi, please consider the following changes: > > this PR addresses the issue of stringop-overflow warnings produced by GCC. The compiler does think that the thread pointer returned by `JavaThread::current()` can be null, though it cant. The thread pointer ends up being an argument in `__atomic_load`, and the compiler reports the warning related to argument of that method. > > The patch adds a hint to the compiler by means of `__builtin_unreachable()` intrinsic, which tells the compiler that certain piece of code will never be reached (case of thread pointer being null). This solves the issue. > > Tested in tiers 1-3 and GHA. Changes requested by kbarrett (Reviewer). src/hotspot/share/jvmci/jvmciCodeInstaller.cpp line 926: > 924: JVMCI::CodeInstallResult CodeInstaller::initialize_buffer(JVMCIObject compiled_code, CodeBuffer& buffer, HotSpotCompiledCodeStream* stream, u1 code_flags, JVMCI_TRAPS) { > 925: JavaThread* thread = stream->thread(); > 926: #if defined(__GNUC__) && !defined(__clang__) && !defined(PRODUCT) Note that `!PRODUCT` does not imply `ASSERT`. There is also the "optimized" build type, which defines neither `PRODUCT` nor `ASSERT`. I have no idea whether the false-positive gcc warnings occur in that build configuration. If so, then my suggestion of using an assertion to give the compiler the clue it needs won't work. But I'm guessing that isn't a problem, in which case the macro check should be `defined(ASSERT)`. src/hotspot/share/jvmci/jvmciCodeInstaller.cpp line 936: > 934: __builtin_unreachable(); > 935: } > 936: #endif I think this could be replaced with asserting non-null. A failed assert calls a noreturn reporting function. src/hotspot/share/runtime/javaThread.hpp line 1079: > 1077: } > 1078: #endif > 1079: return result; Similarly here, I think this could be replaced with asserting non-null. ------------- PR Review: https://git.openjdk.org/jdk/pull/26067#pullrequestreview-2979254552 PR Review Comment: https://git.openjdk.org/jdk/pull/26067#discussion_r2180140733 PR Review Comment: https://git.openjdk.org/jdk/pull/26067#discussion_r2180123147 PR Review Comment: https://git.openjdk.org/jdk/pull/26067#discussion_r2180120768 From iklam at openjdk.org Wed Jul 2 17:39:18 2025 From: iklam at openjdk.org (Ioi Lam) Date: Wed, 2 Jul 2025 17:39:18 GMT Subject: RFR: 8361292: Rename ModuleEntry::module() to module_oop() Message-ID: A module has both a Java and a C++ representation - C++: `ModuleEntry` - Java: `java.lang.Module` In C++, we have the following two methods - `ModuleEntry* InstanceKlass::module()` - `oop ModuleEntry::module()` This can lead to confusing code like this: InstanceKlass* ik = ...; oop module = ik->module()->module() Proposal: - Leave `InstanceKlass::module()` as is -- there's another function with the same style: `PackageEntry* InstanceKlass::package()` - Rename `ModuleEntry::module()` to `ModuleEntry::module_oop()`, so the above example can be more readable: InstanceKlass* ik = ...; oop module = ik->module()->module_oop() ------------- Commit messages: - 8361292: Rename ModuleEntry::module() to module_oop() Changes: https://git.openjdk.org/jdk/pull/26102/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=26102&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8361292 Stats: 35 lines in 12 files changed: 0 ins; 0 del; 35 mod Patch: https://git.openjdk.org/jdk/pull/26102.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26102/head:pull/26102 PR: https://git.openjdk.org/jdk/pull/26102 From never at openjdk.org Wed Jul 2 17:40:44 2025 From: never at openjdk.org (Tom Rodriguez) Date: Wed, 2 Jul 2025 17:40:44 GMT Subject: RFR: 8357424: [JVMCI] Avoid incrementing decompilation count for hosted compiled nmethod [v10] In-Reply-To: References: Message-ID: On Wed, 2 Jul 2025 11:27:25 GMT, Yudi Zheng wrote: >> Hosted Truffle compilations are installed on the OptimizedCallTarget#profiledPERoot method. Any deoptimization contributes to its decompile count, which can easily exceed the PerMethodRecompilationCutoff threshold, permanently preventing highest tier compilation on this method. This PR exempts hosted compilations from this cutoff by ensuring their decompile count is not incremented for hosted compiled nmethods. > > Yudi Zheng has updated the pull request incrementally with one additional commit since the last revision: > > address comments Looks great. ------------- Marked as reviewed by never (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/25356#pullrequestreview-2980076551 From coleenp at openjdk.org Wed Jul 2 17:54:40 2025 From: coleenp at openjdk.org (Coleen Phillimore) Date: Wed, 2 Jul 2025 17:54:40 GMT Subject: RFR: 8361292: Rename ModuleEntry::module() to module_oop() In-Reply-To: References: Message-ID: On Wed, 2 Jul 2025 17:33:40 GMT, Ioi Lam wrote: > A module has both a Java and a C++ representation > > - C++: `ModuleEntry` > - Java: `java.lang.Module` > > In C++, we have the following two methods > > - `ModuleEntry* InstanceKlass::module()` > - `oop ModuleEntry::module()` > > This can lead to confusing code like this: > > > InstanceKlass* ik = ...; > oop module = ik->module()->module() > > > Proposal: > > - Leave `InstanceKlass::module()` as is -- there's another function with the same style: `PackageEntry* InstanceKlass::package()` > - Rename `ModuleEntry::module()` to `ModuleEntry::module_oop()`, so the above example can be more readable: > > > InstanceKlass* ik = ...; > oop module = ik->module()->module_oop() I like this change other than precond(). ModuleEntry vs java.lang.Module oops is clearer with a different method name. I've been confused by this too. src/hotspot/share/runtime/reflection.cpp line 555: > 553: } else { > 554: oop module_oop = module_to->module_oop(); > 555: precond(module_oop != nullptr); I don't like precond() when you could have a useful assert message instead. src/hotspot/share/runtime/reflection.cpp line 582: > 580: } else { > 581: oop module_oop = module_from->module_oop(); > 582: precond(module_oop != nullptr); same here. "Module oop should be non-null in ModuleEntry" ------------- Marked as reviewed by coleenp (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/26102#pullrequestreview-2980107062 PR Review Comment: https://git.openjdk.org/jdk/pull/26102#discussion_r2180644851 PR Review Comment: https://git.openjdk.org/jdk/pull/26102#discussion_r2180646204 From iklam at openjdk.org Wed Jul 2 18:14:57 2025 From: iklam at openjdk.org (Ioi Lam) Date: Wed, 2 Jul 2025 18:14:57 GMT Subject: RFR: 8361292: Rename ModuleEntry::module() to module_oop() [v2] In-Reply-To: References: Message-ID: <70Nl64CPVziB0aP054IDyxJE2YC5QV55GhkxmMgQs0E=.560e3a99-5e84-4b67-be2f-10925c6367d2@github.com> On Wed, 2 Jul 2025 17:50:52 GMT, Coleen Phillimore wrote: >> Ioi Lam has updated the pull request incrementally with one additional commit since the last revision: >> >> @coleenp comments > > src/hotspot/share/runtime/reflection.cpp line 582: > >> 580: } else { >> 581: oop module_oop = module_from->module_oop(); >> 582: precond(module_oop != nullptr); > > same here. "Module oop should be non-null in ModuleEntry" We have just read the oop from the module entry and assert that it's not null, so the original message didn't add any extra information. That's why I removed it. I have added back a message, "should have been initialized". The real story is more complex, but I think this message willl give enough hints -- the module oop is usually initialized inside the ModuleEntry constructor, except for a few cases for the java.base module where the module oop is retroactively updated. In any case, by the time we reach this assert, the module oop must have been initialized in one of those possible paths. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26102#discussion_r2180678283 From iklam at openjdk.org Wed Jul 2 18:14:57 2025 From: iklam at openjdk.org (Ioi Lam) Date: Wed, 2 Jul 2025 18:14:57 GMT Subject: RFR: 8361292: Rename ModuleEntry::module() to module_oop() [v2] In-Reply-To: References: Message-ID: > A module has both a Java and a C++ representation > > - C++: `ModuleEntry` > - Java: `java.lang.Module` > > In C++, we have the following two methods > > - `ModuleEntry* InstanceKlass::module()` > - `oop ModuleEntry::module()` > > This can lead to confusing code like this: > > > InstanceKlass* ik = ...; > oop module = ik->module()->module() > > > Proposal: > > - Leave `InstanceKlass::module()` as is -- there's another function with the same style: `PackageEntry* InstanceKlass::package()` > - Rename `ModuleEntry::module()` to `ModuleEntry::module_oop()`, so the above example can be more readable: > > > InstanceKlass* ik = ...; > oop module = ik->module()->module_oop() Ioi Lam has updated the pull request incrementally with one additional commit since the last revision: @coleenp comments ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26102/files - new: https://git.openjdk.org/jdk/pull/26102/files/69b453e2..f58f2852 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26102&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26102&range=00-01 Stats: 2 lines in 1 file changed: 0 ins; 0 del; 2 mod Patch: https://git.openjdk.org/jdk/pull/26102.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26102/head:pull/26102 PR: https://git.openjdk.org/jdk/pull/26102 From cslucas at openjdk.org Wed Jul 2 18:24:39 2025 From: cslucas at openjdk.org (Cesar Soares Lucas) Date: Wed, 2 Jul 2025 18:24:39 GMT Subject: RFR: 8357424: [JVMCI] Avoid incrementing decompilation count for hosted compiled nmethod [v10] In-Reply-To: References: Message-ID: <3XqBb7N7ypUenwmwX2F8lRjRTeJxrXb8BfqN4vwvPa8=.eb0f51d5-8718-41b1-b89e-20b00ab9820e@github.com> On Wed, 2 Jul 2025 11:27:25 GMT, Yudi Zheng wrote: >> Hosted Truffle compilations are installed on the OptimizedCallTarget#profiledPERoot method. Any deoptimization contributes to its decompile count, which can easily exceed the PerMethodRecompilationCutoff threshold, permanently preventing highest tier compilation on this method. This PR exempts hosted compilations from this cutoff by ensuring their decompile count is not incremented for hosted compiled nmethods. > > Yudi Zheng has updated the pull request incrementally with one additional commit since the last revision: > > address comments LGTM. Thanks. ------------- Marked as reviewed by cslucas (Committer). PR Review: https://git.openjdk.org/jdk/pull/25356#pullrequestreview-2980201037 From yzheng at openjdk.org Wed Jul 2 18:41:46 2025 From: yzheng at openjdk.org (Yudi Zheng) Date: Wed, 2 Jul 2025 18:41:46 GMT Subject: RFR: 8357424: [JVMCI] Avoid incrementing decompilation count for hosted compiled nmethod [v10] In-Reply-To: References: Message-ID: On Wed, 2 Jul 2025 11:27:25 GMT, Yudi Zheng wrote: >> Hosted Truffle compilations are installed on the OptimizedCallTarget#profiledPERoot method. Any deoptimization contributes to its decompile count, which can easily exceed the PerMethodRecompilationCutoff threshold, permanently preventing highest tier compilation on this method. This PR exempts hosted compilations from this cutoff by ensuring their decompile count is not incremented for hosted compiled nmethods. > > Yudi Zheng has updated the pull request incrementally with one additional commit since the last revision: > > address comments Thanks for the review! Passed Tier1-3 ------------- PR Comment: https://git.openjdk.org/jdk/pull/25356#issuecomment-3028957076 From yzheng at openjdk.org Wed Jul 2 18:41:47 2025 From: yzheng at openjdk.org (Yudi Zheng) Date: Wed, 2 Jul 2025 18:41:47 GMT Subject: Integrated: 8357424: [JVMCI] Avoid incrementing decompilation count for hosted compiled nmethod In-Reply-To: References: Message-ID: On Wed, 21 May 2025 15:00:29 GMT, Yudi Zheng wrote: > Hosted Truffle compilations are installed on the OptimizedCallTarget#profiledPERoot method. Any deoptimization contributes to its decompile count, which can easily exceed the PerMethodRecompilationCutoff threshold, permanently preventing highest tier compilation on this method. This PR exempts hosted compilations from this cutoff by ensuring their decompile count is not incremented for hosted compiled nmethods. This pull request has now been integrated. Changeset: ea86a20e Author: Yudi Zheng URL: https://git.openjdk.org/jdk/commit/ea86a20e6d74baea54df32415d9096d3b7bba1d7 Stats: 58 lines in 5 files changed: 48 ins; 1 del; 9 mod 8357424: [JVMCI] Avoid incrementing decompilation count for hosted compiled nmethod Reviewed-by: dnsimon, never, cslucas ------------- PR: https://git.openjdk.org/jdk/pull/25356 From coleenp at openjdk.org Wed Jul 2 19:04:38 2025 From: coleenp at openjdk.org (Coleen Phillimore) Date: Wed, 2 Jul 2025 19:04:38 GMT Subject: RFR: 8361292: Rename ModuleEntry::module() to module_oop() [v2] In-Reply-To: References: Message-ID: On Wed, 2 Jul 2025 18:14:57 GMT, Ioi Lam wrote: >> A module has both a Java and a C++ representation >> >> - C++: `ModuleEntry` >> - Java: `java.lang.Module` >> >> In C++, we have the following two methods >> >> - `ModuleEntry* InstanceKlass::module()` >> - `oop ModuleEntry::module()` >> >> This can lead to confusing code like this: >> >> >> InstanceKlass* ik = ...; >> oop module = ik->module()->module() >> >> >> Proposal: >> >> - Leave `InstanceKlass::module()` as is -- there's another function with the same style: `PackageEntry* InstanceKlass::package()` >> - Rename `ModuleEntry::module()` to `ModuleEntry::module_oop()`, so the above example can be more readable: >> >> >> InstanceKlass* ik = ...; >> oop module = ik->module()->module_oop() > > Ioi Lam has updated the pull request incrementally with one additional commit since the last revision: > > @coleenp comments Marked as reviewed by coleenp (Reviewer). ------------- PR Review: https://git.openjdk.org/jdk/pull/26102#pullrequestreview-2980324205 From ccheung at openjdk.org Wed Jul 2 21:28:40 2025 From: ccheung at openjdk.org (Calvin Cheung) Date: Wed, 2 Jul 2025 21:28:40 GMT Subject: RFR: 8361292: Rename ModuleEntry::module() to module_oop() [v2] In-Reply-To: References: Message-ID: On Wed, 2 Jul 2025 18:14:57 GMT, Ioi Lam wrote: >> A module has both a Java and a C++ representation >> >> - C++: `ModuleEntry` >> - Java: `java.lang.Module` >> >> In C++, we have the following two methods >> >> - `ModuleEntry* InstanceKlass::module()` >> - `oop ModuleEntry::module()` >> >> This can lead to confusing code like this: >> >> >> InstanceKlass* ik = ...; >> oop module = ik->module()->module() >> >> >> Proposal: >> >> - Leave `InstanceKlass::module()` as is -- there's another function with the same style: `PackageEntry* InstanceKlass::package()` >> - Rename `ModuleEntry::module()` to `ModuleEntry::module_oop()`, so the above example can be more readable: >> >> >> InstanceKlass* ik = ...; >> oop module = ik->module()->module_oop() > > Ioi Lam has updated the pull request incrementally with one additional commit since the last revision: > > @coleenp comments Looks good. src/hotspot/share/classfile/moduleEntry.cpp line 52: > 50: ModuleEntry* ModuleEntryTable::_javabase_module = nullptr; > 51: > 52: oop ModuleEntry::module_oop() const { return _module_handle.resolve(); } (Pre-existing) Just wondering why this one-liner function doesn't reside in the moduleEntry.hpp? ------------- Marked as reviewed by ccheung (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/26102#pullrequestreview-2980677723 PR Review Comment: https://git.openjdk.org/jdk/pull/26102#discussion_r2181000093 From iklam at openjdk.org Wed Jul 2 21:52:44 2025 From: iklam at openjdk.org (Ioi Lam) Date: Wed, 2 Jul 2025 21:52:44 GMT Subject: RFR: 8361292: Rename ModuleEntry::module() to module_oop() [v2] In-Reply-To: References: Message-ID: On Wed, 2 Jul 2025 21:25:04 GMT, Calvin Cheung wrote: >> Ioi Lam has updated the pull request incrementally with one additional commit since the last revision: >> >> @coleenp comments > > src/hotspot/share/classfile/moduleEntry.cpp line 52: > >> 50: ModuleEntry* ModuleEntryTable::_javabase_module = nullptr; >> 51: >> 52: oop ModuleEntry::module_oop() const { return _module_handle.resolve(); } > > (Pre-existing) Just wondering why this one-liner function doesn't reside in the moduleEntry.hpp? I think it's because `OopHandle::resolve()` is an inline function, but we are not allowed to include `xxx.inline.hpp` in non-inlined `.hpp` files. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26102#discussion_r2181036271 From sspitsyn at openjdk.org Wed Jul 2 22:04:43 2025 From: sspitsyn at openjdk.org (Serguei Spitsyn) Date: Wed, 2 Jul 2025 22:04:43 GMT Subject: RFR: 8361292: Rename ModuleEntry::module() to module_oop() [v2] In-Reply-To: References: Message-ID: On Wed, 2 Jul 2025 18:14:57 GMT, Ioi Lam wrote: >> A module has both a Java and a C++ representation >> >> - C++: `ModuleEntry` >> - Java: `java.lang.Module` >> >> In C++, we have the following two methods >> >> - `ModuleEntry* InstanceKlass::module()` >> - `oop ModuleEntry::module()` >> >> This can lead to confusing code like this: >> >> >> InstanceKlass* ik = ...; >> oop module = ik->module()->module() >> >> >> Proposal: >> >> - Leave `InstanceKlass::module()` as is -- there's another function with the same style: `PackageEntry* InstanceKlass::package()` >> - Rename `ModuleEntry::module()` to `ModuleEntry::module_oop()`, so the above example can be more readable: >> >> >> InstanceKlass* ik = ...; >> oop module = ik->module()->module_oop() > > Ioi Lam has updated the pull request incrementally with one additional commit since the last revision: > > @coleenp comments Looks good. ------------- Marked as reviewed by sspitsyn (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/26102#pullrequestreview-2980760653 From kbarrett at openjdk.org Thu Jul 3 01:32:53 2025 From: kbarrett at openjdk.org (Kim Barrett) Date: Thu, 3 Jul 2025 01:32:53 GMT Subject: RFR: 8320353: Reenable stringop-overflow warnings In-Reply-To: References: Message-ID: On Wed, 2 Jul 2025 13:51:24 GMT, Kim Barrett wrote: >> Hi, please consider the following changes: >> >> this PR addresses the issue of stringop-overflow warnings produced by GCC. The compiler does think that the thread pointer returned by `JavaThread::current()` can be null, though it cant. The thread pointer ends up being an argument in `__atomic_load`, and the compiler reports the warning related to argument of that method. >> >> The patch adds a hint to the compiler by means of `__builtin_unreachable()` intrinsic, which tells the compiler that certain piece of code will never be reached (case of thread pointer being null). This solves the issue. >> >> Tested in tiers 1-3 and GHA. > > src/hotspot/share/jvmci/jvmciCodeInstaller.cpp line 936: > >> 934: __builtin_unreachable(); >> 935: } >> 936: #endif > > I think this could be replaced with asserting non-null. A failed assert calls a noreturn reporting > function. Although I wonder why the assert in Thread::current() isn't sufficient? Maybe non-null info isn't propagating through the cast to JavaThread? ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26067#discussion_r2181311538 From kbarrett at openjdk.org Thu Jul 3 01:52:41 2025 From: kbarrett at openjdk.org (Kim Barrett) Date: Thu, 3 Jul 2025 01:52:41 GMT Subject: RFR: 8320353: Reenable stringop-overflow warnings In-Reply-To: References: Message-ID: On Tue, 1 Jul 2025 12:25:04 GMT, Anton Artemov wrote: > Hi, please consider the following changes: > > this PR addresses the issue of stringop-overflow warnings produced by GCC. The compiler does think that the thread pointer returned by `JavaThread::current()` can be null, though it cant. The thread pointer ends up being an argument in `__atomic_load`, and the compiler reports the warning related to argument of that method. > > The patch adds a hint to the compiler by means of `__builtin_unreachable()` intrinsic, which tells the compiler that certain piece of code will never be reached (case of thread pointer being null). This solves the issue. > > Tested in tiers 1-3 and GHA. make/hotspot/lib/CompileJvm.gmk line 199: > 197: DISABLED_WARNINGS_gcc_macroAssembler_ppc_sha.cpp := unused-const-variable, \ > 198: DISABLED_WARNINGS_gcc_postaloc.cpp := address, \ > 199: DISABLED_WARNINGS_gcc_shenandoahLock.cpp := stringop-overflow, \ What about this one in shenandoahLock.cpp? ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26067#discussion_r2181357398 From kbarrett at openjdk.org Thu Jul 3 05:36:42 2025 From: kbarrett at openjdk.org (Kim Barrett) Date: Thu, 3 Jul 2025 05:36:42 GMT Subject: RFR: 8320353: Reenable stringop-overflow warnings In-Reply-To: References: Message-ID: On Tue, 1 Jul 2025 12:25:04 GMT, Anton Artemov wrote: > Hi, please consider the following changes: > > this PR addresses the issue of stringop-overflow warnings produced by GCC. The compiler does think that the thread pointer returned by `JavaThread::current()` can be null, though it cant. The thread pointer ends up being an argument in `__atomic_load`, and the compiler reports the warning related to argument of that method. > > The patch adds a hint to the compiler by means of `__builtin_unreachable()` intrinsic, which tells the compiler that certain piece of code will never be reached (case of thread pointer being null). This solves the issue. > > Tested in tiers 1-3 and GHA. My suggestion of using assertions instead doesn't seem to work, still getting bogus warnings. This is with gcc14.2 on linux-aarch64, which also uses __atomic_load. That is mysteriously weird. The noreturn reporting function should be roughly equivalent to calling an ordinary function with an "unreachable" following it. But then, this whole issue is mysteriously weird. But that's okay; I wasn't really all that keen on adding assertions to suppress bogus compiler warnings anyway. At this point I think this change should just not be made. It's a compiler bug. The existing suppression of the warnings is fine with me. I think what's really needed is for someone to file a gcc bug. It's too bad nobody did that when the issue was first noticed. There's already a bug that is similar, and might even be the same, even though it involves sanitizers and ours doesn't: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113775 ------------- PR Comment: https://git.openjdk.org/jdk/pull/26067#issuecomment-3030839463 From duke at openjdk.org Thu Jul 3 07:47:40 2025 From: duke at openjdk.org (Anton Artemov) Date: Thu, 3 Jul 2025 07:47:40 GMT Subject: RFR: 8320353: Reenable stringop-overflow warnings In-Reply-To: References: Message-ID: On Thu, 3 Jul 2025 05:34:27 GMT, Kim Barrett wrote: > My suggestion of using assertions instead doesn't seem to work, still getting bogus warnings. This is with gcc14.2 on linux-aarch64, which also uses __atomic_load. That is mysteriously weird. The noreturn reporting function should be roughly equivalent to calling an ordinary function with an "unreachable" following it. But then, this whole issue is mysteriously weird. > > But that's okay; I wasn't really all that keen on adding assertions to suppress bogus compiler warnings anyway. > > At this point I think this change should just not be made. It's a compiler bug. The existing suppression of the warnings is fine with me. > > I think what's really needed is for someone to file a gcc bug. It's too bad nobody did that when the issue was first noticed. There's already a bug that is similar, and might even be the same, even though it involves sanitizers and ours doesn't: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113775 Thanks @kimbarrett, after looking at your findings I agree that it looks like a GCC bug, and therefore we should not do this change. I will try to make the smallest reproducible example and submit a bug report. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26067#issuecomment-3031232698 From bmaillard at openjdk.org Thu Jul 3 08:09:41 2025 From: bmaillard at openjdk.org (=?UTF-8?B?QmVub8OudA==?= Maillard) Date: Thu, 3 Jul 2025 08:09:41 GMT Subject: RFR: 8347901: C2 should remove unused leaf / pure runtime calls [v3] In-Reply-To: References: Message-ID: On Mon, 23 Jun 2025 12:39:23 GMT, Marc Chevalier wrote: >> A first part toward a better support of pure functions, but this time, with guidance from @iwanowww. >> >> ## Pure Functions >> >> Pure functions (considered here) are functions that have no side effects, no effect on the control flow (no exception or such), cannot deopt etc.. It's really a function that you can execute anywhere, with whichever arguments without effect other than wasting time. Integer division is not pure as dividing by zero is throwing. But many floating point functions will just return `NaN` or `+/-infinity` in problematic cases. >> >> ## Scope >> >> We are not going all powerful for now! It's mostly about identifying some pure functions and being able to remove them if the result is unused. Some other things are not part of this PR, on purpose. Especially, this PR doesn't propose a way to move pure calls around. The reason is that pure calls are later expanded into regular calls, which require a control input. To be able to do the expansion, we just keep the control in the pure call as well. >> >> ## Implementation Overview >> >> We created here some new node kind for pure calls, inheriting leaf calls, that are expanded into regular leaf calls during final graph reshaping. The possibility to support pure call directly in AD file is left open. >> >> This PR also introduces `TupleNode` (largely based on an original idea/implem of @iwanowww), that just tie multiple input together and play well with `ProjNode`: the n-th projection of a `TupleNode` is the n-th input of the tuple. This is a convenient way to skip and remove nodes from the graph while delegating the difficulty of the surgery to the trusted IGVN's implementation. >> >> Thanks, >> Marc > > Marc Chevalier has updated the pull request incrementally with one additional commit since the last revision: > > mostly comments src/hotspot/share/opto/parse2.cpp line 1100: > 1098: Node* Parse::floating_point_mod(Node* a, Node* b, BasicType type) { > 1099: assert(type == BasicType::T_FLOAT || type == BasicType::T_DOUBLE, "only float and double are floating points"); > 1100: CallLeafPureNode* mod = type == BasicType::T_DOUBLE ? static_cast(new ModDNode(C, a, b)) : new ModFNode(C, a, b); May I ask why we only need the `static_cast` for the `ModDNode` here? ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25760#discussion_r2180229177 From mchevalier at openjdk.org Thu Jul 3 08:21:41 2025 From: mchevalier at openjdk.org (Marc Chevalier) Date: Thu, 3 Jul 2025 08:21:41 GMT Subject: RFR: 8347901: C2 should remove unused leaf / pure runtime calls [v3] In-Reply-To: References: Message-ID: On Wed, 2 Jul 2025 14:35:26 GMT, Beno?t Maillard wrote: >> Marc Chevalier has updated the pull request incrementally with one additional commit since the last revision: >> >> mostly comments > > src/hotspot/share/opto/parse2.cpp line 1100: > >> 1098: Node* Parse::floating_point_mod(Node* a, Node* b, BasicType type) { >> 1099: assert(type == BasicType::T_FLOAT || type == BasicType::T_DOUBLE, "only float and double are floating points"); >> 1100: CallLeafPureNode* mod = type == BasicType::T_DOUBLE ? static_cast(new ModDNode(C, a, b)) : new ModFNode(C, a, b); > > May I ask why we only need the `static_cast` for the `ModDNode` here? It's C/C++ being annoying here: both branches of the ternary must have the same type, or something compatible. If I remove the cast: error: conditional expression between distinct pointer types 'ModDNode*' and 'ModFNode*' lacks a cast With the case, C++ can converrt the `ModFNode*` into a `CallLeafPureNode*` just fine. I didn't invent the cast, it was here before, but good to question it. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25760#discussion_r2182166387 From duke at openjdk.org Thu Jul 3 12:04:44 2025 From: duke at openjdk.org (Anton Artemov) Date: Thu, 3 Jul 2025 12:04:44 GMT Subject: Withdrawn: 8320353: Reenable stringop-overflow warnings In-Reply-To: References: Message-ID: On Tue, 1 Jul 2025 12:25:04 GMT, Anton Artemov wrote: > Hi, please consider the following changes: > > this PR addresses the issue of stringop-overflow warnings produced by GCC. The compiler does think that the thread pointer returned by `JavaThread::current()` can be null, though it cant. The thread pointer ends up being an argument in `__atomic_load`, and the compiler reports the warning related to argument of that method. > > The patch adds a hint to the compiler by means of `__builtin_unreachable()` intrinsic, which tells the compiler that certain piece of code will never be reached (case of thread pointer being null). This solves the issue. > > Tested in tiers 1-3 and GHA. This pull request has been closed without being integrated. ------------- PR: https://git.openjdk.org/jdk/pull/26067 From dnsimon at openjdk.org Thu Jul 3 13:04:19 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Thu, 3 Jul 2025 13:04:19 GMT Subject: RFR: 8361355: Negative cases of Annotated.getAnnotationData implementations are broken Message-ID: This PR fixes bugs in the implementation of `jdk.vm.ci.meta.Annotated.getAnnotationData`: 1. Calling `getAnnotatedData(annotationType)` fails with an ArrayIndexOutOfBoundsException instead of returning null when the receiver type is not annotated by `annotationType`. 2. Calling either of the `getAnnotatedData` methods with an `annotationType` value that does not represent an annotation interface silently succeeds when the receiver type does not (or can not) have any annotations (e.g. array and primitive types). ------------- Commit messages: - fixed negative cases in getAnnotationData Changes: https://git.openjdk.org/jdk/pull/26116/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=26116&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8361355 Stats: 100 lines in 7 files changed: 89 ins; 1 del; 10 mod Patch: https://git.openjdk.org/jdk/pull/26116.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26116/head:pull/26116 PR: https://git.openjdk.org/jdk/pull/26116 From dnsimon at openjdk.org Thu Jul 3 14:13:23 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Thu, 3 Jul 2025 14:13:23 GMT Subject: RFR: 8361355: Negative cases of Annotated.getAnnotationData implementations are broken [v2] In-Reply-To: References: Message-ID: > This PR fixes bugs in the implementation of `jdk.vm.ci.meta.Annotated.getAnnotationData`: > 1. Calling `getAnnotatedData(annotationType)` fails with an ArrayIndexOutOfBoundsException instead of returning null when the receiver type is not annotated by `annotationType`. > 2. Calling either of the `getAnnotatedData` methods with an `annotationType` value that does not represent an annotation interface silently succeeds when the receiver type does not (or can not) have any annotations (e.g. array and primitive types). Doug Simon has refreshed the contents of this pull request, and previous commits have been removed. The incremental views will show differences compared to the previous content of the PR. The pull request contains one new commit since the last revision: fixed negative cases in getAnnotationData ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26116/files - new: https://git.openjdk.org/jdk/pull/26116/files/86b41636..b25684f7 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26116&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26116&range=00-01 Stats: 11 lines in 1 file changed: 5 ins; 0 del; 6 mod Patch: https://git.openjdk.org/jdk/pull/26116.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26116/head:pull/26116 PR: https://git.openjdk.org/jdk/pull/26116 From never at openjdk.org Thu Jul 3 14:59:39 2025 From: never at openjdk.org (Tom Rodriguez) Date: Thu, 3 Jul 2025 14:59:39 GMT Subject: RFR: 8361355: Negative cases of Annotated.getAnnotationData implementations are broken [v2] In-Reply-To: References: Message-ID: On Thu, 3 Jul 2025 14:13:23 GMT, Doug Simon wrote: >> This PR fixes bugs in the implementation of `jdk.vm.ci.meta.Annotated.getAnnotationData`: >> 1. Calling `getAnnotatedData(annotationType)` fails with an ArrayIndexOutOfBoundsException instead of returning null when the receiver type is not annotated by `annotationType`. >> 2. Calling either of the `getAnnotatedData` methods with an `annotationType` value that does not represent an annotation interface silently succeeds when the receiver type does not (or can not) have any annotations (e.g. array and primitive types). > > Doug Simon has refreshed the contents of this pull request, and previous commits have been removed. The incremental views will show differences compared to the previous content of the PR. The pull request contains one new commit since the last revision: > > fixed negative cases in getAnnotationData Looks good. ------------- Marked as reviewed by never (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/26116#pullrequestreview-2983525519 From iklam at openjdk.org Thu Jul 3 16:55:45 2025 From: iklam at openjdk.org (Ioi Lam) Date: Thu, 3 Jul 2025 16:55:45 GMT Subject: RFR: 8361292: Rename ModuleEntry::module() to module_oop() [v2] In-Reply-To: References: Message-ID: <7t8AhNKgTL2MU_ba0F3rCllEqaodLFmshj_9QvGwY00=.1ba3ff82-905d-4b7a-8b4a-6944f5b22b5e@github.com> On Wed, 2 Jul 2025 19:02:30 GMT, Coleen Phillimore wrote: >> Ioi Lam has updated the pull request incrementally with one additional commit since the last revision: >> >> @coleenp comments > > Marked as reviewed by coleenp (Reviewer). Thanks @coleenp @calvinccheung @sspitsyn for the review ------------- PR Comment: https://git.openjdk.org/jdk/pull/26102#issuecomment-3032931506 From iklam at openjdk.org Thu Jul 3 16:55:46 2025 From: iklam at openjdk.org (Ioi Lam) Date: Thu, 3 Jul 2025 16:55:46 GMT Subject: Integrated: 8361292: Rename ModuleEntry::module() to module_oop() In-Reply-To: References: Message-ID: On Wed, 2 Jul 2025 17:33:40 GMT, Ioi Lam wrote: > A module has both a Java and a C++ representation > > - C++: `ModuleEntry` > - Java: `java.lang.Module` > > In C++, we have the following two methods > > - `ModuleEntry* InstanceKlass::module()` > - `oop ModuleEntry::module()` > > This can lead to confusing code like this: > > > InstanceKlass* ik = ...; > oop module = ik->module()->module() > > > Proposal: > > - Leave `InstanceKlass::module()` as is -- there's another function with the same style: `PackageEntry* InstanceKlass::package()` > - Rename `ModuleEntry::module()` to `ModuleEntry::module_oop()`, so the above example can be more readable: > > > InstanceKlass* ik = ...; > oop module = ik->module()->module_oop() This pull request has now been integrated. Changeset: 66836d40 Author: Ioi Lam URL: https://git.openjdk.org/jdk/commit/66836d40b80f9c5482c1322d1d07f078ad9dcc02 Stats: 35 lines in 12 files changed: 0 ins; 0 del; 35 mod 8361292: Rename ModuleEntry::module() to module_oop() Reviewed-by: coleenp, ccheung, sspitsyn ------------- PR: https://git.openjdk.org/jdk/pull/26102 From dnsimon at openjdk.org Thu Jul 3 17:30:56 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Thu, 3 Jul 2025 17:30:56 GMT Subject: RFR: 8361355: Negative cases of Annotated.getAnnotationData implementations are broken [v3] In-Reply-To: References: Message-ID: <83aGkzmp5J7JllBsWK5ZzwZAa4GVsNk5VjmkH0O3FjE=.2507d7ce-65df-4121-acdf-35125d530d39@github.com> > This PR fixes bugs in the implementation of `jdk.vm.ci.meta.Annotated.getAnnotationData`: > 1. Calling `getAnnotatedData(annotationType)` fails with an ArrayIndexOutOfBoundsException instead of returning null when the receiver type is not annotated by `annotationType`. > 2. Calling either of the `getAnnotatedData` methods with an `annotationType` value that does not represent an annotation interface silently succeeds when the receiver type does not (or can not) have any annotations (e.g. array and primitive types). Doug Simon has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains two additional commits since the last revision: - Merge tag 'jdk-26+4' into JDK-8361355 Added tag jdk-26+4 for changeset 1ca008fd - fixed negative cases in getAnnotationData ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26116/files - new: https://git.openjdk.org/jdk/pull/26116/files/b25684f7..ec161d59 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26116&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26116&range=01-02 Stats: 6616 lines in 362 files changed: 3437 ins; 1484 del; 1695 mod Patch: https://git.openjdk.org/jdk/pull/26116.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26116/head:pull/26116 PR: https://git.openjdk.org/jdk/pull/26116 From dnsimon at openjdk.org Fri Jul 4 07:39:45 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Fri, 4 Jul 2025 07:39:45 GMT Subject: RFR: 8361355: Negative cases of Annotated.getAnnotationData implementations are broken [v3] In-Reply-To: <83aGkzmp5J7JllBsWK5ZzwZAa4GVsNk5VjmkH0O3FjE=.2507d7ce-65df-4121-acdf-35125d530d39@github.com> References: <83aGkzmp5J7JllBsWK5ZzwZAa4GVsNk5VjmkH0O3FjE=.2507d7ce-65df-4121-acdf-35125d530d39@github.com> Message-ID: On Thu, 3 Jul 2025 17:30:56 GMT, Doug Simon wrote: >> This PR fixes bugs in the implementation of `jdk.vm.ci.meta.Annotated.getAnnotationData`: >> 1. Calling `getAnnotatedData(annotationType)` fails with an ArrayIndexOutOfBoundsException instead of returning null when the receiver type is not annotated by `annotationType`. >> 2. Calling either of the `getAnnotatedData` methods with an `annotationType` value that does not represent an annotation interface silently succeeds when the receiver type does not (or can not) have any annotations (e.g. array and primitive types). > > Doug Simon has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains two additional commits since the last revision: > > - Merge tag 'jdk-26+4' into JDK-8361355 > > Added tag jdk-26+4 for changeset 1ca008fd > - fixed negative cases in getAnnotationData Thanks for the review. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26116#issuecomment-3034837278 From dnsimon at openjdk.org Fri Jul 4 07:39:46 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Fri, 4 Jul 2025 07:39:46 GMT Subject: Integrated: 8361355: Negative cases of Annotated.getAnnotationData implementations are broken In-Reply-To: References: Message-ID: On Thu, 3 Jul 2025 12:52:10 GMT, Doug Simon wrote: > This PR fixes bugs in the implementation of `jdk.vm.ci.meta.Annotated.getAnnotationData`: > 1. Calling `getAnnotatedData(annotationType)` fails with an ArrayIndexOutOfBoundsException instead of returning null when the receiver type is not annotated by `annotationType`. > 2. Calling either of the `getAnnotatedData` methods with an `annotationType` value that does not represent an annotation interface silently succeeds when the receiver type does not (or can not) have any annotations (e.g. array and primitive types). This pull request has now been integrated. Changeset: 5cf349c3 Author: Doug Simon URL: https://git.openjdk.org/jdk/commit/5cf349c3b08324e994a4143dcc34a59fd81323f9 Stats: 111 lines in 7 files changed: 94 ins; 1 del; 16 mod 8361355: Negative cases of Annotated.getAnnotationData implementations are broken Reviewed-by: never ------------- PR: https://git.openjdk.org/jdk/pull/26116 From dnsimon at openjdk.org Sat Jul 5 10:31:37 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Sat, 5 Jul 2025 10:31:37 GMT Subject: RFR: 8361417: JVMCI getModifiers incorrect for inner classes Message-ID: The result of `ResolvedJavaType.getModifiers()` should always have been the same as `Class.getModifiers()`. This is currently not the case for inner classes. Instead, the value is derived from `Klass::_access_flags` where as it should be derived from the `InnerClasses` attribute (as it is for `Class`). This PR aligns `ResolvedJavaType.getModifiers()` with `Class.getModifiers()`. ------------- Commit messages: - fix getModifiers() for inner classes Changes: https://git.openjdk.org/jdk/pull/26135/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=26135&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8361417 Stats: 71 lines in 7 files changed: 36 ins; 20 del; 15 mod Patch: https://git.openjdk.org/jdk/pull/26135.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26135/head:pull/26135 PR: https://git.openjdk.org/jdk/pull/26135 From missa at openjdk.org Mon Jul 7 03:10:15 2025 From: missa at openjdk.org (Mohamed Issa) Date: Mon, 7 Jul 2025 03:10:15 GMT Subject: RFR: 8360559: Optimize Math.sinh for x86 64 bit platforms Message-ID: The goal of this PR is to implement an x86_64 intrinsic for java.lang.Math.sinh() using libm. There is a new set of micro-benchmarks are included to check the performance of specific input value ranges to help prevent regressions in the future. The command to run all range specific micro-benchmarks is posted below. `make test TEST="micro:SinhPerf.SinhPerfRanges"` The results of all tests posted below were captured with an [Intel? Xeon 8488C](https://advisor.cloudzero.com/aws/ec2/r7i.metal-24xl) using [OpenJDK v26-b4](https://github.com/openjdk/jdk/releases/tag/jdk-26%2B4) as the baseline version. For performance data collected with the new built in range micro-benchmark, see the table below. Each result is the mean of 8 individual runs, and the input ranges used match those from the original Java implementation. Overall, the intrinsic provides an an average uplift of 64% when input values fall into the middle three ranges where heavy computation is required. However, very small inputs and very large inputs show drops of 74% and 66% respectively. | Input range(s) | Baseline throughput (ops/ms) | Intrinsic throughput (ops/ms) | Speedup | | :------------------------------------: | :-------------------------------: | :--------------------------------: | :--------: | | [-2^(-28), 2^(-28)] | 844160 | 216029 | 0.26x | | [-22, -2^(-28)], [2^(-28), 22] | 81662 | 157351 | 1.93x | | [-709.78, -22], [22, 709.78] | 119075 | 167635 | 1.41x | | [-710.48, -709.78], [709.78, 710.48] | 111636 | 177125 | 1.59x | | (-INF, -710.48], [710.48, INF) | 959296 | 313839 | 0.33x | Finally, the `jtreg:test/jdk/java/lang/Math/HyperbolicTests.java` test passed with the changes. ------------- Commit messages: - x86_64 intrinsic for sinh using libm Changes: https://git.openjdk.org/jdk/pull/26152/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=26152&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8360559 Stats: 740 lines in 26 files changed: 737 ins; 0 del; 3 mod Patch: https://git.openjdk.org/jdk/pull/26152.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26152/head:pull/26152 PR: https://git.openjdk.org/jdk/pull/26152 From fweimer at openjdk.org Mon Jul 7 04:50:37 2025 From: fweimer at openjdk.org (Florian Weimer) Date: Mon, 7 Jul 2025 04:50:37 GMT Subject: RFR: 8360559: Optimize Math.sinh for x86 64 bit platforms In-Reply-To: References: Message-ID: On Mon, 7 Jul 2025 03:05:15 GMT, Mohamed Issa wrote: > The goal of this PR is to implement an x86_64 intrinsic for java.lang.Math.sinh() using libm. There is a new set of micro-benchmarks are included to check the performance of specific input value ranges to help prevent regressions in the future. > > The command to run all range specific micro-benchmarks is posted below. > > `make test TEST="micro:SinhPerf.SinhPerfRanges"` > > The results of all tests posted below were captured with an [Intel? Xeon 8488C](https://advisor.cloudzero.com/aws/ec2/r7i.metal-24xl) using [OpenJDK v26-b4](https://github.com/openjdk/jdk/releases/tag/jdk-26%2B4) as the baseline version. > > For performance data collected with the new built in range micro-benchmark, see the table below. Each result is the mean of 8 individual runs, and the input ranges used match those from the original Java implementation. Overall, the intrinsic provides an an average uplift of 64% when input values fall into the middle three ranges where heavy computation is required. However, very small inputs and very large inputs show drops of 74% and 66% respectively. > > | Input range(s) | Baseline throughput (ops/ms) | Intrinsic throughput (ops/ms) | Speedup | > | :------------------------------------: | :-------------------------------: | :--------------------------------: | :--------: | > | [-2^(-28), 2^(-28)] | 844160 | 216029 | 0.26x | > | [-22, -2^(-28)], [2^(-28), 22] | 81662 | 157351 | 1.93x | > | [-709.78, -22], [22, 709.78] | 119075 | 167635 | 1.41x | > | [-710.48, -709.78], [709.78, 710.48] | 111636 | 177125 | 1.59x | > | (-INF, -710.48], [710.48, INF) | 959296 | 313839 | 0.33x | > > Finally, the `jtreg:test/jdk/java/lang/Math/HyperbolicTests.java` test passed with the changes. Isn't this effectively a libm benchmark (where the `sinh` implementation resides)? Please include the libm version for reference here. Thanks. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26152#issuecomment-3043465393 From thartmann at openjdk.org Mon Jul 7 07:45:46 2025 From: thartmann at openjdk.org (Tobias Hartmann) Date: Mon, 7 Jul 2025 07:45:46 GMT Subject: RFR: 8359344: C2: Malformed control flow after intrinsic bailout [v2] In-Reply-To: <1cFRkcs5JmgnbWEIaEoT8I9RiUtNxgKieAdkSB2Fgmc=.1d97b5c4-b6ef-43c6-b721-1e52eee19d3a@github.com> References: <1cFRkcs5JmgnbWEIaEoT8I9RiUtNxgKieAdkSB2Fgmc=.1d97b5c4-b6ef-43c6-b721-1e52eee19d3a@github.com> Message-ID: On Tue, 1 Jul 2025 16:14:00 GMT, Marc Chevalier wrote: >> When intrinsic bailout, we assume that the control in the `LibraryCallKit` did not change: >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L137 >> >> This is enforced by restoring the old state, like in >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L1722-L1732 >> >> That is good, but not sufficient. First, the most obvious, one could have already built some structure without moving the control. For instance, we can obtain something such as: >> >> ![1 after-intrinsic-bailout-during-late-inlining](https://github.com/user-attachments/assets/2fd255cc-0bfc-4841-8dd1-f64d502e0ee1) >> >> >> Here, during late inlining, the call `323` is candidate to be inline, but that bails out. Yet, a call to `make_unsafe_address` was made, which built nodes `354 If` and everything under. This is needed as tests are made on the resulting nodes (especially `366 AddP`) to know whether we should bail out or not. At the end, we get 2 control successor to `346 IfFalse`: the call that is not removed and the leftover of the intrinsic that will be cleanup much later, but not by RemoveUseless. >> >> Another situation is somewhat worse, when happening during parsing. It can lead to such cases: >> >> ![2 after-intrinsic-bailout-during-parsing](https://github.com/user-attachments/assets/4524c615-6521-4f0d-8f61-c426f9179035) >> >> The nodes `31 OpaqueNotNull`, `31 If`, `36 IfTrue`, `33 IfFalse`, `35 Halt`, `44 If`, `45 IfTrue`, `46 IfFalse` are leftover from a bailing out intrinsic. The replacement call `49 CallStaticJava` should come just under `5 Parm`, but the control was updated and the call is actually built under `36 If`. Then, why does the previous assert doesn't complain? >> >> This is because there is more than one control, or one map. In intrinsics that need to restore their state, the initial `SafePoint` map is cloned, the clone is kept aside, and if needed (bailing out), we set the current map to this saved clone. But there is another map from which the one of the `LibraryCallKit` comes, and that survives longer, it's the one that is contained in the `JVMState`: >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L101-L102 >> >> And here there is the challenge: >> - the `JVMState jvms` contains a `SafePoint` map, this map must have `jvms` as `jvms` (pointer comparison) >> ... > > Marc Chevalier has updated the pull request incrementally with one additional commit since the last revision: > > Remove useless loop Nice analysis! In general, the fix looks good to me. I added a few comments / suggestions. src/hotspot/share/opto/library_call.cpp line 1732: > 1730: return false; > 1731: } > 1732: destruct_map_clone(old_state.map); I think `destruct_map_clone` could be refactored to take a `SavedState`. src/hotspot/share/opto/library_call.cpp line 2376: > 2374: state.map = clone_map(); > 2375: for (DUIterator_Fast imax, i = control()->fast_outs(imax); i < imax; i++) { > 2376: Node* out = control()->fast_out(i); Could we have a similar issue with non-control users? For example, couldn't we also have stray memory users after bailout? src/hotspot/share/opto/library_call.cpp line 2393: > 2391: Node* out = control()->fast_out(i); > 2392: if (out->is_CFG() && out->in(0) == control() && out != map() && !state.ctrl_succ.member(out)) { > 2393: out->set_req(0, C->top()); Could `out` already be in the GVN hash ("remove node from hash table before modifying it")? src/hotspot/share/opto/library_call.hpp line 129: > 127: virtual int reexecute_sp() { return _reexecute_sp; } > 128: > 129: struct SavedState { Please add a comment describing what it's used for. test/hotspot/jtreg/compiler/intrinsics/VectorIntoArrayInvalidControlFlow.java line 2: > 1: /* > 2: * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. Suggestion: * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java line 104: > 102: public static final String START = "(\\d+(\\s){2}("; > 103: public static final String MID = ".*)+(\\s){2}===.*"; > 104: public static final String END = ")"; I don't like exposing these outside the IR framework but then again I don't really have an idea on how to check the "graph should not have both nodes" invariant. Maybe we should extend the `counts` annotation to support something like `@IR(counts = {IRNode.CallStaticJava, IRNode.OpaqueNotNull, "<= 1"} [...]`? ------------- Marked as reviewed by thartmann (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/25936#pullrequestreview-2992473824 PR Review Comment: https://git.openjdk.org/jdk/pull/25936#discussion_r2189175998 PR Review Comment: https://git.openjdk.org/jdk/pull/25936#discussion_r2189211960 PR Review Comment: https://git.openjdk.org/jdk/pull/25936#discussion_r2189198041 PR Review Comment: https://git.openjdk.org/jdk/pull/25936#discussion_r2189172691 PR Review Comment: https://git.openjdk.org/jdk/pull/25936#discussion_r2189212910 PR Review Comment: https://git.openjdk.org/jdk/pull/25936#discussion_r2189244934 From thartmann at openjdk.org Mon Jul 7 08:35:50 2025 From: thartmann at openjdk.org (Tobias Hartmann) Date: Mon, 7 Jul 2025 08:35:50 GMT Subject: RFR: 8347901: C2 should remove unused leaf / pure runtime calls [v3] In-Reply-To: References: Message-ID: On Mon, 23 Jun 2025 12:39:23 GMT, Marc Chevalier wrote: >> A first part toward a better support of pure functions, but this time, with guidance from @iwanowww. >> >> ## Pure Functions >> >> Pure functions (considered here) are functions that have no side effects, no effect on the control flow (no exception or such), cannot deopt etc.. It's really a function that you can execute anywhere, with whichever arguments without effect other than wasting time. Integer division is not pure as dividing by zero is throwing. But many floating point functions will just return `NaN` or `+/-infinity` in problematic cases. >> >> ## Scope >> >> We are not going all powerful for now! It's mostly about identifying some pure functions and being able to remove them if the result is unused. Some other things are not part of this PR, on purpose. Especially, this PR doesn't propose a way to move pure calls around. The reason is that pure calls are later expanded into regular calls, which require a control input. To be able to do the expansion, we just keep the control in the pure call as well. >> >> ## Implementation Overview >> >> We created here some new node kind for pure calls, inheriting leaf calls, that are expanded into regular leaf calls during final graph reshaping. The possibility to support pure call directly in AD file is left open. >> >> This PR also introduces `TupleNode` (largely based on an original idea/implem of @iwanowww), that just tie multiple input together and play well with `ProjNode`: the n-th projection of a `TupleNode` is the n-th input of the tuple. This is a convenient way to skip and remove nodes from the graph while delegating the difficulty of the surgery to the trusted IGVN's implementation. >> >> Thanks, >> Marc > > Marc Chevalier has updated the pull request incrementally with one additional commit since the last revision: > > mostly comments Thanks for digging into this Marc. The changes look good to me. I just added a few minor comments / questions. > this PR doesn't propose a way to move pure calls around Should we have a separate RFE for that? src/hotspot/share/opto/divnode.cpp line 1522: > 1520: Node* super = CallLeafPureNode::Ideal(phase, can_reshape); > 1521: if (super != nullptr) { > 1522: return super; Can't we just do `return CallLeafPureNode::Ideal(phase, can_reshape);` at the end of `ModFNode::Ideal` instead of `return nullptr`? That's what we usually do in C2, for example in `CallStaticJavaNode::Ideal` -> `CallNode::Ideal`. Feels more natural to me and would avoid the `super != nullptr` check. Also for the other `Ideal` methods that you modified. src/hotspot/share/opto/divnode.cpp line 1528: > 1526: bool not_dead = proj_out_or_null(TypeFunc::Control) != nullptr; > 1527: if (result_is_unused && not_dead) { > 1528: return replace_with_con(igvn, TypeF::make(0.)); Can we replace all the other usages of `ModFloatingNode::replace_with_con` by `TupleNode` and get rid of that method? src/hotspot/share/opto/graphKit.cpp line 1916: > 1914: if (call->is_CallLeafPure()) { > 1915: // Pure function have only control (for now) and data output, in particular > 1916: // the don't touch the memory, so we don't want a memory proj that is set after. Suggestion: // they don't touch the memory, so we don't want a memory proj that is set after. ------------- Marked as reviewed by thartmann (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/25760#pullrequestreview-2992602888 PR Review Comment: https://git.openjdk.org/jdk/pull/25760#discussion_r2189268498 PR Review Comment: https://git.openjdk.org/jdk/pull/25760#discussion_r2189357774 PR Review Comment: https://git.openjdk.org/jdk/pull/25760#discussion_r2189261824 From tschatzl at openjdk.org Mon Jul 7 12:36:40 2025 From: tschatzl at openjdk.org (Thomas Schatzl) Date: Mon, 7 Jul 2025 12:36:40 GMT Subject: RFR: 8342382: Implementation of JEP G1: Improve Application Throughput with a More Efficient Write-Barrier [v41] In-Reply-To: References: Message-ID: > Hi all, > > please review this change that implements (currently Draft) JEP: G1: Improve Application Throughput with a More Efficient Write-Barrier. > > The reason for posting this early is that this is a large change, and the JEP process is already taking very long with no end in sight but we would like to have this ready by JDK 25. > > ### Current situation > > With this change, G1 will reduce the post write barrier to much more resemble Parallel GC's as described in the JEP. The reason is that G1 lacks in throughput compared to Parallel/Serial GC due to larger barrier. > > The main reason for the current barrier is how g1 implements concurrent refinement: > * g1 tracks dirtied cards using sets (dirty card queue set - dcqs) of buffers (dirty card queues - dcq) containing the location of dirtied cards. Refinement threads pick up their contents to re-refine. The barrier needs to enqueue card locations. > * For correctness dirty card updates requires fine-grained synchronization between mutator and refinement threads, > * Finally there is generic code to avoid dirtying cards altogether (filters), to avoid executing the synchronization and the enqueuing as much as possible. > > These tasks require the current barrier to look as follows for an assignment `x.a = y` in pseudo code: > > > // Filtering > if (region(@x.a) == region(y)) goto done; // same region check > if (y == null) goto done; // null value check > if (card(@x.a) == young_card) goto done; // write to young gen check > StoreLoad; // synchronize > if (card(@x.a) == dirty_card) goto done; > > *card(@x.a) = dirty > > // Card tracking > enqueue(card-address(@x.a)) into thread-local-dcq; > if (thread-local-dcq is not full) goto done; > > call runtime to move thread-local-dcq into dcqs > > done: > > > Overall this post-write barrier alone is in the range of 40-50 total instructions, compared to three or four(!) for parallel and serial gc. > > The large size of the inlined barrier not only has a large code footprint, but also prevents some compiler optimizations like loop unrolling or inlining. > > There are several papers showing that this barrier alone can decrease throughput by 10-20% ([Yang12](https://dl.acm.org/doi/10.1145/2426642.2259004)), which is corroborated by some benchmarks (see links). > > The main idea for this change is to not use fine-grained synchronization between refinement and mutator threads, but coarse grained based on atomically switching card tables. Mutators only work on the "primary" card table, refinement threads on a se... Thomas Schatzl has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 57 commits: - Merge branch 'master' into 8342382-card-table-instead-of-dcq - Merge branch 'master' into 8342382-card-table-instead-of-dcq - Merge branch 'master' into 8342382-card-table-instead-of-dcq - Merge branch 'master' into 8342382-card-table-instead-of-dcq - * ayang review: remove sweep_epoch - Merge branch 'master' into card-table-as-dcq-merge - Merge branch 'master' into 8342382-card-table-instead-of-dcq - * ayang review (part 2 - yield duration changes) - * ayang review (part 1) - * indentation fix - ... and 47 more: https://git.openjdk.org/jdk/compare/d75ea7e6...441c234a ------------- Changes: https://git.openjdk.org/jdk/pull/23739/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=23739&range=40 Stats: 7121 lines in 112 files changed: 2585 ins; 3590 del; 946 mod Patch: https://git.openjdk.org/jdk/pull/23739.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/23739/head:pull/23739 PR: https://git.openjdk.org/jdk/pull/23739 From duke at openjdk.org Mon Jul 7 13:07:55 2025 From: duke at openjdk.org (Andrej =?UTF-8?B?UGXEjWltw7p0aA==?=) Date: Mon, 7 Jul 2025 13:07:55 GMT Subject: RFR: 8357689: Refactor JVMCI to enable replay compilation in Graal Message-ID: This PR introduces a few minor JVMCI refactorings to make replay compilation possible in the Graal compiler. ------------- Commit messages: - Remove an unused import. - Use a pattern variable. - use list when applicable - JVMCI refactorings to enable replay compilation in Graal. Changes: https://git.openjdk.org/jdk/pull/25433/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=25433&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8357689 Stats: 434 lines in 21 files changed: 310 ins; 8 del; 116 mod Patch: https://git.openjdk.org/jdk/pull/25433.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/25433/head:pull/25433 PR: https://git.openjdk.org/jdk/pull/25433 From dnsimon at openjdk.org Mon Jul 7 13:07:56 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Mon, 7 Jul 2025 13:07:56 GMT Subject: RFR: 8357689: Refactor JVMCI to enable replay compilation in Graal In-Reply-To: References: Message-ID: On Sat, 24 May 2025 16:49:23 GMT, Andrej Pe?im?th wrote: > This PR introduces a few minor JVMCI refactorings to make replay compilation possible in the Graal compiler. src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/BytecodeFrame.java line 397: > 395: * @return a copy of the slot kinds array > 396: */ > 397: public JavaKind[] getSlotKinds() { Keep in mind that `slotKinds` is being [converted](https://github.com/openjdk/jdk/pull/25442/files#diff-43834727ed7dcd5128c10238ba56963c7d8feb66578b036c75dcf734bfa2ec92R80) to a List. In that context, can we return the list without making a copy? Or is the caller expected to be able to mutate the return value? src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/VirtualObject.java line 293: > 291: return true; > 292: } > 293: if (o instanceof VirtualObject) { Rename `l` to `that` and use pattern instanceof: Suggestion: if (o instanceof VirtualObject that) { src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/VirtualObject.java line 325: > 323: * values have not been initialized. > 324: */ > 325: public JavaKind[] getSlotKinds() { Same comments as for BytecodeFrame.getSlotKinds. This applies to all other non-primitive array return values added by this PR. src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompiledCode.java line 225: > 223: * Returns a copy of the array of {@link ResolvedJavaMethod} objects representing the methods > 224: * whose bytecodes were used as input to the compilation. If the compilation did not record > 225: * method dependencies, this method returns {@code null}. Otherwise, the first element of the null -> empty list? ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25433#discussion_r2109017920 PR Review Comment: https://git.openjdk.org/jdk/pull/25433#discussion_r2109025913 PR Review Comment: https://git.openjdk.org/jdk/pull/25433#discussion_r2109034172 PR Review Comment: https://git.openjdk.org/jdk/pull/25433#discussion_r2109040017 From duke at openjdk.org Mon Jul 7 13:07:56 2025 From: duke at openjdk.org (Andrej =?UTF-8?B?UGXEjWltw7p0aA==?=) Date: Mon, 7 Jul 2025 13:07:56 GMT Subject: RFR: 8357689: Refactor JVMCI to enable replay compilation in Graal In-Reply-To: References: Message-ID: On Tue, 27 May 2025 12:10:29 GMT, Doug Simon wrote: >> This PR introduces a few minor JVMCI refactorings to make replay compilation possible in the Graal compiler. > > src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/BytecodeFrame.java line 397: > >> 395: * @return a copy of the slot kinds array >> 396: */ >> 397: public JavaKind[] getSlotKinds() { > > Keep in mind that `slotKinds` is being [converted](https://github.com/openjdk/jdk/pull/25442/files#diff-43834727ed7dcd5128c10238ba56963c7d8feb66578b036c75dcf734bfa2ec92R80) to a List. In that context, can we return the list without making a copy? Or is the caller expected to be able to mutate the return value? Applied the changes provided by @mur47x111. > src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/VirtualObject.java line 325: > >> 323: * values have not been initialized. >> 324: */ >> 325: public JavaKind[] getSlotKinds() { > > Same comments as for BytecodeFrame.getSlotKinds. This applies to all other non-primitive array return values added by this PR. I left `Object[]` as the return value of `EncodedSpeculationReason#getReason` since the array could contain null elements, preventing the use of an immutable list like everywhere else. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25433#discussion_r2189993024 PR Review Comment: https://git.openjdk.org/jdk/pull/25433#discussion_r2190003945 From darcy at openjdk.org Mon Jul 7 18:03:40 2025 From: darcy at openjdk.org (Joe Darcy) Date: Mon, 7 Jul 2025 18:03:40 GMT Subject: RFR: 8360559: Optimize Math.sinh for x86 64 bit platforms In-Reply-To: References: Message-ID: On Mon, 7 Jul 2025 03:05:15 GMT, Mohamed Issa wrote: > The goal of this PR is to implement an x86_64 intrinsic for java.lang.Math.sinh() using libm. There is a new set of micro-benchmarks are included to check the performance of specific input value ranges to help prevent regressions in the future. > > The command to run all range specific micro-benchmarks is posted below. > > `make test TEST="micro:SinhPerf.SinhPerfRanges"` > > The results of all tests posted below were captured with an [Intel? Xeon 8488C](https://advisor.cloudzero.com/aws/ec2/r7i.metal-24xl) using [OpenJDK v26-b4](https://github.com/openjdk/jdk/releases/tag/jdk-26%2B4) as the baseline version. > > For performance data collected with the new built in range micro-benchmark, see the table below. Each result is the mean of 8 individual runs, and the input ranges used match those from the original Java implementation. Overall, the intrinsic provides an an average uplift of 64% when input values fall into the middle three ranges where heavy computation is required. However, very small inputs and very large inputs show drops of 74% and 66% respectively. > > | Input range(s) | Baseline throughput (ops/ms) | Intrinsic throughput (ops/ms) | Speedup | > | :------------------------------------: | :-------------------------------: | :--------------------------------: | :--------: | > | [-2^(-28), 2^(-28)] | 844160 | 216029 | 0.26x | > | [-22, -2^(-28)], [2^(-28), 22] | 81662 | 157351 | 1.93x | > | [-709.78, -22], [22, 709.78] | 119075 | 167635 | 1.41x | > | [-710.48, -709.78], [709.78, 710.48] | 111636 | 177125 | 1.59x | > | (-INF, -710.48], [710.48, INF) | 959296 | 313839 | 0.33x | > > Finally, the `jtreg:test/jdk/java/lang/Math/HyperbolicTests.java` test passed with the changes. Are there plans for a cosh intrinsic as follow-up work? There was a previous effort to intrinsify tanh. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26152#issuecomment-3046086649 From darcy at openjdk.org Mon Jul 7 18:06:39 2025 From: darcy at openjdk.org (Joe Darcy) Date: Mon, 7 Jul 2025 18:06:39 GMT Subject: RFR: 8360559: Optimize Math.sinh for x86 64 bit platforms In-Reply-To: References: Message-ID: On Mon, 7 Jul 2025 03:05:15 GMT, Mohamed Issa wrote: > The goal of this PR is to implement an x86_64 intrinsic for java.lang.Math.sinh() using libm. There is a new set of micro-benchmarks are included to check the performance of specific input value ranges to help prevent regressions in the future. > > The command to run all range specific micro-benchmarks is posted below. > > `make test TEST="micro:SinhPerf.SinhPerfRanges"` > > The results of all tests posted below were captured with an [Intel? Xeon 8488C](https://advisor.cloudzero.com/aws/ec2/r7i.metal-24xl) using [OpenJDK v26-b4](https://github.com/openjdk/jdk/releases/tag/jdk-26%2B4) as the baseline version. > > For performance data collected with the new built in range micro-benchmark, see the table below. Each result is the mean of 8 individual runs, and the input ranges used match those from the original Java implementation. Overall, the intrinsic provides an an average uplift of 64% when input values fall into the middle three ranges where heavy computation is required. However, very small inputs and very large inputs show drops of 74% and 66% respectively. > > | Input range(s) | Baseline throughput (ops/ms) | Intrinsic throughput (ops/ms) | Speedup | > | :------------------------------------: | :-------------------------------: | :--------------------------------: | :--------: | > | [-2^(-28), 2^(-28)] | 844160 | 216029 | 0.26x | > | [-22, -2^(-28)], [2^(-28), 22] | 81662 | 157351 | 1.93x | > | [-709.78, -22], [22, 709.78] | 119075 | 167635 | 1.41x | > | [-710.48, -709.78], [709.78, 710.48] | 111636 | 177125 | 1.59x | > | (-INF, -710.48], [710.48, INF) | 959296 | 313839 | 0.33x | > > Finally, the `jtreg:test/jdk/java/lang/Math/HyperbolicTests.java` test passed with the changes. A large fraction of floating-point numbers are in the [-2^(-28), 2^(-28)] range where there is a performance degradation with the new implementation. What is the expected distribution of arguments to sinh? ------------- PR Comment: https://git.openjdk.org/jdk/pull/26152#issuecomment-3046093111 From missa at openjdk.org Mon Jul 7 23:36:39 2025 From: missa at openjdk.org (Mohamed Issa) Date: Mon, 7 Jul 2025 23:36:39 GMT Subject: RFR: 8360559: Optimize Math.sinh for x86 64 bit platforms In-Reply-To: References: Message-ID: On Mon, 7 Jul 2025 18:03:54 GMT, Joe Darcy wrote: > A large fraction of floating-point numbers are in the [-2^(-28), 2^(-28)] range where there is a performance degradation with the new implementation. > > What is the expected distribution of arguments to sinh? I don't know about an expected distribution of distribution of arguments to sinh. From glancing through research papers though, I get the sense that the [-2^(-28), 2^(-28)] range isn't used all that much. A couple of papers showing this are linked below. 1. [An Analysis of the Hyperbolic Bid Stacking Technique's Use in Modeling Power Prices](https://dl.acm.org/doi/10.1145/3640115.3640182) 2. [Experimental Validation of a 3GPP compliant 5G-based Positioning System](https://dl.acm.org/doi/10.1145/3636534.3697324) I think the [-2^(-28), 2^(-28)] range isn't all that interesting for sinh anyway as it just returns the input itself. So, I doubt any applications are relying all that heavily on it. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26152#issuecomment-3046818744 From missa at openjdk.org Mon Jul 7 23:47:38 2025 From: missa at openjdk.org (Mohamed Issa) Date: Mon, 7 Jul 2025 23:47:38 GMT Subject: RFR: 8360559: Optimize Math.sinh for x86 64 bit platforms In-Reply-To: References: Message-ID: On Mon, 7 Jul 2025 18:01:26 GMT, Joe Darcy wrote: > Are there plans for a cosh intrinsic as follow-up work? There was a previous effort to intrinsify tanh. Yes, the intention is to have cosh as next math intrinsic. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26152#issuecomment-3046847281 From missa at openjdk.org Mon Jul 7 23:55:39 2025 From: missa at openjdk.org (Mohamed Issa) Date: Mon, 7 Jul 2025 23:55:39 GMT Subject: RFR: 8360559: Optimize Math.sinh for x86 64 bit platforms In-Reply-To: References: Message-ID: On Mon, 7 Jul 2025 04:48:18 GMT, Florian Weimer wrote: > Isn't this effectively a libm benchmark (where the `sinh` implementation resides)? Please include the libm version for reference here. Thanks. I'm not sure which libm version you're referring to. The only current sinh benchmark I'm aware of is in MathBench.java, and the benchmarks in SinhPerf.java didn't exist until now. Could you clarify? ------------- PR Comment: https://git.openjdk.org/jdk/pull/26152#issuecomment-3046866329 From duke at openjdk.org Tue Jul 8 08:41:59 2025 From: duke at openjdk.org (Andrej =?UTF-8?B?UGXEjWltw7p0aA==?=) Date: Tue, 8 Jul 2025 08:41:59 GMT Subject: RFR: 8357689: Refactor JVMCI to enable replay compilation in Graal [v2] In-Reply-To: References: Message-ID: > This PR introduces a few minor JVMCI refactorings to make replay compilation possible in the Graal compiler. Andrej Pe?im?th has refreshed the contents of this pull request, and previous commits have been removed. The incremental views will show differences compared to the previous content of the PR. The pull request contains one new commit since the last revision: JVMCI refactorings to enable replay compilation in Graal. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/25433/files - new: https://git.openjdk.org/jdk/pull/25433/files/c12f507c..c6c3bb62 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=25433&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=25433&range=00-01 Stats: 204 lines in 10 files changed: 3 ins; 88 del; 113 mod Patch: https://git.openjdk.org/jdk/pull/25433.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/25433/head:pull/25433 PR: https://git.openjdk.org/jdk/pull/25433 From duke at openjdk.org Tue Jul 8 08:41:59 2025 From: duke at openjdk.org (Andrej =?UTF-8?B?UGXEjWltw7p0aA==?=) Date: Tue, 8 Jul 2025 08:41:59 GMT Subject: RFR: 8357689: Refactor JVMCI to enable replay compilation in Graal [v2] In-Reply-To: References: Message-ID: On Tue, 8 Jul 2025 08:37:53 GMT, Andrej Pe?im?th wrote: >> This PR introduces a few minor JVMCI refactorings to make replay compilation possible in the Graal compiler. > > Andrej Pe?im?th has refreshed the contents of this pull request, and previous commits have been removed. The incremental views will show differences compared to the previous content of the PR. The pull request contains one new commit since the last revision: > > JVMCI refactorings to enable replay compilation in Graal. src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/code/BytecodeFrame.java line 227: > 225: this.duringCall = duringCall; > 226: this.values = values; > 227: this.slotKinds = listFromTrustedArray(slotKinds); `ImmutableCollections#listFromTrustedArray` asserts that the array class is `Object[].class`, but the type of `slotKinds` is `JavaKind[]` - so these refactorings do not work. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25433#discussion_r2190153203 From mchevalier at openjdk.org Tue Jul 8 13:38:26 2025 From: mchevalier at openjdk.org (Marc Chevalier) Date: Tue, 8 Jul 2025 13:38:26 GMT Subject: RFR: 8359344: C2: Malformed control flow after intrinsic bailout [v3] In-Reply-To: References: Message-ID: > When intrinsic bailout, we assume that the control in the `LibraryCallKit` did not change: > > https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L137 > > This is enforced by restoring the old state, like in > > https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L1722-L1732 > > That is good, but not sufficient. First, the most obvious, one could have already built some structure without moving the control. For instance, we can obtain something such as: > > ![1 after-intrinsic-bailout-during-late-inlining](https://github.com/user-attachments/assets/2fd255cc-0bfc-4841-8dd1-f64d502e0ee1) > > > Here, during late inlining, the call `323` is candidate to be inline, but that bails out. Yet, a call to `make_unsafe_address` was made, which built nodes `354 If` and everything under. This is needed as tests are made on the resulting nodes (especially `366 AddP`) to know whether we should bail out or not. At the end, we get 2 control successor to `346 IfFalse`: the call that is not removed and the leftover of the intrinsic that will be cleanup much later, but not by RemoveUseless. > > Another situation is somewhat worse, when happening during parsing. It can lead to such cases: > > ![2 after-intrinsic-bailout-during-parsing](https://github.com/user-attachments/assets/4524c615-6521-4f0d-8f61-c426f9179035) > > The nodes `31 OpaqueNotNull`, `31 If`, `36 IfTrue`, `33 IfFalse`, `35 Halt`, `44 If`, `45 IfTrue`, `46 IfFalse` are leftover from a bailing out intrinsic. The replacement call `49 CallStaticJava` should come just under `5 Parm`, but the control was updated and the call is actually built under `36 If`. Then, why does the previous assert doesn't complain? > > This is because there is more than one control, or one map. In intrinsics that need to restore their state, the initial `SafePoint` map is cloned, the clone is kept aside, and if needed (bailing out), we set the current map to this saved clone. But there is another map from which the one of the `LibraryCallKit` comes, and that survives longer, it's the one that is contained in the `JVMState`: > > https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L101-L102 > > And here there is the challenge: > - the `JVMState jvms` contains a `SafePoint` map, this map must have `jvms` as `jvms` (pointer comparison) > - we can't really change the pointer, just the content > -... Marc Chevalier has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains nine commits: - Merge remote-tracking branch 'origin/master' into fix/too-many-ctrl-successor-after-intrinsic - Address comments - Remove useless loop - whoops Forgot to remove a bit, and restore sp - Urgh - Adapt test - Re-try - Fix test - Trying something ------------- Changes: https://git.openjdk.org/jdk/pull/25936/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=25936&range=02 Stats: 349 lines in 7 files changed: 230 ins; 50 del; 69 mod Patch: https://git.openjdk.org/jdk/pull/25936.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/25936/head:pull/25936 PR: https://git.openjdk.org/jdk/pull/25936 From mchevalier at openjdk.org Tue Jul 8 13:38:26 2025 From: mchevalier at openjdk.org (Marc Chevalier) Date: Tue, 8 Jul 2025 13:38:26 GMT Subject: RFR: 8359344: C2: Malformed control flow after intrinsic bailout [v2] In-Reply-To: References: <1cFRkcs5JmgnbWEIaEoT8I9RiUtNxgKieAdkSB2Fgmc=.1d97b5c4-b6ef-43c6-b721-1e52eee19d3a@github.com> Message-ID: On Mon, 7 Jul 2025 07:28:37 GMT, Tobias Hartmann wrote: >> Marc Chevalier has updated the pull request incrementally with one additional commit since the last revision: >> >> Remove useless loop > > src/hotspot/share/opto/library_call.cpp line 2376: > >> 2374: state.map = clone_map(); >> 2375: for (DUIterator_Fast imax, i = control()->fast_outs(imax); i < imax; i++) { >> 2376: Node* out = control()->fast_out(i); > > Could we have a similar issue with non-control users? For example, couldn't we also have stray memory users after bailout? We could, but it should be relatively harmless. Control is more annoying to have more than one successor. > src/hotspot/share/opto/library_call.cpp line 2393: > >> 2391: Node* out = control()->fast_out(i); >> 2392: if (out->is_CFG() && out->in(0) == control() && out != map() && !state.ctrl_succ.member(out)) { >> 2393: out->set_req(0, C->top()); > > Could `out` already be in the GVN hash ("remove node from hash table before modifying it")? I've added it, since indeed, it could. As far as I understand, I was just lucky in the situation where it happens, but there is no reason it would always hold. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25936#discussion_r2192553330 PR Review Comment: https://git.openjdk.org/jdk/pull/25936#discussion_r2192556138 From mchevalier at openjdk.org Tue Jul 8 13:44:45 2025 From: mchevalier at openjdk.org (Marc Chevalier) Date: Tue, 8 Jul 2025 13:44:45 GMT Subject: RFR: 8359344: C2: Malformed control flow after intrinsic bailout [v2] In-Reply-To: References: <1cFRkcs5JmgnbWEIaEoT8I9RiUtNxgKieAdkSB2Fgmc=.1d97b5c4-b6ef-43c6-b721-1e52eee19d3a@github.com> Message-ID: <053aI6bIhjDWZgWQSx_KRGcDzAxg2DF86WNVBco2DkA=.7ccf19bf-3fa7-471d-929c-d20f01006235@github.com> On Mon, 7 Jul 2025 07:18:11 GMT, Tobias Hartmann wrote: >> Marc Chevalier has updated the pull request incrementally with one additional commit since the last revision: >> >> Remove useless loop > > src/hotspot/share/opto/library_call.cpp line 1732: > >> 1730: return false; >> 1731: } >> 1732: destruct_map_clone(old_state.map); > > I think `destruct_map_clone` could be refactored to take a `SavedState`. I've made an override of destruct_map_clone taking a SavedState (and delegating to the existing one) rather than changing the existing one for the following reasons: - `destruct_map_clone` is in `GraphKit` so doesn't know about `SavedState`. Either I'd need to bring `SavedState` to the base class (useless visibility) (or something with forward declarations...) or move `destruct_map_clone` to the derived class `LibraryCallKit` - `destruct_map_clone` makes sense to have next to `clone_map`. But `clone_map` is used also in `GraphKit`, so not possible to move to the derived class - The existing `destruct_map_clone` doesn't need a `SavedState` and makes sense without. Requiring more information just make it less usable, but it's fine to have a thin adapter that one can by-pass if one has a `SafePointNode` and not a whole `SavedState`. > test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java line 104: > >> 102: public static final String START = "(\\d+(\\s){2}("; >> 103: public static final String MID = ".*)+(\\s){2}===.*"; >> 104: public static final String END = ")"; > > I don't like exposing these outside the IR framework but then again I don't really have an idea on how to check the "graph should not have both nodes" invariant. Maybe we should extend the `counts` annotation to support something like `@IR(counts = {IRNode.CallStaticJava, IRNode.OpaqueNotNull, "<= 1"} [...]`? As discussed, I now have a JBS issue about this, and I factored the duplicated regex into a single final String with name and comment. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25936#discussion_r2192570629 PR Review Comment: https://git.openjdk.org/jdk/pull/25936#discussion_r2192574207 From mchevalier at openjdk.org Tue Jul 8 13:53:25 2025 From: mchevalier at openjdk.org (Marc Chevalier) Date: Tue, 8 Jul 2025 13:53:25 GMT Subject: RFR: 8359344: C2: Malformed control flow after intrinsic bailout [v4] In-Reply-To: References: Message-ID: > When intrinsic bailout, we assume that the control in the `LibraryCallKit` did not change: > > https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L137 > > This is enforced by restoring the old state, like in > > https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L1722-L1732 > > That is good, but not sufficient. First, the most obvious, one could have already built some structure without moving the control. For instance, we can obtain something such as: > > ![1 after-intrinsic-bailout-during-late-inlining](https://github.com/user-attachments/assets/2fd255cc-0bfc-4841-8dd1-f64d502e0ee1) > > > Here, during late inlining, the call `323` is candidate to be inline, but that bails out. Yet, a call to `make_unsafe_address` was made, which built nodes `354 If` and everything under. This is needed as tests are made on the resulting nodes (especially `366 AddP`) to know whether we should bail out or not. At the end, we get 2 control successor to `346 IfFalse`: the call that is not removed and the leftover of the intrinsic that will be cleanup much later, but not by RemoveUseless. > > Another situation is somewhat worse, when happening during parsing. It can lead to such cases: > > ![2 after-intrinsic-bailout-during-parsing](https://github.com/user-attachments/assets/4524c615-6521-4f0d-8f61-c426f9179035) > > The nodes `31 OpaqueNotNull`, `31 If`, `36 IfTrue`, `33 IfFalse`, `35 Halt`, `44 If`, `45 IfTrue`, `46 IfFalse` are leftover from a bailing out intrinsic. The replacement call `49 CallStaticJava` should come just under `5 Parm`, but the control was updated and the call is actually built under `36 If`. Then, why does the previous assert doesn't complain? > > This is because there is more than one control, or one map. In intrinsics that need to restore their state, the initial `SafePoint` map is cloned, the clone is kept aside, and if needed (bailing out), we set the current map to this saved clone. But there is another map from which the one of the `LibraryCallKit` comes, and that survives longer, it's the one that is contained in the `JVMState`: > > https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L101-L102 > > And here there is the challenge: > - the `JVMState jvms` contains a `SafePoint` map, this map must have `jvms` as `jvms` (pointer comparison) > - we can't really change the pointer, just the content > -... Marc Chevalier has updated the pull request incrementally with one additional commit since the last revision: Somehow intellij doesn't remove empty indented line ------------- Changes: - all: https://git.openjdk.org/jdk/pull/25936/files - new: https://git.openjdk.org/jdk/pull/25936/files/e57cf47f..09b24ec4 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=25936&range=03 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=25936&range=02-03 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/25936.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/25936/head:pull/25936 PR: https://git.openjdk.org/jdk/pull/25936 From mchevalier at openjdk.org Tue Jul 8 13:56:39 2025 From: mchevalier at openjdk.org (Marc Chevalier) Date: Tue, 8 Jul 2025 13:56:39 GMT Subject: RFR: 8359344: C2: Malformed control flow after intrinsic bailout [v4] In-Reply-To: References: Message-ID: On Tue, 8 Jul 2025 13:53:25 GMT, Marc Chevalier wrote: >> When intrinsic bailout, we assume that the control in the `LibraryCallKit` did not change: >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L137 >> >> This is enforced by restoring the old state, like in >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L1722-L1732 >> >> That is good, but not sufficient. First, the most obvious, one could have already built some structure without moving the control. For instance, we can obtain something such as: >> >> ![1 after-intrinsic-bailout-during-late-inlining](https://github.com/user-attachments/assets/2fd255cc-0bfc-4841-8dd1-f64d502e0ee1) >> >> >> Here, during late inlining, the call `323` is candidate to be inline, but that bails out. Yet, a call to `make_unsafe_address` was made, which built nodes `354 If` and everything under. This is needed as tests are made on the resulting nodes (especially `366 AddP`) to know whether we should bail out or not. At the end, we get 2 control successor to `346 IfFalse`: the call that is not removed and the leftover of the intrinsic that will be cleanup much later, but not by RemoveUseless. >> >> Another situation is somewhat worse, when happening during parsing. It can lead to such cases: >> >> ![2 after-intrinsic-bailout-during-parsing](https://github.com/user-attachments/assets/4524c615-6521-4f0d-8f61-c426f9179035) >> >> The nodes `31 OpaqueNotNull`, `31 If`, `36 IfTrue`, `33 IfFalse`, `35 Halt`, `44 If`, `45 IfTrue`, `46 IfFalse` are leftover from a bailing out intrinsic. The replacement call `49 CallStaticJava` should come just under `5 Parm`, but the control was updated and the call is actually built under `36 If`. Then, why does the previous assert doesn't complain? >> >> This is because there is more than one control, or one map. In intrinsics that need to restore their state, the initial `SafePoint` map is cloned, the clone is kept aside, and if needed (bailing out), we set the current map to this saved clone. But there is another map from which the one of the `LibraryCallKit` comes, and that survives longer, it's the one that is contained in the `JVMState`: >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L101-L102 >> >> And here there is the challenge: >> - the `JVMState jvms` contains a `SafePoint` map, this map must have `jvms` as `jvms` (pointer comparison) >> ... > > Marc Chevalier has updated the pull request incrementally with one additional commit since the last revision: > > Somehow intellij doesn't remove empty indented line I've addressed the comments, ready for a second pass! ------------- PR Comment: https://git.openjdk.org/jdk/pull/25936#issuecomment-3049067672 From mchevalier at openjdk.org Tue Jul 8 14:26:28 2025 From: mchevalier at openjdk.org (Marc Chevalier) Date: Tue, 8 Jul 2025 14:26:28 GMT Subject: RFR: 8347901: C2 should remove unused leaf / pure runtime calls [v4] In-Reply-To: References: Message-ID: > A first part toward a better support of pure functions, but this time, with guidance from @iwanowww. > > ## Pure Functions > > Pure functions (considered here) are functions that have no side effects, no effect on the control flow (no exception or such), cannot deopt etc.. It's really a function that you can execute anywhere, with whichever arguments without effect other than wasting time. Integer division is not pure as dividing by zero is throwing. But many floating point functions will just return `NaN` or `+/-infinity` in problematic cases. > > ## Scope > > We are not going all powerful for now! It's mostly about identifying some pure functions and being able to remove them if the result is unused. Some other things are not part of this PR, on purpose. Especially, this PR doesn't propose a way to move pure calls around. The reason is that pure calls are later expanded into regular calls, which require a control input. To be able to do the expansion, we just keep the control in the pure call as well. > > ## Implementation Overview > > We created here some new node kind for pure calls, inheriting leaf calls, that are expanded into regular leaf calls during final graph reshaping. The possibility to support pure call directly in AD file is left open. > > This PR also introduces `TupleNode` (largely based on an original idea/implem of @iwanowww), that just tie multiple input together and play well with `ProjNode`: the n-th projection of a `TupleNode` is the n-th input of the tuple. This is a convenient way to skip and remove nodes from the graph while delegating the difficulty of the surgery to the trusted IGVN's implementation. > > Thanks, > Marc Marc Chevalier has updated the pull request incrementally with one additional commit since the last revision: typo ------------- Changes: - all: https://git.openjdk.org/jdk/pull/25760/files - new: https://git.openjdk.org/jdk/pull/25760/files/7028b561..7f18c9f6 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=25760&range=03 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=25760&range=02-03 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/25760.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/25760/head:pull/25760 PR: https://git.openjdk.org/jdk/pull/25760 From mchevalier at openjdk.org Tue Jul 8 14:26:29 2025 From: mchevalier at openjdk.org (Marc Chevalier) Date: Tue, 8 Jul 2025 14:26:29 GMT Subject: RFR: 8347901: C2 should remove unused leaf / pure runtime calls [v3] In-Reply-To: References: Message-ID: On Mon, 7 Jul 2025 07:53:24 GMT, Tobias Hartmann wrote: >> Marc Chevalier has updated the pull request incrementally with one additional commit since the last revision: >> >> mostly comments > > src/hotspot/share/opto/divnode.cpp line 1522: > >> 1520: Node* super = CallLeafPureNode::Ideal(phase, can_reshape); >> 1521: if (super != nullptr) { >> 1522: return super; > > Can't we just do `return CallLeafPureNode::Ideal(phase, can_reshape);` at the end of `ModFNode::Ideal` instead of `return nullptr`? That's what we usually do in C2, for example in `CallStaticJavaNode::Ideal` -> `CallNode::Ideal`. Feels more natural to me and would avoid the `super != nullptr` check. Also for the other `Ideal` methods that you modified. We could but it's not that direct. `ModFNode::Ideal` has 6 `return`s (without mine): - 3 are `return replace_with_con(...);` which in their turn return `nullptr` but after making changes in the graph. - 2 are `return nullptr;` - 1 is actually returning a node. And especially the final one is return replace_with_con(igvn, TypeF::make(jfloat_cast(xr))); If we change `replace_with_con` to actually return a `TupleNode` to do the job, we still have 2 places where to call the base class' `Ideal`. So I'm not sure how much better it would be to duplicate the call. It also adds a maintenance burden: if one adds another case where we don't want to make changes, one needs to add another call to `CallLeafPureNode::Ideal`. I think it's because of the structure of this function: rather than selecting cases where we want to do something and reaching the end with only the leftover cases, we select the cases we don't want to continue with, and we return early, making more cases where we should call the super method. I'll try something. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25760#discussion_r2192664653 From mchevalier at openjdk.org Tue Jul 8 14:26:29 2025 From: mchevalier at openjdk.org (Marc Chevalier) Date: Tue, 8 Jul 2025 14:26:29 GMT Subject: RFR: 8347901: C2 should remove unused leaf / pure runtime calls [v4] In-Reply-To: References: Message-ID: On Mon, 7 Jul 2025 08:30:00 GMT, Tobias Hartmann wrote: >> Marc Chevalier has updated the pull request incrementally with one additional commit since the last revision: >> >> typo > > src/hotspot/share/opto/divnode.cpp line 1528: > >> 1526: bool not_dead = proj_out_or_null(TypeFunc::Control) != nullptr; >> 1527: if (result_is_unused && not_dead) { >> 1528: return replace_with_con(igvn, TypeF::make(0.)); > > Can we replace all the other usages of `ModFloatingNode::replace_with_con` by `TupleNode` and get rid of that method? Yes, that sounds like a good idea. One still need to build the right `TupleNode`, which takes a bit of code. So in detail, I'd rather replace `replace_with_con` with a function returning the right `TupleNode` to be as concise on the call-site. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25760#discussion_r2192669986 From thartmann at openjdk.org Tue Jul 8 15:13:40 2025 From: thartmann at openjdk.org (Tobias Hartmann) Date: Tue, 8 Jul 2025 15:13:40 GMT Subject: RFR: 8359344: C2: Malformed control flow after intrinsic bailout [v2] In-Reply-To: References: <1cFRkcs5JmgnbWEIaEoT8I9RiUtNxgKieAdkSB2Fgmc=.1d97b5c4-b6ef-43c6-b721-1e52eee19d3a@github.com> Message-ID: On Tue, 8 Jul 2025 13:35:27 GMT, Marc Chevalier wrote: >> src/hotspot/share/opto/library_call.cpp line 2393: >> >>> 2391: Node* out = control()->fast_out(i); >>> 2392: if (out->is_CFG() && out->in(0) == control() && out != map() && !state.ctrl_succ.member(out)) { >>> 2393: out->set_req(0, C->top()); >> >> Could `out` already be in the GVN hash ("remove node from hash table before modifying it")? > > I've added it, since indeed, it could. As far as I understand, I was just lucky in the situation where it happens, but there is no reason it would always hold. I think you also need to re-insert it via `hash_find_insert`. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25936#discussion_r2192795199 From thartmann at openjdk.org Tue Jul 8 15:16:42 2025 From: thartmann at openjdk.org (Tobias Hartmann) Date: Tue, 8 Jul 2025 15:16:42 GMT Subject: RFR: 8359344: C2: Malformed control flow after intrinsic bailout [v4] In-Reply-To: References: Message-ID: On Tue, 8 Jul 2025 13:53:25 GMT, Marc Chevalier wrote: >> When intrinsic bailout, we assume that the control in the `LibraryCallKit` did not change: >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L137 >> >> This is enforced by restoring the old state, like in >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L1722-L1732 >> >> That is good, but not sufficient. First, the most obvious, one could have already built some structure without moving the control. For instance, we can obtain something such as: >> >> ![1 after-intrinsic-bailout-during-late-inlining](https://github.com/user-attachments/assets/2fd255cc-0bfc-4841-8dd1-f64d502e0ee1) >> >> >> Here, during late inlining, the call `323` is candidate to be inline, but that bails out. Yet, a call to `make_unsafe_address` was made, which built nodes `354 If` and everything under. This is needed as tests are made on the resulting nodes (especially `366 AddP`) to know whether we should bail out or not. At the end, we get 2 control successor to `346 IfFalse`: the call that is not removed and the leftover of the intrinsic that will be cleanup much later, but not by RemoveUseless. >> >> Another situation is somewhat worse, when happening during parsing. It can lead to such cases: >> >> ![2 after-intrinsic-bailout-during-parsing](https://github.com/user-attachments/assets/4524c615-6521-4f0d-8f61-c426f9179035) >> >> The nodes `31 OpaqueNotNull`, `31 If`, `36 IfTrue`, `33 IfFalse`, `35 Halt`, `44 If`, `45 IfTrue`, `46 IfFalse` are leftover from a bailing out intrinsic. The replacement call `49 CallStaticJava` should come just under `5 Parm`, but the control was updated and the call is actually built under `36 If`. Then, why does the previous assert doesn't complain? >> >> This is because there is more than one control, or one map. In intrinsics that need to restore their state, the initial `SafePoint` map is cloned, the clone is kept aside, and if needed (bailing out), we set the current map to this saved clone. But there is another map from which the one of the `LibraryCallKit` comes, and that survives longer, it's the one that is contained in the `JVMState`: >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L101-L102 >> >> And here there is the challenge: >> - the `JVMState jvms` contains a `SafePoint` map, this map must have `jvms` as `jvms` (pointer comparison) >> ... > > Marc Chevalier has updated the pull request incrementally with one additional commit since the last revision: > > Somehow intellij doesn't remove empty indented line src/hotspot/share/opto/library_call.cpp line 2507: > 2505: > 2506: if (alias_type->adr_type() == TypeInstPtr::KLASS || > 2507: alias_type->adr_type() == TypeAryPtr::RANGE) { The indentation is off here. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25936#discussion_r2192803477 From thartmann at openjdk.org Tue Jul 8 15:16:44 2025 From: thartmann at openjdk.org (Tobias Hartmann) Date: Tue, 8 Jul 2025 15:16:44 GMT Subject: RFR: 8359344: C2: Malformed control flow after intrinsic bailout [v2] In-Reply-To: <053aI6bIhjDWZgWQSx_KRGcDzAxg2DF86WNVBco2DkA=.7ccf19bf-3fa7-471d-929c-d20f01006235@github.com> References: <1cFRkcs5JmgnbWEIaEoT8I9RiUtNxgKieAdkSB2Fgmc=.1d97b5c4-b6ef-43c6-b721-1e52eee19d3a@github.com> <053aI6bIhjDWZgWQSx_KRGcDzAxg2DF86WNVBco2DkA=.7ccf19bf-3fa7-471d-929c-d20f01006235@github.com> Message-ID: <5ezM7iZKoLDPycAuRWgVXAIOQ2d9ukvK28kxE7dklDE=.1740e1e7-5482-4239-99bf-75edecd41e6a@github.com> On Tue, 8 Jul 2025 13:42:14 GMT, Marc Chevalier wrote: >> test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java line 104: >> >>> 102: public static final String START = "(\\d+(\\s){2}("; >>> 103: public static final String MID = ".*)+(\\s){2}===.*"; >>> 104: public static final String END = ")"; >> >> I don't like exposing these outside the IR framework but then again I don't really have an idea on how to check the "graph should not have both nodes" invariant. Maybe we should extend the `counts` annotation to support something like `@IR(counts = {IRNode.CallStaticJava, IRNode.OpaqueNotNull, "<= 1"} [...]`? > > As discussed, I now have a JBS issue about this, and I factored the duplicated regex into a single final String with name and comment. Thanks, that looks good! ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25936#discussion_r2192804630 From thartmann at openjdk.org Tue Jul 8 15:19:43 2025 From: thartmann at openjdk.org (Tobias Hartmann) Date: Tue, 8 Jul 2025 15:19:43 GMT Subject: RFR: 8347901: C2 should remove unused leaf / pure runtime calls [v3] In-Reply-To: References: Message-ID: On Tue, 8 Jul 2025 14:19:23 GMT, Marc Chevalier wrote: >> src/hotspot/share/opto/divnode.cpp line 1522: >> >>> 1520: Node* super = CallLeafPureNode::Ideal(phase, can_reshape); >>> 1521: if (super != nullptr) { >>> 1522: return super; >> >> Can't we just do `return CallLeafPureNode::Ideal(phase, can_reshape);` at the end of `ModFNode::Ideal` instead of `return nullptr`? That's what we usually do in C2, for example in `CallStaticJavaNode::Ideal` -> `CallNode::Ideal`. Feels more natural to me and would avoid the `super != nullptr` check. Also for the other `Ideal` methods that you modified. > > We could but it's not that direct. `ModFNode::Ideal` has 6 `return`s (without mine): > - 3 are `return replace_with_con(...);` which in their turn return `nullptr` but after making changes in the graph. > - 2 are `return nullptr;` > - 1 is actually returning a node. > And especially the final one is > > return replace_with_con(igvn, TypeF::make(jfloat_cast(xr))); > > If we change `replace_with_con` to actually return a `TupleNode` to do the job, we still have 2 places where to call the base class' `Ideal`. So I'm not sure how much better it would be to duplicate the call. It also adds a maintenance burden: if one adds another case where we don't want to make changes, one needs to add another call to `CallLeafPureNode::Ideal`. I think it's because of the structure of this function: rather than selecting cases where we want to do something and reaching the end with only the leftover cases, we select the cases we don't want to continue with, and we return early, making more cases where we should call the super method. > > I'll try something. Ah, makes sense. Feel free to leave as-is then. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25760#discussion_r2192809070 From thartmann at openjdk.org Tue Jul 8 15:19:44 2025 From: thartmann at openjdk.org (Tobias Hartmann) Date: Tue, 8 Jul 2025 15:19:44 GMT Subject: RFR: 8347901: C2 should remove unused leaf / pure runtime calls [v4] In-Reply-To: References: Message-ID: <7CvQqj41V2ysWMJACPif3jOCSF9xFypACLH9DiKYnc0=.aad8e7fe-56ba-44a3-bc31-187618af35d6@github.com> On Tue, 8 Jul 2025 14:21:20 GMT, Marc Chevalier wrote: >> src/hotspot/share/opto/divnode.cpp line 1528: >> >>> 1526: bool not_dead = proj_out_or_null(TypeFunc::Control) != nullptr; >>> 1527: if (result_is_unused && not_dead) { >>> 1528: return replace_with_con(igvn, TypeF::make(0.)); >> >> Can we replace all the other usages of `ModFloatingNode::replace_with_con` by `TupleNode` and get rid of that method? > > Yes, that sounds like a good idea. One still need to build the right `TupleNode`, which takes a bit of code. So in detail, I'd rather replace `replace_with_con` with a function returning the right `TupleNode` to be as concise on the call-site. Yes, that sounds good. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25760#discussion_r2192809839 From mchevalier at openjdk.org Tue Jul 8 15:28:39 2025 From: mchevalier at openjdk.org (Marc Chevalier) Date: Tue, 8 Jul 2025 15:28:39 GMT Subject: RFR: 8359344: C2: Malformed control flow after intrinsic bailout [v2] In-Reply-To: References: <1cFRkcs5JmgnbWEIaEoT8I9RiUtNxgKieAdkSB2Fgmc=.1d97b5c4-b6ef-43c6-b721-1e52eee19d3a@github.com> Message-ID: On Tue, 8 Jul 2025 15:11:09 GMT, Tobias Hartmann wrote: >> I've added it, since indeed, it could. As far as I understand, I was just lucky in the situation where it happens, but there is no reason it would always hold. > > I think you also need to re-insert it via `hash_find_insert`. // Some Ideal and other transforms delete --> modify --> insert values yes, indeed. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25936#discussion_r2192831829 From yzheng at openjdk.org Tue Jul 8 16:03:50 2025 From: yzheng at openjdk.org (Yudi Zheng) Date: Tue, 8 Jul 2025 16:03:50 GMT Subject: RFR: 8361569: [JVMCI] Further refine JVMCI-compiled nmethod that should not collect deoptimiztaion profile Message-ID: In https://github.com/openjdk/jdk/pull/25356 we prevent all non-CompilerBroker JVMCI compilations from collecting deoptimiztaion profiles. This causes some regression in Graal's whitebox unit tests, some of which employ non-CompilerBroker compilations to test deoptimiztaions. ------------- Commit messages: - [JVMCI] Further refine JVMCI-compiled nmethod that should not collect deoptimiztaion profile Changes: https://git.openjdk.org/jdk/pull/26192/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=26192&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8361569 Stats: 65 lines in 10 files changed: 35 ins; 5 del; 25 mod Patch: https://git.openjdk.org/jdk/pull/26192.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26192/head:pull/26192 PR: https://git.openjdk.org/jdk/pull/26192 From dnsimon at openjdk.org Tue Jul 8 17:13:41 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Tue, 8 Jul 2025 17:13:41 GMT Subject: RFR: 8357689: Refactor JVMCI to enable replay compilation in Graal [v2] In-Reply-To: References: Message-ID: On Tue, 8 Jul 2025 08:41:59 GMT, Andrej Pe?im?th wrote: >> This PR introduces a few minor JVMCI refactorings to make replay compilation possible in the Graal compiler. > > Andrej Pe?im?th has refreshed the contents of this pull request, and previous commits have been removed. The incremental views will show differences compared to the previous content of the PR. The pull request contains one new commit since the last revision: > > JVMCI refactorings to enable replay compilation in Graal. Looks good. ------------- Marked as reviewed by dnsimon (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/25433#pullrequestreview-2998482956 From duke at openjdk.org Tue Jul 8 17:37:57 2025 From: duke at openjdk.org (Andrej Pecimuth) Date: Tue, 8 Jul 2025 17:37:57 GMT Subject: RFR: 8357689: Refactor JVMCI to enable replay compilation in Graal [v3] In-Reply-To: References: Message-ID: > This PR introduces a few minor JVMCI refactorings to make replay compilation possible in the Graal compiler. Andrej Pecimuth has updated the pull request incrementally with one additional commit since the last revision: Remove unnecessary public modifier. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/25433/files - new: https://git.openjdk.org/jdk/pull/25433/files/c6c3bb62..1b845fa9 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=25433&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=25433&range=01-02 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/25433.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/25433/head:pull/25433 PR: https://git.openjdk.org/jdk/pull/25433 From dnsimon at openjdk.org Tue Jul 8 17:50:42 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Tue, 8 Jul 2025 17:50:42 GMT Subject: RFR: 8357689: Refactor JVMCI to enable replay compilation in Graal [v3] In-Reply-To: References: Message-ID: <0ZpzR9oc9eKbKHiDI6XTpi5tN28FhHq4ywHrF4nxSzI=.314d1794-a540-45db-8ab1-26eeb65b77f5@github.com> On Tue, 8 Jul 2025 17:37:57 GMT, Andrej Pecimuth wrote: >> This PR introduces a few minor JVMCI refactorings to make replay compilation possible in the Graal compiler. > > Andrej Pecimuth has updated the pull request incrementally with one additional commit since the last revision: > > Remove unnecessary public modifier. Still good. ------------- Marked as reviewed by dnsimon (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/25433#pullrequestreview-2998590011 From yzheng at openjdk.org Tue Jul 8 19:23:31 2025 From: yzheng at openjdk.org (Yudi Zheng) Date: Tue, 8 Jul 2025 19:23:31 GMT Subject: RFR: 8361569: [JVMCI] Further refine JVMCI-compiled nmethod that should not collect deoptimiztaion profile [v2] In-Reply-To: References: Message-ID: > In https://github.com/openjdk/jdk/pull/25356 we prevent all non-CompilerBroker JVMCI compilations from collecting deoptimiztaion profiles. This causes some regression in Graal's whitebox unit tests, some of which employ non-CompilerBroker compilations to test deoptimiztaions. Yudi Zheng has updated the pull request incrementally with one additional commit since the last revision: restore HotSpotNmethod constructor ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26192/files - new: https://git.openjdk.org/jdk/pull/26192/files/53c9279d..b17efc69 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26192&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26192&range=00-01 Stats: 12 lines in 2 files changed: 7 ins; 0 del; 5 mod Patch: https://git.openjdk.org/jdk/pull/26192.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26192/head:pull/26192 PR: https://git.openjdk.org/jdk/pull/26192 From dnsimon at openjdk.org Tue Jul 8 19:52:41 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Tue, 8 Jul 2025 19:52:41 GMT Subject: RFR: 8361569: [JVMCI] Further refine JVMCI-compiled nmethod that should not collect deoptimiztaion profile [v2] In-Reply-To: References: Message-ID: On Tue, 8 Jul 2025 19:23:31 GMT, Yudi Zheng wrote: >> In https://github.com/openjdk/jdk/pull/25356 we prevent all non-CompilerBroker JVMCI compilations from collecting deoptimiztaion profiles. This causes some regression in Graal's whitebox unit tests, some of which employ non-CompilerBroker compilations to test deoptimiztaions. > > Yudi Zheng has updated the pull request incrementally with one additional commit since the last revision: > > restore HotSpotNmethod constructor Looks good to me. ------------- Marked as reviewed by dnsimon (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/26192#pullrequestreview-2998930031 From kvn at openjdk.org Tue Jul 8 20:25:45 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Tue, 8 Jul 2025 20:25:45 GMT Subject: RFR: 8359344: C2: Malformed control flow after intrinsic bailout [v4] In-Reply-To: References: Message-ID: On Tue, 8 Jul 2025 13:53:25 GMT, Marc Chevalier wrote: >> When intrinsic bailout, we assume that the control in the `LibraryCallKit` did not change: >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L137 >> >> This is enforced by restoring the old state, like in >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L1722-L1732 >> >> That is good, but not sufficient. First, the most obvious, one could have already built some structure without moving the control. For instance, we can obtain something such as: >> >> ![1 after-intrinsic-bailout-during-late-inlining](https://github.com/user-attachments/assets/2fd255cc-0bfc-4841-8dd1-f64d502e0ee1) >> >> >> Here, during late inlining, the call `323` is candidate to be inline, but that bails out. Yet, a call to `make_unsafe_address` was made, which built nodes `354 If` and everything under. This is needed as tests are made on the resulting nodes (especially `366 AddP`) to know whether we should bail out or not. At the end, we get 2 control successor to `346 IfFalse`: the call that is not removed and the leftover of the intrinsic that will be cleanup much later, but not by RemoveUseless. >> >> Another situation is somewhat worse, when happening during parsing. It can lead to such cases: >> >> ![2 after-intrinsic-bailout-during-parsing](https://github.com/user-attachments/assets/4524c615-6521-4f0d-8f61-c426f9179035) >> >> The nodes `31 OpaqueNotNull`, `31 If`, `36 IfTrue`, `33 IfFalse`, `35 Halt`, `44 If`, `45 IfTrue`, `46 IfFalse` are leftover from a bailing out intrinsic. The replacement call `49 CallStaticJava` should come just under `5 Parm`, but the control was updated and the call is actually built under `36 If`. Then, why does the previous assert doesn't complain? >> >> This is because there is more than one control, or one map. In intrinsics that need to restore their state, the initial `SafePoint` map is cloned, the clone is kept aside, and if needed (bailing out), we set the current map to this saved clone. But there is another map from which the one of the `LibraryCallKit` comes, and that survives longer, it's the one that is contained in the `JVMState`: >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L101-L102 >> >> And here there is the challenge: >> - the `JVMState jvms` contains a `SafePoint` map, this map must have `jvms` as `jvms` (pointer comparison) >> ... > > Marc Chevalier has updated the pull request incrementally with one additional commit since the last revision: > > Somehow intellij doesn't remove empty indented line src/hotspot/share/opto/library_call.hpp line 150: > 148: void restore_state(const SavedState&); > 149: void destruct_map_clone(const SavedState& sfp); > 150: Can this be a class instead of struct? These methods could be members. Initialization can be done through constructor. The destructor can do restoration by default unless `destruct_map_clone()` was called before. I don't like name `destruct_map_clone()` for this. How about `SavedState::remove()` or something. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25936#discussion_r2193378458 From yzheng at openjdk.org Tue Jul 8 20:36:19 2025 From: yzheng at openjdk.org (Yudi Zheng) Date: Tue, 8 Jul 2025 20:36:19 GMT Subject: RFR: 8361569: [JVMCI] Further refine JVMCI-compiled nmethod that should not collect deoptimiztaion profile [v3] In-Reply-To: References: Message-ID: > In https://github.com/openjdk/jdk/pull/25356 we prevent all non-CompilerBroker JVMCI compilations from collecting deoptimiztaion profiles. This causes some regression in Graal's whitebox unit tests, some of which employ non-CompilerBroker compilations to test deoptimiztaions. Yudi Zheng has updated the pull request incrementally with one additional commit since the last revision: JNIJVMCI::HotSpotNmethod::constructor() cannot be overloaded ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26192/files - new: https://git.openjdk.org/jdk/pull/26192/files/b17efc69..c0afd3c1 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26192&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26192&range=01-02 Stats: 8 lines in 5 files changed: 0 ins; 5 del; 3 mod Patch: https://git.openjdk.org/jdk/pull/26192.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26192/head:pull/26192 PR: https://git.openjdk.org/jdk/pull/26192 From duke at openjdk.org Wed Jul 9 07:29:39 2025 From: duke at openjdk.org (duke) Date: Wed, 9 Jul 2025 07:29:39 GMT Subject: RFR: 8357689: Refactor JVMCI to enable replay compilation in Graal [v3] In-Reply-To: References: Message-ID: On Tue, 8 Jul 2025 17:37:57 GMT, Andrej Pecimuth wrote: >> This PR introduces a few minor JVMCI refactorings to make replay compilation possible in the Graal compiler. > > Andrej Pecimuth has updated the pull request incrementally with one additional commit since the last revision: > > Remove unnecessary public modifier. @pecimuth Your change (at version 1b845fa92383367026d8072ba5a9525ded15dccb) is now ready to be sponsored by a Committer. ------------- PR Comment: https://git.openjdk.org/jdk/pull/25433#issuecomment-3051484038 From yzheng at openjdk.org Wed Jul 9 08:01:52 2025 From: yzheng at openjdk.org (Yudi Zheng) Date: Wed, 9 Jul 2025 08:01:52 GMT Subject: RFR: 8361569: [JVMCI] Further refine JVMCI-compiled nmethod that should not collect deoptimization profile [v4] In-Reply-To: References: Message-ID: > In https://github.com/openjdk/jdk/pull/25356 we prevent all non-CompilerBroker JVMCI compilations from collecting deoptimiztaion profiles. This causes some regression in Graal's whitebox unit tests, some of which employ non-CompilerBroker compilations to test deoptimiztaions. Yudi Zheng has updated the pull request incrementally with one additional commit since the last revision: fix compilation error in test ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26192/files - new: https://git.openjdk.org/jdk/pull/26192/files/c0afd3c1..3f7b2362 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26192&range=03 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26192&range=02-03 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/26192.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26192/head:pull/26192 PR: https://git.openjdk.org/jdk/pull/26192 From dnsimon at openjdk.org Wed Jul 9 08:09:38 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Wed, 9 Jul 2025 08:09:38 GMT Subject: RFR: 8361569: [JVMCI] Further refine JVMCI-compiled nmethod that should not collect deoptimization profile [v4] In-Reply-To: References: Message-ID: <3uFGBbe0KELpzdGDivwsEUR8DWZSoQhGXuT_t6qD_Bg=.1c4cc3f2-aa64-4901-bc4c-3639171feda4@github.com> On Wed, 9 Jul 2025 08:01:52 GMT, Yudi Zheng wrote: >> In https://github.com/openjdk/jdk/pull/25356 we prevent all non-CompilerBroker JVMCI compilations from collecting deoptimiztaion profiles. This causes some regression in Graal's whitebox unit tests, some of which employ non-CompilerBroker compilations to test deoptimiztaions. > > Yudi Zheng has updated the pull request incrementally with one additional commit since the last revision: > > fix compilation error in test Marked as reviewed by dnsimon (Reviewer). ------------- PR Review: https://git.openjdk.org/jdk/pull/26192#pullrequestreview-3000496268 From duke at openjdk.org Wed Jul 9 08:22:44 2025 From: duke at openjdk.org (Andrej Pecimuth) Date: Wed, 9 Jul 2025 08:22:44 GMT Subject: Integrated: 8357689: Refactor JVMCI to enable replay compilation in Graal In-Reply-To: References: Message-ID: On Sat, 24 May 2025 16:49:23 GMT, Andrej Pecimuth wrote: > This PR introduces a few minor JVMCI refactorings to make replay compilation possible in the Graal compiler. This pull request has now been integrated. Changeset: 963b83fc Author: Andrej Pecimuth Committer: Doug Simon URL: https://git.openjdk.org/jdk/commit/963b83fcf158d273e9433b6845380184b3ad0de5 Stats: 258 lines in 16 files changed: 224 ins; 7 del; 27 mod 8357689: Refactor JVMCI to enable replay compilation in Graal Reviewed-by: dnsimon ------------- PR: https://git.openjdk.org/jdk/pull/25433 From yzheng at openjdk.org Wed Jul 9 10:53:20 2025 From: yzheng at openjdk.org (Yudi Zheng) Date: Wed, 9 Jul 2025 10:53:20 GMT Subject: RFR: 8361569: [JVMCI] Further refine JVMCI-compiled nmethod that should not collect deoptimization profile [v5] In-Reply-To: References: Message-ID: > In https://github.com/openjdk/jdk/pull/25356 we prevent all non-CompilerBroker JVMCI compilations from collecting deoptimiztaion profiles. This causes some regression in Graal's whitebox unit tests, some of which employ non-CompilerBroker compilations to test deoptimiztaions. Yudi Zheng has updated the pull request incrementally with one additional commit since the last revision: fix compilation error, update copyright year ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26192/files - new: https://git.openjdk.org/jdk/pull/26192/files/3f7b2362..b67bd1bb Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26192&range=04 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26192&range=03-04 Stats: 4 lines in 3 files changed: 0 ins; 0 del; 4 mod Patch: https://git.openjdk.org/jdk/pull/26192.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26192/head:pull/26192 PR: https://git.openjdk.org/jdk/pull/26192 From gdub at openjdk.org Wed Jul 9 11:27:39 2025 From: gdub at openjdk.org (Gilles Duboscq) Date: Wed, 9 Jul 2025 11:27:39 GMT Subject: RFR: 8361569: [JVMCI] Further refine JVMCI-compiled nmethod that should not collect deoptimization profile [v5] In-Reply-To: References: Message-ID: On Wed, 9 Jul 2025 10:53:20 GMT, Yudi Zheng wrote: >> In https://github.com/openjdk/jdk/pull/25356 we prevent all non-CompilerBroker JVMCI compilations from collecting deoptimiztaion profiles. This causes some regression in Graal's whitebox unit tests, some of which employ non-CompilerBroker compilations to test deoptimiztaions. > > Yudi Zheng has updated the pull request incrementally with one additional commit since the last revision: > > fix compilation error, update copyright year Marked as reviewed by gdub (Committer). ------------- PR Review: https://git.openjdk.org/jdk/pull/26192#pullrequestreview-3001149894 From dnsimon at openjdk.org Wed Jul 9 11:46:42 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Wed, 9 Jul 2025 11:46:42 GMT Subject: RFR: 8361569: [JVMCI] Further refine JVMCI-compiled nmethod that should not collect deoptimization profile [v5] In-Reply-To: References: Message-ID: On Wed, 9 Jul 2025 10:53:20 GMT, Yudi Zheng wrote: >> In https://github.com/openjdk/jdk/pull/25356 we prevent all non-CompilerBroker JVMCI compilations from collecting deoptimiztaion profiles. This causes some regression in Graal's whitebox unit tests, some of which employ non-CompilerBroker compilations to test deoptimiztaions. > > Yudi Zheng has updated the pull request incrementally with one additional commit since the last revision: > > fix compilation error, update copyright year Marked as reviewed by dnsimon (Reviewer). ------------- PR Review: https://git.openjdk.org/jdk/pull/26192#pullrequestreview-3001204538 From mchevalier at openjdk.org Wed Jul 9 12:36:31 2025 From: mchevalier at openjdk.org (Marc Chevalier) Date: Wed, 9 Jul 2025 12:36:31 GMT Subject: RFR: 8347901: C2 should remove unused leaf / pure runtime calls [v5] In-Reply-To: References: Message-ID: > A first part toward a better support of pure functions, but this time, with guidance from @iwanowww. > > ## Pure Functions > > Pure functions (considered here) are functions that have no side effects, no effect on the control flow (no exception or such), cannot deopt etc.. It's really a function that you can execute anywhere, with whichever arguments without effect other than wasting time. Integer division is not pure as dividing by zero is throwing. But many floating point functions will just return `NaN` or `+/-infinity` in problematic cases. > > ## Scope > > We are not going all powerful for now! It's mostly about identifying some pure functions and being able to remove them if the result is unused. Some other things are not part of this PR, on purpose. Especially, this PR doesn't propose a way to move pure calls around. The reason is that pure calls are later expanded into regular calls, which require a control input. To be able to do the expansion, we just keep the control in the pure call as well. > > ## Implementation Overview > > We created here some new node kind for pure calls, inheriting leaf calls, that are expanded into regular leaf calls during final graph reshaping. The possibility to support pure call directly in AD file is left open. > > This PR also introduces `TupleNode` (largely based on an original idea/implem of @iwanowww), that just tie multiple input together and play well with `ProjNode`: the n-th projection of a `TupleNode` is the n-th input of the tuple. This is a convenient way to skip and remove nodes from the graph while delegating the difficulty of the surgery to the trusted IGVN's implementation. > > Thanks, > Marc Marc Chevalier has updated the pull request incrementally with one additional commit since the last revision: Tentative to address Tobias' comments ------------- Changes: - all: https://git.openjdk.org/jdk/pull/25760/files - new: https://git.openjdk.org/jdk/pull/25760/files/7f18c9f6..7553e307 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=25760&range=04 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=25760&range=03-04 Stats: 118 lines in 2 files changed: 29 ins; 38 del; 51 mod Patch: https://git.openjdk.org/jdk/pull/25760.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/25760/head:pull/25760 PR: https://git.openjdk.org/jdk/pull/25760 From mchevalier at openjdk.org Wed Jul 9 12:36:32 2025 From: mchevalier at openjdk.org (Marc Chevalier) Date: Wed, 9 Jul 2025 12:36:32 GMT Subject: RFR: 8347901: C2 should remove unused leaf / pure runtime calls [v3] In-Reply-To: References: Message-ID: <785hwTKUD5k99LD_yX2GOLlWWk0-6fsQ3piigA_FIhs=.ed24d7c7-9ea6-4815-a738-1f61bade24e4@github.com> On Tue, 8 Jul 2025 15:16:16 GMT, Tobias Hartmann wrote: >> We could but it's not that direct. `ModFNode::Ideal` has 6 `return`s (without mine): >> - 3 are `return replace_with_con(...);` which in their turn return `nullptr` but after making changes in the graph. >> - 2 are `return nullptr;` >> - 1 is actually returning a node. >> And especially the final one is >> >> return replace_with_con(igvn, TypeF::make(jfloat_cast(xr))); >> >> If we change `replace_with_con` to actually return a `TupleNode` to do the job, we still have 2 places where to call the base class' `Ideal`. So I'm not sure how much better it would be to duplicate the call. It also adds a maintenance burden: if one adds another case where we don't want to make changes, one needs to add another call to `CallLeafPureNode::Ideal`. I think it's because of the structure of this function: rather than selecting cases where we want to do something and reaching the end with only the leftover cases, we select the cases we don't want to continue with, and we return early, making more cases where we should call the super method. >> >> I'll try something. > > Ah, makes sense. Feel free to leave as-is then. There, you can see the thing I've tried. It changes a bit more code, but overall, I think it makes it clearer and address your comment. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25760#discussion_r2194912203 From mchevalier at openjdk.org Wed Jul 9 12:38:26 2025 From: mchevalier at openjdk.org (Marc Chevalier) Date: Wed, 9 Jul 2025 12:38:26 GMT Subject: RFR: 8359344: C2: Malformed control flow after intrinsic bailout [v5] In-Reply-To: References: Message-ID: > When intrinsic bailout, we assume that the control in the `LibraryCallKit` did not change: > > https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L137 > > This is enforced by restoring the old state, like in > > https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L1722-L1732 > > That is good, but not sufficient. First, the most obvious, one could have already built some structure without moving the control. For instance, we can obtain something such as: > > ![1 after-intrinsic-bailout-during-late-inlining](https://github.com/user-attachments/assets/2fd255cc-0bfc-4841-8dd1-f64d502e0ee1) > > > Here, during late inlining, the call `323` is candidate to be inline, but that bails out. Yet, a call to `make_unsafe_address` was made, which built nodes `354 If` and everything under. This is needed as tests are made on the resulting nodes (especially `366 AddP`) to know whether we should bail out or not. At the end, we get 2 control successor to `346 IfFalse`: the call that is not removed and the leftover of the intrinsic that will be cleanup much later, but not by RemoveUseless. > > Another situation is somewhat worse, when happening during parsing. It can lead to such cases: > > ![2 after-intrinsic-bailout-during-parsing](https://github.com/user-attachments/assets/4524c615-6521-4f0d-8f61-c426f9179035) > > The nodes `31 OpaqueNotNull`, `31 If`, `36 IfTrue`, `33 IfFalse`, `35 Halt`, `44 If`, `45 IfTrue`, `46 IfFalse` are leftover from a bailing out intrinsic. The replacement call `49 CallStaticJava` should come just under `5 Parm`, but the control was updated and the call is actually built under `36 If`. Then, why does the previous assert doesn't complain? > > This is because there is more than one control, or one map. In intrinsics that need to restore their state, the initial `SafePoint` map is cloned, the clone is kept aside, and if needed (bailing out), we set the current map to this saved clone. But there is another map from which the one of the `LibraryCallKit` comes, and that survives longer, it's the one that is contained in the `JVMState`: > > https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L101-L102 > > And here there is the challenge: > - the `JVMState jvms` contains a `SafePoint` map, this map must have `jvms` as `jvms` (pointer comparison) > - we can't really change the pointer, just the content > -... Marc Chevalier has updated the pull request incrementally with two additional commits since the last revision: - Tentative addressing Vladimir's comments - Re-insert ------------- Changes: - all: https://git.openjdk.org/jdk/pull/25936/files - new: https://git.openjdk.org/jdk/pull/25936/files/09b24ec4..59133778 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=25936&range=04 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=25936&range=03-04 Stats: 83 lines in 3 files changed: 12 ins; 29 del; 42 mod Patch: https://git.openjdk.org/jdk/pull/25936.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/25936/head:pull/25936 PR: https://git.openjdk.org/jdk/pull/25936 From mchevalier at openjdk.org Wed Jul 9 12:40:42 2025 From: mchevalier at openjdk.org (Marc Chevalier) Date: Wed, 9 Jul 2025 12:40:42 GMT Subject: RFR: 8359344: C2: Malformed control flow after intrinsic bailout [v4] In-Reply-To: References: Message-ID: On Tue, 8 Jul 2025 20:23:08 GMT, Vladimir Kozlov wrote: >> Marc Chevalier has updated the pull request incrementally with one additional commit since the last revision: >> >> Somehow intellij doesn't remove empty indented line > > src/hotspot/share/opto/library_call.hpp line 150: > >> 148: void restore_state(const SavedState&); >> 149: void destruct_map_clone(const SavedState& sfp); >> 150: > > Can this be a class instead of struct? These methods could be members. Initialization can be done through constructor. The destructor can do restoration by default unless `destruct_map_clone()` was called before. > I don't like name `destruct_map_clone()` for this. How about `SavedState::remove()` or something. I like it. Since intrinsic implementations have mostly bailing out returns, and few success paths, it's nice to say when we are good, rather than every path that ends with bailing out. I've called the member function `discard`. It gives as `old_state.discard()`, which reads well, I think. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25936#discussion_r2194921677 From thartmann at openjdk.org Wed Jul 9 12:47:41 2025 From: thartmann at openjdk.org (Tobias Hartmann) Date: Wed, 9 Jul 2025 12:47:41 GMT Subject: RFR: 8359344: C2: Malformed control flow after intrinsic bailout [v5] In-Reply-To: References: Message-ID: On Wed, 9 Jul 2025 12:38:26 GMT, Marc Chevalier wrote: >> When intrinsic bailout, we assume that the control in the `LibraryCallKit` did not change: >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L137 >> >> This is enforced by restoring the old state, like in >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L1722-L1732 >> >> That is good, but not sufficient. First, the most obvious, one could have already built some structure without moving the control. For instance, we can obtain something such as: >> >> ![1 after-intrinsic-bailout-during-late-inlining](https://github.com/user-attachments/assets/2fd255cc-0bfc-4841-8dd1-f64d502e0ee1) >> >> >> Here, during late inlining, the call `323` is candidate to be inline, but that bails out. Yet, a call to `make_unsafe_address` was made, which built nodes `354 If` and everything under. This is needed as tests are made on the resulting nodes (especially `366 AddP`) to know whether we should bail out or not. At the end, we get 2 control successor to `346 IfFalse`: the call that is not removed and the leftover of the intrinsic that will be cleanup much later, but not by RemoveUseless. >> >> Another situation is somewhat worse, when happening during parsing. It can lead to such cases: >> >> ![2 after-intrinsic-bailout-during-parsing](https://github.com/user-attachments/assets/4524c615-6521-4f0d-8f61-c426f9179035) >> >> The nodes `31 OpaqueNotNull`, `31 If`, `36 IfTrue`, `33 IfFalse`, `35 Halt`, `44 If`, `45 IfTrue`, `46 IfFalse` are leftover from a bailing out intrinsic. The replacement call `49 CallStaticJava` should come just under `5 Parm`, but the control was updated and the call is actually built under `36 If`. Then, why does the previous assert doesn't complain? >> >> This is because there is more than one control, or one map. In intrinsics that need to restore their state, the initial `SafePoint` map is cloned, the clone is kept aside, and if needed (bailing out), we set the current map to this saved clone. But there is another map from which the one of the `LibraryCallKit` comes, and that survives longer, it's the one that is contained in the `JVMState`: >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L101-L102 >> >> And here there is the challenge: >> - the `JVMState jvms` contains a `SafePoint` map, this map must have `jvms` as `jvms` (pointer comparison) >> ... > > Marc Chevalier has updated the pull request incrementally with two additional commits since the last revision: > > - Tentative addressing Vladimir's comments > - Re-insert Nice! Looks good to me. ------------- Marked as reviewed by thartmann (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/25936#pullrequestreview-3001409938 From thartmann at openjdk.org Wed Jul 9 13:11:44 2025 From: thartmann at openjdk.org (Tobias Hartmann) Date: Wed, 9 Jul 2025 13:11:44 GMT Subject: RFR: 8347901: C2 should remove unused leaf / pure runtime calls [v5] In-Reply-To: References: Message-ID: On Wed, 9 Jul 2025 12:36:31 GMT, Marc Chevalier wrote: >> A first part toward a better support of pure functions, but this time, with guidance from @iwanowww. >> >> ## Pure Functions >> >> Pure functions (considered here) are functions that have no side effects, no effect on the control flow (no exception or such), cannot deopt etc.. It's really a function that you can execute anywhere, with whichever arguments without effect other than wasting time. Integer division is not pure as dividing by zero is throwing. But many floating point functions will just return `NaN` or `+/-infinity` in problematic cases. >> >> ## Scope >> >> We are not going all powerful for now! It's mostly about identifying some pure functions and being able to remove them if the result is unused. Some other things are not part of this PR, on purpose. Especially, this PR doesn't propose a way to move pure calls around. The reason is that pure calls are later expanded into regular calls, which require a control input. To be able to do the expansion, we just keep the control in the pure call as well. >> >> ## Implementation Overview >> >> We created here some new node kind for pure calls, inheriting leaf calls, that are expanded into regular leaf calls during final graph reshaping. The possibility to support pure call directly in AD file is left open. >> >> This PR also introduces `TupleNode` (largely based on an original idea/implem of @iwanowww), that just tie multiple input together and play well with `ProjNode`: the n-th projection of a `TupleNode` is the n-th input of the tuple. This is a convenient way to skip and remove nodes from the graph while delegating the difficulty of the surgery to the trusted IGVN's implementation. >> >> Thanks, >> Marc > > Marc Chevalier has updated the pull request incrementally with one additional commit since the last revision: > > Tentative to address Tobias' comments Thanks for making these changes, I like that version more. ------------- Marked as reviewed by thartmann (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/25760#pullrequestreview-3001503959 From yzheng at openjdk.org Wed Jul 9 13:37:56 2025 From: yzheng at openjdk.org (Yudi Zheng) Date: Wed, 9 Jul 2025 13:37:56 GMT Subject: RFR: 8361569: [JVMCI] Further refine JVMCI-compiled nmethod that should not collect deoptimization profile [v6] In-Reply-To: References: Message-ID: > In https://github.com/openjdk/jdk/pull/25356 we prevent all non-CompilerBroker JVMCI compilations from collecting deoptimiztaion profiles. This causes some regression in Graal's whitebox unit tests, some of which employ non-CompilerBroker compilations to test deoptimiztaions. Yudi Zheng has updated the pull request incrementally with one additional commit since the last revision: fix method not found in truffle tests ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26192/files - new: https://git.openjdk.org/jdk/pull/26192/files/b67bd1bb..ca92354e Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26192&range=05 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26192&range=04-05 Stats: 5 lines in 3 files changed: 2 ins; 0 del; 3 mod Patch: https://git.openjdk.org/jdk/pull/26192.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26192/head:pull/26192 PR: https://git.openjdk.org/jdk/pull/26192 From yzheng at openjdk.org Wed Jul 9 15:20:29 2025 From: yzheng at openjdk.org (Yudi Zheng) Date: Wed, 9 Jul 2025 15:20:29 GMT Subject: RFR: 8361569: [JVMCI] Further refine JVMCI-compiled nmethod that should not collect deoptimization profile [v7] In-Reply-To: References: Message-ID: > In https://github.com/openjdk/jdk/pull/25356 we prevent all non-CompilerBroker JVMCI compilations from collecting deoptimiztaion profiles. This causes some regression in Graal's whitebox unit tests, some of which employ non-CompilerBroker compilations to test deoptimiztaions. Yudi Zheng has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains eight additional commits since the last revision: - Merge remote-tracking branch 'upstream/master' into JDK-8361569 - update signature - fix method not found in truffle tests - fix compilation error, update copyright year - fix compilation error in test - JNIJVMCI::HotSpotNmethod::constructor() cannot be overloaded - restore HotSpotNmethod constructor - [JVMCI] Further refine JVMCI-compiled nmethod that should not collect deoptimiztaion profile ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26192/files - new: https://git.openjdk.org/jdk/pull/26192/files/ca92354e..413c1f38 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26192&range=06 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26192&range=05-06 Stats: 6846 lines in 241 files changed: 3657 ins; 830 del; 2359 mod Patch: https://git.openjdk.org/jdk/pull/26192.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26192/head:pull/26192 PR: https://git.openjdk.org/jdk/pull/26192 From kvn at openjdk.org Wed Jul 9 16:36:39 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Wed, 9 Jul 2025 16:36:39 GMT Subject: RFR: 8359344: C2: Malformed control flow after intrinsic bailout [v5] In-Reply-To: References: Message-ID: <06SLl1SEu1oWp3YWh9xR3LbQR5rDGs6thA5UAS_kMtk=.5fb6e090-7ac6-4e99-9700-b767f2a08348@github.com> On Wed, 9 Jul 2025 12:38:26 GMT, Marc Chevalier wrote: >> When intrinsic bailout, we assume that the control in the `LibraryCallKit` did not change: >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L137 >> >> This is enforced by restoring the old state, like in >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L1722-L1732 >> >> That is good, but not sufficient. First, the most obvious, one could have already built some structure without moving the control. For instance, we can obtain something such as: >> >> ![1 after-intrinsic-bailout-during-late-inlining](https://github.com/user-attachments/assets/2fd255cc-0bfc-4841-8dd1-f64d502e0ee1) >> >> >> Here, during late inlining, the call `323` is candidate to be inline, but that bails out. Yet, a call to `make_unsafe_address` was made, which built nodes `354 If` and everything under. This is needed as tests are made on the resulting nodes (especially `366 AddP`) to know whether we should bail out or not. At the end, we get 2 control successor to `346 IfFalse`: the call that is not removed and the leftover of the intrinsic that will be cleanup much later, but not by RemoveUseless. >> >> Another situation is somewhat worse, when happening during parsing. It can lead to such cases: >> >> ![2 after-intrinsic-bailout-during-parsing](https://github.com/user-attachments/assets/4524c615-6521-4f0d-8f61-c426f9179035) >> >> The nodes `31 OpaqueNotNull`, `31 If`, `36 IfTrue`, `33 IfFalse`, `35 Halt`, `44 If`, `45 IfTrue`, `46 IfFalse` are leftover from a bailing out intrinsic. The replacement call `49 CallStaticJava` should come just under `5 Parm`, but the control was updated and the call is actually built under `36 If`. Then, why does the previous assert doesn't complain? >> >> This is because there is more than one control, or one map. In intrinsics that need to restore their state, the initial `SafePoint` map is cloned, the clone is kept aside, and if needed (bailing out), we set the current map to this saved clone. But there is another map from which the one of the `LibraryCallKit` comes, and that survives longer, it's the one that is contained in the `JVMState`: >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L101-L102 >> >> And here there is the challenge: >> - the `JVMState jvms` contains a `SafePoint` map, this map must have `jvms` as `jvms` (pointer comparison) >> ... > > Marc Chevalier has updated the pull request incrementally with two additional commits since the last revision: > > - Tentative addressing Vladimir's comments > - Re-insert src/hotspot/share/opto/library_call.hpp line 147: > 145: SafePointNode* _map; > 146: Unique_Node_List _ctrl_succ; > 147: bool discarded = false; `discarded` is not static field. I suggest to initialize it in constructor. And use `_` prefix. Otherwise changes are good. Thank you for taking my suggestion. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25936#discussion_r2195470155 From dnsimon at openjdk.org Wed Jul 9 18:50:41 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Wed, 9 Jul 2025 18:50:41 GMT Subject: RFR: 8361569: [JVMCI] Further refine JVMCI-compiled nmethod that should not collect deoptimization profile [v7] In-Reply-To: References: Message-ID: <77OT73LZ631dhxno_DH8ul9EGtW5b4kPcKLDtW3H6Lk=.23dd5f7c-d300-4d68-a1a0-241635bb89b3@github.com> On Wed, 9 Jul 2025 15:20:29 GMT, Yudi Zheng wrote: >> In https://github.com/openjdk/jdk/pull/25356 we prevent all non-CompilerBroker JVMCI compilations from collecting deoptimiztaion profiles. This causes some regression in Graal's whitebox unit tests, some of which employ non-CompilerBroker compilations to test deoptimiztaions. > > Yudi Zheng has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains eight additional commits since the last revision: > > - Merge remote-tracking branch 'upstream/master' into JDK-8361569 > - update signature > - fix method not found in truffle tests > - fix compilation error, update copyright year > - fix compilation error in test > - JNIJVMCI::HotSpotNmethod::constructor() cannot be overloaded > - restore HotSpotNmethod constructor > - [JVMCI] Further refine JVMCI-compiled nmethod that should not collect deoptimiztaion profile Marked as reviewed by dnsimon (Reviewer). ------------- PR Review: https://git.openjdk.org/jdk/pull/26192#pullrequestreview-3002711174 From yzheng at openjdk.org Wed Jul 9 19:15:47 2025 From: yzheng at openjdk.org (Yudi Zheng) Date: Wed, 9 Jul 2025 19:15:47 GMT Subject: RFR: 8361569: [JVMCI] Further refine JVMCI-compiled nmethod that should not collect deoptimization profile [v7] In-Reply-To: References: Message-ID: On Wed, 9 Jul 2025 15:20:29 GMT, Yudi Zheng wrote: >> In https://github.com/openjdk/jdk/pull/25356 we prevent all non-CompilerBroker JVMCI compilations from collecting deoptimiztaion profiles. This causes some regression in Graal's whitebox unit tests, some of which employ non-CompilerBroker compilations to test deoptimiztaions. > > Yudi Zheng has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains eight additional commits since the last revision: > > - Merge remote-tracking branch 'upstream/master' into JDK-8361569 > - update signature > - fix method not found in truffle tests > - fix compilation error, update copyright year > - fix compilation error in test > - JNIJVMCI::HotSpotNmethod::constructor() cannot be overloaded > - restore HotSpotNmethod constructor > - [JVMCI] Further refine JVMCI-compiled nmethod that should not collect deoptimiztaion profile Thanks for the review! Passed Tier1-3 ------------- PR Comment: https://git.openjdk.org/jdk/pull/26192#issuecomment-3053725076 From yzheng at openjdk.org Wed Jul 9 19:15:47 2025 From: yzheng at openjdk.org (Yudi Zheng) Date: Wed, 9 Jul 2025 19:15:47 GMT Subject: Integrated: 8361569: [JVMCI] Further refine JVMCI-compiled nmethod that should not collect deoptimization profile In-Reply-To: References: Message-ID: On Tue, 8 Jul 2025 15:59:10 GMT, Yudi Zheng wrote: > In https://github.com/openjdk/jdk/pull/25356 we prevent all non-CompilerBroker JVMCI compilations from collecting deoptimiztaion profiles. This causes some regression in Graal's whitebox unit tests, some of which employ non-CompilerBroker compilations to test deoptimiztaions. This pull request has now been integrated. Changeset: 6681fc72 Author: Yudi Zheng URL: https://git.openjdk.org/jdk/commit/6681fc72d3463e13876eb84a285eb580ee92b464 Stats: 86 lines in 18 files changed: 39 ins; 5 del; 42 mod 8361569: [JVMCI] Further refine JVMCI-compiled nmethod that should not collect deoptimization profile Reviewed-by: dnsimon, gdub ------------- PR: https://git.openjdk.org/jdk/pull/26192 From darcy at openjdk.org Thu Jul 10 04:54:37 2025 From: darcy at openjdk.org (Joe Darcy) Date: Thu, 10 Jul 2025 04:54:37 GMT Subject: RFR: 8360559: Optimize Math.sinh for x86 64 bit platforms In-Reply-To: References: Message-ID: On Mon, 7 Jul 2025 03:05:15 GMT, Mohamed Issa wrote: > The goal of this PR is to implement an x86_64 intrinsic for java.lang.Math.sinh() using libm. There is a new set of micro-benchmarks are included to check the performance of specific input value ranges to help prevent regressions in the future. > > The command to run all range specific micro-benchmarks is posted below. > > `make test TEST="micro:SinhPerf.SinhPerfRanges"` > > The results of all tests posted below were captured with an [Intel? Xeon 8488C](https://advisor.cloudzero.com/aws/ec2/r7i.metal-24xl) using [OpenJDK v26-b4](https://github.com/openjdk/jdk/releases/tag/jdk-26%2B4) as the baseline version. > > For performance data collected with the new built in range micro-benchmark, see the table below. Each result is the mean of 8 individual runs, and the input ranges used match those from the original Java implementation. Overall, the intrinsic provides an an average uplift of 64% when input values fall into the middle three ranges where heavy computation is required. However, very small inputs and very large inputs show drops of 74% and 66% respectively. > > | Input range(s) | Baseline throughput (ops/ms) | Intrinsic throughput (ops/ms) | Speedup | > | :------------------------------------: | :-------------------------------: | :--------------------------------: | :--------: | > | [-2^(-28), 2^(-28)] | 844160 | 216029 | 0.26x | > | [-22, -2^(-28)], [2^(-28), 22] | 81662 | 157351 | 1.93x | > | [-709.78, -22], [22, 709.78] | 119075 | 167635 | 1.41x | > | [-710.48, -709.78], [709.78, 710.48] | 111636 | 177125 | 1.59x | > | (-INF, -710.48], [710.48, INF) | 959296 | 313839 | 0.33x | > > Finally, the `jtreg:test/jdk/java/lang/Math/HyperbolicTests.java` test passed with the changes. What is the accuracy of the algorithm in ulps (units the last place)? The java.lang.Math specification has max error and various other accuracy requirements any implementation must meet. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26152#issuecomment-3055484802 From mchevalier at openjdk.org Thu Jul 10 06:13:27 2025 From: mchevalier at openjdk.org (Marc Chevalier) Date: Thu, 10 Jul 2025 06:13:27 GMT Subject: RFR: 8359344: C2: Malformed control flow after intrinsic bailout [v6] In-Reply-To: References: Message-ID: <-rnlrm6PHRZeO1izbXh5nOrm368YKrsFft1u6SHXzWA=.9c8e6646-0b72-4705-895e-f795f74f3906@github.com> > When intrinsic bailout, we assume that the control in the `LibraryCallKit` did not change: > > https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L137 > > This is enforced by restoring the old state, like in > > https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L1722-L1732 > > That is good, but not sufficient. First, the most obvious, one could have already built some structure without moving the control. For instance, we can obtain something such as: > > ![1 after-intrinsic-bailout-during-late-inlining](https://github.com/user-attachments/assets/2fd255cc-0bfc-4841-8dd1-f64d502e0ee1) > > > Here, during late inlining, the call `323` is candidate to be inline, but that bails out. Yet, a call to `make_unsafe_address` was made, which built nodes `354 If` and everything under. This is needed as tests are made on the resulting nodes (especially `366 AddP`) to know whether we should bail out or not. At the end, we get 2 control successor to `346 IfFalse`: the call that is not removed and the leftover of the intrinsic that will be cleanup much later, but not by RemoveUseless. > > Another situation is somewhat worse, when happening during parsing. It can lead to such cases: > > ![2 after-intrinsic-bailout-during-parsing](https://github.com/user-attachments/assets/4524c615-6521-4f0d-8f61-c426f9179035) > > The nodes `31 OpaqueNotNull`, `31 If`, `36 IfTrue`, `33 IfFalse`, `35 Halt`, `44 If`, `45 IfTrue`, `46 IfFalse` are leftover from a bailing out intrinsic. The replacement call `49 CallStaticJava` should come just under `5 Parm`, but the control was updated and the call is actually built under `36 If`. Then, why does the previous assert doesn't complain? > > This is because there is more than one control, or one map. In intrinsics that need to restore their state, the initial `SafePoint` map is cloned, the clone is kept aside, and if needed (bailing out), we set the current map to this saved clone. But there is another map from which the one of the `LibraryCallKit` comes, and that survives longer, it's the one that is contained in the `JVMState`: > > https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L101-L102 > > And here there is the challenge: > - the `JVMState jvms` contains a `SafePoint` map, this map must have `jvms` as `jvms` (pointer comparison) > - we can't really change the pointer, just the content > -... Marc Chevalier has updated the pull request incrementally with two additional commits since the last revision: - Forgot to destruct_map_clone - +'_' and ctor init ------------- Changes: - all: https://git.openjdk.org/jdk/pull/25936/files - new: https://git.openjdk.org/jdk/pull/25936/files/59133778..be5c0241 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=25936&range=05 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=25936&range=04-05 Stats: 6 lines in 2 files changed: 2 ins; 0 del; 4 mod Patch: https://git.openjdk.org/jdk/pull/25936.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/25936/head:pull/25936 PR: https://git.openjdk.org/jdk/pull/25936 From mchevalier at openjdk.org Thu Jul 10 06:13:27 2025 From: mchevalier at openjdk.org (Marc Chevalier) Date: Thu, 10 Jul 2025 06:13:27 GMT Subject: RFR: 8359344: C2: Malformed control flow after intrinsic bailout [v5] In-Reply-To: References: Message-ID: On Wed, 9 Jul 2025 12:38:26 GMT, Marc Chevalier wrote: >> When intrinsic bailout, we assume that the control in the `LibraryCallKit` did not change: >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L137 >> >> This is enforced by restoring the old state, like in >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L1722-L1732 >> >> That is good, but not sufficient. First, the most obvious, one could have already built some structure without moving the control. For instance, we can obtain something such as: >> >> ![1 after-intrinsic-bailout-during-late-inlining](https://github.com/user-attachments/assets/2fd255cc-0bfc-4841-8dd1-f64d502e0ee1) >> >> >> Here, during late inlining, the call `323` is candidate to be inline, but that bails out. Yet, a call to `make_unsafe_address` was made, which built nodes `354 If` and everything under. This is needed as tests are made on the resulting nodes (especially `366 AddP`) to know whether we should bail out or not. At the end, we get 2 control successor to `346 IfFalse`: the call that is not removed and the leftover of the intrinsic that will be cleanup much later, but not by RemoveUseless. >> >> Another situation is somewhat worse, when happening during parsing. It can lead to such cases: >> >> ![2 after-intrinsic-bailout-during-parsing](https://github.com/user-attachments/assets/4524c615-6521-4f0d-8f61-c426f9179035) >> >> The nodes `31 OpaqueNotNull`, `31 If`, `36 IfTrue`, `33 IfFalse`, `35 Halt`, `44 If`, `45 IfTrue`, `46 IfFalse` are leftover from a bailing out intrinsic. The replacement call `49 CallStaticJava` should come just under `5 Parm`, but the control was updated and the call is actually built under `36 If`. Then, why does the previous assert doesn't complain? >> >> This is because there is more than one control, or one map. In intrinsics that need to restore their state, the initial `SafePoint` map is cloned, the clone is kept aside, and if needed (bailing out), we set the current map to this saved clone. But there is another map from which the one of the `LibraryCallKit` comes, and that survives longer, it's the one that is contained in the `JVMState`: >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L101-L102 >> >> And here there is the challenge: >> - the `JVMState jvms` contains a `SafePoint` map, this map must have `jvms` as `jvms` (pointer comparison) >> ... > > Marc Chevalier has updated the pull request incrementally with two additional commits since the last revision: > > - Tentative addressing Vladimir's comments > - Re-insert Turns out in this `SavedState` tiny refactoring, I removed the underlying call to `destruct_map_clone`. It's probably benign up to memory consumption, and it made no test fail. Nevertheless, it's back. ------------- PR Comment: https://git.openjdk.org/jdk/pull/25936#issuecomment-3055733721 From mchevalier at openjdk.org Thu Jul 10 06:13:28 2025 From: mchevalier at openjdk.org (Marc Chevalier) Date: Thu, 10 Jul 2025 06:13:28 GMT Subject: RFR: 8359344: C2: Malformed control flow after intrinsic bailout [v5] In-Reply-To: <06SLl1SEu1oWp3YWh9xR3LbQR5rDGs6thA5UAS_kMtk=.5fb6e090-7ac6-4e99-9700-b767f2a08348@github.com> References: <06SLl1SEu1oWp3YWh9xR3LbQR5rDGs6thA5UAS_kMtk=.5fb6e090-7ac6-4e99-9700-b767f2a08348@github.com> Message-ID: <4cs83TE2oMQrKZJBJy72dLKotjXgyh2WLheJyTPvvSM=.e22e5aea-befe-4857-86b3-a86ef6e9a57a@github.com> On Wed, 9 Jul 2025 16:34:15 GMT, Vladimir Kozlov wrote: >> Marc Chevalier has updated the pull request incrementally with two additional commits since the last revision: >> >> - Tentative addressing Vladimir's comments >> - Re-insert > > src/hotspot/share/opto/library_call.hpp line 147: > >> 145: SafePointNode* _map; >> 146: Unique_Node_List _ctrl_succ; >> 147: bool discarded = false; > > `discarded` is not static field. I suggest to initialize it in constructor. And use `_` prefix. > > Otherwise changes are good. Thank you for taking my suggestion. Done! ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25936#discussion_r2196677989 From thartmann at openjdk.org Thu Jul 10 07:17:43 2025 From: thartmann at openjdk.org (Tobias Hartmann) Date: Thu, 10 Jul 2025 07:17:43 GMT Subject: RFR: 8359344: C2: Malformed control flow after intrinsic bailout [v6] In-Reply-To: <-rnlrm6PHRZeO1izbXh5nOrm368YKrsFft1u6SHXzWA=.9c8e6646-0b72-4705-895e-f795f74f3906@github.com> References: <-rnlrm6PHRZeO1izbXh5nOrm368YKrsFft1u6SHXzWA=.9c8e6646-0b72-4705-895e-f795f74f3906@github.com> Message-ID: On Thu, 10 Jul 2025 06:13:27 GMT, Marc Chevalier wrote: >> When intrinsic bailout, we assume that the control in the `LibraryCallKit` did not change: >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L137 >> >> This is enforced by restoring the old state, like in >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L1722-L1732 >> >> That is good, but not sufficient. First, the most obvious, one could have already built some structure without moving the control. For instance, we can obtain something such as: >> >> ![1 after-intrinsic-bailout-during-late-inlining](https://github.com/user-attachments/assets/2fd255cc-0bfc-4841-8dd1-f64d502e0ee1) >> >> >> Here, during late inlining, the call `323` is candidate to be inline, but that bails out. Yet, a call to `make_unsafe_address` was made, which built nodes `354 If` and everything under. This is needed as tests are made on the resulting nodes (especially `366 AddP`) to know whether we should bail out or not. At the end, we get 2 control successor to `346 IfFalse`: the call that is not removed and the leftover of the intrinsic that will be cleanup much later, but not by RemoveUseless. >> >> Another situation is somewhat worse, when happening during parsing. It can lead to such cases: >> >> ![2 after-intrinsic-bailout-during-parsing](https://github.com/user-attachments/assets/4524c615-6521-4f0d-8f61-c426f9179035) >> >> The nodes `31 OpaqueNotNull`, `31 If`, `36 IfTrue`, `33 IfFalse`, `35 Halt`, `44 If`, `45 IfTrue`, `46 IfFalse` are leftover from a bailing out intrinsic. The replacement call `49 CallStaticJava` should come just under `5 Parm`, but the control was updated and the call is actually built under `36 If`. Then, why does the previous assert doesn't complain? >> >> This is because there is more than one control, or one map. In intrinsics that need to restore their state, the initial `SafePoint` map is cloned, the clone is kept aside, and if needed (bailing out), we set the current map to this saved clone. But there is another map from which the one of the `LibraryCallKit` comes, and that survives longer, it's the one that is contained in the `JVMState`: >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L101-L102 >> >> And here there is the challenge: >> - the `JVMState jvms` contains a `SafePoint` map, this map must have `jvms` as `jvms` (pointer comparison) >> ... > > Marc Chevalier has updated the pull request incrementally with two additional commits since the last revision: > > - Forgot to destruct_map_clone > - +'_' and ctor init Marked as reviewed by thartmann (Reviewer). ------------- PR Review: https://git.openjdk.org/jdk/pull/25936#pullrequestreview-3004286462 From fweimer at openjdk.org Thu Jul 10 10:07:38 2025 From: fweimer at openjdk.org (Florian Weimer) Date: Thu, 10 Jul 2025 10:07:38 GMT Subject: RFR: 8360559: Optimize Math.sinh for x86 64 bit platforms In-Reply-To: References: Message-ID: On Mon, 7 Jul 2025 23:53:14 GMT, Mohamed Issa wrote: > I'm not sure which libm version you're referring to. The only current sinh benchmark I'm aware of is in MathBench.java, and the benchmarks in SinhPerf.java didn't exist until now. Could you clarify? I didn't notice the code you ported over from the Intel math library at first. I assumed ?libm? referred to the system libm version. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26152#issuecomment-3056706410 From mchevalier at openjdk.org Thu Jul 10 10:48:43 2025 From: mchevalier at openjdk.org (Marc Chevalier) Date: Thu, 10 Jul 2025 10:48:43 GMT Subject: RFR: 8347901: C2 should remove unused leaf / pure runtime calls [v5] In-Reply-To: References: Message-ID: On Wed, 9 Jul 2025 12:36:31 GMT, Marc Chevalier wrote: >> A first part toward a better support of pure functions, but this time, with guidance from @iwanowww. >> >> ## Pure Functions >> >> Pure functions (considered here) are functions that have no side effects, no effect on the control flow (no exception or such), cannot deopt etc.. It's really a function that you can execute anywhere, with whichever arguments without effect other than wasting time. Integer division is not pure as dividing by zero is throwing. But many floating point functions will just return `NaN` or `+/-infinity` in problematic cases. >> >> ## Scope >> >> We are not going all powerful for now! It's mostly about identifying some pure functions and being able to remove them if the result is unused. Some other things are not part of this PR, on purpose. Especially, this PR doesn't propose a way to move pure calls around. The reason is that pure calls are later expanded into regular calls, which require a control input. To be able to do the expansion, we just keep the control in the pure call as well. >> >> ## Implementation Overview >> >> We created here some new node kind for pure calls, inheriting leaf calls, that are expanded into regular leaf calls during final graph reshaping. The possibility to support pure call directly in AD file is left open. >> >> This PR also introduces `TupleNode` (largely based on an original idea/implem of @iwanowww), that just tie multiple input together and play well with `ProjNode`: the n-th projection of a `TupleNode` is the n-th input of the tuple. This is a convenient way to skip and remove nodes from the graph while delegating the difficulty of the surgery to the trusted IGVN's implementation. >> >> Thanks, >> Marc > > Marc Chevalier has updated the pull request incrementally with one additional commit since the last revision: > > Tentative to address Tobias' comments @iwanowww would you like to take a look at it, since you have quite some context already? ------------- PR Comment: https://git.openjdk.org/jdk/pull/25760#issuecomment-3056888461 From vyazici at openjdk.org Thu Jul 10 12:58:54 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Thu, 10 Jul 2025 12:58:54 GMT Subject: RFR: 8361842: Validate input in both Java and C++ for java.lang.StringCoding intrinsics In-Reply-To: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Thu, 26 Jun 2025 10:48:37 GMT, Volkan Yazici wrote: > Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated C++ methods, and adapt them to cause VM crash on invalid input. > > ## Implementation notes > > The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, > > 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) > 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too > 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method > 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag > > Following preliminary work needs to be carried out as well: > > 1. Add a new `VerifyIntrinsicChecks` VM flag > 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. > > 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. > > ## Functional and performance tests > > - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. > > - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. > > ## Verification of the VM crash > > I've tested the VM crash scenario as follows: > > 1. Created the following test program: > > public class StrIntri { > public static void main(String[] args) { > Exception lastException = null; > for (int i = 0; i < 1_000_000; i++) { > try { > jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); > } catch (Exception exception) { > lastException = exception; > } > } > if (lastException != null) { > lastException.printStackTrace(); > } else { > System.out.println("completed"); > } > } > } > > 2. Comp... src/hotspot/share/opto/library_call.cpp line 963: > 961: > 962: if (bailout->req() > 1) { > 963: if (halt) { Toggle to force a VM crash to be used to surface intrinsic Java wrappers failing to spot invalid input. src/java.base/share/classes/java/lang/StringCoding.java line 140: > 138: * > 139: * @param sa the source byte array containing characters encoded in UTF-16 > 140: * @param sp the index of the byte (not character!) from the source array to start reading from Note the `byte (not character!)` emphasis here and below. src/java.base/share/classes/java/lang/StringCoding.java line 150: > 148: */ > 149: static int encodeISOArray(byte[] sa, int sp, byte[] da, int dp, int len) { > 150: checkFromIndexSize(sp, len << 1, requireNonNull(sa, "sa").length, AIOOBE_FORMATTER); `sa` contains 2-byte `char`s, and `sp` points to an index of this inflated array. Though, `len` denotes the codepoint count, hence the `len << 1` while checking `sp` and `len` bounds. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2197576759 PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2197566783 PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2197572078 From liach at openjdk.org Thu Jul 10 12:58:55 2025 From: liach at openjdk.org (Chen Liang) Date: Thu, 10 Jul 2025 12:58:55 GMT Subject: RFR: 8361842: Validate input in both Java and C++ for java.lang.StringCoding intrinsics In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Fri, 27 Jun 2025 07:22:48 GMT, Tobias Hartmann wrote: >> src/java.base/share/classes/java/lang/StringCoding.java line 93: >> >>> 91: public static int countPositives(byte[] ba, int off, int len) { >>> 92: Objects.requireNonNull(ba, "ba"); >>> 93: Objects.checkFromIndexSize(off, len, ba.length); >> >> I recall core libraries intentionally avoided this because of performance problems. Is it possible for us to say trust the `len` argument to be non-negative? That allows us to simplify this to `Objects.checkIndex(off, ba.length - len)`. See this usage in perf-sensitive FFM API: https://github.com/openjdk/jdk/blob/149882416a956dec728a964c150b826dd589908f/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java#L401 > > But the original code already checks for `len >= 0`, right? See `LibraryCallKit::inline_countPositives` -> `generate_string_range_check` -> `// Offset and count must not be negative` > > This PR is about moving the range checks from the intrinsics into the Java wrappers. Removing range checks is out of the scope and should be carefully evaluated on a case-by-case basis separately. My point is this is a performance-sensitive API. We are using a known-slow check method `checkFromIndexSize` which may introduce a performance regression. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2172044145 From duke at openjdk.org Thu Jul 10 12:58:56 2025 From: duke at openjdk.org (ExE Boss) Date: Thu, 10 Jul 2025 12:58:56 GMT Subject: RFR: 8361842: Validate input in both Java and C++ for java.lang.StringCoding intrinsics In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Fri, 27 Jun 2025 13:24:52 GMT, Chen Liang wrote: >> But the original code already checks for `len >= 0`, right? See `LibraryCallKit::inline_countPositives` -> `generate_string_range_check` -> `// Offset and count must not be negative` >> >> This PR is about moving the range checks from the intrinsics into the Java wrappers. Removing range checks is out of the scope and should be carefully evaluated on a case-by-case basis separately. > > My point is this is a performance-sensitive API. We are using a known-slow check method `checkFromIndexSize` which may introduce a performance regression. Maybe?use `jdk.internal.util.Preconditions` directly?instead? Suggestion: Preconditions.checkFromIndexSize(off, len, ba.length, null); ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2172823303 From liach at openjdk.org Thu Jul 10 12:58:55 2025 From: liach at openjdk.org (Chen Liang) Date: Thu, 10 Jul 2025 12:58:55 GMT Subject: RFR: 8361842: Validate input in both Java and C++ for java.lang.StringCoding intrinsics In-Reply-To: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Thu, 26 Jun 2025 10:48:37 GMT, Volkan Yazici wrote: > Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated C++ methods, and adapt them to cause VM crash on invalid input. > > ## Implementation notes > > The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, > > 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) > 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too > 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method > 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag > > Following preliminary work needs to be carried out as well: > > 1. Add a new `VerifyIntrinsicChecks` VM flag > 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. > > 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. > > ## Functional and performance tests > > - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. > > - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. > > ## Verification of the VM crash > > I've tested the VM crash scenario as follows: > > 1. Created the following test program: > > public class StrIntri { > public static void main(String[] args) { > Exception lastException = null; > for (int i = 0; i < 1_000_000; i++) { > try { > jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); > } catch (Exception exception) { > lastException = exception; > } > } > if (lastException != null) { > lastException.printStackTrace(); > } else { > System.out.println("completed"); > } > } > } > > 2. Comp... src/java.base/share/classes/java/lang/StringCoding.java line 93: > 91: public static int countPositives(byte[] ba, int off, int len) { > 92: Objects.requireNonNull(ba, "ba"); > 93: Objects.checkFromIndexSize(off, len, ba.length); I recall core libraries intentionally avoided this because of performance problems. Is it possible for us to say trust the `len` argument to be non-negative? That allows us to simplify this to `Objects.checkIndex(off, ba.length - len)`. See this usage in perf-sensitive FFM API: https://github.com/openjdk/jdk/blob/149882416a956dec728a964c150b826dd589908f/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java#L401 ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2169545990 From vyazici at openjdk.org Thu Jul 10 12:58:56 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Thu, 10 Jul 2025 12:58:56 GMT Subject: RFR: 8361842: Validate input in both Java and C++ for java.lang.StringCoding intrinsics In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Fri, 27 Jun 2025 13:24:52 GMT, Chen Liang wrote: >> But the original code already checks for `len >= 0`, right? See `LibraryCallKit::inline_countPositives` -> `generate_string_range_check` -> `// Offset and count must not be negative` >> >> This PR is about moving the range checks from the intrinsics into the Java wrappers. Removing range checks is out of the scope and should be carefully evaluated on a case-by-case basis separately. > > My point is this is a performance-sensitive API. We are using a known-slow check method `checkFromIndexSize` which may introduce a performance regression. @liach, thanks for sharing your feedback on this draft, much appreciated. ? In order to address your (rightful) concerns (which I also share) regarding the performance impact, in 196fc5d, I've added `StringCodingCountPositives` JMH benchmark and produced the following results: *OS:* Ubuntu 24.04.2 *CPU:* Intel Core Ultra 9 185H x 22 Mode Cnt Score Error Units avgt 10 8.617 ? 0.646 ns/op # 149882416a9 (strIntrinCheck) avgt 10 8.787 ? 0.313 ns/op # 5a1301df195 (master) AFAICT, (even though the patched version appears to be performing better ?) the scores do match. Note that I will run the entire `test/micro/org/openjdk/bench/java/lang/String*.java` suite on various platforms and make sure there are no (visible?) performance regressions, before promoting this draft to a PR. Let me know if this addresses your concerns and if there is anything else I can do to better assess the performance impact. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2185582087 From vyazici at openjdk.org Thu Jul 10 12:58:53 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Thu, 10 Jul 2025 12:58:53 GMT Subject: RFR: 8361842: Validate input in both Java and C++ for java.lang.StringCoding intrinsics Message-ID: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated C++ methods, and adapt them to cause VM crash on invalid input. ## Implementation notes The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag Following preliminary work needs to be carried out as well: 1. Add a new `VerifyIntrinsicChecks` VM flag 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. ## Functional and performance tests - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. ## Verification of the VM crash I've tested the VM crash scenario as follows: 1. Created the following test program: public class StrIntri { public static void main(String[] args) { Exception lastException = null; for (int i = 0; i < 1_000_000; i++) { try { jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); } catch (Exception exception) { lastException = exception; } } if (lastException != null) { lastException.printStackTrace(); } else { System.out.println("completed"); } } } 2. Compiled the JDK and run the test: $ bash jib.sh configure -p linux-x64-slowdebug $ CONF=linux-x64-slowdebug make jdk $ ./build/linux-x64-slowdebug/jdk/bin/java -XX:+VerifyIntrinsicChecks --add-exports java.base/jdk.internal.access=ALL-UNNAMED StrIntri.java java.lang.ArrayIndexOutOfBoundsException: Range [2, 2 + 5) out of bounds for length 3 Received `AIOOBE` as expected. 3. Removed all checks in `StringCodec.java`, and re-compiled the JDK 4. Set the `countPositives(...)` arguments in the program to `(null, 1, 1)`, run it, and observed the VM crash with `unexpected null in intrinsic`. 5. Set the `countPositives(...)` arguments in the program to `(new byte[]{1,2,3}, 2, 5)`, run it, and observed the VM crash with `unexpected guard failure in intrinsic`. ------------- Commit messages: - Merge remote-tracking branch 'upstream/master' into strIntrinCheck - Fix `EUC_JP.java.template` broken due to `encodeASCII` rename - Remove `StringCodingCountPositives`, `String{En,De}code` already cover our cases - Improve intrinsics in `StringCoding` - Add `StringCodingCountPositives` benchmark - Apply review feedback - Move `StringCoding::countPositives` checks from C++ to Java Changes: https://git.openjdk.org/jdk/pull/25998/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=25998&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8361842 Stats: 271 lines in 18 files changed: 157 ins; 19 del; 95 mod Patch: https://git.openjdk.org/jdk/pull/25998.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/25998/head:pull/25998 PR: https://git.openjdk.org/jdk/pull/25998 From vyazici at openjdk.org Thu Jul 10 12:58:56 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Thu, 10 Jul 2025 12:58:56 GMT Subject: RFR: 8361842: Validate input in both Java and C++ for java.lang.StringCoding intrinsics In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Fri, 27 Jun 2025 20:21:31 GMT, ExE Boss wrote: >> My point is this is a performance-sensitive API. We are using a known-slow check method `checkFromIndexSize` which may introduce a performance regression. > > Maybe?use `jdk.internal.util.Preconditions` directly?instead? > Suggestion: > > Preconditions.checkFromIndexSize(off, len, ba.length, null); @ExE-Boss, I consulted this internally and decided to stick to using public APIs, unless there is a reason not to do so. In short, given `Objects::checkFromIndexSize` directly delegates to `Preconditions::checkFromIndexSize`, I expect that C2 will do its magic. Note my remark above that, prior to promoting this draft to a PR, a comprehensive benchmark suite run will be performed when all intrinsics of concern are addressed. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2185587428 From thartmann at openjdk.org Thu Jul 10 12:58:55 2025 From: thartmann at openjdk.org (Tobias Hartmann) Date: Thu, 10 Jul 2025 12:58:55 GMT Subject: RFR: 8361842: Validate input in both Java and C++ for java.lang.StringCoding intrinsics In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Thu, 26 Jun 2025 17:26:02 GMT, Chen Liang wrote: >> Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated C++ methods, and adapt them to cause VM crash on invalid input. >> >> ## Implementation notes >> >> The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, >> >> 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) >> 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too >> 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method >> 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag >> >> Following preliminary work needs to be carried out as well: >> >> 1. Add a new `VerifyIntrinsicChecks` VM flag >> 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. >> >> 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. >> >> ## Functional and performance tests >> >> - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. >> >> - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. >> >> ## Verification of the VM crash >> >> I've tested the VM crash scenario as follows: >> >> 1. Created the following test program: >> >> public class StrIntri { >> public static void main(String[] args) { >> Exception lastException = null; >> for (int i = 0; i < 1_000_000; i++) { >> try { >> jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); >> } catch (Exception exception) { >> lastException = exception; >> } >> } >> if (lastException != null) { >> lastException.printStackTrace(); >> ... > > src/java.base/share/classes/java/lang/StringCoding.java line 93: > >> 91: public static int countPositives(byte[] ba, int off, int len) { >> 92: Objects.requireNonNull(ba, "ba"); >> 93: Objects.checkFromIndexSize(off, len, ba.length); > > I recall core libraries intentionally avoided this because of performance problems. Is it possible for us to say trust the `len` argument to be non-negative? That allows us to simplify this to `Objects.checkIndex(off, ba.length - len)`. See this usage in perf-sensitive FFM API: https://github.com/openjdk/jdk/blob/149882416a956dec728a964c150b826dd589908f/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java#L401 But the original code already checks for `len >= 0`, right? See `LibraryCallKit::inline_countPositives` -> `generate_string_range_check` -> `// Offset and count must not be negative` This PR is about moving the range checks from the intrinsics into the Java wrappers. Removing range checks is out of the scope and should be carefully evaluated on a case-by-case basis separately. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2170997677 From vyazici at openjdk.org Thu Jul 10 12:58:56 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Thu, 10 Jul 2025 12:58:56 GMT Subject: RFR: 8361842: Validate input in both Java and C++ for java.lang.StringCoding intrinsics In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Fri, 4 Jul 2025 15:03:33 GMT, Volkan Yazici wrote: >> Maybe?use `jdk.internal.util.Preconditions` directly?instead? >> Suggestion: >> >> Preconditions.checkFromIndexSize(off, len, ba.length, null); > > @ExE-Boss, I consulted this internally and decided to stick to using public APIs, unless there is a reason not to do so. In short, given `Objects::checkFromIndexSize` directly delegates to `Preconditions::checkFromIndexSize`, I expect that C2 will do its magic. Note my remark above that, prior to promoting this draft to a PR, a comprehensive benchmark suite run will be performed when all intrinsics of concern are addressed. Doh! I've just noticed `Objects::checkFromIndexSize` throws `IndexOutOfBoundsException`, though we need `ArrayIndexOutOfBoundsException`. `Objects::checkFromIndexSize` doesn't accept an exception supplier, replacing it with `Preconditions::checkFromIndexSize`. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2185930404 From missa at openjdk.org Thu Jul 10 14:33:40 2025 From: missa at openjdk.org (Mohamed Issa) Date: Thu, 10 Jul 2025 14:33:40 GMT Subject: RFR: 8360559: Optimize Math.sinh for x86 64 bit platforms In-Reply-To: References: Message-ID: On Thu, 10 Jul 2025 04:52:01 GMT, Joe Darcy wrote: > What is the accuracy of the algorithm in ulps (units the last place)? > > The java.lang.Math specification has max error and various other accuracy requirements any implementation must meet. 0.51 ulps ------------- PR Comment: https://git.openjdk.org/jdk/pull/26152#issuecomment-3057699676 From kvn at openjdk.org Thu Jul 10 17:04:40 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Thu, 10 Jul 2025 17:04:40 GMT Subject: RFR: 8359344: C2: Malformed control flow after intrinsic bailout [v6] In-Reply-To: <-rnlrm6PHRZeO1izbXh5nOrm368YKrsFft1u6SHXzWA=.9c8e6646-0b72-4705-895e-f795f74f3906@github.com> References: <-rnlrm6PHRZeO1izbXh5nOrm368YKrsFft1u6SHXzWA=.9c8e6646-0b72-4705-895e-f795f74f3906@github.com> Message-ID: On Thu, 10 Jul 2025 06:13:27 GMT, Marc Chevalier wrote: >> When intrinsic bailout, we assume that the control in the `LibraryCallKit` did not change: >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L137 >> >> This is enforced by restoring the old state, like in >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L1722-L1732 >> >> That is good, but not sufficient. First, the most obvious, one could have already built some structure without moving the control. For instance, we can obtain something such as: >> >> ![1 after-intrinsic-bailout-during-late-inlining](https://github.com/user-attachments/assets/2fd255cc-0bfc-4841-8dd1-f64d502e0ee1) >> >> >> Here, during late inlining, the call `323` is candidate to be inline, but that bails out. Yet, a call to `make_unsafe_address` was made, which built nodes `354 If` and everything under. This is needed as tests are made on the resulting nodes (especially `366 AddP`) to know whether we should bail out or not. At the end, we get 2 control successor to `346 IfFalse`: the call that is not removed and the leftover of the intrinsic that will be cleanup much later, but not by RemoveUseless. >> >> Another situation is somewhat worse, when happening during parsing. It can lead to such cases: >> >> ![2 after-intrinsic-bailout-during-parsing](https://github.com/user-attachments/assets/4524c615-6521-4f0d-8f61-c426f9179035) >> >> The nodes `31 OpaqueNotNull`, `31 If`, `36 IfTrue`, `33 IfFalse`, `35 Halt`, `44 If`, `45 IfTrue`, `46 IfFalse` are leftover from a bailing out intrinsic. The replacement call `49 CallStaticJava` should come just under `5 Parm`, but the control was updated and the call is actually built under `36 If`. Then, why does the previous assert doesn't complain? >> >> This is because there is more than one control, or one map. In intrinsics that need to restore their state, the initial `SafePoint` map is cloned, the clone is kept aside, and if needed (bailing out), we set the current map to this saved clone. But there is another map from which the one of the `LibraryCallKit` comes, and that survives longer, it's the one that is contained in the `JVMState`: >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L101-L102 >> >> And here there is the challenge: >> - the `JVMState jvms` contains a `SafePoint` map, this map must have `jvms` as `jvms` (pointer comparison) >> ... > > Marc Chevalier has updated the pull request incrementally with two additional commits since the last revision: > > - Forgot to destruct_map_clone > - +'_' and ctor init Looks good. ------------- Marked as reviewed by kvn (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/25936#pullrequestreview-3006571921 From jrose at openjdk.org Thu Jul 10 20:56:38 2025 From: jrose at openjdk.org (John R Rose) Date: Thu, 10 Jul 2025 20:56:38 GMT Subject: RFR: 8361842: Validate input in both Java and C++ for java.lang.StringCoding intrinsics In-Reply-To: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: <4dolSfV2QJhf4nW0zxQ3Z6hti93KWU1PD9sYvXfYDnc=.307324ef-6bad-43ce-9397-e39abcfad410@github.com> On Thu, 26 Jun 2025 10:48:37 GMT, Volkan Yazici wrote: > Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated C++ methods, and adapt them to cause VM crash on invalid input. > > ## Implementation notes > > The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, > > 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) > 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too > 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method > 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag > > Following preliminary work needs to be carried out as well: > > 1. Add a new `VerifyIntrinsicChecks` VM flag > 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. > > 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. > > ## Functional and performance tests > > - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. > > - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. > > ## Verification of the VM crash > > I've tested the VM crash scenario as follows: > > 1. Created the following test program: > > public class StrIntri { > public static void main(String[] args) { > Exception lastException = null; > for (int i = 0; i < 1_000_000; i++) { > try { > jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); > } catch (Exception exception) { > lastException = exception; > } > } > if (lastException != null) { > lastException.printStackTrace(); > } else { > System.out.println("completed"); > } > } > } > > 2. Comp... I disagree with a small part of the statement of goals: > Always validate all input at the intrinsic (but preferably behind a VM flag) As formulated above, this is a violation of DRY and if embraced the wrong way will lead to code that is harder to review and prove bug-free. Performing 100% accurate range/null/validation checks is deeply impractical for an assembly-based or IR-based intrinsic. It?s too hard to verify by code review, and coverage testing is suspect. We must frankly put all the weight of verification on Java code, including Java bytecode intrinsic behaviors. Java code is high-level and can be read mostly as a declarative spec, if clearly written (as straight-line code, then the intrinsic call). Also, such simple Java code shapes (and their underlying bytecodes) are tested many orders of magnitude more than any given intrinsic. I see two bits of evidence that you agree with me on this: 1. The intrinsic-local validation (IR or assembly) is allowed to Halt instead of throw, and 2. the intrinsic-local validation is optional, turned on only by a stress test mode. This tells me that the extra optional testing is also not required to be 100%. Thus, I think the above goal would be better stated this way: > Validate input in the IR or assembly code of the intrinsic in an ad hoc manner to catch bugs in the Java validation. > Note: IR or assembly based validation code should not obscure the code or add large maintenance costs, and under a VM diagnostic flag (or debug flag), and causing a VM halt instead of a Java throw. I think I'm agreeing with you on the material points. It is important to summarize our intentions accurately at the top, for those readers that are reading only the top as a summary. ------------- PR Comment: https://git.openjdk.org/jdk/pull/25998#issuecomment-3059044829 From darcy at openjdk.org Thu Jul 10 21:26:37 2025 From: darcy at openjdk.org (Joe Darcy) Date: Thu, 10 Jul 2025 21:26:37 GMT Subject: RFR: 8360559: Optimize Math.sinh for x86 64 bit platforms In-Reply-To: References: Message-ID: On Thu, 10 Jul 2025 14:31:02 GMT, Mohamed Issa wrote: > > What is the accuracy of the algorithm in ulps (units the last place)? > > The java.lang.Math specification has max error and various other accuracy requirements any implementation must meet. > > 0.51 ulps Please add that as a comment to the changeset. Also, if the worst-case inputs for this algorithm are known, they should the added as part of the core libraries regression tests for the math library. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26152#issuecomment-3059152934 From mchevalier at openjdk.org Fri Jul 11 07:09:54 2025 From: mchevalier at openjdk.org (Marc Chevalier) Date: Fri, 11 Jul 2025 07:09:54 GMT Subject: RFR: 8359344: C2: Malformed control flow after intrinsic bailout [v6] In-Reply-To: <-rnlrm6PHRZeO1izbXh5nOrm368YKrsFft1u6SHXzWA=.9c8e6646-0b72-4705-895e-f795f74f3906@github.com> References: <-rnlrm6PHRZeO1izbXh5nOrm368YKrsFft1u6SHXzWA=.9c8e6646-0b72-4705-895e-f795f74f3906@github.com> Message-ID: On Thu, 10 Jul 2025 06:13:27 GMT, Marc Chevalier wrote: >> When intrinsic bailout, we assume that the control in the `LibraryCallKit` did not change: >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L137 >> >> This is enforced by restoring the old state, like in >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L1722-L1732 >> >> That is good, but not sufficient. First, the most obvious, one could have already built some structure without moving the control. For instance, we can obtain something such as: >> >> ![1 after-intrinsic-bailout-during-late-inlining](https://github.com/user-attachments/assets/2fd255cc-0bfc-4841-8dd1-f64d502e0ee1) >> >> >> Here, during late inlining, the call `323` is candidate to be inline, but that bails out. Yet, a call to `make_unsafe_address` was made, which built nodes `354 If` and everything under. This is needed as tests are made on the resulting nodes (especially `366 AddP`) to know whether we should bail out or not. At the end, we get 2 control successor to `346 IfFalse`: the call that is not removed and the leftover of the intrinsic that will be cleanup much later, but not by RemoveUseless. >> >> Another situation is somewhat worse, when happening during parsing. It can lead to such cases: >> >> ![2 after-intrinsic-bailout-during-parsing](https://github.com/user-attachments/assets/4524c615-6521-4f0d-8f61-c426f9179035) >> >> The nodes `31 OpaqueNotNull`, `31 If`, `36 IfTrue`, `33 IfFalse`, `35 Halt`, `44 If`, `45 IfTrue`, `46 IfFalse` are leftover from a bailing out intrinsic. The replacement call `49 CallStaticJava` should come just under `5 Parm`, but the control was updated and the call is actually built under `36 If`. Then, why does the previous assert doesn't complain? >> >> This is because there is more than one control, or one map. In intrinsics that need to restore their state, the initial `SafePoint` map is cloned, the clone is kept aside, and if needed (bailing out), we set the current map to this saved clone. But there is another map from which the one of the `LibraryCallKit` comes, and that survives longer, it's the one that is contained in the `JVMState`: >> >> https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L101-L102 >> >> And here there is the challenge: >> - the `JVMState jvms` contains a `SafePoint` map, this map must have `jvms` as `jvms` (pointer comparison) >> ... > > Marc Chevalier has updated the pull request incrementally with two additional commits since the last revision: > > - Forgot to destruct_map_clone > - +'_' and ctor init Thanks @vnkozlov and @TobiHartmann for reviews! ------------- PR Comment: https://git.openjdk.org/jdk/pull/25936#issuecomment-3060908007 From mchevalier at openjdk.org Fri Jul 11 07:09:55 2025 From: mchevalier at openjdk.org (Marc Chevalier) Date: Fri, 11 Jul 2025 07:09:55 GMT Subject: Integrated: 8359344: C2: Malformed control flow after intrinsic bailout In-Reply-To: References: Message-ID: On Mon, 23 Jun 2025 13:09:43 GMT, Marc Chevalier wrote: > When intrinsic bailout, we assume that the control in the `LibraryCallKit` did not change: > > https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L137 > > This is enforced by restoring the old state, like in > > https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L1722-L1732 > > That is good, but not sufficient. First, the most obvious, one could have already built some structure without moving the control. For instance, we can obtain something such as: > > ![1 after-intrinsic-bailout-during-late-inlining](https://github.com/user-attachments/assets/2fd255cc-0bfc-4841-8dd1-f64d502e0ee1) > > > Here, during late inlining, the call `323` is candidate to be inline, but that bails out. Yet, a call to `make_unsafe_address` was made, which built nodes `354 If` and everything under. This is needed as tests are made on the resulting nodes (especially `366 AddP`) to know whether we should bail out or not. At the end, we get 2 control successor to `346 IfFalse`: the call that is not removed and the leftover of the intrinsic that will be cleanup much later, but not by RemoveUseless. > > Another situation is somewhat worse, when happening during parsing. It can lead to such cases: > > ![2 after-intrinsic-bailout-during-parsing](https://github.com/user-attachments/assets/4524c615-6521-4f0d-8f61-c426f9179035) > > The nodes `31 OpaqueNotNull`, `31 If`, `36 IfTrue`, `33 IfFalse`, `35 Halt`, `44 If`, `45 IfTrue`, `46 IfFalse` are leftover from a bailing out intrinsic. The replacement call `49 CallStaticJava` should come just under `5 Parm`, but the control was updated and the call is actually built under `36 If`. Then, why does the previous assert doesn't complain? > > This is because there is more than one control, or one map. In intrinsics that need to restore their state, the initial `SafePoint` map is cloned, the clone is kept aside, and if needed (bailing out), we set the current map to this saved clone. But there is another map from which the one of the `LibraryCallKit` comes, and that survives longer, it's the one that is contained in the `JVMState`: > > https://github.com/openjdk/jdk/blob/c4fb00a7be51c7a05a29d3d57d787feb5c698ddf/src/hotspot/share/opto/library_call.cpp#L101-L102 > > And here there is the challenge: > - the `JVMState jvms` contains a `SafePoint` map, this map must have `jvms` as `jvms` (pointer comparison) > - we can't really change the pointer, just the content > -... This pull request has now been integrated. Changeset: 3ffc5b9e Author: Marc Chevalier URL: https://git.openjdk.org/jdk/commit/3ffc5b9ef720a07143ef5728d2597afdf2f2c251 Stats: 358 lines in 7 files changed: 240 ins; 75 del; 43 mod 8359344: C2: Malformed control flow after intrinsic bailout Reviewed-by: thartmann, kvn ------------- PR: https://git.openjdk.org/jdk/pull/25936 From vyazici at openjdk.org Fri Jul 11 08:40:40 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Fri, 11 Jul 2025 08:40:40 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics In-Reply-To: <4dolSfV2QJhf4nW0zxQ3Z6hti93KWU1PD9sYvXfYDnc=.307324ef-6bad-43ce-9397-e39abcfad410@github.com> References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> <4dolSfV2QJhf4nW0zxQ3Z6hti93KWU1PD9sYvXfYDnc=.307324ef-6bad-43ce-9397-e39abcfad410@github.com> Message-ID: On Thu, 10 Jul 2025 20:54:24 GMT, John R Rose wrote: >> Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. >> >> ## Implementation notes >> >> The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, >> >> 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) >> 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too >> 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method >> 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag >> >> Following preliminary work needs to be carried out as well: >> >> 1. Add a new `VerifyIntrinsicChecks` VM flag >> 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. >> >> 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. >> >> ## Functional and performance tests >> >> - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. >> >> - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. >> >> ## Verification of the VM crash >> >> I've tested the VM crash scenario as follows: >> >> 1. Created the following test program: >> >> public class StrIntri { >> public static void main(String[] args) { >> Exception lastException = null; >> for (int i = 0; i < 1_000_000; i++) { >> try { >> jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); >> } catch (Exception exception) { >> lastException = exception; >> } >> } >> if (lastException != null) { >> lastException.printStackTrace... > > I disagree with a small part of the statement of goals: > >> Always validate all input at the intrinsic (but preferably behind a VM flag) > > As formulated above, this is a violation of DRY and if embraced the wrong way will lead to code that is harder to review and prove bug-free. Performing 100% accurate range/null/validation checks is deeply impractical for an assembly-based or IR-based intrinsic. It?s too hard to verify by code review, and coverage testing is suspect. > > We must frankly put all the weight of verification on Java code, including Java bytecode intrinsic behaviors. Java code is high-level and can be read mostly as a declarative spec, if clearly written (as straight-line code, then the intrinsic call). Also, such simple Java code shapes (and their underlying bytecodes) are tested many orders of magnitude more than any given intrinsic. > > I see two bits of evidence that you agree with me on this: 1. The intrinsic-local validation (IR or assembly) is allowed to Halt instead of throw, and 2. the intrinsic-local validation is optional, turned on only by a stress test mode. This tells me that the extra optional testing is also not required to be 100%. > > Thus, I think the above goal would be better stated this way: > >> Validate input in the IR or assembly code of the intrinsic in an ad hoc manner to catch bugs in the Java validation. > >> Note: IR or assembly based validation code should not obscure the code or add large maintenance costs, and under a VM diagnostic flag (or debug flag), and causing a VM halt instead of a Java throw. > > I think I'm agreeing with you on the material points. It is important to summarize our intentions accurately at the top, for those readers that are reading only the top as a summary. @rose00, thanks so much for the feedback. I agree with your remarks and get your points on _"Always validate all input at the intrinsic"_ is a violation of DRY and an impractical goal. I incorporated your suggestions as follows: 1. Renamed the ticket to `Move input validation checks to Java for String-related intrinsics` (to better reflect the goal) 2. Replaced `Always validate all input at the intrinsic...` with your suggestion ------------- PR Comment: https://git.openjdk.org/jdk/pull/25998#issuecomment-3061201145 From duke at openjdk.org Sun Jul 13 18:31:59 2025 From: duke at openjdk.org (duke) Date: Sun, 13 Jul 2025 18:31:59 GMT Subject: Withdrawn: 8342382: Implementation of JEP G1: Improve Application Throughput with a More Efficient Write-Barrier In-Reply-To: References: Message-ID: On Sun, 23 Feb 2025 18:53:33 GMT, Thomas Schatzl wrote: > Hi all, > > please review this change that implements (currently Draft) JEP: G1: Improve Application Throughput with a More Efficient Write-Barrier. > > The reason for posting this early is that this is a large change, and the JEP process is already taking very long with no end in sight but we would like to have this ready by JDK 25. > > ### Current situation > > With this change, G1 will reduce the post write barrier to much more resemble Parallel GC's as described in the JEP. The reason is that G1 lacks in throughput compared to Parallel/Serial GC due to larger barrier. > > The main reason for the current barrier is how g1 implements concurrent refinement: > * g1 tracks dirtied cards using sets (dirty card queue set - dcqs) of buffers (dirty card queues - dcq) containing the location of dirtied cards. Refinement threads pick up their contents to re-refine. The barrier needs to enqueue card locations. > * For correctness dirty card updates requires fine-grained synchronization between mutator and refinement threads, > * Finally there is generic code to avoid dirtying cards altogether (filters), to avoid executing the synchronization and the enqueuing as much as possible. > > These tasks require the current barrier to look as follows for an assignment `x.a = y` in pseudo code: > > > // Filtering > if (region(@x.a) == region(y)) goto done; // same region check > if (y == null) goto done; // null value check > if (card(@x.a) == young_card) goto done; // write to young gen check > StoreLoad; // synchronize > if (card(@x.a) == dirty_card) goto done; > > *card(@x.a) = dirty > > // Card tracking > enqueue(card-address(@x.a)) into thread-local-dcq; > if (thread-local-dcq is not full) goto done; > > call runtime to move thread-local-dcq into dcqs > > done: > > > Overall this post-write barrier alone is in the range of 40-50 total instructions, compared to three or four(!) for parallel and serial gc. > > The large size of the inlined barrier not only has a large code footprint, but also prevents some compiler optimizations like loop unrolling or inlining. > > There are several papers showing that this barrier alone can decrease throughput by 10-20% ([Yang12](https://dl.acm.org/doi/10.1145/2426642.2259004)), which is corroborated by some benchmarks (see links). > > The main idea for this change is to not use fine-grained synchronization between refinement and mutator threads, but coarse grained based on atomically switching card tables. Mutators only work on the "primary" card table, refinement threads on a se... This pull request has been closed without being integrated. ------------- PR: https://git.openjdk.org/jdk/pull/23739 From tschatzl at openjdk.org Mon Jul 14 08:03:47 2025 From: tschatzl at openjdk.org (Thomas Schatzl) Date: Mon, 14 Jul 2025 08:03:47 GMT Subject: RFR: 8342382: Implementation of JEP G1: Improve Application Throughput with a More Efficient Write-Barrier [v41] In-Reply-To: References: Message-ID: On Mon, 7 Jul 2025 12:36:40 GMT, Thomas Schatzl wrote: >> Hi all, >> >> please review this change that implements (currently Draft) JEP: G1: Improve Application Throughput with a More Efficient Write-Barrier. >> >> The reason for posting this early is that this is a large change, and the JEP process is already taking very long with no end in sight but we would like to have this ready by JDK 25. >> >> ### Current situation >> >> With this change, G1 will reduce the post write barrier to much more resemble Parallel GC's as described in the JEP. The reason is that G1 lacks in throughput compared to Parallel/Serial GC due to larger barrier. >> >> The main reason for the current barrier is how g1 implements concurrent refinement: >> * g1 tracks dirtied cards using sets (dirty card queue set - dcqs) of buffers (dirty card queues - dcq) containing the location of dirtied cards. Refinement threads pick up their contents to re-refine. The barrier needs to enqueue card locations. >> * For correctness dirty card updates requires fine-grained synchronization between mutator and refinement threads, >> * Finally there is generic code to avoid dirtying cards altogether (filters), to avoid executing the synchronization and the enqueuing as much as possible. >> >> These tasks require the current barrier to look as follows for an assignment `x.a = y` in pseudo code: >> >> >> // Filtering >> if (region(@x.a) == region(y)) goto done; // same region check >> if (y == null) goto done; // null value check >> if (card(@x.a) == young_card) goto done; // write to young gen check >> StoreLoad; // synchronize >> if (card(@x.a) == dirty_card) goto done; >> >> *card(@x.a) = dirty >> >> // Card tracking >> enqueue(card-address(@x.a)) into thread-local-dcq; >> if (thread-local-dcq is not full) goto done; >> >> call runtime to move thread-local-dcq into dcqs >> >> done: >> >> >> Overall this post-write barrier alone is in the range of 40-50 total instructions, compared to three or four(!) for parallel and serial gc. >> >> The large size of the inlined barrier not only has a large code footprint, but also prevents some compiler optimizations like loop unrolling or inlining. >> >> There are several papers showing that this barrier alone can decrease throughput by 10-20% ([Yang12](https://dl.acm.org/doi/10.1145/2426642.2259004)), which is corroborated by some benchmarks (see links). >> >> The main idea for this change is to not use fine-grained synchronization between refinement and mutator threads, but coarse grained based on atomically switching c... > > Thomas Schatzl has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 57 commits: > > - Merge branch 'master' into 8342382-card-table-instead-of-dcq > - Merge branch 'master' into 8342382-card-table-instead-of-dcq > - Merge branch 'master' into 8342382-card-table-instead-of-dcq > - Merge branch 'master' into 8342382-card-table-instead-of-dcq > - * ayang review: remove sweep_epoch > - Merge branch 'master' into card-table-as-dcq-merge > - Merge branch 'master' into 8342382-card-table-instead-of-dcq > - * ayang review (part 2 - yield duration changes) > - * ayang review (part 1) > - * indentation fix > - ... and 47 more: https://git.openjdk.org/jdk/compare/d75ea7e6...441c234a Not yet... ------------- PR Comment: https://git.openjdk.org/jdk/pull/23739#issuecomment-3068246695 From aph at openjdk.org Mon Jul 14 08:25:48 2025 From: aph at openjdk.org (Andrew Haley) Date: Mon, 14 Jul 2025 08:25:48 GMT Subject: RFR: 8342382: Implementation of JEP G1: Improve Application Throughput with a More Efficient Write-Barrier [v41] In-Reply-To: References: Message-ID: On Mon, 7 Jul 2025 12:36:40 GMT, Thomas Schatzl wrote: >> Hi all, >> >> please review this change that implements (currently Draft) JEP: G1: Improve Application Throughput with a More Efficient Write-Barrier. >> >> The reason for posting this early is that this is a large change, and the JEP process is already taking very long with no end in sight but we would like to have this ready by JDK 25. >> >> ### Current situation >> >> With this change, G1 will reduce the post write barrier to much more resemble Parallel GC's as described in the JEP. The reason is that G1 lacks in throughput compared to Parallel/Serial GC due to larger barrier. >> >> The main reason for the current barrier is how g1 implements concurrent refinement: >> * g1 tracks dirtied cards using sets (dirty card queue set - dcqs) of buffers (dirty card queues - dcq) containing the location of dirtied cards. Refinement threads pick up their contents to re-refine. The barrier needs to enqueue card locations. >> * For correctness dirty card updates requires fine-grained synchronization between mutator and refinement threads, >> * Finally there is generic code to avoid dirtying cards altogether (filters), to avoid executing the synchronization and the enqueuing as much as possible. >> >> These tasks require the current barrier to look as follows for an assignment `x.a = y` in pseudo code: >> >> >> // Filtering >> if (region(@x.a) == region(y)) goto done; // same region check >> if (y == null) goto done; // null value check >> if (card(@x.a) == young_card) goto done; // write to young gen check >> StoreLoad; // synchronize >> if (card(@x.a) == dirty_card) goto done; >> >> *card(@x.a) = dirty >> >> // Card tracking >> enqueue(card-address(@x.a)) into thread-local-dcq; >> if (thread-local-dcq is not full) goto done; >> >> call runtime to move thread-local-dcq into dcqs >> >> done: >> >> >> Overall this post-write barrier alone is in the range of 40-50 total instructions, compared to three or four(!) for parallel and serial gc. >> >> The large size of the inlined barrier not only has a large code footprint, but also prevents some compiler optimizations like loop unrolling or inlining. >> >> There are several papers showing that this barrier alone can decrease throughput by 10-20% ([Yang12](https://dl.acm.org/doi/10.1145/2426642.2259004)), which is corroborated by some benchmarks (see links). >> >> The main idea for this change is to not use fine-grained synchronization between refinement and mutator threads, but coarse grained based on atomically switching c... > > Thomas Schatzl has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 57 commits: > > - Merge branch 'master' into 8342382-card-table-instead-of-dcq > - Merge branch 'master' into 8342382-card-table-instead-of-dcq > - Merge branch 'master' into 8342382-card-table-instead-of-dcq > - Merge branch 'master' into 8342382-card-table-instead-of-dcq > - * ayang review: remove sweep_epoch > - Merge branch 'master' into card-table-as-dcq-merge > - Merge branch 'master' into 8342382-card-table-instead-of-dcq > - * ayang review (part 2 - yield duration changes) > - * ayang review (part 1) > - * indentation fix > - ... and 47 more: https://git.openjdk.org/jdk/compare/d75ea7e6...441c234a AArch64 looks good. ------------- Marked as reviewed by aph (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/23739#pullrequestreview-3015276922 From tschatzl at openjdk.org Mon Jul 14 09:13:38 2025 From: tschatzl at openjdk.org (Thomas Schatzl) Date: Mon, 14 Jul 2025 09:13:38 GMT Subject: RFR: 8342382: Implementation of JEP G1: Improve Application Throughput with a More Efficient Write-Barrier [v42] In-Reply-To: References: Message-ID: <8lZdT84SJ-daIPPpdq35hAZ0MGa8b07TPpPa3IDp030=.201a5b52-aecb-424e-9bdf-4c64baff5e87@github.com> > Hi all, > > please review this change that implements (currently Draft) JEP: G1: Improve Application Throughput with a More Efficient Write-Barrier. > > The reason for posting this early is that this is a large change, and the JEP process is already taking very long with no end in sight but we would like to have this ready by JDK 25. > > ### Current situation > > With this change, G1 will reduce the post write barrier to much more resemble Parallel GC's as described in the JEP. The reason is that G1 lacks in throughput compared to Parallel/Serial GC due to larger barrier. > > The main reason for the current barrier is how g1 implements concurrent refinement: > * g1 tracks dirtied cards using sets (dirty card queue set - dcqs) of buffers (dirty card queues - dcq) containing the location of dirtied cards. Refinement threads pick up their contents to re-refine. The barrier needs to enqueue card locations. > * For correctness dirty card updates requires fine-grained synchronization between mutator and refinement threads, > * Finally there is generic code to avoid dirtying cards altogether (filters), to avoid executing the synchronization and the enqueuing as much as possible. > > These tasks require the current barrier to look as follows for an assignment `x.a = y` in pseudo code: > > > // Filtering > if (region(@x.a) == region(y)) goto done; // same region check > if (y == null) goto done; // null value check > if (card(@x.a) == young_card) goto done; // write to young gen check > StoreLoad; // synchronize > if (card(@x.a) == dirty_card) goto done; > > *card(@x.a) = dirty > > // Card tracking > enqueue(card-address(@x.a)) into thread-local-dcq; > if (thread-local-dcq is not full) goto done; > > call runtime to move thread-local-dcq into dcqs > > done: > > > Overall this post-write barrier alone is in the range of 40-50 total instructions, compared to three or four(!) for parallel and serial gc. > > The large size of the inlined barrier not only has a large code footprint, but also prevents some compiler optimizations like loop unrolling or inlining. > > There are several papers showing that this barrier alone can decrease throughput by 10-20% ([Yang12](https://dl.acm.org/doi/10.1145/2426642.2259004)), which is corroborated by some benchmarks (see links). > > The main idea for this change is to not use fine-grained synchronization between refinement and mutator threads, but coarse grained based on atomically switching card tables. Mutators only work on the "primary" card table, refinement threads on a se... Thomas Schatzl has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 58 commits: - Merge branch 'master' into pull/23739 - Merge branch 'master' into 8342382-card-table-instead-of-dcq - Merge branch 'master' into 8342382-card-table-instead-of-dcq - Merge branch 'master' into 8342382-card-table-instead-of-dcq - Merge branch 'master' into 8342382-card-table-instead-of-dcq - * ayang review: remove sweep_epoch - Merge branch 'master' into card-table-as-dcq-merge - Merge branch 'master' into 8342382-card-table-instead-of-dcq - * ayang review (part 2 - yield duration changes) - * ayang review (part 1) - ... and 48 more: https://git.openjdk.org/jdk/compare/14c79be1...5ab928e8 ------------- Changes: https://git.openjdk.org/jdk/pull/23739/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=23739&range=41 Stats: 7124 lines in 112 files changed: 2589 ins; 3594 del; 941 mod Patch: https://git.openjdk.org/jdk/pull/23739.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/23739/head:pull/23739 PR: https://git.openjdk.org/jdk/pull/23739 From dfenacci at openjdk.org Mon Jul 14 10:34:45 2025 From: dfenacci at openjdk.org (Damon Fenacci) Date: Mon, 14 Jul 2025 10:34:45 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics In-Reply-To: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Thu, 26 Jun 2025 10:48:37 GMT, Volkan Yazici wrote: > Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. > > ## Implementation notes > > The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, > > 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) > 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too > 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method > 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag > > Following preliminary work needs to be carried out as well: > > 1. Add a new `VerifyIntrinsicChecks` VM flag > 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. > > 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. > > ## Functional and performance tests > > - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. > > - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. > > ## Verification of the VM crash > > I've tested the VM crash scenario as follows: > > 1. Created the following test program: > > public class StrIntri { > public static void main(String[] args) { > Exception lastException = null; > for (int i = 0; i < 1_000_000; i++) { > try { > jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); > } catch (Exception exception) { > lastException = exception; > } > } > if (lastException != null) { > lastException.printStackTrace(); > } else { > System.out.println("completed"); > } > } > } > ... Thanks a lot for looking into this Volkan! I left a couple of minor comments. I also noticed that you haven't yet added the benchmark results to the description: do you want to run them again after the reviews? src/hotspot/cpu/x86/macroAssembler_x86.cpp line 6014: > 6012: } > 6013: > 6014: // Encode given `char[]`/`byte[]` to `byte[]` in ISO_8859_1 or ASCII Thanks for updating the comments! Do we need the markdown back quotes here (and in other `macroAssembler-*` file comments)? src/hotspot/share/classfile/vmIntrinsics.hpp line 417: > 415: \ > 416: do_class(java_lang_StringCoding, "java/lang/StringCoding") \ > 417: do_intrinsic(_countPositives, java_lang_StringCoding, countPositives_name, countPositives_signature, F_S) \ It is a matter of taste but it might be better not to change the whitespaces (it might make searching for changes (and possibly backports) harder. The rest of the file is not too consistent anyway). src/hotspot/share/opto/c2_globals.hpp line 666: > 664: \ > 665: develop(bool, VerifyIntrinsicChecks, false, \ > 666: "Verify that Java level checks in intrinsics work as expected") \ To make it clearer I think we might want to move "in intrinsic" after "Verify" or at the end. ------------- PR Review: https://git.openjdk.org/jdk/pull/25998#pullrequestreview-3015376813 PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2204312397 PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2204505403 PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2204256430 From vyazici at openjdk.org Tue Jul 15 19:21:28 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Tue, 15 Jul 2025 19:21:28 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v2] In-Reply-To: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: <3ySadb4ljhHpenFOP9xRX2su1JyWBXWlRv09x--NnBc=.ea4de36e-403b-4cd9-831a-a80aacfcfde5@github.com> > Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. > > ## Implementation notes > > The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, > > 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) > 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too > 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method > 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag > > Following preliminary work needs to be carried out as well: > > 1. Add a new `VerifyIntrinsicChecks` VM flag > 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. > > 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. > > ## Functional and performance tests > > - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. > > - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. > > ## Verification of the VM crash > > I've tested the VM crash scenario as follows: > > 1. Created the following test program: > > public class StrIntri { > public static void main(String[] args) { > Exception lastException = null; > for (int i = 0; i < 1_000_000; i++) { > try { > jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); > } catch (Exception exception) { > lastException = exception; > } > } > if (lastException != null) { > lastException.printStackTrace(); > } else { > System.out.println("completed"); > } > } > } > ... Volkan Yazici has updated the pull request incrementally with three additional commits since the last revision: - Minimize the number of touched lines in `vmIntrinsics.hpp` - Remove Markdown-styling in comments - Improve wording of the `VerifyIntrinsicChecks` flag ------------- Changes: - all: https://git.openjdk.org/jdk/pull/25998/files - new: https://git.openjdk.org/jdk/pull/25998/files/6af98646..7c042b35 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=25998&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=25998&range=00-01 Stats: 14 lines in 5 files changed: 0 ins; 0 del; 14 mod Patch: https://git.openjdk.org/jdk/pull/25998.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/25998/head:pull/25998 PR: https://git.openjdk.org/jdk/pull/25998 From vyazici at openjdk.org Tue Jul 15 19:21:29 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Tue, 15 Jul 2025 19:21:29 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v2] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Mon, 14 Jul 2025 08:49:44 GMT, Damon Fenacci wrote: >> Volkan Yazici has updated the pull request incrementally with three additional commits since the last revision: >> >> - Minimize the number of touched lines in `vmIntrinsics.hpp` >> - Remove Markdown-styling in comments >> - Improve wording of the `VerifyIntrinsicChecks` flag > > src/hotspot/share/opto/c2_globals.hpp line 666: > >> 664: \ >> 665: develop(bool, VerifyIntrinsicChecks, false, \ >> 666: "Verify that Java level checks in intrinsics work as expected") \ > > To make it clearer I think we might want to move "in intrinsic" after "Verify" or at the end. Changed as suggested in c331fbfa. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2208455093 From vyazici at openjdk.org Tue Jul 15 19:27:44 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Tue, 15 Jul 2025 19:27:44 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v2] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Mon, 14 Jul 2025 10:27:45 GMT, Damon Fenacci wrote: >> Volkan Yazici has updated the pull request incrementally with three additional commits since the last revision: >> >> - Minimize the number of touched lines in `vmIntrinsics.hpp` >> - Remove Markdown-styling in comments >> - Improve wording of the `VerifyIntrinsicChecks` flag > > src/hotspot/share/classfile/vmIntrinsics.hpp line 417: > >> 415: \ >> 416: do_class(java_lang_StringCoding, "java/lang/StringCoding") \ >> 417: do_intrinsic(_countPositives, java_lang_StringCoding, countPositives_name, countPositives_signature, F_S) \ > > It is a matter of taste but it might be better not to change the whitespaces (it might make searching for changes (and possibly backports) harder. The rest of the file is not too consistent anyway). Fixed in 7c042b35. I completely agree with your point. In fact, I'm opposed to _"vertical alignment"_ due to its obvious maintainability and version control hygiene issues. Alas, that is the existing style, and I tried to adhere to it. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2208469532 From vyazici at openjdk.org Tue Jul 15 19:31:42 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Tue, 15 Jul 2025 19:31:42 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v2] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Mon, 14 Jul 2025 09:11:08 GMT, Damon Fenacci wrote: >> Volkan Yazici has updated the pull request incrementally with three additional commits since the last revision: >> >> - Minimize the number of touched lines in `vmIntrinsics.hpp` >> - Remove Markdown-styling in comments >> - Improve wording of the `VerifyIntrinsicChecks` flag > > src/hotspot/cpu/x86/macroAssembler_x86.cpp line 6014: > >> 6012: } >> 6013: >> 6014: // Encode given `char[]`/`byte[]` to `byte[]` in ISO_8859_1 or ASCII > > Thanks for updating the comments! Do we need the markdown back quotes here (and in other `macroAssembler-*` file comments)? No, we don't. Since Markdown has become ubiquitous in text-based typesetting, I find it easier to read and, whenever needed, share it in other mediums; Slack, GitHub, JIRA, Javadoc, Microsoft Office 365, Google Docs, etc. I presume you prefer without backticks ? removed them in b60ff457. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2208477825 From vyazici at openjdk.org Tue Jul 15 19:34:42 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Tue, 15 Jul 2025 19:34:42 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v2] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: <0Rbm6JuupxK9iYkXljWRpmdCAg_fmf_92FUckntpQ3A=.7c633679-c46c-4395-8431-8564301b0dbb@github.com> On Mon, 14 Jul 2025 10:32:24 GMT, Damon Fenacci wrote: > I left a couple of minor comments. I also noticed that you haven't yet added the benchmark results to the description: do you want to run them again after the reviews? @dafedafe, thanks so much for the review! I've implemented the changes you requested, and shared some benchmark figures in the associated ticket. I am still actively working on evaluating the performance impact. ------------- PR Comment: https://git.openjdk.org/jdk/pull/25998#issuecomment-3075223785 From rriggs at openjdk.org Tue Jul 15 19:50:43 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Tue, 15 Jul 2025 19:50:43 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v2] In-Reply-To: <3ySadb4ljhHpenFOP9xRX2su1JyWBXWlRv09x--NnBc=.ea4de36e-403b-4cd9-831a-a80aacfcfde5@github.com> References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> <3ySadb4ljhHpenFOP9xRX2su1JyWBXWlRv09x--NnBc=.ea4de36e-403b-4cd9-831a-a80aacfcfde5@github.com> Message-ID: On Tue, 15 Jul 2025 19:21:28 GMT, Volkan Yazici wrote: >> Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. >> >> ## Implementation notes >> >> The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, >> >> 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) >> 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too >> 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method >> 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag >> >> Following preliminary work needs to be carried out as well: >> >> 1. Add a new `VerifyIntrinsicChecks` VM flag >> 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. >> >> 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. >> >> ## Functional and performance tests >> >> - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. >> >> - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. >> >> ## Verification of the VM crash >> >> I've tested the VM crash scenario as follows: >> >> 1. Created the following test program: >> >> public class StrIntri { >> public static void main(String[] args) { >> Exception lastException = null; >> for (int i = 0; i < 1_000_000; i++) { >> try { >> jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); >> } catch (Exception exception) { >> lastException = exception; >> } >> } >> if (lastException != null) { >> lastException.printStackTrace... > > Volkan Yazici has updated the pull request incrementally with three additional commits since the last revision: > > - Minimize the number of touched lines in `vmIntrinsics.hpp` > - Remove Markdown-styling in comments > - Improve wording of the `VerifyIntrinsicChecks` flag src/java.base/share/classes/java/lang/StringCoding.java line 36: > 34: import static java.util.Objects.requireNonNull; > 35: import static jdk.internal.util.Preconditions.AIOOBE_FORMATTER; > 36: import static jdk.internal.util.Preconditions.checkFromIndexSize; Avoid import static of methods, it makes the code harder to read and understand where the methods come from. Just import Preconditions. src/java.base/share/classes/java/lang/StringCoding.java line 162: > 160: if (c > '\u00FF') > 161: break; > 162: da[dp++] = (byte) c; Revert: Omit the space after (byte); there many more usages of "(byte)c" and this file does not need to drift from the prevailing style in StringUTF16.java AbstractStringBuilder, etc. Here and at line 195: src/java.base/share/classes/java/lang/StringCoding.java line 189: > 187: > 188: @IntrinsicCandidate > 189: private static int encodeAsciiArray0(char[] sa, int sp, byte[] da, int dp, int len) { I rather prefer the readability of the src and dest parameters being on separate lines. (but not "{" by itself Suggestion: private static int encodeAsciiArray0(char[] sa, int sp, byte[] da, int dp, int len) { src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java line 43: > 41: import static java.util.Objects.requireNonNull; > 42: import static jdk.internal.util.Preconditions.AIOOBE_FORMATTER; > 43: import static jdk.internal.util.Preconditions.checkFromIndexSize; Avoid static imports of methods, it makes it harder to read and know where the methods are especially when crossing package boundaries. src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java line 177: > 175: if (c > '\u00FF') > 176: break; > 177: da[dp++] = (byte) c; Revert extra space. src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java line 201: > 199: int len = (dlen < slen) ? dlen : slen; > 200: try { > 201: int ret = len <= 0 ? 0 : encodeISOArray(sa, sp, da, dp, len); Moving the length correction into `encodeISOArray` would help other callers too. (There's only 1 at the moment). ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2208470957 PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2208491363 PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2208494207 PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2208503099 PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2208504829 PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2208510343 From vyazici at openjdk.org Tue Jul 15 20:24:04 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Tue, 15 Jul 2025 20:24:04 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v3] In-Reply-To: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: <8vCbaelpmz8qseHlyYRYiF0iDIycfg63fnthX52ZqJk=.3fa6d066-4a5b-4dae-8bcd-d25a336ccb94@github.com> > Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. > > ## Implementation notes > > The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, > > 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) > 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too > 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method > 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag > > Following preliminary work needs to be carried out as well: > > 1. Add a new `VerifyIntrinsicChecks` VM flag > 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. > > 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. > > ## Functional and performance tests > > - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. > > - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. > > ## Verification of the VM crash > > I've tested the VM crash scenario as follows: > > 1. Created the following test program: > > public class StrIntri { > public static void main(String[] args) { > Exception lastException = null; > for (int i = 0; i < 1_000_000; i++) { > try { > jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); > } catch (Exception exception) { > lastException = exception; > } > } > if (lastException != null) { > lastException.printStackTrace(); > } else { > System.out.println("completed"); > } > } > } > ... Volkan Yazici has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains 12 additional commits since the last revision: - Merge remote-tracking branch 'upstream/master' into strIntrinCheck - Apply review feedback (styling changes) - Minimize the number of touched lines in `vmIntrinsics.hpp` - Remove Markdown-styling in comments - Improve wording of the `VerifyIntrinsicChecks` flag - Merge remote-tracking branch 'upstream/master' into strIntrinCheck - Fix `EUC_JP.java.template` broken due to `encodeASCII` rename - Remove `StringCodingCountPositives`, `String{En,De}code` already cover our cases This reverts commit 196fc5d406851b8e7070c97ac53ca59c4615aad9. - Improve intrinsics in `StringCoding` - Add `StringCodingCountPositives` benchmark - ... and 2 more: https://git.openjdk.org/jdk/compare/b424f31d...85f19864 ------------- Changes: - all: https://git.openjdk.org/jdk/pull/25998/files - new: https://git.openjdk.org/jdk/pull/25998/files/7c042b35..85f19864 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=25998&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=25998&range=01-02 Stats: 7104 lines in 199 files changed: 2886 ins; 3418 del; 800 mod Patch: https://git.openjdk.org/jdk/pull/25998.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/25998/head:pull/25998 PR: https://git.openjdk.org/jdk/pull/25998 From vyazici at openjdk.org Tue Jul 15 20:24:04 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Tue, 15 Jul 2025 20:24:04 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v2] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> <3ySadb4ljhHpenFOP9xRX2su1JyWBXWlRv09x--NnBc=.ea4de36e-403b-4cd9-831a-a80aacfcfde5@github.com> Message-ID: On Tue, 15 Jul 2025 19:25:31 GMT, Roger Riggs wrote: >> Volkan Yazici has updated the pull request incrementally with three additional commits since the last revision: >> >> - Minimize the number of touched lines in `vmIntrinsics.hpp` >> - Remove Markdown-styling in comments >> - Improve wording of the `VerifyIntrinsicChecks` flag > > src/java.base/share/classes/java/lang/StringCoding.java line 36: > >> 34: import static java.util.Objects.requireNonNull; >> 35: import static jdk.internal.util.Preconditions.AIOOBE_FORMATTER; >> 36: import static jdk.internal.util.Preconditions.checkFromIndexSize; > > Avoid import static of methods, it makes the code harder to read and understand where the methods come from. > Just import Preconditions. Fixed in 2672f7c1ada. > src/java.base/share/classes/java/lang/StringCoding.java line 162: > >> 160: if (c > '\u00FF') >> 161: break; >> 162: da[dp++] = (byte) c; > > Revert: Omit the space after (byte); there many more usages of "(byte)c" and this file does not need to drift from the prevailing style in StringUTF16.java AbstractStringBuilder, etc. > Here and at line 195: I've actually made these changes to match the code shared in intrinsics, e.g., `macroAssembler_x86.cpp`. Reverted them in 2672f7c1ada as you requested. > src/java.base/share/classes/java/lang/StringCoding.java line 189: > >> 187: >> 188: @IntrinsicCandidate >> 189: private static int encodeAsciiArray0(char[] sa, int sp, byte[] da, int dp, int len) { > > I rather prefer the readability of the src and dest parameters being on separate lines. (but not "{" by itself > Suggestion: > > private static int encodeAsciiArray0(char[] sa, int sp, > byte[] da, int dp, int len) { Changed as requested in 2672f7c1ada. > src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java line 43: > >> 41: import static java.util.Objects.requireNonNull; >> 42: import static jdk.internal.util.Preconditions.AIOOBE_FORMATTER; >> 43: import static jdk.internal.util.Preconditions.checkFromIndexSize; > > Avoid static imports of methods, it makes it harder to read and know where the methods are especially when crossing package boundaries. Changed as requested in 2672f7c1ada. > src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java line 177: > >> 175: if (c > '\u00FF') >> 176: break; >> 177: da[dp++] = (byte) c; > > Revert extra space. Changed as requested in 2672f7c1ada. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2208575103 PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2208578241 PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2208579144 PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2208579489 PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2208579689 From vyazici at openjdk.org Tue Jul 15 20:26:41 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Tue, 15 Jul 2025 20:26:41 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v2] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> <3ySadb4ljhHpenFOP9xRX2su1JyWBXWlRv09x--NnBc=.ea4de36e-403b-4cd9-831a-a80aacfcfde5@github.com> Message-ID: On Tue, 15 Jul 2025 19:45:33 GMT, Roger Riggs wrote: >> Volkan Yazici has updated the pull request incrementally with three additional commits since the last revision: >> >> - Minimize the number of touched lines in `vmIntrinsics.hpp` >> - Remove Markdown-styling in comments >> - Improve wording of the `VerifyIntrinsicChecks` flag > > src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java line 201: > >> 199: int len = (dlen < slen) ? dlen : slen; >> 200: try { >> 201: int ret = len <= 0 ? 0 : encodeISOArray(sa, sp, da, dp, len); > > Moving the length correction into `encodeISOArray` would help other callers too. (There's only 1 at the moment). I've tried to make the code such that wrapper functions contain nothing but argument checks. Moving `if (len <= 0) { return 0; }` logic to the wrapper function will introduce a behavior different than the one implemented by the intrinsic. @RogerRiggs, do you still prefer me to carry out this change? ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2208585771 From rriggs at openjdk.org Tue Jul 15 20:32:43 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Tue, 15 Jul 2025 20:32:43 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v2] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> <3ySadb4ljhHpenFOP9xRX2su1JyWBXWlRv09x--NnBc=.ea4de36e-403b-4cd9-831a-a80aacfcfde5@github.com> Message-ID: <97fQvq2H2iV-UmT7CnECiBAza6fhFXdexNzkyPOaThc=.482af2ba-78a5-4201-b1b5-476d24c93f39@github.com> On Tue, 15 Jul 2025 20:24:22 GMT, Volkan Yazici wrote: >> src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java line 201: >> >>> 199: int len = (dlen < slen) ? dlen : slen; >>> 200: try { >>> 201: int ret = len <= 0 ? 0 : encodeISOArray(sa, sp, da, dp, len); >> >> Moving the length correction into `encodeISOArray` would help other callers too. (There's only 1 at the moment). > > I've tried to make the code such that wrapper functions contain nothing but argument checks. Moving `if (len <= 0) { return 0; }` logic to the wrapper function will introduce a behavior different than the one implemented by the intrinsic. @RogerRiggs, do you still prefer me to carry out this change? The wrapper is the method actually called, the intrinsic `encodeISOArray0` intrinsic would be inlined into it. I don't have a compelling reason to change it, given the solitary caller. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2208599130 From rriggs at openjdk.org Tue Jul 15 21:52:45 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Tue, 15 Jul 2025 21:52:45 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v3] In-Reply-To: <8vCbaelpmz8qseHlyYRYiF0iDIycfg63fnthX52ZqJk=.3fa6d066-4a5b-4dae-8bcd-d25a336ccb94@github.com> References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> <8vCbaelpmz8qseHlyYRYiF0iDIycfg63fnthX52ZqJk=.3fa6d066-4a5b-4dae-8bcd-d25a336ccb94@github.com> Message-ID: On Tue, 15 Jul 2025 20:24:04 GMT, Volkan Yazici wrote: >> Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. >> >> ## Implementation notes >> >> The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, >> >> 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) >> 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too >> 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method >> 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag >> >> Following preliminary work needs to be carried out as well: >> >> 1. Add a new `VerifyIntrinsicChecks` VM flag >> 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. >> >> 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. >> >> ## Functional and performance tests >> >> - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. >> >> - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. >> >> ## Verification of the VM crash >> >> I've tested the VM crash scenario as follows: >> >> 1. Created the following test program: >> >> public class StrIntri { >> public static void main(String[] args) { >> Exception lastException = null; >> for (int i = 0; i < 1_000_000; i++) { >> try { >> jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); >> } catch (Exception exception) { >> lastException = exception; >> } >> } >> if (lastException != null) { >> lastException.printStackTrace... > > Volkan Yazici has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains 12 additional commits since the last revision: > > - Merge remote-tracking branch 'upstream/master' into strIntrinCheck > - Apply review feedback (styling changes) > - Minimize the number of touched lines in `vmIntrinsics.hpp` > - Remove Markdown-styling in comments > - Improve wording of the `VerifyIntrinsicChecks` flag > - Merge remote-tracking branch 'upstream/master' into strIntrinCheck > - Fix `EUC_JP.java.template` broken due to `encodeASCII` rename > - Remove `StringCodingCountPositives`, `String{En,De}code` already cover our cases > > This reverts commit 196fc5d406851b8e7070c97ac53ca59c4615aad9. > - Improve intrinsics in `StringCoding` > - Add `StringCodingCountPositives` benchmark > - ... and 2 more: https://git.openjdk.org/jdk/compare/611f6cea...85f19864 Looks good, thanks for the updates. A Hotspot reviewer should approve also. /Reviewers 2 reviewer ------------- Marked as reviewed by rriggs (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/25998#pullrequestreview-3022453251 PR Comment: https://git.openjdk.org/jdk/pull/25998#issuecomment-3075835741 From thartmann at openjdk.org Wed Jul 16 05:32:45 2025 From: thartmann at openjdk.org (Tobias Hartmann) Date: Wed, 16 Jul 2025 05:32:45 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v3] In-Reply-To: <8vCbaelpmz8qseHlyYRYiF0iDIycfg63fnthX52ZqJk=.3fa6d066-4a5b-4dae-8bcd-d25a336ccb94@github.com> References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> <8vCbaelpmz8qseHlyYRYiF0iDIycfg63fnthX52ZqJk=.3fa6d066-4a5b-4dae-8bcd-d25a336ccb94@github.com> Message-ID: <4zqK_rAHpX2bdDGf_kw2TOXtdOgONZykPs7mlR-rDrA=.d7d2bcd4-1e48-40ed-9628-46a681a5c4bb@github.com> On Tue, 15 Jul 2025 20:24:04 GMT, Volkan Yazici wrote: >> Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. >> >> ## Implementation notes >> >> The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, >> >> 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) >> 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too >> 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method >> 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag >> >> Following preliminary work needs to be carried out as well: >> >> 1. Add a new `VerifyIntrinsicChecks` VM flag >> 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. >> >> 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. >> >> ## Functional and performance tests >> >> - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. >> >> - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. >> >> ## Verification of the VM crash >> >> I've tested the VM crash scenario as follows: >> >> 1. Created the following test program: >> >> public class StrIntri { >> public static void main(String[] args) { >> Exception lastException = null; >> for (int i = 0; i < 1_000_000; i++) { >> try { >> jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); >> } catch (Exception exception) { >> lastException = exception; >> } >> } >> if (lastException != null) { >> lastException.printStackTrace... > > Volkan Yazici has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains 12 additional commits since the last revision: > > - Merge remote-tracking branch 'upstream/master' into strIntrinCheck > - Apply review feedback (styling changes) > - Minimize the number of touched lines in `vmIntrinsics.hpp` > - Remove Markdown-styling in comments > - Improve wording of the `VerifyIntrinsicChecks` flag > - Merge remote-tracking branch 'upstream/master' into strIntrinCheck > - Fix `EUC_JP.java.template` broken due to `encodeASCII` rename > - Remove `StringCodingCountPositives`, `String{En,De}code` already cover our cases > > This reverts commit 196fc5d406851b8e7070c97ac53ca59c4615aad9. > - Improve intrinsics in `StringCoding` > - Add `StringCodingCountPositives` benchmark > - ... and 2 more: https://git.openjdk.org/jdk/compare/32d96877...85f19864 Thanks a lot for working on this, Volkan! The changes look good to me, I just added two comments. src/hotspot/share/opto/c2_globals.hpp line 665: > 663: "prints attempted and successful inlining of intrinsics") \ > 664: \ > 665: develop(bool, VerifyIntrinsicChecks, false, \ We should add testing that uses this new flag. Maybe we could add a run to the tests that check the affected intrinsics? We could also add it to our (Oracle internal) stress test jobs at higher tiers. src/hotspot/share/opto/library_call.cpp line 971: > 969: } else { > 970: PreserveJVMState pjvms(this); > 971: set_control(_gvn.transform(bailout)); Suggestion: bailout = _gvn.transform(bailout); if (halt) { Node* frame = _gvn.transform(new ParmNode(C->start(), TypeFunc::FramePtr)); Node* halt = _gvn.transform(new HaltNode(bailout, frame, "unexpected guard failure in intrinsic")); C->root()->add_req(halt); } else { PreserveJVMState pjvms(this); set_control(bailout); ------------- Marked as reviewed by thartmann (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/25998#pullrequestreview-3023137214 PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2209259866 PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2209245394 From vyazici at openjdk.org Wed Jul 16 07:51:26 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Wed, 16 Jul 2025 07:51:26 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v4] In-Reply-To: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: <3L2KmYco1fW5Or9Lzhp17mW-Pk-ANOp5UYQ6sL3gZfs=.d7560969-8b3f-478f-a89d-2c34cf875ec9@github.com> > Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. > > ## Implementation notes > > The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, > > 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) > 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too > 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method > 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag > > Following preliminary work needs to be carried out as well: > > 1. Add a new `VerifyIntrinsicChecks` VM flag > 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. > > 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. > > ## Functional and performance tests > > - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. > > - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. > > ## Verification of the VM crash > > I've tested the VM crash scenario as follows: > > 1. Created the following test program: > > public class StrIntri { > public static void main(String[] args) { > Exception lastException = null; > for (int i = 0; i < 1_000_000; i++) { > try { > jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); > } catch (Exception exception) { > lastException = exception; > } > } > if (lastException != null) { > lastException.printStackTrace(); > } else { > System.out.println("completed"); > } > } > } > ... Volkan Yazici has updated the pull request incrementally with one additional commit since the last revision: Improve `generate_string_range_check` changes Co-authored-by: Tobias Hartmann ------------- Changes: - all: https://git.openjdk.org/jdk/pull/25998/files - new: https://git.openjdk.org/jdk/pull/25998/files/85f19864..2b89e880 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=25998&range=03 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=25998&range=02-03 Stats: 4 lines in 1 file changed: 1 ins; 1 del; 2 mod Patch: https://git.openjdk.org/jdk/pull/25998.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/25998/head:pull/25998 PR: https://git.openjdk.org/jdk/pull/25998 From dnsimon at openjdk.org Wed Jul 16 08:43:49 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Wed, 16 Jul 2025 08:43:49 GMT Subject: RFR: 8362306: HotSpotJVMCIRuntime.getMirror can crash Message-ID: This PR fixes `HotSpotJVMCIRuntime.getMirror(ResolvedJavaMethod method)` and `HotSpotJVMCIRuntime.getMirror(ResolvedJavaField field)` so that they return null for `` and an injected field respectively instead of crashing. ------------- Commit messages: - fixed bug in HotSpotJVMCIRuntime.getMirror for and injected fields Changes: https://git.openjdk.org/jdk/pull/26346/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=26346&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8362306 Stats: 68 lines in 5 files changed: 58 ins; 1 del; 9 mod Patch: https://git.openjdk.org/jdk/pull/26346.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26346/head:pull/26346 PR: https://git.openjdk.org/jdk/pull/26346 From dnsimon at openjdk.org Wed Jul 16 08:48:53 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Wed, 16 Jul 2025 08:48:53 GMT Subject: RFR: 8362306: HotSpotJVMCIRuntime.getMirror can crash [v2] In-Reply-To: References: Message-ID: > This PR fixes `HotSpotJVMCIRuntime.getMirror(ResolvedJavaMethod method)` and `HotSpotJVMCIRuntime.getMirror(ResolvedJavaField field)` so that they return null for `` and an injected field respectively instead of crashing. Doug Simon has refreshed the contents of this pull request, and previous commits have been removed. The incremental views will show differences compared to the previous content of the PR. The pull request contains one new commit since the last revision: fixed bug in HotSpotJVMCIRuntime.getMirror for and injected fields ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26346/files - new: https://git.openjdk.org/jdk/pull/26346/files/8c44d9ff..cca137a3 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26346&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26346&range=00-01 Stats: 1 line in 1 file changed: 1 ins; 0 del; 0 mod Patch: https://git.openjdk.org/jdk/pull/26346.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26346/head:pull/26346 PR: https://git.openjdk.org/jdk/pull/26346 From gdub at openjdk.org Wed Jul 16 10:27:40 2025 From: gdub at openjdk.org (Gilles Duboscq) Date: Wed, 16 Jul 2025 10:27:40 GMT Subject: RFR: 8362306: HotSpotJVMCIRuntime.getMirror can crash [v2] In-Reply-To: References: Message-ID: On Wed, 16 Jul 2025 08:48:53 GMT, Doug Simon wrote: >> This PR fixes `HotSpotJVMCIRuntime.getMirror(ResolvedJavaMethod method)` and `HotSpotJVMCIRuntime.getMirror(ResolvedJavaField field)` so that they return null for `` and an injected field respectively instead of crashing. > > Doug Simon has refreshed the contents of this pull request, and previous commits have been removed. The incremental views will show differences compared to the previous content of the PR. The pull request contains one new commit since the last revision: > > fixed bug in HotSpotJVMCIRuntime.getMirror for and injected fields src/hotspot/share/jvmci/jvmciCompilerToVM.cpp line 3000: > 2998: } > 2999: > 3000: C2V_VMENTRY_NULL(jobject, asReflectionField, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass), jint index)) There is the same pattern in `getEncodedFieldAnnotationData`, we should probably defend there as well. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26346#discussion_r2209921506 From dnsimon at openjdk.org Wed Jul 16 13:17:04 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Wed, 16 Jul 2025 13:17:04 GMT Subject: RFR: 8362306: HotSpotJVMCIRuntime.getMirror can crash [v3] In-Reply-To: References: Message-ID: > This PR fixes `HotSpotJVMCIRuntime.getMirror(ResolvedJavaMethod method)` and `HotSpotJVMCIRuntime.getMirror(ResolvedJavaField field)` so that they return null for `` and an injected field respectively instead of crashing. Doug Simon has updated the pull request incrementally with two additional commits since the last revision: - fixed bug in use of JVMCI traps - moved inject field check into check_field for benefit of get_encoded_annotation_data ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26346/files - new: https://git.openjdk.org/jdk/pull/26346/files/cca137a3..c76efe51 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26346&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26346&range=01-02 Stats: 17 lines in 1 file changed: 8 ins; 4 del; 5 mod Patch: https://git.openjdk.org/jdk/pull/26346.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26346/head:pull/26346 PR: https://git.openjdk.org/jdk/pull/26346 From dnsimon at openjdk.org Wed Jul 16 13:17:04 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Wed, 16 Jul 2025 13:17:04 GMT Subject: RFR: 8362306: HotSpotJVMCIRuntime.getMirror can crash [v2] In-Reply-To: References: Message-ID: On Wed, 16 Jul 2025 10:25:24 GMT, Gilles Duboscq wrote: >> Doug Simon has refreshed the contents of this pull request, and previous commits have been removed. The incremental views will show differences compared to the previous content of the PR. The pull request contains one new commit since the last revision: >> >> fixed bug in HotSpotJVMCIRuntime.getMirror for and injected fields > > src/hotspot/share/jvmci/jvmciCompilerToVM.cpp line 3000: > >> 2998: } >> 2999: >> 3000: C2V_VMENTRY_NULL(jobject, asReflectionField, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass), jint index)) > > There is the same pattern in `getEncodedFieldAnnotationData`, we should probably defend there as well. Good point: c2c41aa20ef214c5f63942cc5e257dfaaafb13ea ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26346#discussion_r2210397327 From gdub at openjdk.org Wed Jul 16 14:42:49 2025 From: gdub at openjdk.org (Gilles Duboscq) Date: Wed, 16 Jul 2025 14:42:49 GMT Subject: RFR: 8362306: HotSpotJVMCIRuntime.getMirror can crash [v3] In-Reply-To: References: Message-ID: On Wed, 16 Jul 2025 13:17:04 GMT, Doug Simon wrote: >> This PR fixes `HotSpotJVMCIRuntime.getMirror(ResolvedJavaMethod method)` and `HotSpotJVMCIRuntime.getMirror(ResolvedJavaField field)` so that they return null for `` and an injected field respectively instead of crashing. > > Doug Simon has updated the pull request incrementally with two additional commits since the last revision: > > - fixed bug in use of JVMCI traps > - moved inject field check into check_field for benefit of get_encoded_annotation_data src/hotspot/share/jvmci/jvmciCompilerToVM.cpp line 3084: > 3082: CompilerThreadCanCallJava canCallJava(thread, true); // Requires Java support > 3083: InstanceKlass* holder = InstanceKlass::cast(UNPACK_PAIR(Klass, klass)); > 3084: return get_encoded_annotation_data(holder, holder->class_annotations(), true, filter_length, filter_klass_pointers, THREAD, JVMCI_CHECK_NULL); Can `JVMCI_CHECK_` be used in `return` statements? i think the "check and return default value" part would be unreachable. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26346#discussion_r2210628575 From dnsimon at openjdk.org Wed Jul 16 15:03:36 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Wed, 16 Jul 2025 15:03:36 GMT Subject: RFR: 8362306: HotSpotJVMCIRuntime.getMirror can crash [v4] In-Reply-To: References: Message-ID: > This PR fixes `HotSpotJVMCIRuntime.getMirror(ResolvedJavaMethod method)` and `HotSpotJVMCIRuntime.getMirror(ResolvedJavaField field)` so that they return null for `` and an injected field respectively instead of crashing. Doug Simon has updated the pull request incrementally with one additional commit since the last revision: revert from JVMCI_CHECK_NULL back to JVMCIENV in final return statement of method ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26346/files - new: https://git.openjdk.org/jdk/pull/26346/files/c76efe51..7cf4b26c Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26346&range=03 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26346&range=02-03 Stats: 4 lines in 1 file changed: 0 ins; 0 del; 4 mod Patch: https://git.openjdk.org/jdk/pull/26346.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26346/head:pull/26346 PR: https://git.openjdk.org/jdk/pull/26346 From dnsimon at openjdk.org Wed Jul 16 15:03:39 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Wed, 16 Jul 2025 15:03:39 GMT Subject: RFR: 8362306: HotSpotJVMCIRuntime.getMirror can crash [v3] In-Reply-To: References: Message-ID: On Wed, 16 Jul 2025 14:38:35 GMT, Gilles Duboscq wrote: >> Doug Simon has updated the pull request incrementally with two additional commits since the last revision: >> >> - fixed bug in use of JVMCI traps >> - moved inject field check into check_field for benefit of get_encoded_annotation_data > > src/hotspot/share/jvmci/jvmciCompilerToVM.cpp line 3084: > >> 3082: CompilerThreadCanCallJava canCallJava(thread, true); // Requires Java support >> 3083: InstanceKlass* holder = InstanceKlass::cast(UNPACK_PAIR(Klass, klass)); >> 3084: return get_encoded_annotation_data(holder, holder->class_annotations(), true, filter_length, filter_klass_pointers, THREAD, JVMCI_CHECK_NULL); > > Can `JVMCI_CHECK_` be used in `return` statements? i think the "check and return default value" part would be unreachable. Indeed - I've been bitten by this before! In this case, it's harmless given that the return statement is anyway the last statement in the method. Still, I'll revert my "fix". I'm also wondering (again?) why the C++ compiler does not warning about unreachable code. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26346#discussion_r2210679057 From gdub at openjdk.org Wed Jul 16 15:12:40 2025 From: gdub at openjdk.org (Gilles Duboscq) Date: Wed, 16 Jul 2025 15:12:40 GMT Subject: RFR: 8362306: HotSpotJVMCIRuntime.getMirror can crash [v4] In-Reply-To: References: Message-ID: <6dUGyR9-38wxACBU-qXBcUdNuChfSQjPXNHpKsAJ3Y4=.f2397b87-fd84-4e87-9d52-0cda901810df@github.com> On Wed, 16 Jul 2025 15:03:36 GMT, Doug Simon wrote: >> This PR fixes `HotSpotJVMCIRuntime.getMirror(ResolvedJavaMethod method)` and `HotSpotJVMCIRuntime.getMirror(ResolvedJavaField field)` so that they return null for `` and an injected field respectively instead of crashing. > > Doug Simon has updated the pull request incrementally with one additional commit since the last revision: > > revert from JVMCI_CHECK_NULL back to JVMCIENV in final return statement of method Maybe you could add a test in `TestResolvedJavaType.getClassInitializer` to check that `getMirror` doesn't crash on that and returns null? ------------- PR Comment: https://git.openjdk.org/jdk/pull/26346#issuecomment-3079072065 From dnsimon at openjdk.org Wed Jul 16 15:40:27 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Wed, 16 Jul 2025 15:40:27 GMT Subject: RFR: 8362306: HotSpotJVMCIRuntime.getMirror can crash [v5] In-Reply-To: References: Message-ID: > This PR fixes `HotSpotJVMCIRuntime.getMirror(ResolvedJavaMethod method)` and `HotSpotJVMCIRuntime.getMirror(ResolvedJavaField field)` so that they return null for `` and an injected field respectively instead of crashing. Doug Simon has updated the pull request incrementally with one additional commit since the last revision: test that getMirror on clinit returns null ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26346/files - new: https://git.openjdk.org/jdk/pull/26346/files/7cf4b26c..fd44d95c Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26346&range=04 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26346&range=03-04 Stats: 1 line in 1 file changed: 1 ins; 0 del; 0 mod Patch: https://git.openjdk.org/jdk/pull/26346.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26346/head:pull/26346 PR: https://git.openjdk.org/jdk/pull/26346 From dnsimon at openjdk.org Wed Jul 16 15:40:27 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Wed, 16 Jul 2025 15:40:27 GMT Subject: RFR: 8362306: HotSpotJVMCIRuntime.getMirror can crash [v4] In-Reply-To: <6dUGyR9-38wxACBU-qXBcUdNuChfSQjPXNHpKsAJ3Y4=.f2397b87-fd84-4e87-9d52-0cda901810df@github.com> References: <6dUGyR9-38wxACBU-qXBcUdNuChfSQjPXNHpKsAJ3Y4=.f2397b87-fd84-4e87-9d52-0cda901810df@github.com> Message-ID: On Wed, 16 Jul 2025 15:09:43 GMT, Gilles Duboscq wrote: > Maybe you could add a test in `TestResolvedJavaType.getClassInitializer` to check that `getMirror` doesn't crash on that and returns null? Done: https://github.com/openjdk/jdk/pull/26346/commits/fd44d95c83bb9160395b5fe94298f1a300233001 ------------- PR Comment: https://git.openjdk.org/jdk/pull/26346#issuecomment-3079185834 From gdub at openjdk.org Wed Jul 16 15:49:41 2025 From: gdub at openjdk.org (Gilles Duboscq) Date: Wed, 16 Jul 2025 15:49:41 GMT Subject: RFR: 8362306: HotSpotJVMCIRuntime.getMirror can crash [v5] In-Reply-To: References: Message-ID: On Wed, 16 Jul 2025 15:40:27 GMT, Doug Simon wrote: >> This PR fixes `HotSpotJVMCIRuntime.getMirror(ResolvedJavaMethod method)` and `HotSpotJVMCIRuntime.getMirror(ResolvedJavaField field)` so that they return null for `` and an injected field respectively instead of crashing. > > Doug Simon has updated the pull request incrementally with one additional commit since the last revision: > > test that getMirror on clinit returns null Marked as reviewed by gdub (Committer). ------------- PR Review: https://git.openjdk.org/jdk/pull/26346#pullrequestreview-3025670605 From vyazici at openjdk.org Wed Jul 16 19:38:02 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Wed, 16 Jul 2025 19:38:02 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v5] In-Reply-To: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: > Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. > > ## Implementation notes > > The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, > > 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) > 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too > 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method > 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag > > Following preliminary work needs to be carried out as well: > > 1. Add a new `VerifyIntrinsicChecks` VM flag > 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. > > 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. > > ## Functional and performance tests > > - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. > > - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. > > ## Verification of the VM crash > > I've tested the VM crash scenario as follows: > > 1. Created the following test program: > > public class StrIntri { > public static void main(String[] args) { > Exception lastException = null; > for (int i = 0; i < 1_000_000; i++) { > try { > jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); > } catch (Exception exception) { > lastException = exception; > } > } > if (lastException != null) { > lastException.printStackTrace(); > } else { > System.out.println("completed"); > } > } > } > ... Volkan Yazici has updated the pull request incrementally with one additional commit since the last revision: Add test verifying the effectiveness of `VerifyIntrinsicChecks` ------------- Changes: - all: https://git.openjdk.org/jdk/pull/25998/files - new: https://git.openjdk.org/jdk/pull/25998/files/2b89e880..8941e6b6 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=25998&range=04 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=25998&range=03-04 Stats: 110 lines in 3 files changed: 108 ins; 0 del; 2 mod Patch: https://git.openjdk.org/jdk/pull/25998.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/25998/head:pull/25998 PR: https://git.openjdk.org/jdk/pull/25998 From vyazici at openjdk.org Wed Jul 16 19:42:32 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Wed, 16 Jul 2025 19:42:32 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v6] In-Reply-To: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: > Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. > > ## Implementation notes > > The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, > > 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) > 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too > 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method > 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag > > Following preliminary work needs to be carried out as well: > > 1. Add a new `VerifyIntrinsicChecks` VM flag > 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. > > 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. > > ## Functional and performance tests > > - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. > > - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. > > ## Verification of the VM crash > > I've tested the VM crash scenario as follows: > > 1. Created the following test program: > > public class StrIntri { > public static void main(String[] args) { > Exception lastException = null; > for (int i = 0; i < 1_000_000; i++) { > try { > jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); > } catch (Exception exception) { > lastException = exception; > } > } > if (lastException != null) { > lastException.printStackTrace(); > } else { > System.out.println("completed"); > } > } > } > ... Volkan Yazici has refreshed the contents of this pull request, and previous commits have been removed. The incremental views will show differences compared to the previous content of the PR. The pull request contains one new commit since the last revision: Add test verifying the effectiveness of `VerifyIntrinsicChecks` ------------- Changes: - all: https://git.openjdk.org/jdk/pull/25998/files - new: https://git.openjdk.org/jdk/pull/25998/files/8941e6b6..bcb073cb Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=25998&range=05 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=25998&range=04-05 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/25998.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/25998/head:pull/25998 PR: https://git.openjdk.org/jdk/pull/25998 From cslucas at openjdk.org Wed Jul 16 22:54:47 2025 From: cslucas at openjdk.org (Cesar Soares Lucas) Date: Wed, 16 Jul 2025 22:54:47 GMT Subject: RFR: 8362306: HotSpotJVMCIRuntime.getMirror can crash [v5] In-Reply-To: References: Message-ID: On Wed, 16 Jul 2025 15:40:27 GMT, Doug Simon wrote: >> This PR fixes `HotSpotJVMCIRuntime.getMirror(ResolvedJavaMethod method)` and `HotSpotJVMCIRuntime.getMirror(ResolvedJavaField field)` so that they return null for `` and an injected field respectively instead of crashing. > > Doug Simon has updated the pull request incrementally with one additional commit since the last revision: > > test that getMirror on clinit returns null LGTM ------------- Marked as reviewed by cslucas (Committer). PR Review: https://git.openjdk.org/jdk/pull/26346#pullrequestreview-3027147958 From vyazici at openjdk.org Thu Jul 17 04:37:49 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Thu, 17 Jul 2025 04:37:49 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v6] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Thu, 10 Jul 2025 12:23:06 GMT, Volkan Yazici wrote: >> Volkan Yazici has refreshed the contents of this pull request, and previous commits have been removed. The incremental views will show differences compared to the previous content of the PR. The pull request contains one new commit since the last revision: >> >> Add test verifying the effectiveness of `VerifyIntrinsicChecks` > > src/hotspot/share/opto/library_call.cpp line 963: > >> 961: >> 962: if (bailout->req() > 1) { >> 963: if (halt) { > > Toggle to force a VM crash to be used to surface intrinsic Java wrappers failing to spot invalid input. @TobiHartmann, this change results in the following compiler error: /home/vy/.../src/hotspot/share/opto/library_call.cpp:958:35: error: invalid conversion from 'Node*' to 'RegionNode*' [-fpermissive] 958 | generate_negative_guard(offset, bailout); | ^~~~~~~ | | | Node* That is, `bailout` is supposed to be of type `RegionNode*`, but `_gvn.transform()` returns a value of type `Node*`. I will locally amend this change as bailout = (RegionNode*) _gvn.transform(bailout); Let me know if you disagree. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2212232094 From vyazici at openjdk.org Thu Jul 17 06:13:30 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Thu, 17 Jul 2025 06:13:30 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v7] In-Reply-To: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: > Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. > > ## Implementation notes > > The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, > > 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) > 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too > 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method > 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag > > Following preliminary work needs to be carried out as well: > > 1. Add a new `VerifyIntrinsicChecks` VM flag > 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. > > 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. > > ## Functional and performance tests > > - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. > > - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. > > ## Verification of the VM crash > > I've tested the VM crash scenario as follows: > > 1. Created the following test program: > > public class StrIntri { > public static void main(String[] args) { > Exception lastException = null; > for (int i = 0; i < 1_000_000; i++) { > try { > jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); > } catch (Exception exception) { > lastException = exception; > } > } > if (lastException != null) { > lastException.printStackTrace(); > } else { > System.out.println("completed"); > } > } > } > ... Volkan Yazici has updated the pull request incrementally with two additional commits since the last revision: - Duplicate affected tests with `-XX:+VerifyIntrinsicChecks` variants - Fix compiler error in `generate_string_range_check` ------------- Changes: - all: https://git.openjdk.org/jdk/pull/25998/files - new: https://git.openjdk.org/jdk/pull/25998/files/bcb073cb..abc0eeb3 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=25998&range=06 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=25998&range=05-06 Stats: 61 lines in 4 files changed: 53 ins; 2 del; 6 mod Patch: https://git.openjdk.org/jdk/pull/25998.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/25998/head:pull/25998 PR: https://git.openjdk.org/jdk/pull/25998 From vyazici at openjdk.org Thu Jul 17 06:15:53 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Thu, 17 Jul 2025 06:15:53 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v3] In-Reply-To: <4zqK_rAHpX2bdDGf_kw2TOXtdOgONZykPs7mlR-rDrA=.d7d2bcd4-1e48-40ed-9628-46a681a5c4bb@github.com> References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> <8vCbaelpmz8qseHlyYRYiF0iDIycfg63fnthX52ZqJk=.3fa6d066-4a5b-4dae-8bcd-d25a336ccb94@github.com> <4zqK_rAHpX2bdDGf_kw2TOXtdOgONZykPs7mlR-rDrA=.d7d2bcd4-1e48-40ed-9628-46a681a5c4bb@github.com> Message-ID: On Wed, 16 Jul 2025 05:28:55 GMT, Tobias Hartmann wrote: >> Volkan Yazici has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains 12 additional commits since the last revision: >> >> - Merge remote-tracking branch 'upstream/master' into strIntrinCheck >> - Apply review feedback (styling changes) >> - Minimize the number of touched lines in `vmIntrinsics.hpp` >> - Remove Markdown-styling in comments >> - Improve wording of the `VerifyIntrinsicChecks` flag >> - Merge remote-tracking branch 'upstream/master' into strIntrinCheck >> - Fix `EUC_JP.java.template` broken due to `encodeASCII` rename >> - Remove `StringCodingCountPositives`, `String{En,De}code` already cover our cases >> >> This reverts commit 196fc5d406851b8e7070c97ac53ca59c4615aad9. >> - Improve intrinsics in `StringCoding` >> - Add `StringCodingCountPositives` benchmark >> - ... and 2 more: https://git.openjdk.org/jdk/compare/921f85ab...85f19864 > > src/hotspot/share/opto/c2_globals.hpp line 665: > >> 663: "prints attempted and successful inlining of intrinsics") \ >> 664: \ >> 665: develop(bool, VerifyIntrinsicChecks, false, \ > > We should add testing that uses this new flag. Maybe we could add a run to the tests that check the affected intrinsics? We could also add it to our (Oracle internal) stress test jobs at higher tiers. @TobiHartmann, agreed. I've pushed two commits: 1. bcb073cbb41 adds `TestVerifyIntrinsicChecks` to verify the effectiveness of the `VerifyIntrinsicChecks` VM flag. That is, does VM indeed crash if intrinsic Java wrapper fails to properly validate the input? 2. abc0eeb3bfc adds a separate `/* @test ... @run ... -XX:+VerifyIntrinsicChecks` block to the tests using `StringCoding` intrinsics Please let me know if these two address your remarks. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2212371103 From vyazici at openjdk.org Thu Jul 17 06:21:56 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Thu, 17 Jul 2025 06:21:56 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v7] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: <66HgANGbmZLWZpH-g9ChFl_VX3WRq_WgYlq4edeVAIg=.7e3f06ab-ba80-4952-9ff5-168d64025783@github.com> On Thu, 17 Jul 2025 06:13:30 GMT, Volkan Yazici wrote: >> Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. >> >> ## Implementation notes >> >> The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, >> >> 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) >> 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too >> 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method >> 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag >> >> Following preliminary work needs to be carried out as well: >> >> 1. Add a new `VerifyIntrinsicChecks` VM flag >> 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. >> >> 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. >> >> ## Functional and performance tests >> >> - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. >> >> - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. >> >> ## Verification of the VM crash >> >> I've tested the VM crash scenario as follows: >> >> 1. Created the following test program: >> >> public class StrIntri { >> public static void main(String[] args) { >> Exception lastException = null; >> for (int i = 0; i < 1_000_000; i++) { >> try { >> jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); >> } catch (Exception exception) { >> lastException = exception; >> } >> } >> if (lastException != null) { >> lastException.printStackTrace... > > Volkan Yazici has updated the pull request incrementally with two additional commits since the last revision: > > - Duplicate affected tests with `-XX:+VerifyIntrinsicChecks` variants > - Fix compiler error in `generate_string_range_check` test/hotspot/jtreg/compiler/intrinsics/TestVerifyIntrinsicChecks.java line 84: > 82: char[] buffer = new char[length]; > 83: for (int i = 0; i < length; i++) { > 84: buffer[i] = (char) (i % '\u0080'); ASCII (<= 0x7F) production ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2212379110 From vyazici at openjdk.org Thu Jul 17 06:31:55 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Thu, 17 Jul 2025 06:31:55 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v7] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Thu, 17 Jul 2025 06:13:30 GMT, Volkan Yazici wrote: >> Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. >> >> ## Implementation notes >> >> The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, >> >> 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) >> 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too >> 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method >> 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag >> >> Following preliminary work needs to be carried out as well: >> >> 1. Add a new `VerifyIntrinsicChecks` VM flag >> 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. >> >> 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. >> >> ## Functional and performance tests >> >> - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. >> >> - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. >> >> ## Verification of the VM crash >> >> I've tested the VM crash scenario as follows: >> >> 1. Created the following test program: >> >> public class StrIntri { >> public static void main(String[] args) { >> Exception lastException = null; >> for (int i = 0; i < 1_000_000; i++) { >> try { >> jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); >> } catch (Exception exception) { >> lastException = exception; >> } >> } >> if (lastException != null) { >> lastException.printStackTrace... > > Volkan Yazici has updated the pull request incrementally with two additional commits since the last revision: > > - Duplicate affected tests with `-XX:+VerifyIntrinsicChecks` variants > - Fix compiler error in `generate_string_range_check` test/hotspot/jtreg/compiler/patches/java.base/java/lang/Helper.java line 44: > 42: @jdk.internal.vm.annotation.ForceInline > 43: public static int StringCodingEncodeAsciiArray0(char[] sa, int sp, byte[] da, int dp, int len) { > 44: return StringCoding.encodeAsciiArray0(sa, sp, da, dp, len); `TestVerifyIntrinsicChecks` needs to have access to an intrinsic that uses the `VerifyIntrinsicChecks` VM flag. For that purpose, I chose `StringCoding::encodeAsciiArray`, which is the guarded public door to `@IntrinsicCandidate encodeAsciiArray0()` ? note the `0` suffix! `TestVerifyIntrinsicChecks` needs to feed invalid input to `encodeAsciiArray0()` to trip the checks in the compiler intrinsic. Though, `encodeAsciiArray0()` is, as is one of the main motivations of this PR, private. In `TestVerifyIntrinsicChecks`, I first tried accessing to `encodeAsciiArray0()` using reflection, but this blocked the method get inlined, which is a requirement for intrinsification. Hence, I made the `encodeAsciiArray0()` package-private and exposed it via `StringCodingEncodeAsciiArray0` to allow inlining, and, eventually, intrinsification. This worked. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2212396003 From thartmann at openjdk.org Thu Jul 17 07:06:52 2025 From: thartmann at openjdk.org (Tobias Hartmann) Date: Thu, 17 Jul 2025 07:06:52 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v7] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Thu, 17 Jul 2025 04:35:01 GMT, Volkan Yazici wrote: >> src/hotspot/share/opto/library_call.cpp line 963: >> >>> 961: >>> 962: if (bailout->req() > 1) { >>> 963: if (halt) { >> >> Toggle to force a VM crash to be used to surface intrinsic Java wrappers failing to spot invalid input. > > @TobiHartmann, this change results in the following compiler error: > > > /home/vy/.../src/hotspot/share/opto/library_call.cpp:958:35: error: invalid conversion from 'Node*' to 'RegionNode*' [-fpermissive] > 958 | generate_negative_guard(offset, bailout); > | ^~~~~~~ > | | > | Node* > > > That is, `bailout` is supposed to be of type `RegionNode*`, but `_gvn.transform()` returns a value of type `Node*`. bfc301798d1 amends failing code with > > > bailout = (RegionNode*) _gvn.transform(bailout); > > > Let me know if you disagree. Please use `->as_Region()` instead. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2212467404 From vyazici at openjdk.org Thu Jul 17 07:20:34 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Thu, 17 Jul 2025 07:20:34 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v8] In-Reply-To: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: > Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. > > ## Implementation notes > > The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, > > 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) > 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too > 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method > 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag > > Following preliminary work needs to be carried out as well: > > 1. Add a new `VerifyIntrinsicChecks` VM flag > 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. > > 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. > > ## Functional and performance tests > > - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. > > - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. > > ## Verification of the VM crash > > I've tested the VM crash scenario as follows: > > 1. Created the following test program: > > public class StrIntri { > public static void main(String[] args) { > Exception lastException = null; > for (int i = 0; i < 1_000_000; i++) { > try { > jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); > } catch (Exception exception) { > lastException = exception; > } > } > if (lastException != null) { > lastException.printStackTrace(); > } else { > System.out.println("completed"); > } > } > } > ... Volkan Yazici has updated the pull request incrementally with one additional commit since the last revision: Replace casting with `as_Region()` in `generate_string_range_check` ------------- Changes: - all: https://git.openjdk.org/jdk/pull/25998/files - new: https://git.openjdk.org/jdk/pull/25998/files/abc0eeb3..db1ed388 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=25998&range=07 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=25998&range=06-07 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/25998.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/25998/head:pull/25998 PR: https://git.openjdk.org/jdk/pull/25998 From vyazici at openjdk.org Thu Jul 17 07:20:34 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Thu, 17 Jul 2025 07:20:34 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v8] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Thu, 17 Jul 2025 07:04:00 GMT, Tobias Hartmann wrote: >> @TobiHartmann, this change results in the following compiler error: >> >> >> /home/vy/.../src/hotspot/share/opto/library_call.cpp:958:35: error: invalid conversion from 'Node*' to 'RegionNode*' [-fpermissive] >> 958 | generate_negative_guard(offset, bailout); >> | ^~~~~~~ >> | | >> | Node* >> >> >> That is, `bailout` is supposed to be of type `RegionNode*`, but `_gvn.transform()` returns a value of type `Node*`. bfc301798d1 amends failing code with >> >> >> bailout = (RegionNode*) _gvn.transform(bailout); >> >> >> Let me know if you disagree. > > Please use `->as_Region()` instead. Changed as requested in db1ed388765. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2212492666 From thartmann at openjdk.org Thu Jul 17 08:33:51 2025 From: thartmann at openjdk.org (Tobias Hartmann) Date: Thu, 17 Jul 2025 08:33:51 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v8] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Thu, 17 Jul 2025 07:20:34 GMT, Volkan Yazici wrote: >> Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. >> >> ## Implementation notes >> >> The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, >> >> 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) >> 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too >> 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method >> 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag >> >> Following preliminary work needs to be carried out as well: >> >> 1. Add a new `VerifyIntrinsicChecks` VM flag >> 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. >> >> 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. >> >> ## Functional and performance tests >> >> - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. >> >> - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. >> >> ## Verification of the VM crash >> >> I've tested the VM crash scenario as follows: >> >> 1. Created the following test program: >> >> public class StrIntri { >> public static void main(String[] args) { >> Exception lastException = null; >> for (int i = 0; i < 1_000_000; i++) { >> try { >> jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); >> } catch (Exception exception) { >> lastException = exception; >> } >> } >> if (lastException != null) { >> lastException.printStackTrace... > > Volkan Yazici has updated the pull request incrementally with one additional commit since the last revision: > > Replace casting with `as_Region()` in `generate_string_range_check` That looks good to me. Thanks! ------------- Marked as reviewed by thartmann (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/25998#pullrequestreview-3028497094 From dfenacci at openjdk.org Thu Jul 17 09:37:51 2025 From: dfenacci at openjdk.org (Damon Fenacci) Date: Thu, 17 Jul 2025 09:37:51 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v8] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Thu, 17 Jul 2025 07:20:34 GMT, Volkan Yazici wrote: >> Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. >> >> ## Implementation notes >> >> The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, >> >> 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) >> 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too >> 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method >> 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag >> >> Following preliminary work needs to be carried out as well: >> >> 1. Add a new `VerifyIntrinsicChecks` VM flag >> 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. >> >> 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. >> >> ## Functional and performance tests >> >> - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. >> >> - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. >> >> ## Verification of the VM crash >> >> I've tested the VM crash scenario as follows: >> >> 1. Created the following test program: >> >> public class StrIntri { >> public static void main(String[] args) { >> Exception lastException = null; >> for (int i = 0; i < 1_000_000; i++) { >> try { >> jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); >> } catch (Exception exception) { >> lastException = exception; >> } >> } >> if (lastException != null) { >> lastException.printStackTrace... > > Volkan Yazici has updated the pull request incrementally with one additional commit since the last revision: > > Replace casting with `as_Region()` in `generate_string_range_check` Looks good to me too. Thanks @vy! ------------- Marked as reviewed by dfenacci (Committer). PR Review: https://git.openjdk.org/jdk/pull/25998#pullrequestreview-3028731726 From rgiulietti at openjdk.org Thu Jul 17 14:16:52 2025 From: rgiulietti at openjdk.org (Raffaello Giulietti) Date: Thu, 17 Jul 2025 14:16:52 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v8] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Thu, 17 Jul 2025 07:20:34 GMT, Volkan Yazici wrote: >> Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. >> >> ## Implementation notes >> >> The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, >> >> 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) >> 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too >> 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method >> 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag >> >> Following preliminary work needs to be carried out as well: >> >> 1. Add a new `VerifyIntrinsicChecks` VM flag >> 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. >> >> 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. >> >> ## Functional and performance tests >> >> - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. >> >> - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. >> >> ## Verification of the VM crash >> >> I've tested the VM crash scenario as follows: >> >> 1. Created the following test program: >> >> public class StrIntri { >> public static void main(String[] args) { >> Exception lastException = null; >> for (int i = 0; i < 1_000_000; i++) { >> try { >> jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); >> } catch (Exception exception) { >> lastException = exception; >> } >> } >> if (lastException != null) { >> lastException.printStackTrace... > > Volkan Yazici has updated the pull request incrementally with one additional commit since the last revision: > > Replace casting with `as_Region()` in `generate_string_range_check` src/java.base/share/classes/java/lang/StringCoding.java line 130: > 128: *

> 129: * This method assumes that {@code sa} is encoded in UTF-16, and hence, > 130: * each {@code char} maps to 2 bytes. Since `sa` is assumed to be encoded in UTF-16, what's the point of the previous paragraph? src/java.base/share/classes/java/lang/StringCoding.java line 132: > 130: * each {@code char} maps to 2 bytes. > 131: *

> 132: * {@code sp} is encoded in ISO-8859-1. There each {@code byte} corresponds As this is an index, it doesn't make sense to state that it is encoded in ISO-8859-1. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2213428956 PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2213429091 From rgiulietti at openjdk.org Thu Jul 17 14:16:53 2025 From: rgiulietti at openjdk.org (Raffaello Giulietti) Date: Thu, 17 Jul 2025 14:16:53 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v8] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Thu, 10 Jul 2025 12:18:25 GMT, Volkan Yazici wrote: >> Volkan Yazici has updated the pull request incrementally with one additional commit since the last revision: >> >> Replace casting with `as_Region()` in `generate_string_range_check` > > src/java.base/share/classes/java/lang/StringCoding.java line 140: > >> 138: * >> 139: * @param sa the source byte array containing characters encoded in UTF-16 >> 140: * @param sp the index of the byte (not character!) from the source array to start reading from > > Note the `byte (not character!)` emphasis here and below. I think this is incorrect. This is the index of a character (two bytes). As it is used in `encodeISOArray0()`, it is incremented by 1 and passed to `StringUTF16.getChar()`, where it is multiplied by 2 to obtain the real `byte[]` index. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2213466146 From rgiulietti at openjdk.org Thu Jul 17 14:31:56 2025 From: rgiulietti at openjdk.org (Raffaello Giulietti) Date: Thu, 17 Jul 2025 14:31:56 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v8] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Thu, 17 Jul 2025 07:20:34 GMT, Volkan Yazici wrote: >> Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. >> >> ## Implementation notes >> >> The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, >> >> 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) >> 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too >> 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method >> 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag >> >> Following preliminary work needs to be carried out as well: >> >> 1. Add a new `VerifyIntrinsicChecks` VM flag >> 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. >> >> 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. >> >> ## Functional and performance tests >> >> - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. >> >> - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. >> >> ## Verification of the VM crash >> >> I've tested the VM crash scenario as follows: >> >> 1. Created the following test program: >> >> public class StrIntri { >> public static void main(String[] args) { >> Exception lastException = null; >> for (int i = 0; i < 1_000_000; i++) { >> try { >> jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); >> } catch (Exception exception) { >> lastException = exception; >> } >> } >> if (lastException != null) { >> lastException.printStackTrace... > > Volkan Yazici has updated the pull request incrementally with one additional commit since the last revision: > > Replace casting with `as_Region()` in `generate_string_range_check` What is the thinking when an `@IntrinsicCandidate` method invokes another `@IntrinsicCandidate` method? Which part is responsible for the checks? For example, the Java code of `StringCoding.encodeISOArray0()` invokes `StringUTF16.getChar()`, another `@IntrinsicCandidate` method. The latter does not check its arguments (OK, there's an `assert`, but this is a weak check). The invocation from `encodeISOArray0()` is fine and safe, but `getChar()` is invoked by other parts of the code. So what is the general strategy? Add checks to `getChar()` and rely on the runtime to eliminate redundant checks? ------------- PR Comment: https://git.openjdk.org/jdk/pull/25998#issuecomment-3084301249 From rriggs at openjdk.org Thu Jul 17 14:35:53 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Thu, 17 Jul 2025 14:35:53 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v8] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Thu, 10 Jul 2025 12:20:45 GMT, Volkan Yazici wrote: >> Volkan Yazici has updated the pull request incrementally with one additional commit since the last revision: >> >> Replace casting with `as_Region()` in `generate_string_range_check` > > src/java.base/share/classes/java/lang/StringCoding.java line 150: > >> 148: */ >> 149: static int encodeISOArray(byte[] sa, int sp, byte[] da, int dp, int len) { >> 150: checkFromIndexSize(sp, len << 1, requireNonNull(sa, "sa").length, AIOOBE_FORMATTER); > > `sa` contains 2-byte `char`s, and `sp` points to an index of this inflated array. Though, `len` denotes the codepoint count, hence the `len << 1` while checking `sp` and `len` bounds. The reference of `sa.length` is likely wrong also, as it is the source length in bytes but for the index check should be checking the source length in chars. It might be worth trying to find or create a test for the accidental incorrect interpretation of length in bytes vs chars.. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2213528045 From never at openjdk.org Thu Jul 17 14:37:53 2025 From: never at openjdk.org (Tom Rodriguez) Date: Thu, 17 Jul 2025 14:37:53 GMT Subject: RFR: 8362306: HotSpotJVMCIRuntime.getMirror can crash [v5] In-Reply-To: References: Message-ID: <8q5bw4B4Yd36332fWAOPO18XzJOPdQUlpCg9M9eBWVA=.d6d45d7d-f3a4-4105-8f1d-f800d8100d2a@github.com> On Wed, 16 Jul 2025 15:40:27 GMT, Doug Simon wrote: >> This PR fixes `HotSpotJVMCIRuntime.getMirror(ResolvedJavaMethod method)` and `HotSpotJVMCIRuntime.getMirror(ResolvedJavaField field)` so that they return null for `` and an injected field respectively instead of crashing. > > Doug Simon has updated the pull request incrementally with one additional commit since the last revision: > > test that getMirror on clinit returns null Marked as reviewed by never (Reviewer). src/hotspot/share/jvmci/jvmciCompilerToVM.cpp line 3011: > 3009: requireInHotSpot("asReflectionField", JVMCI_CHECK_NULL); > 3010: Klass* klass = UNPACK_PAIR(Klass, klass); > 3011: InstanceKlass* iklass = check_field(klass, index, JVMCI_CHECK_NULL); There's another copy of this idiom in getDeclaredFieldsInfo which might be worth fixing. ------------- PR Review: https://git.openjdk.org/jdk/pull/26346#pullrequestreview-3029824400 PR Review Comment: https://git.openjdk.org/jdk/pull/26346#discussion_r2213530140 From rgiulietti at openjdk.org Thu Jul 17 14:42:55 2025 From: rgiulietti at openjdk.org (Raffaello Giulietti) Date: Thu, 17 Jul 2025 14:42:55 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v8] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Thu, 17 Jul 2025 07:20:34 GMT, Volkan Yazici wrote: >> Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. >> >> ## Implementation notes >> >> The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, >> >> 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) >> 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too >> 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method >> 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag >> >> Following preliminary work needs to be carried out as well: >> >> 1. Add a new `VerifyIntrinsicChecks` VM flag >> 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. >> >> 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. >> >> ## Functional and performance tests >> >> - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. >> >> - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. >> >> ## Verification of the VM crash >> >> I've tested the VM crash scenario as follows: >> >> 1. Created the following test program: >> >> public class StrIntri { >> public static void main(String[] args) { >> Exception lastException = null; >> for (int i = 0; i < 1_000_000; i++) { >> try { >> jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); >> } catch (Exception exception) { >> lastException = exception; >> } >> } >> if (lastException != null) { >> lastException.printStackTrace... > > Volkan Yazici has updated the pull request incrementally with one additional commit since the last revision: > > Replace casting with `as_Region()` in `generate_string_range_check` src/java.base/share/classes/java/lang/StringCoding.java line 150: > 148: Objects.requireNonNull(sa, "sa"); > 149: Objects.requireNonNull(da, "da"); > 150: Preconditions.checkFromIndexSize(sp, len << 1, sa.length, Preconditions.AIOOBE_FORMATTER); Since `sp` is a character index and `len` counts characters but `sa.length` is in bytes, this should look like so Suggestion: Preconditions.checkFromIndexSize(sp, len, sa.length >>> 1, Preconditions.AIOOBE_FORMATTER); or something similar. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2213543167 From tschatzl at openjdk.org Thu Jul 17 14:50:46 2025 From: tschatzl at openjdk.org (Thomas Schatzl) Date: Thu, 17 Jul 2025 14:50:46 GMT Subject: RFR: 8342382: Implementation of JEP G1: Improve Application Throughput with a More Efficient Write-Barrier [v43] In-Reply-To: References: Message-ID: > Hi all, > > please review this change that implements (currently Draft) JEP: G1: Improve Application Throughput with a More Efficient Write-Barrier. > > The reason for posting this early is that this is a large change, and the JEP process is already taking very long with no end in sight but we would like to have this ready by JDK 25. > > ### Current situation > > With this change, G1 will reduce the post write barrier to much more resemble Parallel GC's as described in the JEP. The reason is that G1 lacks in throughput compared to Parallel/Serial GC due to larger barrier. > > The main reason for the current barrier is how g1 implements concurrent refinement: > * g1 tracks dirtied cards using sets (dirty card queue set - dcqs) of buffers (dirty card queues - dcq) containing the location of dirtied cards. Refinement threads pick up their contents to re-refine. The barrier needs to enqueue card locations. > * For correctness dirty card updates requires fine-grained synchronization between mutator and refinement threads, > * Finally there is generic code to avoid dirtying cards altogether (filters), to avoid executing the synchronization and the enqueuing as much as possible. > > These tasks require the current barrier to look as follows for an assignment `x.a = y` in pseudo code: > > > // Filtering > if (region(@x.a) == region(y)) goto done; // same region check > if (y == null) goto done; // null value check > if (card(@x.a) == young_card) goto done; // write to young gen check > StoreLoad; // synchronize > if (card(@x.a) == dirty_card) goto done; > > *card(@x.a) = dirty > > // Card tracking > enqueue(card-address(@x.a)) into thread-local-dcq; > if (thread-local-dcq is not full) goto done; > > call runtime to move thread-local-dcq into dcqs > > done: > > > Overall this post-write barrier alone is in the range of 40-50 total instructions, compared to three or four(!) for parallel and serial gc. > > The large size of the inlined barrier not only has a large code footprint, but also prevents some compiler optimizations like loop unrolling or inlining. > > There are several papers showing that this barrier alone can decrease throughput by 10-20% ([Yang12](https://dl.acm.org/doi/10.1145/2426642.2259004)), which is corroborated by some benchmarks (see links). > > The main idea for this change is to not use fine-grained synchronization between refinement and mutator threads, but coarse grained based on atomically switching card tables. Mutators only work on the "primary" card table, refinement threads on a se... Thomas Schatzl has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 59 commits: - Merge branch 'master' into 8342382-card-table-instead-of-dcq - Merge branch 'master' into pull/23739 - Merge branch 'master' into 8342382-card-table-instead-of-dcq - Merge branch 'master' into 8342382-card-table-instead-of-dcq - Merge branch 'master' into 8342382-card-table-instead-of-dcq - Merge branch 'master' into 8342382-card-table-instead-of-dcq - * ayang review: remove sweep_epoch - Merge branch 'master' into card-table-as-dcq-merge - Merge branch 'master' into 8342382-card-table-instead-of-dcq - * ayang review (part 2 - yield duration changes) - ... and 49 more: https://git.openjdk.org/jdk/compare/ea774b74...4b21868a ------------- Changes: https://git.openjdk.org/jdk/pull/23739/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=23739&range=42 Stats: 7120 lines in 112 files changed: 2589 ins; 3590 del; 941 mod Patch: https://git.openjdk.org/jdk/pull/23739.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/23739/head:pull/23739 PR: https://git.openjdk.org/jdk/pull/23739 From dnsimon at openjdk.org Thu Jul 17 15:00:11 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Thu, 17 Jul 2025 15:00:11 GMT Subject: RFR: 8362306: HotSpotJVMCIRuntime.getMirror can crash [v6] In-Reply-To: References: Message-ID: > This PR fixes `HotSpotJVMCIRuntime.getMirror(ResolvedJavaMethod method)` and `HotSpotJVMCIRuntime.getMirror(ResolvedJavaField field)` so that they return null for `` and an injected field respectively instead of crashing. Doug Simon has updated the pull request incrementally with one additional commit since the last revision: replaced use of JVMCIENV with JVMCI_CHECK_NULL in getDeclaredFieldsInfo ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26346/files - new: https://git.openjdk.org/jdk/pull/26346/files/fd44d95c..d62c74d9 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26346&range=05 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26346&range=04-05 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/26346.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26346/head:pull/26346 PR: https://git.openjdk.org/jdk/pull/26346 From yzheng at openjdk.org Thu Jul 17 15:04:52 2025 From: yzheng at openjdk.org (Yudi Zheng) Date: Thu, 17 Jul 2025 15:04:52 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v8] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Thu, 17 Jul 2025 07:20:34 GMT, Volkan Yazici wrote: >> Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. >> >> ## Implementation notes >> >> The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, >> >> 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) >> 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too >> 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method >> 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag >> >> Following preliminary work needs to be carried out as well: >> >> 1. Add a new `VerifyIntrinsicChecks` VM flag >> 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. >> >> 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. >> >> ## Functional and performance tests >> >> - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. >> >> - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. >> >> ## Verification of the VM crash >> >> I've tested the VM crash scenario as follows: >> >> 1. Created the following test program: >> >> public class StrIntri { >> public static void main(String[] args) { >> Exception lastException = null; >> for (int i = 0; i < 1_000_000; i++) { >> try { >> jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); >> } catch (Exception exception) { >> lastException = exception; >> } >> } >> if (lastException != null) { >> lastException.printStackTrace... > > Volkan Yazici has updated the pull request incrementally with one additional commit since the last revision: > > Replace casting with `as_Region()` in `generate_string_range_check` test/hotspot/jtreg/compiler/intrinsics/TestVerifyIntrinsicChecks.java line 25: > 23: > 24: /* > 25: * @test could you please add ` * @requires !vm.graal.enabled`? Graal is failing this test ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2213601907 From gdub at openjdk.org Thu Jul 17 15:05:50 2025 From: gdub at openjdk.org (Gilles Duboscq) Date: Thu, 17 Jul 2025 15:05:50 GMT Subject: RFR: 8362306: HotSpotJVMCIRuntime.getMirror can crash [v6] In-Reply-To: References: Message-ID: On Thu, 17 Jul 2025 15:00:11 GMT, Doug Simon wrote: >> This PR fixes `HotSpotJVMCIRuntime.getMirror(ResolvedJavaMethod method)` and `HotSpotJVMCIRuntime.getMirror(ResolvedJavaField field)` so that they return null for `` and an injected field respectively instead of crashing. > > Doug Simon has updated the pull request incrementally with one additional commit since the last revision: > > replaced use of JVMCIENV with JVMCI_CHECK_NULL in getDeclaredFieldsInfo Marked as reviewed by gdub (Committer). ------------- PR Review: https://git.openjdk.org/jdk/pull/26346#pullrequestreview-3029932165 From rgiulietti at openjdk.org Thu Jul 17 15:35:52 2025 From: rgiulietti at openjdk.org (Raffaello Giulietti) Date: Thu, 17 Jul 2025 15:35:52 GMT Subject: RFR: 8361842: Move input validation checks to Java for String-related intrinsics [v8] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Thu, 17 Jul 2025 14:29:08 GMT, Raffaello Giulietti wrote: > What is the thinking when an `@IntrinsicCandidate` method invokes another `@IntrinsicCandidate` method? Which part is responsible for the checks? > > For example, the Java code of `StringCoding.encodeISOArray0()` invokes `StringUTF16.getChar()`, another `@IntrinsicCandidate` method. The latter does not check its arguments (OK, there's an `assert`, but this is a weak check). The invocation from `encodeISOArray0()` is fine and safe, but `getChar()` is invoked by other parts of the code. > > So what is the general strategy? Add checks to `getChar()` and rely on the runtime to eliminate redundant checks? To reformulate my confusing question for the above example, there are apparently around 75-80 invocations of `getChar()`. How to make sure that they are all safe? Some are easy to verify, but others are not. ------------- PR Comment: https://git.openjdk.org/jdk/pull/25998#issuecomment-3084525709 From never at openjdk.org Thu Jul 17 16:06:50 2025 From: never at openjdk.org (Tom Rodriguez) Date: Thu, 17 Jul 2025 16:06:50 GMT Subject: RFR: 8362306: HotSpotJVMCIRuntime.getMirror can crash [v6] In-Reply-To: References: Message-ID: On Thu, 17 Jul 2025 15:00:11 GMT, Doug Simon wrote: >> This PR fixes `HotSpotJVMCIRuntime.getMirror(ResolvedJavaMethod method)` and `HotSpotJVMCIRuntime.getMirror(ResolvedJavaField field)` so that they return null for `` and an injected field respectively instead of crashing. > > Doug Simon has updated the pull request incrementally with one additional commit since the last revision: > > replaced use of JVMCIENV with JVMCI_CHECK_NULL in getDeclaredFieldsInfo Marked as reviewed by never (Reviewer). ------------- PR Review: https://git.openjdk.org/jdk/pull/26346#pullrequestreview-3030157052 From dnsimon at openjdk.org Thu Jul 17 16:22:54 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Thu, 17 Jul 2025 16:22:54 GMT Subject: RFR: 8362306: HotSpotJVMCIRuntime.getMirror can crash [v6] In-Reply-To: References: Message-ID: On Thu, 17 Jul 2025 15:00:11 GMT, Doug Simon wrote: >> This PR fixes `HotSpotJVMCIRuntime.getMirror(ResolvedJavaMethod method)` and `HotSpotJVMCIRuntime.getMirror(ResolvedJavaField field)` so that they return null for `` and an injected field respectively instead of crashing. > > Doug Simon has updated the pull request incrementally with one additional commit since the last revision: > > replaced use of JVMCIENV with JVMCI_CHECK_NULL in getDeclaredFieldsInfo Thanks for the reviews. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26346#issuecomment-3084663685 From dnsimon at openjdk.org Thu Jul 17 16:22:54 2025 From: dnsimon at openjdk.org (Doug Simon) Date: Thu, 17 Jul 2025 16:22:54 GMT Subject: Integrated: 8362306: HotSpotJVMCIRuntime.getMirror can crash In-Reply-To: References: Message-ID: <_ZZSxTjw3aPpjDUUwSQprjwqRqmcsNrfbcJg7FyI9uA=.35e55ffd-bdeb-4032-8604-b6b381dd1e76@github.com> On Wed, 16 Jul 2025 08:35:10 GMT, Doug Simon wrote: > This PR fixes `HotSpotJVMCIRuntime.getMirror(ResolvedJavaMethod method)` and `HotSpotJVMCIRuntime.getMirror(ResolvedJavaField field)` so that they return null for `` and an injected field respectively instead of crashing. This pull request has now been integrated. Changeset: 2b11a289 Author: Doug Simon URL: https://git.openjdk.org/jdk/commit/2b11a28997ad7ca424ad5595f9a7c7a9af530727 Stats: 77 lines in 6 files changed: 64 ins; 1 del; 12 mod 8362306: HotSpotJVMCIRuntime.getMirror can crash Reviewed-by: gdub, never, cslucas ------------- PR: https://git.openjdk.org/jdk/pull/26346 From jkratochvil at openjdk.org Thu Jul 17 16:30:24 2025 From: jkratochvil at openjdk.org (Jan Kratochvil) Date: Thu, 17 Jul 2025 16:30:24 GMT Subject: RFR: 8362524: Fix confusing but harmless typos in x86 CPU Features Message-ID: The name `DECLARE_CPU_FEATURE_FLAG` is used in all other cases. In `vmStructs_jvmci.cpp` there was no matching `#define`. ------------- Commit messages: - 8362524: Fix confusing but harmless typos in x86 CPU Features Changes: https://git.openjdk.org/jdk/pull/26371/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=26371&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8362524 Stats: 3 lines in 2 files changed: 0 ins; 1 del; 2 mod Patch: https://git.openjdk.org/jdk/pull/26371.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26371/head:pull/26371 PR: https://git.openjdk.org/jdk/pull/26371 From missa at openjdk.org Thu Jul 17 18:46:06 2025 From: missa at openjdk.org (Mohamed Issa) Date: Thu, 17 Jul 2025 18:46:06 GMT Subject: RFR: 8360559: Optimize Math.sinh for x86 64 bit platforms [v2] In-Reply-To: References: Message-ID: <9pe9LuUrBnk6A2TQ2emhgonljAvnJLcmSV_lEbrYIlo=.fec9b081-d6ae-4d85-8826-489828d9f442@github.com> > The goal of this PR is to implement an x86_64 intrinsic for java.lang.Math.sinh() using libm. There is a new set of micro-benchmarks are included to check the performance of specific input value ranges to help prevent regressions in the future. > > The command to run all range specific micro-benchmarks is posted below. > > `make test TEST="micro:SinhPerf.SinhPerfRanges"` > > The results of all tests posted below were captured with an [Intel? Xeon 8488C](https://advisor.cloudzero.com/aws/ec2/r7i.metal-24xl) using [OpenJDK v26-b4](https://github.com/openjdk/jdk/releases/tag/jdk-26%2B4) as the baseline version. > > For performance data collected with the new built in range micro-benchmark, see the table below. Each result is the mean of 8 individual runs, and the input ranges used match those from the original Java implementation. Overall, the intrinsic provides an an average uplift of 64% when input values fall into the middle three ranges where heavy computation is required. However, very small inputs and very large inputs show drops of 74% and 66% respectively. > > | Input range(s) | Baseline throughput (ops/ms) | Intrinsic throughput (ops/ms) | Speedup | > | :------------------------------------: | :-------------------------------: | :--------------------------------: | :--------: | > | [-2^(-28), 2^(-28)] | 844160 | 216029 | 0.26x | > | [-22, -2^(-28)], [2^(-28), 22] | 81662 | 157351 | 1.93x | > | [-709.78, -22], [22, 709.78] | 119075 | 167635 | 1.41x | > | [-710.48, -709.78], [709.78, 710.48] | 111636 | 177125 | 1.59x | > | (-INF, -710.48], [710.48, INF) | 959296 | 313839 | 0.33x | > > Finally, the `jtreg:test/jdk/java/lang/Math/HyperbolicTests.java` test passed with the changes. Mohamed Issa has updated the pull request incrementally with one additional commit since the last revision: Move error bound to separate section in comment header ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26152/files - new: https://git.openjdk.org/jdk/pull/26152/files/9c5cc60c..c0adc8b3 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26152&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26152&range=00-01 Stats: 3 lines in 1 file changed: 2 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/26152.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26152/head:pull/26152 PR: https://git.openjdk.org/jdk/pull/26152 From missa at openjdk.org Thu Jul 17 18:51:47 2025 From: missa at openjdk.org (Mohamed Issa) Date: Thu, 17 Jul 2025 18:51:47 GMT Subject: RFR: 8360559: Optimize Math.sinh for x86 64 bit platforms In-Reply-To: References: Message-ID: On Thu, 10 Jul 2025 21:23:50 GMT, Joe Darcy wrote: > > > What is the accuracy of the algorithm in ulps (units the last place)? > > > The java.lang.Math specification has max error and various other accuracy requirements any implementation must meet. > > > > > > 0.51 ulps > > Please add that as a comment to the changeset. > > Also, if the worst-case inputs for this algorithm are known, they should the added as part of the core libraries regression tests for the math library. I included the error bound as a separate section of the comment header in the stub generator source file. Also, the input ranges are covered in `jtreg:test/jdk/java/lang/Math/HyperbolicTests.java`. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26152#issuecomment-3085084538 From kbarrett at openjdk.org Fri Jul 18 00:32:49 2025 From: kbarrett at openjdk.org (Kim Barrett) Date: Fri, 18 Jul 2025 00:32:49 GMT Subject: RFR: 8362524: Fix confusing but harmless typos in x86 CPU Features In-Reply-To: References: Message-ID: On Thu, 17 Jul 2025 16:24:43 GMT, Jan Kratochvil wrote: > The name `DECLARE_CPU_FEATURE_FLAG` is used in all other cases. In `vmStructs_jvmci.cpp` there was no matching `#define`. Changes requested by kbarrett (Reviewer). src/hotspot/cpu/x86/vm_version_x86.cpp line 50: > 48: VM_Version::CpuidInfo VM_Version::_cpuid_info = { 0, }; > 49: > 50: #define DECLARE_CPU_FEATURE_FLAG(id, name, bit) name, I think the "typo" here is in the `#undef` rather than the define. Calling this `xxx_NAME` seems appropriate, since it is providing the name for the feature for collection in `_features_names[]`. Places that are using `xxx_FLAG` are constructing the enumerator for the feature. There is no requirement that all uses of an X-macro use the same name for the passed in macro, and indeed it is quite normal to not do so. ------------- PR Review: https://git.openjdk.org/jdk/pull/26371#pullrequestreview-3031385928 PR Review Comment: https://git.openjdk.org/jdk/pull/26371#discussion_r2214569387 From jkratochvil at openjdk.org Fri Jul 18 06:32:35 2025 From: jkratochvil at openjdk.org (Jan Kratochvil) Date: Fri, 18 Jul 2025 06:32:35 GMT Subject: RFR: 8362524: Fix confusing but harmless typos in x86 CPU Features [v2] In-Reply-To: References: Message-ID: > The name `DECLARE_CPU_FEATURE_FLAG` is used in all other cases. In `vmStructs_jvmci.cpp` there was no matching `#define`. Jan Kratochvil has updated the pull request incrementally with one additional commit since the last revision: Call it DECLARE_CPU_FEATURE_NAME ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26371/files - new: https://git.openjdk.org/jdk/pull/26371/files/56c13975..eb8a5261 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26371&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26371&range=00-01 Stats: 3 lines in 1 file changed: 0 ins; 0 del; 3 mod Patch: https://git.openjdk.org/jdk/pull/26371.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26371/head:pull/26371 PR: https://git.openjdk.org/jdk/pull/26371 From jkratochvil at openjdk.org Fri Jul 18 06:32:36 2025 From: jkratochvil at openjdk.org (Jan Kratochvil) Date: Fri, 18 Jul 2025 06:32:36 GMT Subject: RFR: 8362524: Fix confusing but harmless typos in x86 CPU Features [v2] In-Reply-To: References: Message-ID: On Fri, 18 Jul 2025 00:23:45 GMT, Kim Barrett wrote: >> Jan Kratochvil has updated the pull request incrementally with one additional commit since the last revision: >> >> Call it DECLARE_CPU_FEATURE_NAME > > src/hotspot/cpu/x86/vm_version_x86.cpp line 50: > >> 48: VM_Version::CpuidInfo VM_Version::_cpuid_info = { 0, }; >> 49: >> 50: #define DECLARE_CPU_FEATURE_FLAG(id, name, bit) name, > > I think the "typo" here is in the `#undef` rather than the define. Calling this `xxx_NAME` seems > appropriate, since it is providing the name for the feature for collection in `_features_names[]`. > Places that are using `xxx_FLAG` are constructing the enumerator for the feature. There is no > requirement that all uses of an X-macro use the same name for the passed in macro, and indeed > it is quite normal to not do so. Yes but then this typo has happened. Anyway it is changed now, thanks for the review. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26371#discussion_r2215092851 From kbarrett at openjdk.org Fri Jul 18 08:04:55 2025 From: kbarrett at openjdk.org (Kim Barrett) Date: Fri, 18 Jul 2025 08:04:55 GMT Subject: RFR: 8362524: Fix confusing but harmless typos in x86 CPU Features [v2] In-Reply-To: References: Message-ID: On Fri, 18 Jul 2025 06:32:35 GMT, Jan Kratochvil wrote: >> The name `DECLARE_CPU_FEATURE_FLAG` is used in all other cases. In `vmStructs_jvmci.cpp` there was no matching `#define`. > > Jan Kratochvil has updated the pull request incrementally with one additional commit since the last revision: > > Call it DECLARE_CPU_FEATURE_NAME Looks good. ------------- Marked as reviewed by kbarrett (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/26371#pullrequestreview-3032455563 From kvn at openjdk.org Fri Jul 18 15:09:48 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Fri, 18 Jul 2025 15:09:48 GMT Subject: RFR: 8362524: Fix confusing but harmless typos in x86 CPU Features [v2] In-Reply-To: References: Message-ID: On Fri, 18 Jul 2025 06:32:35 GMT, Jan Kratochvil wrote: >> The name `DECLARE_CPU_FEATURE_FLAG` is used in all other cases. In `vmStructs_jvmci.cpp` there was no matching `#define`. > > Jan Kratochvil has updated the pull request incrementally with one additional commit since the last revision: > > Call it DECLARE_CPU_FEATURE_NAME Good. ------------- Marked as reviewed by kvn (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/26371#pullrequestreview-3033915669 From duke at openjdk.org Fri Jul 18 16:59:39 2025 From: duke at openjdk.org (duke) Date: Fri, 18 Jul 2025 16:59:39 GMT Subject: RFR: 8362524: Fix confusing but harmless typos in x86 CPU Features [v2] In-Reply-To: References: Message-ID: On Fri, 18 Jul 2025 06:32:35 GMT, Jan Kratochvil wrote: >> The name `DECLARE_CPU_FEATURE_FLAG` is used in all other cases. In `vmStructs_jvmci.cpp` there was no matching `#define`. > > Jan Kratochvil has updated the pull request incrementally with one additional commit since the last revision: > > Call it DECLARE_CPU_FEATURE_NAME @jankratochvil Your change (at version eb8a5261346bcd0e78e47f455fe8d2ef36911671) is now ready to be sponsored by a Committer. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26371#issuecomment-3089902470 From jkratochvil at openjdk.org Fri Jul 18 17:19:45 2025 From: jkratochvil at openjdk.org (Jan Kratochvil) Date: Fri, 18 Jul 2025 17:19:45 GMT Subject: Integrated: 8362524: Fix confusing but harmless typos in x86 CPU Features In-Reply-To: References: Message-ID: <8CBTIbYdAjDgt_Uo8Y1Fl4qiAlPxJoYSRCu9EnZZ2_M=.83041cc3-e7ea-46d1-9029-0b74295af0b8@github.com> On Thu, 17 Jul 2025 16:24:43 GMT, Jan Kratochvil wrote: > The name `DECLARE_CPU_FEATURE_FLAG` is used in all other cases. In `vmStructs_jvmci.cpp` there was no matching `#define`. This pull request has now been integrated. Changeset: 60c29ff5 Author: Jan Kratochvil Committer: Vladimir Kozlov URL: https://git.openjdk.org/jdk/commit/60c29ff57b22fa7c0bedb38316067e8e1988a24b Stats: 2 lines in 2 files changed: 0 ins; 1 del; 1 mod 8362524: Fix confusing but harmless typos in x86 CPU Features Reviewed-by: kbarrett, kvn ------------- PR: https://git.openjdk.org/jdk/pull/26371 From jrose at openjdk.org Fri Jul 18 23:20:40 2025 From: jrose at openjdk.org (John R Rose) Date: Fri, 18 Jul 2025 23:20:40 GMT Subject: RFR: 8361842: Move input validation checks to Java for java.lang.StringCoding intrinsics [v8] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Thu, 17 Jul 2025 15:33:37 GMT, Raffaello Giulietti wrote: > What is the thinking when an `@IntrinsicCandidate` method invokes another `@IntrinsicCandidate` method? Which part is responsible for the checks? This is a good question. Suppose IC1 calls IC2 and both are intrinsic candidates, and suppose that M1 and M2 are their checked "front doors". I think the answer has to be that, once you start executing IC1, you cannot expect any further checks. Probably some assembler macro implements IC2 and it may be called from more than one place. The tricky thing to prove is that all uses of IC2's intrinsic code, whether direct (via M2) or indirect (via things like M1) have adequate checks. If intrinsics are factored this way (as they are for string methods) I think that IC1 has to advertise that it calls IC2, so that the front door method M1 is responsible for validity checks for both IC1 and IC2. That is because after intrinsic expansion, IC2 is reached without going through M2; the entry was indirectly from M1. So M1 has to duplicate M2's front door checks. To make this workable, it may be that M2's front door checks are factored into a subroutine FD2, so that M1 can refer to FD2, rather than do risky code duplication. If (as in this case) IC2 loops over calls to IC1, then perhaps M2 should have a companion method FD2R which checks a range a range of inputs to IC2, so that M1 can call FD2R. If all goes well, then FD2R has a range check that duplicates the front door logic of M1, so that the JIT can remove the duplicate checking. In the case of `StringUTF16.getChar`, I see it is marked as trusted, and it does not have a front-door method, and does have many callers. In the terms of this PR, perhaps it should be renamed `getChar0` (or the like) to make it more clear (at non-local use points) that it must be called from trusted code. Perhaps it should also have a range check method associated with it, so that some callers can use that range check method, so that the non-local responsibility is more clearly fulfilled. Maybe some callers (if less performance critical) should be changed to call a properly checked front-door method, `getChar` (as opposed to `getChar0`). Remaining callers of `getChar0` should be clearly linked to the front-door checks required by `getChar0`. The above seems to be the principled way to deal with an unchecked intrinsic called from many trusted use sites. The basic idea is that every trusted use site should reaffirm its responsibility locally, not just hope that a non-local assert will catch a bug. We want some kind of reviewable (static/local) proof that each use site (of an unchecked private intrinsics) has correct checks. Some examples: A new front-door `getChar` method can be used in less important places like `AbstractStringBuilder::getChar`. In trusted loops over `getChar` like `String::encodeASCII`, the loop containing `getChar` can be prefaced by a range check which is batched for all the loop iterations, something like `StringUTF16.getCharChecks(val, 0, len)`. The same pattern occurs in `String::encode8859_1` and `encodeUTF8_UTF16` and `computeSizeUTF8_UTF16` and maybe elsewhere. The `val` reference and limit variable `len` or `sl` should be marked `final` to ensure that the batched range check remains correct (because it should not take loop-variant inputs). As I read through `String.java` I see that a batched range check would cover a lot of use cases? I haven't read though all the uses of `getChar`, however. The intrinsic `encodeISOArray0` (was `implEncodeISOArray`) calls `getChar`. This is an example where its front door method (now `encodeISOArray` with no "0") should call a batched check method like `getCharBatchChecks`. Let's look at this in detail. The `getCharBatchChecks` method could look like this: //non-public void getCharBatchChecks(byte[] val, int charStart, int charSize) { Objects.requireNonNull(val, "val"); // *** what style guide mandates this line?? Preconditions.checkFromIndexSize(charStart << 1, charSize << 1, val.length, Preconditions.AIOOBE_FORMATTER); // *** using "char" in the names helps reduce confusion from the mix of byte and char indexes } ? static int encodeISOArray(?) { ? StringUTF16.getCharBatchChecks(sa, sp, len); // next method loops over getChar(sa, sp++) return encodeISOArray0(sa, sp, da, dp, len); } Note that after inlining, the batch checks exactly match pre-existing checks for the caller intrinsic. Perhaps the caller's checks could be removed manually, or perhaps the JIT removes the duplication. Actually, I think you got this documentation wrong: @param sp the index of the byte (not character!) from the source array to start reading from AFAICT, `sp` is a char index; note that `getChar` scales it as `(index=sp)<<1`. Note that `getChar` has zero javadoc, so you are left to guess helplessly about its index operand. This stuff is complicated to get right. The above exercise in wiring up the checking logic tends to uncover bugs and misconceptions, I think. ------------- PR Comment: https://git.openjdk.org/jdk/pull/25998#issuecomment-3091231708 From jrose at openjdk.org Sat Jul 19 06:25:46 2025 From: jrose at openjdk.org (John R Rose) Date: Sat, 19 Jul 2025 06:25:46 GMT Subject: RFR: 8361842: Move input validation checks to Java for java.lang.StringCoding intrinsics [v8] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: <-Slk7vUMDszUJMCmtPgaiWeUdmBszJpUOmkkxTGTe38=.f460e240-44d5-4e44-b0c3-ad073315c8c8@github.com> On Fri, 18 Jul 2025 23:18:16 GMT, John R Rose wrote: > If (as in this case) IC2 loops over calls to IC1 Correction; I meant IC1 calls IC2, in a loop, N times. We don't want a pre-loop in M1 that checks each of N distinct arguments to IC2 (like N calls to M2 would), but rather a batch check routine which checks all of the arguments to IC2, in O(1) time. ------------- PR Comment: https://git.openjdk.org/jdk/pull/25998#issuecomment-3091934621 From vyazici at openjdk.org Mon Jul 21 12:33:30 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Mon, 21 Jul 2025 12:33:30 GMT Subject: RFR: 8361842: Move input validation checks to Java for java.lang.StringCoding intrinsics [v9] In-Reply-To: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: > Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. > > ## Implementation notes > > The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, > > 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) > 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too > 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method > 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag > > Following preliminary work needs to be carried out as well: > > 1. Add a new `VerifyIntrinsicChecks` VM flag > 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. > > 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. > > ## Functional and performance tests > > - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. > > - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. > > ## Verification of the VM crash > > I've tested the VM crash scenario as follows: > > 1. Created the following test program: > > public class StrIntri { > public static void main(String[] args) { > Exception lastException = null; > for (int i = 0; i < 1_000_000; i++) { > try { > jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); > } catch (Exception exception) { > lastException = exception; > } > } > if (lastException != null) { > lastException.printStackTrace(); > } else { > System.out.println("completed"); > } > } > } > ... Volkan Yazici has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains 23 additional commits since the last revision: - Merge remote-tracking branch 'upstream/master' into strIntrinCheck - Make `StringCoding` encoding intrinsics lenient - Fix `encodeISOArray` bounds checks and Javadoc - Disable `TestVerifyIntrinsicChecks` for GraalVM - Relax target array capacity check for intrinsic Java wrappers It's not possible to determine the required capacity of the target array in constant time, as Unicode code points may occupy either one or two `char` values. As a result, existing implementations typically invoke encoding methods in a loop, handling each unmappable character on a case-by-case basis. For an example, see `sun.nio.cs.DoubleByte.Encoder::encode`. - Fix out-of-bounds in `sun.nio.cs.SingleByte.Encoder::encodeArrayLoop` - Replace casting with `as_Region()` in `generate_string_range_check` - Duplicate affected tests with `-XX:+VerifyIntrinsicChecks` variants - Fix compiler error in `generate_string_range_check` - Add test verifying the effectiveness of `VerifyIntrinsicChecks` - ... and 13 more: https://git.openjdk.org/jdk/compare/c179d680...f69374fb ------------- Changes: - all: https://git.openjdk.org/jdk/pull/25998/files - new: https://git.openjdk.org/jdk/pull/25998/files/db1ed388..f69374fb Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=25998&range=08 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=25998&range=07-08 Stats: 13609 lines in 414 files changed: 10649 ins; 1054 del; 1906 mod Patch: https://git.openjdk.org/jdk/pull/25998.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/25998/head:pull/25998 PR: https://git.openjdk.org/jdk/pull/25998 From vyazici at openjdk.org Mon Jul 21 12:41:45 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Mon, 21 Jul 2025 12:41:45 GMT Subject: RFR: 8361842: Move input validation checks to Java for java.lang.StringCoding intrinsics [v3] In-Reply-To: <4zqK_rAHpX2bdDGf_kw2TOXtdOgONZykPs7mlR-rDrA=.d7d2bcd4-1e48-40ed-9628-46a681a5c4bb@github.com> References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> <8vCbaelpmz8qseHlyYRYiF0iDIycfg63fnthX52ZqJk=.3fa6d066-4a5b-4dae-8bcd-d25a336ccb94@github.com> <4zqK_rAHpX2bdDGf_kw2TOXtdOgONZykPs7mlR-rDrA=.d7d2bcd4-1e48-40ed-9628-46a681a5c4bb@github.com> Message-ID: On Wed, 16 Jul 2025 05:28:55 GMT, Tobias Hartmann wrote: >> Volkan Yazici has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains 12 additional commits since the last revision: >> >> - Merge remote-tracking branch 'upstream/master' into strIntrinCheck >> - Apply review feedback (styling changes) >> - Minimize the number of touched lines in `vmIntrinsics.hpp` >> - Remove Markdown-styling in comments >> - Improve wording of the `VerifyIntrinsicChecks` flag >> - Merge remote-tracking branch 'upstream/master' into strIntrinCheck >> - Fix `EUC_JP.java.template` broken due to `encodeASCII` rename >> - Remove `StringCodingCountPositives`, `String{En,De}code` already cover our cases >> >> This reverts commit 196fc5d406851b8e7070c97ac53ca59c4615aad9. >> - Improve intrinsics in `StringCoding` >> - Add `StringCodingCountPositives` benchmark >> - ... and 2 more: https://git.openjdk.org/jdk/compare/c4b2ddec...85f19864 > > src/hotspot/share/opto/c2_globals.hpp line 665: > >> 663: "prints attempted and successful inlining of intrinsics") \ >> 664: \ >> 665: develop(bool, VerifyIntrinsicChecks, false, \ > > We should add testing that uses this new flag. Maybe we could add a run to the tests that check the affected intrinsics? We could also add it to our (Oracle internal) stress test jobs at higher tiers. Given @TobiHartmann's later approval, I'm marking this as resolved. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2219089077 From vyazici at openjdk.org Mon Jul 21 12:46:43 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Mon, 21 Jul 2025 12:46:43 GMT Subject: RFR: 8361842: Move input validation checks to Java for java.lang.StringCoding intrinsics [v8] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Thu, 17 Jul 2025 13:58:32 GMT, Raffaello Giulietti wrote: >> Volkan Yazici has updated the pull request incrementally with one additional commit since the last revision: >> >> Replace casting with `as_Region()` in `generate_string_range_check` > > src/java.base/share/classes/java/lang/StringCoding.java line 130: > >> 128: *

>> 129: * This method assumes that {@code sa} is encoded in UTF-16, and hence, >> 130: * each {@code char} maps to 2 bytes. > > Since `sa` is assumed to be encoded in UTF-16, what's the point of the previous paragraph? It might be obvious to some, but some (incl. myself) got really confused on what input arguments actually denote, and how they are operated. I'm inclined to keep the for-dummies explanation, unless there is a strong objection. > src/java.base/share/classes/java/lang/StringCoding.java line 150: > >> 148: Objects.requireNonNull(sa, "sa"); >> 149: Objects.requireNonNull(da, "da"); >> 150: Preconditions.checkFromIndexSize(sp, len << 1, sa.length, Preconditions.AIOOBE_FORMATTER); > > Since `sp` is a character index and `len` counts characters but `sa.length` is in bytes, this should look like so > Suggestion: > > Preconditions.checkFromIndexSize(sp, len, sa.length >>> 1, Preconditions.AIOOBE_FORMATTER); > > or something similar. Very sharp of you @rgiulietti! Thanks so much! ? Fixed. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2219097580 PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2219099452 From vyazici at openjdk.org Mon Jul 21 12:46:45 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Mon, 21 Jul 2025 12:46:45 GMT Subject: RFR: 8361842: Move input validation checks to Java for java.lang.StringCoding intrinsics [v8] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Thu, 17 Jul 2025 15:02:21 GMT, Yudi Zheng wrote: >> Volkan Yazici has updated the pull request incrementally with one additional commit since the last revision: >> >> Replace casting with `as_Region()` in `generate_string_range_check` > > test/hotspot/jtreg/compiler/intrinsics/TestVerifyIntrinsicChecks.java line 25: > >> 23: >> 24: /* >> 25: * @test > > could you please add ` * @requires !vm.graal.enabled`? Graal is failing this test @mur47x111 added in 4016c7a1fe. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25998#discussion_r2219101443 From vyazici at openjdk.org Mon Jul 21 12:52:40 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Mon, 21 Jul 2025 12:52:40 GMT Subject: RFR: 8361842: Move input validation checks to Java for java.lang.StringCoding intrinsics [v10] In-Reply-To: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: > Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. > > ## Implementation notes > > The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, > > 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) > 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too > 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method > 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag > > Following preliminary work needs to be carried out as well: > > 1. Add a new `VerifyIntrinsicChecks` VM flag > 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. > > 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. > > ## Functional and performance tests > > - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. > > - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. > > ## Verification of the VM crash > > I've tested the VM crash scenario as follows: > > 1. Created the following test program: > > public class StrIntri { > public static void main(String[] args) { > Exception lastException = null; > for (int i = 0; i < 1_000_000; i++) { > try { > jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); > } catch (Exception exception) { > lastException = exception; > } > } > if (lastException != null) { > lastException.printStackTrace(); > } else { > System.out.println("completed"); > } > } > } > ... Volkan Yazici has updated the pull request incrementally with one additional commit since the last revision: Remove superseded `@throws` Javadoc ------------- Changes: - all: https://git.openjdk.org/jdk/pull/25998/files - new: https://git.openjdk.org/jdk/pull/25998/files/f69374fb..86e3ed8d Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=25998&range=09 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=25998&range=08-09 Stats: 2 lines in 1 file changed: 0 ins; 2 del; 0 mod Patch: https://git.openjdk.org/jdk/pull/25998.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/25998/head:pull/25998 PR: https://git.openjdk.org/jdk/pull/25998 From vyazici at openjdk.org Mon Jul 21 12:52:43 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Mon, 21 Jul 2025 12:52:43 GMT Subject: RFR: 8361842: Move input validation checks to Java for java.lang.StringCoding intrinsics [v9] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Mon, 21 Jul 2025 12:33:30 GMT, Volkan Yazici wrote: >> Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. >> >> ## Implementation notes >> >> The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, >> >> 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) >> 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too >> 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method >> 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag >> >> Following preliminary work needs to be carried out as well: >> >> 1. Add a new `VerifyIntrinsicChecks` VM flag >> 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. >> >> 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. >> >> ## Functional and performance tests >> >> - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. >> >> - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. >> >> ## Verification of the VM crash >> >> I've tested the VM crash scenario as follows: >> >> 1. Created the following test program: >> >> public class StrIntri { >> public static void main(String[] args) { >> Exception lastException = null; >> for (int i = 0; i < 1_000_000; i++) { >> try { >> jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); >> } catch (Exception exception) { >> lastException = exception; >> } >> } >> if (lastException != null) { >> lastException.printStackTrace... > > Volkan Yazici has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains 23 additional commits since the last revision: > > - Merge remote-tracking branch 'upstream/master' into strIntrinCheck > - Make `StringCoding` encoding intrinsics lenient > - Fix `encodeISOArray` bounds checks and Javadoc > - Disable `TestVerifyIntrinsicChecks` for GraalVM > - Relax target array capacity check for intrinsic Java wrappers > > It's not possible to determine the required capacity of the target > array in constant time, as Unicode code points may occupy either one > or two `char` values. As a result, existing implementations typically > invoke encoding methods in a loop, handling each unmappable character > on a case-by-case basis. For an example, see > `sun.nio.cs.DoubleByte.Encoder::encode`. > - Fix out-of-bounds in `sun.nio.cs.SingleByte.Encoder::encodeArrayLoop` > - Replace casting with `as_Region()` in `generate_string_range_check` > - Duplicate affected tests with `-XX:+VerifyIntrinsicChecks` variants > - Fix compiler error in `generate_string_range_check` > - Add test verifying the effectiveness of `VerifyIntrinsicChecks` > - ... and 13 more: https://git.openjdk.org/jdk/compare/514f29e4...f69374fb Needed to replace all `Preconditions` invocations throwing `AIOOB` on failure with a more lenient approach that returns 0 on out-of-bounds, because, 1. this matches the compiler intrinsic behavior 2. there are several (i.e., ~7) `sun.nio.cs` classes that depend on this lenient behavior. I needed to either fix(?) these 7 classes or make the intrinsic wrappers more lenient ------------- PR Comment: https://git.openjdk.org/jdk/pull/25998#issuecomment-3096649239 From vyazici at openjdk.org Mon Jul 21 12:54:50 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Mon, 21 Jul 2025 12:54:50 GMT Subject: RFR: 8361842: Move input validation checks to Java for java.lang.StringCoding intrinsics [v9] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Mon, 21 Jul 2025 12:33:30 GMT, Volkan Yazici wrote: >> Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. >> >> ## Implementation notes >> >> The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, >> >> 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) >> 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too >> 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method >> 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag >> >> Following preliminary work needs to be carried out as well: >> >> 1. Add a new `VerifyIntrinsicChecks` VM flag >> 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. >> >> 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. >> >> ## Functional and performance tests >> >> - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. >> >> - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. >> >> ## Verification of the VM crash >> >> I've tested the VM crash scenario as follows: >> >> 1. Created the following test program: >> >> public class StrIntri { >> public static void main(String[] args) { >> Exception lastException = null; >> for (int i = 0; i < 1_000_000; i++) { >> try { >> jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); >> } catch (Exception exception) { >> lastException = exception; >> } >> } >> if (lastException != null) { >> lastException.printStackTrace... > > Volkan Yazici has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains 23 additional commits since the last revision: > > - Merge remote-tracking branch 'upstream/master' into strIntrinCheck > - Make `StringCoding` encoding intrinsics lenient > - Fix `encodeISOArray` bounds checks and Javadoc > - Disable `TestVerifyIntrinsicChecks` for GraalVM > - Relax target array capacity check for intrinsic Java wrappers > > It's not possible to determine the required capacity of the target > array in constant time, as Unicode code points may occupy either one > or two `char` values. As a result, existing implementations typically > invoke encoding methods in a loop, handling each unmappable character > on a case-by-case basis. For an example, see > `sun.nio.cs.DoubleByte.Encoder::encode`. > - Fix out-of-bounds in `sun.nio.cs.SingleByte.Encoder::encodeArrayLoop` > - Replace casting with `as_Region()` in `generate_string_range_check` > - Duplicate affected tests with `-XX:+VerifyIntrinsicChecks` variants > - Fix compiler error in `generate_string_range_check` > - Add test verifying the effectiveness of `VerifyIntrinsicChecks` > - ... and 13 more: https://git.openjdk.org/jdk/compare/343fc72a...f69374fb > > What is the thinking when an `@IntrinsicCandidate` method invokes another `@IntrinsicCandidate` method? Which part is responsible for the checks? > > ... > In the case of `StringUTF16.getChar`, ... @rgiulietti, thanks so much for this crucial question. @rose00, thanks so much for the elaborate response. I will work on `StringUTF16` in a separate PR and use these guidelines provided. ? ------------- PR Comment: https://git.openjdk.org/jdk/pull/25998#issuecomment-3096668620 From vyazici at openjdk.org Mon Jul 21 13:28:00 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Mon, 21 Jul 2025 13:28:00 GMT Subject: RFR: 8361842: Move input validation checks to Java for java.lang.StringCoding intrinsics [v11] In-Reply-To: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: <_YafZXn8pIbA-zuOFNN5sVGBM-uKKy47RPhgRod9Tf4=.1927921f-59af-44a2-be6d-18ce70779f51@github.com> > Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. > > ## Implementation notes > > The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, > > 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) > 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too > 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method > 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag > > Following preliminary work needs to be carried out as well: > > 1. Add a new `VerifyIntrinsicChecks` VM flag > 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. > > 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. > > ## Functional and performance tests > > - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. > > - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. > > ## Verification of the VM crash > > I've tested the VM crash scenario as follows: > > 1. Created the following test program: > > public class StrIntri { > public static void main(String[] args) { > Exception lastException = null; > for (int i = 0; i < 1_000_000; i++) { > try { > jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); > } catch (Exception exception) { > lastException = exception; > } > } > if (lastException != null) { > lastException.printStackTrace(); > } else { > System.out.println("completed"); > } > } > } > ... Volkan Yazici has updated the pull request incrementally with one additional commit since the last revision: Fix bit shifting ------------- Changes: - all: https://git.openjdk.org/jdk/pull/25998/files - new: https://git.openjdk.org/jdk/pull/25998/files/86e3ed8d..025c7ef7 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=25998&range=10 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=25998&range=09-10 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/25998.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/25998/head:pull/25998 PR: https://git.openjdk.org/jdk/pull/25998 From vyazici at openjdk.org Mon Jul 21 13:56:42 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Mon, 21 Jul 2025 13:56:42 GMT Subject: RFR: 8361842: Move input validation checks to Java for java.lang.StringCoding intrinsics [v8] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Thu, 17 Jul 2025 15:33:37 GMT, Raffaello Giulietti wrote: >> What is the thinking when an `@IntrinsicCandidate` method invokes another `@IntrinsicCandidate` method? >> Which part is responsible for the checks? >> >> For example, the Java code of `StringCoding.encodeISOArray0()` invokes `StringUTF16.getChar()`, another `@IntrinsicCandidate` method. The latter does not check its arguments (OK, there's an `assert`, but this is a weak check). The invocation from `encodeISOArray0()` is fine and safe, but `getChar()` is invoked by other parts of the code. >> >> So what is the general strategy? Add checks to `getChar()` and rely on the runtime to eliminate redundant checks? > >> What is the thinking when an `@IntrinsicCandidate` method invokes another `@IntrinsicCandidate` method? Which part is responsible for the checks? >> >> For example, the Java code of `StringCoding.encodeISOArray0()` invokes `StringUTF16.getChar()`, another `@IntrinsicCandidate` method. The latter does not check its arguments (OK, there's an `assert`, but this is a weak check). The invocation from `encodeISOArray0()` is fine and safe, but `getChar()` is invoked by other parts of the code. >> >> So what is the general strategy? Add checks to `getChar()` and rely on the runtime to eliminate redundant checks? > > To reformulate my confusing question for the above example, there are apparently around 75-80 invocations of `getChar()`. How to make sure that they are all safe? Some are easy to verify, but others are not. Even though the `tier1,tier2,tier3,tier4,tier5,hs-comp-stress,hs-precheckin-comp` tests pass on several platforms, @rgiulietti pointed me other shortcomings regarding the recent lenient approach taken. Please allow me some time with this PR. I will keep this PR updated. :popcorn: ------------- PR Comment: https://git.openjdk.org/jdk/pull/25998#issuecomment-3096882515 From myankelevich at openjdk.org Mon Jul 21 15:42:27 2025 From: myankelevich at openjdk.org (Mikhail Yankelevich) Date: Mon, 21 Jul 2025 15:42:27 GMT Subject: RFR: 8361842: Move input validation checks to Java for java.lang.StringCoding intrinsics [v11] In-Reply-To: <_YafZXn8pIbA-zuOFNN5sVGBM-uKKy47RPhgRod9Tf4=.1927921f-59af-44a2-be6d-18ce70779f51@github.com> References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> <_YafZXn8pIbA-zuOFNN5sVGBM-uKKy47RPhgRod9Tf4=.1927921f-59af-44a2-be6d-18ce70779f51@github.com> Message-ID: On Mon, 21 Jul 2025 13:28:00 GMT, Volkan Yazici wrote: >> Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. >> >> ## Implementation notes >> >> The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, >> >> 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) >> 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too >> 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method >> 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag >> >> Following preliminary work needs to be carried out as well: >> >> 1. Add a new `VerifyIntrinsicChecks` VM flag >> 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. >> >> 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. >> >> ## Functional and performance tests >> >> - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. >> >> - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. >> >> ## Verification of the VM crash >> >> I've tested the VM crash scenario as follows: >> >> 1. Created the following test program: >> >> public class StrIntri { >> public static void main(String[] args) { >> Exception lastException = null; >> for (int i = 0; i < 1_000_000; i++) { >> try { >> jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); >> } catch (Exception exception) { >> lastException = exception; >> } >> } >> if (lastException != null) { >> lastException.printStackTrace... > > Volkan Yazici has updated the pull request incrementally with one additional commit since the last revision: > > Fix bit shifting Minor: could you please add a bug id to the `@bug` annotations in tests? ------------- PR Comment: https://git.openjdk.org/jdk/pull/25998#issuecomment-3097286276 From vlivanov at openjdk.org Mon Jul 21 21:15:31 2025 From: vlivanov at openjdk.org (Vladimir Ivanov) Date: Mon, 21 Jul 2025 21:15:31 GMT Subject: RFR: 8347901: C2 should remove unused leaf / pure runtime calls [v5] In-Reply-To: References: Message-ID: On Wed, 9 Jul 2025 12:36:31 GMT, Marc Chevalier wrote: >> A first part toward a better support of pure functions, but this time, with guidance from @iwanowww. >> >> ## Pure Functions >> >> Pure functions (considered here) are functions that have no side effects, no effect on the control flow (no exception or such), cannot deopt etc.. It's really a function that you can execute anywhere, with whichever arguments without effect other than wasting time. Integer division is not pure as dividing by zero is throwing. But many floating point functions will just return `NaN` or `+/-infinity` in problematic cases. >> >> ## Scope >> >> We are not going all powerful for now! It's mostly about identifying some pure functions and being able to remove them if the result is unused. Some other things are not part of this PR, on purpose. Especially, this PR doesn't propose a way to move pure calls around. The reason is that pure calls are later expanded into regular calls, which require a control input. To be able to do the expansion, we just keep the control in the pure call as well. >> >> ## Implementation Overview >> >> We created here some new node kind for pure calls, inheriting leaf calls, that are expanded into regular leaf calls during final graph reshaping. The possibility to support pure call directly in AD file is left open. >> >> This PR also introduces `TupleNode` (largely based on an original idea/implem of @iwanowww), that just tie multiple input together and play well with `ProjNode`: the n-th projection of a `TupleNode` is the n-th input of the tuple. This is a convenient way to skip and remove nodes from the graph while delegating the difficulty of the surgery to the trusted IGVN's implementation. >> >> Thanks, >> Marc > > Marc Chevalier has updated the pull request incrementally with one additional commit since the last revision: > > Tentative to address Tobias' comments Looks good. ------------- Marked as reviewed by vlivanov (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/25760#pullrequestreview-3039873221 From mchevalier at openjdk.org Tue Jul 22 08:51:35 2025 From: mchevalier at openjdk.org (Marc Chevalier) Date: Tue, 22 Jul 2025 08:51:35 GMT Subject: RFR: 8347901: C2 should remove unused leaf / pure runtime calls [v5] In-Reply-To: References: Message-ID: On Wed, 9 Jul 2025 12:36:31 GMT, Marc Chevalier wrote: >> A first part toward a better support of pure functions, but this time, with guidance from @iwanowww. >> >> ## Pure Functions >> >> Pure functions (considered here) are functions that have no side effects, no effect on the control flow (no exception or such), cannot deopt etc.. It's really a function that you can execute anywhere, with whichever arguments without effect other than wasting time. Integer division is not pure as dividing by zero is throwing. But many floating point functions will just return `NaN` or `+/-infinity` in problematic cases. >> >> ## Scope >> >> We are not going all powerful for now! It's mostly about identifying some pure functions and being able to remove them if the result is unused. Some other things are not part of this PR, on purpose. Especially, this PR doesn't propose a way to move pure calls around. The reason is that pure calls are later expanded into regular calls, which require a control input. To be able to do the expansion, we just keep the control in the pure call as well. >> >> ## Implementation Overview >> >> We created here some new node kind for pure calls, inheriting leaf calls, that are expanded into regular leaf calls during final graph reshaping. The possibility to support pure call directly in AD file is left open. >> >> This PR also introduces `TupleNode` (largely based on an original idea/implem of @iwanowww), that just tie multiple input together and play well with `ProjNode`: the n-th projection of a `TupleNode` is the n-th input of the tuple. This is a convenient way to skip and remove nodes from the graph while delegating the difficulty of the surgery to the trusted IGVN's implementation. >> >> Thanks, >> Marc > > Marc Chevalier has updated the pull request incrementally with one additional commit since the last revision: > > Tentative to address Tobias' comments Thanks all for your comments! ------------- PR Comment: https://git.openjdk.org/jdk/pull/25760#issuecomment-3101702054 From mchevalier at openjdk.org Tue Jul 22 08:51:37 2025 From: mchevalier at openjdk.org (Marc Chevalier) Date: Tue, 22 Jul 2025 08:51:37 GMT Subject: Integrated: 8347901: C2 should remove unused leaf / pure runtime calls In-Reply-To: References: Message-ID: On Wed, 11 Jun 2025 16:18:41 GMT, Marc Chevalier wrote: > A first part toward a better support of pure functions, but this time, with guidance from @iwanowww. > > ## Pure Functions > > Pure functions (considered here) are functions that have no side effects, no effect on the control flow (no exception or such), cannot deopt etc.. It's really a function that you can execute anywhere, with whichever arguments without effect other than wasting time. Integer division is not pure as dividing by zero is throwing. But many floating point functions will just return `NaN` or `+/-infinity` in problematic cases. > > ## Scope > > We are not going all powerful for now! It's mostly about identifying some pure functions and being able to remove them if the result is unused. Some other things are not part of this PR, on purpose. Especially, this PR doesn't propose a way to move pure calls around. The reason is that pure calls are later expanded into regular calls, which require a control input. To be able to do the expansion, we just keep the control in the pure call as well. > > ## Implementation Overview > > We created here some new node kind for pure calls, inheriting leaf calls, that are expanded into regular leaf calls during final graph reshaping. The possibility to support pure call directly in AD file is left open. > > This PR also introduces `TupleNode` (largely based on an original idea/implem of @iwanowww), that just tie multiple input together and play well with `ProjNode`: the n-th projection of a `TupleNode` is the n-th input of the tuple. This is a convenient way to skip and remove nodes from the graph while delegating the difficulty of the surgery to the trusted IGVN's implementation. > > Thanks, > Marc This pull request has now been integrated. Changeset: ed70910b Author: Marc Chevalier URL: https://git.openjdk.org/jdk/commit/ed70910b0f3e1b19d915ec13ac3434407d01bc5d Stats: 343 lines in 15 files changed: 198 ins; 61 del; 84 mod 8347901: C2 should remove unused leaf / pure runtime calls Reviewed-by: thartmann, vlivanov ------------- PR: https://git.openjdk.org/jdk/pull/25760 From kvn at openjdk.org Tue Jul 22 22:03:10 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Tue, 22 Jul 2025 22:03:10 GMT Subject: RFR: 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs Message-ID: `StubRoutines::_crc_table_adr` and `_crc32c_table_addr` are used by initial stubs. In Leyden these addresses should be recorded in `AOTCodeAddressTable` to be used by AOTed stubs. But recording in `AOTCodeAddressTable` is done in `AOTCodeCache::init2()` which is called before initial stubs are generated and `_crc*_table_addr` are set. We need to move `_crc_table_addr` and `_crc32c_table_addr` initialization to `preuniverse` blob to be available in `AOTCodeCache::init2()`. I also renamed `_crc_table_adr` to `_crc_table_addr` to match other names. During testing I found that `-Xlog:stubs` affects empty blobs generation. There was typo there: `return nullptr;` was in wrong place. I have to specify sizes of `preuniverse` blobs so they are called after I fixed typo. `32` bytes is cache line size on most CPUs. Note, there will be no assembler code generation for this case: `_crc*_table_addr` are initialized by address of C tables. I did not move `_crc*_table_addr` declaration in `stubDeclarations.hpp` from `init` to `preuniverse` blob. I tried but there is issue: they require to specify stub name and I can move `updateBytesCRC32` stub declaration. I tries add fake stub but it did not work. I would prefer if I could use `nullptr` instead of stub in such case. But it will complicate other code. I think it is fine `do_entry()` macro only creates field and accessor function. Tested: tier1-4,tier10-rt,xcomp,stress ------------- Commit messages: - 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs Changes: https://git.openjdk.org/jdk/pull/26434/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=26434&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8363837 Stats: 63 lines in 13 files changed: 37 ins; 13 del; 13 mod Patch: https://git.openjdk.org/jdk/pull/26434.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26434/head:pull/26434 PR: https://git.openjdk.org/jdk/pull/26434 From kvn at openjdk.org Tue Jul 22 22:03:10 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Tue, 22 Jul 2025 22:03:10 GMT Subject: RFR: 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs In-Reply-To: References: Message-ID: On Tue, 22 Jul 2025 21:56:13 GMT, Vladimir Kozlov wrote: > `StubRoutines::_crc_table_adr` and `_crc32c_table_addr` are used by initial stubs. In Leyden these addresses should be recorded in `AOTCodeAddressTable` to be used by AOTed stubs. But recording in `AOTCodeAddressTable` is done in `AOTCodeCache::init2()` which is called before initial stubs are generated and `_crc*_table_addr` are set. > > We need to move `_crc_table_addr` and `_crc32c_table_addr` initialization to `preuniverse` blob to be available in `AOTCodeCache::init2()`. > > I also renamed `_crc_table_adr` to `_crc_table_addr` to match other names. > > During testing I found that `-Xlog:stubs` affects empty blobs generation. There was typo there: `return nullptr;` was in wrong place. > > I have to specify sizes of `preuniverse` blobs so they are called after I fixed typo. `32` bytes is cache line size on most CPUs. Note, there will be no assembler code generation for this case: `_crc*_table_addr` are initialized by address of C tables. > > I did not move `_crc*_table_addr` declaration in `stubDeclarations.hpp` from `init` to `preuniverse` blob. I tried but there is issue: they require to specify stub name and I can move `updateBytesCRC32` stub declaration. I tries add fake stub but it did not work. I would prefer if I could use `nullptr` instead of stub in such case. But it will complicate other code. I think it is fine `do_entry()` macro only creates field and accessor function. > > Tested: tier1-4,tier10-rt,xcomp,stress @adinn please look ------------- PR Comment: https://git.openjdk.org/jdk/pull/26434#issuecomment-3104946401 From kvn at openjdk.org Tue Jul 22 22:34:58 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Tue, 22 Jul 2025 22:34:58 GMT Subject: RFR: 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs In-Reply-To: References: Message-ID: On Tue, 22 Jul 2025 21:56:13 GMT, Vladimir Kozlov wrote: > and I can move updateBytesCRC32 stub declaration. and I can **NOT** move updateBytesCRC32 stub declaration. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26434#issuecomment-3105014228 From kvn at openjdk.org Wed Jul 23 01:10:55 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Wed, 23 Jul 2025 01:10:55 GMT Subject: RFR: 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs In-Reply-To: References: Message-ID: On Tue, 22 Jul 2025 21:56:13 GMT, Vladimir Kozlov wrote: > `StubRoutines::_crc_table_adr` and `_crc32c_table_addr` are used by initial stubs. In Leyden these addresses should be recorded in `AOTCodeAddressTable` to be used by AOTed stubs. But recording in `AOTCodeAddressTable` is done in `AOTCodeCache::init2()` which is called before initial stubs are generated and `_crc*_table_addr` are set. > > We need to move `_crc_table_addr` and `_crc32c_table_addr` initialization to `preuniverse` blob to be available in `AOTCodeCache::init2()`. > > I also renamed `_crc_table_adr` to `_crc_table_addr` to match other names. > > During testing I found that `-Xlog:stubs` affects empty blobs generation. There was typo there: `return nullptr;` was in wrong place. > > I have to specify sizes of `preuniverse` blobs so they are called after I fixed typo. `32` bytes is cache line size on most CPUs. Note, there will be no assembler code generation for this case: `_crc*_table_addr` are initialized by address of C tables. > > I did not move `_crc*_table_addr` declaration in `stubDeclarations.hpp` from `init` to `preuniverse` blob. I tried but there is issue: they require to specify stub name and I can move `updateBytesCRC32` stub declaration. I tries add fake stub but it did not work. I would prefer if I could use `nullptr` instead of stub in such case. But it will complicate other code. I think it is fine `do_entry()` macro only creates field and accessor function. > > Tested: tier1-4,tier10-rt,xcomp,stress @TheRealMDoerr @offamitkumar @RealFYang please test these changes on your platforms. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26434#issuecomment-3105290106 From kvn at openjdk.org Wed Jul 23 02:00:43 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Wed, 23 Jul 2025 02:00:43 GMT Subject: RFR: 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs [v2] In-Reply-To: References: Message-ID: > `StubRoutines::_crc_table_adr` and `_crc32c_table_addr` are used by initial stubs. In Leyden these addresses should be recorded in `AOTCodeAddressTable` to be used by AOTed stubs. But recording in `AOTCodeAddressTable` is done in `AOTCodeCache::init2()` which is called before initial stubs are generated and `_crc*_table_addr` are set. > > We need to move `_crc_table_addr` and `_crc32c_table_addr` initialization to `preuniverse` blob to be available in `AOTCodeCache::init2()`. > > I also renamed `_crc_table_adr` to `_crc_table_addr` to match other names. > > During testing I found that `-Xlog:stubs` affects empty blobs generation. There was typo there: `return nullptr;` was in wrong place. > > I have to specify sizes of `preuniverse` blobs so they are called after I fixed typo. `32` bytes is cache line size on most CPUs. Note, there will be no assembler code generation for this case: `_crc*_table_addr` are initialized by address of C tables. > > I did not move `_crc*_table_addr` declaration in `stubDeclarations.hpp` from `init` to `preuniverse` blob. I tried but there is issue: they require to specify stub name and I can move `updateBytesCRC32` stub declaration. I tries add fake stub but it did not work. I would prefer if I could use `nullptr` instead of stub in such case. But it will complicate other code. I think it is fine `do_entry()` macro only creates field and accessor function. > > Tested: tier1-4,tier10-rt,xcomp,stress Vladimir Kozlov has updated the pull request incrementally with one additional commit since the last revision: Fixed Zero VM ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26434/files - new: https://git.openjdk.org/jdk/pull/26434/files/08f27284..6459712d Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26434&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26434&range=00-01 Stats: 3 lines in 1 file changed: 0 ins; 0 del; 3 mod Patch: https://git.openjdk.org/jdk/pull/26434.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26434/head:pull/26434 PR: https://git.openjdk.org/jdk/pull/26434 From vyazici at openjdk.org Wed Jul 23 12:54:00 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Wed, 23 Jul 2025 12:54:00 GMT Subject: RFR: 8361842: Move input validation checks to Java for java.lang.StringCoding intrinsics [v12] In-Reply-To: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: > Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. > > ## Implementation notes > > The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, > > 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) > 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too > 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method > 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag > > Following preliminary work needs to be carried out as well: > > 1. Add a new `VerifyIntrinsicChecks` VM flag > 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. > > 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. > > ## Functional and performance tests > > - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. > > - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. > > ## Verification of the VM crash > > I've tested the VM crash scenario as follows: > > 1. Created the following test program: > > public class StrIntri { > public static void main(String[] args) { > Exception lastException = null; > for (int i = 0; i < 1_000_000; i++) { > try { > jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); > } catch (Exception exception) { > lastException = exception; > } > } > if (lastException != null) { > lastException.printStackTrace(); > } else { > System.out.println("completed"); > } > } > } > ... Volkan Yazici has updated the pull request incrementally with four additional commits since the last revision: - Add `@bug` tags - Improve wording of `@param len` - Make source array bound checks lenient too - Cap destination array bounds ------------- Changes: - all: https://git.openjdk.org/jdk/pull/25998/files - new: https://git.openjdk.org/jdk/pull/25998/files/025c7ef7..1d02189f Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=25998&range=11 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=25998&range=10-11 Stats: 29 lines in 6 files changed: 8 ins; 12 del; 9 mod Patch: https://git.openjdk.org/jdk/pull/25998.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/25998/head:pull/25998 PR: https://git.openjdk.org/jdk/pull/25998 From vyazici at openjdk.org Wed Jul 23 12:54:01 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Wed, 23 Jul 2025 12:54:01 GMT Subject: RFR: 8361842: Move input validation checks to Java for java.lang.StringCoding intrinsics [v11] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> <_YafZXn8pIbA-zuOFNN5sVGBM-uKKy47RPhgRod9Tf4=.1927921f-59af-44a2-be6d-18ce70779f51@github.com> Message-ID: On Mon, 21 Jul 2025 15:39:34 GMT, Mikhail Yankelevich wrote: > Minor: could you please add a bug id to the `@bug` annotations in tests? @myankelev, thanks for the heads up. Implemented in 1d02189fba1. ------------- PR Comment: https://git.openjdk.org/jdk/pull/25998#issuecomment-3107998200 From adinn at openjdk.org Wed Jul 23 13:21:54 2025 From: adinn at openjdk.org (Andrew Dinn) Date: Wed, 23 Jul 2025 13:21:54 GMT Subject: RFR: 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs In-Reply-To: References: Message-ID: On Wed, 23 Jul 2025 01:07:58 GMT, Vladimir Kozlov wrote: >> `StubRoutines::_crc_table_adr` and `_crc32c_table_addr` are used by initial stubs. In Leyden these addresses should be recorded in `AOTCodeAddressTable` to be used by AOTed stubs. But recording in `AOTCodeAddressTable` is done in `AOTCodeCache::init2()` which is called before initial stubs are generated and `_crc*_table_addr` are set. >> >> We need to move `_crc_table_addr` and `_crc32c_table_addr` initialization to `preuniverse` blob to be available in `AOTCodeCache::init2()`. >> >> I also renamed `_crc_table_adr` to `_crc_table_addr` to match other names. >> >> During testing I found that `-Xlog:stubs` affects empty blobs generation. There was typo there: `return nullptr;` was in wrong place. >> >> I have to specify sizes of `preuniverse` blobs so they are called after I fixed typo. `32` bytes is cache line size on most CPUs. Note, there will be no assembler code generation for this case: `_crc*_table_addr` are initialized by address of C tables. >> >> I did not move `_crc*_table_addr` declaration in `stubDeclarations.hpp` from `init` to `preuniverse` blob. I tried but there is issue: they require to specify stub name and I can move `updateBytesCRC32` stub declaration. I tries add fake stub but it did not work. I would prefer if I could use `nullptr` instead of stub in such case. But it will complicate other code. I think it is fine `do_entry()` macro only creates field and accessor function. >> >> Tested: tier1-4,tier10-rt,xcomp,stress > > @TheRealMDoerr @offamitkumar @RealFYang please test these changes on your platforms. @vnkozlov I'll note straight off that the situation here is complicated by the fact that `crc_table_adr` and `crc32c_table_addr` are pseudo-'entries'. They do not actually hold (code or data) addresses in generated code. What they really identify is an arch-specific address for foreign (C++) data that is assigned as a side-effect of performing generation for other entries. the only reason for marking them as entries is so we get a generated field and associated getter in class `StubRoutines`. I'm not sure we need to care too much about their pseudo-entry status. More importantly, I dislike your solution of moving the initialization into `generate_preuniverse_stubs()`. This moves that initialization step away from the generator code that uses the resulting value, making it harder to see how the intrinsic works. It also has the unfortunate side effect of forcing us to create a preuinverse blob for every arch even if when we don't really need one. You are right that we cannot add these addresses to the external addresses list under `AOTCodeCache::init2()` (via the call to `table->init_extrs()`) because the assignment of the pseudo-entry has not yet happened. However, we have two alternatives. 1) We can simply pretend that they are real entries add them to the stub addresses list under `AOTCodeCache::init_early_stubs_table()` (via the call to `table->init_early_stubs()`). That will successfully advertise them after they have been created as addresses that need relocation at AOT Cache load. However, it will also misclassify them as addresses in generated code when they are actually foreign addresses. Do we care about that misclassification (do we use a different reloc for stubs addresses vs external addresses?) 2) We can leave the external addresses table open at the end of the call to table->init_extrs()`. When we enter table->init_early_stubs() we can add these two extra 'pseudo-stub' addresses to the external addresses list and close it before registering the early stubs addresses. Both of these seem to me to be simpler and cleaner ways to deal with the address publication problem. What do you think? ------------- PR Comment: https://git.openjdk.org/jdk/pull/26434#issuecomment-3108328211 From tschatzl at openjdk.org Wed Jul 23 14:34:47 2025 From: tschatzl at openjdk.org (Thomas Schatzl) Date: Wed, 23 Jul 2025 14:34:47 GMT Subject: RFR: 8342382: Implementation of JEP G1: Improve Application Throughput with a More Efficient Write-Barrier [v44] In-Reply-To: References: Message-ID: <0KXHzGhrVDYfe_gWdT7DFsZYNyKDDVv9Os8K91HLfUQ=.b120a07e-95d0-4140-be81-a95e1b02f5d5@github.com> > Hi all, > > please review this change that implements (currently Draft) JEP: G1: Improve Application Throughput with a More Efficient Write-Barrier. > > The reason for posting this early is that this is a large change, and the JEP process is already taking very long with no end in sight but we would like to have this ready by JDK 25. > > ### Current situation > > With this change, G1 will reduce the post write barrier to much more resemble Parallel GC's as described in the JEP. The reason is that G1 lacks in throughput compared to Parallel/Serial GC due to larger barrier. > > The main reason for the current barrier is how g1 implements concurrent refinement: > * g1 tracks dirtied cards using sets (dirty card queue set - dcqs) of buffers (dirty card queues - dcq) containing the location of dirtied cards. Refinement threads pick up their contents to re-refine. The barrier needs to enqueue card locations. > * For correctness dirty card updates requires fine-grained synchronization between mutator and refinement threads, > * Finally there is generic code to avoid dirtying cards altogether (filters), to avoid executing the synchronization and the enqueuing as much as possible. > > These tasks require the current barrier to look as follows for an assignment `x.a = y` in pseudo code: > > > // Filtering > if (region(@x.a) == region(y)) goto done; // same region check > if (y == null) goto done; // null value check > if (card(@x.a) == young_card) goto done; // write to young gen check > StoreLoad; // synchronize > if (card(@x.a) == dirty_card) goto done; > > *card(@x.a) = dirty > > // Card tracking > enqueue(card-address(@x.a)) into thread-local-dcq; > if (thread-local-dcq is not full) goto done; > > call runtime to move thread-local-dcq into dcqs > > done: > > > Overall this post-write barrier alone is in the range of 40-50 total instructions, compared to three or four(!) for parallel and serial gc. > > The large size of the inlined barrier not only has a large code footprint, but also prevents some compiler optimizations like loop unrolling or inlining. > > There are several papers showing that this barrier alone can decrease throughput by 10-20% ([Yang12](https://dl.acm.org/doi/10.1145/2426642.2259004)), which is corroborated by some benchmarks (see links). > > The main idea for this change is to not use fine-grained synchronization between refinement and mutator threads, but coarse grained based on atomically switching card tables. Mutators only work on the "primary" card table, refinement threads on a se... Thomas Schatzl has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 61 commits: - * remove unused G1DetachedRefinementStats_lock - Merge branch 'master' into 8342382-card-table-instead-of-dcq - Merge branch 'master' into 8342382-card-table-instead-of-dcq - Merge branch 'master' into pull/23739 - Merge branch 'master' into 8342382-card-table-instead-of-dcq - Merge branch 'master' into 8342382-card-table-instead-of-dcq - Merge branch 'master' into 8342382-card-table-instead-of-dcq - Merge branch 'master' into 8342382-card-table-instead-of-dcq - * ayang review: remove sweep_epoch - Merge branch 'master' into card-table-as-dcq-merge - ... and 51 more: https://git.openjdk.org/jdk/compare/743c8212...dd836387 ------------- Changes: https://git.openjdk.org/jdk/pull/23739/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=23739&range=43 Stats: 7122 lines in 112 files changed: 2588 ins; 3592 del; 942 mod Patch: https://git.openjdk.org/jdk/pull/23739.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/23739/head:pull/23739 PR: https://git.openjdk.org/jdk/pull/23739 From kvn at openjdk.org Wed Jul 23 15:06:54 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Wed, 23 Jul 2025 15:06:54 GMT Subject: RFR: 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs In-Reply-To: References: Message-ID: On Wed, 23 Jul 2025 13:19:35 GMT, Andrew Dinn wrote: >> @TheRealMDoerr @offamitkumar @RealFYang please test these changes on your platforms. > > @vnkozlov I'll note straight off that the situation here is complicated by the fact that `crc_table_adr` and `crc32c_table_addr` are pseudo-'entries'. They do not actually hold (code or data) addresses in generated code. What they really identify is an arch-specific address for foreign (C++) data that is assigned as a side-effect of performing generation for other entries. the only reason for marking them as entries is so we get a generated field and associated getter in class `StubRoutines`. > > I'm not sure we need to care too much about their pseudo-entry status. More importantly, I dislike your solution of moving the initialization into `generate_preuniverse_stubs()`. This moves that initialization step away from the generator code that uses the resulting value, making it harder to see how the intrinsic works. It also has the unfortunate side effect of forcing us to create a preuinverse blob for every arch even if when we don't really need one. > > You are right that we cannot add these addresses to the external addresses list under `AOTCodeCache::init2()` (via the call to `table->init_extrs()`) because the assignment of the pseudo-entry has not yet happened. However, we have two alternatives. > > 1) We can simply pretend that they are real entries add them to the stub addresses list under `AOTCodeCache::init_early_stubs_table()` (via the call to `table->init_early_stubs()`). That will successfully advertise them after they have been created as addresses that need relocation at AOT Cache load. However, it will also misclassify them as addresses in generated code when they are actually foreign addresses. Do we care about that misclassification (do we use a different reloc for stubs addresses vs external addresses?) > > 2) We can leave the external addresses table open at the end of the call to table->init_extrs()`. When we enter table->init_early_stubs() we can add these two extra 'pseudo-stub' addresses to the external addresses list and close it before registering the early stubs addresses. > > Both of these seem to me to be simpler and cleaner ways to deal with the address publication problem. What do you think? Thank you, @adinn for you suggestions. > do we use a different reloc for stubs addresses vs external addresses? 1. will not work. They could be different. Stubs use `runtime_call` relic and `crc` uses `external_word`. I considered 2. when I worked on this but there is assumption that we have all external addresses recorded when we look for matching address in `AOTCodeAddressTable::id_for_address()`. There is specific assert there. And we have relocation in all stubs and adapters. I am concern about some concurrency issues if we don't satisfy the assumption. An other solution would be to have separate `StubRoutines::get_crc_table_addr()` which can be use early by AOT code and later by `generate_initial_stubs()`. It will check local value (StubRoutines::x86::_crc32c_table on x86, for example) and calculate it if needed. What do you think? ------------- PR Comment: https://git.openjdk.org/jdk/pull/26434#issuecomment-3109030825 From adinn at openjdk.org Wed Jul 23 15:45:57 2025 From: adinn at openjdk.org (Andrew Dinn) Date: Wed, 23 Jul 2025 15:45:57 GMT Subject: RFR: 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs In-Reply-To: References: Message-ID: On Wed, 23 Jul 2025 15:04:07 GMT, Vladimir Kozlov wrote: > Another solution would be to have separate StubRoutines::get_crc_table_addr() which can be use early by AOT code and later by generate_initial_stubs(). It will check local value (StubRoutines::x86::_crc32c_table on x86, for example) and calculate it if needed. Yes, I think it would be much better if we removed the entry declarations for `crc_table_adr` and `crc32c_table_addr` from stubDeclarations.hpp and instead always looked up the address using a getter method declared in the shared header and implemented in each arch. We don't need a generated field in class StubRoutines nor any way to track the value as we do for real generated addresses. So, using the declaration mechanism was the wrong way to do this. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26434#issuecomment-3109177274 From kvn at openjdk.org Wed Jul 23 21:26:11 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Wed, 23 Jul 2025 21:26:11 GMT Subject: RFR: 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs [v3] In-Reply-To: References: Message-ID: > `StubRoutines::_crc_table_adr` and `_crc32c_table_addr` are used by initial stubs. In Leyden these addresses should be recorded in `AOTCodeAddressTable` to be used by AOTed stubs. But recording in `AOTCodeAddressTable` is done in `AOTCodeCache::init2()` which is called before initial stubs are generated and `_crc*_table_addr` are set. > > We need to move `_crc_table_addr` and `_crc32c_table_addr` initialization to `preuniverse` blob to be available in `AOTCodeCache::init2()`. > > I also renamed `_crc_table_adr` to `_crc_table_addr` to match other names. > > During testing I found that `-Xlog:stubs` affects empty blobs generation. There was typo there: `return nullptr;` was in wrong place. > > I have to specify sizes of `preuniverse` blobs so they are called after I fixed typo. `32` bytes is cache line size on most CPUs. Note, there will be no assembler code generation for this case: `_crc*_table_addr` are initialized by address of C tables. > > I did not move `_crc*_table_addr` declaration in `stubDeclarations.hpp` from `init` to `preuniverse` blob. I tried but there is issue: they require to specify stub name and I can move `updateBytesCRC32` stub declaration. I tries add fake stub but it did not work. I would prefer if I could use `nullptr` instead of stub in such case. But it will complicate other code. I think it is fine `do_entry()` macro only creates field and accessor function. > > Tested: tier1-4,tier10-rt,xcomp,stress Vladimir Kozlov has updated the pull request incrementally with one additional commit since the last revision: Rework the fix ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26434/files - new: https://git.openjdk.org/jdk/pull/26434/files/6459712d..f0378d20 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26434&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26434&range=01-02 Stats: 105 lines in 25 files changed: 50 ins; 41 del; 14 mod Patch: https://git.openjdk.org/jdk/pull/26434.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26434/head:pull/26434 PR: https://git.openjdk.org/jdk/pull/26434 From kvn at openjdk.org Wed Jul 23 21:29:00 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Wed, 23 Jul 2025 21:29:00 GMT Subject: RFR: 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs [v2] In-Reply-To: References: Message-ID: On Wed, 23 Jul 2025 02:00:43 GMT, Vladimir Kozlov wrote: >> `StubRoutines::_crc_table_adr` and `_crc32c_table_addr` are used by initial stubs. In Leyden these addresses should be recorded in `AOTCodeAddressTable` to be used by AOTed stubs. But recording in `AOTCodeAddressTable` is done in `AOTCodeCache::init2()` which is called before initial stubs are generated and `_crc*_table_addr` are set. >> >> We need to move `_crc_table_addr` and `_crc32c_table_addr` initialization to `preuniverse` blob to be available in `AOTCodeCache::init2()`. >> >> I also renamed `_crc_table_adr` to `_crc_table_addr` to match other names. >> >> During testing I found that `-Xlog:stubs` affects empty blobs generation. There was typo there: `return nullptr;` was in wrong place. >> >> I have to specify sizes of `preuniverse` blobs so they are called after I fixed typo. `32` bytes is cache line size on most CPUs. Note, there will be no assembler code generation for this case: `_crc*_table_addr` are initialized by address of C tables. >> >> I did not move `_crc*_table_addr` declaration in `stubDeclarations.hpp` from `init` to `preuniverse` blob. I tried but there is issue: they require to specify stub name and I can move `updateBytesCRC32` stub declaration. I tries add fake stub but it did not work. I would prefer if I could use `nullptr` instead of stub in such case. But it will complicate other code. I think it is fine `do_entry()` macro only creates field and accessor function. >> >> Tested: tier1-4,tier10-rt,xcomp,stress > > Vladimir Kozlov has updated the pull request incrementally with one additional commit since the last revision: > > Fixed Zero VM Here is new version of fix as we discussed. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26434#issuecomment-3110218210 From fyang at openjdk.org Thu Jul 24 07:18:54 2025 From: fyang at openjdk.org (Fei Yang) Date: Thu, 24 Jul 2025 07:18:54 GMT Subject: RFR: 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs In-Reply-To: References: Message-ID: On Wed, 23 Jul 2025 01:07:58 GMT, Vladimir Kozlov wrote: > @TheRealMDoerr @offamitkumar @RealFYang please test these changes on your platforms. Thanks for the ping. I performed tier1 test and I see the result is clean with the latest version on linux-riscv64. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26434#issuecomment-3112326408 From adinn at openjdk.org Thu Jul 24 07:44:55 2025 From: adinn at openjdk.org (Andrew Dinn) Date: Thu, 24 Jul 2025 07:44:55 GMT Subject: RFR: 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs [v3] In-Reply-To: References: Message-ID: On Wed, 23 Jul 2025 21:26:11 GMT, Vladimir Kozlov wrote: >> `StubRoutines::_crc_table_adr` and `_crc32c_table_addr` are used by initial stubs. In Leyden these addresses should be recorded in `AOTCodeAddressTable` to be used by AOTed stubs. But recording in `AOTCodeAddressTable` is done in `AOTCodeCache::init2()` which is called before initial stubs are generated and `_crc*_table_addr` are set. >> >> We need to move `_crc_table_addr` and `_crc32c_table_addr` initialization to `preuniverse` blob to be available in `AOTCodeCache::init2()`. >> >> I also renamed `_crc_table_adr` to `_crc_table_addr` to match other names. >> >> During testing I found that `-Xlog:stubs` affects empty blobs generation. There was typo there: `return nullptr;` was in wrong place. >> >> I have to specify sizes of `preuniverse` blobs so they are called after I fixed typo. `32` bytes is cache line size on most CPUs. Note, there will be no assembler code generation for this case: `_crc*_table_addr` are initialized by address of C tables. >> >> I did not move `_crc*_table_addr` declaration in `stubDeclarations.hpp` from `init` to `preuniverse` blob. I tried but there is issue: they require to specify stub name and I can move `updateBytesCRC32` stub declaration. I tries add fake stub but it did not work. I would prefer if I could use `nullptr` instead of stub in such case. But it will complicate other code. I think it is fine `do_entry()` macro only creates field and accessor function. >> >> Tested: tier1-4,tier10-rt,xcomp,stress > > Vladimir Kozlov has updated the pull request incrementally with one additional commit since the last revision: > > Rework the fix src/hotspot/cpu/zero/stubDeclarations_zero.hpp line 40: > 38: do_arch_entry, \ > 39: do_arch_entry_init) \ > 40: do_arch_blob(initial, 32) \ Do we need this any more? ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26434#discussion_r2227698445 From adinn at openjdk.org Thu Jul 24 07:51:01 2025 From: adinn at openjdk.org (Andrew Dinn) Date: Thu, 24 Jul 2025 07:51:01 GMT Subject: RFR: 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs [v3] In-Reply-To: References: Message-ID: On Wed, 23 Jul 2025 21:26:11 GMT, Vladimir Kozlov wrote: >> `StubRoutines::_crc_table_adr` and `_crc32c_table_addr` are used by initial stubs. In Leyden these addresses should be recorded in `AOTCodeAddressTable` to be used by AOTed stubs. But recording in `AOTCodeAddressTable` is done in `AOTCodeCache::init2()` which is called before initial stubs are generated and `_crc*_table_addr` are set. >> >> We need to move `_crc_table_addr` and `_crc32c_table_addr` initialization to `preuniverse` blob to be available in `AOTCodeCache::init2()`. >> >> I also renamed `_crc_table_adr` to `_crc_table_addr` to match other names. >> >> During testing I found that `-Xlog:stubs` affects empty blobs generation. There was typo there: `return nullptr;` was in wrong place. >> >> I have to specify sizes of `preuniverse` blobs so they are called after I fixed typo. `32` bytes is cache line size on most CPUs. Note, there will be no assembler code generation for this case: `_crc*_table_addr` are initialized by address of C tables. >> >> I did not move `_crc*_table_addr` declaration in `stubDeclarations.hpp` from `init` to `preuniverse` blob. I tried but there is issue: they require to specify stub name and I can move `updateBytesCRC32` stub declaration. I tries add fake stub but it did not work. I would prefer if I could use `nullptr` instead of stub in such case. But it will complicate other code. I think it is fine `do_entry()` macro only creates field and accessor function. >> >> Tested: tier1-4,tier10-rt,xcomp,stress > > Vladimir Kozlov has updated the pull request incrementally with one additional commit since the last revision: > > Rework the fix src/hotspot/share/runtime/stubRoutines.hpp line 306: > 304: return dest_uninitialized ? _arrayof_oop_disjoint_arraycopy_uninit : _arrayof_oop_disjoint_arraycopy; > 305: } > 306: Could we have a comment here to note that 1) this method is implemented in architecture-specific code 2) any table that is returned must be allocated once-only in foreign memory rather generated in the code cache. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26434#discussion_r2227726242 From yzheng at openjdk.org Thu Jul 24 13:25:57 2025 From: yzheng at openjdk.org (Yudi Zheng) Date: Thu, 24 Jul 2025 13:25:57 GMT Subject: RFR: 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs [v2] In-Reply-To: References: Message-ID: On Wed, 23 Jul 2025 02:00:43 GMT, Vladimir Kozlov wrote: >> `StubRoutines::_crc_table_adr` and `_crc32c_table_addr` are used by initial stubs. In Leyden these addresses should be recorded in `AOTCodeAddressTable` to be used by AOTed stubs. But recording in `AOTCodeAddressTable` is done in `AOTCodeCache::init2()` which is called before initial stubs are generated and `_crc*_table_addr` are set. >> >> We need to move `_crc_table_addr` and `_crc32c_table_addr` initialization to `preuniverse` blob to be available in `AOTCodeCache::init2()`. >> >> I also renamed `_crc_table_adr` to `_crc_table_addr` to match other names. >> >> During testing I found that `-Xlog:stubs` affects empty blobs generation. There was typo there: `return nullptr;` was in wrong place. >> >> I have to specify sizes of `preuniverse` blobs so they are called after I fixed typo. `32` bytes is cache line size on most CPUs. Note, there will be no assembler code generation for this case: `_crc*_table_addr` are initialized by address of C tables. >> >> I did not move `_crc*_table_addr` declaration in `stubDeclarations.hpp` from `init` to `preuniverse` blob. I tried but there is issue: they require to specify stub name and I can move `updateBytesCRC32` stub declaration. I tries add fake stub but it did not work. I would prefer if I could use `nullptr` instead of stub in such case. But it will complicate other code. I think it is fine `do_entry()` macro only creates field and accessor function. >> >> Tested: tier1-4,tier10-rt,xcomp,stress > > Vladimir Kozlov has updated the pull request incrementally with one additional commit since the last revision: > > Fixed Zero VM src/hotspot/share/jvmci/vmStructs_jvmci.cpp line 420: > 418: static_field(StubRoutines, _dilithiumDecomposePoly, address) \ > 419: static_field(StubRoutines, _updateBytesCRC32, address) \ > 420: static_field(StubRoutines, _crc_table_addr, address) \ Could you please export via `CompilerToVM::Data`? diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp index 41531b083fc..71331b578a5 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp @@ -131,6 +131,8 @@ class CompilerToVM { static address dlog10; static address dpow; + static address crc_table_addr; + static address symbol_init; static address symbol_clinit; diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp index b6d919fdfe9..8a1a02d62b3 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp @@ -151,6 +151,8 @@ address CompilerToVM::Data::dlog; address CompilerToVM::Data::dlog10; address CompilerToVM::Data::dpow; +address CompilerToVM::Data::crc_table_addr; + address CompilerToVM::Data::symbol_init; address CompilerToVM::Data::symbol_clinit; @@ -289,6 +291,7 @@ void CompilerToVM::Data::initialize(JVMCI_TRAPS) { SET_TRIGFUNC_OR_NULL(dtanh); SET_TRIGFUNC_OR_NULL(dcbrt); + SET_TRIGFUNC_OR_NULL(crc_table_addr); #undef SET_TRIGFUNC_OR_NULL diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp index 1408cb09b0a..88d098468e9 100644 --- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp +++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp @@ -147,6 +147,7 @@ static_field(CompilerToVM::Data, dlog, address) \ static_field(CompilerToVM::Data, dlog10, address) \ static_field(CompilerToVM::Data, dpow, address) \ + static_field(CompilerToVM::Data, crc_table_addr, address) \ \ static_field(CompilerToVM::Data, symbol_init, address) \ static_field(CompilerToVM::Data, symbol_clinit, address) \ ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26434#discussion_r2228514289 From rriggs at openjdk.org Thu Jul 24 14:08:57 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Thu, 24 Jul 2025 14:08:57 GMT Subject: RFR: 8361842: Move input validation checks to Java for java.lang.StringCoding intrinsics [v12] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: On Wed, 23 Jul 2025 12:54:00 GMT, Volkan Yazici wrote: >> Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. >> >> ## Implementation notes >> >> The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, >> >> 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) >> 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too >> 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method >> 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag >> >> Following preliminary work needs to be carried out as well: >> >> 1. Add a new `VerifyIntrinsicChecks` VM flag >> 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. >> >> 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. >> >> ## Functional and performance tests >> >> - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. >> >> - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. >> >> ## Verification of the VM crash >> >> I've tested the VM crash scenario as follows: >> >> 1. Created the following test program: >> >> public class StrIntri { >> public static void main(String[] args) { >> Exception lastException = null; >> for (int i = 0; i < 1_000_000; i++) { >> try { >> jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); >> } catch (Exception exception) { >> lastException = exception; >> } >> } >> if (lastException != null) { >> lastException.printStackTrace... > > Volkan Yazici has updated the pull request incrementally with four additional commits since the last revision: > > - Add `@bug` tags > - Improve wording of `@param len` > - Make source array bound checks lenient too > - Cap destination array bounds Will re-review when the changes settle. ------------- Changes requested by rriggs (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/25998#pullrequestreview-3051829566 From kvn at openjdk.org Thu Jul 24 15:06:57 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Thu, 24 Jul 2025 15:06:57 GMT Subject: RFR: 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs [v3] In-Reply-To: References: Message-ID: <4ME73Xqjc4FYKFsOxK0n1JViBulhj9-_ukphppVCHyw=.764525b8-c965-4522-a0c5-c70422f060b0@github.com> On Thu, 24 Jul 2025 07:42:03 GMT, Andrew Dinn wrote: >> Vladimir Kozlov has updated the pull request incrementally with one additional commit since the last revision: >> >> Rework the fix > > src/hotspot/cpu/zero/stubDeclarations_zero.hpp line 40: > >> 38: do_arch_entry, \ >> 39: do_arch_entry_init) \ >> 40: do_arch_blob(initial, 32) \ > > Do we need this any more? Yes, to call `generate_initial_stubs()` where `_call_stub_entry` is set. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26434#discussion_r2228794225 From kvn at openjdk.org Thu Jul 24 15:21:52 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Thu, 24 Jul 2025 15:21:52 GMT Subject: RFR: 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs [v4] In-Reply-To: References: Message-ID: > `StubRoutines::_crc_table_adr` and `_crc32c_table_addr` are used by initial stubs. In Leyden these addresses should be recorded in `AOTCodeAddressTable` to be used by AOTed stubs. But recording in `AOTCodeAddressTable` is done in `AOTCodeCache::init2()` which is called before initial stubs are generated and `_crc*_table_addr` are set. > > We need to move `_crc_table_addr` and `_crc32c_table_addr` initialization to `preuniverse` blob to be available in `AOTCodeCache::init2()`. > > I also renamed `_crc_table_adr` to `_crc_table_addr` to match other names. > > During testing I found that `-Xlog:stubs` affects empty blobs generation. There was typo there: `return nullptr;` was in wrong place. > > I have to specify sizes of `preuniverse` blobs so they are called after I fixed typo. `32` bytes is cache line size on most CPUs. Note, there will be no assembler code generation for this case: `_crc*_table_addr` are initialized by address of C tables. > > I did not move `_crc*_table_addr` declaration in `stubDeclarations.hpp` from `init` to `preuniverse` blob. I tried but there is issue: they require to specify stub name and I can move `updateBytesCRC32` stub declaration. I tries add fake stub but it did not work. I would prefer if I could use `nullptr` instead of stub in such case. But it will complicate other code. I think it is fine `do_entry()` macro only creates field and accessor function. > > Tested: tier1-4,tier10-rt,xcomp,stress Vladimir Kozlov has updated the pull request incrementally with one additional commit since the last revision: Add comment ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26434/files - new: https://git.openjdk.org/jdk/pull/26434/files/f0378d20..71d29f9f Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26434&range=03 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26434&range=02-03 Stats: 3 lines in 1 file changed: 3 ins; 0 del; 0 mod Patch: https://git.openjdk.org/jdk/pull/26434.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26434/head:pull/26434 PR: https://git.openjdk.org/jdk/pull/26434 From kvn at openjdk.org Thu Jul 24 15:21:55 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Thu, 24 Jul 2025 15:21:55 GMT Subject: RFR: 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs [v2] In-Reply-To: References: Message-ID: On Thu, 24 Jul 2025 13:23:26 GMT, Yudi Zheng wrote: >> Vladimir Kozlov has updated the pull request incrementally with one additional commit since the last revision: >> >> Fixed Zero VM > > src/hotspot/share/jvmci/vmStructs_jvmci.cpp line 420: > >> 418: static_field(StubRoutines, _dilithiumDecomposePoly, address) \ >> 419: static_field(StubRoutines, _updateBytesCRC32, address) \ >> 420: static_field(StubRoutines, _crc_table_addr, address) \ > > Could you please export via `CompilerToVM::Data`? > > diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp > index 41531b083fc..71331b578a5 100644 > --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp > +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp > @@ -131,6 +131,8 @@ class CompilerToVM { > static address dlog10; > static address dpow; > > + static address crc_table_addr; > + > static address symbol_init; > static address symbol_clinit; > > diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp > index b6d919fdfe9..8a1a02d62b3 100644 > --- a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp > +++ b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp > @@ -151,6 +151,8 @@ address CompilerToVM::Data::dlog; > address CompilerToVM::Data::dlog10; > address CompilerToVM::Data::dpow; > > +address CompilerToVM::Data::crc_table_addr; > + > address CompilerToVM::Data::symbol_init; > address CompilerToVM::Data::symbol_clinit; > > @@ -289,6 +291,7 @@ void CompilerToVM::Data::initialize(JVMCI_TRAPS) { > > SET_TRIGFUNC_OR_NULL(dtanh); > SET_TRIGFUNC_OR_NULL(dcbrt); > + SET_TRIGFUNC_OR_NULL(crc_table_addr); > > #undef SET_TRIGFUNC_OR_NULL > > diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp > index 1408cb09b0a..88d098468e9 100644 > --- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp > +++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp > @@ -147,6 +147,7 @@ > static_field(CompilerToVM::Data, dlog, address) \ > static_field(CompilerToVM::Data, dlog10, address) \ > static_field(CompilerToVM::Data, dpow, address) \ > + static_field(CompilerToVM::Data, crc_table_addr, address) ... @mur47x111 sure. But do you need also `crc32c_table_addr`? And I don't see initialization. Can you prepare full patch for JVMCI which I can integrate? ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26434#discussion_r2228817259 From kvn at openjdk.org Thu Jul 24 15:21:55 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Thu, 24 Jul 2025 15:21:55 GMT Subject: RFR: 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs [v2] In-Reply-To: References: Message-ID: <13d4kwnP300UqJmQOGcEBZ41O58rfPVvzHao-jMvt78=.1ebb29cf-4bf5-4ac4-aea4-6e35a22bf7b3@github.com> On Thu, 24 Jul 2025 15:13:04 GMT, Vladimir Kozlov wrote: >> src/hotspot/share/jvmci/vmStructs_jvmci.cpp line 420: >> >>> 418: static_field(StubRoutines, _dilithiumDecomposePoly, address) \ >>> 419: static_field(StubRoutines, _updateBytesCRC32, address) \ >>> 420: static_field(StubRoutines, _crc_table_addr, address) \ >> >> Could you please export via `CompilerToVM::Data`? >> >> diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp >> index 41531b083fc..71331b578a5 100644 >> --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp >> +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp >> @@ -131,6 +131,8 @@ class CompilerToVM { >> static address dlog10; >> static address dpow; >> >> + static address crc_table_addr; >> + >> static address symbol_init; >> static address symbol_clinit; >> >> diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp >> index b6d919fdfe9..8a1a02d62b3 100644 >> --- a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp >> +++ b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp >> @@ -151,6 +151,8 @@ address CompilerToVM::Data::dlog; >> address CompilerToVM::Data::dlog10; >> address CompilerToVM::Data::dpow; >> >> +address CompilerToVM::Data::crc_table_addr; >> + >> address CompilerToVM::Data::symbol_init; >> address CompilerToVM::Data::symbol_clinit; >> >> @@ -289,6 +291,7 @@ void CompilerToVM::Data::initialize(JVMCI_TRAPS) { >> >> SET_TRIGFUNC_OR_NULL(dtanh); >> SET_TRIGFUNC_OR_NULL(dcbrt); >> + SET_TRIGFUNC_OR_NULL(crc_table_addr); >> >> #undef SET_TRIGFUNC_OR_NULL >> >> diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp >> index 1408cb09b0a..88d098468e9 100644 >> --- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp >> +++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp >> @@ -147,6 +147,7 @@ >> static_field(CompilerToVM::Data, dlog, address) \ >> static_field(CompilerToVM::Data, dlog10, address) \ >> static_field(CompilerToVM::Data, dpow, address) \ >> + sta... > > @mur47x111 sure. But do you need also `crc32c_table_addr`? And I don't see initialization. Can you prepare full patch for JVMCI which I can integrate? Initialization is done by `SET_TRIGFUNC_OR_NULL()`. I see. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26434#discussion_r2228825985 From kvn at openjdk.org Thu Jul 24 15:21:56 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Thu, 24 Jul 2025 15:21:56 GMT Subject: RFR: 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs [v2] In-Reply-To: <13d4kwnP300UqJmQOGcEBZ41O58rfPVvzHao-jMvt78=.1ebb29cf-4bf5-4ac4-aea4-6e35a22bf7b3@github.com> References: <13d4kwnP300UqJmQOGcEBZ41O58rfPVvzHao-jMvt78=.1ebb29cf-4bf5-4ac4-aea4-6e35a22bf7b3@github.com> Message-ID: On Thu, 24 Jul 2025 15:16:10 GMT, Vladimir Kozlov wrote: >> @mur47x111 sure. But do you need also `crc32c_table_addr`? And I don't see initialization. Can you prepare full patch for JVMCI which I can integrate? > > Initialization is done by `SET_TRIGFUNC_OR_NULL()`. I see. Okay, I will add crc32c_table_addr myself then. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26434#discussion_r2228830008 From kvn at openjdk.org Thu Jul 24 15:21:58 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Thu, 24 Jul 2025 15:21:58 GMT Subject: RFR: 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs [v3] In-Reply-To: References: Message-ID: <6L0u6QsWNsH9G_vmwaJheoORE5EUcePeeu-BTqHaer0=.b09dfaa1-fe24-4e5f-9cff-a022d0f5f622@github.com> On Thu, 24 Jul 2025 07:48:40 GMT, Andrew Dinn wrote: >> Vladimir Kozlov has updated the pull request incrementally with one additional commit since the last revision: >> >> Rework the fix > > src/hotspot/share/runtime/stubRoutines.hpp line 306: > >> 304: return dest_uninitialized ? _arrayof_oop_disjoint_arraycopy_uninit : _arrayof_oop_disjoint_arraycopy; >> 305: } >> 306: > > Could we have a comment here to note that 1) this method is implemented in architecture-specific code 2) any table that is returned must be allocated once-only in foreign memory rather generated in the code cache. Done! ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26434#discussion_r2228819851 From kvn at openjdk.org Thu Jul 24 15:36:00 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Thu, 24 Jul 2025 15:36:00 GMT Subject: RFR: 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs [v2] In-Reply-To: References: <13d4kwnP300UqJmQOGcEBZ41O58rfPVvzHao-jMvt78=.1ebb29cf-4bf5-4ac4-aea4-6e35a22bf7b3@github.com> Message-ID: On Thu, 24 Jul 2025 15:17:48 GMT, Vladimir Kozlov wrote: >> Initialization is done by `SET_TRIGFUNC_OR_NULL()`. I see. > > Okay, I will add crc32c_table_addr myself then. I see that crc32c_table_addr() failed on Aarch64 because we should not call it. I will go with your patch @mur47x111 then and let you solve crc32c. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26434#discussion_r2228864420 From kvn at openjdk.org Thu Jul 24 15:45:26 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Thu, 24 Jul 2025 15:45:26 GMT Subject: RFR: 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs [v5] In-Reply-To: References: Message-ID: > `StubRoutines::_crc_table_adr` and `_crc32c_table_addr` are used by initial stubs. In Leyden these addresses should be recorded in `AOTCodeAddressTable` to be used by AOTed stubs. But recording in `AOTCodeAddressTable` is done in `AOTCodeCache::init2()` which is called before initial stubs are generated and `_crc*_table_addr` are set. > > We need to move `_crc_table_addr` and `_crc32c_table_addr` initialization to `preuniverse` blob to be available in `AOTCodeCache::init2()`. > > I also renamed `_crc_table_adr` to `_crc_table_addr` to match other names. > > During testing I found that `-Xlog:stubs` affects empty blobs generation. There was typo there: `return nullptr;` was in wrong place. > > I have to specify sizes of `preuniverse` blobs so they are called after I fixed typo. `32` bytes is cache line size on most CPUs. Note, there will be no assembler code generation for this case: `_crc*_table_addr` are initialized by address of C tables. > > I did not move `_crc*_table_addr` declaration in `stubDeclarations.hpp` from `init` to `preuniverse` blob. I tried but there is issue: they require to specify stub name and I can move `updateBytesCRC32` stub declaration. I tries add fake stub but it did not work. I would prefer if I could use `nullptr` instead of stub in such case. But it will complicate other code. I think it is fine `do_entry()` macro only creates field and accessor function. > > Tested: tier1-4,tier10-rt,xcomp,stress Vladimir Kozlov has updated the pull request incrementally with one additional commit since the last revision: JVMCI fix ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26434/files - new: https://git.openjdk.org/jdk/pull/26434/files/71d29f9f..eaba165a Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26434&range=04 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26434&range=03-04 Stats: 6 lines in 3 files changed: 6 ins; 0 del; 0 mod Patch: https://git.openjdk.org/jdk/pull/26434.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26434/head:pull/26434 PR: https://git.openjdk.org/jdk/pull/26434 From adinn at openjdk.org Thu Jul 24 15:45:26 2025 From: adinn at openjdk.org (Andrew Dinn) Date: Thu, 24 Jul 2025 15:45:26 GMT Subject: RFR: 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs [v5] In-Reply-To: References: Message-ID: On Thu, 24 Jul 2025 15:42:34 GMT, Vladimir Kozlov wrote: >> `StubRoutines::_crc_table_adr` and `_crc32c_table_addr` are used by initial stubs. In Leyden these addresses should be recorded in `AOTCodeAddressTable` to be used by AOTed stubs. But recording in `AOTCodeAddressTable` is done in `AOTCodeCache::init2()` which is called before initial stubs are generated and `_crc*_table_addr` are set. >> >> We need to move `_crc_table_addr` and `_crc32c_table_addr` initialization to `preuniverse` blob to be available in `AOTCodeCache::init2()`. >> >> I also renamed `_crc_table_adr` to `_crc_table_addr` to match other names. >> >> During testing I found that `-Xlog:stubs` affects empty blobs generation. There was typo there: `return nullptr;` was in wrong place. >> >> I have to specify sizes of `preuniverse` blobs so they are called after I fixed typo. `32` bytes is cache line size on most CPUs. Note, there will be no assembler code generation for this case: `_crc*_table_addr` are initialized by address of C tables. >> >> I did not move `_crc*_table_addr` declaration in `stubDeclarations.hpp` from `init` to `preuniverse` blob. I tried but there is issue: they require to specify stub name and I can move `updateBytesCRC32` stub declaration. I tries add fake stub but it did not work. I would prefer if I could use `nullptr` instead of stub in such case. But it will complicate other code. I think it is fine `do_entry()` macro only creates field and accessor function. >> >> Tested: tier1-4,tier10-rt,xcomp,stress > > Vladimir Kozlov has updated the pull request incrementally with one additional commit since the last revision: > > JVMCI fix Looks ok to me. ------------- Marked as reviewed by adinn (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/26434#pullrequestreview-3052221039 From kvn at openjdk.org Thu Jul 24 15:45:26 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Thu, 24 Jul 2025 15:45:26 GMT Subject: RFR: 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs In-Reply-To: References: Message-ID: On Thu, 24 Jul 2025 07:16:25 GMT, Fei Yang wrote: > Thanks for the ping. I performed tier1 test and I see the result is clean with the latest version on linux-riscv64. @RealFYang thank you for testing. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26434#issuecomment-3113964641 From adinn at openjdk.org Thu Jul 24 15:45:26 2025 From: adinn at openjdk.org (Andrew Dinn) Date: Thu, 24 Jul 2025 15:45:26 GMT Subject: RFR: 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs [v3] In-Reply-To: <4ME73Xqjc4FYKFsOxK0n1JViBulhj9-_ukphppVCHyw=.764525b8-c965-4522-a0c5-c70422f060b0@github.com> References: <4ME73Xqjc4FYKFsOxK0n1JViBulhj9-_ukphppVCHyw=.764525b8-c965-4522-a0c5-c70422f060b0@github.com> Message-ID: <5SqARIslbcf1EcbYwT4xJA9pOdLk-mDJ5pB1b-7yDeY=.bc52ba77-0a64-426b-b260-a368ba559c0e@github.com> On Thu, 24 Jul 2025 15:04:30 GMT, Vladimir Kozlov wrote: >> src/hotspot/cpu/zero/stubDeclarations_zero.hpp line 40: >> >>> 38: do_arch_entry, \ >>> 39: do_arch_entry_init) \ >>> 40: do_arch_blob(initial, 32) \ >> >> Do we need this any more? > > Yes, to call `generate_initial_stubs()` where `_call_stub_entry` is set. Ah, yes, how annoying. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26434#discussion_r2228882777 From kvn at openjdk.org Thu Jul 24 15:45:27 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Thu, 24 Jul 2025 15:45:27 GMT Subject: RFR: 8363837: Move StubRoutines::_crc_table_adr initialization to preuniverse stubs [v2] In-Reply-To: References: <13d4kwnP300UqJmQOGcEBZ41O58rfPVvzHao-jMvt78=.1ebb29cf-4bf5-4ac4-aea4-6e35a22bf7b3@github.com> Message-ID: <0fCXiQSsivc_DMmlKdYXASHyudDNlBW_Wfko9gRxzwI=.1ca9c4fa-d38d-4e38-a1d9-c5a4610a7df9@github.com> On Thu, 24 Jul 2025 15:31:38 GMT, Vladimir Kozlov wrote: >> Okay, I will add crc32c_table_addr myself then. > > I see that crc32c_table_addr() failed on Aarch64 because we should not call it. > I will go with your patch @mur47x111 then and let you solve crc32c. Done ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26434#discussion_r2228881208 From kvn at openjdk.org Thu Jul 24 15:52:03 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Thu, 24 Jul 2025 15:52:03 GMT Subject: RFR: 8363837: Make StubRoutines::crc_table_adr() into platform-specific method [v5] In-Reply-To: References: Message-ID: On Thu, 24 Jul 2025 15:45:26 GMT, Vladimir Kozlov wrote: >> `StubRoutines::_crc_table_adr` and `_crc32c_table_addr` are used by initial stubs. In Leyden these addresses should be recorded in `AOTCodeAddressTable` to be used by AOTed stubs. But recording in `AOTCodeAddressTable` is done in `AOTCodeCache::init2()` which is called before initial stubs are generated and `_crc*_table_addr` are set. >> >> We need to move `_crc_table_addr` and `_crc32c_table_addr` initialization to `preuniverse` blob to be available in `AOTCodeCache::init2()`. >> >> I also renamed `_crc_table_adr` to `_crc_table_addr` to match other names. >> >> During testing I found that `-Xlog:stubs` affects empty blobs generation. There was typo there: `return nullptr;` was in wrong place. >> >> I have to specify sizes of `preuniverse` blobs so they are called after I fixed typo. `32` bytes is cache line size on most CPUs. Note, there will be no assembler code generation for this case: `_crc*_table_addr` are initialized by address of C tables. >> >> I did not move `_crc*_table_addr` declaration in `stubDeclarations.hpp` from `init` to `preuniverse` blob. I tried but there is issue: they require to specify stub name and I can move `updateBytesCRC32` stub declaration. I tries add fake stub but it did not work. I would prefer if I could use `nullptr` instead of stub in such case. But it will complicate other code. I think it is fine `do_entry()` macro only creates field and accessor function. >> >> Tested: tier1-4,tier10-rt,xcomp,stress > > Vladimir Kozlov has updated the pull request incrementally with one additional commit since the last revision: > > JVMCI fix I updated title to reflect current implementation. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26434#issuecomment-3113984526 From kvn at openjdk.org Thu Jul 24 15:52:03 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Thu, 24 Jul 2025 15:52:03 GMT Subject: RFR: 8363837: Make StubRoutines::crc_table_adr() into platform-specific method In-Reply-To: References: Message-ID: On Wed, 23 Jul 2025 15:42:34 GMT, Andrew Dinn wrote: >> Thank you, @adinn for you suggestions. >> >>> do we use a different reloc for stubs addresses vs external addresses? >> >> 1. will not work. They could be different. Stubs use `runtime_call` relic and `crc` uses `external_word`. >> >> I considered 2. when I worked on this but there is assumption that we have all external addresses recorded when we look for matching address in `AOTCodeAddressTable::id_for_address()`. There is specific assert there. And we have relocation in all stubs and adapters. I am concern about some concurrency issues if we don't satisfy the assumption. >> >> An other solution would be to have separate `StubRoutines::get_crc_table_addr()` which can be use early by AOT code and later by `generate_initial_stubs()`. It will check local value (StubRoutines::x86::_crc32c_table on x86, for example) and calculate it if needed. >> >> What do you think? > >> Another solution would be to have separate StubRoutines::get_crc_table_addr() which can be use early by AOT code and later by generate_initial_stubs(). It will check local value (StubRoutines::x86::_crc32c_table on x86, for example) and calculate it if needed. > > Yes, I think it would be much better if we removed the entry declarations for `crc_table_adr` and `crc32c_table_addr` from stubDeclarations.hpp and instead always looked up the address using a getter method declared in the shared header and implemented in each arch. > > We don't need a generated field in class StubRoutines nor any way to track the value as we do for real generated addresses. So, using the declaration mechanism was the wrong way to do this. Thank you @adinn ------------- PR Comment: https://git.openjdk.org/jdk/pull/26434#issuecomment-3113986140 From yzheng at openjdk.org Thu Jul 24 19:39:58 2025 From: yzheng at openjdk.org (Yudi Zheng) Date: Thu, 24 Jul 2025 19:39:58 GMT Subject: RFR: 8363837: Make StubRoutines::crc_table_adr() into platform-specific method [v2] In-Reply-To: <0fCXiQSsivc_DMmlKdYXASHyudDNlBW_Wfko9gRxzwI=.1ca9c4fa-d38d-4e38-a1d9-c5a4610a7df9@github.com> References: <13d4kwnP300UqJmQOGcEBZ41O58rfPVvzHao-jMvt78=.1ebb29cf-4bf5-4ac4-aea4-6e35a22bf7b3@github.com> <0fCXiQSsivc_DMmlKdYXASHyudDNlBW_Wfko9gRxzwI=.1ca9c4fa-d38d-4e38-a1d9-c5a4610a7df9@github.com> Message-ID: On Thu, 24 Jul 2025 15:38:19 GMT, Vladimir Kozlov wrote: >> I see that crc32c_table_addr() failed on Aarch64 because we should not call it. >> I will go with your patch @mur47x111 then and let you solve crc32c. > > Done Thanks! I also ran across the `ShouldNotCallThis` on aarch64 and decided to drop that because anyway we don't use `crc32c_table_addr`. I think `crc32c_table_addr` is only used internally in HotSpot but not via intrinsification call. Let's only export `crc_table_addr` for now. I will examine the `crc32c_table_addr` later ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26434#discussion_r2229418122 From kvn at openjdk.org Thu Jul 24 19:57:59 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Thu, 24 Jul 2025 19:57:59 GMT Subject: RFR: 8363837: Make StubRoutines::crc_table_adr() into platform-specific method [v2] In-Reply-To: References: <13d4kwnP300UqJmQOGcEBZ41O58rfPVvzHao-jMvt78=.1ebb29cf-4bf5-4ac4-aea4-6e35a22bf7b3@github.com> <0fCXiQSsivc_DMmlKdYXASHyudDNlBW_Wfko9gRxzwI=.1ca9c4fa-d38d-4e38-a1d9-c5a4610a7df9@github.com> Message-ID: On Thu, 24 Jul 2025 19:37:12 GMT, Yudi Zheng wrote: >> Done > > Thanks! I also ran across the `ShouldNotCallThis` on aarch64 and decided to drop that because anyway we don't use `crc32c_table_addr`. I think `crc32c_table_addr` is only used internally in HotSpot but not via intrinsification call. Let's only export `crc_table_addr` for now. I will examine the `crc32c_table_addr` later Thank you, @mur47x111 ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26434#discussion_r2229451275 From vyazici at openjdk.org Fri Jul 25 07:40:46 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Fri, 25 Jul 2025 07:40:46 GMT Subject: RFR: 8361842: Move input validation checks to Java for java.lang.StringCoding intrinsics [v13] In-Reply-To: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: > Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. > > ## Implementation notes > > The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, > > 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) > 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too > 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method > 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag > > Following preliminary work needs to be carried out as well: > > 1. Add a new `VerifyIntrinsicChecks` VM flag > 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. > > 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. > > ## Functional and performance tests > > - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. > > - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. > > ## Verification of the VM crash > > I've tested the VM crash scenario as follows: > > 1. Created the following test program: > > public class StrIntri { > public static void main(String[] args) { > Exception lastException = null; > for (int i = 0; i < 1_000_000; i++) { > try { > jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); > } catch (Exception exception) { > lastException = exception; > } > } > if (lastException != null) { > lastException.printStackTrace(); > } else { > System.out.println("completed"); > } > } > } > ... Volkan Yazici has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains 31 additional commits since the last revision: - Merge remote-tracking branch 'upstream/master' into strIntrinCheck - Replace `requireNonNull` with implicit null checks to reduce bytecode size - Add `@bug` tags - Improve wording of `@param len` - Make source array bound checks lenient too - Cap destination array bounds - Fix bit shifting - Remove superseded `@throws` Javadoc - Merge remote-tracking branch 'upstream/master' into strIntrinCheck - Make `StringCoding` encoding intrinsics lenient - ... and 21 more: https://git.openjdk.org/jdk/compare/9331736c...c322f0e0 ------------- Changes: - all: https://git.openjdk.org/jdk/pull/25998/files - new: https://git.openjdk.org/jdk/pull/25998/files/1d02189f..c322f0e0 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=25998&range=12 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=25998&range=11-12 Stats: 11682 lines in 267 files changed: 4951 ins; 5263 del; 1468 mod Patch: https://git.openjdk.org/jdk/pull/25998.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/25998/head:pull/25998 PR: https://git.openjdk.org/jdk/pull/25998 From jbhateja at openjdk.org Fri Jul 25 13:50:55 2025 From: jbhateja at openjdk.org (Jatin Bhateja) Date: Fri, 25 Jul 2025 13:50:55 GMT Subject: RFR: 8303762: Optimize vector slice operation with constant index using VPALIGNR instruction Message-ID: Patch optimizes Vector. slice operation with constant index using x86 ALIGNR instruction. It also adds a new hybrid call generator to facilitate lazy intrinsification or else perform procedural inlining to prevent call overhead and boxing penalties in case the fallback implementation expects to operate over vectors. The existing vector API-based slice implementation is now the fallback code that gets inlined in case intrinsification fails. Idea here is to add infrastructure support to enable intrinsification of fast path for selected vector APIs, else enable inlining of fall-back implementation if it's based on vector APIs. Existing call generators like PredictedCallGenerator, used to handle bi-morphic inlining, already make use of multiple call generators to handle hit/miss scenarios for a particular receiver type. The newly added hybrid call generator is lazy and called during incremental inlining optimization. It also relieves the inline expander to handle slow paths, which can easily be implemented library side (Java). Vector API jtreg tests pass at AVX level 2, remaining validation in progress. Performance numbers: System : 13th Gen Intel(R) Core(TM) i3-1315U Baseline: Benchmark (size) Mode Cnt Score Error Units VectorSliceBenchmark.byteVectorSliceWithConstantIndex1 1024 thrpt 2 9444.444 ops/ms VectorSliceBenchmark.byteVectorSliceWithConstantIndex2 1024 thrpt 2 10009.319 ops/ms VectorSliceBenchmark.byteVectorSliceWithVariableIndex 1024 thrpt 2 9081.926 ops/ms VectorSliceBenchmark.intVectorSliceWithConstantIndex1 1024 thrpt 2 6085.825 ops/ms VectorSliceBenchmark.intVectorSliceWithConstantIndex2 1024 thrpt 2 6505.378 ops/ms VectorSliceBenchmark.intVectorSliceWithVariableIndex 1024 thrpt 2 6204.489 ops/ms VectorSliceBenchmark.longVectorSliceWithConstantIndex1 1024 thrpt 2 1651.334 ops/ms VectorSliceBenchmark.longVectorSliceWithConstantIndex2 1024 thrpt 2 1642.784 ops/ms VectorSliceBenchmark.longVectorSliceWithVariableIndex 1024 thrpt 2 1474.808 ops/ms VectorSliceBenchmark.shortVectorSliceWithConstantIndex1 1024 thrpt 2 10399.394 ops/ms VectorSliceBenchmark.shortVectorSliceWithConstantIndex2 1024 thrpt 2 10502.894 ops/ms VectorSliceBenchmark.shortVectorSliceWithVariableIndex 1024 thrpt 2 9756.573 ops/ms With opt: Benchmark (size) Mode Cnt Score Error Units VectorSliceBenchmark.byteVectorSliceWithConstantIndex1 1024 thrpt 2 34122.435 ops/ms VectorSliceBenchmark.byteVectorSliceWithConstantIndex2 1024 thrpt 2 33281.868 ops/ms VectorSliceBenchmark.byteVectorSliceWithVariableIndex 1024 thrpt 2 9345.154 ops/ms VectorSliceBenchmark.intVectorSliceWithConstantIndex1 1024 thrpt 2 8283.247 ops/ms VectorSliceBenchmark.intVectorSliceWithConstantIndex2 1024 thrpt 2 8510.695 ops/ms VectorSliceBenchmark.intVectorSliceWithVariableIndex 1024 thrpt 2 5626.367 ops/ms VectorSliceBenchmark.longVectorSliceWithConstantIndex1 1024 thrpt 2 960.958 ops/ms VectorSliceBenchmark.longVectorSliceWithConstantIndex2 1024 thrpt 2 4155.801 ops/ms VectorSliceBenchmark.longVectorSliceWithVariableIndex 1024 thrpt 2 1465.953 ops/ms VectorSliceBenchmark.shortVectorSliceWithConstantIndex1 1024 thrpt 2 32748.061 ops/ms VectorSliceBenchmark.shortVectorSliceWithConstantIndex2 1024 thrpt 2 33674.408 ops/ms VectorSliceBenchmark.shortVectorSliceWithVariableIndex 1024 thrpt 2 9346.148 ops/ms Please share your feedback. Best Regards, Jatin ------------- Commit messages: - Fixes for failing regressions - Optimizing AVX2 backend and some re-factoring - new benchmark - Merge branch 'master' of https://github.com/openjdk/jdk into JDK-8303762 - 8303762: Optimize vector slice operation with constant index using VPALIGNR instruction Changes: https://git.openjdk.org/jdk/pull/24104/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=24104&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8303762 Stats: 747 lines in 32 files changed: 664 ins; 0 del; 83 mod Patch: https://git.openjdk.org/jdk/pull/24104.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/24104/head:pull/24104 PR: https://git.openjdk.org/jdk/pull/24104 From jbhateja at openjdk.org Fri Jul 25 13:50:56 2025 From: jbhateja at openjdk.org (Jatin Bhateja) Date: Fri, 25 Jul 2025 13:50:56 GMT Subject: RFR: 8303762: Optimize vector slice operation with constant index using VPALIGNR instruction In-Reply-To: References: Message-ID: On Tue, 18 Mar 2025 20:51:46 GMT, Jatin Bhateja wrote: > Patch optimizes Vector. slice operation with constant index using x86 ALIGNR instruction. > It also adds a new hybrid call generator to facilitate lazy intrinsification or else perform procedural inlining to prevent call overhead and boxing penalties in case the fallback implementation expects to operate over vectors. The existing vector API-based slice implementation is now the fallback code that gets inlined in case intrinsification fails. > > Idea here is to add infrastructure support to enable intrinsification of fast path for selected vector APIs, else enable inlining of fall-back implementation if it's based on vector APIs. Existing call generators like PredictedCallGenerator, used to handle bi-morphic inlining, already make use of multiple call generators to handle hit/miss scenarios for a particular receiver type. The newly added hybrid call generator is lazy and called during incremental inlining optimization. It also relieves the inline expander to handle slow paths, which can easily be implemented library side (Java). > > Vector API jtreg tests pass at AVX level 2, remaining validation in progress. > > Performance numbers: > > > System : 13th Gen Intel(R) Core(TM) i3-1315U > > Baseline: > Benchmark (size) Mode Cnt Score Error Units > VectorSliceBenchmark.byteVectorSliceWithConstantIndex1 1024 thrpt 2 9444.444 ops/ms > VectorSliceBenchmark.byteVectorSliceWithConstantIndex2 1024 thrpt 2 10009.319 ops/ms > VectorSliceBenchmark.byteVectorSliceWithVariableIndex 1024 thrpt 2 9081.926 ops/ms > VectorSliceBenchmark.intVectorSliceWithConstantIndex1 1024 thrpt 2 6085.825 ops/ms > VectorSliceBenchmark.intVectorSliceWithConstantIndex2 1024 thrpt 2 6505.378 ops/ms > VectorSliceBenchmark.intVectorSliceWithVariableIndex 1024 thrpt 2 6204.489 ops/ms > VectorSliceBenchmark.longVectorSliceWithConstantIndex1 1024 thrpt 2 1651.334 ops/ms > VectorSliceBenchmark.longVectorSliceWithConstantIndex2 1024 thrpt 2 1642.784 ops/ms > VectorSliceBenchmark.longVectorSliceWithVariableIndex 1024 thrpt 2 1474.808 ops/ms > VectorSliceBenchmark.shortVectorSliceWithConstantIndex1 1024 thrpt 2 10399.394 ops/ms > VectorSliceBenchmark.shortVectorSliceWithConstantIndex2 1024 thrpt 2 10502.894 ops/ms > VectorSliceBenchmark.shortVectorSliceWithVariableIndex 1024 ... Performance after AVX2 backend modifications Benchmark (size) Mode Cnt Score Error Units VectorSliceBenchmark.byteVectorSliceWithConstantIndex1 1024 thrpt 2 51644.530 ops/ms VectorSliceBenchmark.byteVectorSliceWithConstantIndex2 1024 thrpt 2 48171.079 ops/ms VectorSliceBenchmark.byteVectorSliceWithVariableIndex 1024 thrpt 2 9662.306 ops/ms VectorSliceBenchmark.intVectorSliceWithConstantIndex1 1024 thrpt 2 14358.347 ops/ms VectorSliceBenchmark.intVectorSliceWithConstantIndex2 1024 thrpt 2 14619.920 ops/ms VectorSliceBenchmark.intVectorSliceWithVariableIndex 1024 thrpt 2 6675.824 ops/ms VectorSliceBenchmark.longVectorSliceWithConstantIndex1 1024 thrpt 2 818.911 ops/ms VectorSliceBenchmark.longVectorSliceWithConstantIndex2 1024 thrpt 2 4778.321 ops/ms VectorSliceBenchmark.longVectorSliceWithVariableIndex 1024 thrpt 2 1612.264 ops/ms VectorSliceBenchmark.shortVectorSliceWithConstantIndex1 1024 thrpt 2 35961.146 ops/ms VectorSliceBenchmark.shortVectorSliceWithConstantIndex2 1024 thrpt 2 39072.170 ops/ms VectorSliceBenchmark.shortVectorSliceWithVariableIndex 1024 thrpt 2 11209.685 ops/ms ------------- PR Comment: https://git.openjdk.org/jdk/pull/24104#issuecomment-3116214722 From yzheng at openjdk.org Fri Jul 25 16:15:00 2025 From: yzheng at openjdk.org (Yudi Zheng) Date: Fri, 25 Jul 2025 16:15:00 GMT Subject: RFR: 8363837: Make StubRoutines::crc_table_adr() into platform-specific method [v5] In-Reply-To: References: Message-ID: On Thu, 24 Jul 2025 15:45:26 GMT, Vladimir Kozlov wrote: >> `StubRoutines::_crc_table_adr` and `_crc32c_table_addr` are used by initial stubs. In Leyden these addresses should be recorded in `AOTCodeAddressTable` to be used by AOTed stubs. But recording in `AOTCodeAddressTable` is done in `AOTCodeCache::init2()` which is called before initial stubs are generated and `_crc*_table_addr` are set. >> >> We need to move `_crc_table_addr` and `_crc32c_table_addr` initialization to `preuniverse` blob to be available in `AOTCodeCache::init2()`. >> >> I also renamed `_crc_table_adr` to `_crc_table_addr` to match other names. >> >> During testing I found that `-Xlog:stubs` affects empty blobs generation. There was typo there: `return nullptr;` was in wrong place. >> >> I have to specify sizes of `preuniverse` blobs so they are called after I fixed typo. `32` bytes is cache line size on most CPUs. Note, there will be no assembler code generation for this case: `_crc*_table_addr` are initialized by address of C tables. >> >> I did not move `_crc*_table_addr` declaration in `stubDeclarations.hpp` from `init` to `preuniverse` blob. I tried but there is issue: they require to specify stub name and I can move `updateBytesCRC32` stub declaration. I tries add fake stub but it did not work. I would prefer if I could use `nullptr` instead of stub in such case. But it will complicate other code. I think it is fine `do_entry()` macro only creates field and accessor function. >> >> Tested: tier1-4,tier10-rt,xcomp,stress > > Vladimir Kozlov has updated the pull request incrementally with one additional commit since the last revision: > > JVMCI fix LGTM ------------- Marked as reviewed by yzheng (Committer). PR Review: https://git.openjdk.org/jdk/pull/26434#pullrequestreview-3056079592 From kvn at openjdk.org Fri Jul 25 16:50:03 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Fri, 25 Jul 2025 16:50:03 GMT Subject: RFR: 8363837: Make StubRoutines::crc_table_adr() into platform-specific method [v5] In-Reply-To: References: Message-ID: On Thu, 24 Jul 2025 15:45:26 GMT, Vladimir Kozlov wrote: >> `StubRoutines::_crc_table_adr` and `_crc32c_table_addr` are used by initial stubs. In Leyden these addresses should be recorded in `AOTCodeAddressTable` to be used by AOTed stubs. But recording in `AOTCodeAddressTable` is done in `AOTCodeCache::init2()` which is called before initial stubs are generated and `_crc*_table_addr` are set. >> >> We need to move `_crc_table_addr` and `_crc32c_table_addr` initialization to `preuniverse` blob to be available in `AOTCodeCache::init2()`. >> >> I also renamed `_crc_table_adr` to `_crc_table_addr` to match other names. >> >> During testing I found that `-Xlog:stubs` affects empty blobs generation. There was typo there: `return nullptr;` was in wrong place. >> >> I have to specify sizes of `preuniverse` blobs so they are called after I fixed typo. `32` bytes is cache line size on most CPUs. Note, there will be no assembler code generation for this case: `_crc*_table_addr` are initialized by address of C tables. >> >> I did not move `_crc*_table_addr` declaration in `stubDeclarations.hpp` from `init` to `preuniverse` blob. I tried but there is issue: they require to specify stub name and I can move `updateBytesCRC32` stub declaration. I tries add fake stub but it did not work. I would prefer if I could use `nullptr` instead of stub in such case. But it will complicate other code. I think it is fine `do_entry()` macro only creates field and accessor function. >> >> Tested: tier1-4,tier10-rt,xcomp,stress > > Vladimir Kozlov has updated the pull request incrementally with one additional commit since the last revision: > > JVMCI fix Thank you all for reviews. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26434#issuecomment-3119381710 From kvn at openjdk.org Fri Jul 25 16:50:04 2025 From: kvn at openjdk.org (Vladimir Kozlov) Date: Fri, 25 Jul 2025 16:50:04 GMT Subject: Integrated: 8363837: Make StubRoutines::crc_table_adr() into platform-specific method In-Reply-To: References: Message-ID: On Tue, 22 Jul 2025 21:56:13 GMT, Vladimir Kozlov wrote: > `StubRoutines::_crc_table_adr` and `_crc32c_table_addr` are used by initial stubs. In Leyden these addresses should be recorded in `AOTCodeAddressTable` to be used by AOTed stubs. But recording in `AOTCodeAddressTable` is done in `AOTCodeCache::init2()` which is called before initial stubs are generated and `_crc*_table_addr` are set. > > We need to move `_crc_table_addr` and `_crc32c_table_addr` initialization to `preuniverse` blob to be available in `AOTCodeCache::init2()`. > > I also renamed `_crc_table_adr` to `_crc_table_addr` to match other names. > > During testing I found that `-Xlog:stubs` affects empty blobs generation. There was typo there: `return nullptr;` was in wrong place. > > I have to specify sizes of `preuniverse` blobs so they are called after I fixed typo. `32` bytes is cache line size on most CPUs. Note, there will be no assembler code generation for this case: `_crc*_table_addr` are initialized by address of C tables. > > I did not move `_crc*_table_addr` declaration in `stubDeclarations.hpp` from `init` to `preuniverse` blob. I tried but there is issue: they require to specify stub name and I can move `updateBytesCRC32` stub declaration. I tries add fake stub but it did not work. I would prefer if I could use `nullptr` instead of stub in such case. But it will complicate other code. I think it is fine `do_entry()` macro only creates field and accessor function. > > Tested: tier1-4,tier10-rt,xcomp,stress This pull request has now been integrated. Changeset: 89fe586e Author: Vladimir Kozlov URL: https://git.openjdk.org/jdk/commit/89fe586edd5044923a2ce86f8cc5bf16004ac0b5 Stats: 85 lines in 24 files changed: 60 ins; 18 del; 7 mod 8363837: Make StubRoutines::crc_table_adr() into platform-specific method Reviewed-by: adinn, yzheng ------------- PR: https://git.openjdk.org/jdk/pull/26434 From jbhateja at openjdk.org Fri Jul 25 20:09:40 2025 From: jbhateja at openjdk.org (Jatin Bhateja) Date: Fri, 25 Jul 2025 20:09:40 GMT Subject: RFR: 8303762: Optimize vector slice operation with constant index using VPALIGNR instruction [v2] In-Reply-To: References: Message-ID: > Patch optimizes Vector. slice operation with constant index using x86 ALIGNR instruction. > It also adds a new hybrid call generator to facilitate lazy intrinsification or else perform procedural inlining to prevent call overhead and boxing penalties in case the fallback implementation expects to operate over vectors. The existing vector API-based slice implementation is now the fallback code that gets inlined in case intrinsification fails. > > Idea here is to add infrastructure support to enable intrinsification of fast path for selected vector APIs, else enable inlining of fall-back implementation if it's based on vector APIs. Existing call generators like PredictedCallGenerator, used to handle bi-morphic inlining, already make use of multiple call generators to handle hit/miss scenarios for a particular receiver type. The newly added hybrid call generator is lazy and called during incremental inlining optimization. It also relieves the inline expander to handle slow paths, which can easily be implemented library side (Java). > > Vector API jtreg tests pass at AVX level 2, remaining validation in progress. > > Performance numbers: > > > System : 13th Gen Intel(R) Core(TM) i3-1315U > > Baseline: > Benchmark (size) Mode Cnt Score Error Units > VectorSliceBenchmark.byteVectorSliceWithConstantIndex1 1024 thrpt 2 9444.444 ops/ms > VectorSliceBenchmark.byteVectorSliceWithConstantIndex2 1024 thrpt 2 10009.319 ops/ms > VectorSliceBenchmark.byteVectorSliceWithVariableIndex 1024 thrpt 2 9081.926 ops/ms > VectorSliceBenchmark.intVectorSliceWithConstantIndex1 1024 thrpt 2 6085.825 ops/ms > VectorSliceBenchmark.intVectorSliceWithConstantIndex2 1024 thrpt 2 6505.378 ops/ms > VectorSliceBenchmark.intVectorSliceWithVariableIndex 1024 thrpt 2 6204.489 ops/ms > VectorSliceBenchmark.longVectorSliceWithConstantIndex1 1024 thrpt 2 1651.334 ops/ms > VectorSliceBenchmark.longVectorSliceWithConstantIndex2 1024 thrpt 2 1642.784 ops/ms > VectorSliceBenchmark.longVectorSliceWithVariableIndex 1024 thrpt 2 1474.808 ops/ms > VectorSliceBenchmark.shortVectorSliceWithConstantIndex1 1024 thrpt 2 10399.394 ops/ms > VectorSliceBenchmark.shortVectorSliceWithConstantIndex2 1024 thrpt 2 10502.894 ops/ms > VectorSliceBenchmark.shortVectorSliceWithVariableIndex 1024 ... Jatin Bhateja has updated the pull request incrementally with one additional commit since the last revision: Updating predicate checks ------------- Changes: - all: https://git.openjdk.org/jdk/pull/24104/files - new: https://git.openjdk.org/jdk/pull/24104/files/b2e93434..04be59a6 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=24104&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=24104&range=00-01 Stats: 2 lines in 1 file changed: 0 ins; 0 del; 2 mod Patch: https://git.openjdk.org/jdk/pull/24104.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/24104/head:pull/24104 PR: https://git.openjdk.org/jdk/pull/24104 From jbhateja at openjdk.org Mon Jul 28 05:55:55 2025 From: jbhateja at openjdk.org (Jatin Bhateja) Date: Mon, 28 Jul 2025 05:55:55 GMT Subject: RFR: 8303762: Optimize vector slice operation with constant index using VPALIGNR instruction [v2] In-Reply-To: References: Message-ID: On Fri, 25 Jul 2025 20:09:40 GMT, Jatin Bhateja wrote: >> Patch optimizes Vector. slice operation with constant index using x86 ALIGNR instruction. >> It also adds a new hybrid call generator to facilitate lazy intrinsification or else perform procedural inlining to prevent call overhead and boxing penalties in case the fallback implementation expects to operate over vectors. The existing vector API-based slice implementation is now the fallback code that gets inlined in case intrinsification fails. >> >> Idea here is to add infrastructure support to enable intrinsification of fast path for selected vector APIs, else enable inlining of fall-back implementation if it's based on vector APIs. Existing call generators like PredictedCallGenerator, used to handle bi-morphic inlining, already make use of multiple call generators to handle hit/miss scenarios for a particular receiver type. The newly added hybrid call generator is lazy and called during incremental inlining optimization. It also relieves the inline expander to handle slow paths, which can easily be implemented library side (Java). >> >> Vector API jtreg tests pass at AVX level 2, remaining validation in progress. >> >> Performance numbers: >> >> >> System : 13th Gen Intel(R) Core(TM) i3-1315U >> >> Baseline: >> Benchmark (size) Mode Cnt Score Error Units >> VectorSliceBenchmark.byteVectorSliceWithConstantIndex1 1024 thrpt 2 9444.444 ops/ms >> VectorSliceBenchmark.byteVectorSliceWithConstantIndex2 1024 thrpt 2 10009.319 ops/ms >> VectorSliceBenchmark.byteVectorSliceWithVariableIndex 1024 thrpt 2 9081.926 ops/ms >> VectorSliceBenchmark.intVectorSliceWithConstantIndex1 1024 thrpt 2 6085.825 ops/ms >> VectorSliceBenchmark.intVectorSliceWithConstantIndex2 1024 thrpt 2 6505.378 ops/ms >> VectorSliceBenchmark.intVectorSliceWithVariableIndex 1024 thrpt 2 6204.489 ops/ms >> VectorSliceBenchmark.longVectorSliceWithConstantIndex1 1024 thrpt 2 1651.334 ops/ms >> VectorSliceBenchmark.longVectorSliceWithConstantIndex2 1024 thrpt 2 1642.784 ops/ms >> VectorSliceBenchmark.longVectorSliceWithVariableIndex 1024 thrpt 2 1474.808 ops/ms >> VectorSliceBenchmark.shortVectorSliceWithConstantIndex1 1024 thrpt 2 10399.394 ops/ms >> VectorSliceBenchmark.shortVectorSliceWithConstantIndex2 1024 thrpt 2 10502.894 ops/ms >> VectorSliceB... > > Jatin Bhateja has updated the pull request incrementally with one additional commit since the last revision: > > Updating predicate checks Performance on AVX512 machine Baseline: Benchmark (size) Mode Cnt Score Error Units VectorSliceBenchmark.byteVectorSliceWithConstantIndex1 1024 thrpt 4 35741.780 ? 1561.065 ops/ms VectorSliceBenchmark.byteVectorSliceWithConstantIndex2 1024 thrpt 4 35011.929 ? 5886.902 ops/ms VectorSliceBenchmark.byteVectorSliceWithVariableIndex 1024 thrpt 4 32366.844 ? 1489.449 ops/ms VectorSliceBenchmark.intVectorSliceWithConstantIndex1 1024 thrpt 4 10636.281 ? 608.705 ops/ms VectorSliceBenchmark.intVectorSliceWithConstantIndex2 1024 thrpt 4 10750.833 ? 328.997 ops/ms VectorSliceBenchmark.intVectorSliceWithVariableIndex 1024 thrpt 4 10257.338 ? 2027.422 ops/ms VectorSliceBenchmark.longVectorSliceWithConstantIndex1 1024 thrpt 4 5362.330 ? 4199.651 ops/ms VectorSliceBenchmark.longVectorSliceWithConstantIndex2 1024 thrpt 4 4992.399 ? 6053.641 ops/ms VectorSliceBenchmark.longVectorSliceWithVariableIndex 1024 thrpt 4 4941.258 ? 478.193 ops/ms VectorSliceBenchmark.shortVectorSliceWithConstantIndex1 1024 thrpt 4 40432.828 ? 26672.673 ops/ms VectorSliceBenchmark.shortVectorSliceWithConstantIndex2 1024 thrpt 4 41300.811 ? 34342.482 ops/ms VectorSliceBenchmark.shortVectorSliceWithVariableIndex 1024 thrpt 4 36958.309 ? 1899.676 ops/ms Withopt: Benchmark (size) Mode Cnt Score Error Units VectorSliceBenchmark.byteVectorSliceWithConstantIndex1 1024 thrpt 10 67936.711 ? 389.783 ops/ms VectorSliceBenchmark.byteVectorSliceWithConstantIndex2 1024 thrpt 10 70086.731 ? 5972.968 ops/ms VectorSliceBenchmark.byteVectorSliceWithVariableIndex 1024 thrpt 10 31879.187 ? 148.213 ops/ms VectorSliceBenchmark.intVectorSliceWithConstantIndex1 1024 thrpt 10 17676.883 ? 217.238 ops/ms VectorSliceBenchmark.intVectorSliceWithConstantIndex2 1024 thrpt 10 16983.007 ? 3988.548 ops/ms VectorSliceBenchmark.intVectorSliceWithVariableIndex 1024 thrpt 10 9851.266 ? 31.773 ops/ms VectorSliceBenchmark.longVectorSliceWithConstantIndex1 1024 thrpt 10 9194.216 ? 42.772 ops/ms VectorSliceBenchmark.longVectorSliceWithConstantIndex2 1024 thrpt 10 8411.738 ? 33.209 ops/ms VectorSliceBenchmark.longVectorSliceWithVariableIndex 1024 thrpt 10 5244.850 ? 12.214 ops/ms VectorSliceBenchmark.shortVectorSliceWithConstantIndex1 1024 thrpt 10 61233.526 ? 20472.895 ops/ms VectorSliceBenchmark.shortVectorSliceWithConstantIndex2 1024 thrpt 10 61545.276 ? 20722.066 ops/ms VectorSliceBenchmark.shortVectorSliceWithVariableIndex 1024 thrpt 10 41208.718 ? 5374.829 ops/ms ------------- PR Comment: https://git.openjdk.org/jdk/pull/24104#issuecomment-3125629912 From tschatzl at openjdk.org Mon Jul 28 09:12:53 2025 From: tschatzl at openjdk.org (Thomas Schatzl) Date: Mon, 28 Jul 2025 09:12:53 GMT Subject: RFR: 8342382: Implementation of JEP G1: Improve Application Throughput with a More Efficient Write-Barrier [v45] In-Reply-To: References: Message-ID: > Hi all, > > please review this change that implements (currently Draft) JEP: G1: Improve Application Throughput with a More Efficient Write-Barrier. > > The reason for posting this early is that this is a large change, and the JEP process is already taking very long with no end in sight but we would like to have this ready by JDK 25. > > ### Current situation > > With this change, G1 will reduce the post write barrier to much more resemble Parallel GC's as described in the JEP. The reason is that G1 lacks in throughput compared to Parallel/Serial GC due to larger barrier. > > The main reason for the current barrier is how g1 implements concurrent refinement: > * g1 tracks dirtied cards using sets (dirty card queue set - dcqs) of buffers (dirty card queues - dcq) containing the location of dirtied cards. Refinement threads pick up their contents to re-refine. The barrier needs to enqueue card locations. > * For correctness dirty card updates requires fine-grained synchronization between mutator and refinement threads, > * Finally there is generic code to avoid dirtying cards altogether (filters), to avoid executing the synchronization and the enqueuing as much as possible. > > These tasks require the current barrier to look as follows for an assignment `x.a = y` in pseudo code: > > > // Filtering > if (region(@x.a) == region(y)) goto done; // same region check > if (y == null) goto done; // null value check > if (card(@x.a) == young_card) goto done; // write to young gen check > StoreLoad; // synchronize > if (card(@x.a) == dirty_card) goto done; > > *card(@x.a) = dirty > > // Card tracking > enqueue(card-address(@x.a)) into thread-local-dcq; > if (thread-local-dcq is not full) goto done; > > call runtime to move thread-local-dcq into dcqs > > done: > > > Overall this post-write barrier alone is in the range of 40-50 total instructions, compared to three or four(!) for parallel and serial gc. > > The large size of the inlined barrier not only has a large code footprint, but also prevents some compiler optimizations like loop unrolling or inlining. > > There are several papers showing that this barrier alone can decrease throughput by 10-20% ([Yang12](https://dl.acm.org/doi/10.1145/2426642.2259004)), which is corroborated by some benchmarks (see links). > > The main idea for this change is to not use fine-grained synchronization between refinement and mutator threads, but coarse grained based on atomically switching card tables. Mutators only work on the "primary" card table, refinement threads on a se... Thomas Schatzl has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 62 commits: - Merge branch 'master' into 8342382-card-table-instead-of-dcq - * remove unused G1DetachedRefinementStats_lock - Merge branch 'master' into 8342382-card-table-instead-of-dcq - Merge branch 'master' into 8342382-card-table-instead-of-dcq - Merge branch 'master' into pull/23739 - Merge branch 'master' into 8342382-card-table-instead-of-dcq - Merge branch 'master' into 8342382-card-table-instead-of-dcq - Merge branch 'master' into 8342382-card-table-instead-of-dcq - Merge branch 'master' into 8342382-card-table-instead-of-dcq - * ayang review: remove sweep_epoch - ... and 52 more: https://git.openjdk.org/jdk/compare/bdc1ef20...23aa2c8b ------------- Changes: https://git.openjdk.org/jdk/pull/23739/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=23739&range=44 Stats: 7123 lines in 112 files changed: 2588 ins; 3593 del; 942 mod Patch: https://git.openjdk.org/jdk/pull/23739.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/23739/head:pull/23739 PR: https://git.openjdk.org/jdk/pull/23739 From vyazici at openjdk.org Mon Jul 28 09:36:00 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Mon, 28 Jul 2025 09:36:00 GMT Subject: RFR: 8361842: Move input validation checks to Java for java.lang.StringCoding intrinsics [v13] In-Reply-To: References: <-o9qy_Jsa4tvizzy8WgngfPuz9tx8Cwcztzl9AXiB70=.9ddb14d6-ee47-448d-a5a5-9c9ac4db3e0c@github.com> Message-ID: <7pEtXtLj_rHcJb_-M1FNge1GhM48UoW0ZMHhI44HH-w=.5401889c-3613-4cc6-aef6-52266066b821@github.com> On Fri, 25 Jul 2025 07:40:46 GMT, Volkan Yazici wrote: >> Validate input in `java.lang.StringCoding` intrinsic Java wrappers, improve their documentation, enhance the checks in the associated IR or assembly code, and adapt them to cause VM crash on invalid input. >> >> ## Implementation notes >> >> The goal of the associated umbrella issue [JDK-8156534](https://bugs.openjdk.org/browse/JDK-8156534) is to, for `java.lang.String*` classes, >> >> 1. Move `@IntrinsicCandidate`-annotated `public` methods1 (in Java code) to `private` ones, and wrap them with a `public` ["front door" method](https://github.com/openjdk/jdk/pull/24982#discussion_r2087493446) >> 2. Since we moved the `@IntrinsicCandidate` annotation to a new method, intrinsic mappings ? i.e., associated `do_intrinsic()` calls in `vmIntrinsics.hpp` ? need to be updated too >> 3. Add necessary input validation (range, null, etc.) checks to the newly created public front door method >> 4. Place all input validation checks in the intrinsic code (add if missing!) behind a `VerifyIntrinsicChecks` VM flag >> >> Following preliminary work needs to be carried out as well: >> >> 1. Add a new `VerifyIntrinsicChecks` VM flag >> 2. Update `generate_string_range_check` to produce a `HaltNode`. That is, crash the VM if `VerifyIntrinsicChecks` is set and a Java wrapper fails to spot an invalid input. >> >> 1 `@IntrinsicCandidate`-annotated constructors are not subject to this change, since they are a special case. >> >> ## Functional and performance tests >> >> - `tier1` (which includes `test/hotspot/jtreg/compiler/intrinsics/string`) passes on several platforms. Further tiers will be executed after integrating reviewer feedback. >> >> - Performance impact is still actively monitored using `test/micro/org/openjdk/bench/java/lang/String{En,De}code.java`, among other tests. If you have suggestions on benchmarks, please share in the comments. >> >> ## Verification of the VM crash >> >> I've tested the VM crash scenario as follows: >> >> 1. Created the following test program: >> >> public class StrIntri { >> public static void main(String[] args) { >> Exception lastException = null; >> for (int i = 0; i < 1_000_000; i++) { >> try { >> jdk.internal.access.SharedSecrets.getJavaLangAccess().countPositives(new byte[]{1,2,3}, 2, 5); >> } catch (Exception exception) { >> lastException = exception; >> } >> } >> if (lastException != null) { >> lastException.printStackTrace... > > Volkan Yazici has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains 31 additional commits since the last revision: > > - Merge remote-tracking branch 'upstream/master' into strIntrinCheck > - Replace `requireNonNull` with implicit null checks to reduce bytecode size > - Add `@bug` tags > - Improve wording of `@param len` > - Make source array bound checks lenient too > - Cap destination array bounds > - Fix bit shifting > - Remove superseded `@throws` Javadoc > - Merge remote-tracking branch 'upstream/master' into strIntrinCheck > - Make `StringCoding` encoding intrinsics lenient > - ... and 21 more: https://git.openjdk.org/jdk/compare/8888d41d...c322f0e0 Status update: * Changes are pretty-much settled. I'm waiting for a final review from @cl4es. * Checked the performance impact of changes against [DaCapo](https://www.dacapobench.org/) BioJava, and `org.openjdk.bench.java.lang.String{En,De}code` benchmarks on several platforms. Spotted one consistent significant (i.e., >2%) regression: `StringDecode::decodeShortMixed` ? explicitly forcing inlining1 did not help either. Granted this is the only, and benchmark- and platform-specific regression, @RogerRiggs suggested creating a follow-up ticket for this particular regression and integrating this PR. I will wait for input from @cl4es. 1 `-XX:CompileCommand=inline,java.lang.StringCoding::encodeISOArray -XX:CompileCommand=inline,java.lang.StringCoding::encodeAsciiArray` ------------- PR Comment: https://git.openjdk.org/jdk/pull/25998#issuecomment-3126372979 From sparasa at openjdk.org Mon Jul 28 18:38:55 2025 From: sparasa at openjdk.org (Srinivas Vamsi Parasa) Date: Mon, 28 Jul 2025 18:38:55 GMT Subject: RFR: 8360559: Optimize Math.sinh for x86 64 bit platforms [v2] In-Reply-To: <9pe9LuUrBnk6A2TQ2emhgonljAvnJLcmSV_lEbrYIlo=.fec9b081-d6ae-4d85-8826-489828d9f442@github.com> References: <9pe9LuUrBnk6A2TQ2emhgonljAvnJLcmSV_lEbrYIlo=.fec9b081-d6ae-4d85-8826-489828d9f442@github.com> Message-ID: On Thu, 17 Jul 2025 18:46:06 GMT, Mohamed Issa wrote: >> The goal of this PR is to implement an x86_64 intrinsic for java.lang.Math.sinh() using libm. There is a new set of micro-benchmarks are included to check the performance of specific input value ranges to help prevent regressions in the future. >> >> The command to run all range specific micro-benchmarks is posted below. >> >> `make test TEST="micro:SinhPerf.SinhPerfRanges"` >> >> The results of all tests posted below were captured with an [Intel? Xeon 8488C](https://advisor.cloudzero.com/aws/ec2/r7i.metal-24xl) using [OpenJDK v26-b4](https://github.com/openjdk/jdk/releases/tag/jdk-26%2B4) as the baseline version. >> >> For performance data collected with the new built in range micro-benchmark, see the table below. Each result is the mean of 8 individual runs, and the input ranges used match those from the original Java implementation. Overall, the intrinsic provides an an average uplift of 64% when input values fall into the middle three ranges where heavy computation is required. However, very small inputs and very large inputs show drops of 74% and 66% respectively. >> >> | Input range(s) | Baseline throughput (ops/ms) | Intrinsic throughput (ops/ms) | Speedup | >> | :------------------------------------: | :-------------------------------: | :--------------------------------: | :--------: | >> | [-2^(-28), 2^(-28)] | 844160 | 216029 | 0.26x | >> | [-22, -2^(-28)], [2^(-28), 22] | 81662 | 157351 | 1.93x | >> | [-709.78, -22], [22, 709.78] | 119075 | 167635 | 1.41x | >> | [-710.48, -709.78], [709.78, 710.48] | 111636 | 177125 | 1.59x | >> | (-INF, -710.48], [710.48, INF) | 959296 | 313839 | 0.33x | >> >> Finally, the `jtreg:test/jdk/java/lang/Math/HyperbolicTests.java` test passed with the changes. > > Mohamed Issa has updated the pull request incrementally with one additional commit since the last revision: > > Move error bound to separate section in comment header I reviewed the code, ran the benchmarks and correctness test and verified that it's passing. This PR looks good to me. ------------- Marked as reviewed by sparasa (Author). PR Review: https://git.openjdk.org/jdk/pull/26152#pullrequestreview-3064160746 From coleenp at openjdk.org Mon Jul 28 20:19:31 2025 From: coleenp at openjdk.org (Coleen Phillimore) Date: Mon, 28 Jul 2025 20:19:31 GMT Subject: RFR: 8364187: Make getClassAccessFlagsRaw non-native Message-ID: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> This change removes the intrinsic for getClassAccessFlagsRaw for reflection and initializes an rawAccessFlags field in java.lang.Class instead, that Java code can non-natively access. Tested with tier1-4. ------------- Commit messages: - The only caller for getRawClassAccessFlags in Class.java doesn't call it for arrays so we really want the "raw" classfile access flags. - Add a comment - 8364187: Make getClassAccessFlagsRaw non-native Changes: https://git.openjdk.org/jdk/pull/26517/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=26517&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8364187 Stats: 98 lines in 16 files changed: 38 ins; 46 del; 14 mod Patch: https://git.openjdk.org/jdk/pull/26517.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26517/head:pull/26517 PR: https://git.openjdk.org/jdk/pull/26517 From liach at openjdk.org Mon Jul 28 22:00:59 2025 From: liach at openjdk.org (Chen Liang) Date: Mon, 28 Jul 2025 22:00:59 GMT Subject: RFR: 8364187: Make getClassAccessFlagsRaw non-native In-Reply-To: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> References: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> Message-ID: On Mon, 28 Jul 2025 20:14:15 GMT, Coleen Phillimore wrote: > This change removes the intrinsic for getClassAccessFlagsRaw for reflection and initializes an rawAccessFlags field in java.lang.Class instead, that Java code can non-natively access. > Tested with tier1-4. src/java.base/share/classes/java/lang/Class.java line 1012: > 1010: private transient Object[] signers; // Read by VM, mutable > 1011: private final transient char modifiers; // Set by the VM > 1012: private final transient char rawAccessFlags; // Set by the VM I suggest `classFileFlags` in the spirit of `getClassFileVersion` - this is the flag on the JVMS 4 `ClassFile` structure, while the `modifiers` can be alternatively from `InnerClasses` attribute. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26517#discussion_r2237933184 From coleenp at openjdk.org Tue Jul 29 12:02:14 2025 From: coleenp at openjdk.org (Coleen Phillimore) Date: Tue, 29 Jul 2025 12:02:14 GMT Subject: RFR: 8364187: Make getClassAccessFlagsRaw non-native In-Reply-To: References: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> Message-ID: On Mon, 28 Jul 2025 21:56:16 GMT, Chen Liang wrote: >> This change removes the intrinsic for getClassAccessFlagsRaw for reflection and initializes an rawAccessFlags field in java.lang.Class instead, that Java code can non-natively access. >> Tested with tier1-4. > > src/java.base/share/classes/java/lang/Class.java line 1012: > >> 1010: private transient Object[] signers; // Read by VM, mutable >> 1011: private final transient char modifiers; // Set by the VM >> 1012: private final transient char rawAccessFlags; // Set by the VM > > I suggest `classFileFlags` in the spirit of `getClassFileVersion` - this is the flag on the JVMS 4 `ClassFile` structure, while the `modifiers` can be alternatively from `InnerClasses` attribute. This is a good suggestion but I made it Raw to match getRawClassAnnotations this name. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26517#discussion_r2239571176 From coleenp at openjdk.org Tue Jul 29 13:43:35 2025 From: coleenp at openjdk.org (Coleen Phillimore) Date: Tue, 29 Jul 2025 13:43:35 GMT Subject: RFR: 8364187: Make getClassAccessFlagsRaw non-native [v2] In-Reply-To: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> References: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> Message-ID: > This change removes the intrinsic for getClassAccessFlagsRaw for reflection and initializes an rawAccessFlags field in java.lang.Class instead, that Java code can non-natively access. > Tested with tier1-4. Coleen Phillimore has updated the pull request incrementally with one additional commit since the last revision: Rename getRawClassAccessFlags to getClassFileAccessFlags and fix the test to reflect what the JVM does. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26517/files - new: https://git.openjdk.org/jdk/pull/26517/files/b4daf731..163a8e5c Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26517&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26517&range=00-01 Stats: 57 lines in 6 files changed: 32 ins; 0 del; 25 mod Patch: https://git.openjdk.org/jdk/pull/26517.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26517/head:pull/26517 PR: https://git.openjdk.org/jdk/pull/26517 From liach at openjdk.org Tue Jul 29 14:37:59 2025 From: liach at openjdk.org (Chen Liang) Date: Tue, 29 Jul 2025 14:37:59 GMT Subject: RFR: 8364187: Make getClassAccessFlagsRaw non-native [v2] In-Reply-To: References: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> Message-ID: On Tue, 29 Jul 2025 11:58:50 GMT, Coleen Phillimore wrote: >> src/java.base/share/classes/java/lang/Class.java line 1012: >> >>> 1010: private transient Object[] signers; // Read by VM, mutable >>> 1011: private final transient char modifiers; // Set by the VM >>> 1012: private final transient char rawAccessFlags; // Set by the VM >> >> I suggest `classFileFlags` in the spirit of `getClassFileVersion` - this is the flag on the JVMS 4 `ClassFile` structure, while the `modifiers` can be alternatively from `InnerClasses` attribute. > > This is a good suggestion but I made it Raw to match getRawClassAnnotations this name. Thanks for the rename. I think `raw annotations` means the uninterpreted byte data in the attribute is carried over raw; this concept is less applicable to the access_flags u2 value. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26517#discussion_r2240075254 From rriggs at openjdk.org Tue Jul 29 15:02:59 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Tue, 29 Jul 2025 15:02:59 GMT Subject: RFR: 8364187: Make getClassAccessFlagsRaw non-native [v2] In-Reply-To: References: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> Message-ID: <5rPWGuXUbiRbQ7TlwHJnQDjRYSuWRITbbo0OUtMfhrY=.cfe52d81-3450-477f-b5d8-02b3590971d0@github.com> On Tue, 29 Jul 2025 13:43:35 GMT, Coleen Phillimore wrote: >> This change removes the intrinsic for getClassAccessFlagsRaw for reflection and initializes an rawAccessFlags field in java.lang.Class instead, that Java code can non-natively access. >> Tested with tier1-4. > > Coleen Phillimore has updated the pull request incrementally with one additional commit since the last revision: > > Rename getRawClassAccessFlags to getClassFileAccessFlags and fix the test to reflect what the JVM does. src/java.base/share/classes/java/lang/Class.java line 248: > 246: protectionDomain = pd; > 247: primitive = isPrim; > 248: classFileAccessFlags = flags; Its not that hard to add a field, why not have done this for identity? src/java.base/share/classes/java/lang/Class.java line 4143: > 4141: * {@code FINAL}. > 4142: * If this {@code Class} object represents an array type return 0. This > 4143: * is not called in Class but can be called with an array type in Reflection. The comment about "not called in Class" may get stale. I don't think it needs to be specified. src/java.base/share/classes/jdk/internal/reflect/Reflection.java line 87: > 85: class Holder { > 86: static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); > 87: } Yuck, another class and another shared secret. There's no need for a Holder class, just call SharedSecrets.getJavaLangAccess every time. It just returning a value from a static field. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26517#discussion_r2240132537 PR Review Comment: https://git.openjdk.org/jdk/pull/26517#discussion_r2240117128 PR Review Comment: https://git.openjdk.org/jdk/pull/26517#discussion_r2240126279 From liach at openjdk.org Tue Jul 29 15:26:56 2025 From: liach at openjdk.org (Chen Liang) Date: Tue, 29 Jul 2025 15:26:56 GMT Subject: RFR: 8364187: Make getClassAccessFlagsRaw non-native [v2] In-Reply-To: <5rPWGuXUbiRbQ7TlwHJnQDjRYSuWRITbbo0OUtMfhrY=.cfe52d81-3450-477f-b5d8-02b3590971d0@github.com> References: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> <5rPWGuXUbiRbQ7TlwHJnQDjRYSuWRITbbo0OUtMfhrY=.cfe52d81-3450-477f-b5d8-02b3590971d0@github.com> Message-ID: On Tue, 29 Jul 2025 14:55:04 GMT, Roger Riggs wrote: >> Coleen Phillimore has updated the pull request incrementally with one additional commit since the last revision: >> >> Rename getRawClassAccessFlags to getClassFileAccessFlags and fix the test to reflect what the JVM does. > > src/java.base/share/classes/java/lang/Class.java line 248: > >> 246: protectionDomain = pd; >> 247: primitive = isPrim; >> 248: classFileAccessFlags = flags; > > Its not that hard to add a field, why not have done this for identity? Fields are initialized by injection in javaClasses instead of through this constructor, so it's easy for us to accidentally forget to inject a field. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26517#discussion_r2240207422 From duke at openjdk.org Tue Jul 29 16:42:56 2025 From: duke at openjdk.org (ExE Boss) Date: Tue, 29 Jul 2025 16:42:56 GMT Subject: RFR: 8364187: Make getClassAccessFlagsRaw non-native [v2] In-Reply-To: <5rPWGuXUbiRbQ7TlwHJnQDjRYSuWRITbbo0OUtMfhrY=.cfe52d81-3450-477f-b5d8-02b3590971d0@github.com> References: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> <5rPWGuXUbiRbQ7TlwHJnQDjRYSuWRITbbo0OUtMfhrY=.cfe52d81-3450-477f-b5d8-02b3590971d0@github.com> Message-ID: On Tue, 29 Jul 2025 14:52:53 GMT, Roger Riggs wrote: >> Coleen Phillimore has updated the pull request incrementally with one additional commit since the last revision: >> >> Rename getRawClassAccessFlags to getClassFileAccessFlags and fix the test to reflect what the JVM does. > > src/java.base/share/classes/jdk/internal/reflect/Reflection.java line 87: > >> 85: class Holder { >> 86: static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); >> 87: } > > Yuck, another class and another shared secret. > There's no need for a Holder class, just call SharedSecrets.getJavaLangAccess every time. > It just returning a value from a static field. Arguably, the?fields in?`SharedSecrets` should?be?made `@Stable`. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26517#discussion_r2240401098 From coleenp at openjdk.org Tue Jul 29 19:58:14 2025 From: coleenp at openjdk.org (Coleen Phillimore) Date: Tue, 29 Jul 2025 19:58:14 GMT Subject: RFR: 8364187: Make getClassAccessFlagsRaw non-native [v2] In-Reply-To: References: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> <5rPWGuXUbiRbQ7TlwHJnQDjRYSuWRITbbo0OUtMfhrY=.cfe52d81-3450-477f-b5d8-02b3590971d0@github.com> Message-ID: On Tue, 29 Jul 2025 16:40:22 GMT, ExE Boss wrote: >> src/java.base/share/classes/jdk/internal/reflect/Reflection.java line 87: >> >>> 85: class Holder { >>> 86: static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); >>> 87: } >> >> Yuck, another class and another shared secret. >> There's no need for a Holder class, just call SharedSecrets.getJavaLangAccess every time. >> It just returning a value from a static field. > > Arguably, the?fields in?`SharedSecrets` should?be?made `@Stable`. Okay, I'll remove the Holder class. I copied it from another method in the file. yeah, sorry for the additional shared secret but I didn't want to make the java.lang.Class method public. I didn't add a field to SharedSecrets, and the field in Class is transient which I think supersedes @Stable - at least that's what I remember from our discussion of the modifiers field in Class. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26517#discussion_r2240789122 From coleenp at openjdk.org Tue Jul 29 19:58:11 2025 From: coleenp at openjdk.org (Coleen Phillimore) Date: Tue, 29 Jul 2025 19:58:11 GMT Subject: RFR: 8364187: Make getClassAccessFlagsRaw non-native [v2] In-Reply-To: References: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> <5rPWGuXUbiRbQ7TlwHJnQDjRYSuWRITbbo0OUtMfhrY=.cfe52d81-3450-477f-b5d8-02b3590971d0@github.com> Message-ID: <5gvsQ413EdL2Lvs-rmusDgTPMiT7lVag5H4fF5Fk4P4=.1416ddb9-6161-419e-8fc2-653e073dd399@github.com> On Tue, 29 Jul 2025 15:22:53 GMT, Chen Liang wrote: >> src/java.base/share/classes/java/lang/Class.java line 248: >> >>> 246: protectionDomain = pd; >>> 247: primitive = isPrim; >>> 248: classFileAccessFlags = flags; >> >> Its not that hard to add a field, why not have done this for identity? > > Fields are initialized by injection in javaClasses instead of through this constructor, so it's easy for us to accidentally forget to inject a field. For IDENTITY, I didn't have to inject that one because the Java code knew when to set it, not the JVM code reading the data out of the classfile. And the logic belongs in the Java code, not the JVM. This one comes from the classfile, there isn't another way to get the information to the java.lang.Class. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26517#discussion_r2240783242 From coleenp at openjdk.org Tue Jul 29 19:58:12 2025 From: coleenp at openjdk.org (Coleen Phillimore) Date: Tue, 29 Jul 2025 19:58:12 GMT Subject: RFR: 8364187: Make getClassAccessFlagsRaw non-native [v2] In-Reply-To: <5rPWGuXUbiRbQ7TlwHJnQDjRYSuWRITbbo0OUtMfhrY=.cfe52d81-3450-477f-b5d8-02b3590971d0@github.com> References: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> <5rPWGuXUbiRbQ7TlwHJnQDjRYSuWRITbbo0OUtMfhrY=.cfe52d81-3450-477f-b5d8-02b3590971d0@github.com> Message-ID: <0vCCEQN8w5kI1KG08bFyMXlpNkQ0ijhI6SSxrhkWPUs=.8104e221-c4fc-4524-ba67-79ab6b080dc0@github.com> On Tue, 29 Jul 2025 14:49:33 GMT, Roger Riggs wrote: >> Coleen Phillimore has updated the pull request incrementally with one additional commit since the last revision: >> >> Rename getRawClassAccessFlags to getClassFileAccessFlags and fix the test to reflect what the JVM does. > > src/java.base/share/classes/java/lang/Class.java line 4143: > >> 4141: * {@code FINAL}. >> 4142: * If this {@code Class} object represents an array type return 0. This >> 4143: * is not called in Class but can be called with an array type in Reflection. > > The comment about "not called in Class" may get stale. I don't think it needs to be specified. Okay, I'll remove it. I wanted to explain the change of the algorithm, and why I removed the handling for arrays. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26517#discussion_r2240785622 From coleenp at openjdk.org Tue Jul 29 19:58:10 2025 From: coleenp at openjdk.org (Coleen Phillimore) Date: Tue, 29 Jul 2025 19:58:10 GMT Subject: RFR: 8364187: Make getClassAccessFlagsRaw non-native [v3] In-Reply-To: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> References: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> Message-ID: > This change removes the intrinsic for getClassAccessFlagsRaw for reflection and initializes an rawAccessFlags field in java.lang.Class instead, that Java code can non-natively access. > Tested with tier1-4. Coleen Phillimore has updated the pull request incrementally with one additional commit since the last revision: Fix comments and remove Holder. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26517/files - new: https://git.openjdk.org/jdk/pull/26517/files/163a8e5c..a4974473 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26517&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26517&range=01-02 Stats: 6 lines in 2 files changed: 0 ins; 3 del; 3 mod Patch: https://git.openjdk.org/jdk/pull/26517.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26517/head:pull/26517 PR: https://git.openjdk.org/jdk/pull/26517 From duke at openjdk.org Tue Jul 29 22:11:58 2025 From: duke at openjdk.org (ExE Boss) Date: Tue, 29 Jul 2025 22:11:58 GMT Subject: RFR: 8364187: Make getClassAccessFlagsRaw non-native [v3] In-Reply-To: References: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> Message-ID: On Tue, 29 Jul 2025 19:58:10 GMT, Coleen Phillimore wrote: >> This change removes the intrinsic for getClassAccessFlagsRaw for reflection and initializes an rawAccessFlags field in java.lang.Class instead, that Java code can non-natively access. >> Tested with tier1-4. > > Coleen Phillimore has updated the pull request incrementally with one additional commit since the last revision: > > Fix comments and remove Holder. src/java.base/share/classes/jdk/internal/reflect/Reflection.java line 86: > 84: public static int getClassAccessFlags(Class c) { > 85: JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); > 86: return JLA.getClassFileAccessFlags(c); Suggestion: return SharedSecrets.getJavaLangAccess().getClassFileAccessFlags(c); ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26517#discussion_r2241101969 From duke at openjdk.org Tue Jul 29 22:11:58 2025 From: duke at openjdk.org (ExE Boss) Date: Tue, 29 Jul 2025 22:11:58 GMT Subject: RFR: 8364187: Make getClassAccessFlagsRaw non-native [v2] In-Reply-To: References: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> <5rPWGuXUbiRbQ7TlwHJnQDjRYSuWRITbbo0OUtMfhrY=.cfe52d81-3450-477f-b5d8-02b3590971d0@github.com> Message-ID: On Tue, 29 Jul 2025 19:46:06 GMT, Coleen Phillimore wrote: >> Arguably, the?fields in?`SharedSecrets` should?be?made `@Stable`. > > Okay, I'll remove the Holder class. I copied it from another method in the file. yeah, sorry for the additional shared secret but I didn't want to make the java.lang.Class method public. > > I didn't add a field to SharedSecrets, and the field in Class is transient which I think supersedes @Stable - at least that's what I remember from our discussion of the modifiers field in Class. I?mean the?existing private?fields of?`SharedSecrets`[^1] so?that the?JIT is?able to?constant?fold calls?to?`SharedSecrets?::getJava*Access()` so?that it?becomes equally?as?performant as?using a?`Holder`?class. Modifiers are?transient, as?those are?sourced?from the?`InnerClasses`?attribute, which?can?be?changed when?classes are?redefined by?a?**JVMTI**?agent, but?access?flags can?t?be?changed through?redefinition. [^1]: https://github.com/openjdk/jdk/blob/330ee871315348594171c43aa75b58f6027001af/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java#L62-L92 ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26517#discussion_r2241100994 From coleenp at openjdk.org Wed Jul 30 10:59:55 2025 From: coleenp at openjdk.org (Coleen Phillimore) Date: Wed, 30 Jul 2025 10:59:55 GMT Subject: RFR: 8364187: Make getClassAccessFlagsRaw non-native [v2] In-Reply-To: References: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> <5rPWGuXUbiRbQ7TlwHJnQDjRYSuWRITbbo0OUtMfhrY=.cfe52d81-3450-477f-b5d8-02b3590971d0@github.com> Message-ID: <3KAsrKOGuC7XInNaIEmocMu2vX8RTL5dOJhwsnFnSPs=.6c5dc374-6807-416d-9c78-cd664cd04f6f@github.com> On Tue, 29 Jul 2025 21:59:41 GMT, ExE Boss wrote: >> Okay, I'll remove the Holder class. I copied it from another method in the file. yeah, sorry for the additional shared secret but I didn't want to make the java.lang.Class method public. >> >> I didn't add a field to SharedSecrets, and the field in Class is transient which I think supersedes @Stable - at least that's what I remember from our discussion of the modifiers field in Class. > > I?mean the?existing private?fields of?`SharedSecrets`[^1] so?that the?JIT is?able to?constant?fold calls?to?`SharedSecrets?::getJava*Access()` so?that it?becomes equally?as?performant as?using a?`Holder`?class. > > Modifiers are?transient, as?those are?sourced?from the?`InnerClasses`?attribute, which?can?be?changed when?classes are?redefined by?a?**JVMTI**?agent, but?access?flags can?t?be?changed through?redefinition. > > [^1]: https://github.com/openjdk/jdk/blob/330ee871315348594171c43aa75b58f6027001af/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java#L62-L92 I don't think inner class attributes can be changed via JVMTI RedefineClasses either. I'm pretty sure we check and that's considered a change of schema. File an RFE to make SharedSecrets fields @Stable though for a different change. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26517#discussion_r2242267576 From coleenp at openjdk.org Wed Jul 30 11:05:34 2025 From: coleenp at openjdk.org (Coleen Phillimore) Date: Wed, 30 Jul 2025 11:05:34 GMT Subject: RFR: 8364187: Make getClassAccessFlagsRaw non-native [v4] In-Reply-To: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> References: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> Message-ID: > This change removes the intrinsic for getClassAccessFlagsRaw for reflection and initializes an rawAccessFlags field in java.lang.Class instead, that Java code can non-natively access. > Tested with tier1-4. Coleen Phillimore has updated the pull request incrementally with one additional commit since the last revision: Update src/java.base/share/classes/jdk/internal/reflect/Reflection.java Co-authored-by: ExE Boss <3889017+ExE-Boss at users.noreply.github.com> ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26517/files - new: https://git.openjdk.org/jdk/pull/26517/files/a4974473..45b92c5c Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26517&range=03 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26517&range=02-03 Stats: 2 lines in 1 file changed: 0 ins; 1 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/26517.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26517/head:pull/26517 PR: https://git.openjdk.org/jdk/pull/26517 From thartmann at openjdk.org Wed Jul 30 12:23:55 2025 From: thartmann at openjdk.org (Tobias Hartmann) Date: Wed, 30 Jul 2025 12:23:55 GMT Subject: RFR: 8364187: Make getClassAccessFlagsRaw non-native [v4] In-Reply-To: References: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> Message-ID: On Wed, 30 Jul 2025 11:05:34 GMT, Coleen Phillimore wrote: >> This change removes the intrinsic for getClassAccessFlagsRaw for reflection and initializes an rawAccessFlags field in java.lang.Class instead, that Java code can non-natively access. >> Tested with tier1-4. > > Coleen Phillimore has updated the pull request incrementally with one additional commit since the last revision: > > Update src/java.base/share/classes/jdk/internal/reflect/Reflection.java > > Co-authored-by: ExE Boss <3889017+ExE-Boss at users.noreply.github.com> src/hotspot/share/opto/memnode.cpp line 1986: > 1984: // (Folds up the 2nd indirection in Reflection.getClassAccessFlags(aClassConstant).) > 1985: assert(Opcode() == Op_LoadUS, "must load an unsigned short from _access_flags"); > 1986: return TypeInt::make(klass->access_flags()); I think this optimization should stay because the `_getSuperclass` intrinsic still emits a load from `Klass::access_flags_offset()` that could potentially be optimized here, see: https://github.com/openjdk/jdk/blob/ed70910b0f3e1b19d915ec13ac3434407d01bc5d/src/hotspot/share/opto/library_call.cpp#L4081-L4088 -> https://github.com/openjdk/jdk/blob/ed70910b0f3e1b19d915ec13ac3434407d01bc5d/src/hotspot/share/opto/library_call.cpp#L3970-L3973 You can still remove the lines referencing `Reflection.getClassAccessFlags`. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26517#discussion_r2242464835 From coleenp at openjdk.org Wed Jul 30 16:57:56 2025 From: coleenp at openjdk.org (Coleen Phillimore) Date: Wed, 30 Jul 2025 16:57:56 GMT Subject: RFR: 8364187: Make getClassAccessFlagsRaw non-native [v4] In-Reply-To: References: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> Message-ID: On Wed, 30 Jul 2025 12:21:14 GMT, Tobias Hartmann wrote: >> Coleen Phillimore has updated the pull request incrementally with one additional commit since the last revision: >> >> Update src/java.base/share/classes/jdk/internal/reflect/Reflection.java >> >> Co-authored-by: ExE Boss <3889017+ExE-Boss at users.noreply.github.com> > > src/hotspot/share/opto/memnode.cpp line 1986: > >> 1984: // (Folds up the 2nd indirection in Reflection.getClassAccessFlags(aClassConstant).) >> 1985: assert(Opcode() == Op_LoadUS, "must load an unsigned short from _access_flags"); >> 1986: return TypeInt::make(klass->access_flags()); > > I think this optimization should stay because the `_getSuperclass` intrinsic still emits a load from `Klass::access_flags_offset()` that could potentially be optimized here, see: > https://github.com/openjdk/jdk/blob/ed70910b0f3e1b19d915ec13ac3434407d01bc5d/src/hotspot/share/opto/library_call.cpp#L4081-L4088 > -> > https://github.com/openjdk/jdk/blob/ed70910b0f3e1b19d915ec13ac3434407d01bc5d/src/hotspot/share/opto/library_call.cpp#L3970-L3973 > > You can still remove the lines referencing `Reflection.getClassAccessFlags`. Thank you, right, the code still references Klass::_access_flags. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26517#discussion_r2243330614 From coleenp at openjdk.org Wed Jul 30 19:25:34 2025 From: coleenp at openjdk.org (Coleen Phillimore) Date: Wed, 30 Jul 2025 19:25:34 GMT Subject: RFR: 8364187: Make getClassAccessFlagsRaw non-native [v5] In-Reply-To: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> References: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> Message-ID: > This change removes the intrinsic for getClassAccessFlagsRaw for reflection and initializes an rawAccessFlags field in java.lang.Class instead, that Java code can non-natively access. > Tested with tier1-4. Coleen Phillimore has updated the pull request incrementally with one additional commit since the last revision: Restore c2 optimization. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26517/files - new: https://git.openjdk.org/jdk/pull/26517/files/45b92c5c..fb6c15e8 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26517&range=04 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26517&range=03-04 Stats: 5 lines in 1 file changed: 5 ins; 0 del; 0 mod Patch: https://git.openjdk.org/jdk/pull/26517.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26517/head:pull/26517 PR: https://git.openjdk.org/jdk/pull/26517 From rriggs at openjdk.org Wed Jul 30 20:27:55 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Wed, 30 Jul 2025 20:27:55 GMT Subject: RFR: 8364187: Make getClassAccessFlagsRaw non-native [v2] In-Reply-To: <5gvsQ413EdL2Lvs-rmusDgTPMiT7lVag5H4fF5Fk4P4=.1416ddb9-6161-419e-8fc2-653e073dd399@github.com> References: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> <5rPWGuXUbiRbQ7TlwHJnQDjRYSuWRITbbo0OUtMfhrY=.cfe52d81-3450-477f-b5d8-02b3590971d0@github.com> <5gvsQ413EdL2Lvs-rmusDgTPMiT7lVag5H4fF5Fk4P4=.1416ddb9-6161-419e-8fc2-653e073dd399@github.com> Message-ID: On Tue, 29 Jul 2025 19:42:42 GMT, Coleen Phillimore wrote: >> Fields are initialized by injection in javaClasses instead of through this constructor, so it's easy for us to accidentally forget to inject a field. > > For IDENTITY, I didn't have to inject that one because the Java code knew when to set it, not the JVM code reading the data out of the classfile. And the logic belongs in the Java code, not the JVM. This one comes from the classfile, there isn't another way to get the information to the java.lang.Class. The VM and Java use the same logic for the value of isIdentity(). It is computed from as many a 5 fields/flags. At present, it has to be computed on each call to Class.isIdentity(). It would be reasonable to compute the value once in the constructor, but the code in the constructor is not run. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26517#discussion_r2243785633 From sviswanathan at openjdk.org Wed Jul 30 23:51:54 2025 From: sviswanathan at openjdk.org (Sandhya Viswanathan) Date: Wed, 30 Jul 2025 23:51:54 GMT Subject: RFR: 8360559: Optimize Math.sinh for x86 64 bit platforms [v2] In-Reply-To: <9pe9LuUrBnk6A2TQ2emhgonljAvnJLcmSV_lEbrYIlo=.fec9b081-d6ae-4d85-8826-489828d9f442@github.com> References: <9pe9LuUrBnk6A2TQ2emhgonljAvnJLcmSV_lEbrYIlo=.fec9b081-d6ae-4d85-8826-489828d9f442@github.com> Message-ID: On Thu, 17 Jul 2025 18:46:06 GMT, Mohamed Issa wrote: >> The goal of this PR is to implement an x86_64 intrinsic for java.lang.Math.sinh() using libm. There is a new set of micro-benchmarks are included to check the performance of specific input value ranges to help prevent regressions in the future. >> >> The command to run all range specific micro-benchmarks is posted below. >> >> `make test TEST="micro:SinhPerf.SinhPerfRanges"` >> >> The results of all tests posted below were captured with an [Intel? Xeon 8488C](https://advisor.cloudzero.com/aws/ec2/r7i.metal-24xl) using [OpenJDK v26-b4](https://github.com/openjdk/jdk/releases/tag/jdk-26%2B4) as the baseline version. >> >> For performance data collected with the new built in range micro-benchmark, see the table below. Each result is the mean of 8 individual runs, and the input ranges used match those from the original Java implementation. Overall, the intrinsic provides an an average uplift of 64% when input values fall into the middle three ranges where heavy computation is required. However, very small inputs and very large inputs show drops of 74% and 66% respectively. >> >> | Input range(s) | Baseline throughput (ops/ms) | Intrinsic throughput (ops/ms) | Speedup | >> | :------------------------------------: | :-------------------------------: | :--------------------------------: | :--------: | >> | [-2^(-28), 2^(-28)] | 844160 | 216029 | 0.26x | >> | [-22, -2^(-28)], [2^(-28), 22] | 81662 | 157351 | 1.93x | >> | [-709.78, -22], [22, 709.78] | 119075 | 167635 | 1.41x | >> | [-710.48, -709.78], [709.78, 710.48] | 111636 | 177125 | 1.59x | >> | (-INF, -710.48], [710.48, INF) | 959296 | 313839 | 0.33x | >> >> Finally, the `jtreg:test/jdk/java/lang/Math/HyperbolicTests.java` test passed with the changes. > > Mohamed Issa has updated the pull request incrementally with one additional commit since the last revision: > > Move error bound to separate section in comment header src/hotspot/cpu/x86/stubGenerator_x86_64_sinh.cpp line 325: > 323: __ jcc(Assembler::aboveEqual, L_2TAG_PACKET_0_0_2); // Branch only if |x| is not in [23/64, 3*2^8) > 324: __ movsd(xmm3, ExternalAddress(HALFMASK), r11 /*rscratch*/); > 325: __ movsd(xmm1, ExternalAddress(L2E), r11 /*rscratch*/); xmm1 is used at L_2TAG_PACKET_0_0_2 -> L_2TAG_PACKET_3_0_2 line 507 below so should be loaded prior to L_2TAG_PACKET_0_0_2. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26152#discussion_r2243550202 From coleenp at openjdk.org Thu Jul 31 11:47:59 2025 From: coleenp at openjdk.org (Coleen Phillimore) Date: Thu, 31 Jul 2025 11:47:59 GMT Subject: RFR: 8364187: Make getClassAccessFlagsRaw non-native [v2] In-Reply-To: References: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> <5rPWGuXUbiRbQ7TlwHJnQDjRYSuWRITbbo0OUtMfhrY=.cfe52d81-3450-477f-b5d8-02b3590971d0@github.com> <5gvsQ413EdL2Lvs-rmusDgTPMiT7lVag5H4fF5Fk4P4=.1416ddb9-6161-419e-8fc2-653e073dd399@github.com> Message-ID: On Wed, 30 Jul 2025 20:25:22 GMT, Roger Riggs wrote: >> For IDENTITY, I didn't have to inject that one because the Java code knew when to set it, not the JVM code reading the data out of the classfile. And the logic belongs in the Java code, not the JVM. This one comes from the classfile, there isn't another way to get the information to the java.lang.Class. > > The VM and Java use the same logic for the value of isIdentity(). > It is computed from as many a 5 fields/flags. At present, it has to be computed on each call to Class.isIdentity(). > It would be reasonable to compute the value once in the constructor, but the code in the constructor is not run. Roger, can you file another RFE for this for repo-valhalla and I can try to figure out how to best to do this? Or I can. I didn't think the valhalla isIdentityClass() code was expensive to call. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26517#discussion_r2245151689 From thartmann at openjdk.org Thu Jul 31 12:49:56 2025 From: thartmann at openjdk.org (Tobias Hartmann) Date: Thu, 31 Jul 2025 12:49:56 GMT Subject: RFR: 8364187: Make getClassAccessFlagsRaw non-native [v5] In-Reply-To: References: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> Message-ID: On Wed, 30 Jul 2025 19:25:34 GMT, Coleen Phillimore wrote: >> This change removes the intrinsic for getClassAccessFlagsRaw for reflection and initializes an rawAccessFlags field in java.lang.Class instead, that Java code can non-natively access. >> Tested with tier1-4. > > Coleen Phillimore has updated the pull request incrementally with one additional commit since the last revision: > > Restore c2 optimization. Compiler changes look good to me. ------------- Marked as reviewed by thartmann (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/26517#pullrequestreview-3075269461 From rriggs at openjdk.org Thu Jul 31 15:20:59 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Thu, 31 Jul 2025 15:20:59 GMT Subject: RFR: 8364187: Make getClassAccessFlagsRaw non-native [v5] In-Reply-To: References: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> Message-ID: On Wed, 30 Jul 2025 19:25:34 GMT, Coleen Phillimore wrote: >> This change removes the intrinsic for getClassAccessFlagsRaw for reflection and initializes an rawAccessFlags field in java.lang.Class instead, that Java code can non-natively access. >> Tested with tier1-4. > > Coleen Phillimore has updated the pull request incrementally with one additional commit since the last revision: > > Restore c2 optimization. Looks good, thanks ------------- Marked as reviewed by rriggs (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/26517#pullrequestreview-3075875144 From rriggs at openjdk.org Thu Jul 31 15:21:00 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Thu, 31 Jul 2025 15:21:00 GMT Subject: RFR: 8364187: Make getClassAccessFlagsRaw non-native [v2] In-Reply-To: References: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> <5rPWGuXUbiRbQ7TlwHJnQDjRYSuWRITbbo0OUtMfhrY=.cfe52d81-3450-477f-b5d8-02b3590971d0@github.com> <5gvsQ413EdL2Lvs-rmusDgTPMiT7lVag5H4fF5Fk4P4=.1416ddb9-6161-419e-8fc2-653e073dd399@github.com> Message-ID: On Thu, 31 Jul 2025 11:45:00 GMT, Coleen Phillimore wrote: >> The VM and Java use the same logic for the value of isIdentity(). >> It is computed from as many a 5 fields/flags. At present, it has to be computed on each call to Class.isIdentity(). >> It would be reasonable to compute the value once in the constructor, but the code in the constructor is not run. > > Roger, can you file another RFE for this for repo-valhalla and I can try to figure out how to best to do this? Or I can. I didn't think the valhalla isIdentityClass() code was expensive to call. Created [JDK-8364447](https://bugs.openjdk.org/browse/JDK-8364447) ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26517#discussion_r2245695722 From missa at openjdk.org Thu Jul 31 21:27:55 2025 From: missa at openjdk.org (Mohamed Issa) Date: Thu, 31 Jul 2025 21:27:55 GMT Subject: RFR: 8360559: Optimize Math.sinh for x86 64 bit platforms [v2] In-Reply-To: References: <9pe9LuUrBnk6A2TQ2emhgonljAvnJLcmSV_lEbrYIlo=.fec9b081-d6ae-4d85-8826-489828d9f442@github.com> Message-ID: On Wed, 30 Jul 2025 18:26:22 GMT, Sandhya Viswanathan wrote: >> Mohamed Issa has updated the pull request incrementally with one additional commit since the last revision: >> >> Move error bound to separate section in comment header > > src/hotspot/cpu/x86/stubGenerator_x86_64_sinh.cpp line 325: > >> 323: __ jcc(Assembler::aboveEqual, L_2TAG_PACKET_0_0_2); // Branch only if |x| is not in [23/64, 3*2^8) >> 324: __ movsd(xmm3, ExternalAddress(HALFMASK), r11 /*rscratch*/); >> 325: __ movsd(xmm1, ExternalAddress(L2E), r11 /*rscratch*/); > > xmm1 is used at L_2TAG_PACKET_0_0_2 -> L_2TAG_PACKET_3_0_2 line 507 below so should be loaded prior to L_2TAG_PACKET_0_0_2. At the end of L_2TAG_PACKET_3_0_2, the goal is to generate +/- Infinity and set the overflow flag, so the L2E load into xmm1 actually doesn't matter in this case. I'll move the load to ensure xmm1 is initialized with a known value before it's used though. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26152#discussion_r2246405871 From missa at openjdk.org Thu Jul 31 21:32:16 2025 From: missa at openjdk.org (Mohamed Issa) Date: Thu, 31 Jul 2025 21:32:16 GMT Subject: RFR: 8360559: Optimize Math.sinh for x86 64 bit platforms [v3] In-Reply-To: References: Message-ID: <_c3ITcxrb66Z6Bq4dJc5uHhPFawXXfhyOhscoGicO3k=.2214b54a-c875-41be-936c-550efd649b91@github.com> > The goal of this PR is to implement an x86_64 intrinsic for java.lang.Math.sinh() using libm. There is a new set of micro-benchmarks are included to check the performance of specific input value ranges to help prevent regressions in the future. > > The command to run all range specific micro-benchmarks is posted below. > > `make test TEST="micro:SinhPerf.SinhPerfRanges"` > > The results of all tests posted below were captured with an [Intel? Xeon 8488C](https://advisor.cloudzero.com/aws/ec2/r7i.metal-24xl) using [OpenJDK v26-b4](https://github.com/openjdk/jdk/releases/tag/jdk-26%2B4) as the baseline version. > > For performance data collected with the new built in range micro-benchmark, see the table below. Each result is the mean of 8 individual runs, and the input ranges used match those from the original Java implementation. Overall, the intrinsic provides an an average uplift of 64% when input values fall into the middle three ranges where heavy computation is required. However, very small inputs and very large inputs show drops of 74% and 66% respectively. > > | Input range(s) | Baseline throughput (ops/ms) | Intrinsic throughput (ops/ms) | Speedup | > | :------------------------------------: | :-------------------------------: | :--------------------------------: | :--------: | > | [-2^(-28), 2^(-28)] | 844160 | 216029 | 0.26x | > | [-22, -2^(-28)], [2^(-28), 22] | 81662 | 157351 | 1.93x | > | [-709.78, -22], [22, 709.78] | 119075 | 167635 | 1.41x | > | [-710.48, -709.78], [709.78, 710.48] | 111636 | 177125 | 1.59x | > | (-INF, -710.48], [710.48, INF) | 959296 | 313839 | 0.33x | > > Finally, the `jtreg:test/jdk/java/lang/Math/HyperbolicTests.java` test passed with the changes. Mohamed Issa has updated the pull request incrementally with one additional commit since the last revision: Make sure xmm1 is initialized before potential use in L_2TAG_PACKET_3_0_2 ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26152/files - new: https://git.openjdk.org/jdk/pull/26152/files/c0adc8b3..3ab7ab3e Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26152&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26152&range=01-02 Stats: 2 lines in 1 file changed: 1 ins; 1 del; 0 mod Patch: https://git.openjdk.org/jdk/pull/26152.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26152/head:pull/26152 PR: https://git.openjdk.org/jdk/pull/26152 From sviswanathan at openjdk.org Thu Jul 31 23:03:55 2025 From: sviswanathan at openjdk.org (Sandhya Viswanathan) Date: Thu, 31 Jul 2025 23:03:55 GMT Subject: RFR: 8360559: Optimize Math.sinh for x86 64 bit platforms [v3] In-Reply-To: <_c3ITcxrb66Z6Bq4dJc5uHhPFawXXfhyOhscoGicO3k=.2214b54a-c875-41be-936c-550efd649b91@github.com> References: <_c3ITcxrb66Z6Bq4dJc5uHhPFawXXfhyOhscoGicO3k=.2214b54a-c875-41be-936c-550efd649b91@github.com> Message-ID: On Thu, 31 Jul 2025 21:32:16 GMT, Mohamed Issa wrote: >> The goal of this PR is to implement an x86_64 intrinsic for java.lang.Math.sinh() using libm. There is a new set of micro-benchmarks are included to check the performance of specific input value ranges to help prevent regressions in the future. >> >> The command to run all range specific micro-benchmarks is posted below. >> >> `make test TEST="micro:SinhPerf.SinhPerfRanges"` >> >> The results of all tests posted below were captured with an [Intel? Xeon 8488C](https://advisor.cloudzero.com/aws/ec2/r7i.metal-24xl) using [OpenJDK v26-b4](https://github.com/openjdk/jdk/releases/tag/jdk-26%2B4) as the baseline version. >> >> For performance data collected with the new built in range micro-benchmark, see the table below. Each result is the mean of 8 individual runs, and the input ranges used match those from the original Java implementation. Overall, the intrinsic provides an an average uplift of 64% when input values fall into the middle three ranges where heavy computation is required. However, very small inputs and very large inputs show drops of 74% and 66% respectively. >> >> | Input range(s) | Baseline throughput (ops/ms) | Intrinsic throughput (ops/ms) | Speedup | >> | :------------------------------------: | :-------------------------------: | :--------------------------------: | :--------: | >> | [-2^(-28), 2^(-28)] | 844160 | 216029 | 0.26x | >> | [-22, -2^(-28)], [2^(-28), 22] | 81662 | 157351 | 1.93x | >> | [-709.78, -22], [22, 709.78] | 119075 | 167635 | 1.41x | >> | [-710.48, -709.78], [709.78, 710.48] | 111636 | 177125 | 1.59x | >> | (-INF, -710.48], [710.48, INF) | 959296 | 313839 | 0.33x | >> >> Finally, the `jtreg:test/jdk/java/lang/Math/HyperbolicTests.java` test passed with the changes. > > Mohamed Issa has updated the pull request incrementally with one additional commit since the last revision: > > Make sure xmm1 is initialized before potential use in L_2TAG_PACKET_3_0_2 Looks good to me. ------------- Marked as reviewed by sviswanathan (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/26152#pullrequestreview-3077118616 From liach at openjdk.org Thu Jul 31 23:34:55 2025 From: liach at openjdk.org (Chen Liang) Date: Thu, 31 Jul 2025 23:34:55 GMT Subject: RFR: 8364187: Make getClassAccessFlagsRaw non-native [v5] In-Reply-To: References: <84FVULnDO38-jO9EcshCFwsOx9PRZ920y8KwTt5z0xU=.6b4b8adb-b046-481f-b121-dd1ffa0d7a78@github.com> Message-ID: <-4Y7tMRv4npz0NHmvNpe4WCP1DSfZwQDMD2uxE36QNE=.8a72f648-6901-4556-9265-ae665992865b@github.com> On Wed, 30 Jul 2025 19:25:34 GMT, Coleen Phillimore wrote: >> This change removes the intrinsic for getClassAccessFlagsRaw for reflection and initializes an rawAccessFlags field in java.lang.Class instead, that Java code can non-natively access. >> Tested with tier1-4. > > Coleen Phillimore has updated the pull request incrementally with one additional commit since the last revision: > > Restore c2 optimization. These changes look reasonable. ------------- Marked as reviewed by liach (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/26517#pullrequestreview-3077160252