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