On Fri, 14 Nov 2025 04:46:26 GMT, Shaojin Wen <[email protected]> wrote:

>> This PR introduces a new efficient API for appending two-digit integers to 
>> StringBuilders and refactors DateTimeHelper to leverage this new 
>> functionality.
>> 
>> Changes include:
>> 
>> 1. New `appendPair` method for efficient two-digit integer formatting 
>> (00-99):
>>    - Added `AbstractStringBuilder.appendLatin1(char c1, char c2)` with core 
>> implementation
>>    - Added `JavaLangAccess.appendPair(StringBuilder, char c1, char c2)` for 
>> internal access
>>    - Added `DecimalDigits.appendPair(StringBuilder, int)` public static 
>> utility method
>>    - Enhanced Javadoc documentation for all new methods
>> 
>> 2. Refactored `DateTimeHelper` to use the new `DecimalDigits.appendPair`:
>>    - Updated `DateTimeHelper.formatTo` methods for `LocalDate` and 
>> `LocalTime`
>>    - Replaced manual formatting logic with the new efficient two-digit 
>> appending
>>    - Improved code clarity and consistency in date/time formatting
>> 
>> These changes improve code clarity and performance when formatting two-digit 
>> numbers, particularly in date/time formatting scenarios.
>
> Shaojin Wen has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   remove JLA

I wanted to modify the DecimalDigits.appendQuad method as follows, but this 
caused `MergeStore` to not work.

    public static void appendQuad(StringBuilder buf, int v) {
        // The & 0x7f operation keeps the index within the safe range [0, 127] 
for the DIGITS array,
        // which allows the JIT compiler to eliminate array bounds checks for 
performance.
        int packed = DIGITS[(v / 100) & 0x7f] | (DIGITS[(v % 100) & 0x7f] << 
16);
        // The temporary String and byte[] objects created here are typically 
eliminated
        // by the JVM's escape analysis and scalar replacement optimizations 
during
        // runtime compilation, avoiding actual heap allocations in optimized 
code.
        buf.append(
                JLA.uncheckedNewStringWithLatin1Bytes(
                        new byte[] {(byte) packed,         (byte) (packed >> 8),
                                    (byte) (packed >> 16), (byte) (packed  >> 
24)}));
    }


The output is as follows:

[TraceMergeStores] MergePrimitiveStores::run:  868  StoreB  === 887 813 861 145 
 [[ 872 ]]  @byte[int:>=0] 
(java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, idx=7;  Memory: 
@byte[int:>=0] (java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, 
idx=7;
[TraceMergeStores] expect no use: None
[TraceMergeStores] expect def: None
[TraceMergeStores] MergePrimitiveStores::run:  848  StoreB  === 888 813 840 81  
[[ 853 ]]  @byte[int:>=0] 
(java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, idx=7;  Memory: 
@byte[int:>=0] (java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, 
idx=7;
[TraceMergeStores] expect no use: None
[TraceMergeStores] expect def: None
[TraceMergeStores] MergePrimitiveStores::run:  559  StoreB  === 548 543 351 352 
 [[ 562 ]]  @java/lang/AbstractStringBuilder 
(java/lang/CharSequence,java/lang/Appendable)+16 *, name=coder, idx=13;  
Memory: @java/lang/StringBuilder 
(java/io/Serializable,java/lang/Comparable,java/lang/CharSequence,java/lang/Appendable):NotNull:exact+16
 *, name=coder, idx=13; !jvms: AbstractStringBuilder::append @ bci:78 (line 
651) StringBuilder::append @ bci:2 (line 179) DecimalDigits::appendQuad @ 
bci:68 (line 496)
[TraceMergeStores] expect no use: None
[TraceMergeStores] expect def: None
[TraceMergeStores] MergePrimitiveStores::run:  739  StoreI  === 879 813 354 456 
 [[ 17 ]]  @java/lang/AbstractStringBuilder 
(java/lang/CharSequence,java/lang/Appendable)+12 *, name=count, idx=14;  
Memory: @java/lang/StringBuilder 
(java/io/Serializable,java/lang/Comparable,java/lang/CharSequence,java/lang/Appendable):NotNull:exact+12
 *, name=count, idx=14; !jvms: AbstractStringBuilder::append @ bci:95 (line 
654) StringBuilder::append @ bci:2 (line 179) DecimalDigits::appendQuad @ 
bci:68 (line 496)
[TraceMergeStores] expect no use: None
[TraceMergeStores] expect def: None
[TraceMergeStores] MergePrimitiveStores::run:  872  StoreB  === 887 868 856 912 
 [[ 876 ]]  @byte[int:>=0] 
(java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, idx=7;  Memory: 
@byte[int:>=0] (java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, 
idx=7;
[TraceMergeStores] expect no use: None
[TraceMergeStores] expect def: None
[TraceMergeStores] MergePrimitiveStores::run:  853  StoreB  === 888 848 851 906 
 [[ 858 ]]  @byte[int:>=0] 
(java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, idx=7;  Memory: 
@byte[int:>=0] (java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, 
idx=7;
[TraceMergeStores] expect no use: None
[TraceMergeStores] expect def: None
[TraceMergeStores] MergePrimitiveStores::run:  858  StoreB  === 888 853 856 912 
 [[ 863 ]]  @byte[int:>=0] 
(java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, idx=7;  Memory: 
@byte[int:>=0] (java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, 
idx=7;
[TraceMergeStores] expect no use: None
[TraceMergeStores] expect def: None
[TraceMergeStores] MergePrimitiveStores::run:  863  StoreB  === 888 858 861 145 
 [[ 880 ]]  @byte[int:>=0] 
(java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, idx=7;  Memory: 
@byte[int:>=0] (java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, 
idx=7;
[TraceMergeStores] expect no use: None
[TraceMergeStores] expect def: None
[TraceMergeStores] MergePrimitiveStores::run:  876  StoreB  === 887 872 851 906 
 [[ 878 ]]  @byte[int:>=0] 
(java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, idx=7;  Memory: 
@byte[int:>=0] (java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, 
idx=7;
[TraceMergeStores] expect no use: None
[TraceMergeStores] expect def: None
[TraceMergeStores] MergePrimitiveStores::run:  878  StoreB  === 887 876 840 81  
[[ 880 ]]  @byte[int:>=0] 
(java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, idx=7;  Memory: 
@byte[int:>=0] (java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, 
idx=7;
[TraceMergeStores] expect no use: None
[TraceMergeStores] expect def: None

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

PR Comment: https://git.openjdk.org/jdk/pull/26911#issuecomment-3531435995

Reply via email to