RFR: 8343962: [REDO] Move getChars to DecimalDigits [v4]

Claes Redestad redestad at openjdk.org
Tue Dec 10 12:27:42 UTC 2024


On Mon, 9 Dec 2024 06:24:21 GMT, Shaojin Wen <swen at openjdk.org> wrote:

>> This PR is a resubmission after PR #21593 was rolled back, and the unsafe offset overflow issue has been fixed.
>> 
>> 1) Move getChars methods of StringLatin1 and StringUTF16 to DecimalDigits to reduce duplication.
>> 
>> 2) HexDigits and OctalDigits also include getCharsLatin1 and getCharsUTF16
>> 
>> 3) Putting these two methods into DecimalDigits can avoid the need to expose them in JavaLangAccess
>> Eliminate duplicate code in BigDecimal
>> 
>> 4) This PR will improve the performance of Integer/Long.toString and StringBuilder.append(int/long) scenarios. This is because Unsafe.putByte is used to eliminate array bounds checks, and of course this elimination is safe. In previous versions, in Integer/Long.toString and StringBuilder.append(int/long) scenarios, -COMPACT_STRING performed better than +COMPACT_STRING. This is because StringUTF16.getChars uses StringUTF16.putChar, which is similar to Unsafe.putChar, and there is no bounds check.
>
> Shaojin Wen 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 17 additional commits since the last revision:
> 
>  - Merge remote-tracking branch 'upstream/master' into int_get_chars_dedup_202411
>  - Merge remote-tracking branch 'upstream/master' into int_get_chars_dedup_202411
>  - Merge remote-tracking branch 'upstream/master' into int_get_chars_dedup_202411
>  - fix unsafe address overflow
>  - add benchmark
>  - remove comments, from @liach
>  - Merge remote-tracking branch 'upstream/master' into int_get_chars_dedup_202410
>  - fix Helper
>  - fix Helper
>  - fix Helper
>  - ... and 7 more: https://git.openjdk.org/jdk/compare/4d831fe5...a05c2f5f

I need to carve out more time for a full review. Some comments in the meantime.

src/java.base/share/classes/java/math/BigDecimal.java line 4198:

> 4196:             int highIntSize = DecimalDigits.stringSize(highInt);
> 4197:             byte[] buf = new byte[highIntSize + 3];
> 4198:             DecimalDigits.putPairLatin1(buf, highIntSize + 1, lowInt);

I think this would read a bit easier if the order of writes to `buf` was reversed

src/java.base/share/classes/java/math/BigDecimal.java line 4212:

> 4210:         // Get the significand as an absolute value
> 4211:         if (intCompact != INFLATED) {
> 4212:             coeff = new char[19];

Add this now-removed comment back here? 

            // All non negative longs can be made to fit into 19 character array.

src/java.base/share/classes/java/math/BigDecimal.java line 4213:

> 4211:         if (intCompact != INFLATED) {
> 4212:             coeff = new char[19];
> 4213:             offset = DecimalDigits.getChars(Math.abs(intCompact), coeff.length, coeff);

`StringBuilderHelper.putIntCompact` asserts that `Math.abs(intCompact)` is non-negative, but there is no such assert in `DecimalDigits.getChars`. I'm not too familiar with `BigDecimal` and maybe `intCompact` wouldn't be set for `Long.MIN_VALUE`. If so perhaps this should use `StrictMath#absExact(long)` for clarity rather than lean on an assert?

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

PR Review: https://git.openjdk.org/jdk/pull/22023#pullrequestreview-2492139816
PR Review Comment: https://git.openjdk.org/jdk/pull/22023#discussion_r1877984262
PR Review Comment: https://git.openjdk.org/jdk/pull/22023#discussion_r1877991901
PR Review Comment: https://git.openjdk.org/jdk/pull/22023#discussion_r1878004613


More information about the core-libs-dev mailing list