From prappo at openjdk.org Wed Oct 1 13:26:52 2025 From: prappo at openjdk.org (Pavel Rappo) Date: Wed, 1 Oct 2025 13:26:52 GMT Subject: RFR: 8367704: Fix minor documentation issues in java.time.** [v8] In-Reply-To: References: Message-ID: > Please review this documentation-only change, which I believe does **NOT** require CSR. > > The change touches java.time.** classes that I happen to have been using a lot recently. While the diff is pretty self-describing, here's the summary of what I did: > > * used a comma separator for some big integer values, to improve readability; > * fixed a few typos and grammar. > > While I'm open to discuss the change, I also have some questions. Note: I'm not attempting to address those questions in this PR. > > * What's the significance of the second argument in Duration.between(Temporal, Temporal) being exclusive? For example, would the result of the following call be different if the second argument was inclusive? > > Duration.between(Instant.ofEpochSecond(1), Instant.ofEpochSecond(2)) > > Are there any cases here where that distinction matters? > > * In many cases, the following phrase is used throughout documentation: > > > positive or negative > > While the intent is clearly to stress the directed nature of values, shouldn't we -- for completeness -- also mention zero where applicable? > > * What's the significance of title-case for Java Time-Scale? FWIW, the documentation also uses "Java time-scale". Pavel Rappo 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: - Merge remote-tracking branch 'jdk/master' into java.time - Revert this tiny change "Should" still feels out of place, but it's the same text copied across multiple packages. So it's better to leave it as is. - Remove CSR-triggering changes - An empty commit to kick GHA - Update src/java.base/share/classes/java/time/temporal/ChronoField.java Co-authored-by: Justin Lu - Update copyright years Note: any commit hashes below might be outdated due to subsequent history rewriting (e.g. git rebase). + update src/java.base/share/classes/java/time/package-info.java due to e58c5a4c023 + update src/java.base/share/classes/java/time/temporal/ChronoField.java due to 4d8aadf8754 - A few more typos - Extra typos and decimal separator - Use comma as a decimal separator - Fix Duration.abs - ... and 1 more: https://git.openjdk.org/jdk/compare/6e4fc3db...47c0d45f ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27296/files - new: https://git.openjdk.org/jdk/pull/27296/files/7c4cc716..47c0d45f Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27296&range=07 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27296&range=06-07 Stats: 153876 lines in 1576 files changed: 128305 ins; 14999 del; 10572 mod Patch: https://git.openjdk.org/jdk/pull/27296.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27296/head:pull/27296 PR: https://git.openjdk.org/jdk/pull/27296 From prappo at openjdk.org Wed Oct 1 13:26:54 2025 From: prappo at openjdk.org (Pavel Rappo) Date: Wed, 1 Oct 2025 13:26:54 GMT Subject: RFR: 8367704: Fix minor documentation issues in java.time.** [v7] In-Reply-To: References: Message-ID: On Wed, 17 Sep 2025 16:28:06 GMT, Roger Riggs wrote: >> Pavel Rappo has updated the pull request incrementally with one additional commit since the last revision: >> >> Remove CSR-triggering changes > > Keeping the change to typos removes the necessity of the the CSR. @RogerRiggs, @naotoj, please re-review this PR. If you are okay with that latest trivial change, I will integrate the PR today. Thanks. ------------- PR Comment: https://git.openjdk.org/jdk/pull/27296#issuecomment-3356302262 From rriggs at openjdk.org Wed Oct 1 13:30:50 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Wed, 1 Oct 2025 13:30:50 GMT Subject: RFR: 8368825: Use switch expression for DateTimeFormatterBuilder pattern character lookup [v4] In-Reply-To: References: Message-ID: On Tue, 30 Sep 2025 23:21:32 GMT, Shaojin Wen wrote: >> The DateTimeFormatterBuilder::FIELD_MAP previously used a Map for mapping pattern characters to TemporalField >> instances. This PR refactors that implementation to use a switch expression instead, which eliminates the need to hold a Map in >> memory. >> >> The switch expression approach offers these advantages: >> - No memory overhead for maintaining a HashMap structure >> - More direct character-to-field mapping without hash computation >> - Better code readability and maintainability >> >> This change maintains the same functionality while improving the memory efficiency of pattern character lookup in >> DateTimeFormatterBuilder by eliminating the static Map that was previously used for character-to-field mapping. >> >> * before >> image > > Shaojin Wen has updated the pull request incrementally with one additional commit since the last revision: > > revert comment @liach Marked as reviewed by rriggs (Reviewer). ------------- PR Review: https://git.openjdk.org/jdk/pull/26634#pullrequestreview-3289145865 From rriggs at openjdk.org Wed Oct 1 13:50:29 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Wed, 1 Oct 2025 13:50:29 GMT Subject: RFR: 8367704: Fix minor documentation issues in java.time.** [v8] In-Reply-To: References: Message-ID: On Wed, 1 Oct 2025 13:26:52 GMT, Pavel Rappo wrote: >> Please review this documentation-only change, which I believe does **NOT** require CSR. >> >> The change touches java.time.** classes that I happen to have been using a lot recently. While the diff is pretty self-describing, here's the summary of what I did: >> >> * used a comma separator for some big integer values, to improve readability; >> * fixed a few typos and grammar. >> >> While I'm open to discuss the change, I also have some questions. Note: I'm not attempting to address those questions in this PR. >> >> * What's the significance of the second argument in Duration.between(Temporal, Temporal) being exclusive? For example, would the result of the following call be different if the second argument was inclusive? >> >> Duration.between(Instant.ofEpochSecond(1), Instant.ofEpochSecond(2)) >> >> Are there any cases here where that distinction matters? >> >> * In many cases, the following phrase is used throughout documentation: >> >> > positive or negative >> >> While the intent is clearly to stress the directed nature of values, shouldn't we -- for completeness -- also mention zero where applicable? >> >> * What's the significance of title-case for Java Time-Scale? FWIW, the documentation also uses "Java time-scale". > > Pavel Rappo 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: > > - Merge remote-tracking branch 'jdk/master' into java.time > - Revert this tiny change > > "Should" still feels out of place, but it's the same text > copied across multiple packages. So it's better to leave > it as is. > - Remove CSR-triggering changes > - An empty commit to kick GHA > - Update src/java.base/share/classes/java/time/temporal/ChronoField.java > > Co-authored-by: Justin Lu > - Update copyright years > > Note: any commit hashes below might be outdated due to subsequent > history rewriting (e.g. git rebase). > > + update src/java.base/share/classes/java/time/package-info.java due to e58c5a4c023 > + update src/java.base/share/classes/java/time/temporal/ChronoField.java due to 4d8aadf8754 > - A few more typos > - Extra typos and decimal separator > - Use comma as a decimal separator > - Fix Duration.abs > - ... and 1 more: https://git.openjdk.org/jdk/compare/1bf00fe7...47c0d45f Thanks for the updates. ------------- Marked as reviewed by rriggs (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/27296#pullrequestreview-3289252250 From naoto at openjdk.org Wed Oct 1 15:57:00 2025 From: naoto at openjdk.org (Naoto Sato) Date: Wed, 1 Oct 2025 15:57:00 GMT Subject: RFR: 8368825: Use switch expression for DateTimeFormatterBuilder pattern character lookup [v4] In-Reply-To: References: Message-ID: <03DIrJA3CcONrHoKW1eji6ri8XydMjwxuaDb8Eu8ix4=.a95d8913-2c41-4d02-b53e-63d761fd5966@github.com> On Tue, 30 Sep 2025 23:21:32 GMT, Shaojin Wen wrote: >> The DateTimeFormatterBuilder::FIELD_MAP previously used a Map for mapping pattern characters to TemporalField >> instances. This PR refactors that implementation to use a switch expression instead, which eliminates the need to hold a Map in >> memory. >> >> The switch expression approach offers these advantages: >> - No memory overhead for maintaining a HashMap structure >> - More direct character-to-field mapping without hash computation >> - Better code readability and maintainability >> >> This change maintains the same functionality while improving the memory efficiency of pattern character lookup in >> DateTimeFormatterBuilder by eliminating the static Map that was previously used for character-to-field mapping. >> >> * before >> image > > Shaojin Wen has updated the pull request incrementally with one additional commit since the last revision: > > revert comment @liach Marked as reviewed by naoto (Reviewer). ------------- PR Review: https://git.openjdk.org/jdk/pull/26634#pullrequestreview-3289923824 From naoto at openjdk.org Wed Oct 1 16:02:32 2025 From: naoto at openjdk.org (Naoto Sato) Date: Wed, 1 Oct 2025 16:02:32 GMT Subject: RFR: 8367704: Fix minor documentation issues in java.time.** [v8] In-Reply-To: References: Message-ID: On Wed, 1 Oct 2025 13:26:52 GMT, Pavel Rappo wrote: >> Please review this documentation-only change, which I believe does **NOT** require CSR. >> >> The change touches java.time.** classes that I happen to have been using a lot recently. While the diff is pretty self-describing, here's the summary of what I did: >> >> * used a comma separator for some big integer values, to improve readability; >> * fixed a few typos and grammar. >> >> While I'm open to discuss the change, I also have some questions. Note: I'm not attempting to address those questions in this PR. >> >> * What's the significance of the second argument in Duration.between(Temporal, Temporal) being exclusive? For example, would the result of the following call be different if the second argument was inclusive? >> >> Duration.between(Instant.ofEpochSecond(1), Instant.ofEpochSecond(2)) >> >> Are there any cases here where that distinction matters? >> >> * In many cases, the following phrase is used throughout documentation: >> >> > positive or negative >> >> While the intent is clearly to stress the directed nature of values, shouldn't we -- for completeness -- also mention zero where applicable? >> >> * What's the significance of title-case for Java Time-Scale? FWIW, the documentation also uses "Java time-scale". > > Pavel Rappo 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: > > - Merge remote-tracking branch 'jdk/master' into java.time > - Revert this tiny change > > "Should" still feels out of place, but it's the same text > copied across multiple packages. So it's better to leave > it as is. > - Remove CSR-triggering changes > - An empty commit to kick GHA > - Update src/java.base/share/classes/java/time/temporal/ChronoField.java > > Co-authored-by: Justin Lu > - Update copyright years > > Note: any commit hashes below might be outdated due to subsequent > history rewriting (e.g. git rebase). > > + update src/java.base/share/classes/java/time/package-info.java due to e58c5a4c023 > + update src/java.base/share/classes/java/time/temporal/ChronoField.java due to 4d8aadf8754 > - A few more typos > - Extra typos and decimal separator > - Use comma as a decimal separator > - Fix Duration.abs > - ... and 1 more: https://git.openjdk.org/jdk/compare/8c55a4b1...47c0d45f Marked as reviewed by naoto (Reviewer). ------------- PR Review: https://git.openjdk.org/jdk/pull/27296#pullrequestreview-3289939501 From prappo at openjdk.org Wed Oct 1 16:05:07 2025 From: prappo at openjdk.org (Pavel Rappo) Date: Wed, 1 Oct 2025 16:05:07 GMT Subject: RFR: 8367704: Fix minor documentation issues in java.time.** [v8] In-Reply-To: References: Message-ID: On Wed, 1 Oct 2025 13:26:52 GMT, Pavel Rappo wrote: >> Please review this documentation-only change, which I believe does **NOT** require CSR. >> >> The change touches java.time.** classes that I happen to have been using a lot recently. While the diff is pretty self-describing, here's the summary of what I did: >> >> * used a comma separator for some big integer values, to improve readability; >> * fixed a few typos and grammar. >> >> While I'm open to discuss the change, I also have some questions. Note: I'm not attempting to address those questions in this PR. >> >> * What's the significance of the second argument in Duration.between(Temporal, Temporal) being exclusive? For example, would the result of the following call be different if the second argument was inclusive? >> >> Duration.between(Instant.ofEpochSecond(1), Instant.ofEpochSecond(2)) >> >> Are there any cases here where that distinction matters? >> >> * In many cases, the following phrase is used throughout documentation: >> >> > positive or negative >> >> While the intent is clearly to stress the directed nature of values, shouldn't we -- for completeness -- also mention zero where applicable? >> >> * What's the significance of title-case for Java Time-Scale? FWIW, the documentation also uses "Java time-scale". > > Pavel Rappo 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: > > - Merge remote-tracking branch 'jdk/master' into java.time > - Revert this tiny change > > "Should" still feels out of place, but it's the same text > copied across multiple packages. So it's better to leave > it as is. > - Remove CSR-triggering changes > - An empty commit to kick GHA > - Update src/java.base/share/classes/java/time/temporal/ChronoField.java > > Co-authored-by: Justin Lu > - Update copyright years > > Note: any commit hashes below might be outdated due to subsequent > history rewriting (e.g. git rebase). > > + update src/java.base/share/classes/java/time/package-info.java due to e58c5a4c023 > + update src/java.base/share/classes/java/time/temporal/ChronoField.java due to 4d8aadf8754 > - A few more typos > - Extra typos and decimal separator > - Use comma as a decimal separator > - Fix Duration.abs > - ... and 1 more: https://git.openjdk.org/jdk/compare/6e72c19e...47c0d45f Okay, thanks. Since java.time is not covered by tier1, which is what GHA runs, I did this additionally on my machine: % make test TEST="test/jdk/java/time/" ... ============================== Test summary ============================== TEST TOTAL PASS FAIL ERROR SKIP jtreg:test/jdk/java/time 187 187 0 0 0 ============================== TEST SUCCESS ------------- PR Comment: https://git.openjdk.org/jdk/pull/27296#issuecomment-3357097001 From prappo at openjdk.org Wed Oct 1 16:08:41 2025 From: prappo at openjdk.org (Pavel Rappo) Date: Wed, 1 Oct 2025 16:08:41 GMT Subject: Integrated: 8367704: Fix minor documentation issues in java.time.** In-Reply-To: References: Message-ID: On Mon, 15 Sep 2025 15:17:29 GMT, Pavel Rappo wrote: > Please review this documentation-only change, which I believe does **NOT** require CSR. > > The change touches java.time.** classes that I happen to have been using a lot recently. While the diff is pretty self-describing, here's the summary of what I did: > > * used a comma separator for some big integer values, to improve readability; > * fixed a few typos and grammar. > > While I'm open to discuss the change, I also have some questions. Note: I'm not attempting to address those questions in this PR. > > * What's the significance of the second argument in Duration.between(Temporal, Temporal) being exclusive? For example, would the result of the following call be different if the second argument was inclusive? > > Duration.between(Instant.ofEpochSecond(1), Instant.ofEpochSecond(2)) > > Are there any cases here where that distinction matters? > > * In many cases, the following phrase is used throughout documentation: > > > positive or negative > > While the intent is clearly to stress the directed nature of values, shouldn't we -- for completeness -- also mention zero where applicable? > > * What's the significance of title-case for Java Time-Scale? FWIW, the documentation also uses "Java time-scale". This pull request has now been integrated. Changeset: e44ef0c3 Author: Pavel Rappo URL: https://git.openjdk.org/jdk/commit/e44ef0c32b3c2fcd0a6293838d9185b6d0719219 Stats: 36 lines in 8 files changed: 0 ins; 0 del; 36 mod 8367704: Fix minor documentation issues in java.time.** Reviewed-by: naoto, rriggs ------------- PR: https://git.openjdk.org/jdk/pull/27296 From jlu at openjdk.org Wed Oct 1 18:02:49 2025 From: jlu at openjdk.org (Justin Lu) Date: Wed, 1 Oct 2025 18:02:49 GMT Subject: Integrated: 6177299: [Fmt-Nu] NumberFormat.getPercentInstance() does not work correctly In-Reply-To: References: Message-ID: <7QqLWmbtCXGPM5tYbAacAJekA1DCZ7Mx7L8zJXp6alc=.383938b5-9fe8-479e-a0da-67c95d2c7d02@github.com> On Mon, 29 Sep 2025 21:38:28 GMT, Justin Lu wrote: > Please review this PR which corrects an edge case bug for `DecimalFormat` parsing when a multiplier is applied. > > This issue applies to any parsed Strings whose resultant double value is rounded to _9.223372036854776E18_ after the multiplier is applied. The returned value is incorrectly given as `Long.MAX_VALUE` when it should be returned as the double _9.223372036854776E18_. > > For example, the String _"922,337,203,685,477,600,000%"_ is first parsed as _9.223372036854776E20_, after which the multiplier is then applied to give _9.223372036854776E18_. The original code evaluates `9.223372036854776E18 == (double)(long)9.223372036854776E18` as true, leading to the long representation returned. > > The double value should first be checked if it is within the long min/max range before being checked if it can be represented as a long. Note that the check should be inclusive, as during the comparison, `Long.MAX_VALUE` is promoted to _9.223372036854776E18_. Thus _9.223372036854775E18_ correctly compares as false, and all doubles above compare as true. This pull request has now been integrated. Changeset: 6b72b778 Author: Justin Lu URL: https://git.openjdk.org/jdk/commit/6b72b778039afce0e25986114d15dd29a6786529 Stats: 44 lines in 2 files changed: 40 ins; 0 del; 4 mod 6177299: [Fmt-Nu] NumberFormat.getPercentInstance() does not work correctly Reviewed-by: naoto ------------- PR: https://git.openjdk.org/jdk/pull/27563 From naoto at openjdk.org Wed Oct 1 20:01:58 2025 From: naoto at openjdk.org (Naoto Sato) Date: Wed, 1 Oct 2025 20:01:58 GMT Subject: RFR: 8368845: x-IBM930 uses incorrect character for Hex 42 60 Message-ID: <0Ep8UN3_bJ-nR9RCNIUaRA7flGGV3khNSjstui2ijRk=.d3eb41c7-1bae-4916-9c80-876d5912724f@github.com> Fixing a charset en/decoder for x-IBM930. There was a "temporary" mapping for the said code point for the backward compatibility (as of JDK7). Since the issue requests the "correct" mapping, I believe we can replace the temporary one with the correct mapping. ------------- Commit messages: - initial commit Changes: https://git.openjdk.org/jdk/pull/27594/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=27594&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8368845 Stats: 15 lines in 3 files changed: 0 ins; 13 del; 2 mod Patch: https://git.openjdk.org/jdk/pull/27594.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27594/head:pull/27594 PR: https://git.openjdk.org/jdk/pull/27594 From rriggs at openjdk.org Wed Oct 1 20:19:34 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Wed, 1 Oct 2025 20:19:34 GMT Subject: RFR: 8368172: Make java.time.format.DateTimePrintContext immutable [v4] In-Reply-To: References: <5xcmzM6BhoL-zhBZc_TrRSDCKBrOMqq8bRcmihc1zpU=.732bd228-f9ff-43f0-9771-56645dab6cd2@github.com> Message-ID: On Fri, 26 Sep 2025 04:04:40 GMT, Shaojin Wen wrote: >> I propose to make j.t.f.DateTimePrintContext immutable. >> >> Currently, DateTimePrintContext has only one mutable field, optional. This can be replaced by adding an optional parameter to the DateTimeFormatter.formatTo method. >> >> Immutable DateTimePrintContext can be optimized by escape analysis, such as immutable object optimization. > > Shaojin Wen has updated the pull request incrementally with one additional commit since the last revision: > > add DateTimePrinterParser#withOptional, from @RogerRiggs The necessity to replace the nested PrinterParsers in CompositPrinterParser.withOptional is an ugly feature of the design. At some point, someone will complain about that waste of memory and overhead. Only the composite printer has the static optional attribute. The rest are due to the nesting and it is a reasonable design choice to pass explicitly to each formatter as in cac20038d26a6e836cf427deee8a0942a23acc4d. It would be good to keep the design optional in parsing to be aligned with the PrinterParser design to avoid the designs drifting apart. And the documentation should more completely describe how the static and nested optionality cases are complementary. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26913#issuecomment-3357981670 From jlu at openjdk.org Wed Oct 1 20:43:05 2025 From: jlu at openjdk.org (Justin Lu) Date: Wed, 1 Oct 2025 20:43:05 GMT Subject: RFR: 8368845: x-IBM930 uses incorrect character for Hex 42 60 In-Reply-To: <0Ep8UN3_bJ-nR9RCNIUaRA7flGGV3khNSjstui2ijRk=.d3eb41c7-1bae-4916-9c80-876d5912724f@github.com> References: <0Ep8UN3_bJ-nR9RCNIUaRA7flGGV3khNSjstui2ijRk=.d3eb41c7-1bae-4916-9c80-876d5912724f@github.com> Message-ID: On Wed, 1 Oct 2025 19:50:49 GMT, Naoto Sato wrote: > Fixing a charset en/decoder for x-IBM930. There was a "temporary" mapping for the said code point for the backward compatibility (as of JDK7). Since the issue requests the "correct" mapping, I believe we can replace the temporary one with the correct mapping. Should we add a test to confirm the swap to the new behavior? ------------- PR Comment: https://git.openjdk.org/jdk/pull/27594#issuecomment-3358062301 From naoto at openjdk.org Wed Oct 1 21:06:19 2025 From: naoto at openjdk.org (Naoto Sato) Date: Wed, 1 Oct 2025 21:06:19 GMT Subject: RFR: 8368845: x-IBM930 uses incorrect character for Hex 42 60 [v2] In-Reply-To: <0Ep8UN3_bJ-nR9RCNIUaRA7flGGV3khNSjstui2ijRk=.d3eb41c7-1bae-4916-9c80-876d5912724f@github.com> References: <0Ep8UN3_bJ-nR9RCNIUaRA7flGGV3khNSjstui2ijRk=.d3eb41c7-1bae-4916-9c80-876d5912724f@github.com> Message-ID: > Fixing a charset en/decoder for x-IBM930. There was a "temporary" mapping for the said code point for the backward compatibility (as of JDK7). Since the issue requests the "correct" mapping, I believe we can replace the temporary one with the correct mapping. Naoto Sato has updated the pull request incrementally with one additional commit since the last revision: added bugid to the tests ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27594/files - new: https://git.openjdk.org/jdk/pull/27594/files/bd338444..30ba5ce5 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27594&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27594&range=00-01 Stats: 7 lines in 3 files changed: 1 ins; 0 del; 6 mod Patch: https://git.openjdk.org/jdk/pull/27594.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27594/head:pull/27594 PR: https://git.openjdk.org/jdk/pull/27594 From naoto at openjdk.org Wed Oct 1 21:06:21 2025 From: naoto at openjdk.org (Naoto Sato) Date: Wed, 1 Oct 2025 21:06:21 GMT Subject: RFR: 8368845: x-IBM930 uses incorrect character for Hex 42 60 In-Reply-To: References: <0Ep8UN3_bJ-nR9RCNIUaRA7flGGV3khNSjstui2ijRk=.d3eb41c7-1bae-4916-9c80-876d5912724f@github.com> Message-ID: On Wed, 1 Oct 2025 20:40:39 GMT, Justin Lu wrote: > Should we add a test to confirm the swap to the new behavior? I had added the test data for the new mapping (Cp930.b2c) which is used for several test cases. Added the bug id to the relevant tests which should make it clearer. ------------- PR Comment: https://git.openjdk.org/jdk/pull/27594#issuecomment-3358124998 From jlu at openjdk.org Wed Oct 1 21:17:37 2025 From: jlu at openjdk.org (Justin Lu) Date: Wed, 1 Oct 2025 21:17:37 GMT Subject: RFR: 8368981: Case Fold Locale Legacy Tags On Demand Message-ID: Please review this PR which case folds grandfathered BCP47 tags on demand. (Instead of keeping the case compliant versions stored.) This facilitates the cleanup of the `LEGACY` map (which contains a String to String Array mapping). The 2D String array, creation and populating of the `LEGACY` map, as well as lower case folding of the legacy tags can now be removed from the static block of _sun.util.locale.LanguageTag_. Legacy tags are a small subset compared to the entire set of valid BCP47 tags. Reducing the cost for supporting them would be ideal. Instead, legacy tags can now be checked against and folded on demand via a switch statement. The commented grandfathered syntax is removed because the values themselves already exist as code, and the exact case can be found in the provided RFC link. ------------- Commit messages: - Bolstering case folding test cases for legacy tags - inline 'potentialLegacy' and 'modern' - init Changes: https://git.openjdk.org/jdk/pull/27596/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=27596&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8368981 Stats: 208 lines in 2 files changed: 100 ins; 90 del; 18 mod Patch: https://git.openjdk.org/jdk/pull/27596.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27596/head:pull/27596 PR: https://git.openjdk.org/jdk/pull/27596 From naoto at openjdk.org Wed Oct 1 22:05:47 2025 From: naoto at openjdk.org (Naoto Sato) Date: Wed, 1 Oct 2025 22:05:47 GMT Subject: RFR: 8368981: Case Fold Locale Legacy Tags On Demand In-Reply-To: References: Message-ID: On Wed, 1 Oct 2025 21:11:53 GMT, Justin Lu wrote: > Please review this PR which case folds grandfathered BCP47 tags on demand. (Instead of keeping the case compliant versions stored.) > > This facilitates the cleanup of the `LEGACY` map (which contains a String to String Array mapping). The 2D String array, creation and populating of the `LEGACY` map, as well as lower case folding of the legacy tags can now be removed from the static block of _sun.util.locale.LanguageTag_. > > Legacy tags are a small subset compared to the entire set of valid BCP47 tags. Reducing the cost for supporting them would be ideal. Instead, legacy tags can now be checked against and folded on demand via a switch statement. > > The commented grandfathered syntax is removed because the values themselves already exist as code, and the exact case can be found in the provided RFC link. Looks good. Some minor comments follow src/java.base/share/classes/sun/util/locale/LanguageTag.java line 111: > 109: > 110: // Check if the tag is a legacy tag > 111: var modern = legacyToModern(LocaleUtils.toLowerString(languageTag)); I'd use "preferred" instead of "modern", as it is used in the RFC. test/jdk/java/util/Locale/CaseFoldLanguageTagTest.java line 112: > 110: "zh-guoyu", > 111: "i-pwn", > 112: "i-mingo" Is this intentionally randomized? Otherwise I would like it to be sorted. ------------- PR Review: https://git.openjdk.org/jdk/pull/27596#pullrequestreview-3291289066 PR Review Comment: https://git.openjdk.org/jdk/pull/27596#discussion_r2396010744 PR Review Comment: https://git.openjdk.org/jdk/pull/27596#discussion_r2396013611 From jlu at openjdk.org Wed Oct 1 22:51:30 2025 From: jlu at openjdk.org (Justin Lu) Date: Wed, 1 Oct 2025 22:51:30 GMT Subject: RFR: 8368981: Case Fold Locale Legacy Tags On Demand [v2] In-Reply-To: References: Message-ID: > Please review this PR which case folds grandfathered BCP47 tags on demand. (Instead of keeping the case compliant versions stored.) > > This facilitates the cleanup of the `LEGACY` map (which contains a String to String Array mapping). The 2D String array, creation and populating of the `LEGACY` map, as well as lower case folding of the legacy tags can now be removed from the static block of _sun.util.locale.LanguageTag_. > > Legacy tags are a small subset compared to the entire set of valid BCP47 tags. Reducing the cost for supporting them would be ideal. Instead, legacy tags can now be checked against and folded on demand via a switch statement. > > The commented grandfathered syntax is removed because the values themselves already exist as code, and the exact case can be found in the provided RFC link. Justin Lu has updated the pull request incrementally with one additional commit since the last revision: implemenet Naoto's review ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27596/files - new: https://git.openjdk.org/jdk/pull/27596/files/710d7737..3720e24a Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27596&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27596&range=00-01 Stats: 40 lines in 2 files changed: 15 ins; 15 del; 10 mod Patch: https://git.openjdk.org/jdk/pull/27596.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27596/head:pull/27596 PR: https://git.openjdk.org/jdk/pull/27596 From jlu at openjdk.org Wed Oct 1 22:51:30 2025 From: jlu at openjdk.org (Justin Lu) Date: Wed, 1 Oct 2025 22:51:30 GMT Subject: RFR: 8368981: Case Fold Locale Legacy Tags On Demand [v2] In-Reply-To: References: Message-ID: <0ERKiGbLdQe_k6CuJMiS877HpgA1gAQ1nyOwXEybFCo=.a6837f5f-c6ad-4f81-9196-0c5ea2cf858c@github.com> On Wed, 1 Oct 2025 22:02:11 GMT, Naoto Sato wrote: >> Justin Lu has updated the pull request incrementally with one additional commit since the last revision: >> >> implemenet Naoto's review > > test/jdk/java/util/Locale/CaseFoldLanguageTagTest.java line 112: > >> 110: "zh-guoyu", >> 111: "i-pwn", >> 112: "i-mingo" > > Is this intentionally randomized? Otherwise I would like it to be sorted. No reason, just the order of what `entrySet()` gave me. It is now sorted. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27596#discussion_r2396112656 From naoto at openjdk.org Wed Oct 1 23:06:49 2025 From: naoto at openjdk.org (Naoto Sato) Date: Wed, 1 Oct 2025 23:06:49 GMT Subject: RFR: 8368981: Case Fold Locale Legacy Tags On Demand [v2] In-Reply-To: References: Message-ID: On Wed, 1 Oct 2025 22:51:30 GMT, Justin Lu wrote: >> Please review this PR which case folds grandfathered BCP47 tags on demand. (Instead of keeping the case compliant versions stored.) >> >> This facilitates the cleanup of the `LEGACY` map (which contains a String to String Array mapping). The 2D String array, creation and populating of the `LEGACY` map, as well as lower case folding of the legacy tags can now be removed from the static block of _sun.util.locale.LanguageTag_. >> >> Legacy tags are a small subset compared to the entire set of valid BCP47 tags. Reducing the cost for supporting them would be ideal. Instead, legacy tags can now be checked against and folded on demand via a switch statement. >> >> The commented grandfathered syntax is removed because the values themselves already exist as code, and the exact case can be found in the provided RFC link. > > Justin Lu has updated the pull request incrementally with one additional commit since the last revision: > > implemenet Naoto's review LGTM. Thanks for removing the (almost) unnecessary static initialization ------------- Marked as reviewed by naoto (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/27596#pullrequestreview-3291472147 From swen at openjdk.org Thu Oct 2 02:17:31 2025 From: swen at openjdk.org (Shaojin Wen) Date: Thu, 2 Oct 2025 02:17:31 GMT Subject: RFR: 8368172: Make java.time.format.DateTimePrintContext immutable [v5] In-Reply-To: <5xcmzM6BhoL-zhBZc_TrRSDCKBrOMqq8bRcmihc1zpU=.732bd228-f9ff-43f0-9771-56645dab6cd2@github.com> References: <5xcmzM6BhoL-zhBZc_TrRSDCKBrOMqq8bRcmihc1zpU=.732bd228-f9ff-43f0-9771-56645dab6cd2@github.com> Message-ID: > I propose to make j.t.f.DateTimePrintContext immutable. > > Currently, DateTimePrintContext has only one mutable field, optional. This can be replaced by adding an optional parameter to the DateTimeFormatter.formatTo method. > > Immutable DateTimePrintContext can be optimized by escape analysis, such as immutable object optimization. Shaojin Wen has updated the pull request incrementally with one additional commit since the last revision: Revert "add DateTimePrinterParser#withOptional, from @RogerRiggs" This reverts commit 558fa46fa30093ff07e05e30a44ca0a86472e72e. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26913/files - new: https://git.openjdk.org/jdk/pull/26913/files/558fa46f..5a7e2316 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26913&range=04 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26913&range=03-04 Stats: 322 lines in 2 files changed: 2 ins; 242 del; 78 mod Patch: https://git.openjdk.org/jdk/pull/26913.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26913/head:pull/26913 PR: https://git.openjdk.org/jdk/pull/26913 From swen at openjdk.org Thu Oct 2 03:08:32 2025 From: swen at openjdk.org (Shaojin Wen) Date: Thu, 2 Oct 2025 03:08:32 GMT Subject: RFR: 8368172: Make java.time.format.DateTimePrintContext immutable [v6] In-Reply-To: <5xcmzM6BhoL-zhBZc_TrRSDCKBrOMqq8bRcmihc1zpU=.732bd228-f9ff-43f0-9771-56645dab6cd2@github.com> References: <5xcmzM6BhoL-zhBZc_TrRSDCKBrOMqq8bRcmihc1zpU=.732bd228-f9ff-43f0-9771-56645dab6cd2@github.com> Message-ID: <-MQxYO6i5RCnBQ-1NTwm5GcwucQgqYXIRHlFvsxO17A=.a6846ed0-8cc5-4501-9b94-cafa62a4909e@github.com> > I propose to make j.t.f.DateTimePrintContext immutable. > > Currently, DateTimePrintContext has only one mutable field, optional. This can be replaced by adding an optional parameter to the DateTimeFormatter.formatTo method. > > Immutable DateTimePrintContext can be optimized by escape analysis, such as immutable object optimization. Shaojin Wen has updated the pull request incrementally with one additional commit since the last revision: Improve javadoc for optional parameter in DateTimePrinterParser#format method ------------- Changes: - all: https://git.openjdk.org/jdk/pull/26913/files - new: https://git.openjdk.org/jdk/pull/26913/files/5a7e2316..6b35ea29 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=26913&range=05 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=26913&range=04-05 Stats: 5 lines in 1 file changed: 4 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/26913.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26913/head:pull/26913 PR: https://git.openjdk.org/jdk/pull/26913 From scolebourne at openjdk.org Thu Oct 2 06:57:51 2025 From: scolebourne at openjdk.org (Stephen Colebourne) Date: Thu, 2 Oct 2025 06:57:51 GMT Subject: RFR: 8368825: Use switch expression for DateTimeFormatterBuilder pattern character lookup [v4] In-Reply-To: References: Message-ID: On Tue, 30 Sep 2025 23:21:32 GMT, Shaojin Wen wrote: >> The DateTimeFormatterBuilder::FIELD_MAP previously used a Map for mapping pattern characters to TemporalField >> instances. This PR refactors that implementation to use a switch expression instead, which eliminates the need to hold a Map in >> memory. >> >> The switch expression approach offers these advantages: >> - No memory overhead for maintaining a HashMap structure >> - More direct character-to-field mapping without hash computation >> - Better code readability and maintainability >> >> This change maintains the same functionality while improving the memory efficiency of pattern character lookup in >> DateTimeFormatterBuilder by eliminating the static Map that was previously used for character-to-field mapping. >> >> * before >> image > > Shaojin Wen has updated the pull request incrementally with one additional commit since the last revision: > > revert comment @liach Marked as reviewed by scolebourne (Author). ------------- PR Review: https://git.openjdk.org/jdk/pull/26634#pullrequestreview-3292808879 From rriggs at openjdk.org Thu Oct 2 13:26:52 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Thu, 2 Oct 2025 13:26:52 GMT Subject: RFR: 8368172: Make java.time.format.DateTimePrintContext immutable [v6] In-Reply-To: <-MQxYO6i5RCnBQ-1NTwm5GcwucQgqYXIRHlFvsxO17A=.a6846ed0-8cc5-4501-9b94-cafa62a4909e@github.com> References: <5xcmzM6BhoL-zhBZc_TrRSDCKBrOMqq8bRcmihc1zpU=.732bd228-f9ff-43f0-9771-56645dab6cd2@github.com> <-MQxYO6i5RCnBQ-1NTwm5GcwucQgqYXIRHlFvsxO17A=.a6846ed0-8cc5-4501-9b94-cafa62a4909e@github.com> Message-ID: On Thu, 2 Oct 2025 03:08:32 GMT, Shaojin Wen wrote: >> I propose to make j.t.f.DateTimePrintContext immutable. >> >> Currently, DateTimePrintContext has only one mutable field, optional. This can be replaced by adding an optional parameter to the DateTimeFormatter.formatTo method. >> >> Immutable DateTimePrintContext can be optimized by escape analysis, such as immutable object optimization. > > Shaojin Wen has updated the pull request incrementally with one additional commit since the last revision: > > Improve javadoc for optional parameter in DateTimePrinterParser#format method And one more thought/question: The optionality of formatting is a parameter used in the traversal of the formatting and parsing and affect nested formatting calls. The DateTimePrintContext previously counts the depth of the nesting with >0 indicating optional. It is the component that determines (based on optional:true) whether an absent value throws. Was it considered to change DateTimePrinterContext.optional to `final boolean optional` and create a second instance with optional=true. Only the CompositePrinterParser changes the state to indicate that nested PrinterParsers are optional. CompositePrinterParser could substitute the optional DateTimePrintContext. That would be closer to the current design and if allow it to be immutable. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26913#issuecomment-3361215508 From swen at openjdk.org Thu Oct 2 13:35:14 2025 From: swen at openjdk.org (Shaojin Wen) Date: Thu, 2 Oct 2025 13:35:14 GMT Subject: Integrated: 8368825: Use switch expression for DateTimeFormatterBuilder pattern character lookup In-Reply-To: References: Message-ID: On Tue, 5 Aug 2025 01:42:53 GMT, Shaojin Wen wrote: > The DateTimeFormatterBuilder::FIELD_MAP previously used a Map for mapping pattern characters to TemporalField > instances. This PR refactors that implementation to use a switch expression instead, which eliminates the need to hold a Map in > memory. > > The switch expression approach offers these advantages: > - No memory overhead for maintaining a HashMap structure > - More direct character-to-field mapping without hash computation > - Better code readability and maintainability > > This change maintains the same functionality while improving the memory efficiency of pattern character lookup in > DateTimeFormatterBuilder by eliminating the static Map that was previously used for character-to-field mapping. > > * before > image This pull request has now been integrated. Changeset: 2c7f7380 Author: Shaojin Wen URL: https://git.openjdk.org/jdk/commit/2c7f7380ea828e5ec928e1cb05b13806646ecb3d Stats: 49 lines in 1 file changed: 7 ins; 0 del; 42 mod 8368825: Use switch expression for DateTimeFormatterBuilder pattern character lookup Reviewed-by: rriggs, naoto, scolebourne ------------- PR: https://git.openjdk.org/jdk/pull/26634 From swen at openjdk.org Thu Oct 2 13:39:52 2025 From: swen at openjdk.org (Shaojin Wen) Date: Thu, 2 Oct 2025 13:39:52 GMT Subject: RFR: 8368172: Make java.time.format.DateTimePrintContext immutable [v6] In-Reply-To: References: <5xcmzM6BhoL-zhBZc_TrRSDCKBrOMqq8bRcmihc1zpU=.732bd228-f9ff-43f0-9771-56645dab6cd2@github.com> <-MQxYO6i5RCnBQ-1NTwm5GcwucQgqYXIRHlFvsxO17A=.a6846ed0-8cc5-4501-9b94-cafa62a4909e@github.com> Message-ID: <2vNtq03FnpQvKBx4QnRGZGyilEoIcgHRv_SoxPneE3U=.6e1c2c8f-8a89-482c-b2c6-8484ac6cd64b@github.com> On Thu, 2 Oct 2025 13:24:25 GMT, Roger Riggs wrote: > And one more thought/question: The optionality of formatting is a parameter used in the traversal of the formatting and parsing and affect nested formatting calls. The DateTimePrintContext previously counts the depth of the nesting with >0 indicating optional. It is the component that determines (based on optional:true) whether an absent value throws. Was it considered to change DateTimePrinterContext.optional to `final boolean optional` and create a second instance with optional=true. > > Only the CompositePrinterParser changes the state to indicate that nested PrinterParsers are optional. CompositePrinterParser could substitute the optional DateTimePrintContext. That would be closer to the current design and if allow it to be immutable. It seems strange that the formatting process creates a new DateTimePrintContext object. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26913#issuecomment-3361262924 From rriggs at openjdk.org Thu Oct 2 14:24:23 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Thu, 2 Oct 2025 14:24:23 GMT Subject: RFR: 8368172: Make java.time.format.DateTimePrintContext immutable [v6] In-Reply-To: <-MQxYO6i5RCnBQ-1NTwm5GcwucQgqYXIRHlFvsxO17A=.a6846ed0-8cc5-4501-9b94-cafa62a4909e@github.com> References: <5xcmzM6BhoL-zhBZc_TrRSDCKBrOMqq8bRcmihc1zpU=.732bd228-f9ff-43f0-9771-56645dab6cd2@github.com> <-MQxYO6i5RCnBQ-1NTwm5GcwucQgqYXIRHlFvsxO17A=.a6846ed0-8cc5-4501-9b94-cafa62a4909e@github.com> Message-ID: On Thu, 2 Oct 2025 03:08:32 GMT, Shaojin Wen wrote: >> I propose to make j.t.f.DateTimePrintContext immutable. >> >> Currently, DateTimePrintContext has only one mutable field, optional. This can be replaced by adding an optional parameter to the DateTimeFormatter.formatTo method. >> >> Immutable DateTimePrintContext can be optimized by escape analysis, such as immutable object optimization. > > Shaojin Wen has updated the pull request incrementally with one additional commit since the last revision: > > Improve javadoc for optional parameter in DateTimePrinterParser#format method The DateTimePrintContext is exactly that, providing the context for the formatting. It holds the references to the Temporal that has the value and the appendable that is the destination. And in the committed implementation holds the current optional count/flag. If its is to be immutable, then you need to create a second one and pass it down to/through format(). It will be a small, short lived object. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26913#issuecomment-3361450548 From swen at openjdk.org Thu Oct 2 14:36:17 2025 From: swen at openjdk.org (Shaojin Wen) Date: Thu, 2 Oct 2025 14:36:17 GMT Subject: RFR: 8368172: Make java.time.format.DateTimePrintContext immutable [v6] In-Reply-To: <-MQxYO6i5RCnBQ-1NTwm5GcwucQgqYXIRHlFvsxO17A=.a6846ed0-8cc5-4501-9b94-cafa62a4909e@github.com> References: <5xcmzM6BhoL-zhBZc_TrRSDCKBrOMqq8bRcmihc1zpU=.732bd228-f9ff-43f0-9771-56645dab6cd2@github.com> <-MQxYO6i5RCnBQ-1NTwm5GcwucQgqYXIRHlFvsxO17A=.a6846ed0-8cc5-4501-9b94-cafa62a4909e@github.com> Message-ID: On Thu, 2 Oct 2025 03:08:32 GMT, Shaojin Wen wrote: >> I propose to make j.t.f.DateTimePrintContext immutable. >> >> Currently, DateTimePrintContext has only one mutable field, optional. This can be replaced by adding an optional parameter to the DateTimeFormatter.formatTo method. >> >> Immutable DateTimePrintContext can be optimized by escape analysis, such as immutable object optimization. > > Shaojin Wen has updated the pull request incrementally with one additional commit since the last revision: > > Improve javadoc for optional parameter in DateTimePrinterParser#format method Creating a DateTimePrintContext during the formatting process also has a disadvantage: it is difficult to perform manual unrolling performance optimizations like the draft PR #26807 I submitted, and it also makes automatic unrolling by the C2 JIT more difficult. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26913#issuecomment-3361498045 From rriggs at openjdk.org Thu Oct 2 15:05:59 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Thu, 2 Oct 2025 15:05:59 GMT Subject: RFR: 8368981: Case Fold Locale Legacy Tags On Demand [v2] In-Reply-To: References: Message-ID: On Wed, 1 Oct 2025 22:51:30 GMT, Justin Lu wrote: >> Please review this PR which case folds grandfathered BCP47 tags on demand. (Instead of keeping the case compliant versions stored.) >> >> This facilitates the cleanup of the `LEGACY` map (which contains a String to String Array mapping). The 2D String array, creation and populating of the `LEGACY` map, as well as lower case folding of the legacy tags can now be removed from the static block of _sun.util.locale.LanguageTag_. >> >> Legacy tags are a small subset compared to the entire set of valid BCP47 tags. Reducing the cost for supporting them would be ideal. Instead, legacy tags can now be checked against and folded on demand via a switch statement. >> >> The commented grandfathered syntax is removed because the values themselves already exist as code, and the exact case can be found in the provided RFC link. > > Justin Lu has updated the pull request incrementally with one additional commit since the last revision: > > implemenet Naoto's review src/java.base/share/classes/sun/util/locale/LanguageTag.java line 345: > 343: } > 344: } > 345: bldr.deleteCharAt(bldr.length() - 1); // Remove trailing '-' `bldr.setLength(bldr.length() - 1)` might be better? src/java.base/share/classes/sun/util/locale/LanguageTag.java line 516: > 514: if (tag.length() > 11 || tag.length() < 5) { > 515: return null; > 516: } I can see the < 5 having some saving if most of the tags are short. I doubt the > 11 saves anything and it creates a maintenance gotcha, if a tag is added that is longer. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27596#discussion_r2399143786 PR Review Comment: https://git.openjdk.org/jdk/pull/27596#discussion_r2399105662 From rriggs at openjdk.org Thu Oct 2 15:13:24 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Thu, 2 Oct 2025 15:13:24 GMT Subject: RFR: 8368172: Make java.time.format.DateTimePrintContext immutable [v6] In-Reply-To: <-MQxYO6i5RCnBQ-1NTwm5GcwucQgqYXIRHlFvsxO17A=.a6846ed0-8cc5-4501-9b94-cafa62a4909e@github.com> References: <5xcmzM6BhoL-zhBZc_TrRSDCKBrOMqq8bRcmihc1zpU=.732bd228-f9ff-43f0-9771-56645dab6cd2@github.com> <-MQxYO6i5RCnBQ-1NTwm5GcwucQgqYXIRHlFvsxO17A=.a6846ed0-8cc5-4501-9b94-cafa62a4909e@github.com> Message-ID: On Thu, 2 Oct 2025 03:08:32 GMT, Shaojin Wen wrote: >> I propose to make j.t.f.DateTimePrintContext immutable. >> >> Currently, DateTimePrintContext has only one mutable field, optional. This can be replaced by adding an optional parameter to the DateTimeFormatter.formatTo method. >> >> Immutable DateTimePrintContext can be optimized by escape analysis, such as immutable object optimization. > > Shaojin Wen has updated the pull request incrementally with one additional commit since the last revision: > > Improve javadoc for optional parameter in DateTimePrinterParser#format method I beginning to get concerned about the bloat in code cache created by this line of inquiry in the quest for microbenchmark performance. In cloud deployments, extra memory costs money. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26913#issuecomment-3361663586 From naoto at openjdk.org Thu Oct 2 16:08:33 2025 From: naoto at openjdk.org (Naoto Sato) Date: Thu, 2 Oct 2025 16:08:33 GMT Subject: RFR: 8368981: Case Fold Locale Legacy Tags On Demand [v2] In-Reply-To: References: Message-ID: On Thu, 2 Oct 2025 14:52:20 GMT, Roger Riggs wrote: >> Justin Lu has updated the pull request incrementally with one additional commit since the last revision: >> >> implemenet Naoto's review > > src/java.base/share/classes/sun/util/locale/LanguageTag.java line 516: > >> 514: if (tag.length() > 11 || tag.length() < 5) { >> 515: return null; >> 516: } > > I can see the < 5 having some saving if most of the tags are short. > I doubt the > 11 saves anything and it creates a maintenance gotcha, if a tag is added that is longer. Per RFC, it is guaranteed that the list of the grandfathered (=legacy) tags will never change (https://datatracker.ietf.org/doc/html/rfc5646#section-2.1) ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27596#discussion_r2399329170 From jlu at openjdk.org Thu Oct 2 16:58:41 2025 From: jlu at openjdk.org (Justin Lu) Date: Thu, 2 Oct 2025 16:58:41 GMT Subject: RFR: 8368981: Case Fold Locale Legacy Tags On Demand [v3] In-Reply-To: References: Message-ID: > Please review this PR which case folds grandfathered BCP47 tags on demand. (Instead of keeping the case compliant versions stored.) > > This facilitates the cleanup of the `LEGACY` map (which contains a String to String Array mapping). The 2D String array, creation and populating of the `LEGACY` map, as well as lower case folding of the legacy tags can now be removed from the static block of _sun.util.locale.LanguageTag_. > > Legacy tags are a small subset compared to the entire set of valid BCP47 tags. Reducing the cost for supporting them would be ideal. Instead, legacy tags can now be checked against and folded on demand via a switch statement. > > The commented grandfathered syntax is removed because the values themselves already exist as code, and the exact case can be found in the provided RFC link. Justin Lu has updated the pull request incrementally with one additional commit since the last revision: Implement Roger's review ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27596/files - new: https://git.openjdk.org/jdk/pull/27596/files/3720e24a..fb6b1dcc Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27596&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27596&range=01-02 Stats: 2 lines in 1 file changed: 0 ins; 0 del; 2 mod Patch: https://git.openjdk.org/jdk/pull/27596.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27596/head:pull/27596 PR: https://git.openjdk.org/jdk/pull/27596 From jlu at openjdk.org Thu Oct 2 16:58:43 2025 From: jlu at openjdk.org (Justin Lu) Date: Thu, 2 Oct 2025 16:58:43 GMT Subject: RFR: 8368981: Case Fold Locale Legacy Tags On Demand [v2] In-Reply-To: References: Message-ID: On Thu, 2 Oct 2025 16:06:07 GMT, Naoto Sato wrote: >> src/java.base/share/classes/sun/util/locale/LanguageTag.java line 516: >> >>> 514: if (tag.length() > 11 || tag.length() < 5) { >>> 515: return null; >>> 516: } >> >> I can see the < 5 having some saving if most of the tags are short. >> I doubt the > 11 saves anything and it creates a maintenance gotcha, if a tag is added that is longer. > > Per RFC, it is guaranteed that the list of the grandfathered (=legacy) tags will never change (https://datatracker.ietf.org/doc/html/rfc5646#section-2.1) Right, the reason we can have confidence in this shortcut check is that the list is specified to be stable. However, if there is likely no save on cost, then we can remove it. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27596#discussion_r2399453184 From rriggs at openjdk.org Thu Oct 2 19:49:47 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Thu, 2 Oct 2025 19:49:47 GMT Subject: RFR: 8368981: Case Fold Locale Legacy Tags On Demand [v3] In-Reply-To: References: Message-ID: On Thu, 2 Oct 2025 16:58:41 GMT, Justin Lu wrote: >> Please review this PR which case folds grandfathered BCP47 tags on demand. (Instead of keeping the case compliant versions stored.) >> >> This facilitates the cleanup of the `LEGACY` map (which contains a String to String Array mapping). The 2D String array, creation and populating of the `LEGACY` map, as well as lower case folding of the legacy tags can now be removed from the static block of _sun.util.locale.LanguageTag_. >> >> Legacy tags are a small subset compared to the entire set of valid BCP47 tags. Reducing the cost for supporting them would be ideal. Instead, legacy tags can now be checked against and folded on demand via a switch statement. >> >> The commented grandfathered syntax is removed because the values themselves already exist as code, and the exact case can be found in the provided RFC link. > > Justin Lu has updated the pull request incrementally with one additional commit since the last revision: > > Implement Roger's review LGTM ------------- Marked as reviewed by rriggs (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/27596#pullrequestreview-3296165026 From swen at openjdk.org Fri Oct 3 09:10:46 2025 From: swen at openjdk.org (Shaojin Wen) Date: Fri, 3 Oct 2025 09:10:46 GMT Subject: RFR: 8368172: Make java.time.format.DateTimePrintContext immutable [v6] In-Reply-To: References: <5xcmzM6BhoL-zhBZc_TrRSDCKBrOMqq8bRcmihc1zpU=.732bd228-f9ff-43f0-9771-56645dab6cd2@github.com> <-MQxYO6i5RCnBQ-1NTwm5GcwucQgqYXIRHlFvsxO17A=.a6846ed0-8cc5-4501-9b94-cafa62a4909e@github.com> Message-ID: <_6CJOczFmBqEl2qBXgJEYoj3jc9RxAfhN-ieR92zRAw=.0fc6f1e5-5653-4ca4-8db5-58a860002e04@github.com> On Thu, 2 Oct 2025 15:11:05 GMT, Roger Riggs wrote: > I beginning to get concerned about the bloat in code cache created by this line of inquiry in the quest for microbenchmark performance. In cloud deployments, extra memory costs money. When the CodeCache memory space is insufficient, the JIT will discard the oldest compiled methods that are not currently in the execution stack; I think we don't need to worry about this. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26913#issuecomment-3364888865 From prappo at openjdk.org Fri Oct 3 09:50:23 2025 From: prappo at openjdk.org (Pavel Rappo) Date: Fri, 3 Oct 2025 09:50:23 GMT Subject: RFR: 8366829: Add constants for the Duration MIN/MAX values [v3] In-Reply-To: References: Message-ID: > We have [recently discussed][] a possibility of adding the `Duration.MIN` and `Duration.MAX` constants. Can we now start implementation? If and when we are in agreement on this PR, I will file a CSR. > > I drafted a minimal specification and added some tests. I tried to phrase the spec for `Duration.MIN` in a way that makes it clear that `Duration.MIN` is the most negative value and not the least positive. > > [recently discussed]: https://mail.openjdk.org/pipermail/core-libs-dev/2025-September/151098.html Pavel Rappo has updated the pull request incrementally with one additional commit since the last revision: Respond to feedback Apply Stephen's suggestion on wording, although modified. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27534/files - new: https://git.openjdk.org/jdk/pull/27534/files/c5a3f228..abe01ff5 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27534&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27534&range=01-02 Stats: 18 lines in 1 file changed: 2 ins; 1 del; 15 mod Patch: https://git.openjdk.org/jdk/pull/27534.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27534/head:pull/27534 PR: https://git.openjdk.org/jdk/pull/27534 From jlu at openjdk.org Fri Oct 3 16:28:56 2025 From: jlu at openjdk.org (Justin Lu) Date: Fri, 3 Oct 2025 16:28:56 GMT Subject: RFR: 8368981: Case Fold Locale Legacy Tags On Demand [v3] In-Reply-To: References: Message-ID: <8vPRllD5nujUmTtZsCiC-AhlBVi1G_DCFuXVQT4biTo=.e39d8ddf-9ba5-4447-bfbb-c10c60c61b69@github.com> On Thu, 2 Oct 2025 16:58:41 GMT, Justin Lu wrote: >> Please review this PR which case folds grandfathered BCP47 tags on demand. (Instead of keeping the case compliant versions stored.) >> >> This facilitates the cleanup of the `LEGACY` map (which contains a String to String Array mapping). The 2D String array, creation and populating of the `LEGACY` map, as well as lower case folding of the legacy tags can now be removed from the static block of _sun.util.locale.LanguageTag_. >> >> Legacy tags are a small subset compared to the entire set of valid BCP47 tags. Reducing the cost for supporting them would be ideal. Instead, legacy tags can now be checked against and folded on demand via a switch statement. >> >> The commented grandfathered syntax is removed because the values themselves already exist as code, and the exact case can be found in the provided RFC link. > > Justin Lu has updated the pull request incrementally with one additional commit since the last revision: > > Implement Roger's review Thank you for the reviews! ------------- PR Comment: https://git.openjdk.org/jdk/pull/27596#issuecomment-3366355891 From jlu at openjdk.org Fri Oct 3 16:28:57 2025 From: jlu at openjdk.org (Justin Lu) Date: Fri, 3 Oct 2025 16:28:57 GMT Subject: Integrated: 8368981: Case Fold Locale Legacy Tags On Demand In-Reply-To: References: Message-ID: <2t4pwt6e4uOa9YOGmOoNeUmM0vmxrwSq5gatLH2lKMM=.eea1f7b4-504d-4891-95d9-05e8fca18eea@github.com> On Wed, 1 Oct 2025 21:11:53 GMT, Justin Lu wrote: > Please review this PR which case folds grandfathered BCP47 tags on demand. (Instead of keeping the case compliant versions stored.) > > This facilitates the cleanup of the `LEGACY` map (which contains a String to String Array mapping). The 2D String array, creation and populating of the `LEGACY` map, as well as lower case folding of the legacy tags can now be removed from the static block of _sun.util.locale.LanguageTag_. > > Legacy tags are a small subset compared to the entire set of valid BCP47 tags. Reducing the cost for supporting them would be ideal. Instead, legacy tags can now be checked against and folded on demand via a switch statement. > > The commented grandfathered syntax is removed because the values themselves already exist as code, and the exact case can be found in the provided RFC link. This pull request has now been integrated. Changeset: 23a65644 Author: Justin Lu URL: https://git.openjdk.org/jdk/commit/23a65644ae63b271ca99c55a2a60a192c4e4dfb8 Stats: 208 lines in 2 files changed: 100 ins; 90 del; 18 mod 8368981: Case Fold Locale Legacy Tags On Demand Reviewed-by: rriggs, naoto ------------- PR: https://git.openjdk.org/jdk/pull/27596 From naoto at openjdk.org Fri Oct 3 17:55:52 2025 From: naoto at openjdk.org (Naoto Sato) Date: Fri, 3 Oct 2025 17:55:52 GMT Subject: RFR: 8366829: Add java.time.Duration constants MIN and MAX [v3] In-Reply-To: References: Message-ID: On Fri, 3 Oct 2025 09:50:23 GMT, Pavel Rappo wrote: >> We have [recently discussed][] a possibility of adding the `Duration.MIN` and `Duration.MAX` constants. Can we now start implementation? If and when we are in agreement on this PR, I will file a CSR. >> >> I drafted a minimal specification and added some tests. I tried to phrase the spec for `Duration.MIN` in a way that makes it clear that `Duration.MIN` is the most negative value and not the least positive. >> >> [recently discussed]: https://mail.openjdk.org/pipermail/core-libs-dev/2025-September/151098.html > > Pavel Rappo has updated the pull request incrementally with one additional commit since the last revision: > > Respond to feedback > > Apply Stephen's suggestion on wording, although modified. Marked as reviewed by naoto (Reviewer). ------------- PR Review: https://git.openjdk.org/jdk/pull/27534#pullrequestreview-3300200546 From rriggs at openjdk.org Fri Oct 3 18:37:48 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Fri, 3 Oct 2025 18:37:48 GMT Subject: RFR: 8366829: Add java.time.Duration constants MIN and MAX [v3] In-Reply-To: References: Message-ID: On Fri, 3 Oct 2025 09:50:23 GMT, Pavel Rappo wrote: >> We have [recently discussed][] a possibility of adding the `Duration.MIN` and `Duration.MAX` constants. Can we now start implementation? If and when we are in agreement on this PR, I will file a CSR. >> >> I drafted a minimal specification and added some tests. I tried to phrase the spec for `Duration.MIN` in a way that makes it clear that `Duration.MIN` is the most negative value and not the least positive. >> >> [recently discussed]: https://mail.openjdk.org/pipermail/core-libs-dev/2025-September/151098.html > > Pavel Rappo has updated the pull request incrementally with one additional commit since the last revision: > > Respond to feedback > > Apply Stephen's suggestion on wording, although modified. Marked as reviewed by rriggs (Reviewer). ------------- PR Review: https://git.openjdk.org/jdk/pull/27534#pullrequestreview-3300388900 From sherman at openjdk.org Fri Oct 3 19:10:20 2025 From: sherman at openjdk.org (Xueming Shen) Date: Fri, 3 Oct 2025 19:10:20 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support Message-ID: ### Summary Case folding is a key operation for case-insensitive matching (e.g., string equality, regex matching), where the goal is to eliminate case distinctions without applying locale or language specific conversions. Currently, the JDK does not expose a direct API for Unicode-compliant case folding. Developers now rely on methods such as: **String.equalsIgnoreCase(String)** - Unicode-aware, locale-independent. - Implementation uses Character.toLowerCase(Character.toUpperCase(int)) per code point. - Limited: does not support 1:M mapping defined in Unicode case folding. **Character.toLowerCase(int) / Character.toUpperCase(int)** - Locale-independent, single code point only. - No support for 1:M mappings. **String.toLowerCase(Locale.ROOT) / String.toUpperCase(Locale.ROOT)** - Based on Unicode SpecialCasing.txt, supports 1:M mappings. - Intended primarily for presentation/display, not structural case-insensitive matching. - Requires full string conversion before comparison, which is less efficient and not intended for structural matching. **1:M mapping example, U+00DF (?)** - String.toUpperCase(Locale.ROOT, "?") ? "SS" - Case folding produces "ss", matching Unicode caseless comparison rules. jshell> "\u00df".equalsIgnoreCase("ss") $22 ==> false jshell> "\u00df".toUpperCase(Locale.ROOT).toLowerCase(Locale.ROOT).equals("ss") $24 ==> true ### Motivation & Direction Add Unicode standard-compliant case-less comparison methods to the String class, enabling & improving reliable and efficient Unicode-aware/compliant case-insensitive matching. - Unicode-compliant **full** case folding. - Simpler, stable and more efficient case-less matching without workarounds. - Brings Java's string comparison handling in line with other programming languages/libraries. This PR proposes to introduce the following comparison methods in `String` class - boolean equalsFoldCase(String anotherString) - int compareToFoldCase(String anotherString) - Comparator UNICODE_CASEFOLD_ORDER These methods are intended to be the preferred choice when Unicode-compliant case-less matching is required. *Note: An early draft also proposed a String.toCaseFold() method returning a new case-folded string. However, during review this was considered error-prone, as the resulting string could easily be mistaken for a general transformation like toLowerCase() and then passed into APIs where case-folding semantics are not appropriate. ### The New API /** * Compares this {@code String} to another {@code String} for equality, * using Unicode case folding. Two strings are considered equal * by this method if their case-folded forms are identical. *

* Case folding is defined by the Unicode Standard in * CaseFolding.txt, * including 1:M mappings. For example, {@code "Ma?e".equalsFoldCase("MASSE")} * returns {@code true}, since the character {@code U+00DF} (sharp s) folds * to {@code "ss"}. *

* Case folding is locale-independent and language-neutral, unlike * locale-sensitive transformations such as {@link #toLowerCase()} or * {@link #toUpperCase()}. It is intended for caseless matching, * searching, and indexing. * * @apiNote * This method is the Unicode-compliant alternative to * {@link #equalsIgnoreCase(String)}. It implements full case folding as * defined by the Unicode Standard, which may differ from the simpler * per-character mapping performed by {@code equalsIgnoreCase}. * For example: *

{@snippet lang=java :
     * String a = "Ma?e";
     * String b = "MASSE";
     * boolean equalsFoldCase = a.equalsFoldCase(b);       // returns true
     * boolean equalsIgnoreCase = a.equalsIgnoreCase(b);   // returns false
     * }
* * @param anotherString * The {@code String} to compare this {@code String} against * * @return {@code true} if the given object is not {@code null} and represents * the same sequence of characters as this string under Unicode case * folding; {@code false} otherwise. * * @see #compareToFoldCase(String) * @see #equalsIgnoreCase(String) * @since 26 */ public boolean equalsFoldCase(String anotherString) /** * Compares two strings lexicographically using Unicode case folding. * This method returns an integer whose sign is that of calling {@code compareTo} * on the Unicode case folded version of the strings. Unicode Case folding * eliminates differences in case according to the Unicode Standard, using the * mappings defined in * CaseFolding.txt, * including 1:M mappings, such as {@code"?"} ? {@code }"ss"}. *

* Case folding is a locale-independent, language-neutral form of case mapping, * primarily intended for caseless matching. Unlike {@link #compareToIgnoreCase(String)}, * which applies a simpler locale-insensitive uppercase mapping. This method * follows the Unicode full case folding, providing stable and * consistent results across all environments. *

* Note that this method does not take locale into account, and may * produce results that differ from locale-sensitive ordering. Use * {@link java.text.Collator} for locale-sensitive comparison. * * @apiNote * This method is the Unicode-compliant alternative to * {@link #compareToIgnoreCase(String)}. It implements the full case folding * as defined by the Unicode Standard, which may differ from the simpler * per-character mapping performed by {@code compareToIgnoreCase}. * For example: *

{@snippet lang=java :
     * String a = "Ma?e";
     * String b = "MASSE";
     * int cmpFoldCase = a.compareToFoldCase(b);     // returns 0
     * int cmpIgnoreCase = a.compareToIgnoreCase(b); // returns > 0
     * }
* * @param str the {@code String} to be compared. * @return a negative integer, zero, or a positive integer as the specified * String is greater than, equal to, or less than this String, * ignoring case considerations by case folding. * @see #equalsFoldCase(String) * @see #compareToIgnoreCase(String) * @see java.text.Collator * @since 26 */ public int compareToFoldCase(String str) /** * A Comparator that orders {@code String} objects as by * {@link #compareToFoldCase(String) compareToFoldCase()}. * * @see #compareToFoldCase(String) * @since 26 */ public static final Comparator UNICODE_CASEFOLD_ORDER; ### Usage Examples Sharp s (U+00DF) case-folds to "ss" "stra?e".equalsIgnoreCase("strasse"); // false "stra?e".compareToIgnoreCase("strasse"); // != 0 "stra?e".equalsFoldCase("strasse"); // true ### Performance The JMH microbenchmark StringCompareToIgnoreCase has been updated to compare performance of compareToFoldCase with the existing compareToIgnoreCase(). Benchmark Mode Cnt Score Error Units StringCompareToIgnoreCase.asciiGreekLower avgt 15 20.195 ? 0.300 ns/op StringCompareToIgnoreCase.asciiGreekLowerCF avgt 15 11.051 ? 0.254 ns/op StringCompareToIgnoreCase.asciiGreekUpperLower avgt 15 6.035 ? 0.047 ns/op StringCompareToIgnoreCase.asciiGreekUpperLowerCF avgt 15 14.786 ? 0.382 ns/op StringCompareToIgnoreCase.asciiLower avgt 15 17.688 ? 1.396 ns/op StringCompareToIgnoreCase.asciiLowerCF avgt 15 44.552 ? 0.155 ns/op StringCompareToIgnoreCase.asciiUpperLower avgt 15 13.069 ? 0.487 ns/op StringCompareToIgnoreCase.asciiUpperLowerCF avgt 15 58.684 ? 0.274 ns/op StringCompareToIgnoreCase.greekLower avgt 15 20.642 ? 0.082 ns/op StringCompareToIgnoreCase.greekLowerCF avgt 15 7.255 ? 0.271 ns/op StringCompareToIgnoreCase.greekUpperLower avgt 15 5.737 ? 0.013 ns/op StringCompareToIgnoreCase.greekUpperLowerCF avgt 15 11.100 ? 1.147 ns/op StringCompareToIgnoreCase.lower avgt 15 20.192 ? 0.044 ns/op StringCompareToIgnoreCase.lowerrCF avgt 15 11.257 ? 0.259 ns/op StringCompareToIgnoreCase.supLower avgt 15 54.801 ? 0.415 ns/op StringCompareToIgnoreCase.supLowerCF avgt 15 15.207 ? 0.418 ns/op StringCompareToIgnoreCase.supUpperLower avgt 15 14.431 ? 0.188 ns/op StringCompareToIgnoreCase.supUpperLowerCF avgt 15 19.149 ? 0.985 ns/op StringCompareToIgnoreCase.upperLower avgt 15 5.650 ? 0.051 ns/op StringCompareToIgnoreCase.upperLowerCF avgt 15 14.338 ? 0.352 ns/op StringCompareToIgnoreCase.utf16SubLower avgt 15 14.774 ? 0.200 ns/op StringCompareToIgnoreCase.utf16SubLowerCF avgt 15 2.669 ? 0.041 ns/op StringCompareToIgnoreCase.utf16SupUpperLower avgt 15 16.250 ? 0.099 ns/op StringCompareToIgnoreCase.utf16SupUpperLowerCF avgt 15 11.524 ? 0.327 ns/op ### Refs [Unicode Standard 5.18.4 Caseless Matching](https://www.unicode.org/versions/latest/core-spec/chapter-5/#G21790) [Unicode? Standard Annex #44: 5.6 Case and Case Mapping](https://www.unicode.org/reports/tr44/#Casemapping) [Unicode Technical Standard #18: Unicode Regular Expressions RL1.5: Simple Loose Matches](https://www.unicode.org/reports/tr18/#Simple_Loose_Matches) [Unicode SpecialCasing.txt](https://www.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt) [Unicode CaseFolding.txt](https://www.unicode.org/Public/UCD/latest/ucd/CaseFolding.txt) ### Other Languages **Python string.casefold()** The str.casefold() method in Python returns a casefolded version of a string. Casefolding is a more aggressive form of lowercasing, designed to remove all case distinctions in a string, particularly for the purpose of caseless string comparisons. **Perl?s fc()** Returns the casefolded version of EXPR. This is the internal function implementing the \F escape in double-quoted strings. Casefolding is the process of mapping strings to a form where case differences are erased; comparing two strings in their casefolded form is effectively a way of asking if two strings are equal, regardless of case. Perl only implements the full form of casefolding, but you can access the simple folds using "casefold()" in Unicode::UCD] ad "prop_invmap()" in Unicode::UCD]. **ICU4J UCharacter.foldCase (Java)** Purpose: Provides extensions to the standard Java Character class, including support for more Unicode properties and handling of supplementary characters (code points beyond U+FFFF). Method Signature (String based): public static String foldCase(String str, int options) Method Signature (CharSequence & Appendable based): public static A foldCase(CharSequence src, A dest, int options, Edits edits) Key Features: Case Folding: Converts a string to its case-folded equivalent. Locale Independent: Case folding in UCharacter.foldCase is generally not dependent on locale settings. Context Insensitive: The mapping of a character is not affected by surrounding characters. Turkic Option: An option exists to include or exclude special mappings for Turkish/Azerbaijani text. Result Length: The resulting string can be longer or shorter than the original. Edits Recording: Allows for recording of edits for index mapping, styled text, and getting only changes. **u_strFoldCase (C/C++)** A lower-level C API function for case folding a string. Case Folding Options: Similar options as UCharacter.foldCase for controlling case folding behavior. Availability: Found in the ustring.h and unistr.h headers in the ICU4C library. ------------- Commit messages: - 8365675: Add String Unicode Case-Folding Support Changes: https://git.openjdk.org/jdk/pull/26892/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=26892&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8365675 Stats: 1279 lines in 12 files changed: 1116 ins; 137 del; 26 mod Patch: https://git.openjdk.org/jdk/pull/26892.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26892/head:pull/26892 PR: https://git.openjdk.org/jdk/pull/26892 From sherman at openjdk.org Fri Oct 3 19:41:20 2025 From: sherman at openjdk.org (Xueming Shen) Date: Fri, 3 Oct 2025 19:41:20 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v2] In-Reply-To: References: Message-ID: > ### Summary > > Case folding is a key operation for case-insensitive matching (e.g., string equality, regex matching), where the goal is to eliminate case distinctions without applying locale or language specific conversions. > > Currently, the JDK does not expose a direct API for Unicode-compliant case folding. Developers now rely on methods such as: > > **String.equalsIgnoreCase(String)** > > - Unicode-aware, locale-independent. > - Implementation uses Character.toLowerCase(Character.toUpperCase(int)) per code point. > - Limited: does not support 1:M mapping defined in Unicode case folding. > > **Character.toLowerCase(int) / Character.toUpperCase(int)** > > - Locale-independent, single code point only. > - No support for 1:M mappings. > > **String.toLowerCase(Locale.ROOT) / String.toUpperCase(Locale.ROOT)** > > - Based on Unicode SpecialCasing.txt, supports 1:M mappings. > - Intended primarily for presentation/display, not structural case-insensitive matching. > - Requires full string conversion before comparison, which is less efficient and not intended for structural matching. > > **1:M mapping example, U+00DF (?)** > > - String.toUpperCase(Locale.ROOT, "?") ? "SS" > - Case folding produces "ss", matching Unicode caseless comparison rules. > > > jshell> "\u00df".equalsIgnoreCase("ss") > $22 ==> false > > jshell> "\u00df".toUpperCase(Locale.ROOT).toLowerCase(Locale.ROOT).equals("ss") > $24 ==> true > > > ### Motivation & Direction > > Add Unicode standard-compliant case-less comparison methods to the String class, enabling & improving reliable and efficient Unicode-aware/compliant case-insensitive matching. > > - Unicode-compliant **full** case folding. > - Simpler, stable and more efficient case-less matching without workarounds. > - Brings Java's string comparison handling in line with other programming languages/libraries. > > This PR proposes to introduce the following comparison methods in `String` class > > - boolean equalsFoldCase(String anotherString) > - int compareToFoldCase(String anotherString) > - Comparator UNICODE_CASEFOLD_ORDER > > These methods are intended to be the preferred choice when Unicode-compliant case-less matching is required. > > *Note: An early draft also proposed a String.toCaseFold() method returning a new case-folded string. > However, during review this was considered error-prone, as the resulting string could easily be mistaken for a general transformation like toLowerCase() and then passed into APIs where case-folding semantics are not appropriate. > > ### The New API > > > /** > * Compares thi... Xueming Shen has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains two commits: - Merge branch 'master' of https://git.openjdk.org/jdk into JDK-8365675 - 8365675: Add String Unicode Case-Folding Support to update api ------------- Changes: https://git.openjdk.org/jdk/pull/26892/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=26892&range=01 Stats: 1282 lines in 12 files changed: 1119 ins; 137 del; 26 mod Patch: https://git.openjdk.org/jdk/pull/26892.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/26892/head:pull/26892 PR: https://git.openjdk.org/jdk/pull/26892 From rriggs at openjdk.org Fri Oct 3 19:54:22 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Fri, 3 Oct 2025 19:54:22 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v2] In-Reply-To: References: Message-ID: On Fri, 3 Oct 2025 19:41:20 GMT, Xueming Shen wrote: >> ### Summary >> >> Case folding is a key operation for case-insensitive matching (e.g., string equality, regex matching), where the goal is to eliminate case distinctions without applying locale or language specific conversions. >> >> Currently, the JDK does not expose a direct API for Unicode-compliant case folding. Developers now rely on methods such as: >> >> **String.equalsIgnoreCase(String)** >> >> - Unicode-aware, locale-independent. >> - Implementation uses Character.toLowerCase(Character.toUpperCase(int)) per code point. >> - Limited: does not support 1:M mapping defined in Unicode case folding. >> >> **Character.toLowerCase(int) / Character.toUpperCase(int)** >> >> - Locale-independent, single code point only. >> - No support for 1:M mappings. >> >> **String.toLowerCase(Locale.ROOT) / String.toUpperCase(Locale.ROOT)** >> >> - Based on Unicode SpecialCasing.txt, supports 1:M mappings. >> - Intended primarily for presentation/display, not structural case-insensitive matching. >> - Requires full string conversion before comparison, which is less efficient and not intended for structural matching. >> >> **1:M mapping example, U+00DF (?)** >> >> - String.toUpperCase(Locale.ROOT, "?") ? "SS" >> - Case folding produces "ss", matching Unicode caseless comparison rules. >> >> >> jshell> "\u00df".equalsIgnoreCase("ss") >> $22 ==> false >> >> jshell> "\u00df".toUpperCase(Locale.ROOT).toLowerCase(Locale.ROOT).equals("ss") >> $24 ==> true >> >> >> ### Motivation & Direction >> >> Add Unicode standard-compliant case-less comparison methods to the String class, enabling & improving reliable and efficient Unicode-aware/compliant case-insensitive matching. >> >> - Unicode-compliant **full** case folding. >> - Simpler, stable and more efficient case-less matching without workarounds. >> - Brings Java's string comparison handling in line with other programming languages/libraries. >> >> This PR proposes to introduce the following comparison methods in `String` class >> >> - boolean equalsFoldCase(String anotherString) >> - int compareToFoldCase(String anotherString) >> - Comparator UNICODE_CASEFOLD_ORDER >> >> These methods are intended to be the preferred choice when Unicode-compliant case-less matching is required. >> >> *Note: An early draft also proposed a String.toCaseFold() method returning a new case-folded string. >> However, during review this was considered error-prone, as the resulting string could easily be mistaken for a general transformation like toLowerCase() and then pass... > > Xueming Shen has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains two commits: > > - Merge branch 'master' of https://git.openjdk.org/jdk into JDK-8365675 > - 8365675: Add String Unicode Case-Folding Support > > to update api src/java.base/share/classes/jdk/internal/lang/CaseFolding.java.template line 1: > 1: /* We're going to need to find a more compact format for the data, individual 1 or 2 entry char arrays have a large overhead. Plus the map entries take a lot of space for the data and indexing. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26892#discussion_r2403194785 From sherman at openjdk.org Fri Oct 3 19:54:23 2025 From: sherman at openjdk.org (Xueming Shen) Date: Fri, 3 Oct 2025 19:54:23 GMT Subject: Withdrawn: 8365675: Add String Unicode Case-Folding Support In-Reply-To: References: Message-ID: On Fri, 22 Aug 2025 03:50:03 GMT, Xueming Shen wrote: > ### Summary > > Case folding is a key operation for case-insensitive matching (e.g., string equality, regex matching), where the goal is to eliminate case distinctions without applying locale or language specific conversions. > > Currently, the JDK does not expose a direct API for Unicode-compliant case folding. Developers now rely on methods such as: > > **String.equalsIgnoreCase(String)** > > - Unicode-aware, locale-independent. > - Implementation uses Character.toLowerCase(Character.toUpperCase(int)) per code point. > - Limited: does not support 1:M mapping defined in Unicode case folding. > > **Character.toLowerCase(int) / Character.toUpperCase(int)** > > - Locale-independent, single code point only. > - No support for 1:M mappings. > > **String.toLowerCase(Locale.ROOT) / String.toUpperCase(Locale.ROOT)** > > - Based on Unicode SpecialCasing.txt, supports 1:M mappings. > - Intended primarily for presentation/display, not structural case-insensitive matching. > - Requires full string conversion before comparison, which is less efficient and not intended for structural matching. > > **1:M mapping example, U+00DF (?)** > > - String.toUpperCase(Locale.ROOT, "?") ? "SS" > - Case folding produces "ss", matching Unicode caseless comparison rules. > > > jshell> "\u00df".equalsIgnoreCase("ss") > $22 ==> false > > jshell> "\u00df".toUpperCase(Locale.ROOT).toLowerCase(Locale.ROOT).equals("ss") > $24 ==> true > > > ### Motivation & Direction > > Add Unicode standard-compliant case-less comparison methods to the String class, enabling & improving reliable and efficient Unicode-aware/compliant case-insensitive matching. > > - Unicode-compliant **full** case folding. > - Simpler, stable and more efficient case-less matching without workarounds. > - Brings Java's string comparison handling in line with other programming languages/libraries. > > This PR proposes to introduce the following comparison methods in `String` class > > - boolean equalsFoldCase(String anotherString) > - int compareToFoldCase(String anotherString) > - Comparator UNICODE_CASEFOLD_ORDER > > These methods are intended to be the preferred choice when Unicode-compliant case-less matching is required. > > *Note: An early draft also proposed a String.toCaseFold() method returning a new case-folded string. > However, during review this was considered error-prone, as the resulting string could easily be mistaken for a general transformation like toLowerCase() and then passed into APIs where case-folding semantics are not appropriate. > > ### The New API > > > /** > * Compares thi... This pull request has been closed without being integrated. ------------- PR: https://git.openjdk.org/jdk/pull/26892 From sherman at openjdk.org Fri Oct 3 20:09:21 2025 From: sherman at openjdk.org (Xueming Shen) Date: Fri, 3 Oct 2025 20:09:21 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support Message-ID: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> ### Summary Case folding is a key operation for case-insensitive matching (e.g., string equality, regex matching), where the goal is to eliminate case distinctions without applying locale or language specific conversions. Currently, the JDK does not expose a direct API for Unicode-compliant case folding. Developers now rely on methods such as: **String.equalsIgnoreCase(String)** - Unicode-aware, locale-independent. - Implementation uses Character.toLowerCase(Character.toUpperCase(int)) per code point. - Limited: does not support 1:M mapping defined in Unicode case folding. **Character.toLowerCase(int) / Character.toUpperCase(int)** - Locale-independent, single code point only. - No support for 1:M mappings. **String.toLowerCase(Locale.ROOT) / String.toUpperCase(Locale.ROOT)** - Based on Unicode SpecialCasing.txt, supports 1:M mappings. - Intended primarily for presentation/display, not structural case-insensitive matching. - Requires full string conversion before comparison, which is less efficient and not intended for structural matching. **1:M mapping example, U+00DF (?)** - String.toUpperCase(Locale.ROOT, "?") ? "SS" - Case folding produces "ss", matching Unicode caseless comparison rules. jshell> "\u00df".equalsIgnoreCase("ss") $22 ==> false jshell> "\u00df".toUpperCase(Locale.ROOT).toLowerCase(Locale.ROOT).equals("ss") $24 ==> true ### Motivation & Direction Add Unicode standard-compliant case-less comparison methods to the String class, enabling & improving reliable and efficient Unicode-aware/compliant case-insensitive matching. - Unicode-compliant **full** case folding. - Simpler, stable and more efficient case-less matching without workarounds. - Brings Java's string comparison handling in line with other programming languages/libraries. This PR proposes to introduce the following comparison methods in `String` class - boolean equalsFoldCase(String anotherString) - int compareToFoldCase(String anotherString) - Comparator UNICODE_CASEFOLD_ORDER These methods are intended to be the preferred choice when Unicode-compliant case-less matching is required. *Note: An early draft also proposed a String.toCaseFold() method returning a new case-folded string. However, during review this was considered error-prone, as the resulting string could easily be mistaken for a general transformation like toLowerCase() and then passed into APIs where case-folding semantics are not appropriate. ### The New API /** * Compares this {@code String} to another {@code String} for equality, * using Unicode case folding. Two strings are considered equal * by this method if their case-folded forms are identical. *

* Case folding is defined by the Unicode Standard in * CaseFolding.txt, * including 1:M mappings. For example, {@code "Ma?e".equalsFoldCase("MASSE")} * returns {@code true}, since the character {@code U+00DF} (sharp s) folds * to {@code "ss"}. *

* Case folding is locale-independent and language-neutral, unlike * locale-sensitive transformations such as {@link #toLowerCase()} or * {@link #toUpperCase()}. It is intended for caseless matching, * searching, and indexing. * * @apiNote * This method is the Unicode-compliant alternative to * {@link #equalsIgnoreCase(String)}. It implements full case folding as * defined by the Unicode Standard, which may differ from the simpler * per-character mapping performed by {@code equalsIgnoreCase}. * For example: *

{@snippet lang=java :
     * String a = "Ma?e";
     * String b = "MASSE";
     * boolean equalsFoldCase = a.equalsFoldCase(b);       // returns true
     * boolean equalsIgnoreCase = a.equalsIgnoreCase(b);   // returns false
     * }
* * @param anotherString * The {@code String} to compare this {@code String} against * * @return {@code true} if the given object is not {@code null} and represents * the same sequence of characters as this string under Unicode case * folding; {@code false} otherwise. * * @see #compareToFoldCase(String) * @see #equalsIgnoreCase(String) * @since 26 */ public boolean equalsFoldCase(String anotherString) /** * Compares two strings lexicographically using Unicode case folding. * This method returns an integer whose sign is that of calling {@code compareTo} * on the Unicode case folded version of the strings. Unicode Case folding * eliminates differences in case according to the Unicode Standard, using the * mappings defined in * CaseFolding.txt, * including 1:M mappings, such as {@code"?"} ? {@code }"ss"}. *

* Case folding is a locale-independent, language-neutral form of case mapping, * primarily intended for caseless matching. Unlike {@link #compareToIgnoreCase(String)}, * which applies a simpler locale-insensitive uppercase mapping. This method * follows the Unicode full case folding, providing stable and * consistent results across all environments. *

* Note that this method does not take locale into account, and may * produce results that differ from locale-sensitive ordering. Use * {@link java.text.Collator} for locale-sensitive comparison. * * @apiNote * This method is the Unicode-compliant alternative to * {@link #compareToIgnoreCase(String)}. It implements the full case folding * as defined by the Unicode Standard, which may differ from the simpler * per-character mapping performed by {@code compareToIgnoreCase}. * For example: *

{@snippet lang=java :
     * String a = "Ma?e";
     * String b = "MASSE";
     * int cmpFoldCase = a.compareToFoldCase(b);     // returns 0
     * int cmpIgnoreCase = a.compareToIgnoreCase(b); // returns > 0
     * }
* * @param str the {@code String} to be compared. * @return a negative integer, zero, or a positive integer as the specified * String is greater than, equal to, or less than this String, * ignoring case considerations by case folding. * @see #equalsFoldCase(String) * @see #compareToIgnoreCase(String) * @see java.text.Collator * @since 26 */ public int compareToFoldCase(String str) /** * A Comparator that orders {@code String} objects as by * {@link #compareToFoldCase(String) compareToFoldCase()}. * * @see #compareToFoldCase(String) * @since 26 */ public static final Comparator UNICODE_CASEFOLD_ORDER; ### Usage Examples Sharp s (U+00DF) case-folds to "ss" "stra?e".equalsIgnoreCase("strasse"); // false "stra?e".compareToIgnoreCase("strasse"); // != 0 "stra?e".equalsFoldCase("strasse"); // true ### Performance The JMH microbenchmark StringCompareToIgnoreCase has been updated to compare performance of compareToFoldCase with the existing compareToIgnoreCase(). Benchmark Mode Cnt Score Error Units StringCompareToIgnoreCase.asciiGreekLower avgt 15 20.195 ? 0.300 ns/op StringCompareToIgnoreCase.asciiGreekLowerCF avgt 15 11.051 ? 0.254 ns/op StringCompareToIgnoreCase.asciiGreekUpperLower avgt 15 6.035 ? 0.047 ns/op StringCompareToIgnoreCase.asciiGreekUpperLowerCF avgt 15 14.786 ? 0.382 ns/op StringCompareToIgnoreCase.asciiLower avgt 15 17.688 ? 1.396 ns/op StringCompareToIgnoreCase.asciiLowerCF avgt 15 44.552 ? 0.155 ns/op StringCompareToIgnoreCase.asciiUpperLower avgt 15 13.069 ? 0.487 ns/op StringCompareToIgnoreCase.asciiUpperLowerCF avgt 15 58.684 ? 0.274 ns/op StringCompareToIgnoreCase.greekLower avgt 15 20.642 ? 0.082 ns/op StringCompareToIgnoreCase.greekLowerCF avgt 15 7.255 ? 0.271 ns/op StringCompareToIgnoreCase.greekUpperLower avgt 15 5.737 ? 0.013 ns/op StringCompareToIgnoreCase.greekUpperLowerCF avgt 15 11.100 ? 1.147 ns/op StringCompareToIgnoreCase.lower avgt 15 20.192 ? 0.044 ns/op StringCompareToIgnoreCase.lowerrCF avgt 15 11.257 ? 0.259 ns/op StringCompareToIgnoreCase.supLower avgt 15 54.801 ? 0.415 ns/op StringCompareToIgnoreCase.supLowerCF avgt 15 15.207 ? 0.418 ns/op StringCompareToIgnoreCase.supUpperLower avgt 15 14.431 ? 0.188 ns/op StringCompareToIgnoreCase.supUpperLowerCF avgt 15 19.149 ? 0.985 ns/op StringCompareToIgnoreCase.upperLower avgt 15 5.650 ? 0.051 ns/op StringCompareToIgnoreCase.upperLowerCF avgt 15 14.338 ? 0.352 ns/op StringCompareToIgnoreCase.utf16SubLower avgt 15 14.774 ? 0.200 ns/op StringCompareToIgnoreCase.utf16SubLowerCF avgt 15 2.669 ? 0.041 ns/op StringCompareToIgnoreCase.utf16SupUpperLower avgt 15 16.250 ? 0.099 ns/op StringCompareToIgnoreCase.utf16SupUpperLowerCF avgt 15 11.524 ? 0.327 ns/op ### Refs [Unicode Standard 5.18.4 Caseless Matching](https://www.unicode.org/versions/latest/core-spec/chapter-5/#G21790) [Unicode? Standard Annex #44: 5.6 Case and Case Mapping](https://www.unicode.org/reports/tr44/#Casemapping) [Unicode Technical Standard #18: Unicode Regular Expressions RL1.5: Simple Loose Matches](https://www.unicode.org/reports/tr18/#Simple_Loose_Matches) [Unicode SpecialCasing.txt](https://www.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt) [Unicode CaseFolding.txt](https://www.unicode.org/Public/UCD/latest/ucd/CaseFolding.txt) ### Other Languages **Python string.casefold()** The str.casefold() method in Python returns a casefolded version of a string. Casefolding is a more aggressive form of lowercasing, designed to remove all case distinctions in a string, particularly for the purpose of caseless string comparisons. **Perl?s fc()** Returns the casefolded version of EXPR. This is the internal function implementing the \F escape in double-quoted strings. Casefolding is the process of mapping strings to a form where case differences are erased; comparing two strings in their casefolded form is effectively a way of asking if two strings are equal, regardless of case. Perl only implements the full form of casefolding, but you can access the simple folds using "casefold()" in Unicode::UCD] ad "prop_invmap()" in Unicode::UCD]. **ICU4J UCharacter.foldCase (Java)** Purpose: Provides extensions to the standard Java Character class, including support for more Unicode properties and handling of supplementary characters (code points beyond U+FFFF). Method Signature (String based): public static String foldCase(String str, int options) Method Signature (CharSequence & Appendable based): public static A foldCase(CharSequence src, A dest, int options, Edits edits) Key Features: Case Folding: Converts a string to its case-folded equivalent. Locale Independent: Case folding in UCharacter.foldCase is generally not dependent on locale settings. Context Insensitive: The mapping of a character is not affected by surrounding characters. Turkic Option: An option exists to include or exclude special mappings for Turkish/Azerbaijani text. Result Length: The resulting string can be longer or shorter than the original. Edits Recording: Allows for recording of edits for index mapping, styled text, and getting only changes. **u_strFoldCase (C/C++)** A lower-level C API function for case folding a string. Case Folding Options: Similar options as UCharacter.foldCase for controlling case folding behavior. Availability: Found in the ustring.h and unistr.h headers in the ICU4C library. ------------- Commit messages: - Merge branch 'master' of https://git.openjdk.org/jdk into JDK-8365675 - 8365675: Add String Unicode Case-Folding Support Changes: https://git.openjdk.org/jdk/pull/27628/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=27628&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8365675 Stats: 1282 lines in 12 files changed: 1119 ins; 137 del; 26 mod Patch: https://git.openjdk.org/jdk/pull/27628.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27628/head:pull/27628 PR: https://git.openjdk.org/jdk/pull/27628 From duke at openjdk.org Sun Oct 5 00:38:55 2025 From: duke at openjdk.org (Tatsunori Uchino) Date: Sun, 5 Oct 2025 00:38:55 GMT Subject: RFR: 8364007: Add no-argument codePointCount method to CharSequence and String [v3] In-Reply-To: References: Message-ID: On Sat, 26 Jul 2025 10:10:40 GMT, Tatsunori Uchino wrote: >> Adds `codePointCount()` overloads to `String`, `Character`, `(Abstract)StringBuilder`, and `StringBuffer` to make it possible to conveniently retrieve the length of a string as code points without extra boundary checks. >> >> >> if (superTremendouslyLongExpressionYieldingAString().codePointCount() > limit) { >> throw new Exception("exceeding length"); >> } >> >> >> Is a CSR required to this change? > > Tatsunori Uchino has updated the pull request incrementally with four additional commits since the last revision: > > - Update `@bug` in correct file > - Add default implementation on codePointCount in CharSequence > - Update `@bug` entries in test class doc comments > - Discard changes on code whose form is not `str.codePointCount(0, str.length())` > Character.codePointCount(CharSequence) > CharSequence.codePointCount I think that the problem is which of both should be _canonical_ (the other is just a call for the canonical one). public class Character { public static int codePointCount(CharSequence s) { return s.codePointCount(); } } I expect that an inline expansion is applied there. > Do we need codePointCount(int start, int end) in CharSequence too? IMO it is fine either way. It is OK to postpone/defer it. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26461#issuecomment-3368632586 From prappo at openjdk.org Mon Oct 6 11:32:51 2025 From: prappo at openjdk.org (Pavel Rappo) Date: Mon, 6 Oct 2025 11:32:51 GMT Subject: RFR: 8366829: Add java.time.Duration constants MIN and MAX [v3] In-Reply-To: References: Message-ID: On Fri, 3 Oct 2025 09:50:23 GMT, Pavel Rappo wrote: >> We have [recently discussed][] a possibility of adding the `Duration.MIN` and `Duration.MAX` constants. Can we now start implementation? If and when we are in agreement on this PR, I will file a CSR. >> >> I drafted a minimal specification and added some tests. I tried to phrase the spec for `Duration.MIN` in a way that makes it clear that `Duration.MIN` is the most negative value and not the least positive. >> >> [recently discussed]: https://mail.openjdk.org/pipermail/core-libs-dev/2025-September/151098.html > > Pavel Rappo has updated the pull request incrementally with one additional commit since the last revision: > > Respond to feedback > > Apply Stephen's suggestion on wording, although modified. Thanks for the reviews. I'll draft the CSR shortly. ------------- PR Comment: https://git.openjdk.org/jdk/pull/27534#issuecomment-3371166113 From ihse at openjdk.org Mon Oct 6 12:38:41 2025 From: ihse at openjdk.org (Magnus Ihse Bursie) Date: Mon, 6 Oct 2025 12:38:41 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support In-Reply-To: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> Message-ID: On Fri, 3 Oct 2025 19:56:22 GMT, Xueming Shen wrote: > ### Summary > > Case folding is a key operation for case-insensitive matching (e.g., string equality, regex matching), where the goal is to eliminate case distinctions without applying locale or language specific conversions. > > Currently, the JDK does not expose a direct API for Unicode-compliant case folding. Developers now rely on methods such as: > > **String.equalsIgnoreCase(String)** > > - Unicode-aware, locale-independent. > - Implementation uses Character.toLowerCase(Character.toUpperCase(int)) per code point. > - Limited: does not support 1:M mapping defined in Unicode case folding. > > **Character.toLowerCase(int) / Character.toUpperCase(int)** > > - Locale-independent, single code point only. > - No support for 1:M mappings. > > **String.toLowerCase(Locale.ROOT) / String.toUpperCase(Locale.ROOT)** > > - Based on Unicode SpecialCasing.txt, supports 1:M mappings. > - Intended primarily for presentation/display, not structural case-insensitive matching. > - Requires full string conversion before comparison, which is less efficient and not intended for structural matching. > > **1:M mapping example, U+00DF (?)** > > - String.toUpperCase(Locale.ROOT, "?") ? "SS" > - Case folding produces "ss", matching Unicode caseless comparison rules. > > > jshell> "\u00df".equalsIgnoreCase("ss") > $22 ==> false > > jshell> "\u00df".toUpperCase(Locale.ROOT).toLowerCase(Locale.ROOT).equals("ss") > $24 ==> true > > > ### Motivation & Direction > > Add Unicode standard-compliant case-less comparison methods to the String class, enabling & improving reliable and efficient Unicode-aware/compliant case-insensitive matching. > > - Unicode-compliant **full** case folding. > - Simpler, stable and more efficient case-less matching without workarounds. > - Brings Java's string comparison handling in line with other programming languages/libraries. > > This PR proposes to introduce the following comparison methods in `String` class > > - boolean equalsFoldCase(String anotherString) > - int compareToFoldCase(String anotherString) > - Comparator UNICODE_CASEFOLD_ORDER > > These methods are intended to be the preferred choice when Unicode-compliant case-less matching is required. > > *Note: An early draft also proposed a String.toCaseFold() method returning a new case-folded string. > However, during review this was considered error-prone, as the resulting string could easily be mistaken for a general transformation like toLowerCase() and then passed into APIs where case-folding semantics are not appropriate. > > ### The New API > > > /** > * Compares thi... Build changes look fine. ------------- Marked as reviewed by ihse (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/27628#pullrequestreview-3304307032 From scolebourne at openjdk.org Mon Oct 6 19:07:48 2025 From: scolebourne at openjdk.org (Stephen Colebourne) Date: Mon, 6 Oct 2025 19:07:48 GMT Subject: RFR: 8366829: Add java.time.Duration constants MIN and MAX [v3] In-Reply-To: References: Message-ID: On Fri, 3 Oct 2025 09:50:23 GMT, Pavel Rappo wrote: >> We have [recently discussed][] a possibility of adding the `Duration.MIN` and `Duration.MAX` constants. Can we now start implementation? If and when we are in agreement on this PR, I will file a CSR. >> >> I drafted a minimal specification and added some tests. I tried to phrase the spec for `Duration.MIN` in a way that makes it clear that `Duration.MIN` is the most negative value and not the least positive. >> >> [recently discussed]: https://mail.openjdk.org/pipermail/core-libs-dev/2025-September/151098.html > > Pavel Rappo has updated the pull request incrementally with one additional commit since the last revision: > > Respond to feedback > > Apply Stephen's suggestion on wording, although modified. Marked as reviewed by scolebourne (Author). ------------- PR Review: https://git.openjdk.org/jdk/pull/27534#pullrequestreview-3306703205 From sherman at openjdk.org Mon Oct 6 20:59:48 2025 From: sherman at openjdk.org (Xueming Shen) Date: Mon, 6 Oct 2025 20:59:48 GMT Subject: RFR: 8368845: x-IBM930 uses incorrect character for Hex 42 60 [v2] In-Reply-To: References: <0Ep8UN3_bJ-nR9RCNIUaRA7flGGV3khNSjstui2ijRk=.d3eb41c7-1bae-4916-9c80-876d5912724f@github.com> Message-ID: On Wed, 1 Oct 2025 21:06:19 GMT, Naoto Sato wrote: >> Fixing a charset en/decoder for x-IBM930. There was a "temporary" mapping for the said code point for the backward compatibility (as of JDK7). Since the issue requests the "correct" mapping, I believe we can replace the temporary one with the correct mapping. > > Naoto Sato has updated the pull request incrementally with one additional commit since the last revision: > > added bugid to the tests looks good. ------------- PR Comment: https://git.openjdk.org/jdk/pull/27594#issuecomment-3374089434 From naoto at openjdk.org Mon Oct 6 21:43:21 2025 From: naoto at openjdk.org (Naoto Sato) Date: Mon, 6 Oct 2025 21:43:21 GMT Subject: RFR: 8369184: SimpleTimeZone equals() Returns True for Unequal Instances with Different hashCode Values Message-ID: Fixing the equals/hashCode contract in the SimpleTimeZone class. The current implementation includes DST rule fields in hash code computation even for zones that do not observe DST, while equals() always considers them. Also correcting the example code in the class description, where it used 20-year-old obsolete "America/Los_Angeles" rule. ------------- Commit messages: - initial commit Changes: https://git.openjdk.org/jdk/pull/27660/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=27660&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8369184 Stats: 96 lines in 2 files changed: 89 ins; 0 del; 7 mod Patch: https://git.openjdk.org/jdk/pull/27660.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27660/head:pull/27660 PR: https://git.openjdk.org/jdk/pull/27660 From naoto at openjdk.org Mon Oct 6 21:49:31 2025 From: naoto at openjdk.org (Naoto Sato) Date: Mon, 6 Oct 2025 21:49:31 GMT Subject: RFR: 8369184: SimpleTimeZone equals() Returns True for Unequal Instances with Different hashCode Values [v2] In-Reply-To: References: Message-ID: > Fixing the equals/hashCode contract in the SimpleTimeZone class. The current implementation includes DST rule fields in hash code computation even for zones that do not observe DST, while equals() always considers them. Also correcting the example code in the class description, where it used 20-year-old obsolete "America/Los_Angeles" rule. Naoto Sato has updated the pull request incrementally with one additional commit since the last revision: fixed typo ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27660/files - new: https://git.openjdk.org/jdk/pull/27660/files/ad1e8be6..a2c988d8 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27660&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27660&range=00-01 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/27660.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27660/head:pull/27660 PR: https://git.openjdk.org/jdk/pull/27660 From sherman at openjdk.org Mon Oct 6 22:12:45 2025 From: sherman at openjdk.org (Xueming Shen) Date: Mon, 6 Oct 2025 22:12:45 GMT Subject: RFR: 8368845: x-IBM930 uses incorrect character for Hex 42 60 [v2] In-Reply-To: References: <0Ep8UN3_bJ-nR9RCNIUaRA7flGGV3khNSjstui2ijRk=.d3eb41c7-1bae-4916-9c80-876d5912724f@github.com> Message-ID: On Wed, 1 Oct 2025 21:06:19 GMT, Naoto Sato wrote: >> Fixing a charset en/decoder for x-IBM930. There was a "temporary" mapping for the said code point for the backward compatibility (as of JDK7). Since the issue requests the "correct" mapping, I believe we can replace the temporary one with the correct mapping. > > Naoto Sato has updated the pull request incrementally with one additional commit since the last revision: > > added bugid to the tests Looks good. ------------- PR Comment: https://git.openjdk.org/jdk/pull/27594#issuecomment-3374439736 From sherman at openjdk.org Mon Oct 6 22:16:46 2025 From: sherman at openjdk.org (Xueming Shen) Date: Mon, 6 Oct 2025 22:16:46 GMT Subject: RFR: 8368845: x-IBM930 uses incorrect character for Hex 42 60 [v2] In-Reply-To: References: <0Ep8UN3_bJ-nR9RCNIUaRA7flGGV3khNSjstui2ijRk=.d3eb41c7-1bae-4916-9c80-876d5912724f@github.com> Message-ID: On Wed, 1 Oct 2025 21:06:19 GMT, Naoto Sato wrote: >> Fixing a charset en/decoder for x-IBM930. There was a "temporary" mapping for the said code point for the backward compatibility (as of JDK7). Since the issue requests the "correct" mapping, I believe we can replace the temporary one with the correct mapping. > > Naoto Sato has updated the pull request incrementally with one additional commit since the last revision: > > added bugid to the tests Looks good. ------------- Marked as reviewed by sherman (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/27594#pullrequestreview-3307679853 From rriggs at openjdk.org Tue Oct 7 13:21:28 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Tue, 7 Oct 2025 13:21:28 GMT Subject: RFR: 8368845: x-IBM930 uses incorrect character for Hex 42 60 [v2] In-Reply-To: References: <0Ep8UN3_bJ-nR9RCNIUaRA7flGGV3khNSjstui2ijRk=.d3eb41c7-1bae-4916-9c80-876d5912724f@github.com> Message-ID: On Wed, 1 Oct 2025 21:06:19 GMT, Naoto Sato wrote: >> Fixing a charset en/decoder for x-IBM930. There was a "temporary" mapping for the said code point for the backward compatibility (as of JDK7). Since the issue requests the "correct" mapping, I believe we can replace the temporary one with the correct mapping. > > Naoto Sato has updated the pull request incrementally with one additional commit since the last revision: > > added bugid to the tests LGTM ------------- Marked as reviewed by rriggs (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/27594#pullrequestreview-3310084423 From iris at openjdk.org Tue Oct 7 15:48:07 2025 From: iris at openjdk.org (Iris Clark) Date: Tue, 7 Oct 2025 15:48:07 GMT Subject: RFR: 8368845: x-IBM930 uses incorrect character for Hex 42 60 [v2] In-Reply-To: References: <0Ep8UN3_bJ-nR9RCNIUaRA7flGGV3khNSjstui2ijRk=.d3eb41c7-1bae-4916-9c80-876d5912724f@github.com> Message-ID: On Wed, 1 Oct 2025 21:06:19 GMT, Naoto Sato wrote: >> Fixing a charset en/decoder for x-IBM930. There was a "temporary" mapping for the said code point for the backward compatibility (as of JDK7). Since the issue requests the "correct" mapping, I believe we can replace the temporary one with the correct mapping. > > Naoto Sato has updated the pull request incrementally with one additional commit since the last revision: > > added bugid to the tests Marked as reviewed by iris (Reviewer). ------------- PR Review: https://git.openjdk.org/jdk/pull/27594#pullrequestreview-3310763073 From naoto at openjdk.org Tue Oct 7 17:23:48 2025 From: naoto at openjdk.org (Naoto Sato) Date: Tue, 7 Oct 2025 17:23:48 GMT Subject: RFR: 8368845: x-IBM930 uses incorrect character for Hex 42 60 [v2] In-Reply-To: References: <0Ep8UN3_bJ-nR9RCNIUaRA7flGGV3khNSjstui2ijRk=.d3eb41c7-1bae-4916-9c80-876d5912724f@github.com> Message-ID: On Wed, 1 Oct 2025 21:06:19 GMT, Naoto Sato wrote: >> Fixing a charset en/decoder for x-IBM930. There was a "temporary" mapping for the said code point for the backward compatibility (as of JDK7). Since the issue requests the "correct" mapping, I believe we can replace the temporary one with the correct mapping. > > Naoto Sato has updated the pull request incrementally with one additional commit since the last revision: > > added bugid to the tests Thanks for the reviews! ------------- PR Comment: https://git.openjdk.org/jdk/pull/27594#issuecomment-3377830143 From naoto at openjdk.org Tue Oct 7 17:23:50 2025 From: naoto at openjdk.org (Naoto Sato) Date: Tue, 7 Oct 2025 17:23:50 GMT Subject: Integrated: 8368845: x-IBM930 uses incorrect character for Hex 42 60 In-Reply-To: <0Ep8UN3_bJ-nR9RCNIUaRA7flGGV3khNSjstui2ijRk=.d3eb41c7-1bae-4916-9c80-876d5912724f@github.com> References: <0Ep8UN3_bJ-nR9RCNIUaRA7flGGV3khNSjstui2ijRk=.d3eb41c7-1bae-4916-9c80-876d5912724f@github.com> Message-ID: On Wed, 1 Oct 2025 19:50:49 GMT, Naoto Sato wrote: > Fixing a charset en/decoder for x-IBM930. There was a "temporary" mapping for the said code point for the backward compatibility (as of JDK7). Since the issue requests the "correct" mapping, I believe we can replace the temporary one with the correct mapping. This pull request has now been integrated. Changeset: 6b316262 Author: Naoto Sato URL: https://git.openjdk.org/jdk/commit/6b3162620bd808227ec7b4331ae6fc32ceb909e8 Stats: 22 lines in 6 files changed: 1 ins; 13 del; 8 mod 8368845: x-IBM930 uses incorrect character for Hex 42 60 Reviewed-by: sherman, rriggs, iris ------------- PR: https://git.openjdk.org/jdk/pull/27594 From naoto at openjdk.org Tue Oct 7 18:41:09 2025 From: naoto at openjdk.org (Naoto Sato) Date: Tue, 7 Oct 2025 18:41:09 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support In-Reply-To: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> Message-ID: <3joVVX55ZEto_x9dhTVpYgMGzPtL8tdNNvZxiBmsuHE=.42d5f21c-64b4-4547-99e1-f2a3af104272@github.com> On Fri, 3 Oct 2025 19:56:22 GMT, Xueming Shen wrote: > ### Summary > > Case folding is a key operation for case-insensitive matching (e.g., string equality, regex matching), where the goal is to eliminate case distinctions without applying locale or language specific conversions. > > Currently, the JDK does not expose a direct API for Unicode-compliant case folding. Developers now rely on methods such as: > > **String.equalsIgnoreCase(String)** > > - Unicode-aware, locale-independent. > - Implementation uses Character.toLowerCase(Character.toUpperCase(int)) per code point. > - Limited: does not support 1:M mapping defined in Unicode case folding. > > **Character.toLowerCase(int) / Character.toUpperCase(int)** > > - Locale-independent, single code point only. > - No support for 1:M mappings. > > **String.toLowerCase(Locale.ROOT) / String.toUpperCase(Locale.ROOT)** > > - Based on Unicode SpecialCasing.txt, supports 1:M mappings. > - Intended primarily for presentation/display, not structural case-insensitive matching. > - Requires full string conversion before comparison, which is less efficient and not intended for structural matching. > > **1:M mapping example, U+00DF (?)** > > - String.toUpperCase(Locale.ROOT, "?") ? "SS" > - Case folding produces "ss", matching Unicode caseless comparison rules. > > > jshell> "\u00df".equalsIgnoreCase("ss") > $22 ==> false > > jshell> "\u00df".toUpperCase(Locale.ROOT).toLowerCase(Locale.ROOT).equals("ss") > $24 ==> true > > > ### Motivation & Direction > > Add Unicode standard-compliant case-less comparison methods to the String class, enabling & improving reliable and efficient Unicode-aware/compliant case-insensitive matching. > > - Unicode-compliant **full** case folding. > - Simpler, stable and more efficient case-less matching without workarounds. > - Brings Java's string comparison handling in line with other programming languages/libraries. > > This PR proposes to introduce the following comparison methods in `String` class > > - boolean equalsFoldCase(String anotherString) > - int compareToFoldCase(String anotherString) > - Comparator UNICODE_CASEFOLD_ORDER > > These methods are intended to be the preferred choice when Unicode-compliant case-less matching is required. > > *Note: An early draft also proposed a String.toCaseFold() method returning a new case-folded string. > However, during review this was considered error-prone, as the resulting string could easily be mistaken for a general transformation like toLowerCase() and then passed into APIs where case-folding semantics are not appropriate. > > ### The New API > > > /** > * Compares thi... While working on Unicode 17 upgrade, I noticed that they changed the example from "MASSE"/"Ma?e" to "FUSS"/"Fu?" (https://www.unicode.org/L2/L2025/25085.htm#183-A59), so you might want to switch them as well ------------- PR Comment: https://git.openjdk.org/jdk/pull/27628#issuecomment-3378153999 From jlu at openjdk.org Tue Oct 7 19:00:47 2025 From: jlu at openjdk.org (Justin Lu) Date: Tue, 7 Oct 2025 19:00:47 GMT Subject: RFR: 8369184: SimpleTimeZone equals() Returns True for Unequal Instances with Different hashCode Values [v2] In-Reply-To: References: Message-ID: On Mon, 6 Oct 2025 21:49:31 GMT, Naoto Sato wrote: >> Fixing the equals/hashCode contract in the SimpleTimeZone class. The current implementation includes DST rule fields in hash code computation even for zones that do not observe DST, while equals() always considers them. Also correcting the example code in the class description, where it used 20-year-old obsolete "America/Los_Angeles" rule. > > Naoto Sato has updated the pull request incrementally with one additional commit since the last revision: > > fixed typo LGTM src/java.base/share/classes/java/util/SimpleTimeZone.java line 871: > 869: public int hashCode() > 870: { > 871: int hash = 31 * getID().hashCode() + rawOffset; int hash = Objects.hash(getID(), rawOffset, useDaylight); return !useDaylight ? hash : 31 * hash + Objects.hash( startMonth, startDay, startDayOfWeek, startTime, endMonth, endDay, endDayOfWeek, endTime); Seems reasonable to use `Objects.hash` here. Could save some lines if wanted? test/jdk/java/util/TimeZone/SimpleTimeZoneHashCodeTest.java line 1: > 1: /* Include _equals_ in the test name as well? Perhaps _HashCodeEqualsTest_ or something along those lines. ------------- Marked as reviewed by jlu (Committer). PR Review: https://git.openjdk.org/jdk/pull/27660#pullrequestreview-3311435895 PR Review Comment: https://git.openjdk.org/jdk/pull/27660#discussion_r2411594933 PR Review Comment: https://git.openjdk.org/jdk/pull/27660#discussion_r2411564566 From naoto at openjdk.org Tue Oct 7 20:43:23 2025 From: naoto at openjdk.org (Naoto Sato) Date: Tue, 7 Oct 2025 20:43:23 GMT Subject: RFR: 8369184: SimpleTimeZone equals() Returns True for Unequal Instances with Different hashCode Values [v2] In-Reply-To: References: Message-ID: On Tue, 7 Oct 2025 18:54:34 GMT, Justin Lu wrote: >> Naoto Sato has updated the pull request incrementally with one additional commit since the last revision: >> >> fixed typo > > src/java.base/share/classes/java/util/SimpleTimeZone.java line 871: > >> 869: public int hashCode() >> 870: { >> 871: int hash = 31 * getID().hashCode() + rawOffset; > > int hash = Objects.hash(getID(), rawOffset, useDaylight); > return !useDaylight ? hash : 31 * hash + Objects.hash( > startMonth, startDay, startDayOfWeek, startTime, endMonth, endDay, endDayOfWeek, endTime); > > > Seems reasonable to use `Objects.hash` here. Could save some lines if wanted? Initially, I thought so, but decided to avoid extra array allocation/copy. But on second thought, the instances of this class would seldom be used as hash keys so not that performance critical. Either way is fine with me > test/jdk/java/util/TimeZone/SimpleTimeZoneEqualsHashCodeTest.java line 1: > >> (failed to retrieve contents of file, check the PR for context) > Include _equals_ in the test name as well? Perhaps _HashCodeEqualsTest_ or something along those lines. Renamed. I left `SimpleTimeZone` as the test is specific for this class. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27660#discussion_r2411787045 PR Review Comment: https://git.openjdk.org/jdk/pull/27660#discussion_r2411778576 From naoto at openjdk.org Tue Oct 7 20:43:20 2025 From: naoto at openjdk.org (Naoto Sato) Date: Tue, 7 Oct 2025 20:43:20 GMT Subject: RFR: 8369184: SimpleTimeZone equals() Returns True for Unequal Instances with Different hashCode Values [v3] In-Reply-To: References: Message-ID: > Fixing the equals/hashCode contract in the SimpleTimeZone class. The current implementation includes DST rule fields in hash code computation even for zones that do not observe DST, while equals() always considers them. Also correcting the example code in the class description, where it used 20-year-old obsolete "America/Los_Angeles" rule. Naoto Sato has updated the pull request incrementally with one additional commit since the last revision: Address review comments ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27660/files - new: https://git.openjdk.org/jdk/pull/27660/files/a2c988d8..aafdf18b Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27660&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27660&range=01-02 Stats: 2 lines in 1 file changed: 0 ins; 0 del; 2 mod Patch: https://git.openjdk.org/jdk/pull/27660.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27660/head:pull/27660 PR: https://git.openjdk.org/jdk/pull/27660 From rriggs at openjdk.org Tue Oct 7 22:25:08 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Tue, 7 Oct 2025 22:25:08 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support In-Reply-To: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> Message-ID: On Fri, 3 Oct 2025 19:56:22 GMT, Xueming Shen wrote: > ### Summary > > Case folding is a key operation for case-insensitive matching (e.g., string equality, regex matching), where the goal is to eliminate case distinctions without applying locale or language specific conversions. > > Currently, the JDK does not expose a direct API for Unicode-compliant case folding. Developers now rely on methods such as: > > **String.equalsIgnoreCase(String)** > > - Unicode-aware, locale-independent. > - Implementation uses Character.toLowerCase(Character.toUpperCase(int)) per code point. > - Limited: does not support 1:M mapping defined in Unicode case folding. > > **Character.toLowerCase(int) / Character.toUpperCase(int)** > > - Locale-independent, single code point only. > - No support for 1:M mappings. > > **String.toLowerCase(Locale.ROOT) / String.toUpperCase(Locale.ROOT)** > > - Based on Unicode SpecialCasing.txt, supports 1:M mappings. > - Intended primarily for presentation/display, not structural case-insensitive matching. > - Requires full string conversion before comparison, which is less efficient and not intended for structural matching. > > **1:M mapping example, U+00DF (?)** > > - String.toUpperCase(Locale.ROOT, "?") ? "SS" > - Case folding produces "ss", matching Unicode caseless comparison rules. > > > jshell> "\u00df".equalsIgnoreCase("ss") > $22 ==> false > > jshell> "\u00df".toUpperCase(Locale.ROOT).toLowerCase(Locale.ROOT).equals("ss") > $24 ==> true > > > ### Motivation & Direction > > Add Unicode standard-compliant case-less comparison methods to the String class, enabling & improving reliable and efficient Unicode-aware/compliant case-insensitive matching. > > - Unicode-compliant **full** case folding. > - Simpler, stable and more efficient case-less matching without workarounds. > - Brings Java's string comparison handling in line with other programming languages/libraries. > > This PR proposes to introduce the following comparison methods in `String` class > > - boolean equalsFoldCase(String anotherString) > - int compareToFoldCase(String anotherString) > - Comparator UNICODE_CASEFOLD_ORDER > > These methods are intended to be the preferred choice when Unicode-compliant case-less matching is required. > > *Note: An early draft also proposed a String.toCaseFold() method returning a new case-folded string. > However, during review this was considered error-prone, as the resulting string could easily be mistaken for a general transformation like toLowerCase() and then passed into APIs where case-folding semantics are not appropriate. > > ### The New API > > > /** > * Compares thi... The API looks good. Is the performance comparable to equalsIgnoreCase? src/java.base/share/classes/java/lang/StringLatin1.java line 194: > 192: char[] folded2 = null; > 193: int k1 = 0, k2 = 0, fk1 = 0, fk2 = 0; > 194: while ((k1 < len1 || folded1 != null && fk1 < folded1.length) && Many suggestions come to mind here on the algorithm, to optimize performance. For example, many strings will have identical prefixes. Using Arrays.mismatch could quickly skip over the identical prefix. Consider using code points (or a long, packing 4 chars) for the folded replacements, to avoid having to step through chars in char arrays. CaseFolding.foldIfDefined could return the full expansion as a long. It may be profitable to use Arrays.mismatch again after expanded characters are determined to be equal. Take another look at the data structure storing and doing the lookup of foldIfDefined both to increase the lookup performance. src/java.base/share/classes/jdk/internal/lang/CaseFolding.java.template line 230: > 228: private static class CaseFoldingEntry { > 229: final int cp; > 230: final char[] folding; Consider storing the folding as a int or long directly to avoid the overhead of small char arrays. Arrange to be able to compare the whole replacement with another codePoint, etc. src/java.base/share/classes/jdk/internal/lang/CaseFolding.java.template line 280: > 278: } > 279: > 280: private void add(CaseFoldingEntry entry) { CDS can map whole objects/data structures into the heap; consider how to make this data structure so it can be mapped and not re-computed each startup. ------------- PR Review: https://git.openjdk.org/jdk/pull/27628#pullrequestreview-3312084027 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2412043131 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2412060747 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2412062604 From jlu at openjdk.org Tue Oct 7 23:52:37 2025 From: jlu at openjdk.org (Justin Lu) Date: Tue, 7 Oct 2025 23:52:37 GMT Subject: RFR: 8369050: DecimalFormat Rounding Errors for Ties Torwards 1 in LSD or 0 Message-ID: Please review this PR which corrects a rounding error for DecimalFormat on tie cases when the maximum fraction digits allowed is one less than the position of the first significant digit in the double rounded. For example, rounding a value such as 0.0005 to a maximum of 3 fractional digits. In order to get the correct `count` value, we must strip the trailing zeros prior to the check to ensure we have the correct value of `count` = 1 so that we can go down the _Rounding position is the last index_ case which properly checks if the String double was already rounded or is exact from its true decimal form. ------------- Commit messages: - small test changes - init Changes: https://git.openjdk.org/jdk/pull/27681/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=27681&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8369050 Stats: 95 lines in 3 files changed: 88 ins; 5 del; 2 mod Patch: https://git.openjdk.org/jdk/pull/27681.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27681/head:pull/27681 PR: https://git.openjdk.org/jdk/pull/27681 From jlu at openjdk.org Tue Oct 7 23:52:39 2025 From: jlu at openjdk.org (Justin Lu) Date: Tue, 7 Oct 2025 23:52:39 GMT Subject: RFR: 8369050: DecimalFormat Rounding Errors for Ties Torwards 1 in LSD or 0 In-Reply-To: References: Message-ID: On Tue, 7 Oct 2025 23:19:28 GMT, Justin Lu wrote: > Please review this PR which corrects a rounding error for DecimalFormat on tie cases when the maximum fraction digits allowed is one less than the position of the first significant digit in the double rounded. For example, rounding a value such as 0.0005 to a maximum of 3 fractional digits. In order to get the correct `count` value, we must strip the trailing zeros prior to the check to ensure we have the correct value of `count` = 1 so that we can go down the _Rounding position is the last index_ case which properly checks if the String double was already rounded or is exact from its true decimal form. For some history, this bug is long-standing, but has taken different forms after recent changes to DigitList. DigitList, when handling the specific case as mentioned in the summary statement returns a faulty value due to an incorrect value of `count`. DigitList used to parse its own `count` value, but was recently changed in [JDK-8367324](https://bugs.openjdk.org/browse/JDK-8367324) to retrieve `count`from `FloatingDecimal`. Consider the double `0.00005` rounded to 4 fractional digits, `count` prior to JDK-8367324 would be calculated as 2 while it is now calculated as 17 due to the implementation differences. Thus, when handling the following case, } else if (-decimalAt == maximumDigits) { // If we round 0.0009 to 3 fractional digits, then we have to // create a new one digit in the least significant location. if (shouldRoundUp(0, roundedUp, valueExactAsDecimal)) { count = 1; ++decimalAt; digits[0] = '1'; } else { For both `count` values, `if (maximumDigits == (count - 1))` is erroneously evaluated in `shouldRoundUp` under the HALF_* cases and instead falls under the _Rounding position is not the last index_ case. Notice that before JDK-8367324, `count` was still being read **incorrectly** as 2 (for fractional doubles in exponential form). However, the behavioral differences had not been observed, since the HALF_UP/DOWN cases prior to https://bugs.openjdk.org/browse/JDK-8314169 could return the right values by chance when going down the wrong path. test/jdk/java/text/Format/DecimalFormat/RoundingToLSDTieTest.java line 1: > 1: /* I considered adding the tests in this file under _TieRoundingTest_, but did not do so to make review easier since JUnit could be used for the test in this PR. (_TieRoundingTest_ is old and does not use JUnit.) Will consider updating _TieRoundingTest_ to use JUnit and merging the tests in this PR under it in a separate issue. test/jdk/java/text/Format/NumberFormat/NumberRegression.java line 1779: > 1777: "0%", "0%", "1%", "1%", "1%", > 1778: "0", "2", "0.2", "0.6", "0.04", > 1779: "0.04", "0.001", "0.002", This test is checking that `.0005` rounded to 3 digits is "0.000" under HALF_EVEN. This is wrong. See, `new BigDecimal(0.0005) ==> 0.0005000000000000000104083408558608425664715468883514404296875`. Resolving the bug in this PR requires fixing this incorrect test case. From the JDK-4241880 issue, it seems this case may have been put in to "document the incorrect but actual behavior". ------------- PR Comment: https://git.openjdk.org/jdk/pull/27681#issuecomment-3379027299 PR Review Comment: https://git.openjdk.org/jdk/pull/27681#discussion_r2412168905 PR Review Comment: https://git.openjdk.org/jdk/pull/27681#discussion_r2412167812 From sherman at openjdk.org Wed Oct 8 00:33:20 2025 From: sherman at openjdk.org (Xueming Shen) Date: Wed, 8 Oct 2025 00:33:20 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v2] In-Reply-To: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> Message-ID: > ### Summary > > Case folding is a key operation for case-insensitive matching (e.g., string equality, regex matching), where the goal is to eliminate case distinctions without applying locale or language specific conversions. > > Currently, the JDK does not expose a direct API for Unicode-compliant case folding. Developers now rely on methods such as: > > **String.equalsIgnoreCase(String)** > > - Unicode-aware, locale-independent. > - Implementation uses Character.toLowerCase(Character.toUpperCase(int)) per code point. > - Limited: does not support 1:M mapping defined in Unicode case folding. > > **Character.toLowerCase(int) / Character.toUpperCase(int)** > > - Locale-independent, single code point only. > - No support for 1:M mappings. > > **String.toLowerCase(Locale.ROOT) / String.toUpperCase(Locale.ROOT)** > > - Based on Unicode SpecialCasing.txt, supports 1:M mappings. > - Intended primarily for presentation/display, not structural case-insensitive matching. > - Requires full string conversion before comparison, which is less efficient and not intended for structural matching. > > **1:M mapping example, U+00DF (?)** > > - String.toUpperCase(Locale.ROOT, "?") ? "SS" > - Case folding produces "ss", matching Unicode caseless comparison rules. > > > jshell> "\u00df".equalsIgnoreCase("ss") > $22 ==> false > > jshell> "\u00df".toUpperCase(Locale.ROOT).toLowerCase(Locale.ROOT).equals("ss") > $24 ==> true > > > ### Motivation & Direction > > Add Unicode standard-compliant case-less comparison methods to the String class, enabling & improving reliable and efficient Unicode-aware/compliant case-insensitive matching. > > - Unicode-compliant **full** case folding. > - Simpler, stable and more efficient case-less matching without workarounds. > - Brings Java's string comparison handling in line with other programming languages/libraries. > > This PR proposes to introduce the following comparison methods in `String` class > > - boolean equalsFoldCase(String anotherString) > - int compareToFoldCase(String anotherString) > - Comparator UNICODE_CASEFOLD_ORDER > > These methods are intended to be the preferred choice when Unicode-compliant case-less matching is required. > > *Note: An early draft also proposed a String.toCaseFold() method returning a new case-folded string. > However, during review this was considered error-prone, as the resulting string could easily be mistaken for a general transformation like toLowerCase() and then passed into APIs where case-folding semantics are not appropriate. > > ### The New API > > See CSR https://bugs.openjd... Xueming Shen has updated the pull request incrementally with one additional commit since the last revision: minor api doc updates ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27628/files - new: https://git.openjdk.org/jdk/pull/27628/files/1abb0228..9d9997dc Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27628&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27628&range=00-01 Stats: 18 lines in 1 file changed: 5 ins; 2 del; 11 mod Patch: https://git.openjdk.org/jdk/pull/27628.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27628/head:pull/27628 PR: https://git.openjdk.org/jdk/pull/27628 From rriggs at openjdk.org Wed Oct 8 13:24:48 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Wed, 8 Oct 2025 13:24:48 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v2] In-Reply-To: References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> Message-ID: On Tue, 7 Oct 2025 22:18:58 GMT, Roger Riggs wrote: >> Xueming Shen has updated the pull request incrementally with one additional commit since the last revision: >> >> minor api doc updates > > src/java.base/share/classes/jdk/internal/lang/CaseFolding.java.template line 230: > >> 228: private static class CaseFoldingEntry { >> 229: final int cp; >> 230: final char[] folding; > > Consider storing the folding as a int or long directly to avoid the overhead of small char arrays. > Arrange to be able to compare the whole replacement with another codePoint, etc. I misunderstood the algorithm when comparing folded characters against non-folded sequences. I still think a fast path for single character replacements will lower memory costs and improve performance. The case of single-codepoint to single-codepoint dominates the case folding mappings. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2413846987 From liach at openjdk.org Wed Oct 8 14:14:26 2025 From: liach at openjdk.org (Chen Liang) Date: Wed, 8 Oct 2025 14:14:26 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v2] In-Reply-To: References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> Message-ID: On Wed, 8 Oct 2025 00:33:20 GMT, Xueming Shen wrote: >> ### Summary >> >> Case folding is a key operation for case-insensitive matching (e.g., string equality, regex matching), where the goal is to eliminate case distinctions without applying locale or language specific conversions. >> >> Currently, the JDK does not expose a direct API for Unicode-compliant case folding. Developers now rely on methods such as: >> >> **String.equalsIgnoreCase(String)** >> >> - Unicode-aware, locale-independent. >> - Implementation uses Character.toLowerCase(Character.toUpperCase(int)) per code point. >> - Limited: does not support 1:M mapping defined in Unicode case folding. >> >> **Character.toLowerCase(int) / Character.toUpperCase(int)** >> >> - Locale-independent, single code point only. >> - No support for 1:M mappings. >> >> **String.toLowerCase(Locale.ROOT) / String.toUpperCase(Locale.ROOT)** >> >> - Based on Unicode SpecialCasing.txt, supports 1:M mappings. >> - Intended primarily for presentation/display, not structural case-insensitive matching. >> - Requires full string conversion before comparison, which is less efficient and not intended for structural matching. >> >> **1:M mapping example, U+00DF (?)** >> >> - String.toUpperCase(Locale.ROOT, "?") ? "SS" >> - Case folding produces "ss", matching Unicode caseless comparison rules. >> >> >> jshell> "\u00df".equalsIgnoreCase("ss") >> $22 ==> false >> >> jshell> "\u00df".toUpperCase(Locale.ROOT).toLowerCase(Locale.ROOT).equals("ss") >> $24 ==> true >> >> >> ### Motivation & Direction >> >> Add Unicode standard-compliant case-less comparison methods to the String class, enabling & improving reliable and efficient Unicode-aware/compliant case-insensitive matching. >> >> - Unicode-compliant **full** case folding. >> - Simpler, stable and more efficient case-less matching without workarounds. >> - Brings Java's string comparison handling in line with other programming languages/libraries. >> >> This PR proposes to introduce the following comparison methods in `String` class >> >> - boolean equalsFoldCase(String anotherString) >> - int compareToFoldCase(String anotherString) >> - Comparator UNICODE_CASEFOLD_ORDER >> >> These methods are intended to be the preferred choice when Unicode-compliant case-less matching is required. >> >> *Note: An early draft also proposed a String.toCaseFold() method returning a new case-folded string. >> However, during review this was considered error-prone, as the resulting string could easily be mistaken for a general transformation like toLowerCase() and then pass... > > Xueming Shen has updated the pull request incrementally with one additional commit since the last revision: > > minor api doc updates Given this patch obviously has so many performance optimization opportunities, I recommend handling those in subsequent RFEs so that we can review this purely from a specification point of view. make/modules/java.base/gensrc/GensrcCharacterData.gmk line 76: > 74: > 75: > 76: GENSRC_STRINGCASEFOLDING := $(SUPPORT_OUTPUTDIR)/gensrc/java.base/jdk/internal/java/lang/CaseFolding.java Can we target the package `jdk.internal.lang` instead of `jdk.internal.java.lang`? I think the previous one is the convention set forth by stable values. ------------- PR Review: https://git.openjdk.org/jdk/pull/27628#pullrequestreview-3314954963 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2413957017 From rriggs at openjdk.org Wed Oct 8 14:38:26 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Wed, 8 Oct 2025 14:38:26 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v2] In-Reply-To: References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> Message-ID: On Wed, 8 Oct 2025 14:11:28 GMT, Chen Liang wrote: > Given this patch obviously has so many performance optimization opportunities, I recommend handling those in subsequent RFEs so that we can review this purely from a specification point of view. There is adequate time before RPD1 (Dec 4, 25) to improve performance, but the feature should not be included in JDK 26 unless the performance is comparable to the existing `compareToIgnoreCase` and `equalsIgnoreCase`. ------------- PR Comment: https://git.openjdk.org/jdk/pull/27628#issuecomment-3381857251 From rriggs at openjdk.org Wed Oct 8 16:28:09 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Wed, 8 Oct 2025 16:28:09 GMT Subject: RFR: 8369184: SimpleTimeZone equals() Returns True for Unequal Instances with Different hashCode Values [v3] In-Reply-To: References: Message-ID: On Tue, 7 Oct 2025 20:43:20 GMT, Naoto Sato wrote: >> Fixing the equals/hashCode contract in the SimpleTimeZone class. The current implementation includes DST rule fields in hash code computation even for zones that do not observe DST, while equals() always considers them. Also correcting the example code in the class description, where it used 20-year-old obsolete "America/Los_Angeles" rule. > > Naoto Sato has updated the pull request incrementally with one additional commit since the last revision: > > Address review comments LGTM ------------- Marked as reviewed by rriggs (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/27660#pullrequestreview-3315634206 From iris at openjdk.org Wed Oct 8 16:34:07 2025 From: iris at openjdk.org (Iris Clark) Date: Wed, 8 Oct 2025 16:34:07 GMT Subject: RFR: 8369184: SimpleTimeZone equals() Returns True for Unequal Instances with Different hashCode Values [v3] In-Reply-To: References: Message-ID: On Tue, 7 Oct 2025 20:43:20 GMT, Naoto Sato wrote: >> Fixing the equals/hashCode contract in the SimpleTimeZone class. The current implementation includes DST rule fields in hash code computation even for zones that do not observe DST, while equals() always considers them. Also correcting the example code in the class description, where it used 20-year-old obsolete "America/Los_Angeles" rule. > > Naoto Sato has updated the pull request incrementally with one additional commit since the last revision: > > Address review comments Marked as reviewed by iris (Reviewer). ------------- PR Review: https://git.openjdk.org/jdk/pull/27660#pullrequestreview-3315652499 From duke at openjdk.org Wed Oct 8 16:35:05 2025 From: duke at openjdk.org (Bernd) Date: Wed, 8 Oct 2025 16:35:05 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v2] In-Reply-To: References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> Message-ID: <9c13AiS1RTrKhWGiVifePZ4CZa7Iws-AirXB-YMR4NQ=.cc24d342-334f-4be1-b886-7efd2c0a8898@github.com> On Wed, 8 Oct 2025 00:33:20 GMT, Xueming Shen wrote: >> ### Summary >> >> Case folding is a key operation for case-insensitive matching (e.g., string equality, regex matching), where the goal is to eliminate case distinctions without applying locale or language specific conversions. >> >> Currently, the JDK does not expose a direct API for Unicode-compliant case folding. Developers now rely on methods such as: >> >> **String.equalsIgnoreCase(String)** >> >> - Unicode-aware, locale-independent. >> - Implementation uses Character.toLowerCase(Character.toUpperCase(int)) per code point. >> - Limited: does not support 1:M mapping defined in Unicode case folding. >> >> **Character.toLowerCase(int) / Character.toUpperCase(int)** >> >> - Locale-independent, single code point only. >> - No support for 1:M mappings. >> >> **String.toLowerCase(Locale.ROOT) / String.toUpperCase(Locale.ROOT)** >> >> - Based on Unicode SpecialCasing.txt, supports 1:M mappings. >> - Intended primarily for presentation/display, not structural case-insensitive matching. >> - Requires full string conversion before comparison, which is less efficient and not intended for structural matching. >> >> **1:M mapping example, U+00DF (?)** >> >> - String.toUpperCase(Locale.ROOT, "?") ? "SS" >> - Case folding produces "ss", matching Unicode caseless comparison rules. >> >> >> jshell> "\u00df".equalsIgnoreCase("ss") >> $22 ==> false >> >> jshell> "\u00df".toUpperCase(Locale.ROOT).toLowerCase(Locale.ROOT).equals("ss") >> $24 ==> true >> >> >> ### Motivation & Direction >> >> Add Unicode standard-compliant case-less comparison methods to the String class, enabling & improving reliable and efficient Unicode-aware/compliant case-insensitive matching. >> >> - Unicode-compliant **full** case folding. >> - Simpler, stable and more efficient case-less matching without workarounds. >> - Brings Java's string comparison handling in line with other programming languages/libraries. >> >> This PR proposes to introduce the following comparison methods in `String` class >> >> - boolean equalsFoldCase(String anotherString) >> - int compareToFoldCase(String anotherString) >> - Comparator UNICODE_CASEFOLD_ORDER >> >> These methods are intended to be the preferred choice when Unicode-compliant case-less matching is required. >> >> *Note: An early draft also proposed a String.toCaseFold() method returning a new case-folded string. >> However, during review this was considered error-prone, as the resulting string could easily be mistaken for a general transformation like toLowerCase() and then pass... > > Xueming Shen has updated the pull request incrementally with one additional commit since the last revision: > > minor api doc updates Great progress thanks. Did you also consider a startsWith/containsCaseFold, I missed the case ignoring variants of those already. Or maybe provide an API to implement them on the cases folded intermediate buffers? If the API footprint gets too big on String as CaseFoldString.contains() helper maybe? ------------- PR Comment: https://git.openjdk.org/jdk/pull/27628#issuecomment-3382351349 From jlu at openjdk.org Wed Oct 8 17:27:15 2025 From: jlu at openjdk.org (Justin Lu) Date: Wed, 8 Oct 2025 17:27:15 GMT Subject: RFR: 8369184: SimpleTimeZone equals() Returns True for Unequal Instances with Different hashCode Values [v3] In-Reply-To: References: Message-ID: On Tue, 7 Oct 2025 20:43:20 GMT, Naoto Sato wrote: >> Fixing the equals/hashCode contract in the SimpleTimeZone class. The current implementation includes DST rule fields in hash code computation even for zones that do not observe DST, while equals() always considers them. Also correcting the example code in the class description, where it used 20-year-old obsolete "America/Los_Angeles" rule. > > Naoto Sato has updated the pull request incrementally with one additional commit since the last revision: > > Address review comments src/java.base/share/classes/java/util/SimpleTimeZone.java line 112: > 110: *

> 111: * The following are examples of parameters for constructing time zone objects. > 112: *



We can consider replacing `
` with `@snippet` so that the code example can be copied by readers. Although I understand if leaving it for another time as to not invalidate the existing approvals.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/27660#discussion_r2414548133

From prappo at openjdk.org  Wed Oct  8 17:36:50 2025
From: prappo at openjdk.org (Pavel Rappo)
Date: Wed, 8 Oct 2025 17:36:50 GMT
Subject:  RFR: 8369184: SimpleTimeZone equals() Returns True
 for Unequal Instances with Different hashCode Values [v3]
In-Reply-To: 
References: 
 
 
Message-ID: 

On Wed, 8 Oct 2025 17:24:19 GMT, Justin Lu  wrote:

>> Naoto Sato has updated the pull request incrementally with one additional commit since the last revision:
>> 
>>   Address review comments
>
> src/java.base/share/classes/java/util/SimpleTimeZone.java line 112:
> 
>> 110:  * 

>> 111: * The following are examples of parameters for constructing time zone objects. >> 112: *


> 
> We can consider replacing `
` with `@snippet` so that the code example can be copied by readers. Although I understand if leaving it for another time as to not invalidate the existing approvals.

I think, that's out of scope for this PR.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/27660#discussion_r2414569959

From naoto at openjdk.org  Wed Oct  8 17:42:44 2025
From: naoto at openjdk.org (Naoto Sato)
Date: Wed, 8 Oct 2025 17:42:44 GMT
Subject:  RFR: 8369050: DecimalFormat Rounding Errors for Ties
 Torwards 1 in LSD or 0
In-Reply-To: 
References: 
Message-ID: 

On Tue, 7 Oct 2025 23:19:28 GMT, Justin Lu  wrote:

> Please review this PR which corrects a rounding error for DecimalFormat on tie cases when the maximum fraction digits allowed is one less than the position of the first significant digit in the double rounded. For example, rounding a value such as 0.0005 to a maximum of 3 fractional digits. In order to get the correct `count` value, we must strip the trailing zeros prior to the check to ensure we have the correct value of `count` = 1 so that we can go down the _Rounding position is the last index_ case which properly checks if the String double was already rounded or is exact from its true decimal form.

LGTM

-------------

PR Review: https://git.openjdk.org/jdk/pull/27681#pullrequestreview-3315869483

From naoto at openjdk.org  Wed Oct  8 17:42:47 2025
From: naoto at openjdk.org (Naoto Sato)
Date: Wed, 8 Oct 2025 17:42:47 GMT
Subject:  RFR: 8369050: DecimalFormat Rounding Errors for Ties
 Torwards 1 in LSD or 0
In-Reply-To: 
References: 
 
Message-ID: 

On Tue, 7 Oct 2025 23:34:49 GMT, Justin Lu  wrote:

>> Please review this PR which corrects a rounding error for DecimalFormat on tie cases when the maximum fraction digits allowed is one less than the position of the first significant digit in the double rounded. For example, rounding a value such as 0.0005 to a maximum of 3 fractional digits. In order to get the correct `count` value, we must strip the trailing zeros prior to the check to ensure we have the correct value of `count` = 1 so that we can go down the _Rounding position is the last index_ case which properly checks if the String double was already rounded or is exact from its true decimal form.
>
> test/jdk/java/text/Format/DecimalFormat/RoundingToLSDTieTest.java line 1:
> 
>> 1: /*
> 
> I considered adding the tests in this file under _TieRoundingTest_, but did not do so to make review easier since JUnit could be used for the test in this PR. (_TieRoundingTest_ is old and does not use JUnit.) Will consider updating  _TieRoundingTest_ to use JUnit and merging the tests in this PR under it in a separate issue.

I think "LSD" is a bit cryptic. I'd spell-out or replace with other words if possible (and the PR/JBS titles too)

> test/jdk/java/text/Format/NumberFormat/NumberRegression.java line 1779:
> 
>> 1777:                 "0%", "0%", "1%", "1%", "1%",
>> 1778:                 "0", "2", "0.2", "0.6", "0.04",
>> 1779:                 "0.04", "0.001", "0.002",
> 
> This test is checking that `.0005` rounded to 3 digits is "0.000" under HALF_EVEN.
> 
> This is wrong. See,
> `new BigDecimal(0.0005) ==> 0.0005000000000000000104083408558608425664715468883514404296875`. 
> 
> Resolving the bug in this PR requires fixing this incorrect test case. From the JDK-4241880 issue, it seems this case may have been put in to "document the incorrect but actual behavior".

I guess this is the exact case this fix is trying to address, but the expected result wrongly assumes the behavior.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/27681#discussion_r2414578536
PR Review Comment: https://git.openjdk.org/jdk/pull/27681#discussion_r2414581725

From prappo at openjdk.org  Wed Oct  8 17:50:36 2025
From: prappo at openjdk.org (Pavel Rappo)
Date: Wed, 8 Oct 2025 17:50:36 GMT
Subject:  RFR: 8369184: SimpleTimeZone equals() Returns True
 for Unequal Instances with Different hashCode Values [v3]
In-Reply-To: 
References: 
 
Message-ID: 

On Tue, 7 Oct 2025 20:43:20 GMT, Naoto Sato  wrote:

>> Fixing the equals/hashCode contract in the SimpleTimeZone class. The current implementation includes DST rule fields in hash code computation even for zones that do not observe DST, while equals() always considers them. Also correcting the example code in the class description, where it used 20-year-old obsolete "America/Los_Angeles" rule.
>
> Naoto Sato has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Address review comments

test/jdk/java/util/TimeZone/SimpleTimeZoneEqualsHashCodeTest.java line 59:

> 57:         assertNotEquals(STZ_WITH_DST, stz);
> 58:         // from the contract point, hash codes may be the same
> 59:         assertNotEquals(STZ_WITH_DST.hashCode(), stz.hashCode());

Like you said, from `!a.equals(b)` it does not follow that `a.hashCode() != b.hashCode()`. Unless you want hash code to specifically have this additional property, I'd remove this assertion.

test/jdk/java/util/TimeZone/SimpleTimeZoneEqualsHashCodeTest.java line 63:

> 61: 
> 62:     @Test
> 63:     void withOutDSTTest() {

Nit, really:

Suggestion:

    void withoutDSTTest() {

test/jdk/java/util/TimeZone/SimpleTimeZoneEqualsHashCodeTest.java line 76:

> 74:         assertTrue(stz.useDaylightTime());
> 75:         assertNotEquals(STZ_WITHOUT_DST, stz);
> 76:         assertNotEquals(STZ_WITHOUT_DST.hashCode(), stz.hashCode());

Ditto on equals-hashCode contract.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/27660#discussion_r2414592801
PR Review Comment: https://git.openjdk.org/jdk/pull/27660#discussion_r2414583906
PR Review Comment: https://git.openjdk.org/jdk/pull/27660#discussion_r2414599801

From jlu at openjdk.org  Wed Oct  8 18:06:05 2025
From: jlu at openjdk.org (Justin Lu)
Date: Wed, 8 Oct 2025 18:06:05 GMT
Subject:  RFR: 8369050: DecimalFormat Rounding Errors for Ties
 Torwards 1 in LSD or 0
In-Reply-To: 
References: 
 
 
Message-ID: <-I2YDnaUqYuCyjvA0SZizCDga9zYdd4NVwvQjVjzn7I=.e82f011e-4801-436f-8b43-a8bf210b9efa@github.com>

On Wed, 8 Oct 2025 17:39:39 GMT, Naoto Sato  wrote:

>> test/jdk/java/text/Format/NumberFormat/NumberRegression.java line 1779:
>> 
>>> 1777:                 "0%", "0%", "1%", "1%", "1%",
>>> 1778:                 "0", "2", "0.2", "0.6", "0.04",
>>> 1779:                 "0.04", "0.001", "0.002",
>> 
>> This test is checking that `.0005` rounded to 3 digits is "0.000" under HALF_EVEN.
>> 
>> This is wrong. See,
>> `new BigDecimal(0.0005) ==> 0.0005000000000000000104083408558608425664715468883514404296875`. 
>> 
>> Resolving the bug in this PR requires fixing this incorrect test case. From the JDK-4241880 issue, it seems this case may have been put in to "document the incorrect but actual behavior".
>
> I guess this is the exact case this fix is trying to address, but the expected result wrongly assumes the behavior.

Right. This code used to return "0.000" because `count` would erroneously not be `1` for this specific case, hence going down the "there are additional digits" path. For HALF_EVEN, this returns true if there are additional non-zero digits past the last index. As there are none because the String double is given as ".0005", it rounded down.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/27681#discussion_r2414634438

From naoto at openjdk.org  Wed Oct  8 18:08:38 2025
From: naoto at openjdk.org (Naoto Sato)
Date: Wed, 8 Oct 2025 18:08:38 GMT
Subject:  RFR: 8369184: SimpleTimeZone equals() Returns True
 for Unequal Instances with Different hashCode Values [v4]
In-Reply-To: 
References: 
Message-ID: <9bOsoI7nGhYmcdwG8zRjBS74Oca_N5Cfh11iRaAP0oM=.68e1add0-b309-409b-ba95-b583ce99d44f@github.com>

> Fixing the equals/hashCode contract in the SimpleTimeZone class. The current implementation includes DST rule fields in hash code computation even for zones that do not observe DST, while equals() always considers them. Also correcting the example code in the class description, where it used 20-year-old obsolete "America/Los_Angeles" rule.

Naoto Sato has updated the pull request incrementally with one additional commit since the last revision:

  Apply suggestion from @pavelrappo
  
  Co-authored-by: Pavel Rappo <32523691+pavelrappo at users.noreply.github.com>

-------------

Changes:
  - all: https://git.openjdk.org/jdk/pull/27660/files
  - new: https://git.openjdk.org/jdk/pull/27660/files/aafdf18b..e764e2a6

Webrevs:
 - full: https://webrevs.openjdk.org/?repo=jdk&pr=27660&range=03
 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27660&range=02-03

  Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod
  Patch: https://git.openjdk.org/jdk/pull/27660.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/27660/head:pull/27660

PR: https://git.openjdk.org/jdk/pull/27660

From jlu at openjdk.org  Wed Oct  8 18:10:31 2025
From: jlu at openjdk.org (Justin Lu)
Date: Wed, 8 Oct 2025 18:10:31 GMT
Subject:  RFR: 8369050: DecimalFormat Rounding Errors for
 Fractional Ties Near Zero [v2]
In-Reply-To: 
References: 
Message-ID: <27RVFebqGufV83sFeY124966lHN1oi2x2Baa_p0P04Q=.319bfbc4-7fe0-4f3b-a66f-f4e52a8db928@github.com>

> Please review this PR which corrects a rounding error for DecimalFormat on tie cases when the maximum fraction digits allowed is one less than the position of the first significant digit in the double rounded. For example, rounding a value such as 0.0005 to a maximum of 3 fractional digits. In order to get the correct `count` value, we must strip the trailing zeros prior to the check to ensure we have the correct value of `count` = 1 so that we can go down the _Rounding position is the last index_ case which properly checks if the String double was already rounded or is exact from its true decimal form.

Justin Lu has updated the pull request incrementally with one additional commit since the last revision:

  Naoto's review -> test file rename

-------------

Changes:
  - all: https://git.openjdk.org/jdk/pull/27681/files
  - new: https://git.openjdk.org/jdk/pull/27681/files/6d22124e..1ebf7b0e

Webrevs:
 - full: https://webrevs.openjdk.org/?repo=jdk&pr=27681&range=01
 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27681&range=00-01

  Stats: 2 lines in 1 file changed: 0 ins; 0 del; 2 mod
  Patch: https://git.openjdk.org/jdk/pull/27681.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/27681/head:pull/27681

PR: https://git.openjdk.org/jdk/pull/27681

From naoto at openjdk.org  Wed Oct  8 18:15:39 2025
From: naoto at openjdk.org (Naoto Sato)
Date: Wed, 8 Oct 2025 18:15:39 GMT
Subject:  RFR: 8369184: SimpleTimeZone equals() Returns True
 for Unequal Instances with Different hashCode Values [v5]
In-Reply-To: 
References: 
Message-ID: 

> Fixing the equals/hashCode contract in the SimpleTimeZone class. The current implementation includes DST rule fields in hash code computation even for zones that do not observe DST, while equals() always considers them. Also correcting the example code in the class description, where it used 20-year-old obsolete "America/Los_Angeles" rule.

Naoto Sato has updated the pull request incrementally with one additional commit since the last revision:

  Reflects review comments

-------------

Changes:
  - all: https://git.openjdk.org/jdk/pull/27660/files
  - new: https://git.openjdk.org/jdk/pull/27660/files/e764e2a6..75ec7e71

Webrevs:
 - full: https://webrevs.openjdk.org/?repo=jdk&pr=27660&range=04
 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27660&range=03-04

  Stats: 6 lines in 1 file changed: 5 ins; 0 del; 1 mod
  Patch: https://git.openjdk.org/jdk/pull/27660.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/27660/head:pull/27660

PR: https://git.openjdk.org/jdk/pull/27660

From prappo at openjdk.org  Wed Oct  8 18:15:40 2025
From: prappo at openjdk.org (Pavel Rappo)
Date: Wed, 8 Oct 2025 18:15:40 GMT
Subject:  RFR: 8369184: SimpleTimeZone equals() Returns True
 for Unequal Instances with Different hashCode Values [v5]
In-Reply-To: 
References: 
 
Message-ID: 

On Wed, 8 Oct 2025 18:12:45 GMT, Naoto Sato  wrote:

>> Fixing the equals/hashCode contract in the SimpleTimeZone class. The current implementation includes DST rule fields in hash code computation even for zones that do not observe DST, while equals() always considers them. Also correcting the example code in the class description, where it used 20-year-old obsolete "America/Los_Angeles" rule.
>
> Naoto Sato has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Reflects review comments

Marked as reviewed by prappo (Reviewer).

-------------

PR Review: https://git.openjdk.org/jdk/pull/27660#pullrequestreview-3315973763

From naoto at openjdk.org  Wed Oct  8 18:15:42 2025
From: naoto at openjdk.org (Naoto Sato)
Date: Wed, 8 Oct 2025 18:15:42 GMT
Subject:  RFR: 8369184: SimpleTimeZone equals() Returns True
 for Unequal Instances with Different hashCode Values [v3]
In-Reply-To: 
References: 
 
 
Message-ID: 

On Wed, 8 Oct 2025 17:44:43 GMT, Pavel Rappo  wrote:

>> Naoto Sato has updated the pull request incrementally with one additional commit since the last revision:
>> 
>>   Address review comments
>
> test/jdk/java/util/TimeZone/SimpleTimeZoneEqualsHashCodeTest.java line 59:
> 
>> 57:         assertNotEquals(STZ_WITH_DST, stz);
>> 58:         // from the contract point, hash codes may be the same
>> 59:         assertNotEquals(STZ_WITH_DST.hashCode(), stz.hashCode());
> 
> Like you said, from `!a.equals(b)` it does not follow that `a.hashCode() != b.hashCode()`. Unless you want hash code to specifically have this additional property, I'd remove this assertion.

I wanted to test the implementation which takes DST related fields into consideration for hash code calculation. Added some comments for clarity

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/27660#discussion_r2414647340

From liach at openjdk.org  Wed Oct  8 18:23:26 2025
From: liach at openjdk.org (Chen Liang)
Date: Wed, 8 Oct 2025 18:23:26 GMT
Subject:  RFR: 8365675: Add String Unicode Case-Folding
 Support [v2]
In-Reply-To: <9c13AiS1RTrKhWGiVifePZ4CZa7Iws-AirXB-YMR4NQ=.cc24d342-334f-4be1-b886-7efd2c0a8898@github.com>
References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com>
 
 <9c13AiS1RTrKhWGiVifePZ4CZa7Iws-AirXB-YMR4NQ=.cc24d342-334f-4be1-b886-7efd2c0a8898@github.com>
Message-ID: 

On Wed, 8 Oct 2025 16:31:53 GMT, Bernd  wrote:

> Did you also consider a startsWith/containsCaseFold, I missed the case ignoring variants of those already.

I think for this purpose, we should rather introduce an API to case fold a string - we can use these operations on the case-fold-normalized strings.

-------------

PR Comment: https://git.openjdk.org/jdk/pull/27628#issuecomment-3382715644

From naoto at openjdk.org  Wed Oct  8 18:26:25 2025
From: naoto at openjdk.org (Naoto Sato)
Date: Wed, 8 Oct 2025 18:26:25 GMT
Subject:  RFR: 8369050: DecimalFormat Rounding Errors for
 Fractional Ties Near Zero [v2]
In-Reply-To: <27RVFebqGufV83sFeY124966lHN1oi2x2Baa_p0P04Q=.319bfbc4-7fe0-4f3b-a66f-f4e52a8db928@github.com>
References: 
 <27RVFebqGufV83sFeY124966lHN1oi2x2Baa_p0P04Q=.319bfbc4-7fe0-4f3b-a66f-f4e52a8db928@github.com>
Message-ID: 

On Wed, 8 Oct 2025 18:10:31 GMT, Justin Lu  wrote:

>> Please review this PR which corrects a rounding error for DecimalFormat on tie cases when the maximum fraction digits allowed is one less than the position of the first significant digit in the double rounded. For example, rounding a value such as 0.0005 to a maximum of 3 fractional digits. In order to get the correct `count` value, we must strip the trailing zeros prior to the check to ensure we have the correct value of `count` = 1 so that we can go down the _Rounding position is the last index_ case which properly checks if the String double was already rounded or is exact from its true decimal form.
>
> Justin Lu has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Naoto's review -> test file rename

Marked as reviewed by naoto (Reviewer).

-------------

PR Review: https://git.openjdk.org/jdk/pull/27681#pullrequestreview-3316021946

From rriggs at openjdk.org  Wed Oct  8 18:40:58 2025
From: rriggs at openjdk.org (Roger Riggs)
Date: Wed, 8 Oct 2025 18:40:58 GMT
Subject:  RFR: 8365675: Add String Unicode Case-Folding
 Support [v2]
In-Reply-To: 
References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com>
 
Message-ID: 

On Wed, 8 Oct 2025 00:33:20 GMT, Xueming Shen  wrote:

>> ### Summary
>> 
>> Case folding is a key operation for case-insensitive matching (e.g., string equality, regex matching), where the goal is to eliminate case distinctions without applying locale or language specific conversions.
>> 
>> Currently, the JDK does not expose a direct API for Unicode-compliant case folding. Developers now rely on methods such as:
>> 
>> **String.equalsIgnoreCase(String)**
>> 
>> - Unicode-aware, locale-independent.
>> - Implementation uses Character.toLowerCase(Character.toUpperCase(int)) per code point.
>> - Limited: does not support 1:M mapping defined in Unicode case folding.
>> 
>> **Character.toLowerCase(int) / Character.toUpperCase(int)**
>> 
>> - Locale-independent, single code point only.
>> - No support for 1:M mappings.
>> 
>> **String.toLowerCase(Locale.ROOT) / String.toUpperCase(Locale.ROOT)**
>> 
>> - Based on Unicode SpecialCasing.txt, supports 1:M mappings.
>> - Intended primarily for presentation/display, not structural case-insensitive matching.
>> - Requires full string conversion before comparison, which is less efficient and not intended for structural matching.
>> 
>> **1:M mapping example, U+00DF (?)**
>> 
>> - String.toUpperCase(Locale.ROOT, "?") ? "SS"
>> - Case folding produces "ss", matching Unicode caseless comparison rules.
>> 
>> 
>> jshell> "\u00df".equalsIgnoreCase("ss")
>> $22 ==> false
>> 
>> jshell> "\u00df".toUpperCase(Locale.ROOT).toLowerCase(Locale.ROOT).equals("ss")
>> $24 ==> true
>> 
>> 
>> ### Motivation & Direction
>> 
>> Add Unicode standard-compliant case-less comparison methods to the String class, enabling & improving reliable and efficient Unicode-aware/compliant case-insensitive matching.
>> 
>> - Unicode-compliant **full** case folding.
>> - Simpler, stable and more efficient case-less matching without workarounds.
>> - Brings Java's string comparison handling in line with other programming languages/libraries.
>> 
>> This PR proposes to introduce the following comparison methods in `String` class
>> 
>> - boolean equalsFoldCase(String anotherString)
>> - int compareToFoldCase(String anotherString)
>> - Comparator UNICODE_CASEFOLD_ORDER
>> 
>> These methods are intended to be the preferred choice when Unicode-compliant case-less matching is required.
>> 
>> *Note: An early draft also proposed a String.toCaseFold() method returning a new case-folded string.
>> However, during review this was considered error-prone, as the resulting string could easily be mistaken for a general transformation like toLowerCase() and then pass...
>
> Xueming Shen has updated the pull request incrementally with one additional commit since the last revision:
> 
>   minor api doc updates

The new APIs mentioned would be more effective, leveraging the underlying implementation without needing to create new Strings.  Earlier discussions of the support for folding, raised a concern about tempting developers to a more ambiguous situation in which folded and unfolded strings exist and can be confused.

-------------

PR Comment: https://git.openjdk.org/jdk/pull/27628#issuecomment-3382766309

From liach at openjdk.org  Wed Oct  8 18:58:30 2025
From: liach at openjdk.org (Chen Liang)
Date: Wed, 8 Oct 2025 18:58:30 GMT
Subject:  RFR: 8365675: Add String Unicode Case-Folding
 Support [v2]
In-Reply-To: 
References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com>
 
Message-ID: 

On Wed, 8 Oct 2025 00:33:20 GMT, Xueming Shen  wrote:

>> ### Summary
>> 
>> Case folding is a key operation for case-insensitive matching (e.g., string equality, regex matching), where the goal is to eliminate case distinctions without applying locale or language specific conversions.
>> 
>> Currently, the JDK does not expose a direct API for Unicode-compliant case folding. Developers now rely on methods such as:
>> 
>> **String.equalsIgnoreCase(String)**
>> 
>> - Unicode-aware, locale-independent.
>> - Implementation uses Character.toLowerCase(Character.toUpperCase(int)) per code point.
>> - Limited: does not support 1:M mapping defined in Unicode case folding.
>> 
>> **Character.toLowerCase(int) / Character.toUpperCase(int)**
>> 
>> - Locale-independent, single code point only.
>> - No support for 1:M mappings.
>> 
>> **String.toLowerCase(Locale.ROOT) / String.toUpperCase(Locale.ROOT)**
>> 
>> - Based on Unicode SpecialCasing.txt, supports 1:M mappings.
>> - Intended primarily for presentation/display, not structural case-insensitive matching.
>> - Requires full string conversion before comparison, which is less efficient and not intended for structural matching.
>> 
>> **1:M mapping example, U+00DF (?)**
>> 
>> - String.toUpperCase(Locale.ROOT, "?") ? "SS"
>> - Case folding produces "ss", matching Unicode caseless comparison rules.
>> 
>> 
>> jshell> "\u00df".equalsIgnoreCase("ss")
>> $22 ==> false
>> 
>> jshell> "\u00df".toUpperCase(Locale.ROOT).toLowerCase(Locale.ROOT).equals("ss")
>> $24 ==> true
>> 
>> 
>> ### Motivation & Direction
>> 
>> Add Unicode standard-compliant case-less comparison methods to the String class, enabling & improving reliable and efficient Unicode-aware/compliant case-insensitive matching.
>> 
>> - Unicode-compliant **full** case folding.
>> - Simpler, stable and more efficient case-less matching without workarounds.
>> - Brings Java's string comparison handling in line with other programming languages/libraries.
>> 
>> This PR proposes to introduce the following comparison methods in `String` class
>> 
>> - boolean equalsFoldCase(String anotherString)
>> - int compareToFoldCase(String anotherString)
>> - Comparator UNICODE_CASEFOLD_ORDER
>> 
>> These methods are intended to be the preferred choice when Unicode-compliant case-less matching is required.
>> 
>> *Note: An early draft also proposed a String.toCaseFold() method returning a new case-folded string.
>> However, during review this was considered error-prone, as the resulting string could easily be mistaken for a general transformation like toLowerCase() and then pass...
>
> Xueming Shen has updated the pull request incrementally with one additional commit since the last revision:
> 
>   minor api doc updates

I don't think it's a good idea to have an explosion of case-folding variants of string operations if we are adding a case-folding overload for every operation. In that case, the confusion of case folding applicability would be less of a problem compared to the API bloat.

-------------

PR Comment: https://git.openjdk.org/jdk/pull/27628#issuecomment-3382818647

From rriggs at openjdk.org  Wed Oct  8 20:16:25 2025
From: rriggs at openjdk.org (Roger Riggs)
Date: Wed, 8 Oct 2025 20:16:25 GMT
Subject:  RFR: 8366829: Add java.time.Duration constants MIN
 and MAX [v3]
In-Reply-To: 
References: 
 
Message-ID: 

On Fri, 3 Oct 2025 09:50:23 GMT, Pavel Rappo  wrote:

>> We have [recently discussed][] a possibility of adding the `Duration.MIN` and `Duration.MAX` constants. Can we now start implementation? If and when we are in agreement on this PR, I will file a CSR.
>> 
>> I drafted a minimal specification and added some tests. I tried to phrase the spec for `Duration.MIN` in a way that makes it clear that `Duration.MIN` is the most negative value and not the least positive.
>> 
>> [recently discussed]: https://mail.openjdk.org/pipermail/core-libs-dev/2025-September/151098.html
>
> Pavel Rappo has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Respond to feedback
>   
>   Apply Stephen's suggestion on wording, although modified.

As proposed. Duration.MAX() is not the negated value of Duration.MIN.
Is there any value for them to have that mathematical property?
Duration.MIN can not be negated, it throws "Exceeds capacity of Duration".

-------------

PR Comment: https://git.openjdk.org/jdk/pull/27534#issuecomment-3383068470

From duke at openjdk.org  Thu Oct  9 16:11:02 2025
From: duke at openjdk.org (Bernd)
Date: Thu, 9 Oct 2025 16:11:02 GMT
Subject:  RFR: 8365675: Add String Unicode Case-Folding
 Support [v2]
In-Reply-To: 
References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com>
 
Message-ID: <7FNQkL6cersUolPLQ1NViK0811Mx3AkaNzid3tQktbI=.2eaa33d4-8051-486a-b305-a5d4000948de@github.com>

On Wed, 8 Oct 2025 00:33:20 GMT, Xueming Shen  wrote:

>> ### Summary
>> 
>> Case folding is a key operation for case-insensitive matching (e.g., string equality, regex matching), where the goal is to eliminate case distinctions without applying locale or language specific conversions.
>> 
>> Currently, the JDK does not expose a direct API for Unicode-compliant case folding. Developers now rely on methods such as:
>> 
>> **String.equalsIgnoreCase(String)**
>> 
>> - Unicode-aware, locale-independent.
>> - Implementation uses Character.toLowerCase(Character.toUpperCase(int)) per code point.
>> - Limited: does not support 1:M mapping defined in Unicode case folding.
>> 
>> **Character.toLowerCase(int) / Character.toUpperCase(int)**
>> 
>> - Locale-independent, single code point only.
>> - No support for 1:M mappings.
>> 
>> **String.toLowerCase(Locale.ROOT) / String.toUpperCase(Locale.ROOT)**
>> 
>> - Based on Unicode SpecialCasing.txt, supports 1:M mappings.
>> - Intended primarily for presentation/display, not structural case-insensitive matching.
>> - Requires full string conversion before comparison, which is less efficient and not intended for structural matching.
>> 
>> **1:M mapping example, U+00DF (?)**
>> 
>> - String.toUpperCase(Locale.ROOT, "?") ? "SS"
>> - Case folding produces "ss", matching Unicode caseless comparison rules.
>> 
>> 
>> jshell> "\u00df".equalsIgnoreCase("ss")
>> $22 ==> false
>> 
>> jshell> "\u00df".toUpperCase(Locale.ROOT).toLowerCase(Locale.ROOT).equals("ss")
>> $24 ==> true
>> 
>> 
>> ### Motivation & Direction
>> 
>> Add Unicode standard-compliant case-less comparison methods to the String class, enabling & improving reliable and efficient Unicode-aware/compliant case-insensitive matching.
>> 
>> - Unicode-compliant **full** case folding.
>> - Simpler, stable and more efficient case-less matching without workarounds.
>> - Brings Java's string comparison handling in line with other programming languages/libraries.
>> 
>> This PR proposes to introduce the following comparison methods in `String` class
>> 
>> - boolean equalsFoldCase(String anotherString)
>> - int compareToFoldCase(String anotherString)
>> - Comparator UNICODE_CASEFOLD_ORDER
>> 
>> These methods are intended to be the preferred choice when Unicode-compliant case-less matching is required.
>> 
>> *Note: An early draft also proposed a String.toCaseFold() method returning a new case-folded string.
>> However, during review this was considered error-prone, as the resulting string could easily be mistaken for a general transformation like toLowerCase() and then pass...
>
> Xueming Shen has updated the pull request incrementally with one additional commit since the last revision:
> 
>   minor api doc updates

src/java.base/share/classes/jdk/internal/lang/CaseFolding.java.template line 36:

> 34: 
> 35: /**
> 36:  * Utility class for {@code String.toCaseFold()} that handles Unicode case folding

Maybe make it clear this is a planned api (or not refer to it?)

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2417269101

From naoto at openjdk.org  Thu Oct  9 16:23:49 2025
From: naoto at openjdk.org (Naoto Sato)
Date: Thu, 9 Oct 2025 16:23:49 GMT
Subject:  RFR: 8369184: SimpleTimeZone equals() Returns True
 for Unequal Instances with Different hashCode Values [v5]
In-Reply-To: 
References: 
 
Message-ID: 

On Wed, 8 Oct 2025 18:15:39 GMT, Naoto Sato  wrote:

>> Fixing the equals/hashCode contract in the SimpleTimeZone class. The current implementation includes DST rule fields in hash code computation even for zones that do not observe DST, while equals() always considers them. Also correcting the example code in the class description, where it used 20-year-old obsolete "America/Los_Angeles" rule.
>
> Naoto Sato has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Reflects review comments

Thanks for the reviews!

-------------

PR Comment: https://git.openjdk.org/jdk/pull/27660#issuecomment-3386564567

From naoto at openjdk.org  Thu Oct  9 16:23:51 2025
From: naoto at openjdk.org (Naoto Sato)
Date: Thu, 9 Oct 2025 16:23:51 GMT
Subject:  Integrated: 8369184: SimpleTimeZone equals() Returns
 True for Unequal Instances with Different hashCode Values
In-Reply-To: 
References: 
Message-ID: 

On Mon, 6 Oct 2025 21:36:44 GMT, Naoto Sato  wrote:

> Fixing the equals/hashCode contract in the SimpleTimeZone class. The current implementation includes DST rule fields in hash code computation even for zones that do not observe DST, while equals() always considers them. Also correcting the example code in the class description, where it used 20-year-old obsolete "America/Los_Angeles" rule.

This pull request has now been integrated.

Changeset: 37b725d9
Author:    Naoto Sato 
URL:       https://git.openjdk.org/jdk/commit/37b725d9c12834358a562e6c03fb7f566d639ca5
Stats:     102 lines in 2 files changed: 94 ins; 0 del; 8 mod

8369184: SimpleTimeZone equals() Returns True for Unequal Instances with Different hashCode Values

Reviewed-by: prappo, jlu, rriggs, iris

-------------

PR: https://git.openjdk.org/jdk/pull/27660

From jlu at openjdk.org  Thu Oct  9 18:19:13 2025
From: jlu at openjdk.org (Justin Lu)
Date: Thu, 9 Oct 2025 18:19:13 GMT
Subject:  RFR: 8369452: Locale.Builder.setLanguageTag(String) does
 not clear on empty or null String
Message-ID: 

Please review this PR which corrects the behavior of `Locale.Builder.setLanguageTag(String)` on the null and empty String case.

> Null and the empty string cause the builder to be reset

Currently, NPE is thrown for a null tag, and ILE is thrown for an empty String. They are both corrected to not throw, and instead reset the state of the `Locale.Builder`.

-------------

Commit messages:
 - The fix and reg test

Changes: https://git.openjdk.org/jdk/pull/27734/files
  Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=27734&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8369452
  Stats: 25 lines in 2 files changed: 20 ins; 0 del; 5 mod
  Patch: https://git.openjdk.org/jdk/pull/27734.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/27734/head:pull/27734

PR: https://git.openjdk.org/jdk/pull/27734

From prappo at openjdk.org  Thu Oct  9 21:36:01 2025
From: prappo at openjdk.org (Pavel Rappo)
Date: Thu, 9 Oct 2025 21:36:01 GMT
Subject:  RFR: 8366829: Add java.time.Duration constants MIN
 and MAX [v3]
In-Reply-To: 
References: 
 
 
Message-ID: 

On Wed, 8 Oct 2025 20:13:50 GMT, Roger Riggs  wrote:

> As proposed. Duration.MAX() is not the negated value of Duration.MIN. Is there any value for them to have that mathematical property? Duration.MIN can not be negated, it throws "Exceeds capacity of Duration".

To future readers: initially this question was asked in [another PR][], and then I forwarded it to this [mailing list discussion][].

[another PR]: https://github.com/openjdk/jdk/pull/27549#discussion_r2414774950
[mailing list discussion]: https://mail.openjdk.org/pipermail/core-libs-dev/2025-October/153062.html

-------------

PR Comment: https://git.openjdk.org/jdk/pull/27534#issuecomment-3387557653

From duke at openjdk.org  Thu Oct  9 23:17:14 2025
From: duke at openjdk.org (duke)
Date: Thu, 9 Oct 2025 23:17:14 GMT
Subject:  Withdrawn: 8359068: Remove the unused Cstyle code in
 GenerateCharacter
In-Reply-To: 
References: 
Message-ID: 

On Wed, 28 May 2025 03:44:22 GMT, Shaojin Wen  wrote:

> According to the suggestions of @cl4es and @naotoj, Cstyle is no longer used in GenerateCharacter, so remove the Cstyle related code.

This pull request has been closed without being integrated.

-------------

PR: https://git.openjdk.org/jdk/pull/25480

From naoto at openjdk.org  Thu Oct  9 23:30:01 2025
From: naoto at openjdk.org (Naoto Sato)
Date: Thu, 9 Oct 2025 23:30:01 GMT
Subject:  RFR: 8369452: Locale.Builder.setLanguageTag(String)
 does not clear on empty or null String
In-Reply-To: 
References: 
Message-ID: 

On Thu, 9 Oct 2025 18:12:58 GMT, Justin Lu  wrote:

> Please review this PR which corrects the behavior of `Locale.Builder.setLanguageTag(String)` on the null and empty String case.
> 
> This method is specified as follows,
> 
>> Null and the empty string cause the builder to be reset
> 
> Currently, NPE is thrown for a null tag, and ILE is thrown for an empty String. They are both corrected to not throw, and instead reset the state of the `Locale.Builder`.

LGTM

test/jdk/java/util/Locale/LocaleEnhanceTest.java line 779:

> 777:         bldr.setLanguageTag("en-US");
> 778:         assertDoesNotThrow(() -> bldr.setLanguageTag(tag));
> 779:         assertEquals(tag + " did not clear the builder", empty.build(), bldr.build());

Should not happen, but if empty string caused an assertion failure, the error message starts with " did not clear..."

-------------

Marked as reviewed by naoto (Reviewer).

PR Review: https://git.openjdk.org/jdk/pull/27734#pullrequestreview-3320916918
PR Review Comment: https://git.openjdk.org/jdk/pull/27734#discussion_r2418168857

From jlu at openjdk.org  Thu Oct  9 23:42:39 2025
From: jlu at openjdk.org (Justin Lu)
Date: Thu, 9 Oct 2025 23:42:39 GMT
Subject:  RFR: 8369452: Locale.Builder.setLanguageTag(String)
 does not clear on empty or null String [v2]
In-Reply-To: 
References: 
Message-ID: 

> Please review this PR which corrects the behavior of `Locale.Builder.setLanguageTag(String)` on the null and empty String case.
> 
> This method is specified as follows,
> 
>> Null and the empty string cause the builder to be reset
> 
> Currently, NPE is thrown for a null tag, and ILE is thrown for an empty String. They are both corrected to not throw, and instead reset the state of the `Locale.Builder`.

Justin Lu has updated the pull request incrementally with one additional commit since the last revision:

  Naoto's comment - improve err msg

-------------

Changes:
  - all: https://git.openjdk.org/jdk/pull/27734/files
  - new: https://git.openjdk.org/jdk/pull/27734/files/68bb29a1..fa385c8a

Webrevs:
 - full: https://webrevs.openjdk.org/?repo=jdk&pr=27734&range=01
 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27734&range=00-01

  Stats: 3 lines in 1 file changed: 2 ins; 0 del; 1 mod
  Patch: https://git.openjdk.org/jdk/pull/27734.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/27734/head:pull/27734

PR: https://git.openjdk.org/jdk/pull/27734

From jlu at openjdk.org  Thu Oct  9 23:42:40 2025
From: jlu at openjdk.org (Justin Lu)
Date: Thu, 9 Oct 2025 23:42:40 GMT
Subject:  RFR: 8369452: Locale.Builder.setLanguageTag(String)
 does not clear on empty or null String [v2]
In-Reply-To: 
References: 
 
Message-ID: 

On Thu, 9 Oct 2025 23:27:06 GMT, Naoto Sato  wrote:

>> Justin Lu has updated the pull request incrementally with one additional commit since the last revision:
>> 
>>   Naoto's comment - improve err msg
>
> test/jdk/java/util/Locale/LocaleEnhanceTest.java line 779:
> 
>> 777:         bldr.setLanguageTag("en-US");
>> 778:         assertDoesNotThrow(() -> bldr.setLanguageTag(tag));
>> 779:         assertEquals(tag + " did not clear the builder", empty.build(), bldr.build());
> 
> Should not happen, but if empty string caused an assertion failure, the error message starts with " did not clear..."

Good point, updated.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/27734#discussion_r2418189274

From naoto at openjdk.org  Fri Oct 10 16:13:05 2025
From: naoto at openjdk.org (Naoto Sato)
Date: Fri, 10 Oct 2025 16:13:05 GMT
Subject:  RFR: 8369452: Locale.Builder.setLanguageTag(String)
 does not clear on empty or null String [v2]
In-Reply-To: 
References: 
 
Message-ID: 

On Thu, 9 Oct 2025 23:42:39 GMT, Justin Lu  wrote:

>> Please review this PR which corrects the behavior of `Locale.Builder.setLanguageTag(String)` on the null and empty String case.
>> 
>> This method is specified as follows,
>> 
>>> Null and the empty string cause the builder to be reset
>> 
>> Currently, NPE is thrown for a null tag, and ILE is thrown for an empty String. They are both corrected to not throw, and instead reset the state of the `Locale.Builder`.
>
> Justin Lu has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Naoto's comment - improve err msg

Marked as reviewed by naoto (Reviewer).

-------------

PR Review: https://git.openjdk.org/jdk/pull/27734#pullrequestreview-3324546666

From jlu at openjdk.org  Fri Oct 10 16:31:00 2025
From: jlu at openjdk.org (Justin Lu)
Date: Fri, 10 Oct 2025 16:31:00 GMT
Subject:  Integrated: 8369050: DecimalFormat Rounding Errors for
 Fractional Ties Near Zero
In-Reply-To: 
References: 
Message-ID: 

On Tue, 7 Oct 2025 23:19:28 GMT, Justin Lu  wrote:

> Please review this PR which corrects a rounding error for DecimalFormat on tie cases when the maximum fraction digits allowed is one less than the position of the first significant digit in the double rounded. For example, rounding a value such as 0.0005 to a maximum of 3 fractional digits. In order to get the correct `count` value, we must strip the trailing zeros prior to the check to ensure we have the correct value of `count` = 1 so that we can go down the _Rounding position is the last index_ case which properly checks if the String double was already rounded or is exact from its true decimal form.

This pull request has now been integrated.

Changeset: 376d77e8
Author:    Justin Lu 
URL:       https://git.openjdk.org/jdk/commit/376d77e8a71478f456af5baaf47f446eebd79e36
Stats:     95 lines in 3 files changed: 88 ins; 5 del; 2 mod

8369050: DecimalFormat Rounding Errors for Fractional Ties Near Zero

Reviewed-by: naoto

-------------

PR: https://git.openjdk.org/jdk/pull/27681

From duke at openjdk.org  Fri Oct 10 19:52:04 2025
From: duke at openjdk.org (=?UTF-8?B?SmVhbi1Ob8OrbA==?= Rouvignac)
Date: Fri, 10 Oct 2025 19:52:04 GMT
Subject:  RFR: 8365675: Add String Unicode Case-Folding
 Support [v2]
In-Reply-To: 
References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com>
 
Message-ID: 

On Wed, 8 Oct 2025 00:33:20 GMT, Xueming Shen  wrote:

>> ### Summary
>> 
>> Case folding is a key operation for case-insensitive matching (e.g., string equality, regex matching), where the goal is to eliminate case distinctions without applying locale or language specific conversions.
>> 
>> Currently, the JDK does not expose a direct API for Unicode-compliant case folding. Developers now rely on methods such as:
>> 
>> **String.equalsIgnoreCase(String)**
>> 
>> - Unicode-aware, locale-independent.
>> - Implementation uses Character.toLowerCase(Character.toUpperCase(int)) per code point.
>> - Limited: does not support 1:M mapping defined in Unicode case folding.
>> 
>> **Character.toLowerCase(int) / Character.toUpperCase(int)**
>> 
>> - Locale-independent, single code point only.
>> - No support for 1:M mappings.
>> 
>> **String.toLowerCase(Locale.ROOT) / String.toUpperCase(Locale.ROOT)**
>> 
>> - Based on Unicode SpecialCasing.txt, supports 1:M mappings.
>> - Intended primarily for presentation/display, not structural case-insensitive matching.
>> - Requires full string conversion before comparison, which is less efficient and not intended for structural matching.
>> 
>> **1:M mapping example, U+00DF (?)**
>> 
>> - String.toUpperCase(Locale.ROOT, "?") ? "SS"
>> - Case folding produces "ss", matching Unicode caseless comparison rules.
>> 
>> 
>> jshell> "\u00df".equalsIgnoreCase("ss")
>> $22 ==> false
>> 
>> jshell> "\u00df".toUpperCase(Locale.ROOT).toLowerCase(Locale.ROOT).equals("ss")
>> $24 ==> true
>> 
>> 
>> ### Motivation & Direction
>> 
>> Add Unicode standard-compliant case-less comparison methods to the String class, enabling & improving reliable and efficient Unicode-aware/compliant case-insensitive matching.
>> 
>> - Unicode-compliant **full** case folding.
>> - Simpler, stable and more efficient case-less matching without workarounds.
>> - Brings Java's string comparison handling in line with other programming languages/libraries.
>> 
>> This PR proposes to introduce the following comparison methods in `String` class
>> 
>> - boolean equalsFoldCase(String anotherString)
>> - int compareToFoldCase(String anotherString)
>> - Comparator UNICODE_CASEFOLD_ORDER
>> 
>> These methods are intended to be the preferred choice when Unicode-compliant case-less matching is required.
>> 
>> *Note: An early draft also proposed a String.toCaseFold() method returning a new case-folded string.
>> However, during review this was considered error-prone, as the resulting string could easily be mistaken for a general transformation like toLowerCase() and then pass...
>
> Xueming Shen has updated the pull request incrementally with one additional commit since the last revision:
> 
>   minor api doc updates

test/micro/org/openjdk/bench/java/lang/StringCompareToIgnoreCase.java line 89:

> 87: 
> 88:     @Benchmark
> 89:     public int lowerrCF() {

Suggestion:

    public int lowerCF() {

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2421934368

From pminborg at openjdk.org  Mon Oct 13 11:51:02 2025
From: pminborg at openjdk.org (Per Minborg)
Date: Mon, 13 Oct 2025 11:51:02 GMT
Subject:  RFR: 8366178: Implement JEP 526: Lazy Constants (Second
 Preview)
Message-ID: 

Implement JEP 526: Lazy Constants (Second Preview)

The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class.

The old benchmarks are not moved/renamed to allow comparison with previous releases.

`java.util.Optional` is updated so that its field is annotated with `@Stable`.  This is to allow `Optional` instances to be held in lazy constants and still provide constant folding.

-------------

Commit messages:
 - Add optimization where the computing function is returned directly
 - Add benchmark of Optionals
 - Merge branch 'master' into lazy-constants
 - Update src/java.base/share/classes/java/lang/LazyConstant.java
 - Update src/java.base/share/classes/java/util/LazyCollections.java
 - Fix failing test
 - Clean up
 - Merge branch 'master' into lazy-constants
 - Update JEP number
 - Fix doc issues
 - ... and 76 more: https://git.openjdk.org/jdk/compare/1605e839...3e287031

Changes: https://git.openjdk.org/jdk/pull/27605/files
  Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8366178
  Stats: 8721 lines in 60 files changed: 4112 ins; 4490 del; 119 mod
  Patch: https://git.openjdk.org/jdk/pull/27605.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/27605/head:pull/27605

PR: https://git.openjdk.org/jdk/pull/27605

From duke at openjdk.org  Mon Oct 13 11:51:02 2025
From: duke at openjdk.org (ExE Boss)
Date: Mon, 13 Oct 2025 11:51:02 GMT
Subject:  RFR: 8366178: Implement JEP 526: Lazy Constants
 (Second Preview)
In-Reply-To: 
References: 
Message-ID: <8VsjXECvVSYRtKpK4PId8s_8RM0T00n4BzmfO6RTinM=.e1bb59c4-8a85-4d3c-8980-249cd529b50b@github.com>

On Thu, 2 Oct 2025 10:51:08 GMT, Per Minborg  wrote:

> Implement JEP 526: Lazy Constants (Second Preview)
> 
> The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class.
> 
> The old benchmarks are not moved/renamed to allow comparison with previous releases.
> 
> `java.util.Optional` is updated so that its field is annotated with `@Stable`.  This is to allow `Optional` instances to be held in lazy constants and still provide constant folding.

I?m?gonna?miss **Stable?Values**, as?it?has some?use?cases which?aren?t?served by?**Lazy?Constants**, and?on?which I?depend?on in?some of?my?code, so?I?m stuck?with using?regular non?`final`?fields.

--------------------------------------------------------------------------------

Also, in the [JEP?526]?table under ?[Flexible?initialization with?lazy?constants]?:
> |                 	| Update count	| Update location	| Constant folding?	| Concurrent updates?
> | --------------  	| ------------	| ---------------	| -----------------	| -------------------
> | `final` field   	| 1         	| Constructor or static initializer	| Yes 	| No
> | `LazyConstant`  	| [0, 1]    	| Anywhere	| Yes, after initialization	| Yes, by winner
> | Non-`final` field	| [0, ?)    	| Anywhere	| No 	| Yes

The??Update?location? of?`LazyConstant` shouldn?t?be??Anywhere?, as?that?was only?accurate for?`StableValue`, but?not for?`LazyConstant`, which?is?updated by?calling the?passed `Supplier`.

Similarly, concurrent?updates are?prevented for?`LazyConstant`s by?using `synchronized?(this)`.

[JEP?526]: https://openjdk.org/jeps/526
[Flexible?initialization with?lazy?constants]: https://openjdk.org/jeps/526#Flexible-initialization-with-lazy-constants

Getting?access to?the?underlying `StableValue`?API with?**Lazy?Constants** is?way?too?hacky and?convoluted (but?doable):
StableVar.java /* * Any copyright is dedicated to the Public Domain. * https://creativecommons.org/publicdomain/zero/1.0/ */ import java.util.NoSuchElementException; import java.util.function.Supplier; import org.jspecify.annotations.NullMarked; import org.jspecify.annotations.Nullable; import static java.lang.System.identityHashCode; import static java.util.Objects.requireNonNull; /// Horrible awful hack to get access to raw stable values in JDK 26+. @NullMarked public sealed interface StableVar permits StableHacks.StableVarImpl { boolean trySet(final T contents) throws NullPointerException, IllegalStateException; @Nullable T orNull(); T orElse(final T other) throws NullPointerException; T orElseThrow() throws NoSuchElementException; boolean isSet(); T orElseSet(final Supplier supplier) throws NullPointerException, IllegalStateException; void setOrThrow(final T contents) throws NullPointerException, IllegalStateException; static StableVar of() { return StableHacks.newInstance(); } } /// Encapsulates the actual implementation of `StableValue` on `LazyConstant` /// /// @author ExE Boss @NullMarked /*package*/ final @Namespace class StableHacks { private StableHacks() throws InstantiationException { throw new InstantiationException(StableHacks.class.getName()); } private static final String UNSET_SUFFIX = ".unset"; private static final Object UNSET = new Object() { @Override public int hashCode() { return 0; } @Override public String toString() { return "unset"; } }; private static final ScopedValue SCOPE = ScopedValue.newInstance(); private static final Supplier SCOPE_GETTER = SCOPE::get; /*package*/ static final StableVarImpl newInstance() { return new StableValue<>(); } /*package*/ sealed interface StableVarImpl extends StableVar { } private record StableValue( // Implemented as a record so that the JVM treats this as a trusted final field // even when `-XX:+TrustFinalNonStaticFields` is not set LazyConstant contents ) implements StableVarImpl { @SuppressWarnings("unchecked") private StableValue() { this(LazyConstant.of((Supplier) SCOPE_GETTER)); } private StableValue { if (contents.isInitialized()) throw new InternalError(); } @SuppressWarnings("unchecked") private final ScopedValue scope() { return (ScopedValue) SCOPE; } private final void preventReentry() throws IllegalStateException { if (Thread.holdsLock(this)) { throw new IllegalStateException("Recursive initialization of a stable value is illegal"); } } @Override public boolean trySet(final T contents) throws NullPointerException, IllegalStateException { requireNonNull(contents); if (this.contents.isInitialized()) return false; preventReentry(); synchronized (this) { return this.setImpl(contents); } } @Override @SuppressWarnings("unchecked") public final @Nullable T orNull() { return unwrapUnset(((LazyConstant) this.contents).orElse(UNSET)); } @Override public T orElse(T other) throws NullPointerException { return this.contents.orElse(other); } @Override public T orElseThrow() throws NoSuchElementException { { final T contents; if ((contents = this.orNull()) != null) { return contents; } } throw new NoSuchElementException(); } @Override public boolean isSet() { return this.contents.isInitialized(); } @Override public T orElseSet(final Supplier supplier) throws NullPointerException, IllegalStateException { requireNonNull(supplier); { final T contents; if ((contents = this.orNull()) != null) { return contents; } } return orElseSetSlowPath(supplier); } @Override public void setOrThrow(final T contents) throws NullPointerException, IllegalStateException { if (!trySet(contents)) { throw new IllegalStateException(); } } private final T orElseSetSlowPath( final Supplier supplier ) throws NullPointerException, IllegalStateException { preventReentry(); synchronized (this) { { final T contents; if ((contents = this.orNull()) != null) { return contents; } } final T newValue; this.setImpl(newValue = requireNonNull(supplier.get())); return newValue; } } private final boolean setImpl(final T contents) { assert Thread.holdsLock(this); if (this.contents.isInitialized()) { return false; } ScopedValue.where(this.scope(), contents).run(this.contents::get); return true; } @Override public final boolean equals(final Object obj) { return this == obj; } @Override public final int hashCode() { return identityHashCode(this); } @Override public String toString() { final Object contents; return renderValue( "StableValue", (contents = this.orNull()) != this ? contents : "(this StableValue)" ); } } @SuppressWarnings("unchecked") private static final @Nullable T unwrapUnset(final @Nullable Object obj) { return (obj == UNSET) ? null : (T) obj; } private static final String renderValue( final String type, final @Nullable Object value ) throws NullPointerException { return (value == null) ? type.concat(UNSET_SUFFIX) : (type + '[' + value + ']'); } }
------------- PR Comment: https://git.openjdk.org/jdk/pull/27605#issuecomment-3367784825 PR Comment: https://git.openjdk.org/jdk/pull/27605#issuecomment-3368298279 From liach at openjdk.org Mon Oct 13 11:51:04 2025 From: liach at openjdk.org (Chen Liang) Date: Mon, 13 Oct 2025 11:51:04 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) In-Reply-To: <8VsjXECvVSYRtKpK4PId8s_8RM0T00n4BzmfO6RTinM=.e1bb59c4-8a85-4d3c-8980-249cd529b50b@github.com> References: <8VsjXECvVSYRtKpK4PId8s_8RM0T00n4BzmfO6RTinM=.e1bb59c4-8a85-4d3c-8980-249cd529b50b@github.com> Message-ID: On Sat, 4 Oct 2025 14:29:08 GMT, ExE Boss wrote: >> Implement JEP 526: Lazy Constants (Second Preview) >> >> The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. >> >> The old benchmarks are not moved/renamed to allow comparison with previous releases. >> >> `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. > > Getting?access to?the?underlying `StableValue`?API with?**Lazy?Constants** is?way?too?hacky and?convoluted (but?doable): >
> StableVar.java > > > /* > * Any copyright is dedicated to the Public Domain. > * https://creativecommons.org/publicdomain/zero/1.0/ > */ > > import java.util.NoSuchElementException; > import java.util.function.Supplier; > > import org.jspecify.annotations.NullMarked; > import org.jspecify.annotations.Nullable; > > import static java.lang.System.identityHashCode; > import static java.util.Objects.requireNonNull; > > /// Horrible awful hack to get access to raw stable values in JDK 26+. > @NullMarked > public sealed interface StableVar permits StableHacks.StableVarImpl { > boolean trySet(final T contents) throws NullPointerException, IllegalStateException; > @Nullable T orNull(); > T orElse(final T other) throws NullPointerException; > T orElseThrow() throws NoSuchElementException; > boolean isSet(); > T orElseSet(final Supplier supplier) throws NullPointerException, IllegalStateException; > void setOrThrow(final T contents) throws NullPointerException, IllegalStateException; > > static StableVar of() { > return StableHacks.newInstance(); > } > } > > /// Encapsulates the actual implementation of `StableValue` on `LazyConstant` > /// > /// @author ExE Boss > @NullMarked > /*package*/ final @Namespace class StableHacks { > private StableHacks() throws InstantiationException { throw new InstantiationException(StableHacks.class.getName()); } > > private static final String UNSET_SUFFIX = ".unset"; > private static final Object UNSET = new Object() { > @Override > public int hashCode() { > return 0; > } > > @Override > public String toString() { > return "unset"; > } > }; > > private static final ScopedValue SCOPE = ScopedValue.newInstance(); > private static final Supplier SCOPE_GETTER = SCOPE::get; > > /*package*/ static final StableVarImpl newInstance() { > return new StableValue<>(); > } > > /*package*/ sealed interface StableVarImpl extends StableVar { > } > > private record StableValue( > // Implemented as a record so that the JVM treats this as a trusted final field > // even when `-XX:+TrustFinalNonStaticFields` is not set > LazyConstant contents > ) implements StableVarImpl { > @SuppressWarnings("unchecked") > private StableValue() { > this(LazyConstant.of((Supplier) SCOPE_GETTER)); > } > > private StableValue { > if (contents.isInitialized()) throw new InternalError(); > } > > @SuppressWarnings("unchecked") > private fi... Hi @ExE-Boss, this new JEP describes how this functionality will be provided in the future: > Lazy constants cover the common, high-level use cases for lazy initialization. In the future we might consider providing stable access semantics directly, at a lower level, for reference, array, and primitive fields. This would address, for example, use cases where the computing function associated with a lazy constant is not known at construction. This would be necessary, as there are usage patterns (such as nominal descriptors in ClassFile API) that would benefit from multiple assignment and a stable promoted read. ------------- PR Comment: https://git.openjdk.org/jdk/pull/27605#issuecomment-3368317631 From duke at openjdk.org Mon Oct 13 11:51:05 2025 From: duke at openjdk.org (Burning_TNT) Date: Mon, 13 Oct 2025 11:51:05 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) In-Reply-To: References: Message-ID: On Thu, 2 Oct 2025 10:51:08 GMT, Per Minborg wrote: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. It's essential to provide a low-level API as those in StableValue. Completely migrating to factory pattern may forcing users to build their own LazyConstant wrapper as ExeBoss has down above. ------------- PR Comment: https://git.openjdk.org/jdk/pull/27605#issuecomment-3369054838 From pminborg at openjdk.org Mon Oct 13 11:51:05 2025 From: pminborg at openjdk.org (Per Minborg) Date: Mon, 13 Oct 2025 11:51:05 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) In-Reply-To: References: Message-ID: <5N4q67er51rXJ8E1oqNY4gCowyJ_K4x1SCeWncz1dFY=.2fe20197-fffe-467f-a1af-5816594c7e78@github.com> On Thu, 2 Oct 2025 10:51:08 GMT, Per Minborg wrote: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. > I?m?gonna?miss **Stable?Values**, as?it?has some?use?cases which?aren?t?served by?**Lazy?Constants**, and?on?which I?depend?on in?some of?my?code, so?I?m stuck?with using?regular non?`final`?fields. > > Also, in the [JEP?526](https://openjdk.org/jeps/526)?table under ?[Flexible?initialization with?lazy?constants](https://openjdk.org/jeps/526#Flexible-initialization-with-lazy-constants)?: > > > Update count > > Update location > > Constant folding? > > Concurrent updates? > > > > > > > > > > `final` field > > 1 > > Constructor or static initializer > > Yes > > No > > > > > > `LazyConstant` > > [0, 1] > > Anywhere > > Yes, after initialization > > Yes, by winner > > > > > > Non-`final` field > > [0, ?) > > Anywhere > > No > > Yes > > The??Update?location? of?`LazyConstant` shouldn?t?be??Anywhere?, as?that?was only?accurate for?`StableValue`, but?not for?`LazyConstant`, which?is?updated by?calling the?passed `Supplier`. > > Similarly, concurrent?updates are?prevented for?`LazyConstant`s by?using `synchronized?(this)`. I've updated the JEP. Thanks for pointing out this. Let me know what you think about the new text. We are exploring better ways to provide low-level, imperative, lazy constant/stable value fields. This work will be done outside the current JEP. ------------- PR Comment: https://git.openjdk.org/jdk/pull/27605#issuecomment-3396693041 PR Comment: https://git.openjdk.org/jdk/pull/27605#issuecomment-3397160926 From duke at openjdk.org Mon Oct 13 11:51:06 2025 From: duke at openjdk.org (ExE Boss) Date: Mon, 13 Oct 2025 11:51:06 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) In-Reply-To: <5N4q67er51rXJ8E1oqNY4gCowyJ_K4x1SCeWncz1dFY=.2fe20197-fffe-467f-a1af-5816594c7e78@github.com> References: <5N4q67er51rXJ8E1oqNY4gCowyJ_K4x1SCeWncz1dFY=.2fe20197-fffe-467f-a1af-5816594c7e78@github.com> Message-ID: On Mon, 13 Oct 2025 09:49:16 GMT, Per Minborg wrote: > I've updated the JEP. Thanks for pointing out this. Let me know what you think about the new text. The?change was?made to?the?wrong?row (?Non?`final`?field? instead of??`LazyConstant`?). ------------- PR Comment: https://git.openjdk.org/jdk/pull/27605#issuecomment-3396866550 From fandreuzzi at openjdk.org Mon Oct 13 11:51:09 2025 From: fandreuzzi at openjdk.org (Francesco Andreuzzi) Date: Mon, 13 Oct 2025 11:51:09 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) In-Reply-To: References: Message-ID: <9oTBJDVY4LhEXsE4tVJAItdEvmaA3YcZ0BbUrw7M9uk=.86f99b3a-fbb2-4ce4-916d-e0487fce4211@github.com> On Thu, 2 Oct 2025 10:51:08 GMT, Per Minborg wrote: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. src/java.base/share/classes/java/lang/LazyConstant.java line 166: > 164: * > 165: *

Performance

> 166: * As a lazy constant can never change after it has been initialized. Therefore, Suggestion: * A lazy constant can never change after it has been initialized. Therefore, src/java.base/share/classes/java/util/LazyCollections.java line 80: > 78: } > 79: > 80: @Override public boolean isEmpty() { return size == 0;} Suggestion: @Override public boolean isEmpty() { return size == 0; } ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2399059426 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2399074220 From duke at openjdk.org Mon Oct 13 11:51:10 2025 From: duke at openjdk.org (Kerman) Date: Mon, 13 Oct 2025 11:51:10 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) In-Reply-To: References: Message-ID: On Thu, 2 Oct 2025 10:51:08 GMT, Per Minborg wrote: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. src/java.base/share/classes/java/util/Optional.java line 74: > 72: * If non-null, the value; if null, indicates no value is present > 73: */ > 74: @Stable Shouldn?t this also add a null sentinel to allow the folding of the empty case? Or is that irrelevant because empty would be the terminator of a chain. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2399352909 From liach at openjdk.org Mon Oct 13 11:51:11 2025 From: liach at openjdk.org (Chen Liang) Date: Mon, 13 Oct 2025 11:51:11 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) In-Reply-To: References: Message-ID: <-lErHk2PzyJCaPQGrEwCt3nObTrTHs7_p53eBXspUGE=.50dc2375-8769-49a5-9308-ab40132bbd19@github.com> On Thu, 2 Oct 2025 16:16:44 GMT, Kerman wrote: >> Implement JEP 526: Lazy Constants (Second Preview) >> >> The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. >> >> The old benchmarks are not moved/renamed to allow comparison with previous releases. >> >> `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. > > src/java.base/share/classes/java/util/Optional.java line 74: > >> 72: * If non-null, the value; if null, indicates no value is present >> 73: */ >> 74: @Stable > > Shouldn?t this also add a null sentinel to allow the folding of the empty case? Or is that irrelevant because empty would be the terminator of a chain. Usually a null sentinel is used when null indicates something different. I think maybe to allow folding the empty case, we should probably add a new annotation or a new element-value to indicate this status and properly handle it in C1/C2 (similar to the field trusting in ciField) ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2403729792 From pminborg at openjdk.org Mon Oct 13 11:51:11 2025 From: pminborg at openjdk.org (Per Minborg) Date: Mon, 13 Oct 2025 11:51:11 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) In-Reply-To: <-lErHk2PzyJCaPQGrEwCt3nObTrTHs7_p53eBXspUGE=.50dc2375-8769-49a5-9308-ab40132bbd19@github.com> References: <-lErHk2PzyJCaPQGrEwCt3nObTrTHs7_p53eBXspUGE=.50dc2375-8769-49a5-9308-ab40132bbd19@github.com> Message-ID: On Sat, 4 Oct 2025 04:13:05 GMT, Chen Liang wrote: >> src/java.base/share/classes/java/util/Optional.java line 74: >> >>> 72: * If non-null, the value; if null, indicates no value is present >>> 73: */ >>> 74: @Stable >> >> Shouldn?t this also add a null sentinel to allow the folding of the empty case? Or is that irrelevant because empty would be the terminator of a chain. > > Usually a null sentinel is used when null indicates something different. I think maybe to allow folding the empty case, we should probably add a new annotation or a new element-value to indicate this status and properly handle it in C1/C2 (similar to the field trusting in ciField) I've added two new benchmarks: private static final LazyConstant> OPTIONAL_42 = LazyConstant.of(() -> Optional.of(42)); private static final LazyConstant> OPTIONAL_42_2 = LazyConstant.of(() -> Optional.of(42)); private static final LazyConstant> OPTIONAL_EMPTY = LazyConstant.of(Optional::empty); private static final LazyConstant> OPTIONAL_EMPTY2 = LazyConstant.of(Optional::empty); ... @Benchmark public int staticOptional42() { return OPTIONAL_42.get().orElseThrow() + OPTIONAL_42_2.get().orElseThrow(); } @Benchmark public boolean staticOptionalEmpty() { return OPTIONAL_EMPTY.get().isEmpty() ^ OPTIONAL_EMPTY2.get().isEmpty(); } Which gives: Benchmark Mode Cnt Score Error Units StableValueBenchmark.staticOptional42 avgt 10 0.354 ? 0.045 ns/op Benchmark Mode Cnt Score Error Units StableValueBenchmark.staticOptionalEmpty avgt 10 0.370 ? 0.030 ns/op So, both `Optional` variants appears to support constant folding. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2426044826 From liach at openjdk.org Mon Oct 13 11:51:13 2025 From: liach at openjdk.org (Chen Liang) Date: Mon, 13 Oct 2025 11:51:13 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) In-Reply-To: References: Message-ID: On Thu, 2 Oct 2025 10:51:08 GMT, Per Minborg wrote: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. src/java.base/share/classes/jdk/internal/lang/LazyConstantImpl.java line 171: > 169: > 170: public static LazyConstantImpl ofLazy(Supplier computingFunction) { > 171: return new LazyConstantImpl<>(computingFunction); We might return the function if it is already a LazyConstantImpl. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2399678324 From duke at openjdk.org Mon Oct 13 11:51:14 2025 From: duke at openjdk.org (Jefferson Quesado) Date: Mon, 13 Oct 2025 11:51:14 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) In-Reply-To: References: Message-ID: On Thu, 2 Oct 2025 10:51:08 GMT, Per Minborg wrote: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. src/java.base/share/classes/sun/nio/ch/Net.java line 99: > 97: } > 98: > 99: private static final LazyConstant SHUTDOWN_WRITE_BEFORE_CLOSE = LazyConstant.of(new Supplier() { I wonder if there is a reason for not using `BooleanSupplier`. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2399205774 From liach at openjdk.org Mon Oct 13 11:51:15 2025 From: liach at openjdk.org (Chen Liang) Date: Mon, 13 Oct 2025 11:51:15 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) In-Reply-To: References: Message-ID: On Thu, 2 Oct 2025 15:21:37 GMT, Jefferson Quesado wrote: >> Implement JEP 526: Lazy Constants (Second Preview) >> >> The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. >> >> The old benchmarks are not moved/renamed to allow comparison with previous releases. >> >> `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. > > src/java.base/share/classes/sun/nio/ch/Net.java line 99: > >> 97: } >> 98: >> 99: private static final LazyConstant SHUTDOWN_WRITE_BEFORE_CLOSE = LazyConstant.of(new Supplier() { > > I wonder if there is a reason for not using `BooleanSupplier`. Unfortunately, BooleanSupplier does not extend Supplier. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2403730001 From mcimadamore at openjdk.org Mon Oct 13 13:08:03 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Mon, 13 Oct 2025 13:08:03 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) In-Reply-To: References: Message-ID: On Thu, 2 Oct 2025 10:51:08 GMT, Per Minborg wrote: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. test/jdk/java/lang/LazyConstant/DemoImperativeTest.java line 25: > 23: > 24: /* @test > 25: * @summary Demo of an imperative stable value based on a lazy constant Should this summary be updated (and. some of the classes defined here) ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2426297364 From mcimadamore at openjdk.org Mon Oct 13 13:20:38 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Mon, 13 Oct 2025 13:20:38 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) In-Reply-To: References: Message-ID: On Thu, 2 Oct 2025 10:51:08 GMT, Per Minborg wrote: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. src/java.base/share/classes/java/util/LazyCollections.java line 255: > 253: } > 254: > 255: interface LenientList extends List { Ok, this seems needed to give access to `getAcquire` from sublists created from other sublists... src/java.base/share/classes/java/util/LazyCollections.java line 360: > 358: > 359: @Stable > 360: private final Set keySet; I believe putting the field in here might cause some redundancies -- for instance LazyMap extends this class and addss a `Map`, from which you can clearly derive the key set... ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2426326166 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2426329562 From mcimadamore at openjdk.org Mon Oct 13 13:30:34 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Mon, 13 Oct 2025 13:30:34 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) In-Reply-To: References: Message-ID: On Thu, 2 Oct 2025 10:51:08 GMT, Per Minborg wrote: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. src/java.base/share/classes/java/lang/LazyConstant.java line 42: > 40: > 41: /** > 42: * A lazy constant is a deferred, shallowly immutable constant to be computed at It seems like the javadoc is a snapshot of an earlier version of the JEP where the word "content" was replaced with "constant". I think we should go back to "content" and say (as we did for stable values) that a "A lazy constant is a holder of contents that can be set at most once." ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2426358262 From mcimadamore at openjdk.org Mon Oct 13 13:34:33 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Mon, 13 Oct 2025 13:34:33 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) In-Reply-To: References: Message-ID: <56kNzRwD6WRl9bHJUKb-YU1TuN6Tha_crXrwvfb-EmU=.c601a0b2-a66f-4d7f-9952-d235ee935fb1@github.com> On Thu, 2 Oct 2025 10:51:08 GMT, Per Minborg wrote: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. src/java.base/share/classes/java/lang/LazyConstant.java line 98: > 96: * constant is not initialized. > 97: *

> 98: * If the computing function throws any unchecked exception or Error, that Throwable add some code blocks around `Error` and `Throwable` ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2426369216 From mcimadamore at openjdk.org Mon Oct 13 13:40:54 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Mon, 13 Oct 2025 13:40:54 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) In-Reply-To: References: Message-ID: On Thu, 2 Oct 2025 10:51:08 GMT, Per Minborg wrote: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. src/java.base/share/classes/java/lang/LazyConstant.java line 155: > 153: * {@code final} fields of any newly created objects, are safely published. > 154: *

> 155: * The computing function runs on the caller?s thread. Here you might define "we call that thread the computing thread" -- this might be useful when defining other concepts in this section (maybe) src/java.base/share/classes/java/lang/LazyConstant.java line 157: > 155: * The computing function runs on the caller?s thread. > 156: *

> 157: * If a thread that is blocked by another computing thread is interrupted, this is not I'm not sure I understand what you mean in this para src/java.base/share/classes/java/lang/LazyConstant.java line 172: > 170: * (e.g. in cases where the lazy constant itself is stored in a > 171: * {@code static final} field) or forms a trusted chain to such a VM constant via > 172: * one or more layers of a {@linkplain Record record} fields or final fields one or more layers of "trusted" fields -- then in parenthesis you say what these "trusted" fields are. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2426383095 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2426379186 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2426387301 From mcimadamore at openjdk.org Mon Oct 13 13:40:56 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Mon, 13 Oct 2025 13:40:56 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) In-Reply-To: References: Message-ID: On Mon, 13 Oct 2025 13:35:21 GMT, Maurizio Cimadamore wrote: >> Implement JEP 526: Lazy Constants (Second Preview) >> >> The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. >> >> The old benchmarks are not moved/renamed to allow comparison with previous releases. >> >> `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. > > src/java.base/share/classes/java/lang/LazyConstant.java line 157: > >> 155: * The computing function runs on the caller?s thread. >> 156: *

>> 157: * If a thread that is blocked by another computing thread is interrupted, this is not > > I'm not sure I understand what you mean in this para E.g. "thread that is blocked by another computing thread". Did you mean to say "if the thread running the computing function is interrupted"? ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2426381677 From mcimadamore at openjdk.org Mon Oct 13 13:46:48 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Mon, 13 Oct 2025 13:46:48 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) In-Reply-To: References: Message-ID: On Thu, 2 Oct 2025 10:51:08 GMT, Per Minborg wrote: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. src/java.base/share/classes/java/lang/LazyConstant.java line 188: > 186: * arbitrary depth can be used, which provides constant components. > 187: * More generally, a lazy constant can hold other lazy constants of > 188: * arbitrary depth and still provide transitive constancy. I'm not sure the term "constancy" is common to mean constant-ness. I think it might be better to use the term "constant-folding" -- and then define "constant-folding" in the above "performance" section: > A lazy constant can never change after it has been initialized. Therefore, > a JVM implementation may, for an initialized lazy constant, elide all future reads > of that lazy constant, and instead directly use any constant that it has previously > observed Then you can add "we call this optimization constant-folding". src/java.base/share/classes/java/lang/LazyConstant.java line 192: > 190: * The {@code LazyConstant} type is not {@link Serializable}. > 191: *

> 192: * It is not recommended putting lazy constants into equality-based collections Not sure what you mean here. It seems like the javadoc for `equals` says that it triggers initialization, so it should be ok? ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2426397976 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2426402669 From pminborg at openjdk.org Mon Oct 13 13:46:51 2025 From: pminborg at openjdk.org (Per Minborg) Date: Mon, 13 Oct 2025 13:46:51 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) In-Reply-To: References: Message-ID: On Mon, 13 Oct 2025 13:17:37 GMT, Maurizio Cimadamore wrote: >> Implement JEP 526: Lazy Constants (Second Preview) >> >> The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. >> >> The old benchmarks are not moved/renamed to allow comparison with previous releases. >> >> `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. > > src/java.base/share/classes/java/util/LazyCollections.java line 360: > >> 358: >> 359: @Stable >> 360: private final Set keySet; > > I believe putting the field in here might cause some redundancies -- for instance LazyMap extends this class and addss a `Map`, from which you can clearly derive the key set... It is true that `AbstractMap` already contains a `keySet` field. If we annotate `AbstractMap.keySet` with `@Stable` (which seems ok to do), we can get rid of this field. A note here is that eventually, we would like to get rid of all the fields in `AbstractMap`. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2426399337 From mcimadamore at openjdk.org Mon Oct 13 13:50:07 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Mon, 13 Oct 2025 13:50:07 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) In-Reply-To: References: Message-ID: On Thu, 2 Oct 2025 10:51:08 GMT, Per Minborg wrote: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. src/java.base/share/classes/java/lang/LazyConstant.java line 276: > 274: * this method might block or throw. > 275: * > 276: * @implSpec The order of potential initialization triggering is specified as: Do we really need to specify this? src/java.base/share/classes/java/lang/LazyConstant.java line 312: > 310: String toString(); > 311: > 312: // Factories Suggestion: // Factory ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2426409576 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2426412926 From pminborg at openjdk.org Mon Oct 13 13:54:44 2025 From: pminborg at openjdk.org (Per Minborg) Date: Mon, 13 Oct 2025 13:54:44 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v2] In-Reply-To: References: Message-ID: <90jKH5-Bb3vf27uhLPOUtgmYmZRFdH1voVYr8kIR__I=.2aff8cb2-38be-4dd3-a1df-e3f8a7a90542@github.com> > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. Per Minborg has updated the pull request incrementally with one additional commit since the last revision: Remove redundant field ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27605/files - new: https://git.openjdk.org/jdk/pull/27605/files/3e287031..0978179a Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=00-01 Stats: 7 lines in 2 files changed: 3 ins; 3 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/27605.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27605/head:pull/27605 PR: https://git.openjdk.org/jdk/pull/27605 From pminborg at openjdk.org Mon Oct 13 14:03:37 2025 From: pminborg at openjdk.org (Per Minborg) Date: Mon, 13 Oct 2025 14:03:37 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v3] In-Reply-To: References: Message-ID: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. Per Minborg has updated the pull request incrementally with one additional commit since the last revision: Add links around Error and Throwable ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27605/files - new: https://git.openjdk.org/jdk/pull/27605/files/0978179a..5770e033 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=01-02 Stats: 5 lines in 1 file changed: 0 ins; 0 del; 5 mod Patch: https://git.openjdk.org/jdk/pull/27605.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27605/head:pull/27605 PR: https://git.openjdk.org/jdk/pull/27605 From pminborg at openjdk.org Mon Oct 13 14:03:41 2025 From: pminborg at openjdk.org (Per Minborg) Date: Mon, 13 Oct 2025 14:03:41 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v3] In-Reply-To: References: Message-ID: <0kU7XwB4vVkXnZLTj79Gen7puX7sPTKNfZwkf3I1wpM=.840e45e2-87bb-41ad-a4be-8d474458559d@github.com> On Mon, 13 Oct 2025 13:36:19 GMT, Maurizio Cimadamore wrote: >> src/java.base/share/classes/java/lang/LazyConstant.java line 157: >> >>> 155: * The computing function runs on the caller?s thread. >>> 156: *

>>> 157: * If a thread that is blocked by another computing thread is interrupted, this is not >> >> I'm not sure I understand what you mean in this para > > E.g. "thread that is blocked by another computing thread". Did you mean to say "if the thread running the computing function is interrupted"? If a thread `A` won the race and invokes the computing function, and another thread `B` comes along while computation takes place by `A`, then interrupting thread `B` will not have any effect. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2426445641 From kfarrell at openjdk.org Mon Oct 13 14:07:33 2025 From: kfarrell at openjdk.org (Kieran Farrell) Date: Mon, 13 Oct 2025 14:07:33 GMT Subject: [jdk25] RFR: 8369184: SimpleTimeZone equals() Returns True for Unequal Instances with Different hashCode Values Message-ID: Clean backport ------------- Commit messages: - Backport 37b725d9c12834358a562e6c03fb7f566d639ca5 Changes: https://git.openjdk.org/jdk/pull/27772/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=27772&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8369184 Stats: 102 lines in 2 files changed: 94 ins; 0 del; 8 mod Patch: https://git.openjdk.org/jdk/pull/27772.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27772/head:pull/27772 PR: https://git.openjdk.org/jdk/pull/27772 From pminborg at openjdk.org Mon Oct 13 14:13:42 2025 From: pminborg at openjdk.org (Per Minborg) Date: Mon, 13 Oct 2025 14:13:42 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v4] In-Reply-To: References: Message-ID: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. Per Minborg has updated the pull request incrementally with one additional commit since the last revision: Reprhase text around the computing thread ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27605/files - new: https://git.openjdk.org/jdk/pull/27605/files/5770e033..47af4307 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=03 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=02-03 Stats: 13 lines in 1 file changed: 1 ins; 2 del; 10 mod Patch: https://git.openjdk.org/jdk/pull/27605.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27605/head:pull/27605 PR: https://git.openjdk.org/jdk/pull/27605 From pminborg at openjdk.org Mon Oct 13 14:18:53 2025 From: pminborg at openjdk.org (Per Minborg) Date: Mon, 13 Oct 2025 14:18:53 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v5] In-Reply-To: References: Message-ID: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. Per Minborg has updated the pull request incrementally with one additional commit since the last revision: Rephrase trusted field text ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27605/files - new: https://git.openjdk.org/jdk/pull/27605/files/47af4307..ea14b8f9 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=04 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=03-04 Stats: 2 lines in 1 file changed: 0 ins; 0 del; 2 mod Patch: https://git.openjdk.org/jdk/pull/27605.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27605/head:pull/27605 PR: https://git.openjdk.org/jdk/pull/27605 From pminborg at openjdk.org Mon Oct 13 14:22:13 2025 From: pminborg at openjdk.org (Per Minborg) Date: Mon, 13 Oct 2025 14:22:13 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v6] In-Reply-To: References: Message-ID: <5EAP5ubicOh_odm_aPlWJZbDQTuV0AIRs-fHlW7jTlc=.86692372-8a21-49dc-a453-4dbeef84d242@github.com> > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. Per Minborg has updated the pull request incrementally with one additional commit since the last revision: Define constant folding ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27605/files - new: https://git.openjdk.org/jdk/pull/27605/files/ea14b8f9..e25eeb9b Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=05 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=04-05 Stats: 7 lines in 1 file changed: 1 ins; 0 del; 6 mod Patch: https://git.openjdk.org/jdk/pull/27605.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27605/head:pull/27605 PR: https://git.openjdk.org/jdk/pull/27605 From pminborg at openjdk.org Mon Oct 13 14:33:06 2025 From: pminborg at openjdk.org (Per Minborg) Date: Mon, 13 Oct 2025 14:33:06 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v7] In-Reply-To: References: Message-ID: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. Per Minborg has updated the pull request incrementally with one additional commit since the last revision: Update src/java.base/share/classes/java/lang/LazyConstant.java Co-authored-by: Maurizio Cimadamore <54672762+mcimadamore at users.noreply.github.com> ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27605/files - new: https://git.openjdk.org/jdk/pull/27605/files/e25eeb9b..5845a7a5 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=06 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=05-06 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/27605.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27605/head:pull/27605 PR: https://git.openjdk.org/jdk/pull/27605 From mcimadamore at openjdk.org Mon Oct 13 14:33:08 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Mon, 13 Oct 2025 14:33:08 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v6] In-Reply-To: <5EAP5ubicOh_odm_aPlWJZbDQTuV0AIRs-fHlW7jTlc=.86692372-8a21-49dc-a453-4dbeef84d242@github.com> References: <5EAP5ubicOh_odm_aPlWJZbDQTuV0AIRs-fHlW7jTlc=.86692372-8a21-49dc-a453-4dbeef84d242@github.com> Message-ID: On Mon, 13 Oct 2025 14:22:13 GMT, Per Minborg wrote: >> Implement JEP 526: Lazy Constants (Second Preview) >> >> The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. >> >> The old benchmarks are not moved/renamed to allow comparison with previous releases. >> >> `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. > > Per Minborg has updated the pull request incrementally with one additional commit since the last revision: > > Define constant folding src/java.base/share/classes/java/lang/LazyConstant.java line 156: > 154: * {@code final} fields of any newly created objects, are safely published. > 155: *

> 156: * If the computing thread or any thread that is blocked by the computing thread My worry here is that when we say "any thread that is blocked" we really meany "any thread". But in reality this javadoc only refers to threads that are trying to call `get` and end up blocked because some other thread won the race. E.g. if a thread is blocked by the computing thread for any other reason, we don't know whether interrupting that thread will result in an `InterruptedException` ? I think it might be worth simplifying this a bit, starting with the property you want to assert: > Thread interruption does not cancel initialization of a lazy constant. In other words, if the computing thread is > interrupted, `LazyConstant::get` doesn't clear the interrupted thread?s status is not cleared, nor does it throw > an `InterruptedException`. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2426515394 From pminborg at openjdk.org Mon Oct 13 14:33:10 2025 From: pminborg at openjdk.org (Per Minborg) Date: Mon, 13 Oct 2025 14:33:10 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v7] In-Reply-To: References: Message-ID: On Mon, 13 Oct 2025 13:44:07 GMT, Maurizio Cimadamore wrote: >> Per Minborg has updated the pull request incrementally with one additional commit since the last revision: >> >> Update src/java.base/share/classes/java/lang/LazyConstant.java >> >> Co-authored-by: Maurizio Cimadamore <54672762+mcimadamore at users.noreply.github.com> > > src/java.base/share/classes/java/lang/LazyConstant.java line 192: > >> 190: * The {@code LazyConstant} type is not {@link Serializable}. >> 191: *

>> 192: * It is not recommended putting lazy constants into equality-based collections > > Not sure what you mean here. It seems like the javadoc for `equals` says that it triggers initialization, so it should be ok? Formally, it is ok, but may result in strange side effects if we, for example, put a key of type LazyConstant in a map. It will then be initialized immediately (upon `map.put()`), and the put operation can therefore have non-obvious side effects. > src/java.base/share/classes/java/lang/LazyConstant.java line 276: > >> 274: * this method might block or throw. >> 275: * >> 276: * @implSpec The order of potential initialization triggering is specified as: > > Do we really need to specify this? This is a corner case, but we might have two uninitialized LCs. The order in which they get computed might be significant (e.g., they operate on shared data structures). ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2426507366 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2426513556 From mcimadamore at openjdk.org Mon Oct 13 14:33:13 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Mon, 13 Oct 2025 14:33:13 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v7] In-Reply-To: References: Message-ID: On Mon, 13 Oct 2025 14:25:58 GMT, Per Minborg wrote: >> src/java.base/share/classes/java/lang/LazyConstant.java line 276: >> >>> 274: * this method might block or throw. >>> 275: * >>> 276: * @implSpec The order of potential initialization triggering is specified as: >> >> Do we really need to specify this? > > This is a corner case, but we might have two uninitialized LCs. The order in which they get computed might be significant (e.g., they operate on shared data structures). I understand that the order might be significant -- but I still wonder if we should specify that order. This seems to add constraints to the implementation. Do we really want clients to rely on the order in which lazy constants are initialized when calling `equals` ? ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2426522315 From mcimadamore at openjdk.org Mon Oct 13 14:37:27 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Mon, 13 Oct 2025 14:37:27 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v7] In-Reply-To: References: Message-ID: On Mon, 13 Oct 2025 14:23:40 GMT, Per Minborg wrote: >> src/java.base/share/classes/java/lang/LazyConstant.java line 192: >> >>> 190: * The {@code LazyConstant} type is not {@link Serializable}. >>> 191: *

>>> 192: * It is not recommended putting lazy constants into equality-based collections >> >> Not sure what you mean here. It seems like the javadoc for `equals` says that it triggers initialization, so it should be ok? > > Formally, it is ok, but may result in strange side effects if we, for example, put a key of type LazyConstant in a map. It will then be initialized immediately (upon `map.put()`), and the put operation can therefore have non-obvious side effects. I think it would be better to link to `equals` more explicitly -- e.g. "As equals and hashCode might trigger the initialization of a lazy constant, it is recommended to avoid storing lazy constants into equality-based collections (or similar constructs) as their addition (e.g. via `Map::put`, or `Set::add`) might result in subtle side-effects). ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2426535831 From mcimadamore at openjdk.org Mon Oct 13 14:44:09 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Mon, 13 Oct 2025 14:44:09 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v7] In-Reply-To: References: Message-ID: On Mon, 13 Oct 2025 14:33:06 GMT, Per Minborg wrote: >> Implement JEP 526: Lazy Constants (Second Preview) >> >> The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. >> >> The old benchmarks are not moved/renamed to allow comparison with previous releases. >> >> `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. > > Per Minborg has updated the pull request incrementally with one additional commit since the last revision: > > Update src/java.base/share/classes/java/lang/LazyConstant.java > > Co-authored-by: Maurizio Cimadamore <54672762+mcimadamore at users.noreply.github.com> src/java.base/share/classes/java/lang/LazyConstant.java line 287: > 285: */ > 286: @Override > 287: boolean equals(Object obj); There is a tension here (same for hashCode). A lazy constant is a mutable cell that can be updated only once, given some computing function. When you compare two lazy constants, you can either compare the mutable cell (e.g. the pointer to the memory location where the constant will be eventually stored), or you can compare the constants. Here, the javadoc decides to opt for comparing the constants -- but this might be problematic, as now `equals` can throw exceptions too (and/or result in blocking, as you say in the javadoc). So, I'm not too sure what's the best option here -- do we have an idea of how frequent it is to want to compare two lazy constants "by value" ? (for reference, we have no precedent for this: `ClassValue`, `ScopedValue` and `ThreadLocal` do not redefine equals/hashCode). ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2426553275 From jlu at openjdk.org Mon Oct 13 16:14:31 2025 From: jlu at openjdk.org (Justin Lu) Date: Mon, 13 Oct 2025 16:14:31 GMT Subject: Integrated: 8369452: Locale.Builder.setLanguageTag(String) does not clear on empty or null String In-Reply-To: References: Message-ID: On Thu, 9 Oct 2025 18:12:58 GMT, Justin Lu wrote: > Please review this PR which corrects the behavior of `Locale.Builder.setLanguageTag(String)` on the null and empty String case. > > This method is specified as follows, > >> Null and the empty string cause the builder to be reset > > Currently, NPE is thrown for a null tag, and ILE is thrown for an empty String. They are both corrected to not throw, and instead reset the state of the `Locale.Builder`. This pull request has now been integrated. Changeset: 1d6cafdc Author: Justin Lu URL: https://git.openjdk.org/jdk/commit/1d6cafdc5244960ddec2fd82b8454c6c3cafe022 Stats: 27 lines in 2 files changed: 22 ins; 0 del; 5 mod 8369452: Locale.Builder.setLanguageTag(String) does not clear on empty or null String Reviewed-by: naoto ------------- PR: https://git.openjdk.org/jdk/pull/27734 From duke at openjdk.org Mon Oct 13 16:52:00 2025 From: duke at openjdk.org (ExE Boss) Date: Mon, 13 Oct 2025 16:52:00 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v2] In-Reply-To: <90jKH5-Bb3vf27uhLPOUtgmYmZRFdH1voVYr8kIR__I=.2aff8cb2-38be-4dd3-a1df-e3f8a7a90542@github.com> References: <90jKH5-Bb3vf27uhLPOUtgmYmZRFdH1voVYr8kIR__I=.2aff8cb2-38be-4dd3-a1df-e3f8a7a90542@github.com> Message-ID: On Mon, 13 Oct 2025 13:54:44 GMT, Per Minborg wrote: >> Implement JEP 526: Lazy Constants (Second Preview) >> >> The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. >> >> The old benchmarks are not moved/renamed to allow comparison with previous releases. >> >> `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. > > Per Minborg has updated the pull request incrementally with one additional commit since the last revision: > > Remove redundant field src/java.base/share/classes/java/util/AbstractMap.java line 335: > 333: */ > 334: @Stable > 335: transient Set keySet; Are?all?uses of?this?field in?`java.util` able?to?handle the?`@Stable`ness of?this?field correctly? ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2426844190 From liach at openjdk.org Mon Oct 13 18:49:05 2025 From: liach at openjdk.org (Chen Liang) Date: Mon, 13 Oct 2025 18:49:05 GMT Subject: [jdk25] RFR: 8369184: SimpleTimeZone equals() Returns True for Unequal Instances with Different hashCode Values In-Reply-To: References: Message-ID: On Mon, 13 Oct 2025 13:58:04 GMT, Kieran Farrell wrote: > Clean backport Hi, I don't think this is the right branch to backport to - you should backport to the master branch of jdk25u repo. ------------- PR Comment: https://git.openjdk.org/jdk/pull/27772#issuecomment-3398668419 From kfarrell at openjdk.org Mon Oct 13 19:34:14 2025 From: kfarrell at openjdk.org (Kieran Farrell) Date: Mon, 13 Oct 2025 19:34:14 GMT Subject: [jdk25] Withdrawn: 8369184: SimpleTimeZone equals() Returns True for Unequal Instances with Different hashCode Values In-Reply-To: References: Message-ID: On Mon, 13 Oct 2025 13:58:04 GMT, Kieran Farrell wrote: > Clean backport This pull request has been closed without being integrated. ------------- PR: https://git.openjdk.org/jdk/pull/27772 From jlu at openjdk.org Mon Oct 13 21:27:14 2025 From: jlu at openjdk.org (Justin Lu) Date: Mon, 13 Oct 2025 21:27:14 GMT Subject: RFR: 8369590: LocaleEnhanceTest has incorrectly passing test case Message-ID: This PR corrects _test/jdk/java/util/Locale/LocaleEnhanceTest.java_, which has two test cases under `testBuilderSetLanguageTag()` which accidentally pass. One checks that Locale.setLanguageTag(String) throws ILE for duplicate extensions and the other for duplicate U-extension keys. The test cases are updated to actually test the provided code. When the test cases are fixed, they now fail. Fixing the behavior to match the expectation of those test cases is consistent with the specification. >From `Locale.forLanguageTag(String)`, > > *

If the specified language tag contains any ill-formed subtags, > * the first such subtag and all following subtags are ignored. Compare > * to {@link Locale.Builder#setLanguageTag(String)} which throws an exception > * in this case. and the RFC specification > Each singleton subtag MUST appear at most one time in each tag > (other than as a private use subtag). That is, singleton subtags > MUST NOT be repeated. For example, the tag "en-a-bbb-a-ccc" is > invalid because the subtag 'a' appears twice. Since duplicate extensions (and Unicode keys/attributes) are invalid, throwing `IllformedLocaleException` in (the strict) `Locale.Builder` and ignoring in (the lenient) `Locale.forLanguageTag` for such tags would be appropriate. This PR updates the implementation as such. ------------- Commit messages: - Add duplicate checking for Locale.Builder.setLanguageTag(String) - Add duplicate U extension attributes test case - Remove testing classes in favor or JUnit (which fixes unintentional passing) Changes: https://git.openjdk.org/jdk/pull/27775/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=27775&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8369590 Stats: 686 lines in 4 files changed: 75 ins; 169 del; 442 mod Patch: https://git.openjdk.org/jdk/pull/27775.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27775/head:pull/27775 PR: https://git.openjdk.org/jdk/pull/27775 From jlu at openjdk.org Mon Oct 13 21:27:15 2025 From: jlu at openjdk.org (Justin Lu) Date: Mon, 13 Oct 2025 21:27:15 GMT Subject: RFR: 8369590: LocaleEnhanceTest has incorrectly passing test case In-Reply-To: References: Message-ID: On Mon, 13 Oct 2025 20:55:45 GMT, Justin Lu wrote: > This PR corrects _test/jdk/java/util/Locale/LocaleEnhanceTest.java_, which has two test cases under `testBuilderSetLanguageTag()` which accidentally pass. One checks that Locale.setLanguageTag(String) throws ILE for duplicate extensions and the other for duplicate U-extension keys. The test cases are updated to actually test the provided code. When the test cases are fixed, they now fail. > > Fixing the behavior to match the expectation of those test cases is consistent with the specification. > > From `Locale.forLanguageTag(String)`, > >> >> *

If the specified language tag contains any ill-formed subtags, >> * the first such subtag and all following subtags are ignored. Compare >> * to {@link Locale.Builder#setLanguageTag(String)} which throws an exception >> * in this case. > > and the RFC specification > >> Each singleton subtag MUST appear at most one time in each tag >> (other than as a private use subtag). That is, singleton subtags >> MUST NOT be repeated. For example, the tag "en-a-bbb-a-ccc" is >> invalid because the subtag 'a' appears twice. > > Since duplicate extensions (and Unicode keys/attributes) are invalid, throwing `IllformedLocaleException` in (the strict) `Locale.Builder` and ignoring in (the lenient) `Locale.forLanguageTag` for such tags would be appropriate. This PR updates the implementation as such. src/java.base/share/classes/sun/util/locale/InternalLocaleBuilder.java line 212: > 210: > 211: if (UnicodeLocaleExtension.isSingletonChar(key.value())) { > 212: setUnicodeLocaleExtension(val, true); This code is called under `Locale.Builder.setExtension(char, String)`, which remains lenient for duplicate U-extension keys and attributes since this existing behavior is confirmed as a test case in _LocaleEnhanceTest_, // redundant locale extensions are ignored result = builder .clear() .setExtension('u', "nu-thai-NU-chinese-xx-1234") .build() .toLanguageTag(); assertEquals("duplicate keys", "und-u-nu-thai-xx-1234", result); test/jdk/java/util/Locale/LocaleEnhanceTest.java line 767: > 765: > 766: // redundant Unicode locale extension keys within an Unicode locale extension cause a failure > 767: new BuilderILE() { public void call() { b.setLanguageTag("und-u-nu-thai-NU-chinese-xx-1234"); }}; These lines both relied on the `BuilderILE` testing class. However, since they provided no args to the ctor, the `run()` call does not actually execute the provided code under `call()`. `BuilderILE` and the other helper testing classes are replaced with JUnit in https://github.com/openjdk/jdk/pull/27775/commits/f4927421ad3f7b2647ecd29059e2e64683b9f270. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27775#discussion_r2427333112 PR Review Comment: https://git.openjdk.org/jdk/pull/27775#discussion_r2427320692 From jlu at openjdk.org Mon Oct 13 21:51:32 2025 From: jlu at openjdk.org (Justin Lu) Date: Mon, 13 Oct 2025 21:51:32 GMT Subject: RFR: 8369590: LocaleEnhanceTest has incorrectly passing test case [v2] In-Reply-To: References: Message-ID: <11DDueNxPmVaTZ2u9WMchm4kWfC5Ims83jkGE3S2RXQ=.03c79e51-6977-45c0-ae6f-c55e03d62598@github.com> > This PR corrects _test/jdk/java/util/Locale/LocaleEnhanceTest.java_, which has two test cases under `testBuilderSetLanguageTag()` which accidentally pass. One checks that Locale.setLanguageTag(String) throws ILE for duplicate extensions and the other for duplicate U-extension keys. The test cases are updated to actually test the provided code. When the test cases are fixed, they now fail. > > Fixing the behavior to match the expectation of those test cases is consistent with the specification. > > From `Locale.forLanguageTag(String)`, > >> >> *

If the specified language tag contains any ill-formed subtags, >> * the first such subtag and all following subtags are ignored. Compare >> * to {@link Locale.Builder#setLanguageTag(String)} which throws an exception >> * in this case. > > and the RFC specification > >> Each singleton subtag MUST appear at most one time in each tag >> (other than as a private use subtag). That is, singleton subtags >> MUST NOT be repeated. For example, the tag "en-a-bbb-a-ccc" is >> invalid because the subtag 'a' appears twice. > > Since duplicate extensions (and Unicode keys/attributes) are invalid, throwing `IllformedLocaleException` in (the strict) `Locale.Builder` and ignoring in (the lenient) `Locale.forLanguageTag` for such tags would be appropriate. This PR updates the implementation as such. Justin Lu has updated the pull request incrementally with one additional commit since the last revision: Adding test case to confirm duplicate U-extension attributes for setExtension(char, String) ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27775/files - new: https://git.openjdk.org/jdk/pull/27775/files/524dd361..f73a15ae Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27775&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27775&range=00-01 Stats: 8 lines in 1 file changed: 8 ins; 0 del; 0 mod Patch: https://git.openjdk.org/jdk/pull/27775.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27775/head:pull/27775 PR: https://git.openjdk.org/jdk/pull/27775 From naoto at openjdk.org Mon Oct 13 22:29:05 2025 From: naoto at openjdk.org (Naoto Sato) Date: Mon, 13 Oct 2025 22:29:05 GMT Subject: RFR: 8369590: LocaleEnhanceTest has incorrectly passing test case [v2] In-Reply-To: <11DDueNxPmVaTZ2u9WMchm4kWfC5Ims83jkGE3S2RXQ=.03c79e51-6977-45c0-ae6f-c55e03d62598@github.com> References: <11DDueNxPmVaTZ2u9WMchm4kWfC5Ims83jkGE3S2RXQ=.03c79e51-6977-45c0-ae6f-c55e03d62598@github.com> Message-ID: On Mon, 13 Oct 2025 21:51:32 GMT, Justin Lu wrote: >> This PR corrects _test/jdk/java/util/Locale/LocaleEnhanceTest.java_, which has two test cases under `testBuilderSetLanguageTag()` which accidentally pass. One checks that Locale.setLanguageTag(String) throws ILE for duplicate extensions and the other for duplicate U-extension keys. The test cases are updated to actually test the provided code. When the test cases are fixed, they now fail. >> >> Fixing the behavior to match the expectation of those test cases is consistent with the specification. >> >> From `Locale.forLanguageTag(String)`, >> >>> >>> *

If the specified language tag contains any ill-formed subtags, >>> * the first such subtag and all following subtags are ignored. Compare >>> * to {@link Locale.Builder#setLanguageTag(String)} which throws an exception >>> * in this case. >> >> and the RFC specification >> >>> Each singleton subtag MUST appear at most one time in each tag >>> (other than as a private use subtag). That is, singleton subtags >>> MUST NOT be repeated. For example, the tag "en-a-bbb-a-ccc" is >>> invalid because the subtag 'a' appears twice. >> >> Since duplicate extensions (and Unicode keys/attributes) are invalid, throwing `IllformedLocaleException` in (the strict) `Locale.Builder` and ignoring in (the lenient) `Locale.forLanguageTag` for such tags would be appropriate. This PR updates the implementation as such. > > Justin Lu has updated the pull request incrementally with one additional commit since the last revision: > > Adding test case to confirm duplicate U-extension attributes for setExtension(char, String) IIUC, the quote from the RFC refers to duplicate singletons. For example, it would reject something like `-u-aa-bbb-u-cc-ddd`. So I believe that rule doesn?t apply to cases like `-u-aa-bbb-AA-ccc`. I checked the `-u` extension definition in LDML but couldn?t find any description regarding duplicate keywords. That said, I think it makes sense to allow them in lenient mode and throw an exception in strict mode. Since this would introduce a behavioral change, I?d expect it to require a CSR. ------------- PR Comment: https://git.openjdk.org/jdk/pull/27775#issuecomment-3399242375 From jlu at openjdk.org Tue Oct 14 21:11:39 2025 From: jlu at openjdk.org (Justin Lu) Date: Tue, 14 Oct 2025 21:11:39 GMT Subject: RFR: 8369590: LocaleEnhanceTest has incorrectly passing test case [v3] In-Reply-To: References: Message-ID: > This PR corrects _test/jdk/java/util/Locale/LocaleEnhanceTest.java_, which has two test cases under `testBuilderSetLanguageTag()` which accidentally pass. One checks that Locale.setLanguageTag(String) throws ILE for duplicate extensions and the other for duplicate U-extension keys. The test cases are updated to actually test the provided code. When the test cases are fixed, they now fail. > > Fixing the behavior to match the expectation of those test cases is consistent with the specification. > > From `Locale.forLanguageTag(String)`, > >> >> *

If the specified language tag contains any ill-formed subtags, >> * the first such subtag and all following subtags are ignored. Compare >> * to {@link Locale.Builder#setLanguageTag(String)} which throws an exception >> * in this case. > > and the RFC specification > >> Each singleton subtag MUST appear at most one time in each tag >> (other than as a private use subtag). That is, singleton subtags >> MUST NOT be repeated. For example, the tag "en-a-bbb-a-ccc" is >> invalid because the subtag 'a' appears twice. > > Since duplicate extensions (and Unicode keys/attributes) are invalid, throwing `IllformedLocaleException` in (the strict) `Locale.Builder` and ignoring in (the lenient) `Locale.forLanguageTag` for such tags would be appropriate. This PR updates the implementation as such. Justin Lu has updated the pull request incrementally with one additional commit since the last revision: Align setExtension(char, String) + spec updates ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27775/files - new: https://git.openjdk.org/jdk/pull/27775/files/f73a15ae..b3167f13 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27775&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27775&range=01-02 Stats: 32 lines in 3 files changed: 11 ins; 4 del; 17 mod Patch: https://git.openjdk.org/jdk/pull/27775.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27775/head:pull/27775 PR: https://git.openjdk.org/jdk/pull/27775 From jlu at openjdk.org Tue Oct 14 21:11:41 2025 From: jlu at openjdk.org (Justin Lu) Date: Tue, 14 Oct 2025 21:11:41 GMT Subject: RFR: 8369590: LocaleEnhanceTest has incorrectly passing test case [v2] In-Reply-To: References: <11DDueNxPmVaTZ2u9WMchm4kWfC5Ims83jkGE3S2RXQ=.03c79e51-6977-45c0-ae6f-c55e03d62598@github.com> Message-ID: On Mon, 13 Oct 2025 22:26:07 GMT, Naoto Sato wrote: >> Justin Lu has updated the pull request incrementally with one additional commit since the last revision: >> >> Adding test case to confirm duplicate U-extension attributes for setExtension(char, String) > > IIUC, the quote from the RFC refers to duplicate singletons. For example, it would reject something like `-u-aa-bbb-u-cc-ddd`. So I believe that rule doesn?t apply to cases like `-u-aa-bbb-AA-ccc`. I checked the `-u` extension definition in LDML but couldn?t find any description regarding duplicate keywords. > > That said, I think it makes sense to allow them in lenient mode and throw an exception in strict mode. Since this would introduce a behavioral change, I?d expect it to require a CSR. @naotoj CSR is filed and this PR is updated with the appropriate specification updates. `setExtension(char, String)` is also updated to align with `setLanguageTag(String)` on the behavior of duplicate U-extension keys and attributes as we discussed. ------------- PR Comment: https://git.openjdk.org/jdk/pull/27775#issuecomment-3403621489 From aturbanov at openjdk.org Wed Oct 15 08:42:22 2025 From: aturbanov at openjdk.org (Andrey Turbanov) Date: Wed, 15 Oct 2025 08:42:22 GMT Subject: RFR: 8369590: LocaleEnhanceTest has incorrectly passing test case [v3] In-Reply-To: References: Message-ID: On Tue, 14 Oct 2025 21:11:39 GMT, Justin Lu wrote: >> This PR corrects _test/jdk/java/util/Locale/LocaleEnhanceTest.java_, which has two test cases under `testBuilderSetLanguageTag()` which accidentally pass. One checks that Locale.setLanguageTag(String) throws ILE for duplicate extensions and the other for duplicate U-extension keys. The test cases are updated to actually test the provided code. When the test cases are fixed, they now fail. >> >> Fixing the behavior to match the expectation of those test cases is consistent with the specification. >> >> From `Locale.forLanguageTag(String)`, >> >>> >>> *

If the specified language tag contains any ill-formed subtags, >>> * the first such subtag and all following subtags are ignored. Compare >>> * to {@link Locale.Builder#setLanguageTag(String)} which throws an exception >>> * in this case. >> >> and the RFC specification >> >>> Each singleton subtag MUST appear at most one time in each tag >>> (other than as a private use subtag). That is, singleton subtags >>> MUST NOT be repeated. For example, the tag "en-a-bbb-a-ccc" is >>> invalid because the subtag 'a' appears twice. >> >> Since duplicate extensions (and Unicode keys/attributes) are invalid, throwing `IllformedLocaleException` in (the strict) `Locale.Builder` and ignoring in (the lenient) `Locale.forLanguageTag` for such tags would be appropriate. This PR updates the implementation as such. > > Justin Lu has updated the pull request incrementally with one additional commit since the last revision: > > Align setExtension(char, String) + spec updates test/jdk/java/util/Locale/LocaleEnhanceTest.java line 1096: > 1094: // null attribute throws NPE > 1095: assertThrows(NullPointerException.class, > 1096: () -> new Builder().addUnicodeLocaleAttribute(null), "null attribute"); Suggestion: () -> new Builder().addUnicodeLocaleAttribute(null), "null attribute"); ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27775#discussion_r2431645260 From naoto at openjdk.org Wed Oct 15 17:30:53 2025 From: naoto at openjdk.org (Naoto Sato) Date: Wed, 15 Oct 2025 17:30:53 GMT Subject: RFR: 8369590: LocaleEnhanceTest has incorrectly passing test case [v3] In-Reply-To: References: Message-ID: <8UUWtXMN_CGEU_bQKvMXONleEgOgipFjFg9nKDb8ozM=.a6bfa378-8794-49e0-b61c-64da61897bed@github.com> On Tue, 14 Oct 2025 21:11:39 GMT, Justin Lu wrote: >> This PR corrects _test/jdk/java/util/Locale/LocaleEnhanceTest.java_, which has two test cases under `testBuilderSetLanguageTag()` which accidentally pass. One checks that Locale.setLanguageTag(String) throws ILE for duplicate extensions and the other for duplicate U-extension keys. The test cases are updated to actually test the provided code. When the test cases are fixed, they now fail. >> >> Fixing the behavior to match the expectation of those test cases is consistent with the specification. >> >> From `Locale.forLanguageTag(String)`, >> >>> >>> *

If the specified language tag contains any ill-formed subtags, >>> * the first such subtag and all following subtags are ignored. Compare >>> * to {@link Locale.Builder#setLanguageTag(String)} which throws an exception >>> * in this case. >> >> and the RFC specification >> >>> Each singleton subtag MUST appear at most one time in each tag >>> (other than as a private use subtag). That is, singleton subtags >>> MUST NOT be repeated. For example, the tag "en-a-bbb-a-ccc" is >>> invalid because the subtag 'a' appears twice. >> >> Since duplicate extensions (and Unicode keys/attributes) are invalid, throwing `IllformedLocaleException` in (the strict) `Locale.Builder` and ignoring in (the lenient) `Locale.forLanguageTag` for such tags would be appropriate. This PR updates the implementation as such. > > Justin Lu has updated the pull request incrementally with one additional commit since the last revision: > > Align setExtension(char, String) + spec updates LGTM. Glad to see those test clean-ups, especiallly getting rid of the proprietary test framework ------------- Marked as reviewed by naoto (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/27775#pullrequestreview-3341556118 From rgiulietti at openjdk.org Wed Oct 15 18:09:33 2025 From: rgiulietti at openjdk.org (Raffaello Giulietti) Date: Wed, 15 Oct 2025 18:09:33 GMT Subject: RFR: 8341914: The j.u.Formatter doc for TemporalAccessor should be enhanced Message-ID: Doc only change. ------------- Commit messages: - 8341914: The j.u.Formatter doc for TemporalAccessor should be enhanced Changes: https://git.openjdk.org/jdk/pull/27830/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=27830&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8341914 Stats: 8 lines in 1 file changed: 8 ins; 0 del; 0 mod Patch: https://git.openjdk.org/jdk/pull/27830.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27830/head:pull/27830 PR: https://git.openjdk.org/jdk/pull/27830 From rgiulietti at openjdk.org Wed Oct 15 18:20:36 2025 From: rgiulietti at openjdk.org (Raffaello Giulietti) Date: Wed, 15 Oct 2025 18:20:36 GMT Subject: RFR: 8341914: The j.u.Formatter doc for TemporalAccessor should be enhanced [v2] In-Reply-To: References: Message-ID: > Doc only change. Raffaello Giulietti has updated the pull request incrementally with one additional commit since the last revision: Add the 'c' conversion as well. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27830/files - new: https://git.openjdk.org/jdk/pull/27830/files/b3c6a01a..c51f19f6 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27830&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27830&range=00-01 Stats: 4 lines in 1 file changed: 4 ins; 0 del; 0 mod Patch: https://git.openjdk.org/jdk/pull/27830.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27830/head:pull/27830 PR: https://git.openjdk.org/jdk/pull/27830 From rriggs at openjdk.org Wed Oct 15 19:00:59 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Wed, 15 Oct 2025 19:00:59 GMT Subject: RFR: 8341914: The j.u.Formatter doc for TemporalAccessor should be enhanced [v2] In-Reply-To: References: Message-ID: On Wed, 15 Oct 2025 18:20:36 GMT, Raffaello Giulietti wrote: >> Doc only change. > > Raffaello Giulietti has updated the pull request incrementally with one additional commit since the last revision: > > Add the 'c' conversion as well. The PR comment should be more complete than just "doc only change". It should describe the scope and intent. It makes the emails and PR easier to grok without having to read the code. ------------- PR Comment: https://git.openjdk.org/jdk/pull/27830#issuecomment-3407837104 From rriggs at openjdk.org Wed Oct 15 19:15:52 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Wed, 15 Oct 2025 19:15:52 GMT Subject: RFR: 8341914: The j.u.Formatter doc for TemporalAccessor should be enhanced [v2] In-Reply-To: References: Message-ID: On Wed, 15 Oct 2025 18:20:36 GMT, Raffaello Giulietti wrote: >> Doc only change. > > Raffaello Giulietti has updated the pull request incrementally with one additional commit since the last revision: > > Add the 'c' conversion as well. A bit more background would be useful here. The mention of TemporalAccessor in the context of timezone formatting characters seems out of place or too specific. It would be more appropriate to highlight that data dependent requirement in the section on Date/Time formatting. ------------- PR Comment: https://git.openjdk.org/jdk/pull/27830#issuecomment-3407905758 From naoto at openjdk.org Wed Oct 15 19:41:28 2025 From: naoto at openjdk.org (Naoto Sato) Date: Wed, 15 Oct 2025 19:41:28 GMT Subject: RFR: 8341914: The j.u.Formatter doc for TemporalAccessor should be enhanced [v2] In-Reply-To: References: Message-ID: On Wed, 15 Oct 2025 18:20:36 GMT, Raffaello Giulietti wrote: >> Doc only change. > > Raffaello Giulietti has updated the pull request incrementally with one additional commit since the last revision: > > Add the 'c' conversion as well. Would this only apply to time zone? What if `LocalDate` is passed as a `TemporalAccessor` and the conversion requests hour or minute? Could this be more generic? ------------- PR Comment: https://git.openjdk.org/jdk/pull/27830#issuecomment-3407984637 From jlu at openjdk.org Wed Oct 15 20:37:16 2025 From: jlu at openjdk.org (Justin Lu) Date: Wed, 15 Oct 2025 20:37:16 GMT Subject: RFR: 8369590: LocaleEnhanceTest has incorrectly passing test case [v4] In-Reply-To: References: Message-ID: > This PR corrects _test/jdk/java/util/Locale/LocaleEnhanceTest.java_, which has two test cases under `testBuilderSetLanguageTag()` which accidentally pass. One checks that Locale.setLanguageTag(String) throws ILE for duplicate extensions and the other for duplicate U-extension keys. The test cases are updated to actually test the provided code. When the test cases are fixed, they now fail. > > Fixing the behavior to match the expectation of those test cases is consistent with the specification. > > From `Locale.forLanguageTag(String)`, > >> >> *

If the specified language tag contains any ill-formed subtags, >> * the first such subtag and all following subtags are ignored. Compare >> * to {@link Locale.Builder#setLanguageTag(String)} which throws an exception >> * in this case. > > and the RFC specification > >> Each singleton subtag MUST appear at most one time in each tag >> (other than as a private use subtag). That is, singleton subtags >> MUST NOT be repeated. For example, the tag "en-a-bbb-a-ccc" is >> invalid because the subtag 'a' appears twice. > > Since duplicate extensions (and Unicode keys/attributes) are invalid, throwing `IllformedLocaleException` in (the strict) `Locale.Builder` and ignoring in (the lenient) `Locale.forLanguageTag` for such tags would be appropriate. This PR updates the implementation as such. Justin Lu has updated the pull request incrementally with one additional commit since the last revision: Spacing fix in LocaleEnhanceTest.java Co-authored-by: Andrey Turbanov ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27775/files - new: https://git.openjdk.org/jdk/pull/27775/files/b3167f13..b0cfd59b Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27775&range=03 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27775&range=02-03 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/27775.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27775/head:pull/27775 PR: https://git.openjdk.org/jdk/pull/27775 From rgiulietti at openjdk.org Wed Oct 15 20:49:44 2025 From: rgiulietti at openjdk.org (Raffaello Giulietti) Date: Wed, 15 Oct 2025 20:49:44 GMT Subject: RFR: 8341914: The j.u.Formatter doc for TemporalAccessor should be enhanced [v2] In-Reply-To: References: Message-ID: On Wed, 15 Oct 2025 18:20:36 GMT, Raffaello Giulietti wrote: >> Doc only change. > > Raffaello Giulietti has updated the pull request incrementally with one additional commit since the last revision: > > Add the 'c' conversion as well. The `Formatter` documentation related to dates/times has 3 tables: for times, for dates, and for "common date/time compositions". All conversion character for dates are applicable to all dates/datetimes (but not to times-only instances). Something similar should hold for conversion characters of times/datetimes: they should be applicable to all times/datetimes (and not to date-only instances). But `z` and `Z` represent an exception, as they apply only if time zone information is available. ------------- PR Comment: https://git.openjdk.org/jdk/pull/27830#issuecomment-3408216496 From pminborg at openjdk.org Thu Oct 16 12:10:32 2025 From: pminborg at openjdk.org (Per Minborg) Date: Thu, 16 Oct 2025 12:10:32 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v7] In-Reply-To: References: Message-ID: On Mon, 13 Oct 2025 14:41:11 GMT, Maurizio Cimadamore wrote: >> Per Minborg has updated the pull request incrementally with one additional commit since the last revision: >> >> Update src/java.base/share/classes/java/lang/LazyConstant.java >> >> Co-authored-by: Maurizio Cimadamore <54672762+mcimadamore at users.noreply.github.com> > > src/java.base/share/classes/java/lang/LazyConstant.java line 287: > >> 285: */ >> 286: @Override >> 287: boolean equals(Object obj); > > There is a tension here (same for hashCode). A lazy constant is a mutable cell that can be updated only once, given some computing function. When you compare two lazy constants, you can either compare the mutable cell (e.g. the pointer to the memory location where the constant will be eventually stored), or you can compare the constants. Here, the javadoc decides to opt for comparing the constants -- but this might be problematic, as now `equals` can throw exceptions too (and/or result in blocking, as you say in the javadoc). So, I'm not too sure what's the best option here -- do we have an idea of how frequent it is to want to compare two lazy constants "by value" ? > > (for reference, we have no precedent for this: `ClassValue`, `ScopedValue` and `ThreadLocal` do not redefine equals/hashCode). I have reverted back to the default Object::hashCode and Object::equals methods ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2435655625 From pminborg at openjdk.org Thu Oct 16 12:13:46 2025 From: pminborg at openjdk.org (Per Minborg) Date: Thu, 16 Oct 2025 12:13:46 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v2] In-Reply-To: References: <90jKH5-Bb3vf27uhLPOUtgmYmZRFdH1voVYr8kIR__I=.2aff8cb2-38be-4dd3-a1df-e3f8a7a90542@github.com> Message-ID: On Mon, 13 Oct 2025 16:48:07 GMT, ExE Boss wrote: >> Per Minborg has updated the pull request incrementally with one additional commit since the last revision: >> >> Remove redundant field > > src/java.base/share/classes/java/util/AbstractMap.java line 335: > >> 333: */ >> 334: @Stable >> 335: transient Set keySet; > > Are?all?uses of?this?field in?`java.util` able?to?handle the?`@Stable`ness of?this?field correctly? That is a good question. The potentially different keySet values should be freely substitutable or else there seams to be something wrong. If they are FS, then the VM should be able to pick any. But it is a big assumption to say that *all* maps that extend AM behave in such a way. We could go back to the previous version and shadow the field. That seems safest. Note: there is work in progress to remove these fields. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2435668562 From pminborg at openjdk.org Thu Oct 16 12:23:26 2025 From: pminborg at openjdk.org (Per Minborg) Date: Thu, 16 Oct 2025 12:23:26 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v8] In-Reply-To: References: Message-ID: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. Per Minborg 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 94 additional commits since the last revision: - Revert back to Object::(hashCode/equals) - Merge branch 'master' into lazy-constants - Update src/java.base/share/classes/java/lang/LazyConstant.java Co-authored-by: Maurizio Cimadamore <54672762+mcimadamore at users.noreply.github.com> - Define constant folding - Rephrase trusted field text - Reprhase text around the computing thread - Add links around Error and Throwable - Remove redundant field - Add optimization where the computing function is returned directly - Add benchmark of Optionals - ... and 84 more: https://git.openjdk.org/jdk/compare/6cbed094...8fa4a4ca ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27605/files - new: https://git.openjdk.org/jdk/pull/27605/files/5845a7a5..8fa4a4ca Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=07 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=06-07 Stats: 10612 lines in 265 files changed: 5868 ins; 4190 del; 554 mod Patch: https://git.openjdk.org/jdk/pull/27605.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27605/head:pull/27605 PR: https://git.openjdk.org/jdk/pull/27605 From pminborg at openjdk.org Thu Oct 16 12:33:31 2025 From: pminborg at openjdk.org (Per Minborg) Date: Thu, 16 Oct 2025 12:33:31 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v9] In-Reply-To: References: Message-ID: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. Per Minborg has updated the pull request incrementally with one additional commit since the last revision: Rephrase docs on interrupt ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27605/files - new: https://git.openjdk.org/jdk/pull/27605/files/8fa4a4ca..e6268f3d Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=08 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=07-08 Stats: 4 lines in 1 file changed: 0 ins; 1 del; 3 mod Patch: https://git.openjdk.org/jdk/pull/27605.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27605/head:pull/27605 PR: https://git.openjdk.org/jdk/pull/27605 From pminborg at openjdk.org Thu Oct 16 12:37:35 2025 From: pminborg at openjdk.org (Per Minborg) Date: Thu, 16 Oct 2025 12:37:35 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v10] In-Reply-To: References: Message-ID: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. Per Minborg has updated the pull request incrementally with one additional commit since the last revision: Update first javadoc sentence ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27605/files - new: https://git.openjdk.org/jdk/pull/27605/files/e6268f3d..f5493909 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=09 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=08-09 Stats: 2 lines in 1 file changed: 0 ins; 1 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/27605.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27605/head:pull/27605 PR: https://git.openjdk.org/jdk/pull/27605 From pminborg at openjdk.org Thu Oct 16 12:41:56 2025 From: pminborg at openjdk.org (Per Minborg) Date: Thu, 16 Oct 2025 12:41:56 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v11] In-Reply-To: References: Message-ID: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. Per Minborg has updated the pull request incrementally with one additional commit since the last revision: Fix test descriptions ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27605/files - new: https://git.openjdk.org/jdk/pull/27605/files/f5493909..a51f221a Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=10 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=09-10 Stats: 2 lines in 2 files changed: 0 ins; 0 del; 2 mod Patch: https://git.openjdk.org/jdk/pull/27605.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27605/head:pull/27605 PR: https://git.openjdk.org/jdk/pull/27605 From jlu at openjdk.org Thu Oct 16 21:56:33 2025 From: jlu at openjdk.org (Justin Lu) Date: Thu, 16 Oct 2025 21:56:33 GMT Subject: RFR: 8369590: LocaleEnhanceTest has incorrectly passing test case [v5] In-Reply-To: References: Message-ID: > This PR corrects _test/jdk/java/util/Locale/LocaleEnhanceTest.java_, which has two test cases under `testBuilderSetLanguageTag()` which accidentally pass. One checks that Locale.setLanguageTag(String) throws ILE for duplicate extensions and the other for duplicate U-extension keys. The test cases are updated to actually test the provided code. When the test cases are fixed, they now fail. > > Fixing the behavior to match the expectation of those test cases is consistent with the specification. > > From `Locale.forLanguageTag(String)`, > >> >> *

If the specified language tag contains any ill-formed subtags, >> * the first such subtag and all following subtags are ignored. Compare >> * to {@link Locale.Builder#setLanguageTag(String)} which throws an exception >> * in this case. > > and the RFC specification > >> Each singleton subtag MUST appear at most one time in each tag >> (other than as a private use subtag). That is, singleton subtags >> MUST NOT be repeated. For example, the tag "en-a-bbb-a-ccc" is >> invalid because the subtag 'a' appears twice. > > Since duplicate extensions (and Unicode keys/attributes) are invalid, throwing `IllformedLocaleException` in (the strict) `Locale.Builder` and ignoring in (the lenient) `Locale.forLanguageTag` for such tags would be appropriate. This PR updates the implementation as such. Justin Lu has updated the pull request incrementally with one additional commit since the last revision: Remove impl changes. Simply update test to reflect duplicate ignoring behavior ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27775/files - new: https://git.openjdk.org/jdk/pull/27775/files/b0cfd59b..62c9aa5b Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27775&range=04 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27775&range=03-04 Stats: 78 lines in 4 files changed: 4 ins; 38 del; 36 mod Patch: https://git.openjdk.org/jdk/pull/27775.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27775/head:pull/27775 PR: https://git.openjdk.org/jdk/pull/27775 From jlu at openjdk.org Thu Oct 16 21:56:34 2025 From: jlu at openjdk.org (Justin Lu) Date: Thu, 16 Oct 2025 21:56:34 GMT Subject: RFR: 8369590: LocaleEnhanceTest has incorrectly passing test case [v4] In-Reply-To: References: Message-ID: On Wed, 15 Oct 2025 20:37:16 GMT, Justin Lu wrote: >> This PR corrects _test/jdk/java/util/Locale/LocaleEnhanceTest.java_, which has two test cases under `testBuilderSetLanguageTag()` which accidentally pass. One checks that Locale.setLanguageTag(String) throws ILE for duplicate extensions and the other for duplicate U-extension keys. The test cases are updated to actually test the provided code. When the test cases are fixed, they now fail. >> >> Fixing the behavior to match the expectation of those test cases is consistent with the specification. >> >> From `Locale.forLanguageTag(String)`, >> >>> >>> *

If the specified language tag contains any ill-formed subtags, >>> * the first such subtag and all following subtags are ignored. Compare >>> * to {@link Locale.Builder#setLanguageTag(String)} which throws an exception >>> * in this case. >> >> and the RFC specification >> >>> Each singleton subtag MUST appear at most one time in each tag >>> (other than as a private use subtag). That is, singleton subtags >>> MUST NOT be repeated. For example, the tag "en-a-bbb-a-ccc" is >>> invalid because the subtag 'a' appears twice. >> >> Since duplicate extensions (and Unicode keys/attributes) are invalid, throwing `IllformedLocaleException` in (the strict) `Locale.Builder` and ignoring in (the lenient) `Locale.forLanguageTag` for such tags would be appropriate. This PR updates the implementation as such. > > Justin Lu has updated the pull request incrementally with one additional commit since the last revision: > > Spacing fix in LocaleEnhanceTest.java > > Co-authored-by: Andrey Turbanov As discussed, while it would be nice to enforce these duplicate cases, we do not guarantee validity of BCP47 tags. (Primarily, checking against the registry.) Duplicates falls under "valid", not "well-formed" and `Locale.Builder` should not have partial conformance of validity. Rather, the faulty test case should be updated to reflect the existing duplicate behavior. Additional tests to affirm existing behavior are added for duplicate U extension attributes as well. ------------- PR Comment: https://git.openjdk.org/jdk/pull/27775#issuecomment-3412979930 From naoto at openjdk.org Thu Oct 16 22:15:04 2025 From: naoto at openjdk.org (Naoto Sato) Date: Thu, 16 Oct 2025 22:15:04 GMT Subject: RFR: 8369590: LocaleEnhanceTest has incorrectly passing test case [v5] In-Reply-To: References: Message-ID: On Thu, 16 Oct 2025 21:56:33 GMT, Justin Lu wrote: >> This PR corrects _test/jdk/java/util/Locale/LocaleEnhanceTest.java_, which has two test cases under `testBuilderSetLanguageTag()` which accidentally pass. One checks that Locale.setLanguageTag(String) throws ILE for duplicate extensions and the other for duplicate U-extension keys. The test cases are updated to actually test the provided code. When the test cases are fixed, they now fail. >> >> Fixing the behavior to match the expectation of those test cases is consistent with the specification. >> >> From `Locale.forLanguageTag(String)`, >> >>> >>> *

If the specified language tag contains any ill-formed subtags, >>> * the first such subtag and all following subtags are ignored. Compare >>> * to {@link Locale.Builder#setLanguageTag(String)} which throws an exception >>> * in this case. >> >> and the RFC specification >> >>> Each singleton subtag MUST appear at most one time in each tag >>> (other than as a private use subtag). That is, singleton subtags >>> MUST NOT be repeated. For example, the tag "en-a-bbb-a-ccc" is >>> invalid because the subtag 'a' appears twice. >> >> Since duplicate extensions (and Unicode keys/attributes) are invalid, throwing `IllformedLocaleException` in (the strict) `Locale.Builder` and ignoring in (the lenient) `Locale.forLanguageTag` for such tags would be appropriate. This PR updates the implementation as such. > > Justin Lu has updated the pull request incrementally with one additional commit since the last revision: > > Remove impl changes. Simply update test to reflect duplicate ignoring behavior LGTM ------------- Marked as reviewed by naoto (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/27775#pullrequestreview-3347175094 From pminborg at openjdk.org Fri Oct 17 09:25:01 2025 From: pminborg at openjdk.org (Per Minborg) Date: Fri, 17 Oct 2025 09:25:01 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v12] In-Reply-To: References: Message-ID: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. Per Minborg has updated the pull request incrementally with one additional commit since the last revision: Update javadocs ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27605/files - new: https://git.openjdk.org/jdk/pull/27605/files/a51f221a..6a6e804e Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=11 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=10-11 Stats: 59 lines in 1 file changed: 7 ins; 3 del; 49 mod Patch: https://git.openjdk.org/jdk/pull/27605.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27605/head:pull/27605 PR: https://git.openjdk.org/jdk/pull/27605 From mcimadamore at openjdk.org Fri Oct 17 09:51:21 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Fri, 17 Oct 2025 09:51:21 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v12] In-Reply-To: References: Message-ID: On Fri, 17 Oct 2025 09:25:01 GMT, Per Minborg wrote: >> Implement JEP 526: Lazy Constants (Second Preview) >> >> The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. >> >> The old benchmarks are not moved/renamed to allow comparison with previous releases. >> >> `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. > > Per Minborg has updated the pull request incrementally with one additional commit since the last revision: > > Update javadocs src/java.base/share/classes/java/lang/LazyConstant.java line 46: > 44: * A lazy constant is created using the factory method > 45: * {@linkplain LazyConstant#of(Supplier) LazyConstant.of({@code })}. > 46: * When created, the contents (and hence the lazy constant itself) is not initialized. "When created, the lazy constant is not initialized, meaning it has no contents." E.g. it's the lazy constant that is initialized/not initialized. The content "just is". (or "is not", if not initialized). src/java.base/share/classes/java/lang/LazyConstant.java line 47: > 45: * {@linkplain LazyConstant#of(Supplier) LazyConstant.of({@code })}. > 46: * When created, the contents (and hence the lazy constant itself) is not initialized. > 47: * The contents (of type {@code T}) can then be initialized Again, "a lazy constant can be initialized, and its content retrieved, by calling get" src/java.base/share/classes/java/lang/LazyConstant.java line 50: > 48: * (and retrieved) by calling {@linkplain #get()}. The first time {@linkplain #get()} > 49: * is called, the underlying computing function (provided at construction) will > 50: * be invoked and the result will be used to initialize the contents. Once initialized, "and the result will be used to initialize the lazy constant. Once a lazy constant is initialized, its contents can never change..." ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2439058429 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2439060624 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2439064085 From mcimadamore at openjdk.org Fri Oct 17 09:56:18 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Fri, 17 Oct 2025 09:56:18 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v12] In-Reply-To: References: Message-ID: On Fri, 17 Oct 2025 09:25:01 GMT, Per Minborg wrote: >> Implement JEP 526: Lazy Constants (Second Preview) >> >> The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. >> >> The old benchmarks are not moved/renamed to allow comparison with previous releases. >> >> `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. > > Per Minborg has updated the pull request incrementally with one additional commit since the last revision: > > Update javadocs src/java.base/share/classes/java/lang/LazyConstant.java line 54: > 52: * again upon subsequent {@linkplain #get() get} invocations. > 53: *

> 54: * A lazy constant is shallowly immutable, meaning the reference to the contents This para here seems a bit redundant. In part it repeats something already said (when initialized, contents will never change). I'd drop this from here, and maybe push it down to an API note (e.g. note: the contents of a lazy constant can be mutable -- e.g. an ArrayList). src/java.base/share/classes/java/lang/LazyConstant.java line 60: > 58: *

> 59: * Consider the following example where a lazy constant field "{@code logger}" is a > 60: * shallowly immutable holder of an object of type {@code Logger}: "where the lazy constant field "logger" holds an object of type Logger" src/java.base/share/classes/java/lang/LazyConstant.java line 77: > 75: *} > 76: *

> 77: * Initially, the lazy constant (and its contents) is not initialized. Suggestion: * Initially, the lazy constant is not initialized. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2439072055 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2439073774 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2439075865 From mcimadamore at openjdk.org Fri Oct 17 10:08:22 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Fri, 17 Oct 2025 10:08:22 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v12] In-Reply-To: References: Message-ID: On Fri, 17 Oct 2025 09:25:01 GMT, Per Minborg wrote: >> Implement JEP 526: Lazy Constants (Second Preview) >> >> The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. >> >> The old benchmarks are not moved/renamed to allow comparison with previous releases. >> >> `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. > > Per Minborg has updated the pull request incrementally with one additional commit since the last revision: > > Update javadocs src/java.base/share/classes/java/lang/LazyConstant.java line 101: > 99: * {@linkplain Error}, that {@linkplain Throwable} is propagated to the caller, and the > 100: * lazy constant remains uninitialized. In other words, upon an unsuccessful invocation of > 101: * the computing function, neither a constant, the exception, nor the fact that "In other words" I don't think this sentence adds much. I think it's better to just drop it. The main thing to say is that if computing function is unsuccessful, the lazy constant stays uninitialized (which we already said). src/java.base/share/classes/java/lang/LazyConstant.java line 111: > 109: * which are held by lazy constants: > 110: * > 111: * {@snippet lang = java: If you wanted, you could reuse the `Component` class -- that one already has a lazy constant field, so if you put the component itself in another lazy constant field you have your composition example. src/java.base/share/classes/java/lang/LazyConstant.java line 144: > 142: * > 143: *

Thread Safety

> 144: * A lazy constant is guaranteed to be initialized atomically and at most once. If We already mention some of these above: "Furthermore, {@linkplain #get()} guarantees that, out of several threads trying to * invoke the computing function simultaneously, only one is ever selected for * computation" Maybe add a reference form that text to this section? src/java.base/share/classes/java/lang/LazyConstant.java line 152: > 150: *

> 151: * The invocation of the computing function and the resulting initialization of > 152: * the constant {@linkplain java.util.concurrent##MemoryVisibility happens-before} Do you mean constant or content? I think the latter? E.g. when you initialize a lazy constant, you safely publish its contents? (the lazy constant itself is already published) src/java.base/share/classes/java/lang/LazyConstant.java line 158: > 156: * Thread interruption does not cancel the initialization of a lazy constant. In other > 157: * words, if the computing thread is interrupted, {@code LazyConstant::get} doesn't clear > 158: * the interrupted thread?s status, nor does it throw an InterruptedException. Suggestion: * the interrupted thread?s status, nor does it throw an {@code InterruptedException}. src/java.base/share/classes/java/lang/LazyConstant.java line 164: > 162: * > 163: *

Performance

> 164: * A lazy constant can never change after it has been initialized. Therefore, The contents of a lazy constant can never change after the lazy constant has been initialized (again, spell out things clearly) src/java.base/share/classes/java/lang/LazyConstant.java line 166: > 164: * A lazy constant can never change after it has been initialized. Therefore, > 165: * a JVM implementation may, for an initialized lazy constant, elide all future reads > 166: * of that lazy constant and instead directly use any constant that it has previously "elide all future reads of that lazy constant's contents and instead use the contents that has been previously observed" ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2439091644 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2439096445 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2439102301 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2439110166 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2439114804 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2439119542 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2439124386 From mcimadamore at openjdk.org Fri Oct 17 10:20:09 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Fri, 17 Oct 2025 10:20:09 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v12] In-Reply-To: References: Message-ID: <2V6nUv7mUoPV7kx6uQXMTM9D4Xdm-1xEK7ErgbEAdds=.0bc05925-08b5-4799-903c-04b9bfa4760d@github.com> On Fri, 17 Oct 2025 09:25:01 GMT, Per Minborg wrote: >> Implement JEP 526: Lazy Constants (Second Preview) >> >> The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. >> >> The old benchmarks are not moved/renamed to allow comparison with previous releases. >> >> `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. > > Per Minborg has updated the pull request incrementally with one additional commit since the last revision: > > Update javadocs src/java.base/share/classes/java/lang/LazyConstant.java line 168: > 166: * of that lazy constant and instead directly use any constant that it has previously > 167: * observed. We call this optimization constant folding. This is only possible if > 168: * the reference to the lazy constant is a VM constant (e.g. in cases where Not sure talking about VM constant is good. We could alternatively say: "if the lazy constant is stored in a static final field, either directly, or indirectly, via one or more trusted fields (i.e. any combination...)" src/java.base/share/classes/java/lang/LazyConstant.java line 179: > 177: * must be non-null, or a {@link NullPointerException} will be thrown. > 178: * > 179: * @apiNote Once a lazy constant is initialized with an object, the object cannot ever be Once a lazy constant is initialized, its contents can never be removed... src/java.base/share/classes/java/lang/LazyConstant.java line 182: > 180: * removed. This can be a source of an unintended memory leak. More specifically, > 181: * a lazy constant {@linkplain java.lang.ref##reachability strongly references} > 182: * the object it was initialized with. Hence, a lazy constant will hold s/the object it was initialized with/its contents (here and below) src/java.base/share/classes/java/lang/LazyConstant.java line 186: > 184: * is collected (if ever). > 185: *

> 186: * A {@code LazyConstant} that has a type parameter {@code T} that is an "A lazy constant whose contents is an array will not optimize access to the the elements of such array. Instead, ..." src/java.base/share/classes/java/lang/LazyConstant.java line 191: > 189: * Instead, a {@linkplain List#ofLazy(int, IntFunction) lazy list} of > 190: * arbitrary depth can be used, which provides constant components. > 191: * More generally, a lazy constant can hold other lazy constants of More generally... you said that in the composition section? src/java.base/share/classes/java/lang/LazyConstant.java line 233: > 231: > 232: /** > 233: * {@return the initialized contents. If not initialized, first computes and "initialized contents" is not a term you have defined in this javadoc. `get` returns the contents of this lazy constant. If the lazy constant is not initialized... src/java.base/share/classes/java/lang/LazyConstant.java line 267: > 265: */ > 266: @Override > 267: String toString(); I think it might be worth also defining a javadoc for equals/hashCode, to say explicitly that they will also not trigger initialization src/java.base/share/classes/java/lang/LazyConstant.java line 284: > 282: * directly. > 283: * > 284: * @param computingFunction in the form of a Supplier to be used to compute Suggestion: * @param computingFunction a {@code Supplier} used to initialize ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2439138229 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2439141653 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2439144255 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2439156012 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2439150170 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2439161143 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2439169909 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2439174349 From mcimadamore at openjdk.org Fri Oct 17 10:25:47 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Fri, 17 Oct 2025 10:25:47 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v12] In-Reply-To: References: Message-ID: On Fri, 17 Oct 2025 09:25:01 GMT, Per Minborg wrote: >> Implement JEP 526: Lazy Constants (Second Preview) >> >> The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. >> >> The old benchmarks are not moved/renamed to allow comparison with previous releases. >> >> `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. > > Per Minborg has updated the pull request incrementally with one additional commit since the last revision: > > Update javadocs src/java.base/share/classes/java/util/List.java line 1231: > 1229: * will be thrown. > 1230: *

> 1231: * The returned lazy list strongly references its computing We should say that hashCode/equals trigger computation src/java.base/share/classes/java/util/Map.java line 1784: > 1782: * will be thrown. > 1783: *

> 1784: * The returned lazy map strongly references its underlying Again, we should say that equals/hashCode triggers computation ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2439200027 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2439207782 From pminborg at openjdk.org Fri Oct 17 11:43:47 2025 From: pminborg at openjdk.org (Per Minborg) Date: Fri, 17 Oct 2025 11:43:47 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v13] In-Reply-To: References: Message-ID: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. Per Minborg has updated the pull request incrementally with one additional commit since the last revision: Update wording on List/Map Object methods ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27605/files - new: https://git.openjdk.org/jdk/pull/27605/files/6a6e804e..8cde6974 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=12 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=11-12 Stats: 12 lines in 2 files changed: 12 ins; 0 del; 0 mod Patch: https://git.openjdk.org/jdk/pull/27605.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27605/head:pull/27605 PR: https://git.openjdk.org/jdk/pull/27605 From pminborg at openjdk.org Fri Oct 17 12:13:48 2025 From: pminborg at openjdk.org (Per Minborg) Date: Fri, 17 Oct 2025 12:13:48 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v14] In-Reply-To: References: Message-ID: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. Per Minborg has updated the pull request incrementally with one additional commit since the last revision: Improve equals/hashCode document ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27605/files - new: https://git.openjdk.org/jdk/pull/27605/files/8cde6974..77ae3fe1 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=13 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=12-13 Stats: 19 lines in 1 file changed: 16 ins; 0 del; 3 mod Patch: https://git.openjdk.org/jdk/pull/27605.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27605/head:pull/27605 PR: https://git.openjdk.org/jdk/pull/27605 From pminborg at openjdk.org Fri Oct 17 12:28:15 2025 From: pminborg at openjdk.org (Per Minborg) Date: Fri, 17 Oct 2025 12:28:15 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v15] In-Reply-To: References: Message-ID: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. Per Minborg has updated the pull request incrementally with one additional commit since the last revision: Improve method docs ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27605/files - new: https://git.openjdk.org/jdk/pull/27605/files/77ae3fe1..e2c24f5c Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=14 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=13-14 Stats: 10 lines in 1 file changed: 1 ins; 0 del; 9 mod Patch: https://git.openjdk.org/jdk/pull/27605.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27605/head:pull/27605 PR: https://git.openjdk.org/jdk/pull/27605 From pminborg at openjdk.org Fri Oct 17 13:13:45 2025 From: pminborg at openjdk.org (Per Minborg) Date: Fri, 17 Oct 2025 13:13:45 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v16] In-Reply-To: References: Message-ID: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. Per Minborg has updated the pull request incrementally with one additional commit since the last revision: Update docs after comments ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27605/files - new: https://git.openjdk.org/jdk/pull/27605/files/e2c24f5c..d961426d Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=15 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=14-15 Stats: 58 lines in 1 file changed: 3 ins; 16 del; 39 mod Patch: https://git.openjdk.org/jdk/pull/27605.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27605/head:pull/27605 PR: https://git.openjdk.org/jdk/pull/27605 From pminborg at openjdk.org Fri Oct 17 14:06:44 2025 From: pminborg at openjdk.org (Per Minborg) Date: Fri, 17 Oct 2025 14:06:44 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v17] In-Reply-To: References: Message-ID: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. Per Minborg has updated the pull request incrementally with one additional commit since the last revision: Revert the AbstractMap.keySet @Stable annotation ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27605/files - new: https://git.openjdk.org/jdk/pull/27605/files/d961426d..698b4125 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=16 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=15-16 Stats: 5 lines in 2 files changed: 4 ins; 1 del; 0 mod Patch: https://git.openjdk.org/jdk/pull/27605.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27605/head:pull/27605 PR: https://git.openjdk.org/jdk/pull/27605 From pminborg at openjdk.org Fri Oct 17 14:10:39 2025 From: pminborg at openjdk.org (Per Minborg) Date: Fri, 17 Oct 2025 14:10:39 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v2] In-Reply-To: References: <90jKH5-Bb3vf27uhLPOUtgmYmZRFdH1voVYr8kIR__I=.2aff8cb2-38be-4dd3-a1df-e3f8a7a90542@github.com> Message-ID: On Thu, 16 Oct 2025 12:10:51 GMT, Per Minborg wrote: >> src/java.base/share/classes/java/util/AbstractMap.java line 335: >> >>> 333: */ >>> 334: @Stable >>> 335: transient Set keySet; >> >> Are?all?uses of?this?field in?`java.util` able?to?handle the?`@Stable`ness of?this?field correctly? > > That is a good question. The potentially different keySet values should be freely substitutable or else there seams to be something wrong. If they are FS, then the VM should be able to pick any. But it is a big assumption to say that *all* maps that extend AM behave in such a way. We could go back to the previous version and shadow the field. That seems safest. > > Note: there is work in progress to remove these fields. I've reverted the @Stable annotation on AM.keySet. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2440164233 From mcimadamore at openjdk.org Fri Oct 17 14:17:54 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Fri, 17 Oct 2025 14:17:54 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v16] In-Reply-To: References: Message-ID: <_kXdqyWalfyZNF_Bhnuw9NQh-9x3cutCQEB-r72fLR4=.aaadf47e-46d7-43d2-99dc-c6e0da1f8ad6@github.com> On Fri, 17 Oct 2025 13:13:45 GMT, Per Minborg wrote: >> Implement JEP 526: Lazy Constants (Second Preview) >> >> The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. >> >> The old benchmarks are not moved/renamed to allow comparison with previous releases. >> >> `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. > > Per Minborg has updated the pull request incrementally with one additional commit since the last revision: > > Update docs after comments src/java.base/share/classes/java/lang/LazyConstant.java line 154: > 152: * > 153: *

Performance

> 154: * The contents of lazy constant can never change after it has been initialized. Therefore, Suggestion: * The contents of a lazy constant can never change after it has been initialized. Therefore, ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2440185045 From mcimadamore at openjdk.org Fri Oct 17 14:30:06 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Fri, 17 Oct 2025 14:30:06 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v16] In-Reply-To: References: Message-ID: On Fri, 17 Oct 2025 14:23:28 GMT, Maurizio Cimadamore wrote: >> Per Minborg has updated the pull request incrementally with one additional commit since the last revision: >> >> Update docs after comments > > src/java.base/share/classes/java/util/List.java line 1235: > >> 1233: * or more lazy elements. The returned list's {@linkplain Object#toString() toString()} >> 1234: * method never triggers initialization of elements. Instead, an >> 1235: * implementation-dependant string is returned for uninitialized elements. > > Suggestion: > > * implementation-dependent string is returned for uninitialized elements. Design comment: I note some internal discomfort at the fact that equals/hashCode trigger initialization, but toString does not... effectively this would make replacing a regular immutable list with a lazy list not possible in all cases. Not saying we should do anything now -- but something to monitor ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2440214527 From mcimadamore at openjdk.org Fri Oct 17 14:30:05 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Fri, 17 Oct 2025 14:30:05 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v16] In-Reply-To: References: Message-ID: On Fri, 17 Oct 2025 13:13:45 GMT, Per Minborg wrote: >> Implement JEP 526: Lazy Constants (Second Preview) >> >> The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. >> >> The old benchmarks are not moved/renamed to allow comparison with previous releases. >> >> `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. > > Per Minborg has updated the pull request incrementally with one additional commit since the last revision: > > Update docs after comments src/java.base/share/classes/java/lang/LazyConstant.java line 157: > 155: * a JVM implementation may, for an initialized lazy constant, elide all future reads of > 156: * that lazy constant's contents and instead use the contents that has been previously > 157: * observed. We call this optimization constant folding. This is only possible This is still not ok. First, there seems to be some typo ("if the reference to the lazy constant in a static final field or..."). Secondly, trusted chain _to_ such field. I think it's the other way around, the trusted chain starts at a static final field, and then eventually gets to the lazy constant, possibly traversing one or more trusted fields. src/java.base/share/classes/java/lang/LazyConstant.java line 174: > 172: * the lazy constant itself is collected (if ever). > 173: *

> 174: * A lazy constant whose contents is an array will not optimize access to "While it's possible to store an array inside a lazy constant, doing so will not result in improved access to the array elements. Instead ..." src/java.base/share/classes/java/lang/LazyConstant.java line 289: > 287: * > 288: * @param computingFunction in the form of a {@linkplain Supplier} to be used > 289: * to compute the constant s/compute/initialize (e.g. the term "compute the constant" is not defined anywhere) src/java.base/share/classes/java/util/List.java line 1235: > 1233: * or more lazy elements. The returned list's {@linkplain Object#toString() toString()} > 1234: * method never triggers initialization of elements. Instead, an > 1235: * implementation-dependant string is returned for uninitialized elements. Suggestion: * implementation-dependent string is returned for uninitialized elements. src/java.base/share/classes/java/util/Map.java line 1788: > 1786: * or more lazy values. The returned maps's {@linkplain Object#toString() toString()} > 1787: * method never triggers initialization of values. Instead, an > 1788: * implementation-dependant string is returned for uninitialized values. Suggestion: * implementation-dependent string is returned for uninitialized values. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2440193622 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2440203445 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2440207743 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2440209019 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2440216157 From pminborg at openjdk.org Fri Oct 17 14:29:55 2025 From: pminborg at openjdk.org (Per Minborg) Date: Fri, 17 Oct 2025 14:29:55 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v18] In-Reply-To: References: Message-ID: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. Per Minborg 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 104 additional commits since the last revision: - Merge branch 'master' into lazy-constants - Revert the AbstractMap.keySet @Stable annotation - Update docs after comments - Improve method docs - Improve equals/hashCode document - Update wording on List/Map Object methods - Update javadocs - Fix test descriptions - Update first javadoc sentence - Rephrase docs on interrupt - ... and 94 more: https://git.openjdk.org/jdk/compare/e2f6db0f...fc064e47 ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27605/files - new: https://git.openjdk.org/jdk/pull/27605/files/698b4125..fc064e47 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=17 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=16-17 Stats: 8176 lines in 211 files changed: 4888 ins; 2457 del; 831 mod Patch: https://git.openjdk.org/jdk/pull/27605.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27605/head:pull/27605 PR: https://git.openjdk.org/jdk/pull/27605 From pminborg at openjdk.org Fri Oct 17 14:58:44 2025 From: pminborg at openjdk.org (Per Minborg) Date: Fri, 17 Oct 2025 14:58:44 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v19] In-Reply-To: References: Message-ID: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. Per Minborg has updated the pull request incrementally with one additional commit since the last revision: Update after doc comments ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27605/files - new: https://git.openjdk.org/jdk/pull/27605/files/fc064e47..6721ca4a Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=18 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=17-18 Stats: 14 lines in 3 files changed: 1 ins; 0 del; 13 mod Patch: https://git.openjdk.org/jdk/pull/27605.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27605/head:pull/27605 PR: https://git.openjdk.org/jdk/pull/27605 From jlu at openjdk.org Fri Oct 17 16:22:20 2025 From: jlu at openjdk.org (Justin Lu) Date: Fri, 17 Oct 2025 16:22:20 GMT Subject: Integrated: 8369590: LocaleEnhanceTest has incorrectly passing test case In-Reply-To: References: Message-ID: On Mon, 13 Oct 2025 20:55:45 GMT, Justin Lu wrote: > This PR corrects _test/jdk/java/util/Locale/LocaleEnhanceTest.java_, which has two test cases under `testBuilderSetLanguageTag()` which accidentally pass. One checks that Locale.setLanguageTag(String) throws ILE for duplicate extensions and the other for duplicate U-extension keys. The test cases are updated to actually test the provided code. When the test cases are fixed, they now fail. They should instead be updated to check that the duplicates are ignored. This pull request has now been integrated. Changeset: 1e5e17a1 Author: Justin Lu URL: https://git.openjdk.org/jdk/commit/1e5e17a10a001c189f6ab19f61efca2d08cb0301 Stats: 654 lines in 1 file changed: 56 ins; 169 del; 429 mod 8369590: LocaleEnhanceTest has incorrectly passing test case Reviewed-by: naoto ------------- PR: https://git.openjdk.org/jdk/pull/27775 From mcimadamore at openjdk.org Fri Oct 17 19:58:08 2025 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Fri, 17 Oct 2025 19:58:08 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v19] In-Reply-To: References: Message-ID: <2Ow8e38mfpHtFTbD5kUe4BKOaWACguUWAfKwerScgMg=.228371ce-d23d-4dc2-816c-ce80c7da7771@github.com> On Fri, 17 Oct 2025 14:58:44 GMT, Per Minborg wrote: >> Implement JEP 526: Lazy Constants (Second Preview) >> >> The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. >> >> The old benchmarks are not moved/renamed to allow comparison with previous releases. >> >> `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. > > Per Minborg has updated the pull request incrementally with one additional commit since the last revision: > > Update after doc comments src/java.base/share/classes/java/lang/LazyConstant.java line 161: > 159: * to a lazy constant or if there is a chain from a {@code static final} field -- via one > 160: * or more trusted fields (i.e., {@code static final} fields, > 161: * {@linkplain Record record} fields, lazy constants, lazy lists, lazy maps, lazy constants and lazy lists/maps are not themselves "trusted final fields" (at least not yet), so not sure they belong here? ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2441086058 From duke at openjdk.org Sat Oct 18 00:17:12 2025 From: duke at openjdk.org (duke) Date: Sat, 18 Oct 2025 00:17:12 GMT Subject: Withdrawn: 8355522: Remove the `java.locale.useOldISOCodes` system property In-Reply-To: <6Ca8zNdgZWlcivQkpZjjp3rBFWIdyYzQEyKLeXDloVc=.4a5f20b8-49cf-4cea-962f-5b8e99f7b0af@github.com> References: <6Ca8zNdgZWlcivQkpZjjp3rBFWIdyYzQEyKLeXDloVc=.4a5f20b8-49cf-4cea-962f-5b8e99f7b0af@github.com> Message-ID: On Mon, 21 Jul 2025 22:56:50 GMT, Naoto Sato wrote: > This PR removes the system property deprecated in JDK 25. If the property is specified at runtime, a warning will be emitted at startup to inform the user that the value is ignored. A corresponding CSR has been drafted as well This pull request has been closed without being integrated. ------------- PR: https://git.openjdk.org/jdk/pull/26419 From duke at openjdk.org Sat Oct 18 01:07:11 2025 From: duke at openjdk.org (ExE Boss) Date: Sat, 18 Oct 2025 01:07:11 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v19] In-Reply-To: <2Ow8e38mfpHtFTbD5kUe4BKOaWACguUWAfKwerScgMg=.228371ce-d23d-4dc2-816c-ce80c7da7771@github.com> References: <2Ow8e38mfpHtFTbD5kUe4BKOaWACguUWAfKwerScgMg=.228371ce-d23d-4dc2-816c-ce80c7da7771@github.com> Message-ID: <7R8km2ZfztfyDcrUvjd_5P85J7pBMsxAIY-tP76jnTc=.d4311603-0098-4f89-84b3-f073bec00a4d@github.com> On Fri, 17 Oct 2025 19:55:42 GMT, Maurizio Cimadamore wrote: >> Per Minborg has updated the pull request incrementally with one additional commit since the last revision: >> >> Update after doc comments > > src/java.base/share/classes/java/lang/LazyConstant.java line 161: > >> 159: * to a lazy constant or if there is a chain from a {@code static final} field -- via one >> 160: * or more trusted fields (i.e., {@code static final} fields, >> 161: * {@linkplain Record record} fields, lazy constants, lazy lists, lazy maps, > > lazy constants and lazy lists/maps are not themselves "trusted final fields" (at least not yet), so not sure they belong here? The?`@Stable`?annotation makes?fields with?non?`null`?values into?trusted?fields when?the?class is?loaded by?a?platform class?loader. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2441495949 From sherman at openjdk.org Sat Oct 18 08:44:57 2025 From: sherman at openjdk.org (Xueming Shen) Date: Sat, 18 Oct 2025 08:44:57 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v3] In-Reply-To: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> Message-ID: > ### Summary > > Case folding is a key operation for case-insensitive matching (e.g., string equality, regex matching), where the goal is to eliminate case distinctions without applying locale or language specific conversions. > > Currently, the JDK does not expose a direct API for Unicode-compliant case folding. Developers now rely on methods such as: > > **String.equalsIgnoreCase(String)** > > - Unicode-aware, locale-independent. > - Implementation uses Character.toLowerCase(Character.toUpperCase(int)) per code point. > - Limited: does not support 1:M mapping defined in Unicode case folding. > > **Character.toLowerCase(int) / Character.toUpperCase(int)** > > - Locale-independent, single code point only. > - No support for 1:M mappings. > > **String.toLowerCase(Locale.ROOT) / String.toUpperCase(Locale.ROOT)** > > - Based on Unicode SpecialCasing.txt, supports 1:M mappings. > - Intended primarily for presentation/display, not structural case-insensitive matching. > - Requires full string conversion before comparison, which is less efficient and not intended for structural matching. > > **1:M mapping example, U+00DF (?)** > > - String.toUpperCase(Locale.ROOT, "?") ? "SS" > - Case folding produces "ss", matching Unicode caseless comparison rules. > > > jshell> "\u00df".equalsIgnoreCase("ss") > $22 ==> false > > jshell> "\u00df".toUpperCase(Locale.ROOT).toLowerCase(Locale.ROOT).equals("ss") > $24 ==> true > > > ### Motivation & Direction > > Add Unicode standard-compliant case-less comparison methods to the String class, enabling & improving reliable and efficient Unicode-aware/compliant case-insensitive matching. > > - Unicode-compliant **full** case folding. > - Simpler, stable and more efficient case-less matching without workarounds. > - Brings Java's string comparison handling in line with other programming languages/libraries. > > This PR proposes to introduce the following comparison methods in `String` class > > - boolean equalsFoldCase(String anotherString) > - int compareToFoldCase(String anotherString) > - Comparator UNICODE_CASEFOLD_ORDER > > These methods are intended to be the preferred choice when Unicode-compliant case-less matching is required. > > *Note: An early draft also proposed a String.toCaseFold() method returning a new case-folded string. > However, during review this was considered error-prone, as the resulting string could easily be mistaken for a general transformation like toLowerCase() and then passed into APIs where case-folding semantics are not appropriate. > > ### The New API > > See CSR https://bugs.openjd... Xueming Shen has updated the pull request incrementally with one additional commit since the last revision: performance update ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27628/files - new: https://git.openjdk.org/jdk/pull/27628/files/9d9997dc..59b7a4fb Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27628&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27628&range=01-02 Stats: 601 lines in 7 files changed: 285 ins; 242 del; 74 mod Patch: https://git.openjdk.org/jdk/pull/27628.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27628/head:pull/27628 PR: https://git.openjdk.org/jdk/pull/27628 From sherman at openjdk.org Sat Oct 18 08:44:59 2025 From: sherman at openjdk.org (Xueming Shen) Date: Sat, 18 Oct 2025 08:44:59 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v2] In-Reply-To: References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> Message-ID: On Fri, 10 Oct 2025 19:49:19 GMT, Jean-No?l Rouvignac wrote: >> Xueming Shen has updated the pull request incrementally with one additional commit since the last revision: >> >> minor api doc updates > > test/micro/org/openjdk/bench/java/lang/StringCompareToIgnoreCase.java line 89: > >> 87: >> 88: @Benchmark >> 89: public int lowerrCF() { > > Suggestion: > > public int lowerCF() { fixed in the new test source code ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2441835525 From sherman at openjdk.org Sat Oct 18 08:54:01 2025 From: sherman at openjdk.org (Xueming Shen) Date: Sat, 18 Oct 2025 08:54:01 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v3] In-Reply-To: References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> Message-ID: On Tue, 7 Oct 2025 22:10:50 GMT, Roger Riggs wrote: >> Xueming Shen has updated the pull request incrementally with one additional commit since the last revision: >> >> performance update > > src/java.base/share/classes/java/lang/StringLatin1.java line 194: > >> 192: char[] folded2 = null; >> 193: int k1 = 0, k2 = 0, fk1 = 0, fk2 = 0; >> 194: while ((k1 < len1 || folded1 != null && fk1 < folded1.length) && > > Many suggestions come to mind here on the algorithm, to optimize performance. > For example, many strings will have identical prefixes. Using Arrays.mismatch could quickly skip over the identical prefix. > Consider using code points (or a long, packing 4 chars) for the folded replacements, to avoid having to step through chars in char arrays. CaseFolding.foldIfDefined could return the full expansion as a long. > It may be profitable to use Arrays.mismatch again after expanded characters are determined to be equal. > > Take another look at the data structure storing and doing the lookup of foldIfDefined both to increase the lookup performance. With the following changes - Use int[] / code point storage instead of char[] / char for folding data. - Add a fast path for Latin-1 vs. Latin-1 comparisons. - Speed up the UTF-16 path as well. The only remaining ?slow? path is Latin-1 vs. UTF-16 for now. Would appreciate some eagle eyes on the new fast-path implementation. The tests suggest it?s working as expected :-) **StringCompareToFoldCase.latin1UTF16 avgt 15 23.959 ? 2.357 ns/op StringCompareToFoldCase.latin1UTF16EQ avgt 15 22.455 ? 0.104 ns/op StringCompareToFoldCase.latin1UTF16EQFC avgt 15 32.782 ? 0.962 ns/op StringCompareToFoldCase.latin1UTF16FC avgt 15 32.581 ? 0.725 ns/op** Benchmark Mode Cnt Score Error Units StringCompareToFoldCase.asciiLower avgt 15 17.983 ? 0.208 ns/op StringCompareToFoldCase.asciiLowerEQ avgt 15 9.986 ? 0.254 ns/op StringCompareToFoldCase.asciiLowerEQFC avgt 15 10.781 ? 0.161 ns/op StringCompareToFoldCase.asciiLowerFC avgt 15 10.274 ? 0.136 ns/op StringCompareToFoldCase.asciiUpperLower avgt 15 12.465 ? 0.409 ns/op StringCompareToFoldCase.asciiUpperLowerEQ avgt 15 10.961 ? 0.407 ns/op StringCompareToFoldCase.asciiUpperLowerEQFC avgt 15 9.157 ? 0.166 ns/op StringCompareToFoldCase.asciiUpperLowerFC avgt 15 9.228 ? 0.254 ns/op StringCompareToFoldCase.asciiWithDFFC avgt 15 57.603 ? 1.540 ns/op StringCompareToFoldCase.greekLower avgt 15 39.593 ? 0.128 ns/op StringCompareToFoldCase.greekLowerEQ avgt 15 39.249 ? 0.032 ns/op StringCompareToFoldCase.greekLowerEQFC avgt 15 13.993 ? 0.346 ns/op StringCompareToFoldCase.greekLowerFC avgt 15 14.030 ? 0.454 ns/op StringCompareToFoldCase.greekUpperLower avgt 15 7.137 ? 0.130 ns/op StringCompareToFoldCase.greekUpperLowerEQ avgt 15 7.496 ? 0.104 ns/op StringCompareToFoldCase.greekUpperLowerEQFC avgt 15 6.203 ? 0.316 ns/op StringCompareToFoldCase.greekUpperLowerFC avgt 15 6.235 ? 0.256 ns/op StringCompareToFoldCase.latin1UTF16 avgt 15 23.959 ? 2.357 ns/op StringCompareToFoldCase.latin1UTF16EQ avgt 15 22.455 ? 0.104 ns/op StringCompareToFoldCase.latin1UTF16EQFC avgt 15 32.782 ? 0.962 ns/op StringCompareToFoldCase.latin1UTF16FC avgt 15 32.581 ? 0.725 ns/op StringCompareToFoldCase.supLower avgt 15 54.918 ? 0.809 ns/op StringCompareToFoldCase.supLowerEQ avgt 15 55.080 ? 0.511 ns/op StringCompareToFoldCase.supLowerEQFC avgt 15 14.085 ? 0.996 ns/op StringCompareToFoldCase.supLowerFC avgt 15 13.907 ? 0.612 ns/op StringCompareToFoldCase.supUpperLower avgt 15 14.479 ? 0.175 ns/op StringCompareToFoldCase.supUpperLowerEQ avgt 15 14.645 ? 0.059 ns/op StringCompareToFoldCase.supUpperLowerEQFC avgt 15 9.200 ? 0.310 ns/op StringCompareToFoldCase.supUpperLowerFC avgt 15 9.041 ? 0.248 ns/op ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2441849469 From sherman at openjdk.org Sun Oct 19 09:12:42 2025 From: sherman at openjdk.org (Xueming Shen) Date: Sun, 19 Oct 2025 09:12:42 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v4] In-Reply-To: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> Message-ID: > ### Summary > > Case folding is a key operation for case-insensitive matching (e.g., string equality, regex matching), where the goal is to eliminate case distinctions without applying locale or language specific conversions. > > Currently, the JDK does not expose a direct API for Unicode-compliant case folding. Developers now rely on methods such as: > > **String.equalsIgnoreCase(String)** > > - Unicode-aware, locale-independent. > - Implementation uses Character.toLowerCase(Character.toUpperCase(int)) per code point. > - Limited: does not support 1:M mapping defined in Unicode case folding. > > **Character.toLowerCase(int) / Character.toUpperCase(int)** > > - Locale-independent, single code point only. > - No support for 1:M mappings. > > **String.toLowerCase(Locale.ROOT) / String.toUpperCase(Locale.ROOT)** > > - Based on Unicode SpecialCasing.txt, supports 1:M mappings. > - Intended primarily for presentation/display, not structural case-insensitive matching. > - Requires full string conversion before comparison, which is less efficient and not intended for structural matching. > > **1:M mapping example, U+00DF (?)** > > - String.toUpperCase(Locale.ROOT, "?") ? "SS" > - Case folding produces "ss", matching Unicode caseless comparison rules. > > > jshell> "\u00df".equalsIgnoreCase("ss") > $22 ==> false > > jshell> "\u00df".toUpperCase(Locale.ROOT).toLowerCase(Locale.ROOT).equals("ss") > $24 ==> true > > > ### Motivation & Direction > > Add Unicode standard-compliant case-less comparison methods to the String class, enabling & improving reliable and efficient Unicode-aware/compliant case-insensitive matching. > > - Unicode-compliant **full** case folding. > - Simpler, stable and more efficient case-less matching without workarounds. > - Brings Java's string comparison handling in line with other programming languages/libraries. > > This PR proposes to introduce the following comparison methods in `String` class > > - boolean equalsFoldCase(String anotherString) > - int compareToFoldCase(String anotherString) > - Comparator UNICODE_CASEFOLD_ORDER > > These methods are intended to be the preferred choice when Unicode-compliant case-less matching is required. > > *Note: An early draft also proposed a String.toCaseFold() method returning a new case-folded string. > However, during review this was considered error-prone, as the resulting string could easily be mistaken for a general transformation like toLowerCase() and then passed into APIs where case-folding semantics are not appropriate. > > ### The New API > > See CSR https://bugs.openjd... Xueming Shen has updated the pull request incrementally with one additional commit since the last revision: test case update ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27628/files - new: https://git.openjdk.org/jdk/pull/27628/files/59b7a4fb..27626771 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27628&range=03 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27628&range=02-03 Stats: 2 lines in 2 files changed: 0 ins; 0 del; 2 mod Patch: https://git.openjdk.org/jdk/pull/27628.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27628/head:pull/27628 PR: https://git.openjdk.org/jdk/pull/27628 From naoto at openjdk.org Mon Oct 20 15:11:24 2025 From: naoto at openjdk.org (Naoto Sato) Date: Mon, 20 Oct 2025 15:11:24 GMT Subject: RFR: 8355522: Remove the `java.locale.useOldISOCodes` system property [v4] In-Reply-To: References: <6Ca8zNdgZWlcivQkpZjjp3rBFWIdyYzQEyKLeXDloVc=.4a5f20b8-49cf-4cea-962f-5b8e99f7b0af@github.com> Message-ID: <5YU_f7Ye9xv88NU12Seznjf9LztmyXfNURttSKEc4bw=.8b982455-99e0-43f1-b720-e66a35a40bc7@github.com> On Wed, 23 Jul 2025 17:39:12 GMT, Naoto Sato wrote: >> This PR removes the system property deprecated in JDK 25. If the property is specified at runtime, a warning will be emitted at startup to inform the user that the value is ignored. A corresponding CSR has been drafted as well > > Naoto Sato has updated the pull request incrementally with one additional commit since the last revision: > > Further wording refinement This PR is intended for JDK27. Will reopen it when the time comes ------------- PR Comment: https://git.openjdk.org/jdk/pull/26419#issuecomment-3422493428 From jlu at openjdk.org Mon Oct 20 22:58:12 2025 From: jlu at openjdk.org (Justin Lu) Date: Mon, 20 Oct 2025 22:58:12 GMT Subject: RFR: 8370250: Locale should mention the behavior for duplicate subtags Message-ID: Please review this PR which is a first stab at clarifying the behavior of duplicate variants, extension singletons, and U extension keys and attributes for BCP47 subtags in the Locale specification. This is a follow up to https://bugs.openjdk.org/browse/JDK-8369739. Changes are made under the BCP47 and U extension sections that define "well-formed" in the class description. Additionally, changes are made under the relevant Locale and Locale.Builder methods themselves. Will update the CSR accordingly when the proposed wording changes are finalized. ------------- Commit messages: - init Changes: https://git.openjdk.org/jdk/pull/27909/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=27909&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8370250 Stats: 31 lines in 1 file changed: 19 ins; 0 del; 12 mod Patch: https://git.openjdk.org/jdk/pull/27909.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27909/head:pull/27909 PR: https://git.openjdk.org/jdk/pull/27909 From naoto at openjdk.org Mon Oct 20 23:39:03 2025 From: naoto at openjdk.org (Naoto Sato) Date: Mon, 20 Oct 2025 23:39:03 GMT Subject: RFR: 8370250: Locale should mention the behavior for duplicate subtags In-Reply-To: References: Message-ID: On Mon, 20 Oct 2025 22:52:19 GMT, Justin Lu wrote: > Please review this PR which is a first stab at clarifying the behavior of duplicate variants, extension singletons, and U extension keys and attributes for BCP47 subtags in the Locale specification. This is a follow up to https://bugs.openjdk.org/browse/JDK-8369739. > > Changes are made under the BCP47 and U extension sections that define "well-formed" in the class description. > Additionally, changes are made under the relevant Locale and Locale.Builder methods themselves. > > Will update the CSR accordingly when the proposed wording changes are finalized. Looks good. Left a couple of comments. Also we might want to add RFC 6067 for reference. src/java.base/share/classes/java/util/Locale.java line 253: > 251: * {@code [0-9a-zA-Z]{3,8}} (it is a single subtag with the same > 252: * form as a locale type subtag). {@code Locale} does not enforce uniqueness of > 253: * locale keys nor attributes. For methods in {@code Locale} and {@code Locale.Builder} This could be misleading as we are enforcing uniqueness, by ignoring the duplicates. The validity is what is not enforced here. src/java.base/share/classes/java/util/Locale.java line 2736: > 2734: * are accepted but ignored. The same behavior applies to duplicate locale > 2735: * keys and attributes within a U extension. > 2736: * "Note that..." in the prior occurence of this wording might apply here for consistency. ------------- PR Review: https://git.openjdk.org/jdk/pull/27909#pullrequestreview-3358253558 PR Review Comment: https://git.openjdk.org/jdk/pull/27909#discussion_r2446360376 PR Review Comment: https://git.openjdk.org/jdk/pull/27909#discussion_r2446369473 From prappo at openjdk.org Tue Oct 21 06:08:51 2025 From: prappo at openjdk.org (Pavel Rappo) Date: Tue, 21 Oct 2025 06:08:51 GMT Subject: RFR: 8366829: Add java.time.Duration constants MIN and MAX [v4] In-Reply-To: References: Message-ID: > We have [recently discussed][] a possibility of adding the `Duration.MIN` and `Duration.MAX` constants. Can we now start implementation? If and when we are in agreement on this PR, I will file a CSR. > > I drafted a minimal specification and added some tests. I tried to phrase the spec for `Duration.MIN` in a way that makes it clear that `Duration.MIN` is the most negative value and not the least positive. > > [recently discussed]: https://mail.openjdk.org/pipermail/core-libs-dev/2025-September/151098.html Pavel Rappo 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 five additional commits since the last revision: - Merge remote-tracking branch 'jdk/master' into 8366829 - Respond to feedback Apply Stephen's suggestion on wording, although modified. - Update copyright years Note: any commit hashes below might be outdated due to subsequent history rewriting (e.g. git rebase). + update src/java.base/share/classes/java/time/temporal/ChronoUnit.java due to 9a54ba1d353 + update test/jdk/java/time/tck/java/time/TCKDuration.java due to 9a54ba1d353 - Provide @apiNote as suggested - Initial commit ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27534/files - new: https://git.openjdk.org/jdk/pull/27534/files/abe01ff5..9472772a Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27534&range=03 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27534&range=02-03 Stats: 44025 lines in 1299 files changed: 26033 ins; 11350 del; 6642 mod Patch: https://git.openjdk.org/jdk/pull/27534.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27534/head:pull/27534 PR: https://git.openjdk.org/jdk/pull/27534 From prappo at openjdk.org Tue Oct 21 07:51:16 2025 From: prappo at openjdk.org (Pavel Rappo) Date: Tue, 21 Oct 2025 07:51:16 GMT Subject: Integrated: 8366829: Add java.time.Duration constants MIN and MAX In-Reply-To: References: Message-ID: On Fri, 26 Sep 2025 23:06:36 GMT, Pavel Rappo wrote: > We have [recently discussed][] a possibility of adding the `Duration.MIN` and `Duration.MAX` constants. Can we now start implementation? If and when we are in agreement on this PR, I will file a CSR. > > I drafted a minimal specification and added some tests. I tried to phrase the spec for `Duration.MIN` in a way that makes it clear that `Duration.MIN` is the most negative value and not the least positive. > > [recently discussed]: https://mail.openjdk.org/pipermail/core-libs-dev/2025-September/151098.html This pull request has now been integrated. Changeset: ec13c283 Author: Pavel Rappo URL: https://git.openjdk.org/jdk/commit/ec13c283c48c37e80d6c9c2753b09b31f4d14734 Stats: 76 lines in 3 files changed: 71 ins; 1 del; 4 mod 8366829: Add java.time.Duration constants MIN and MAX Reviewed-by: rriggs, naoto, scolebourne ------------- PR: https://git.openjdk.org/jdk/pull/27534 From jlu at openjdk.org Tue Oct 21 16:34:24 2025 From: jlu at openjdk.org (Justin Lu) Date: Tue, 21 Oct 2025 16:34:24 GMT Subject: RFR: 8370250: Locale should mention the behavior for duplicate subtags [v2] In-Reply-To: References: Message-ID: > Please review this PR which is a first stab at clarifying the behavior of duplicate variants, extension singletons, and U extension keys and attributes for BCP47 subtags in the Locale specification. This is a follow up to https://bugs.openjdk.org/browse/JDK-8369739. > > Changes are made under the BCP47 and U extension sections that define "well-formed" in the class description. > Additionally, changes are made under the relevant Locale and Locale.Builder methods themselves. > > Will update the CSR accordingly when the proposed wording changes are finalized. Justin Lu has updated the pull request incrementally with one additional commit since the last revision: Reflect Naoto's review ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27909/files - new: https://git.openjdk.org/jdk/pull/27909/files/5c3fafd3..59f52b32 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27909&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27909&range=00-01 Stats: 7 lines in 1 file changed: 3 ins; 0 del; 4 mod Patch: https://git.openjdk.org/jdk/pull/27909.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27909/head:pull/27909 PR: https://git.openjdk.org/jdk/pull/27909 From jlu at openjdk.org Tue Oct 21 16:34:26 2025 From: jlu at openjdk.org (Justin Lu) Date: Tue, 21 Oct 2025 16:34:26 GMT Subject: RFR: 8370250: Locale should mention the behavior for duplicate subtags [v2] In-Reply-To: References: Message-ID: On Mon, 20 Oct 2025 23:28:29 GMT, Naoto Sato wrote: >> Justin Lu has updated the pull request incrementally with one additional commit since the last revision: >> >> Reflect Naoto's review > > src/java.base/share/classes/java/util/Locale.java line 253: > >> 251: * {@code [0-9a-zA-Z]{3,8}} (it is a single subtag with the same >> 252: * form as a locale type subtag). {@code Locale} does not enforce uniqueness of >> 253: * locale keys nor attributes. For methods in {@code Locale} and {@code Locale.Builder} > > This could be misleading as we are enforcing uniqueness, by ignoring the duplicates. The validity is what is not enforced here. Good point. I updated that sentence. I held off on using "valid" because while rfc5646 mentions duplicates being "invalid", rfc6067 simply mentions that duplicates have no meaning. > src/java.base/share/classes/java/util/Locale.java line 2736: > >> 2734: * are accepted but ignored. The same behavior applies to duplicate locale >> 2735: * keys and attributes within a U extension. >> 2736: * > > "Note that..." in the prior occurence of this wording might apply here for consistency. `Locale.forLanguageTag` is specified to _ignore subsequent subtags on ill-formed input_, so a heads up is warranted. Since `Lcoale.Builder.setLanguageTag` either throws or does not (and duplicate tags do not throw), I think it is implied subsequent subtags are processed. However, that's just my opinion, if you think it is not obvious, I will add it in. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27909#discussion_r2448963024 PR Review Comment: https://git.openjdk.org/jdk/pull/27909#discussion_r2448963157 From naoto at openjdk.org Tue Oct 21 17:36:31 2025 From: naoto at openjdk.org (Naoto Sato) Date: Tue, 21 Oct 2025 17:36:31 GMT Subject: RFR: 8370250: Locale should mention the behavior for duplicate subtags [v2] In-Reply-To: References: Message-ID: On Tue, 21 Oct 2025 16:28:58 GMT, Justin Lu wrote: >> src/java.base/share/classes/java/util/Locale.java line 2736: >> >>> 2734: * are accepted but ignored. The same behavior applies to duplicate locale >>> 2735: * keys and attributes within a U extension. >>> 2736: * >> >> "Note that..." in the prior occurence of this wording might apply here for consistency. > > `Locale.forLanguageTag` is specified to _ignore subsequent subtags on ill-formed input_, so a heads up is warranted. Since `Lcoale.Builder.setLanguageTag` either throws or does not (and duplicate tags do not throw), I think it is implied subsequent subtags are processed. However, that's just my opinion, if you think it is not obvious, I will add it in. I think explicity specifying the note would not hurt here, otherwise missing "note" might unnecessarilly make readers wonder why ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27909#discussion_r2449159863 From jlu at openjdk.org Tue Oct 21 17:45:26 2025 From: jlu at openjdk.org (Justin Lu) Date: Tue, 21 Oct 2025 17:45:26 GMT Subject: RFR: 8370250: Locale should mention the behavior for duplicate subtags [v3] In-Reply-To: References: Message-ID: > Please review this PR which is a first stab at clarifying the behavior of duplicate variants, extension singletons, and U extension keys and attributes for BCP47 subtags in the Locale specification. This is a follow up to https://bugs.openjdk.org/browse/JDK-8369739. > > Changes are made under the BCP47 and U extension sections that define "well-formed" in the class description. > Additionally, changes are made under the relevant Locale and Locale.Builder methods themselves. > > Will update the CSR accordingly when the proposed wording changes are finalized. Justin Lu has updated the pull request incrementally with one additional commit since the last revision: Add 'subsequent' wording to setLanguageTag ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27909/files - new: https://git.openjdk.org/jdk/pull/27909/files/59f52b32..daa7a2e6 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27909&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27909&range=01-02 Stats: 2 lines in 1 file changed: 1 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/27909.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27909/head:pull/27909 PR: https://git.openjdk.org/jdk/pull/27909 From naoto at openjdk.org Tue Oct 21 19:29:19 2025 From: naoto at openjdk.org (Naoto Sato) Date: Tue, 21 Oct 2025 19:29:19 GMT Subject: RFR: 8370250: Locale should mention the behavior for duplicate subtags [v3] In-Reply-To: References: Message-ID: <4WOROwLTGlLh53TDLW95BYHY1Vs2hWcAqYQs5E1Q0Uc=.674323d6-0e5a-4050-b4a4-6ddfce60d4a7@github.com> On Tue, 21 Oct 2025 17:45:26 GMT, Justin Lu wrote: >> Please review this PR which is a first stab at clarifying the behavior of duplicate variants, extension singletons, and U extension keys and attributes for BCP47 subtags in the Locale specification. This is a follow up to https://bugs.openjdk.org/browse/JDK-8369739. >> >> Changes are made under the BCP47 and U extension sections that define "well-formed" in the class description. >> Additionally, changes are made under the relevant Locale and Locale.Builder methods themselves. >> >> Will update the CSR accordingly when the proposed wording changes are finalized. > > Justin Lu has updated the pull request incrementally with one additional commit since the last revision: > > Add 'subsequent' wording to setLanguageTag The updated wording looks good ------------- Marked as reviewed by naoto (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/27909#pullrequestreview-3362391549 From jlu at openjdk.org Tue Oct 21 20:23:02 2025 From: jlu at openjdk.org (Justin Lu) Date: Tue, 21 Oct 2025 20:23:02 GMT Subject: RFR: 8370250: Locale should mention the behavior for duplicate subtags [v3] In-Reply-To: <4WOROwLTGlLh53TDLW95BYHY1Vs2hWcAqYQs5E1Q0Uc=.674323d6-0e5a-4050-b4a4-6ddfce60d4a7@github.com> References: <4WOROwLTGlLh53TDLW95BYHY1Vs2hWcAqYQs5E1Q0Uc=.674323d6-0e5a-4050-b4a4-6ddfce60d4a7@github.com> Message-ID: On Tue, 21 Oct 2025 19:26:26 GMT, Naoto Sato wrote: >> Justin Lu has updated the pull request incrementally with one additional commit since the last revision: >> >> Add 'subsequent' wording to setLanguageTag > > The updated wording looks good @naotoj The CSR is now updated with the proposed wording. ------------- PR Comment: https://git.openjdk.org/jdk/pull/27909#issuecomment-3429419515 From pminborg at openjdk.org Wed Oct 22 07:51:30 2025 From: pminborg at openjdk.org (Per Minborg) Date: Wed, 22 Oct 2025 07:51:30 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v19] In-Reply-To: <7R8km2ZfztfyDcrUvjd_5P85J7pBMsxAIY-tP76jnTc=.d4311603-0098-4f89-84b3-f073bec00a4d@github.com> References: <2Ow8e38mfpHtFTbD5kUe4BKOaWACguUWAfKwerScgMg=.228371ce-d23d-4dc2-816c-ce80c7da7771@github.com> <7R8km2ZfztfyDcrUvjd_5P85J7pBMsxAIY-tP76jnTc=.d4311603-0098-4f89-84b3-f073bec00a4d@github.com> Message-ID: On Sat, 18 Oct 2025 01:04:37 GMT, ExE Boss wrote: >> src/java.base/share/classes/java/lang/LazyConstant.java line 161: >> >>> 159: * to a lazy constant or if there is a chain from a {@code static final} field -- via one >>> 160: * or more trusted fields (i.e., {@code static final} fields, >>> 161: * {@linkplain Record record} fields, lazy constants, lazy lists, lazy maps, >> >> lazy constants and lazy lists/maps are not themselves "trusted final fields" (at least not yet), so not sure they belong here? > > The?`@Stable`?annotation makes?fields with?non?`null`?values into?trusted?fields when?the?class is?loaded by?a?platform class?loader. There could be a chain: `static final` -> record component -> lazy list element -> record component, for example, and this would be a trusted chain. There are other constucts that could be in the chain as well and that are not mentioned (e.g. a `List.of()`) so perhaps we should do some change here. Easiest is to just remove the mention of lazy*. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2450745732 From alsaiditransport0 at gmail.com Wed Oct 22 18:52:34 2025 From: alsaiditransport0 at gmail.com (Alsaiditransport) Date: Wed, 22 Oct 2025 21:52:34 +0300 Subject: =?utf-8?b?2YbZgtmEINi52YHYtCDYrNin2LLYp9mG?= Message-ID: ??? ??? ?????????? ????? ??? ????? ?? ??? ??????? ??? ???????? ?? ???? ??? ??? ?? ??? ????? ???????? ?????? ?? ????? ????? ????? ??????. ?????? ???? ?????? ???? ????? ?????? ?????? ????? ?? ????? ????? ??????. ------------------------------ 1. ????? ??? ????? ?? ????? ???? *???? ??? ??? ????? * ????? ??????? ???? ??????? ???????? ?????? ????? ??? ????? ??????. ????? ?????? ??? ??? ????? ?????? ????? ????? ????? ?????? ?????? ?????? ?? ???????? ????????? ??????? ?????? ???????? ???? ??? ?? ???????. ------------------------------ 2. ??? ????? ?? ???? ?? ????? ???? *???? ??? ??? ???? * ?????? ??????? ????: - ??????? ???????? ????????? ????? ????? ?????? - ??????? ?????? ????? ?????? ????? ????? ????? - ??????? ?????? ?? ?????? ???? ??????? ???? ?????? ???? ?????? ?????? ??????? ?????? ????? ??? ???? ??????. ------------------------------ 3. ??? ????? ?? ????? ??? *???? ??? ??? ????? * ?? ???? ??????? ?? ?????? ??? ????: - ?????? ?????? ????? ?????? ?????? ????? ????? - ???? ???? ?????? ????? ?????????? - ???? ????? ????? ????? ???? ????????? ?????? ??? ?????? ???? ????? ????? ???? ??????? ?? ?????? ??? ???? ??????. ------------------------------ 4. ????? ???? ????? ????? ????? - ??????? ?????? ?????? ????? ??? ?? ???? ???? - ??????? ???? ????? ?????? ?????? ???? - ?????? ?? ????? ????? ????? ?? ????? ????? ?????? ??? ??????? ??????? ?????? ???????? ?? ?? ?????? ????? ???? ??? ??? ???? ????? ????????. ------------------------------ 5. ??????? ??? ????? ?? ????? ????? ?????? ????? ??? ?????. ??????? ?????? ??????? ???????? ??????? ????? ?????? ???? ???? ?????? ?????? ??????? ?? ????? ????? ?????? ??????? ??? ????? ?????? ????? ?????. -------------- next part -------------- An HTML attachment was scrubbed... URL: From rriggs at openjdk.org Thu Oct 23 18:46:38 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Thu, 23 Oct 2025 18:46:38 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v4] In-Reply-To: References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> Message-ID: <_5e7Ota89HOgtcpsy4umlfF1EL1f3Xiyt2lmG1gN_DM=.6a3718d0-4cb3-49d6-82ca-16d6ad7bf8bc@github.com> On Sun, 19 Oct 2025 09:12:42 GMT, Xueming Shen wrote: >> ### Summary >> >> Case folding is a key operation for case-insensitive matching (e.g., string equality, regex matching), where the goal is to eliminate case distinctions without applying locale or language specific conversions. >> >> Currently, the JDK does not expose a direct API for Unicode-compliant case folding. Developers now rely on methods such as: >> >> **String.equalsIgnoreCase(String)** >> >> - Unicode-aware, locale-independent. >> - Implementation uses Character.toLowerCase(Character.toUpperCase(int)) per code point. >> - Limited: does not support 1:M mapping defined in Unicode case folding. >> >> **Character.toLowerCase(int) / Character.toUpperCase(int)** >> >> - Locale-independent, single code point only. >> - No support for 1:M mappings. >> >> **String.toLowerCase(Locale.ROOT) / String.toUpperCase(Locale.ROOT)** >> >> - Based on Unicode SpecialCasing.txt, supports 1:M mappings. >> - Intended primarily for presentation/display, not structural case-insensitive matching. >> - Requires full string conversion before comparison, which is less efficient and not intended for structural matching. >> >> **1:M mapping example, U+00DF (?)** >> >> - String.toUpperCase(Locale.ROOT, "?") ? "SS" >> - Case folding produces "ss", matching Unicode caseless comparison rules. >> >> >> jshell> "\u00df".equalsIgnoreCase("ss") >> $22 ==> false >> >> jshell> "\u00df".toUpperCase(Locale.ROOT).toLowerCase(Locale.ROOT).equals("ss") >> $24 ==> true >> >> >> ### Motivation & Direction >> >> Add Unicode standard-compliant case-less comparison methods to the String class, enabling & improving reliable and efficient Unicode-aware/compliant case-insensitive matching. >> >> - Unicode-compliant **full** case folding. >> - Simpler, stable and more efficient case-less matching without workarounds. >> - Brings Java's string comparison handling in line with other programming languages/libraries. >> >> This PR proposes to introduce the following comparison methods in `String` class >> >> - boolean equalsFoldCase(String anotherString) >> - int compareToFoldCase(String anotherString) >> - Comparator UNICODE_CASEFOLD_ORDER >> >> These methods are intended to be the preferred choice when Unicode-compliant case-less matching is required. >> >> *Note: An early draft also proposed a String.toCaseFold() method returning a new case-folded string. >> However, during review this was considered error-prone, as the resulting string could easily be mistaken for a general transformation like toLowerCase() and then pass... > > Xueming Shen has updated the pull request incrementally with one additional commit since the last revision: > > test case update make/jdk/src/classes/build/tools/generatecharacter/CaseFolding.java line 1: > 1: /* Please rename this build tool to avoid ambiguity in the naming of CaseFolding.java. make/jdk/src/classes/build/tools/generatecharacter/CaseFolding.java line 60: > 58: cp, > 59: Arrays.stream(folding) > 60: .mapToObj(f -> String.format("0x%04x", f)) For each string in fields do the parsing and formatting here; skipping the extra array. Or just use the string from fields[i]; the parse and format seems like a no-op except for catching file format errors. make/jdk/src/classes/build/tools/generatecharacter/CaseFolding.java line 71: > 69: .map(line -> { > 70: String[] cols = line.split("; "); > 71: return new String[]{cols[0], cols[1], cols[2]}; Seems unnecessary to create a new String array with the same strings. src/java.base/share/classes/java/lang/String.java line 2237: > 2235: return true; > 2236: } > 2237: if (anotherString == null) { These tests would be better in UNICODE_CASEFOLD_ORDER and cover more cases including directly using the comparator. Or omit the extra null checks (to be more like the existing CaseInsensitiveComparator). src/java.base/share/classes/java/lang/StringLatin1.java line 70: > 68: return value[index] & 0xff; > 69: } > 70: Seems to be unused and is identical to `getChar` src/java.base/share/classes/java/lang/StringLatin1.java line 192: > 190: int[] folded2 = null; > 191: int k1 = off, k2 = ooff, fk1 = 0, fk2 = 0; > 192: while ((k1 < last || folded1 != null && fk1 < folded1.length) && One less comparison in the loop by checking the common length using `int limit = Math.min(last, olast)`. src/java.base/share/classes/java/lang/StringLatin1.java line 193: > 191: int k1 = off, k2 = ooff, fk1 = 0, fk2 = 0; > 192: while ((k1 < last || folded1 != null && fk1 < folded1.length) && > 193: (k2 < olast || folded2 != null && fk2 < folded2.length)) { Suggest starting the slow path after any matching prefix using `ArraySupport.mismatch(byte[], off1, byte[], off2, length)`. That should have good/best performance for matching sequences. src/java.base/share/classes/java/lang/StringLatin1.java line 217: > 215: if (c1 != c2) { > 216: return c1 - c2; > 217: } Compute difference only once. Suggestion: if ((c1 - c2) != 0) { return c1 - c2; } src/java.base/share/classes/java/lang/StringLatin1.java line 228: > 226: } > 227: > 228: static int compareToFC(byte[] value, byte[] other) { Quirky special cases (like DF) might be worth a description in a single place since there are multiple paths latin1/UTF16, etc. src/java.base/share/classes/java/lang/StringLatin1.java line 229: > 227: > 228: static int compareToFC(byte[] value, byte[] other) { > 229: int len = value.length; The might also be a good place to use ArraySupport.mismatch to find the first non-matching char. src/java.base/share/classes/java/lang/StringLatin1.java line 244: > 242: } > 243: return Character.toLowerCase(c1) - Character.toLowerCase(c2); > 244: Extra blank line. src/java.base/share/classes/java/lang/StringUTF16.java line 605: > 603: int k1 = off, k2 = ooff, fk1 = 0, fk2 = 0; > 604: while ((k1 < last || folded1 != null && fk1 < folded1.length) && > 605: (k2 < olast || folded2 != null && fk2 < folded2.length)) { Use ArraySupport.mismatch to quickly scan past identical sequences. (byte index will need to be converted to char index). src/java.base/share/classes/java/lang/StringUTF16.java line 645: > 643: int tlast = length(value); > 644: int olast = length(other); > 645: int k = 0; Arrays.mismatch can be used to skip leading or complete match before starting per character code path. src/java.base/share/classes/jdk/internal/lang/CaseFolding.java.template line 1: > 1: /* Significant performance improvements could be had by handling single (simple) char -> char folding separately avoiding the overhead of iterating over single character arrays. src/java.base/share/classes/jdk/internal/lang/CaseFolding.java.template line 26: > 24: */ > 25: > 26: package jdk.internal.java.lang; Please use the jdk.internal.lang package. (And adjust GensrcCharacterData.gmk). src/java.base/share/classes/jdk/internal/lang/CaseFolding.java.template line 57: > 55: * @see #fold(int) > 56: */ > 57: public static boolean isFolded(int cp) { The name `isFolded` can be confusing, it implies there is a mapping needed, but it is the opposite. I'd suggest suggest keeping only `isDefined` and perhaps rename to `hasFold` or similar. src/java.base/share/classes/jdk/internal/lang/CaseFolding.java.template line 93: > 91: if (entry != null) > 92: return entry.folding; > 93: return new int[] { cp }; Creating a bunch of small arrays is very wasteful. Single char to single char should not need an allocation. src/java.base/share/classes/jdk/internal/lang/CaseFolding.java.template line 131: > 129: * @return a {@code String} containing the case-folded form of the input string > 130: */ > 131: public static String fold(String s) { Save this unused method for another PR. (and the corresponding tests) test/micro/org/openjdk/bench/java/lang/StringCompareToFoldCase.java line 57: > 55: public String supLower = "\ud801\udc28\ud801\udc29\ud801\udc2a\ud801\udc2b\ud801\udc2c"; > 56: > 57: @Benchmark Add cases also for strings to themselves (latin1, utf16) to see how the fastest path compares. Is there any body of more representative text with more typical intermixing of normal and folded sequences? Strings with multiple ?? are not typical. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2453279238 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2453205161 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2453214070 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2453295048 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2453302601 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2453347556 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2453321434 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2453338377 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2453369663 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2453366657 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2456338704 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2456403245 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2456423333 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2456634925 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2453283972 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2456506906 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2456514193 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2456529794 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2456658965 From rriggs at openjdk.org Thu Oct 23 18:46:40 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Thu, 23 Oct 2025 18:46:40 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v4] In-Reply-To: <_5e7Ota89HOgtcpsy4umlfF1EL1f3Xiyt2lmG1gN_DM=.6a3718d0-4cb3-49d6-82ca-16d6ad7bf8bc@github.com> References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> <_5e7Ota89HOgtcpsy4umlfF1EL1f3Xiyt2lmG1gN_DM=.6a3718d0-4cb3-49d6-82ca-16d6ad7bf8bc@github.com> Message-ID: On Thu, 23 Oct 2025 18:32:03 GMT, Roger Riggs wrote: >> Xueming Shen has updated the pull request incrementally with one additional commit since the last revision: >> >> test case update > > test/micro/org/openjdk/bench/java/lang/StringCompareToFoldCase.java line 57: > >> 55: public String supLower = "\ud801\udc28\ud801\udc29\ud801\udc2a\ud801\udc2b\ud801\udc2c"; >> 56: >> 57: @Benchmark > > Add cases also for strings to themselves (latin1, utf16) to see how the fastest path compares. > > Is there any body of more representative text with more typical intermixing of normal and folded sequences? Strings with multiple ?? are not typical. These will run a long time, consider reducing cases that are very similar. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2456661817 From psadhukhan at openjdk.org Fri Oct 24 07:56:33 2025 From: psadhukhan at openjdk.org (Prasanta Sadhukhan) Date: Fri, 24 Oct 2025 07:56:33 GMT Subject: RFR: 8370560: Remove non-public API reference from public API javadoc Message-ID: <3ybm9NpokeckPQYbMRXiPFpbAihUpHhbt2A3_Kfndyc=.151d4f41-960b-423a-aa20-bd3cc2bdaa46@github.com> Non-public API reference is removed from public API ------------- Commit messages: - 8370560: Remove non-public API reference from public API Changes: https://git.openjdk.org/jdk/pull/27970/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=27970&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8370560 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/27970.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27970/head:pull/27970 PR: https://git.openjdk.org/jdk/pull/27970 From pminborg at openjdk.org Fri Oct 24 08:51:06 2025 From: pminborg at openjdk.org (Per Minborg) Date: Fri, 24 Oct 2025 08:51:06 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v19] In-Reply-To: References: Message-ID: On Fri, 17 Oct 2025 14:58:44 GMT, Per Minborg wrote: >> Implement JEP 526: Lazy Constants (Second Preview) >> >> The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. >> >> The old benchmarks are not moved/renamed to allow comparison with previous releases. >> >> `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. > > Per Minborg has updated the pull request incrementally with one additional commit since the last revision: > > Update after doc comments After some discussion, we have concluded that we need to rework how `toString()` works for `LazyConstant`, lazy maps, and lists: #### For `LazyConstant` In order to align with other comput-later constructs like `Future`, we'd like to provide something like this: java.lang.LazyConstant at 5ed828d[computing function = $Lambda/0x00000ffe000d6550 at 4d3167f4] // Uninitialized java.lang.LazyConstant at 4ad92aa[42] // Initialized #### For lazy list, map, and all their derivatives (e.g., `subList()`, `values()`) There is a tension between the willingness to keep the `toString()` methods lazy during debugging and the compatibility with the existing `List` and `Map` implementations. It would be very surprising if a lazy list would output something different from a normal list for `toString()`. We think it is more important that lazy constructs are compatible with their corresponding eager constructs. Hence, we propose to make `toString()` trigger initialization of all elements/values. ------------- PR Comment: https://git.openjdk.org/jdk/pull/27605#issuecomment-3441894953 From pminborg at openjdk.org Fri Oct 24 09:01:10 2025 From: pminborg at openjdk.org (Per Minborg) Date: Fri, 24 Oct 2025 09:01:10 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v20] In-Reply-To: References: Message-ID: > Implement JEP 526: Lazy Constants (Second Preview) > > The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. > > The old benchmarks are not moved/renamed to allow comparison with previous releases. > > `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. Per Minborg has updated the pull request incrementally with one additional commit since the last revision: Rework toString implementations ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27605/files - new: https://git.openjdk.org/jdk/pull/27605/files/6721ca4a..c3278e0b Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=19 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27605&range=18-19 Stats: 271 lines in 5 files changed: 27 ins; 211 del; 33 mod Patch: https://git.openjdk.org/jdk/pull/27605.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27605/head:pull/27605 PR: https://git.openjdk.org/jdk/pull/27605 From prr at openjdk.org Fri Oct 24 20:54:01 2025 From: prr at openjdk.org (Phil Race) Date: Fri, 24 Oct 2025 20:54:01 GMT Subject: RFR: 8370560: Remove non-public API reference from public API javadoc In-Reply-To: <3ybm9NpokeckPQYbMRXiPFpbAihUpHhbt2A3_Kfndyc=.151d4f41-960b-423a-aa20-bd3cc2bdaa46@github.com> References: <3ybm9NpokeckPQYbMRXiPFpbAihUpHhbt2A3_Kfndyc=.151d4f41-960b-423a-aa20-bd3cc2bdaa46@github.com> Message-ID: On Fri, 24 Oct 2025 07:46:30 GMT, Prasanta Sadhukhan wrote: > Non-public API reference is removed from public API Marked as reviewed by prr (Reviewer). ------------- PR Review: https://git.openjdk.org/jdk/pull/27970#pullrequestreview-3378804616 From duke at openjdk.org Sat Oct 25 02:53:02 2025 From: duke at openjdk.org (Josiah Noel) Date: Sat, 25 Oct 2025 02:53:02 GMT Subject: Withdrawn: 8368695: Support 101 switching protocol in jdk.httpserver In-Reply-To: References: Message-ID: On Fri, 10 Oct 2025 19:45:57 GMT, Josiah Noel wrote: > - adds a flag to ExchangeImpl to signal whether the current request is an Upgrade request > - Adds a new `UpgradeInputStream` to ensure that the server keeps track of when the upgraded request is closed > - on 101 response codes, `sendResponseHeaders` will not immediately close the output stream > - on 101 response codes, `sendResponseHeaders` will use an `UndefLengthOutputStream` This pull request has been closed without being integrated. ------------- PR: https://git.openjdk.org/jdk/pull/27751 From duke at openjdk.org Sat Oct 25 02:53:01 2025 From: duke at openjdk.org (Josiah Noel) Date: Sat, 25 Oct 2025 02:53:01 GMT Subject: RFR: 8368695: Support 101 switching protocol in jdk.httpserver [v13] In-Reply-To: References: Message-ID: > - adds a flag to ExchangeImpl to signal whether the current request is an Upgrade request > - Adds a new `UpgradeInputStream` to ensure that the server keeps track of when the upgraded request is closed > - on 101 response codes, `sendResponseHeaders` will not immediately close the output stream > - on 101 response codes, `sendResponseHeaders` will use an `UndefLengthOutputStream` Josiah Noel has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 18 commits: - Update ExchangeImpl.java - Merge remote-tracking branch 'upstream/master' into JDK-8368695 - reduce diff - Merge remote-tracking branch 'upstream/master' into JDK-8368695 - Update SwitchingProtocolTest.java - Update SwitchingProtocolTest.java - Update SwitchingProtocolTest.java - add exception test - Create UpgradeOutputStream.java - close raw streams - ... and 8 more: https://git.openjdk.org/jdk/compare/32697bf6...ae2b1184 ------------- Changes: https://git.openjdk.org/jdk/pull/27751/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=27751&range=12 Stats: 25304 lines in 632 files changed: 6529 ins; 14641 del; 4134 mod Patch: https://git.openjdk.org/jdk/pull/27751.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27751/head:pull/27751 PR: https://git.openjdk.org/jdk/pull/27751 From psadhukhan at openjdk.org Mon Oct 27 05:20:11 2025 From: psadhukhan at openjdk.org (Prasanta Sadhukhan) Date: Mon, 27 Oct 2025 05:20:11 GMT Subject: Integrated: 8370560: Remove non-public API reference from public API javadoc In-Reply-To: <3ybm9NpokeckPQYbMRXiPFpbAihUpHhbt2A3_Kfndyc=.151d4f41-960b-423a-aa20-bd3cc2bdaa46@github.com> References: <3ybm9NpokeckPQYbMRXiPFpbAihUpHhbt2A3_Kfndyc=.151d4f41-960b-423a-aa20-bd3cc2bdaa46@github.com> Message-ID: On Fri, 24 Oct 2025 07:46:30 GMT, Prasanta Sadhukhan wrote: > Non-public API reference is removed from public API This pull request has now been integrated. Changeset: bfc1db7e Author: Prasanta Sadhukhan URL: https://git.openjdk.org/jdk/commit/bfc1db7ed6bf9563c0441b24abe6943607b532e7 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod 8370560: Remove non-public API reference from public API javadoc Reviewed-by: prr ------------- PR: https://git.openjdk.org/jdk/pull/27970 From sherman at openjdk.org Mon Oct 27 08:42:19 2025 From: sherman at openjdk.org (Xueming Shen) Date: Mon, 27 Oct 2025 08:42:19 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v4] In-Reply-To: <_5e7Ota89HOgtcpsy4umlfF1EL1f3Xiyt2lmG1gN_DM=.6a3718d0-4cb3-49d6-82ca-16d6ad7bf8bc@github.com> References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> <_5e7Ota89HOgtcpsy4umlfF1EL1f3Xiyt2lmG1gN_DM=.6a3718d0-4cb3-49d6-82ca-16d6ad7bf8bc@github.com> Message-ID: On Wed, 22 Oct 2025 20:31:19 GMT, Roger Riggs wrote: >> Xueming Shen has updated the pull request incrementally with one additional commit since the last revision: >> >> test case update > > src/java.base/share/classes/jdk/internal/lang/CaseFolding.java.template line 26: > >> 24: */ >> 25: >> 26: package jdk.internal.java.lang; > > Please use the jdk.internal.lang package. (And adjust GensrcCharacterData.gmk). updated > src/java.base/share/classes/jdk/internal/lang/CaseFolding.java.template line 57: > >> 55: * @see #fold(int) >> 56: */ >> 57: public static boolean isFolded(int cp) { > > The name `isFolded` can be confusing, it implies there is a mapping needed, but it is the opposite. > I'd suggest suggest keeping only `isDefined` and perhaps rename to `hasFold` or similar. removed. not really used. isDefined() is being used. > src/java.base/share/classes/jdk/internal/lang/CaseFolding.java.template line 93: > >> 91: if (entry != null) >> 92: return entry.folding; >> 93: return new int[] { cp }; > > Creating a bunch of small arrays is very wasteful. Single char to single char should not need an allocation. this is not really being used by the string class, for now. removed > src/java.base/share/classes/jdk/internal/lang/CaseFolding.java.template line 131: > >> 129: * @return a {@code String} containing the case-folded form of the input string >> 130: */ >> 131: public static String fold(String s) { > > Save this unused method for another PR. (and the corresponding tests) removed to the test case as a helper method > src/java.base/share/classes/jdk/internal/lang/CaseFolding.java.template line 280: > >> 278: } >> 279: >> 280: private void add(CaseFoldingEntry entry) { > > CDS can map whole objects/data structures into the heap; consider how to make this data structure so it can be mapped and not re-computed each startup. updated to use CDS. still generate the hash table at the init to reduce unnecessary static memory footage. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2464814725 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2464804057 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2464806436 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2464807206 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2464811378 From sherman at openjdk.org Mon Oct 27 09:30:05 2025 From: sherman at openjdk.org (Xueming Shen) Date: Mon, 27 Oct 2025 09:30:05 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v4] In-Reply-To: <_5e7Ota89HOgtcpsy4umlfF1EL1f3Xiyt2lmG1gN_DM=.6a3718d0-4cb3-49d6-82ca-16d6ad7bf8bc@github.com> References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> <_5e7Ota89HOgtcpsy4umlfF1EL1f3Xiyt2lmG1gN_DM=.6a3718d0-4cb3-49d6-82ca-16d6ad7bf8bc@github.com> Message-ID: On Thu, 23 Oct 2025 17:47:51 GMT, Roger Riggs wrote: >> Xueming Shen has updated the pull request incrementally with one additional commit since the last revision: >> >> test case update > > src/java.base/share/classes/java/lang/StringUTF16.java line 605: > >> 603: int k1 = off, k2 = ooff, fk1 = 0, fk2 = 0; >> 604: while ((k1 < last || folded1 != null && fk1 < folded1.length) && >> 605: (k2 < olast || folded2 != null && fk2 < folded2.length)) { > > Use ArraySupport.mismatch to quickly scan past identical sequences. (byte index will need to be converted to char index). seems like we are only using it for case-aware comparison in existing string comparison. just wonder do we really want to apply this for the case insensitive comparision? static int compareTo(byte[] value, byte[] other, int len1, int len2) { int lim = Math.min(len1, len2); int k = ArraysSupport.mismatch(value, other, lim); return (k < 0) ? len1 - len2 : getChar(value, k) - getChar(other, k); } ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2464954933 From sherman at openjdk.org Mon Oct 27 09:46:06 2025 From: sherman at openjdk.org (Xueming Shen) Date: Mon, 27 Oct 2025 09:46:06 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v5] In-Reply-To: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> Message-ID: > ### Summary > > Case folding is a key operation for case-insensitive matching (e.g., string equality, regex matching), where the goal is to eliminate case distinctions without applying locale or language specific conversions. > > Currently, the JDK does not expose a direct API for Unicode-compliant case folding. Developers now rely on methods such as: > > **String.equalsIgnoreCase(String)** > > - Unicode-aware, locale-independent. > - Implementation uses Character.toLowerCase(Character.toUpperCase(int)) per code point. > - Limited: does not support 1:M mapping defined in Unicode case folding. > > **Character.toLowerCase(int) / Character.toUpperCase(int)** > > - Locale-independent, single code point only. > - No support for 1:M mappings. > > **String.toLowerCase(Locale.ROOT) / String.toUpperCase(Locale.ROOT)** > > - Based on Unicode SpecialCasing.txt, supports 1:M mappings. > - Intended primarily for presentation/display, not structural case-insensitive matching. > - Requires full string conversion before comparison, which is less efficient and not intended for structural matching. > > **1:M mapping example, U+00DF (?)** > > - String.toUpperCase(Locale.ROOT, "?") ? "SS" > - Case folding produces "ss", matching Unicode caseless comparison rules. > > > jshell> "\u00df".equalsIgnoreCase("ss") > $22 ==> false > > jshell> "\u00df".toUpperCase(Locale.ROOT).toLowerCase(Locale.ROOT).equals("ss") > $24 ==> true > > > ### Motivation & Direction > > Add Unicode standard-compliant case-less comparison methods to the String class, enabling & improving reliable and efficient Unicode-aware/compliant case-insensitive matching. > > - Unicode-compliant **full** case folding. > - Simpler, stable and more efficient case-less matching without workarounds. > - Brings Java's string comparison handling in line with other programming languages/libraries. > > This PR proposes to introduce the following comparison methods in `String` class > > - boolean equalsFoldCase(String anotherString) > - int compareToFoldCase(String anotherString) > - Comparator UNICODE_CASEFOLD_ORDER > > These methods are intended to be the preferred choice when Unicode-compliant case-less matching is required. > > *Note: An early draft also proposed a String.toCaseFold() method returning a new case-folded string. > However, during review this was considered error-prone, as the resulting string could easily be mistaken for a general transformation like toLowerCase() and then passed into APIs where case-folding semantics are not appropriate. > > ### The New API > > See CSR https://bugs.openjd... Xueming Shen has updated the pull request incrementally with one additional commit since the last revision: update ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27628/files - new: https://git.openjdk.org/jdk/pull/27628/files/27626771..c98543ff Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27628&range=04 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27628&range=03-04 Stats: 505 lines in 9 files changed: 165 ins; 201 del; 139 mod Patch: https://git.openjdk.org/jdk/pull/27628.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27628/head:pull/27628 PR: https://git.openjdk.org/jdk/pull/27628 From sherman at openjdk.org Mon Oct 27 09:46:11 2025 From: sherman at openjdk.org (Xueming Shen) Date: Mon, 27 Oct 2025 09:46:11 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v4] In-Reply-To: <_5e7Ota89HOgtcpsy4umlfF1EL1f3Xiyt2lmG1gN_DM=.6a3718d0-4cb3-49d6-82ca-16d6ad7bf8bc@github.com> References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> <_5e7Ota89HOgtcpsy4umlfF1EL1f3Xiyt2lmG1gN_DM=.6a3718d0-4cb3-49d6-82ca-16d6ad7bf8bc@github.com> Message-ID: On Wed, 22 Oct 2025 19:57:17 GMT, Roger Riggs wrote: >> Xueming Shen has updated the pull request incrementally with one additional commit since the last revision: >> >> test case update > > make/jdk/src/classes/build/tools/generatecharacter/CaseFolding.java line 60: > >> 58: cp, >> 59: Arrays.stream(folding) >> 60: .mapToObj(f -> String.format("0x%04x", f)) > > For each string in fields do the parsing and formatting here; skipping the extra array. > Or just use the string from fields[i]; the parse and format seems like a no-op except for catching file format errors. updated to use the input stream directly > src/java.base/share/classes/java/lang/StringLatin1.java line 217: > >> 215: if (c1 != c2) { >> 216: return c1 - c2; >> 217: } > > Compute difference only once. > Suggestion: > > if ((c1 - c2) != 0) { > return c1 - c2; > } you meant go with if ((c1 - c2) != 0) { return c1 - c2; } ? ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2465004392 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2464997505 From sherman at openjdk.org Mon Oct 27 09:46:14 2025 From: sherman at openjdk.org (Xueming Shen) Date: Mon, 27 Oct 2025 09:46:14 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v2] In-Reply-To: References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> Message-ID: On Wed, 8 Oct 2025 13:57:17 GMT, Chen Liang wrote: >> Xueming Shen has updated the pull request incrementally with one additional commit since the last revision: >> >> minor api doc updates > > make/modules/java.base/gensrc/GensrcCharacterData.gmk line 76: > >> 74: >> 75: >> 76: GENSRC_STRINGCASEFOLDING := $(SUPPORT_OUTPUTDIR)/gensrc/java.base/jdk/internal/java/lang/CaseFolding.java > > Can we target the package `jdk.internal.lang` instead of `jdk.internal.java.lang`? I think the previous one is the convention set forth by stable values. renamed ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2465002293 From vyazici at openjdk.org Mon Oct 27 12:32:39 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Mon, 27 Oct 2025 12:32:39 GMT Subject: RFR: 8363925: Remove unused sun.nio.cs.ArrayEncoder::encode Message-ID: [JDK-6636319] introduced `ArrayEncoder`, composed of _only_ `encode` method. Later on [JDK-8054307] (JEP 254: Compact Strings) removed all its usages. This method can safely be removed, hence this PR. Confirmed that `tier1-2` tests are clear on several platforms after changes. [JDK-6636319]: https://bugs.openjdk.org/browse/JDK-6636319 [JDK-8054307]: https://bugs.openjdk.org/browse/JDK-8054307 ------------- Commit messages: - Remove unused `sun.nio.cs.ArrayEncoder::encode` Changes: https://git.openjdk.org/jdk/pull/27999/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=27999&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8363925 Stats: 261 lines in 6 files changed: 64 ins; 179 del; 18 mod Patch: https://git.openjdk.org/jdk/pull/27999.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27999/head:pull/27999 PR: https://git.openjdk.org/jdk/pull/27999 From rriggs at openjdk.org Mon Oct 27 14:43:59 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Mon, 27 Oct 2025 14:43:59 GMT Subject: RFR: 8363925: Remove unused sun.nio.cs.ArrayEncoder::encode In-Reply-To: References: Message-ID: <2NNRaDE6GVefZ55qD1IaLwfnIv_9BGyCTn6JYxFjvS4=.624d307c-1293-4ae5-8c57-31684a10ffde@github.com> On Mon, 27 Oct 2025 11:42:20 GMT, Volkan Yazici wrote: > [JDK-6636319] introduced `ArrayEncoder`, composed of _only_ `encode` method. Later on [JDK-8054307] (JEP 254: Compact Strings) removed all its usages. This method can safely be removed, hence this PR. Confirmed that `tier1-2` tests are clear on several platforms after changes. > > [JDK-6636319]: https://bugs.openjdk.org/browse/JDK-6636319 > [JDK-8054307]: https://bugs.openjdk.org/browse/JDK-8054307 test/jdk/sun/nio/cs/TestStringCoding.java line 295: > 293: return IntStream.range(0, bs.length) > 294: .mapToObj(i -> String.format("0x%02X", bs[i] & 0xFF)) > 295: .collect(Collectors.joining(", ", "[", "]")); fyi, java.util.HexFormat can do that too: Suggestion: return "[" + HexFormat.ofDelimiter(", ").withPrefix("0x").formatHex(bs) + "]"; ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27999#discussion_r2465949995 From jlu at openjdk.org Mon Oct 27 16:42:55 2025 From: jlu at openjdk.org (Justin Lu) Date: Mon, 27 Oct 2025 16:42:55 GMT Subject: Integrated: 8370250: Locale should mention the behavior for duplicate subtags In-Reply-To: References: Message-ID: On Mon, 20 Oct 2025 22:52:19 GMT, Justin Lu wrote: > Please review this PR which is a first stab at clarifying the behavior of duplicate variants, extension singletons, and U extension keys and attributes for BCP47 subtags in the Locale specification. This is a follow up to https://bugs.openjdk.org/browse/JDK-8369739. > > Changes are made under the BCP47 and U extension sections that define "well-formed" in the class description. > Additionally, changes are made under the relevant Locale and Locale.Builder methods themselves. > > Will update the CSR accordingly when the proposed wording changes are finalized. This pull request has now been integrated. Changeset: ebf9c5bf Author: Justin Lu URL: https://git.openjdk.org/jdk/commit/ebf9c5bfc1b2e8e9210cc37283a29d471f913916 Stats: 35 lines in 1 file changed: 23 ins; 0 del; 12 mod 8370250: Locale should mention the behavior for duplicate subtags Reviewed-by: naoto ------------- PR: https://git.openjdk.org/jdk/pull/27909 From vyazici at openjdk.org Mon Oct 27 19:44:41 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Mon, 27 Oct 2025 19:44:41 GMT Subject: RFR: 8363925: Remove unused sun.nio.cs.ArrayEncoder::encode [v2] In-Reply-To: References: Message-ID: > [JDK-6636319] introduced `ArrayEncoder`, composed of _only_ `encode` method. Later on [JDK-8054307] (JEP 254: Compact Strings) removed all its usages. This method can safely be removed, hence this PR. Confirmed that `tier1-2` tests are clear on several platforms after changes. > > [JDK-6636319]: https://bugs.openjdk.org/browse/JDK-6636319 > [JDK-8054307]: https://bugs.openjdk.org/browse/JDK-8054307 Volkan Yazici has updated the pull request incrementally with one additional commit since the last revision: Use `HexFormat` Co-authored-by: Roger Riggs ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27999/files - new: https://git.openjdk.org/jdk/pull/27999/files/ac07c09d..a8c471f2 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27999&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27999&range=00-01 Stats: 3 lines in 1 file changed: 0 ins; 2 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/27999.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27999/head:pull/27999 PR: https://git.openjdk.org/jdk/pull/27999 From liach at openjdk.org Mon Oct 27 22:39:07 2025 From: liach at openjdk.org (Chen Liang) Date: Mon, 27 Oct 2025 22:39:07 GMT Subject: RFR: 8368172: Make java.time.format.DateTimePrintContext immutable [v6] In-Reply-To: <-MQxYO6i5RCnBQ-1NTwm5GcwucQgqYXIRHlFvsxO17A=.a6846ed0-8cc5-4501-9b94-cafa62a4909e@github.com> References: <5xcmzM6BhoL-zhBZc_TrRSDCKBrOMqq8bRcmihc1zpU=.732bd228-f9ff-43f0-9771-56645dab6cd2@github.com> <-MQxYO6i5RCnBQ-1NTwm5GcwucQgqYXIRHlFvsxO17A=.a6846ed0-8cc5-4501-9b94-cafa62a4909e@github.com> Message-ID: On Thu, 2 Oct 2025 03:08:32 GMT, Shaojin Wen wrote: >> I propose to make j.t.f.DateTimePrintContext immutable. >> >> Currently, DateTimePrintContext has only one mutable field, optional. This can be replaced by adding an optional parameter to the DateTimeFormatter.formatTo method. >> >> Immutable DateTimePrintContext can be optimized by escape analysis, such as immutable object optimization. > > Shaojin Wen has updated the pull request incrementally with one additional commit since the last revision: > > Improve javadoc for optional parameter in DateTimePrinterParser#format method I think this is a good change. This allows DateTimePrintContext to be refactored to a value class later, which may unlock more optimization opportunities. ------------- Marked as reviewed by liach (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/26913#pullrequestreview-3385723601 From liach at openjdk.org Mon Oct 27 22:46:02 2025 From: liach at openjdk.org (Chen Liang) Date: Mon, 27 Oct 2025 22:46:02 GMT Subject: RFR: 8368172: Make java.time.format.DateTimePrintContext immutable [v6] In-Reply-To: <-MQxYO6i5RCnBQ-1NTwm5GcwucQgqYXIRHlFvsxO17A=.a6846ed0-8cc5-4501-9b94-cafa62a4909e@github.com> References: <5xcmzM6BhoL-zhBZc_TrRSDCKBrOMqq8bRcmihc1zpU=.732bd228-f9ff-43f0-9771-56645dab6cd2@github.com> <-MQxYO6i5RCnBQ-1NTwm5GcwucQgqYXIRHlFvsxO17A=.a6846ed0-8cc5-4501-9b94-cafa62a4909e@github.com> Message-ID: <_oV91W9qIUrqzO5uHqYvXqwdZ4Fk_hd1XiP-rmy-WX8=.e68558ee-b549-4b6e-954b-724520968577@github.com> On Thu, 2 Oct 2025 03:08:32 GMT, Shaojin Wen wrote: >> I propose to make j.t.f.DateTimePrintContext immutable. >> >> Currently, DateTimePrintContext has only one mutable field, optional. This can be replaced by adding an optional parameter to the DateTimeFormatter.formatTo method. >> >> Immutable DateTimePrintContext can be optimized by escape analysis, such as immutable object optimization. > > Shaojin Wen has updated the pull request incrementally with one additional commit since the last revision: > > Improve javadoc for optional parameter in DateTimePrinterParser#format method I have sent an internal CI run for this patch after merging latest mainline. Let's make sure the build looks good. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26913#issuecomment-3453612817 From liach at openjdk.org Mon Oct 27 23:05:02 2025 From: liach at openjdk.org (Chen Liang) Date: Mon, 27 Oct 2025 23:05:02 GMT Subject: RFR: 8363925: Remove unused sun.nio.cs.ArrayEncoder::encode [v2] In-Reply-To: References: Message-ID: On Mon, 27 Oct 2025 19:44:41 GMT, Volkan Yazici wrote: >> [JDK-6636319] introduced `ArrayEncoder`, composed of _only_ `encode` method. Later on [JDK-8054307] (JEP 254: Compact Strings) removed all its usages. This method can safely be removed, hence this PR. Confirmed that `tier1-2` tests are clear on several platforms after changes. >> >> [JDK-6636319]: https://bugs.openjdk.org/browse/JDK-6636319 >> [JDK-8054307]: https://bugs.openjdk.org/browse/JDK-8054307 > > Volkan Yazici has updated the pull request incrementally with one additional commit since the last revision: > > Use `HexFormat` > > Co-authored-by: Roger Riggs I recommend further refactors, at least turn the 3 default methods to abstract methods. After removal of ineffective CESU_8, we can make the default methods abstract to improve safety. Down the road, we can remove the -1 handling at use site, and also pass in dp explicitly (I recall this being useful for optimizing Writer/OutputStream) src/java.base/share/classes/sun/nio/cs/CESU_8.java line 1: > 1: /* The ArrayEncoder interface is now useless here. We should remove it. ------------- PR Review: https://git.openjdk.org/jdk/pull/27999#pullrequestreview-3385808944 PR Review Comment: https://git.openjdk.org/jdk/pull/27999#discussion_r2467352713 From vyazici at openjdk.org Tue Oct 28 09:37:58 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Tue, 28 Oct 2025 09:37:58 GMT Subject: RFR: 8363925: Remove unused sun.nio.cs.ArrayEncoder::encode [v3] In-Reply-To: References: Message-ID: > [JDK-6636319] introduced `ArrayEncoder`, composed of _only_ `encode` method. Later on [JDK-8054307] (JEP 254: Compact Strings) removed all its usages. This method can safely be removed, hence this PR. Confirmed that `tier1-2` tests are clear on several platforms after changes. > > [JDK-6636319]: https://bugs.openjdk.org/browse/JDK-6636319 > [JDK-8054307]: https://bugs.openjdk.org/browse/JDK-8054307 Volkan Yazici has updated the pull request incrementally with one additional commit since the last revision: Remove `ArrayEncoder` defaults and add `dp` parameter ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27999/files - new: https://git.openjdk.org/jdk/pull/27999/files/a8c471f2..c599d8d3 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27999&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27999&range=01-02 Stats: 34 lines in 8 files changed: 0 ins; 14 del; 20 mod Patch: https://git.openjdk.org/jdk/pull/27999.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27999/head:pull/27999 PR: https://git.openjdk.org/jdk/pull/27999 From vyazici at openjdk.org Tue Oct 28 09:42:17 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Tue, 28 Oct 2025 09:42:17 GMT Subject: RFR: 8363925: Remove unused sun.nio.cs.ArrayEncoder::encode [v4] In-Reply-To: References: Message-ID: <1LfvGeGuRb5HTipmLXl3WOu_f61eXjmWY0nl9Jw29uc=.42bf8be5-486b-4083-b3d9-6103dff1e314@github.com> > [JDK-6636319] introduced `ArrayEncoder`, composed of _only_ `encode` method. Later on [JDK-8054307] (JEP 254: Compact Strings) removed all its usages. This method can safely be removed, hence this PR. Confirmed that `tier1-2` tests are clear on several platforms after changes. > > [JDK-6636319]: https://bugs.openjdk.org/browse/JDK-6636319 > [JDK-8054307]: https://bugs.openjdk.org/browse/JDK-8054307 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: Remove `ArrayEncoder` defaults and add `dp` parameter ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27999/files - new: https://git.openjdk.org/jdk/pull/27999/files/c599d8d3..7fc52675 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27999&range=03 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27999&range=02-03 Stats: 2 lines in 1 file changed: 1 ins; 1 del; 0 mod Patch: https://git.openjdk.org/jdk/pull/27999.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27999/head:pull/27999 PR: https://git.openjdk.org/jdk/pull/27999 From vyazici at openjdk.org Tue Oct 28 09:42:21 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Tue, 28 Oct 2025 09:42:21 GMT Subject: RFR: 8363925: Remove unused sun.nio.cs.ArrayEncoder::encode [v2] In-Reply-To: References: Message-ID: On Mon, 27 Oct 2025 22:59:07 GMT, Chen Liang wrote: >> Volkan Yazici has updated the pull request incrementally with one additional commit since the last revision: >> >> Use `HexFormat` >> >> Co-authored-by: Roger Riggs > > src/java.base/share/classes/sun/nio/cs/CESU_8.java line 1: > >> 1: /* > > The ArrayEncoder interface is now useless here. We should remove it. Very sharp of you! ? Removed in 7fc526759bf. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27999#discussion_r2468746916 From vyazici at openjdk.org Tue Oct 28 09:46:30 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Tue, 28 Oct 2025 09:46:30 GMT Subject: RFR: 8363925: Remove unused sun.nio.cs.ArrayEncoder::encode [v2] In-Reply-To: References: Message-ID: On Mon, 27 Oct 2025 23:02:44 GMT, Chen Liang wrote: >> Volkan Yazici has updated the pull request incrementally with one additional commit since the last revision: >> >> Use `HexFormat` >> >> Co-authored-by: Roger Riggs > > I recommend further refactors, at least turn the 3 default methods to abstract methods. After removal of ineffective CESU_8, we can make the default methods abstract to improve safety. > > Down the road, we can remove the -1 handling at use site, and also pass in dp explicitly (I recall this being useful for optimizing Writer/OutputStream) @liach, thanks so much for the review! ? > I recommend further refactors, at least turn the 3 default methods to abstract methods. > After removal of ineffective CESU_8, we can make the default methods abstract to improve safety. > Down the road, we can remove the -1 handling at use site, and also pass in dp explicitly All done in 7fc526759bf. > I recall this [passing `dp` explicitly] being useful for optimizing Writer/OutputStream Skimmed through `ArrayEncoder::encodeFrom*` call-sites, but could not spot anything particular that can quickly be addressed. Please let me know if there are any changes I can carry out within the scope of this JBS/PR. ------------- PR Comment: https://git.openjdk.org/jdk/pull/27999#issuecomment-3455507136 From liach at openjdk.org Tue Oct 28 14:03:24 2025 From: liach at openjdk.org (Chen Liang) Date: Tue, 28 Oct 2025 14:03:24 GMT Subject: RFR: 8363925: Remove unused sun.nio.cs.ArrayEncoder::encode [v4] In-Reply-To: <1LfvGeGuRb5HTipmLXl3WOu_f61eXjmWY0nl9Jw29uc=.42bf8be5-486b-4083-b3d9-6103dff1e314@github.com> References: <1LfvGeGuRb5HTipmLXl3WOu_f61eXjmWY0nl9Jw29uc=.42bf8be5-486b-4083-b3d9-6103dff1e314@github.com> Message-ID: On Tue, 28 Oct 2025 09:42:17 GMT, Volkan Yazici wrote: >> [JDK-6636319] introduced `ArrayEncoder`, composed of _only_ `encode` method. Later on [JDK-8054307] (JEP 254: Compact Strings) removed all its usages. This method can safely be removed, hence this PR. Confirmed that `tier1-2` tests are clear on several platforms after changes. >> >> [JDK-6636319]: https://bugs.openjdk.org/browse/JDK-6636319 >> [JDK-8054307]: https://bugs.openjdk.org/browse/JDK-8054307 > > 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: > > Remove `ArrayEncoder` defaults and add `dp` parameter Thank you for this great cleanup. Looks much more maintainable and straightforward. We can re-implement for CESU_8 if there is request later. ------------- Marked as reviewed by liach (Reviewer). PR Review: https://git.openjdk.org/jdk/pull/27999#pullrequestreview-3388946460 From sherman at openjdk.org Tue Oct 28 19:58:23 2025 From: sherman at openjdk.org (Xueming Shen) Date: Tue, 28 Oct 2025 19:58:23 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v6] In-Reply-To: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> Message-ID: > ### Summary > > Case folding is a key operation for case-insensitive matching (e.g., string equality, regex matching), where the goal is to eliminate case distinctions without applying locale or language specific conversions. > > Currently, the JDK does not expose a direct API for Unicode-compliant case folding. Developers now rely on methods such as: > > **String.equalsIgnoreCase(String)** > > - Unicode-aware, locale-independent. > - Implementation uses Character.toLowerCase(Character.toUpperCase(int)) per code point. > - Limited: does not support 1:M mapping defined in Unicode case folding. > > **Character.toLowerCase(int) / Character.toUpperCase(int)** > > - Locale-independent, single code point only. > - No support for 1:M mappings. > > **String.toLowerCase(Locale.ROOT) / String.toUpperCase(Locale.ROOT)** > > - Based on Unicode SpecialCasing.txt, supports 1:M mappings. > - Intended primarily for presentation/display, not structural case-insensitive matching. > - Requires full string conversion before comparison, which is less efficient and not intended for structural matching. > > **1:M mapping example, U+00DF (?)** > > - String.toUpperCase(Locale.ROOT, "?") ? "SS" > - Case folding produces "ss", matching Unicode caseless comparison rules. > > > jshell> "\u00df".equalsIgnoreCase("ss") > $22 ==> false > > jshell> "\u00df".toUpperCase(Locale.ROOT).toLowerCase(Locale.ROOT).equals("ss") > $24 ==> true > > > ### Motivation & Direction > > Add Unicode standard-compliant case-less comparison methods to the String class, enabling & improving reliable and efficient Unicode-aware/compliant case-insensitive matching. > > - Unicode-compliant **full** case folding. > - Simpler, stable and more efficient case-less matching without workarounds. > - Brings Java's string comparison handling in line with other programming languages/libraries. > > This PR proposes to introduce the following comparison methods in `String` class > > - boolean equalsFoldCase(String anotherString) > - int compareToFoldCase(String anotherString) > - Comparator UNICODE_CASEFOLD_ORDER > > These methods are intended to be the preferred choice when Unicode-compliant case-less matching is required. > > *Note: An early draft also proposed a String.toCaseFold() method returning a new case-folded string. > However, during review this was considered error-prone, as the resulting string could easily be mistaken for a general transformation like toLowerCase() and then passed into APIs where case-folding semantics are not appropriate. > > ### The New API > > See CSR https://bugs.openjd... Xueming Shen has updated the pull request incrementally with one additional commit since the last revision: small update ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27628/files - new: https://git.openjdk.org/jdk/pull/27628/files/c98543ff..74b4d83e Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27628&range=05 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27628&range=04-05 Stats: 48 lines in 3 files changed: 4 ins; 23 del; 21 mod Patch: https://git.openjdk.org/jdk/pull/27628.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27628/head:pull/27628 PR: https://git.openjdk.org/jdk/pull/27628 From sherman at openjdk.org Tue Oct 28 20:03:36 2025 From: sherman at openjdk.org (Xueming Shen) Date: Tue, 28 Oct 2025 20:03:36 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v4] In-Reply-To: <_5e7Ota89HOgtcpsy4umlfF1EL1f3Xiyt2lmG1gN_DM=.6a3718d0-4cb3-49d6-82ca-16d6ad7bf8bc@github.com> References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> <_5e7Ota89HOgtcpsy4umlfF1EL1f3Xiyt2lmG1gN_DM=.6a3718d0-4cb3-49d6-82ca-16d6ad7bf8bc@github.com> Message-ID: On Wed, 22 Oct 2025 20:28:53 GMT, Roger Riggs wrote: >> Xueming Shen has updated the pull request incrementally with one additional commit since the last revision: >> >> test case update > > make/jdk/src/classes/build/tools/generatecharacter/GenerateCaseFolding.java line 1: > >> (failed to retrieve contents of file, check the PR for context) > Please rename this build tool to avoid ambiguity in the naming of CaseFolding.java. renamed to GenerateCaseFolding.java > src/java.base/share/classes/jdk/internal/lang/CaseFolding.java.template line 1: > >> 1: /* > > Significant performance improvements could be had by handling single (simple) char -> char folding separately avoiding the overhead of iterating over single character arrays. 1:1 mapping and 1:M mapping are handled separate now. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2470873697 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2470879134 From sherman at openjdk.org Tue Oct 28 20:17:49 2025 From: sherman at openjdk.org (Xueming Shen) Date: Tue, 28 Oct 2025 20:17:49 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v6] In-Reply-To: References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> Message-ID: On Sat, 18 Oct 2025 08:50:48 GMT, Xueming Shen wrote: >> src/java.base/share/classes/java/lang/StringLatin1.java line 194: >> >>> 192: char[] folded2 = null; >>> 193: int k1 = 0, k2 = 0, fk1 = 0, fk2 = 0; >>> 194: while ((k1 < len1 || folded1 != null && fk1 < folded1.length) && >> >> Many suggestions come to mind here on the algorithm, to optimize performance. >> For example, many strings will have identical prefixes. Using Arrays.mismatch could quickly skip over the identical prefix. >> Consider using code points (or a long, packing 4 chars) for the folded replacements, to avoid having to step through chars in char arrays. CaseFolding.foldIfDefined could return the full expansion as a long. >> It may be profitable to use Arrays.mismatch again after expanded characters are determined to be equal. >> >> Take another look at the data structure storing and doing the lookup of foldIfDefined both to increase the lookup performance. > > With the following changes > > - Use int[] / code point storage instead of char[] / char for folding data. > - Add a fast path for Latin-1 vs. Latin-1 comparisons. > - Speed up the UTF-16 path as well. > > The only remaining ?slow? path is Latin-1 vs. UTF-16 for now. > Would appreciate some eagle eyes on the new fast-path implementation. The tests suggest it?s working as expected :-) > > **StringCompareToFoldCase.latin1UTF16 avgt 15 23.959 ? 2.357 ns/op > StringCompareToFoldCase.latin1UTF16EQ avgt 15 22.455 ? 0.104 ns/op > StringCompareToFoldCase.latin1UTF16EQFC avgt 15 32.782 ? 0.962 ns/op > StringCompareToFoldCase.latin1UTF16FC avgt 15 32.581 ? 0.725 ns/op** > > > Benchmark Mode Cnt Score Error Units > StringCompareToFoldCase.asciiLower avgt 15 17.983 ? 0.208 ns/op > StringCompareToFoldCase.asciiLowerEQ avgt 15 9.986 ? 0.254 ns/op > StringCompareToFoldCase.asciiLowerEQFC avgt 15 10.781 ? 0.161 ns/op > StringCompareToFoldCase.asciiLowerFC avgt 15 10.274 ? 0.136 ns/op > StringCompareToFoldCase.asciiUpperLower avgt 15 12.465 ? 0.409 ns/op > StringCompareToFoldCase.asciiUpperLowerEQ avgt 15 10.961 ? 0.407 ns/op > StringCompareToFoldCase.asciiUpperLowerEQFC avgt 15 9.157 ? 0.166 ns/op > StringCompareToFoldCase.asciiUpperLowerFC avgt 15 9.228 ? 0.254 ns/op > StringCompareToFoldCase.asciiWithDFFC avgt 15 57.603 ? 1.540 ns/op > StringCompareToFoldCase.greekLower avgt 15 39.593 ? 0.128 ns/op > StringCompareToFoldCase.greekLowerEQ avgt 15 39.249 ? 0.032 ns/op > StringCompareToFoldCase.greekLowerEQFC avgt 15 13.993 ? 0.346 ns/op > StringCompareToFoldCase.greekLowerFC avgt 15 14.030 ? 0.454 ns/op > StringCompareToFoldCase.greekUpperLower avgt 15 7.137 ? 0.130 ns/op > StringCompareToFoldCase.greekUpperLowerEQ avgt 15 7.496 ? 0.104 ns/op > StringCompareToFoldCase.greekUpperLowerEQFC avgt 15 6.203 ? 0.316 ns/op > StringCompareToFoldCase.greekUpperLowerFC avgt 15 6.235 ? 0.256 ns/op > StringCompareToFoldCase.latin1UTF16 avgt 15 23.959 ? 2.357 ns/op > StringCompareToFoldCase.latin1UTF16EQ avgt 15 22.455 ? 0.104 ns/op > StringCompareToFoldCase.latin1UTF16EQFC avgt 15 32.782 ? 0.962 ns/op > StringCompareToFoldCase.latin1UTF16FC avgt 15 32.581 ? 0.725 ns/op > StringCompareToFoldCase.supLower avgt 15 54.918 ? 0.809 ns/op > StringCompa... Experimenting with Arrays.mismatch at the beginning of the array iteration as int k = ArraysSupport.mismatch(value, other, lim); if (k < 0) return len - olen; for (; k < lim; k++) { .... } The benchmark results suggest that it does help 'dramatically' when the compared strings share with the same prefix. For example those "UpperLower" test cases (which shares the same upper cases text prefix. However it is also relatively expensive, with a 20%-ish overhead when the strings do not share the same string text but are case-insensitively equals. I would suggest let's leave it out for now? ### With Arrays.mismatch Benchmark Mode Cnt Score Error Units StringCompareToFoldCase.asciiLower avgt 15 15.044 ? 0.751 ns/op StringCompareToFoldCase.asciiLowerEQ avgt 15 10.033 ? 0.366 ns/op StringCompareToFoldCase.asciiLowerEQFC avgt 15 12.094 ? 0.288 ns/op StringCompareToFoldCase.asciiLowerFC avgt 15 12.513 ? 0.290 ns/op StringCompareToFoldCase.asciiUpperLower avgt 15 11.716 ? 0.471 ns/op StringCompareToFoldCase.asciiUpperLowerEQ avgt 15 11.120 ? 0.458 ns/op StringCompareToFoldCase.asciiUpperLowerEQFC avgt 15 7.544 ? 0.103 ns/op StringCompareToFoldCase.asciiUpperLowerFC avgt 15 7.384 ? 0.167 ns/op StringCompareToFoldCase.asciiWithDFFC avgt 15 54.949 ? 1.260 ns/op StringCompareToFoldCase.greekLower avgt 15 39.492 ? 0.124 ns/op StringCompareToFoldCase.greekLowerEQ avgt 15 39.266 ? 0.071 ns/op StringCompareToFoldCase.greekLowerEQFC avgt 15 28.049 ? 0.292 ns/op StringCompareToFoldCase.greekLowerFC avgt 15 28.272 ? 0.115 ns/op StringCompareToFoldCase.greekUpperLower avgt 15 7.103 ? 0.052 ns/op StringCompareToFoldCase.greekUpperLowerEQ avgt 15 7.439 ? 0.079 ns/op StringCompareToFoldCase.greekUpperLowerEQFC avgt 15 2.716 ? 0.138 ns/op StringCompareToFoldCase.greekUpperLowerFC avgt 15 2.628 ? 0.051 ns/op StringCompareToFoldCase.latin1UTF16 avgt 15 23.147 ? 0.094 ns/op StringCompareToFoldCase.latin1UTF16EQ avgt 15 22.626 ? 0.081 ns/op StringCompareToFoldCase.latin1UTF16EQFC avgt 15 38.453 ? 0.697 ns/op StringCompareToFoldCase.latin1UTF16FC avgt 15 38.464 ? 0.441 ns/op StringCompareToFoldCase.supLower avgt 15 54.443 ? 0.162 ns/op StringCompareToFoldCase.supLowerEQ avgt 15 54.980 ? 0.232 ns/op StringCompareToFoldCase.supLowerEQFC avgt 15 25.552 ? 0.163 ns/op StringCompareToFoldCase.supLowerFC avgt 15 25.477 ? 0.215 ns/op StringCompareToFoldCase.supUpperLower avgt 15 14.525 ? 0.071 ns/op StringCompareToFoldCase.supUpperLowerEQ avgt 15 14.691 ? 0.082 ns/op StringCompareToFoldCase.supUpperLowerEQFC avgt 15 2.748 ? 0.166 ns/op StringCompareToFoldCase.supUpperLowerFC avgt 15 2.616 ? 0.029 ns/op vs ### Without Arrays.mismatch Benchmark Mode Cnt Score Error Units StringCompareToFoldCase.asciiLower avgt 15 15.793 ? 1.080 ns/op StringCompareToFoldCase.asciiLowerEQ avgt 15 9.862 ? 0.221 ns/op StringCompareToFoldCase.asciiLowerEQFC avgt 15 10.681 ? 0.133 ns/op StringCompareToFoldCase.asciiLowerFC avgt 15 10.220 ? 0.105 ns/op StringCompareToFoldCase.asciiUpperLower avgt 15 11.996 ? 0.649 ns/op StringCompareToFoldCase.asciiUpperLowerEQ avgt 15 10.823 ? 0.353 ns/op StringCompareToFoldCase.asciiUpperLowerEQFC avgt 15 9.199 ? 0.347 ns/op StringCompareToFoldCase.asciiUpperLowerFC avgt 15 9.033 ? 0.144 ns/op StringCompareToFoldCase.asciiWithDFFC avgt 15 54.892 ? 1.049 ns/op StringCompareToFoldCase.greekLower avgt 15 39.568 ? 0.107 ns/op StringCompareToFoldCase.greekLowerEQ avgt 15 39.287 ? 0.068 ns/op StringCompareToFoldCase.greekLowerEQFC avgt 15 22.800 ? 0.347 ns/op StringCompareToFoldCase.greekLowerFC avgt 15 22.794 ? 0.317 ns/op StringCompareToFoldCase.greekUpperLower avgt 15 7.147 ? 0.072 ns/op StringCompareToFoldCase.greekUpperLowerEQ avgt 15 7.499 ? 0.106 ns/op StringCompareToFoldCase.greekUpperLowerEQFC avgt 15 6.958 ? 0.204 ns/op StringCompareToFoldCase.greekUpperLowerFC avgt 15 7.179 ? 0.188 ns/op StringCompareToFoldCase.latin1UTF16 avgt 15 25.787 ? 1.940 ns/op StringCompareToFoldCase.latin1UTF16EQ avgt 15 22.602 ? 0.106 ns/op StringCompareToFoldCase.latin1UTF16EQFC avgt 15 31.317 ? 0.668 ns/op StringCompareToFoldCase.latin1UTF16FC avgt 15 30.881 ? 0.622 ns/op StringCompareToFoldCase.supLower avgt 15 55.771 ? 0.718 ns/op StringCompareToFoldCase.supLowerEQ avgt 15 55.444 ? 0.535 ns/op StringCompareToFoldCase.supLowerEQFC avgt 15 31.180 ? 0.184 ns/op StringCompareToFoldCase.supLowerFC avgt 15 31.269 ? 0.465 ns/op StringCompareToFoldCase.supUpperLower avgt 15 14.386 ? 0.150 ns/op StringCompareToFoldCase.supUpperLowerEQ avgt 15 14.780 ? 0.104 ns/op StringCompareToFoldCase.supUpperLowerEQFC avgt 15 13.733 ? 0.284 ns/op StringCompareToFoldCase.supUpperLowerFC avgt 15 13.607 ? 0.166 ns/op ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2470912393 From rriggs at openjdk.org Tue Oct 28 21:41:36 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Tue, 28 Oct 2025 21:41:36 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v4] In-Reply-To: References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> <_5e7Ota89HOgtcpsy4umlfF1EL1f3Xiyt2lmG1gN_DM=.6a3718d0-4cb3-49d6-82ca-16d6ad7bf8bc@github.com> Message-ID: <9RLqVMEBDHHgSW9aK0CJ51z7e8ef5BU9iTU7NRF4NjA=.e751cbeb-c3a5-4dc9-8504-514c966c3762@github.com> On Mon, 27 Oct 2025 09:40:03 GMT, Xueming Shen wrote: >> src/java.base/share/classes/java/lang/StringLatin1.java line 217: >> >>> 215: if (c1 != c2) { >>> 216: return c1 - c2; >>> 217: } >> >> Compute difference only once. >> Suggestion: >> >> if ((c1 - c2) != 0) { >> return c1 - c2; >> } > > you meant go with > > if ((c1 - c2) != 0) { > return c1 - c2; > } ? Yes, it might be an inconsequential difference but directly computes the difference and returns if not-equal. >> src/java.base/share/classes/java/lang/StringUTF16.java line 605: >> >>> 603: int k1 = off, k2 = ooff, fk1 = 0, fk2 = 0; >>> 604: while ((k1 < last || folded1 != null && fk1 < folded1.length) && >>> 605: (k2 < olast || folded2 != null && fk2 < folded2.length)) { >> >> Use ArraySupport.mismatch to quickly scan past identical sequences. (byte index will need to be converted to char index). > > seems like we are only using it for case-aware comparison in existing string comparison. just wonder do we really want to apply this for the case insensitive comparision? > > static int compareTo(byte[] value, byte[] other, int len1, int len2) { > int lim = Math.min(len1, len2); > int k = ArraysSupport.mismatch(value, other, lim); > return (k < 0) ? len1 - len2 : getChar(value, k) - getChar(other, k); > } I expect most strings will be predominated by normal (not folded) strings, the use of mismatch can rapidly skip over identical strings to find the start of bytes/characters that need to be checked for folding. I would think it would help speed up the case-sensitive comparisons too. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2471124837 PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2471118690 From swen at openjdk.org Wed Oct 29 01:31:25 2025 From: swen at openjdk.org (Shaojin Wen) Date: Wed, 29 Oct 2025 01:31:25 GMT Subject: Integrated: 8368172: Make java.time.format.DateTimePrintContext immutable In-Reply-To: <5xcmzM6BhoL-zhBZc_TrRSDCKBrOMqq8bRcmihc1zpU=.732bd228-f9ff-43f0-9771-56645dab6cd2@github.com> References: <5xcmzM6BhoL-zhBZc_TrRSDCKBrOMqq8bRcmihc1zpU=.732bd228-f9ff-43f0-9771-56645dab6cd2@github.com> Message-ID: On Sat, 23 Aug 2025 11:27:55 GMT, Shaojin Wen wrote: > I propose to make j.t.f.DateTimePrintContext immutable. > > Currently, DateTimePrintContext has only one mutable field, optional. This can be replaced by adding an optional parameter to the DateTimeFormatter.formatTo method. > > Immutable DateTimePrintContext can be optimized by escape analysis, such as immutable object optimization. This pull request has now been integrated. Changeset: a588c120 Author: Shaojin Wen URL: https://git.openjdk.org/jdk/commit/a588c120fc2ec9d5c59c43cda7f247e0a84981ff Stats: 88 lines in 3 files changed: 9 ins; 32 del; 47 mod 8368172: Make java.time.format.DateTimePrintContext immutable Reviewed-by: liach ------------- PR: https://git.openjdk.org/jdk/pull/26913 From sherman at openjdk.org Wed Oct 29 02:03:14 2025 From: sherman at openjdk.org (Xueming Shen) Date: Wed, 29 Oct 2025 02:03:14 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v6] In-Reply-To: References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> Message-ID: On Tue, 28 Oct 2025 20:15:26 GMT, Xueming Shen wrote: >> With the following changes >> >> - Use int[] / code point storage instead of char[] / char for folding data. >> - Add a fast path for Latin-1 vs. Latin-1 comparisons. >> - Speed up the UTF-16 path as well. >> >> The only remaining ?slow? path is Latin-1 vs. UTF-16 for now. >> Would appreciate some eagle eyes on the new fast-path implementation. The tests suggest it?s working as expected :-) >> >> **StringCompareToFoldCase.latin1UTF16 avgt 15 23.959 ? 2.357 ns/op >> StringCompareToFoldCase.latin1UTF16EQ avgt 15 22.455 ? 0.104 ns/op >> StringCompareToFoldCase.latin1UTF16EQFC avgt 15 32.782 ? 0.962 ns/op >> StringCompareToFoldCase.latin1UTF16FC avgt 15 32.581 ? 0.725 ns/op** >> >> >> Benchmark Mode Cnt Score Error Units >> StringCompareToFoldCase.asciiLower avgt 15 17.983 ? 0.208 ns/op >> StringCompareToFoldCase.asciiLowerEQ avgt 15 9.986 ? 0.254 ns/op >> StringCompareToFoldCase.asciiLowerEQFC avgt 15 10.781 ? 0.161 ns/op >> StringCompareToFoldCase.asciiLowerFC avgt 15 10.274 ? 0.136 ns/op >> StringCompareToFoldCase.asciiUpperLower avgt 15 12.465 ? 0.409 ns/op >> StringCompareToFoldCase.asciiUpperLowerEQ avgt 15 10.961 ? 0.407 ns/op >> StringCompareToFoldCase.asciiUpperLowerEQFC avgt 15 9.157 ? 0.166 ns/op >> StringCompareToFoldCase.asciiUpperLowerFC avgt 15 9.228 ? 0.254 ns/op >> StringCompareToFoldCase.asciiWithDFFC avgt 15 57.603 ? 1.540 ns/op >> StringCompareToFoldCase.greekLower avgt 15 39.593 ? 0.128 ns/op >> StringCompareToFoldCase.greekLowerEQ avgt 15 39.249 ? 0.032 ns/op >> StringCompareToFoldCase.greekLowerEQFC avgt 15 13.993 ? 0.346 ns/op >> StringCompareToFoldCase.greekLowerFC avgt 15 14.030 ? 0.454 ns/op >> StringCompareToFoldCase.greekUpperLower avgt 15 7.137 ? 0.130 ns/op >> StringCompareToFoldCase.greekUpperLowerEQ avgt 15 7.496 ? 0.104 ns/op >> StringCompareToFoldCase.greekUpperLowerEQFC avgt 15 6.203 ? 0.316 ns/op >> StringCompareToFoldCase.greekUpperLowerFC avgt 15 6.235 ? 0.256 ns/op >> StringCompareToFoldCase.latin1UTF16 avgt 15 23.959 ? 2.357 ns/op >> StringCompareToFoldCase.latin1UTF16EQ avgt 15 22.455 ? 0.104 ns/op >> StringCompareToFoldCase.latin1UTF16EQFC avgt 15 32.782 ? 0.962 ns/op >> StringCompareToFoldCase.latin1UTF16FC avgt 15 32.581 ? 0.725 ns/op >> StringCompare... > > Experimenting with Arrays.mismatch at the beginning of the array iteration as > > > int k = ArraysSupport.mismatch(value, other, lim); > if (k < 0) > return len - olen; > for (; k < lim; k++) { > .... > } > > > The benchmark results suggest that it does help 'dramatically' when the compared strings share with the same prefix. For example those "UpperLower" test cases (which shares the same upper cases text prefix. However it is also relatively expensive, with a 20%-ish overhead when the strings do not share the same string text but are case-insensitively equals. I would suggest let's leave it out for now? > > ### With Arrays.mismatch > > > Benchmark Mode Cnt Score Error Units > StringCompareToFoldCase.asciiLower avgt 15 15.044 ? 0.751 ns/op > StringCompareToFoldCase.asciiLowerEQ avgt 15 10.033 ? 0.366 ns/op > StringCompareToFoldCase.asciiLowerEQFC avgt 15 12.094 ? 0.288 ns/op > StringCompareToFoldCase.asciiLowerFC avgt 15 12.513 ? 0.290 ns/op > StringCompareToFoldCase.asciiUpperLower avgt 15 11.716 ? 0.471 ns/op > StringCompareToFoldCase.asciiUpperLowerEQ avgt 15 11.120 ? 0.458 ns/op > StringCompareToFoldCase.asciiUpperLowerEQFC avgt 15 7.544 ? 0.103 ns/op > StringCompareToFoldCase.asciiUpperLowerFC avgt 15 7.384 ? 0.167 ns/op > StringCompareToFoldCase.asciiWithDFFC avgt 15 54.949 ? 1.260 ns/op > StringCompareToFoldCase.greekLower avgt 15 39.492 ? 0.124 ns/op > StringCompareToFoldCase.greekLowerEQ avgt 15 39.266 ? 0.071 ns/op > StringCompareToFoldCase.greekLowerEQFC avgt 15 28.049 ? 0.292 ns/op > StringCompareToFoldCase.greekLowerFC avgt 15 28.272 ? 0.115 ns/op > StringCompareToFoldCase.greekUpperLower avgt 15 7.103 ? 0.052 ns/op > StringCompareToFoldCase.greekUpperLowerEQ avgt 15 7.439 ? 0.079 ns/op > StringCompareToFoldCase.greekUpperLowerEQFC avgt 15 2.716 ? 0.138 ns/op > StringCompareToFoldCase.greekUpperLowerFC avgt 15 2.628 ? 0.051 ns/op > StringCompareToFoldCase.latin1UTF16 avgt 15 23.147 ? 0.094 ns/op > StringCompareToFoldCase.latin1UTF16EQ avgt 15 22.626 ? 0.081 ns/op > StringCompareToFoldCase.latin1UTF16EQFC avgt 15 38.453 ? 0.697 ns/op > StringCompareToFoldCase.latin1UTF16FC avgt 15 38.464 ? 0.441 ns/op > StringCompareToFoldCase.supLower avgt 15 54.443 ? 0.162 ns/op > StringCompareToFoldCase.... ### Long: packing 1:M-count + 1-3 folding codepoints https://cr.openjdk.org/~sherman/casefolding_long/ The performance is slightly better, but not as good as I would have expected. The access to codepoint from the long looks a little clumsy, but the logic looks smooth. need more work. opinion? Benchmark Mode Cnt Score Error Units StringCompareToFoldCase.asciiLower avgt 15 15.487 ? 0.298 ns/op StringCompareToFoldCase.asciiLowerEQ avgt 15 10.005 ? 0.368 ns/op StringCompareToFoldCase.asciiLowerEQFC avgt 15 10.755 ? 0.160 ns/op StringCompareToFoldCase.asciiLowerFC avgt 15 10.349 ? 0.155 ns/op StringCompareToFoldCase.asciiUpperLower avgt 15 12.188 ? 0.278 ns/op StringCompareToFoldCase.asciiUpperLowerEQ avgt 15 10.901 ? 0.551 ns/op StringCompareToFoldCase.asciiUpperLowerEQFC avgt 15 9.218 ? 0.165 ns/op StringCompareToFoldCase.asciiUpperLowerFC avgt 15 9.335 ? 0.404 ns/op StringCompareToFoldCase.asciiWithDFFC avgt 15 37.010 ? 0.518 ns/op StringCompareToFoldCase.greekLower avgt 15 39.572 ? 0.098 ns/op StringCompareToFoldCase.greekLowerEQ avgt 15 39.317 ? 0.104 ns/op StringCompareToFoldCase.greekLowerEQFC avgt 15 20.428 ? 0.243 ns/op StringCompareToFoldCase.greekLowerFC avgt 15 19.623 ? 0.141 ns/op StringCompareToFoldCase.greekUpperLower avgt 15 7.105 ? 0.048 ns/op StringCompareToFoldCase.greekUpperLowerEQ avgt 15 7.462 ? 0.092 ns/op StringCompareToFoldCase.greekUpperLowerEQFC avgt 15 6.518 ? 0.128 ns/op StringCompareToFoldCase.greekUpperLowerFC avgt 15 6.593 ? 0.240 ns/op StringCompareToFoldCase.latin1UTF16 avgt 15 23.130 ? 0.152 ns/op StringCompareToFoldCase.latin1UTF16EQ avgt 15 22.606 ? 0.089 ns/op StringCompareToFoldCase.latin1UTF16EQFC avgt 15 29.574 ? 0.348 ns/op StringCompareToFoldCase.latin1UTF16FC avgt 15 29.691 ? 0.445 ns/op StringCompareToFoldCase.supLower avgt 15 55.027 ? 0.676 ns/op StringCompareToFoldCase.supLowerEQ avgt 15 55.784 ? 0.368 ns/op StringCompareToFoldCase.supLowerEQFC avgt 15 24.984 ? 0.157 ns/op StringCompareToFoldCase.supLowerFC avgt 15 24.865 ? 0.139 ns/op StringCompareToFoldCase.supUpperLower avgt 15 14.538 ? 0.144 ns/op StringCompareToFoldCase.supUpperLowerEQ avgt 15 14.728 ? 0.206 ns/op StringCompareToFoldCase.supUpperLowerEQFC avgt 15 9.932 ? 0.121 ns/op StringCompareToFoldCase.supUpperLowerFC avgt 15 9.870 ? 0.119 ns/op ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2471532292 From sherman at openjdk.org Wed Oct 29 07:37:06 2025 From: sherman at openjdk.org (Xueming Shen) Date: Wed, 29 Oct 2025 07:37:06 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v4] In-Reply-To: <_5e7Ota89HOgtcpsy4umlfF1EL1f3Xiyt2lmG1gN_DM=.6a3718d0-4cb3-49d6-82ca-16d6ad7bf8bc@github.com> References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> <_5e7Ota89HOgtcpsy4umlfF1EL1f3Xiyt2lmG1gN_DM=.6a3718d0-4cb3-49d6-82ca-16d6ad7bf8bc@github.com> Message-ID: On Wed, 22 Oct 2025 20:40:32 GMT, Roger Riggs wrote: >> Xueming Shen has updated the pull request incrementally with one additional commit since the last revision: >> >> test case update > > src/java.base/share/classes/java/lang/StringLatin1.java line 70: > >> 68: return value[index] & 0xff; >> 69: } >> 70: > > Seems to be unused and is identical to `getChar` removed ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2471995749 From vyazici at openjdk.org Wed Oct 29 10:04:32 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Wed, 29 Oct 2025 10:04:32 GMT Subject: RFR: 8363925: Remove unused sun.nio.cs.ArrayEncoder::encode [v4] In-Reply-To: <1LfvGeGuRb5HTipmLXl3WOu_f61eXjmWY0nl9Jw29uc=.42bf8be5-486b-4083-b3d9-6103dff1e314@github.com> References: <1LfvGeGuRb5HTipmLXl3WOu_f61eXjmWY0nl9Jw29uc=.42bf8be5-486b-4083-b3d9-6103dff1e314@github.com> Message-ID: On Tue, 28 Oct 2025 09:42:17 GMT, Volkan Yazici wrote: >> [JDK-6636319] introduced `ArrayEncoder`, composed of _only_ `encode` method. Later on [JDK-8054307] (JEP 254: Compact Strings) removed all its usages. This method can safely be removed, hence this PR. Confirmed that `tier1-2` tests are clear on several platforms after changes. >> >> [JDK-6636319]: https://bugs.openjdk.org/browse/JDK-6636319 >> [JDK-8054307]: https://bugs.openjdk.org/browse/JDK-8054307 > > 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: > > Remove `ArrayEncoder` defaults and add `dp` parameter Tier1-2 is clear on 7fc526759bf. ------------- PR Comment: https://git.openjdk.org/jdk/pull/27999#issuecomment-3460666492 From vyazici at openjdk.org Wed Oct 29 10:04:33 2025 From: vyazici at openjdk.org (Volkan Yazici) Date: Wed, 29 Oct 2025 10:04:33 GMT Subject: Integrated: 8363925: Remove unused sun.nio.cs.ArrayEncoder::encode In-Reply-To: References: Message-ID: On Mon, 27 Oct 2025 11:42:20 GMT, Volkan Yazici wrote: > [JDK-6636319] introduced `ArrayEncoder`, composed of _only_ `encode` method. Later on [JDK-8054307] (JEP 254: Compact Strings) removed all its usages. This method can safely be removed, hence this PR. Confirmed that `tier1-2` tests are clear on several platforms after changes. > > [JDK-6636319]: https://bugs.openjdk.org/browse/JDK-6636319 > [JDK-8054307]: https://bugs.openjdk.org/browse/JDK-8054307 This pull request has now been integrated. Changeset: bbe5e83c Author: Volkan Yazici URL: https://git.openjdk.org/jdk/commit/bbe5e83c3910dc4986a1dccf6fcf31d15710c71d Stats: 293 lines in 9 files changed: 62 ins; 193 del; 38 mod 8363925: Remove unused sun.nio.cs.ArrayEncoder::encode Reviewed-by: liach ------------- PR: https://git.openjdk.org/jdk/pull/27999 From rriggs at openjdk.org Wed Oct 29 20:44:01 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Wed, 29 Oct 2025 20:44:01 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v6] In-Reply-To: References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> Message-ID: On Wed, 29 Oct 2025 02:00:16 GMT, Xueming Shen wrote: >> Experimenting with Arrays.mismatch at the beginning of the array iteration as >> >> >> int k = ArraysSupport.mismatch(value, other, lim); >> if (k < 0) >> return len - olen; >> for (; k < lim; k++) { >> .... >> } >> >> >> The benchmark results suggest that it does help 'dramatically' when the compared strings share with the same prefix. For example those "UpperLower" test cases (which shares the same upper cases text prefix. However it is also relatively expensive, with a 20%-ish overhead when the strings do not share the same string text but are case-insensitively equals. I would suggest let's leave it out for now? >> >> ### With Arrays.mismatch >> >> >> Benchmark Mode Cnt Score Error Units >> StringCompareToFoldCase.asciiLower avgt 15 15.044 ? 0.751 ns/op >> StringCompareToFoldCase.asciiLowerEQ avgt 15 10.033 ? 0.366 ns/op >> StringCompareToFoldCase.asciiLowerEQFC avgt 15 12.094 ? 0.288 ns/op >> StringCompareToFoldCase.asciiLowerFC avgt 15 12.513 ? 0.290 ns/op >> StringCompareToFoldCase.asciiUpperLower avgt 15 11.716 ? 0.471 ns/op >> StringCompareToFoldCase.asciiUpperLowerEQ avgt 15 11.120 ? 0.458 ns/op >> StringCompareToFoldCase.asciiUpperLowerEQFC avgt 15 7.544 ? 0.103 ns/op >> StringCompareToFoldCase.asciiUpperLowerFC avgt 15 7.384 ? 0.167 ns/op >> StringCompareToFoldCase.asciiWithDFFC avgt 15 54.949 ? 1.260 ns/op >> StringCompareToFoldCase.greekLower avgt 15 39.492 ? 0.124 ns/op >> StringCompareToFoldCase.greekLowerEQ avgt 15 39.266 ? 0.071 ns/op >> StringCompareToFoldCase.greekLowerEQFC avgt 15 28.049 ? 0.292 ns/op >> StringCompareToFoldCase.greekLowerFC avgt 15 28.272 ? 0.115 ns/op >> StringCompareToFoldCase.greekUpperLower avgt 15 7.103 ? 0.052 ns/op >> StringCompareToFoldCase.greekUpperLowerEQ avgt 15 7.439 ? 0.079 ns/op >> StringCompareToFoldCase.greekUpperLowerEQFC avgt 15 2.716 ? 0.138 ns/op >> StringCompareToFoldCase.greekUpperLowerFC avgt 15 2.628 ? 0.051 ns/op >> StringCompareToFoldCase.latin1UTF16 avgt 15 23.147 ? 0.094 ns/op >> StringCompareToFoldCase.latin1UTF16EQ avgt 15 22.626 ? 0.081 ns/op >> StringCompareToFoldCase.latin1UTF16EQFC avgt 15 38.453 ? 0.697 ns/op >> StringCompareToFoldCase.latin1UTF16FC avgt 15 38.464 ? 0.441 ns/op >> StringCompareToFoldCase.... > > ### Long: packing 1:M-count + 1-3 folding codepoints > > https://cr.openjdk.org/~sherman/casefolding_long/ > > The performance is slightly better, but not as good as I would have expected. The access to codepoint from the long looks a little clumsy, but the logic looks smooth. need more work. opinion? > > > Benchmark Mode Cnt Score Error Units > StringCompareToFoldCase.asciiLower avgt 15 15.487 ? 0.298 ns/op > StringCompareToFoldCase.asciiLowerEQ avgt 15 10.005 ? 0.368 ns/op > StringCompareToFoldCase.asciiLowerEQFC avgt 15 10.755 ? 0.160 ns/op > StringCompareToFoldCase.asciiLowerFC avgt 15 10.349 ? 0.155 ns/op > StringCompareToFoldCase.asciiUpperLower avgt 15 12.188 ? 0.278 ns/op > StringCompareToFoldCase.asciiUpperLowerEQ avgt 15 10.901 ? 0.551 ns/op > StringCompareToFoldCase.asciiUpperLowerEQFC avgt 15 9.218 ? 0.165 ns/op > StringCompareToFoldCase.asciiUpperLowerFC avgt 15 9.335 ? 0.404 ns/op > StringCompareToFoldCase.asciiWithDFFC avgt 15 37.010 ? 0.518 ns/op > StringCompareToFoldCase.greekLower avgt 15 39.572 ? 0.098 ns/op > StringCompareToFoldCase.greekLowerEQ avgt 15 39.317 ? 0.104 ns/op > StringCompareToFoldCase.greekLowerEQFC avgt 15 20.428 ? 0.243 ns/op > StringCompareToFoldCase.greekLowerFC avgt 15 19.623 ? 0.141 ns/op > StringCompareToFoldCase.greekUpperLower avgt 15 7.105 ? 0.048 ns/op > StringCompareToFoldCase.greekUpperLowerEQ avgt 15 7.462 ? 0.092 ns/op > StringCompareToFoldCase.greekUpperLowerEQFC avgt 15 6.518 ? 0.128 ns/op > StringCompareToFoldCase.greekUpperLowerFC avgt 15 6.593 ? 0.240 ns/op > StringCompareToFoldCase.latin1UTF16 avgt 15 23.130 ? 0.152 ns/op > StringCompareToFoldCase.latin1UTF16EQ avgt 15 22.606 ? 0.089 ns/op > StringCompareToFoldCase.latin1UTF16EQFC avgt 15 29.574 ? 0.348 ns/op > StringCompareToFoldCase.latin1UTF16FC avgt 15 29.691 ? 0.445 ns/op > StringCompareToFoldCase.supLower avgt 15 55.027 ? 0.676 ns/op > StringCompareToFoldCase.supLowerEQ avgt 15 55.784 ? 0.368 ns/op > StringCompareToFoldCase.supLowerEQFC avgt 15 24.984 ? 0.157 ns/op > StringCompareToFoldCase.supLowerFC avgt 15 24.865 ? 0.139 ns/op > StringCompareToFoldCase.supUpperLower avgt 15 14.538 ? 0.144 ns/op > StringCompareToFoldCase.supUpperLowerEQ avgt 15 14.728 ? 0.206 ns/op > StringCompareT... > Experimenting with Arrays.mismatch at the beginning of the array iteration as > ... > The benchmark results suggest that it does help 'dramatically' when the compared strings share with the same prefix. For example those "UpperLower" test cases (which shares the same upper cases text prefix. However it is also relatively expensive, with a 20%-ish overhead when the strings do not share the same string text but are case-insensitively equals. I would suggest let's leave it out for now? > ``` Ok to leave it out for now. In similar contexts where System.arraycopy or Arrays.mismatch has some overhead I've suggested doing a simple check (like `size < 8`) to avoid the overhead when the strings/byte arrays are short. Thanks for checking. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2475377160 From rriggs at openjdk.org Wed Oct 29 21:09:33 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Wed, 29 Oct 2025 21:09:33 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v6] In-Reply-To: References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> Message-ID: <8vnnaDLbpvjdSdANjw2p_i_xvu7X8mqkNexoDPSyzE4=.c274163d-1b2e-4b9a-a6c0-e22e5aacd3cd@github.com> On Wed, 29 Oct 2025 20:41:06 GMT, Roger Riggs wrote: >> ### Long: packing 1:M-count + 1-3 folding codepoints >> >> https://cr.openjdk.org/~sherman/casefolding_long/ >> >> The performance is slightly better, but not as good as I would have expected. The access to codepoint from the long looks a little clumsy, but the logic looks smooth. need more work. opinion? >> >> >> Benchmark Mode Cnt Score Error Units >> StringCompareToFoldCase.asciiLower avgt 15 15.487 ? 0.298 ns/op >> StringCompareToFoldCase.asciiLowerEQ avgt 15 10.005 ? 0.368 ns/op >> StringCompareToFoldCase.asciiLowerEQFC avgt 15 10.755 ? 0.160 ns/op >> StringCompareToFoldCase.asciiLowerFC avgt 15 10.349 ? 0.155 ns/op >> StringCompareToFoldCase.asciiUpperLower avgt 15 12.188 ? 0.278 ns/op >> StringCompareToFoldCase.asciiUpperLowerEQ avgt 15 10.901 ? 0.551 ns/op >> StringCompareToFoldCase.asciiUpperLowerEQFC avgt 15 9.218 ? 0.165 ns/op >> StringCompareToFoldCase.asciiUpperLowerFC avgt 15 9.335 ? 0.404 ns/op >> StringCompareToFoldCase.asciiWithDFFC avgt 15 37.010 ? 0.518 ns/op >> StringCompareToFoldCase.greekLower avgt 15 39.572 ? 0.098 ns/op >> StringCompareToFoldCase.greekLowerEQ avgt 15 39.317 ? 0.104 ns/op >> StringCompareToFoldCase.greekLowerEQFC avgt 15 20.428 ? 0.243 ns/op >> StringCompareToFoldCase.greekLowerFC avgt 15 19.623 ? 0.141 ns/op >> StringCompareToFoldCase.greekUpperLower avgt 15 7.105 ? 0.048 ns/op >> StringCompareToFoldCase.greekUpperLowerEQ avgt 15 7.462 ? 0.092 ns/op >> StringCompareToFoldCase.greekUpperLowerEQFC avgt 15 6.518 ? 0.128 ns/op >> StringCompareToFoldCase.greekUpperLowerFC avgt 15 6.593 ? 0.240 ns/op >> StringCompareToFoldCase.latin1UTF16 avgt 15 23.130 ? 0.152 ns/op >> StringCompareToFoldCase.latin1UTF16EQ avgt 15 22.606 ? 0.089 ns/op >> StringCompareToFoldCase.latin1UTF16EQFC avgt 15 29.574 ? 0.348 ns/op >> StringCompareToFoldCase.latin1UTF16FC avgt 15 29.691 ? 0.445 ns/op >> StringCompareToFoldCase.supLower avgt 15 55.027 ? 0.676 ns/op >> StringCompareToFoldCase.supLowerEQ avgt 15 55.784 ? 0.368 ns/op >> StringCompareToFoldCase.supLowerEQFC avgt 15 24.984 ? 0.157 ns/op >> StringCompareToFoldCase.supLowerFC avgt 15 24.865 ? 0.139 ns/op >> StringCompareToFoldCase.supUpperLower avgt 15 14.538 ? 0.144 ns/op >> StringCompareToFoldCas... > >> Experimenting with Arrays.mismatch at the beginning of the array iteration as >> ... >> The benchmark results suggest that it does help 'dramatically' when the compared strings share with the same prefix. For example those "UpperLower" test cases (which shares the same upper cases text prefix. However it is also relatively expensive, with a 20%-ish overhead when the strings do not share the same string text but are case-insensitively equals. I would suggest let's leave it out for now? > >> ``` > Ok to leave it out for now. In similar contexts where System.arraycopy or Arrays.mismatch has some overhead I've suggested doing a simple check (like `size < 8`) to avoid the overhead when the strings/byte arrays are short. > Thanks for checking. > The performance is slightly better, but not as good as I would have expected. The access to codepoint from the long looks a little clumsy, but the logic looks smooth. need more work. opinion? It does look cleaner without the array indexing in the loops. Can the counting of characters (fcnt1,fcnt2) be eliminated by encoding 3 20-bit characters into the long and then checking `f1 != 0` to indicate there are more characters. Its a bit of an odd mix of 16-bit characters vs a single 20-bit char. Are there any 20-bit chars from or to folded replacements in the folding mappings? ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2475481372 From sherman at openjdk.org Thu Oct 30 02:59:45 2025 From: sherman at openjdk.org (Xueming Shen) Date: Thu, 30 Oct 2025 02:59:45 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v7] In-Reply-To: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> Message-ID: > ### Summary > > Case folding is a key operation for case-insensitive matching (e.g., string equality, regex matching), where the goal is to eliminate case distinctions without applying locale or language specific conversions. > > Currently, the JDK does not expose a direct API for Unicode-compliant case folding. Developers now rely on methods such as: > > **String.equalsIgnoreCase(String)** > > - Unicode-aware, locale-independent. > - Implementation uses Character.toLowerCase(Character.toUpperCase(int)) per code point. > - Limited: does not support 1:M mapping defined in Unicode case folding. > > **Character.toLowerCase(int) / Character.toUpperCase(int)** > > - Locale-independent, single code point only. > - No support for 1:M mappings. > > **String.toLowerCase(Locale.ROOT) / String.toUpperCase(Locale.ROOT)** > > - Based on Unicode SpecialCasing.txt, supports 1:M mappings. > - Intended primarily for presentation/display, not structural case-insensitive matching. > - Requires full string conversion before comparison, which is less efficient and not intended for structural matching. > > **1:M mapping example, U+00DF (?)** > > - String.toUpperCase(Locale.ROOT, "?") ? "SS" > - Case folding produces "ss", matching Unicode caseless comparison rules. > > > jshell> "\u00df".equalsIgnoreCase("ss") > $22 ==> false > > jshell> "\u00df".toUpperCase(Locale.ROOT).toLowerCase(Locale.ROOT).equals("ss") > $24 ==> true > > > ### Motivation & Direction > > Add Unicode standard-compliant case-less comparison methods to the String class, enabling & improving reliable and efficient Unicode-aware/compliant case-insensitive matching. > > - Unicode-compliant **full** case folding. > - Simpler, stable and more efficient case-less matching without workarounds. > - Brings Java's string comparison handling in line with other programming languages/libraries. > > This PR proposes to introduce the following comparison methods in `String` class > > - boolean equalsFoldCase(String anotherString) > - int compareToFoldCase(String anotherString) > - Comparator UNICODE_CASEFOLD_ORDER > > These methods are intended to be the preferred choice when Unicode-compliant case-less matching is required. > > *Note: An early draft also proposed a String.toCaseFold() method returning a new case-folded string. > However, during review this was considered error-prone, as the resulting string could easily be mistaken for a general transformation like toLowerCase() and then passed into APIs where case-folding semantics are not appropriate. > > ### The New API > > See CSR https://bugs.openjd... Xueming Shen has updated the pull request incrementally with one additional commit since the last revision: update to use value long for folding ------------- Changes: - all: https://git.openjdk.org/jdk/pull/27628/files - new: https://git.openjdk.org/jdk/pull/27628/files/74b4d83e..c21de111 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=27628&range=06 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=27628&range=05-06 Stats: 166 lines in 5 files changed: 56 ins; 28 del; 82 mod Patch: https://git.openjdk.org/jdk/pull/27628.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/27628/head:pull/27628 PR: https://git.openjdk.org/jdk/pull/27628 From sherman at openjdk.org Thu Oct 30 03:03:08 2025 From: sherman at openjdk.org (Xueming Shen) Date: Thu, 30 Oct 2025 03:03:08 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v7] In-Reply-To: <8vnnaDLbpvjdSdANjw2p_i_xvu7X8mqkNexoDPSyzE4=.c274163d-1b2e-4b9a-a6c0-e22e5aacd3cd@github.com> References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> <8vnnaDLbpvjdSdANjw2p_i_xvu7X8mqkNexoDPSyzE4=.c274163d-1b2e-4b9a-a6c0-e22e5aacd3cd@github.com> Message-ID: On Wed, 29 Oct 2025 21:07:03 GMT, Roger Riggs wrote: >>> Experimenting with Arrays.mismatch at the beginning of the array iteration as >>> ... >>> The benchmark results suggest that it does help 'dramatically' when the compared strings share with the same prefix. For example those "UpperLower" test cases (which shares the same upper cases text prefix. However it is also relatively expensive, with a 20%-ish overhead when the strings do not share the same string text but are case-insensitively equals. I would suggest let's leave it out for now? >> >>> ``` >> Ok to leave it out for now. In similar contexts where System.arraycopy or Arrays.mismatch has some overhead I've suggested doing a simple check (like `size < 8`) to avoid the overhead when the strings/byte arrays are short. >> Thanks for checking. > >> The performance is slightly better, but not as good as I would have expected. The access to codepoint from the long looks a little clumsy, but the logic looks smooth. need more work. opinion? > It does look cleaner without the array indexing in the loops. > Can the counting of characters (fcnt1,fcnt2) be eliminated by encoding 3 20-bit characters into the long and then checking `f1 != 0` to indicate there are more characters. Its a bit of an odd mix of 16-bit characters vs a single 20-bit char. Are there any 20-bit chars from or to folded replacements in the folding mappings? Good idea. After removing the fcnt the implementation looks much cleaner and more straightforward. The1:m folding implementation is also faster. Maybe this is good enough to. go :-) The latest numbers Benchmark Mode Cnt Score Error Units StringCompareToFoldCase.asciiLower avgt 15 15.874 ? 1.276 ns/op StringCompareToFoldCase.asciiLowerEQ avgt 15 9.915 ? 0.242 ns/op StringCompareToFoldCase.asciiLowerEQFC avgt 15 10.751 ? 0.219 ns/op StringCompareToFoldCase.asciiLowerFC avgt 15 10.277 ? 0.126 ns/op StringCompareToFoldCase.asciiUpperLower avgt 15 12.121 ? 0.699 ns/op StringCompareToFoldCase.asciiUpperLowerEQ avgt 15 10.836 ? 0.746 ns/op StringCompareToFoldCase.asciiUpperLowerEQFC avgt 15 9.091 ? 0.273 ns/op StringCompareToFoldCase.asciiUpperLowerFC avgt 15 9.207 ? 0.255 ns/op StringCompareToFoldCase.asciiWithDFFC avgt 15 38.322 ? 0.975 ns/op StringCompareToFoldCase.greekLower avgt 15 39.746 ? 0.127 ns/op StringCompareToFoldCase.greekLowerEQ avgt 15 39.303 ? 0.063 ns/op StringCompareToFoldCase.greekLowerEQFC avgt 15 20.470 ? 0.329 ns/op StringCompareToFoldCase.greekLowerFC avgt 15 19.734 ? 0.295 ns/op StringCompareToFoldCase.greekUpperLower avgt 15 7.084 ? 0.085 ns/op StringCompareToFoldCase.greekUpperLowerEQ avgt 15 7.472 ? 0.115 ns/op StringCompareToFoldCase.greekUpperLowerEQFC avgt 15 6.608 ? 0.248 ns/op StringCompareToFoldCase.greekUpperLowerFC avgt 15 6.573 ? 0.189 ns/op StringCompareToFoldCase.latin1UTF16 avgt 15 24.407 ? 2.157 ns/op StringCompareToFoldCase.latin1UTF16EQ avgt 15 22.632 ? 0.131 ns/op StringCompareToFoldCase.latin1UTF16EQFC avgt 15 29.564 ? 0.655 ns/op StringCompareToFoldCase.latin1UTF16FC avgt 15 29.273 ? 0.324 ns/op StringCompareToFoldCase.supLower avgt 15 54.145 ? 0.075 ns/op StringCompareToFoldCase.supLowerEQ avgt 15 55.545 ? 0.042 ns/op StringCompareToFoldCase.supLowerEQFC avgt 15 24.788 ? 0.180 ns/op StringCompareToFoldCase.supLowerFC avgt 15 24.515 ? 0.025 ns/op StringCompareToFoldCase.supUpperLower avgt 15 14.437 ? 0.127 ns/op StringCompareToFoldCase.supUpperLowerEQ avgt 15 15.253 ? 0.728 ns/op StringCompareToFoldCase.supUpperLowerEQFC avgt 15 9.820 ? 0.104 ns/op StringCompareToFoldCase.supUpperLowerFC avgt 15 9.776 ? 0.127 ns/op Finished running test 'micro:org.openjdk.bench.java.lang.StringCompareToFoldCase' ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2476267966 From rriggs at openjdk.org Thu Oct 30 17:59:42 2025 From: rriggs at openjdk.org (Roger Riggs) Date: Thu, 30 Oct 2025 17:59:42 GMT Subject: RFR: 8365675: Add String Unicode Case-Folding Support [v7] In-Reply-To: References: <3tMaotmLtDYKP4cADaC8DEISDKEJEaWHXr2dYDtZXY8=.22820982-951a-4e91-96a0-d21397c8494d@github.com> <8vnnaDLbpvjdSdANjw2p_i_xvu7X8mqkNexoDPSyzE4=.c274163d-1b2e-4b9a-a6c0-e22e5aacd3cd@github.com> Message-ID: On Thu, 30 Oct 2025 03:00:47 GMT, Xueming Shen wrote: >>> The performance is slightly better, but not as good as I would have expected. The access to codepoint from the long looks a little clumsy, but the logic looks smooth. need more work. opinion? >> It does look cleaner without the array indexing in the loops. >> Can the counting of characters (fcnt1,fcnt2) be eliminated by encoding 3 20-bit characters into the long and then checking `f1 != 0` to indicate there are more characters. Its a bit of an odd mix of 16-bit characters vs a single 20-bit char. Are there any 20-bit chars from or to folded replacements in the folding mappings? > > Good idea. After removing the fcnt the implementation looks much cleaner and more straightforward. The1:m folding implementation is also faster. Maybe this is good enough to. go :-) > > The latest numbers > > > Benchmark Mode Cnt Score Error Units > StringCompareToFoldCase.asciiLower avgt 15 15.874 ? 1.276 ns/op > StringCompareToFoldCase.asciiLowerEQ avgt 15 9.915 ? 0.242 ns/op > StringCompareToFoldCase.asciiLowerEQFC avgt 15 10.751 ? 0.219 ns/op > StringCompareToFoldCase.asciiLowerFC avgt 15 10.277 ? 0.126 ns/op > StringCompareToFoldCase.asciiUpperLower avgt 15 12.121 ? 0.699 ns/op > StringCompareToFoldCase.asciiUpperLowerEQ avgt 15 10.836 ? 0.746 ns/op > StringCompareToFoldCase.asciiUpperLowerEQFC avgt 15 9.091 ? 0.273 ns/op > StringCompareToFoldCase.asciiUpperLowerFC avgt 15 9.207 ? 0.255 ns/op > StringCompareToFoldCase.asciiWithDFFC avgt 15 38.322 ? 0.975 ns/op > StringCompareToFoldCase.greekLower avgt 15 39.746 ? 0.127 ns/op > StringCompareToFoldCase.greekLowerEQ avgt 15 39.303 ? 0.063 ns/op > StringCompareToFoldCase.greekLowerEQFC avgt 15 20.470 ? 0.329 ns/op > StringCompareToFoldCase.greekLowerFC avgt 15 19.734 ? 0.295 ns/op > StringCompareToFoldCase.greekUpperLower avgt 15 7.084 ? 0.085 ns/op > StringCompareToFoldCase.greekUpperLowerEQ avgt 15 7.472 ? 0.115 ns/op > StringCompareToFoldCase.greekUpperLowerEQFC avgt 15 6.608 ? 0.248 ns/op > StringCompareToFoldCase.greekUpperLowerFC avgt 15 6.573 ? 0.189 ns/op > StringCompareToFoldCase.latin1UTF16 avgt 15 24.407 ? 2.157 ns/op > StringCompareToFoldCase.latin1UTF16EQ avgt 15 22.632 ? 0.131 ns/op > StringCompareToFoldCase.latin1UTF16EQFC avgt 15 29.564 ? 0.655 ns/op > StringCompareToFoldCase.latin1UTF16FC avgt 15 29.273 ? 0.324 ns/op > StringCompareToFoldCase.supLower avgt 15 54.145 ? 0.075 ns/op > StringCompareToFoldCase.supLowerEQ avgt 15 55.545 ? 0.042 ns/op > StringCompareToFoldCase.supLowerEQFC avgt 15 24.788 ? 0.180 ns/op > StringCompareToFoldCase.supLowerFC avgt 15 24.515 ? 0.025 ns/op > StringCompareToFoldCase.supUpperLower avgt 15 14.437 ? 0.127 ns/op > StringCompareToFoldCase.supUpperLowerEQ avgt 15 15.253 ? 0.728 ns/op > StringCompareToFoldCase.supUpperLowerEQFC avgt 15 9.820 ? 0.104 ns/op > StringCompareToFoldCase.supUpp... Looking pretty good. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27628#discussion_r2479020631 From alanb at openjdk.org Thu Oct 30 18:48:23 2025 From: alanb at openjdk.org (Alan Bateman) Date: Thu, 30 Oct 2025 18:48:23 GMT Subject: RFR: 8366178: Implement JEP 526: Lazy Constants (Second Preview) [v20] In-Reply-To: References: Message-ID: On Fri, 24 Oct 2025 09:01:10 GMT, Per Minborg wrote: >> Implement JEP 526: Lazy Constants (Second Preview) >> >> The lazy list/map implementations are broken out from `ImmutableCollections` to a separate class. >> >> The old benchmarks are not moved/renamed to allow comparison with previous releases. >> >> `java.util.Optional` is updated so that its field is annotated with `@Stable`. This is to allow `Optional` instances to be held in lazy constants and still provide constant folding. > > Per Minborg has updated the pull request incrementally with one additional commit since the last revision: > > Rework toString implementations src/java.base/share/classes/java/util/List.java line 1200: > 1198: > 1199: /** > 1200: * {@return a new lazily computed list with the provided {@code size}} A minor comment here is that "of the given size" might be a bit clearer than "with the provided size". src/java.base/share/classes/java/util/List.java line 1240: > 1238: * function used to compute elements only so long as there are uncomputed elements > 1239: * after which the computing function is not strongly referenced > 1240: * anymore and may be collected. I think it's okay to say that the computing function is kept strongly reachable until at least all elements have been computed. I'm less sure about the second part being normative text and wonder if it would be better to move that part to an implNote. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2479172995 PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2479168408 From naoto at openjdk.org Thu Oct 30 22:46:09 2025 From: naoto at openjdk.org (Naoto Sato) Date: Thu, 30 Oct 2025 22:46:09 GMT Subject: RFR: 8354548: Update CLDR to Version 48.0 Message-ID: Upgrading the CLDR to version 48.0. A corresponding CSR has also been drafted. ------------- Commit messages: - v48 final - Merge branch 'master' into JDK-8354548-CLDR-48 - Merge branch 'master' into JDK-8354548-CLDR-48 - Merge branch 'master' into JDK-8354548-CLDR-48 - Reverted Optional - release-48-beta3 - Merge branch 'master' into JDK-8354548-CLDR-48 - release-48-beta2 - Merge branch 'master' into JDK-8354548-CLDR-48 - 2025-09-30-1822z - ... and 42 more: https://git.openjdk.org/jdk/compare/cc9483b4...055336bd Changes: https://git.openjdk.org/jdk/pull/28076/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=28076&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8354548 Stats: 135768 lines in 385 files changed: 94267 ins; 15578 del; 25923 mod Patch: https://git.openjdk.org/jdk/pull/28076.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/28076/head:pull/28076 PR: https://git.openjdk.org/jdk/pull/28076 From naoto at openjdk.org Thu Oct 30 23:13:02 2025 From: naoto at openjdk.org (Naoto Sato) Date: Thu, 30 Oct 2025 23:13:02 GMT Subject: RFR: 8354548: Update CLDR to Version 48.0 [v2] In-Reply-To: References: Message-ID: <9VpoTyAJ3oQwtSpHO6sCVwaWA_Jx3B91DS2oxOTTTcI=.afc95ec9-c937-44e8-9a0c-9b087dd3c4ff@github.com> > Upgrading the CLDR to version 48.0. A corresponding CSR has also been drafted. Naoto Sato has updated the pull request incrementally with one additional commit since the last revision: .md files ------------- Changes: - all: https://git.openjdk.org/jdk/pull/28076/files - new: https://git.openjdk.org/jdk/pull/28076/files/055336bd..38f86493 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=28076&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=28076&range=00-01 Stats: 2 lines in 2 files changed: 0 ins; 0 del; 2 mod Patch: https://git.openjdk.org/jdk/pull/28076.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/28076/head:pull/28076 PR: https://git.openjdk.org/jdk/pull/28076