From 468bc6136372495e96a3cb144d6bcfc33265b437 Mon Sep 17 00:00:00 2001 From: "shaojin.wensj" Date: Sat, 1 Jul 2023 08:41:24 +0800 Subject: [PATCH 01/15] 8311207: Optimization for j.u.UUID.toString --- .../share/classes/java/util/HexDigits.java | 28 ++++++------ .../share/classes/java/util/UUID.java | 45 +++++++++++-------- 2 files changed, 40 insertions(+), 33 deletions(-) diff --git a/src/java.base/share/classes/java/util/HexDigits.java b/src/java.base/share/classes/java/util/HexDigits.java index 7cae4b731f8a8..5dcdaac384588 100644 --- a/src/java.base/share/classes/java/util/HexDigits.java +++ b/src/java.base/share/classes/java/util/HexDigits.java @@ -39,27 +39,27 @@ final class HexDigits implements Digits { * Each element of the array represents the ascii encoded * hex relative to its index, for example:

*

-     *       0 -> '00' -> ('0' << 8) | '0' -> 12336
-     *       1 -> '01' -> ('0' << 8) | '1' -> 12337
-     *       2 -> '02' -> ('0' << 8) | '2' -> 12338
+     *       0 -> '00' -> ('0' << 8) | '0' -> 0x3030
+     *       1 -> '01' -> ('0' << 8) | '1' -> 0x3130
+     *       2 -> '02' -> ('0' << 8) | '2' -> 0x3230
      *
      *     ...
      *
-     *      10 -> '0a' -> ('0' << 8) | 'a' -> 12385
-     *      11 -> '0b' -> ('0' << 8) | 'b' -> 12386
-     *      12 -> '0c' -> ('0' << 8) | 'b' -> 12387
+     *      10 -> '0a' -> ('0' << 8) | 'a' -> 0x3061
+     *      11 -> '0b' -> ('0' << 8) | 'b' -> 0x3062
+     *      12 -> '0c' -> ('0' << 8) | 'c' -> 0x3063
      *
      *     ...
      *
-     *      26 -> '1a' -> ('1' << 8) | 'a' -> 12641
-     *      27 -> '1b' -> ('1' << 8) | 'b' -> 12642
-     *      28 -> '1c' -> ('1' << 8) | 'c' -> 12643
+     *      26 -> '1a' -> ('1' << 8) | 'a' -> 0x3161
+     *      27 -> '1b' -> ('1' << 8) | 'b' -> 0x3162
+     *      28 -> '1c' -> ('1' << 8) | 'c' -> 0x3163
      *
      *     ...
      *
-     *     253 -> 'fd' -> ('f' << 8) | 'd' -> 26212
-     *     254 -> 'fe' -> ('f' << 8) | 'e' -> 26213
-     *     255 -> 'ff' -> ('f' << 8) | 'f' -> 26214
+     *     253 -> 'fd' -> ('f' << 8) | 'd' -> 0x6664
+     *     254 -> 'fe' -> ('f' << 8) | 'e' -> 0x6665
+     *     255 -> 'ff' -> ('f' << 8) | 'f' -> 0x6666
      * 
*

use like this: *

@@ -105,14 +105,14 @@ private HexDigits() {
     /**
      * Combine two hex shorts into one int based on big endian
      */
-    static int digit(int b0, int b1) {
+    static int packDigits(int b0, int b1) {
         return (DIGITS[b0 & 0xff] << 16) | DIGITS[b1 & 0xff];
     }
 
     /**
      * Combine four hex shorts into one long based on big endian
      */
-    static long digit(int b0, int b1, int b2, int b3) {
+    static long packDigits(int b0, int b1, int b2, int b3) {
         return (((long) DIGITS[b0 & 0xff]) << 48)
                 | (((long) DIGITS[b1 & 0xff]) << 32)
                 | (DIGITS[b2 & 0xff] << 16)
diff --git a/src/java.base/share/classes/java/util/UUID.java b/src/java.base/share/classes/java/util/UUID.java
index 78846ba48c23a..43b842f2544ab 100644
--- a/src/java.base/share/classes/java/util/UUID.java
+++ b/src/java.base/share/classes/java/util/UUID.java
@@ -31,7 +31,7 @@
 
 import jdk.internal.access.JavaLangAccess;
 import jdk.internal.access.SharedSecrets;
-import jdk.internal.util.ByteArray;
+import jdk.internal.misc.Unsafe;
 
 /**
  * A class that represents an immutable universally unique identifier (UUID).
@@ -466,37 +466,44 @@ public long node() {
      */
     @Override
     public String toString() {
+        Unsafe unsafe = Unsafe.getUnsafe();
         long lsb = leastSigBits;
         long msb = mostSigBits;
         byte[] buf = new byte[36];
-        ByteArray.setLong(
+        unsafe.putLongUnaligned(
                 buf,
-                0,
-                HexDigits.digit((int) (msb >> 56), (int) (msb >> 48), (int) (msb >> 40), (int) (msb >> 32)));
+                Unsafe.ARRAY_BYTE_BASE_OFFSET,
+                HexDigits.packDigits((int) (msb >> 56), (int) (msb >> 48), (int) (msb >> 40), (int) (msb >> 32)),
+                false);
         buf[8] = '-';
-        ByteArray.setInt(
+        unsafe.putIntUnaligned(
                 buf,
-                9,
-                HexDigits.digit(((int) msb) >> 24, ((int) msb) >> 16));
+                Unsafe.ARRAY_BYTE_BASE_OFFSET + 9,
+                HexDigits.packDigits(((int) msb) >> 24, ((int) msb) >> 16),
+                false);
         buf[13] = '-';
-        ByteArray.setInt(
+        unsafe.putIntUnaligned(
                 buf,
-                14,
-                HexDigits.digit(((int) msb) >> 8, (int) msb));
+                Unsafe.ARRAY_BYTE_BASE_OFFSET + 14,
+                HexDigits.packDigits(((int) msb) >> 8, (int) msb),
+                false);
         buf[18] = '-';
-        ByteArray.setInt(
+        unsafe.putIntUnaligned(
                 buf,
-                19,
-                HexDigits.digit((int) (lsb >> 56), (int) (lsb >> 48)));
+                Unsafe.ARRAY_BYTE_BASE_OFFSET + 19,
+                HexDigits.packDigits((int) (lsb >> 56), (int) (lsb >> 48)),
+                false);
         buf[23] = '-';
-        ByteArray.setLong(
+        unsafe.putLongUnaligned(
                 buf,
-                24,
-                HexDigits.digit(((int) (lsb >> 40)), (int) (lsb >> 32), ((int) lsb) >> 24, ((int) lsb) >> 16));
-        ByteArray.setInt(
+                Unsafe.ARRAY_BYTE_BASE_OFFSET + 24,
+                HexDigits.packDigits(((int) (lsb >> 40)), (int) (lsb >> 32), ((int) lsb) >> 24, ((int) lsb) >> 16),
+                false);
+        unsafe.putIntUnaligned(
                 buf,
-                32,
-                HexDigits.digit(((int) lsb) >> 8, (int) lsb));
+                Unsafe.ARRAY_BYTE_BASE_OFFSET + 32,
+                HexDigits.packDigits(((int) lsb) >> 8, (int) lsb),
+                false);
 
         try {
             return jla.newStringNoRepl(buf, StandardCharsets.ISO_8859_1);

From 244c0eb1476291b9d52dcd00c7892028e484703e Mon Sep 17 00:00:00 2001
From: "shaojin.wensj" 
Date: Sat, 1 Jul 2023 09:48:15 +0800
Subject: [PATCH 02/15] use big endian

---
 src/java.base/share/classes/java/util/UUID.java | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/java.base/share/classes/java/util/UUID.java b/src/java.base/share/classes/java/util/UUID.java
index 43b842f2544ab..8e5879f5baa12 100644
--- a/src/java.base/share/classes/java/util/UUID.java
+++ b/src/java.base/share/classes/java/util/UUID.java
@@ -474,36 +474,36 @@ public String toString() {
                 buf,
                 Unsafe.ARRAY_BYTE_BASE_OFFSET,
                 HexDigits.packDigits((int) (msb >> 56), (int) (msb >> 48), (int) (msb >> 40), (int) (msb >> 32)),
-                false);
+                true);
         buf[8] = '-';
         unsafe.putIntUnaligned(
                 buf,
                 Unsafe.ARRAY_BYTE_BASE_OFFSET + 9,
                 HexDigits.packDigits(((int) msb) >> 24, ((int) msb) >> 16),
-                false);
+                true);
         buf[13] = '-';
         unsafe.putIntUnaligned(
                 buf,
                 Unsafe.ARRAY_BYTE_BASE_OFFSET + 14,
                 HexDigits.packDigits(((int) msb) >> 8, (int) msb),
-                false);
+                true);
         buf[18] = '-';
         unsafe.putIntUnaligned(
                 buf,
                 Unsafe.ARRAY_BYTE_BASE_OFFSET + 19,
                 HexDigits.packDigits((int) (lsb >> 56), (int) (lsb >> 48)),
-                false);
+                true);
         buf[23] = '-';
         unsafe.putLongUnaligned(
                 buf,
                 Unsafe.ARRAY_BYTE_BASE_OFFSET + 24,
                 HexDigits.packDigits(((int) (lsb >> 40)), (int) (lsb >> 32), ((int) lsb) >> 24, ((int) lsb) >> 16),
-                false);
+                true);
         unsafe.putIntUnaligned(
                 buf,
                 Unsafe.ARRAY_BYTE_BASE_OFFSET + 32,
                 HexDigits.packDigits(((int) lsb) >> 8, (int) lsb),
-                false);
+                true);
 
         try {
             return jla.newStringNoRepl(buf, StandardCharsets.ISO_8859_1);

From b6c59e01d2b8f525b27c6f4ef885fbf5156255a8 Mon Sep 17 00:00:00 2001
From: liach 
Date: Sat, 1 Jul 2023 10:42:37 +0800
Subject: [PATCH 03/15] Suggested HexDigits change

---
 .../share/classes/java/util/HexDigits.java     | 18 +++++++++---------
 .../share/classes/java/util/UUID.java          | 12 ++++++------
 2 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/src/java.base/share/classes/java/util/HexDigits.java b/src/java.base/share/classes/java/util/HexDigits.java
index 5dcdaac384588..a7fca7c542c8e 100644
--- a/src/java.base/share/classes/java/util/HexDigits.java
+++ b/src/java.base/share/classes/java/util/HexDigits.java
@@ -103,20 +103,20 @@ private HexDigits() {
     }
 
     /**
-     * Combine two hex shorts into one int based on big endian
+     * Return a big-endian packed integer for the 4 ASCII bytes for an input unsigned short value.
      */
-    static int packDigits(int b0, int b1) {
-        return (DIGITS[b0 & 0xff] << 16) | DIGITS[b1 & 0xff];
+    static int packDigits16(int b) {
+        return (DIGITS[(b >> 8) & 0xff] << 16) | DIGITS[b & 0xff];
     }
 
     /**
-     * Combine four hex shorts into one long based on big endian
+     * Return a big-endian packed long for the 8 ASCII bytes for an input unsigned int value.
      */
-    static long packDigits(int b0, int b1, int b2, int b3) {
-        return (((long) DIGITS[b0 & 0xff]) << 48)
-                | (((long) DIGITS[b1 & 0xff]) << 32)
-                | (DIGITS[b2 & 0xff] << 16)
-                | DIGITS[b3 & 0xff];
+    static long packDigits32(int b) {
+        return (((long) DIGITS[(b >> 24) & 0xff]) << 48)
+                | (((long) DIGITS[(b >> 16) & 0xff]) << 32)
+                | (DIGITS[(b >> 8) & 0xff] << 16)
+                | DIGITS[b & 0xff];
     }
 
     @Override
diff --git a/src/java.base/share/classes/java/util/UUID.java b/src/java.base/share/classes/java/util/UUID.java
index 8e5879f5baa12..9713e5e3fb12d 100644
--- a/src/java.base/share/classes/java/util/UUID.java
+++ b/src/java.base/share/classes/java/util/UUID.java
@@ -473,36 +473,36 @@ public String toString() {
         unsafe.putLongUnaligned(
                 buf,
                 Unsafe.ARRAY_BYTE_BASE_OFFSET,
-                HexDigits.packDigits((int) (msb >> 56), (int) (msb >> 48), (int) (msb >> 40), (int) (msb >> 32)),
+                HexDigits.packDigits32((int) (msb >> 32)),
                 true);
         buf[8] = '-';
         unsafe.putIntUnaligned(
                 buf,
                 Unsafe.ARRAY_BYTE_BASE_OFFSET + 9,
-                HexDigits.packDigits(((int) msb) >> 24, ((int) msb) >> 16),
+                HexDigits.packDigits16(((int) msb) >> 16),
                 true);
         buf[13] = '-';
         unsafe.putIntUnaligned(
                 buf,
                 Unsafe.ARRAY_BYTE_BASE_OFFSET + 14,
-                HexDigits.packDigits(((int) msb) >> 8, (int) msb),
+                HexDigits.packDigits16((int) msb),
                 true);
         buf[18] = '-';
         unsafe.putIntUnaligned(
                 buf,
                 Unsafe.ARRAY_BYTE_BASE_OFFSET + 19,
-                HexDigits.packDigits((int) (lsb >> 56), (int) (lsb >> 48)),
+                HexDigits.packDigits16((int) (lsb >> 48)),
                 true);
         buf[23] = '-';
         unsafe.putLongUnaligned(
                 buf,
                 Unsafe.ARRAY_BYTE_BASE_OFFSET + 24,
-                HexDigits.packDigits(((int) (lsb >> 40)), (int) (lsb >> 32), ((int) lsb) >> 24, ((int) lsb) >> 16),
+                HexDigits.packDigits32((int) (lsb >> 16)),
                 true);
         unsafe.putIntUnaligned(
                 buf,
                 Unsafe.ARRAY_BYTE_BASE_OFFSET + 32,
-                HexDigits.packDigits(((int) lsb) >> 8, (int) lsb),
+                HexDigits.packDigits16((int) lsb),
                 true);
 
         try {

From 76dba9649a530a2f21574f3dff1aa55a6ebe8888 Mon Sep 17 00:00:00 2001
From: "shaojin.wensj" 
Date: Sat, 1 Jul 2023 11:17:06 +0800
Subject: [PATCH 04/15] revert to the previous version

---
 .../share/classes/java/util/HexDigits.java         | 14 +++++++-------
 src/java.base/share/classes/java/util/UUID.java    | 12 ++++++------
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/src/java.base/share/classes/java/util/HexDigits.java b/src/java.base/share/classes/java/util/HexDigits.java
index a7fca7c542c8e..684889ca7c39d 100644
--- a/src/java.base/share/classes/java/util/HexDigits.java
+++ b/src/java.base/share/classes/java/util/HexDigits.java
@@ -105,18 +105,18 @@ private HexDigits() {
     /**
      * Return a big-endian packed integer for the 4 ASCII bytes for an input unsigned short value.
      */
-    static int packDigits16(int b) {
-        return (DIGITS[(b >> 8) & 0xff] << 16) | DIGITS[b & 0xff];
+    static int packDigits(int b0, int b1) {
+        return (DIGITS[b0 & 0xff] << 16) | DIGITS[b1 & 0xff];
     }
 
     /**
      * Return a big-endian packed long for the 8 ASCII bytes for an input unsigned int value.
      */
-    static long packDigits32(int b) {
-        return (((long) DIGITS[(b >> 24) & 0xff]) << 48)
-                | (((long) DIGITS[(b >> 16) & 0xff]) << 32)
-                | (DIGITS[(b >> 8) & 0xff] << 16)
-                | DIGITS[b & 0xff];
+    static long packDigits(int b0, int b1, int b2, int b3) {
+        return (((long) DIGITS[b0 & 0xff]) << 48)
+                | (((long) DIGITS[b1 & 0xff]) << 32)
+                | (DIGITS[b2 & 0xff] << 16)
+                | DIGITS[b3 & 0xff];
     }
 
     @Override
diff --git a/src/java.base/share/classes/java/util/UUID.java b/src/java.base/share/classes/java/util/UUID.java
index 9713e5e3fb12d..8e5879f5baa12 100644
--- a/src/java.base/share/classes/java/util/UUID.java
+++ b/src/java.base/share/classes/java/util/UUID.java
@@ -473,36 +473,36 @@ public String toString() {
         unsafe.putLongUnaligned(
                 buf,
                 Unsafe.ARRAY_BYTE_BASE_OFFSET,
-                HexDigits.packDigits32((int) (msb >> 32)),
+                HexDigits.packDigits((int) (msb >> 56), (int) (msb >> 48), (int) (msb >> 40), (int) (msb >> 32)),
                 true);
         buf[8] = '-';
         unsafe.putIntUnaligned(
                 buf,
                 Unsafe.ARRAY_BYTE_BASE_OFFSET + 9,
-                HexDigits.packDigits16(((int) msb) >> 16),
+                HexDigits.packDigits(((int) msb) >> 24, ((int) msb) >> 16),
                 true);
         buf[13] = '-';
         unsafe.putIntUnaligned(
                 buf,
                 Unsafe.ARRAY_BYTE_BASE_OFFSET + 14,
-                HexDigits.packDigits16((int) msb),
+                HexDigits.packDigits(((int) msb) >> 8, (int) msb),
                 true);
         buf[18] = '-';
         unsafe.putIntUnaligned(
                 buf,
                 Unsafe.ARRAY_BYTE_BASE_OFFSET + 19,
-                HexDigits.packDigits16((int) (lsb >> 48)),
+                HexDigits.packDigits((int) (lsb >> 56), (int) (lsb >> 48)),
                 true);
         buf[23] = '-';
         unsafe.putLongUnaligned(
                 buf,
                 Unsafe.ARRAY_BYTE_BASE_OFFSET + 24,
-                HexDigits.packDigits32((int) (lsb >> 16)),
+                HexDigits.packDigits(((int) (lsb >> 40)), (int) (lsb >> 32), ((int) lsb) >> 24, ((int) lsb) >> 16),
                 true);
         unsafe.putIntUnaligned(
                 buf,
                 Unsafe.ARRAY_BYTE_BASE_OFFSET + 32,
-                HexDigits.packDigits16((int) lsb),
+                HexDigits.packDigits(((int) lsb) >> 8, (int) lsb),
                 true);
 
         try {

From 43ec99d078b7e954bc14678e173786049900ddc6 Mon Sep 17 00:00:00 2001
From: "shaojin.wensj" 
Date: Sat, 1 Jul 2023 17:41:01 +0800
Subject: [PATCH 05/15] private static final Unsafe

---
 src/java.base/share/classes/java/util/UUID.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/java.base/share/classes/java/util/UUID.java b/src/java.base/share/classes/java/util/UUID.java
index 8e5879f5baa12..faa10750cc145 100644
--- a/src/java.base/share/classes/java/util/UUID.java
+++ b/src/java.base/share/classes/java/util/UUID.java
@@ -76,6 +76,7 @@
  * @since   1.5
  */
 public final class UUID implements java.io.Serializable, Comparable {
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
 
     /**
      * Explicit serialVersionUID for interoperability.
@@ -466,7 +467,6 @@ public long node() {
      */
     @Override
     public String toString() {
-        Unsafe unsafe = Unsafe.getUnsafe();
         long lsb = leastSigBits;
         long msb = mostSigBits;
         byte[] buf = new byte[36];

From 6abf31488758aef7389b227d1bd1bad0dbe1dd77 Mon Sep 17 00:00:00 2001
From: liach <7806504+liach@users.noreply.github.com>
Date: Sat, 1 Jul 2023 22:29:28 +0800
Subject: [PATCH 06/15] Explain the rationale

Co-authored-by: liach 
---
 src/java.base/share/classes/java/util/HexDigits.java | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/java.base/share/classes/java/util/HexDigits.java b/src/java.base/share/classes/java/util/HexDigits.java
index 684889ca7c39d..619a1a9e594db 100644
--- a/src/java.base/share/classes/java/util/HexDigits.java
+++ b/src/java.base/share/classes/java/util/HexDigits.java
@@ -103,14 +103,18 @@ private HexDigits() {
     }
 
     /**
-     * Return a big-endian packed integer for the 4 ASCII bytes for an input unsigned short value.
+     * Return a big-endian packed integer for the 4 ASCII bytes for an input unsigned 2-byte integer.
+     * {@code b0} is the most significant byte and {@code b1} is the least significant byte.
+     * The integer is passed byte-wise to allow reordering of execution.
      */
     static int packDigits(int b0, int b1) {
         return (DIGITS[b0 & 0xff] << 16) | DIGITS[b1 & 0xff];
     }
 
     /**
-     * Return a big-endian packed long for the 8 ASCII bytes for an input unsigned int value.
+     * Return a big-endian packed long for the 8 ASCII bytes for an input unsigned 4-byte integer.
+     * {@code b0} is the most significant byte and {@code b4} is the least significant byte.
+     * The integer is passed byte-wise to allow reordering of execution.
      */
     static long packDigits(int b0, int b1, int b2, int b3) {
         return (((long) DIGITS[b0 & 0xff]) << 48)

From e5274ddcabc6bfb6b9230e570793664b9dfc2c58 Mon Sep 17 00:00:00 2001
From: "shaojin.wensj" 
Date: Sat, 1 Jul 2023 22:36:55 +0800
Subject: [PATCH 07/15] code style

---
 .../share/classes/java/util/UUID.java         | 28 ++++++++++---------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/src/java.base/share/classes/java/util/UUID.java b/src/java.base/share/classes/java/util/UUID.java
index faa10750cc145..253833de4aaa9 100644
--- a/src/java.base/share/classes/java/util/UUID.java
+++ b/src/java.base/share/classes/java/util/UUID.java
@@ -33,6 +33,8 @@
 import jdk.internal.access.SharedSecrets;
 import jdk.internal.misc.Unsafe;
 
+import static jdk.internal.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET;
+
 /**
  * A class that represents an immutable universally unique identifier (UUID).
  * A UUID represents a 128-bit value.
@@ -76,7 +78,7 @@
  * @since   1.5
  */
 public final class UUID implements java.io.Serializable, Comparable {
-    private static final Unsafe unsafe = Unsafe.getUnsafe();
+    private static final Unsafe UNSAFE = Unsafe.getUnsafe();
 
     /**
      * Explicit serialVersionUID for interoperability.
@@ -470,38 +472,38 @@ public String toString() {
         long lsb = leastSigBits;
         long msb = mostSigBits;
         byte[] buf = new byte[36];
-        unsafe.putLongUnaligned(
+        UNSAFE.putLongUnaligned(
                 buf,
-                Unsafe.ARRAY_BYTE_BASE_OFFSET,
+                ARRAY_BYTE_BASE_OFFSET,
                 HexDigits.packDigits((int) (msb >> 56), (int) (msb >> 48), (int) (msb >> 40), (int) (msb >> 32)),
                 true);
         buf[8] = '-';
-        unsafe.putIntUnaligned(
+        UNSAFE.putIntUnaligned(
                 buf,
-                Unsafe.ARRAY_BYTE_BASE_OFFSET + 9,
+                ARRAY_BYTE_BASE_OFFSET + 9,
                 HexDigits.packDigits(((int) msb) >> 24, ((int) msb) >> 16),
                 true);
         buf[13] = '-';
-        unsafe.putIntUnaligned(
+        UNSAFE.putIntUnaligned(
                 buf,
-                Unsafe.ARRAY_BYTE_BASE_OFFSET + 14,
+                ARRAY_BYTE_BASE_OFFSET + 14,
                 HexDigits.packDigits(((int) msb) >> 8, (int) msb),
                 true);
         buf[18] = '-';
-        unsafe.putIntUnaligned(
+        UNSAFE.putIntUnaligned(
                 buf,
-                Unsafe.ARRAY_BYTE_BASE_OFFSET + 19,
+                ARRAY_BYTE_BASE_OFFSET + 19,
                 HexDigits.packDigits((int) (lsb >> 56), (int) (lsb >> 48)),
                 true);
         buf[23] = '-';
-        unsafe.putLongUnaligned(
+        UNSAFE.putLongUnaligned(
                 buf,
-                Unsafe.ARRAY_BYTE_BASE_OFFSET + 24,
+                ARRAY_BYTE_BASE_OFFSET + 24,
                 HexDigits.packDigits(((int) (lsb >> 40)), (int) (lsb >> 32), ((int) lsb) >> 24, ((int) lsb) >> 16),
                 true);
-        unsafe.putIntUnaligned(
+        UNSAFE.putIntUnaligned(
                 buf,
-                Unsafe.ARRAY_BYTE_BASE_OFFSET + 32,
+                ARRAY_BYTE_BASE_OFFSET + 32,
                 HexDigits.packDigits(((int) lsb) >> 8, (int) lsb),
                 true);
 

From d6bb2725f27ee4de0289f7bd21f49257357eb688 Mon Sep 17 00:00:00 2001
From: "shaojin.wensj" 
Date: Sat, 8 Jul 2023 08:00:21 +0800
Subject: [PATCH 08/15] fix typo

---
 src/java.base/share/classes/java/util/HexDigits.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/java.base/share/classes/java/util/HexDigits.java b/src/java.base/share/classes/java/util/HexDigits.java
index 619a1a9e594db..6c0b6155c8cd6 100644
--- a/src/java.base/share/classes/java/util/HexDigits.java
+++ b/src/java.base/share/classes/java/util/HexDigits.java
@@ -113,7 +113,7 @@ static int packDigits(int b0, int b1) {
 
     /**
      * Return a big-endian packed long for the 8 ASCII bytes for an input unsigned 4-byte integer.
-     * {@code b0} is the most significant byte and {@code b4} is the least significant byte.
+     * {@code b0} is the most significant byte and {@code b3} is the least significant byte.
      * The integer is passed byte-wise to allow reordering of execution.
      */
     static long packDigits(int b0, int b1, int b2, int b3) {

From 25cf0144bf811130b1df95b827137e13fc7f4049 Mon Sep 17 00:00:00 2001
From: "shaojin.wensj" 
Date: Tue, 5 Sep 2023 09:42:55 +0800
Subject: [PATCH 09/15] use ByteArrayLittleEndian

---
 .../share/classes/java/util/HexDigits.java    | 58 ++++---------------
 .../share/classes/java/util/UUID.java         | 48 ++++++---------
 2 files changed, 29 insertions(+), 77 deletions(-)

diff --git a/src/java.base/share/classes/java/util/HexDigits.java b/src/java.base/share/classes/java/util/HexDigits.java
index 6c0b6155c8cd6..ca9f6c1157706 100644
--- a/src/java.base/share/classes/java/util/HexDigits.java
+++ b/src/java.base/share/classes/java/util/HexDigits.java
@@ -35,44 +35,6 @@
  * @since 21
  */
 final class HexDigits implements Digits {
-    /**
-     * Each element of the array represents the ascii encoded
-     * hex relative to its index, for example:

- *

-     *       0 -> '00' -> ('0' << 8) | '0' -> 0x3030
-     *       1 -> '01' -> ('0' << 8) | '1' -> 0x3130
-     *       2 -> '02' -> ('0' << 8) | '2' -> 0x3230
-     *
-     *     ...
-     *
-     *      10 -> '0a' -> ('0' << 8) | 'a' -> 0x3061
-     *      11 -> '0b' -> ('0' << 8) | 'b' -> 0x3062
-     *      12 -> '0c' -> ('0' << 8) | 'c' -> 0x3063
-     *
-     *     ...
-     *
-     *      26 -> '1a' -> ('1' << 8) | 'a' -> 0x3161
-     *      27 -> '1b' -> ('1' << 8) | 'b' -> 0x3162
-     *      28 -> '1c' -> ('1' << 8) | 'c' -> 0x3163
-     *
-     *     ...
-     *
-     *     253 -> 'fd' -> ('f' << 8) | 'd' -> 0x6664
-     *     254 -> 'fe' -> ('f' << 8) | 'e' -> 0x6665
-     *     255 -> 'ff' -> ('f' << 8) | 'f' -> 0x6666
-     * 
- *

use like this: - *

-     *     int v = 254;
-     *
-     *     char[] chars = new char[2];
-     *
-     *     short i = DIGITS[v]; // 26213
-     *
-     *     chars[0] = (char) (byte) (i >> 8); // 'f'
-     *     chars[1] = (char) (byte) i;        // 'e'
-     * 
- */ @Stable private static final short[] DIGITS; @@ -85,10 +47,10 @@ final class HexDigits implements Digits { short[] digits = new short[16 * 16]; for (int i = 0; i < 16; i++) { - short hi = (short) ((i < 10 ? i + '0' : i - 10 + 'a') << 8); + short hi = (short) (i < 10 ? i + '0' : i - 10 + 'a'); for (int j = 0; j < 16; j++) { - short lo = (short) (j < 10 ? j + '0' : j - 10 + 'a'); + short lo = (short) ((j < 10 ? j + '0' : j - 10 + 'a') << 8); digits[(i << 4) + j] = (short) (hi | lo); } } @@ -108,7 +70,7 @@ private HexDigits() { * The integer is passed byte-wise to allow reordering of execution. */ static int packDigits(int b0, int b1) { - return (DIGITS[b0 & 0xff] << 16) | DIGITS[b1 & 0xff]; + return DIGITS[b0 & 0xff] | (DIGITS[b1 & 0xff] << 16); } /** @@ -117,10 +79,10 @@ static int packDigits(int b0, int b1) { * The integer is passed byte-wise to allow reordering of execution. */ static long packDigits(int b0, int b1, int b2, int b3) { - return (((long) DIGITS[b0 & 0xff]) << 48) - | (((long) DIGITS[b1 & 0xff]) << 32) - | (DIGITS[b2 & 0xff] << 16) - | DIGITS[b3 & 0xff]; + return DIGITS[b0 & 0xff] + | (DIGITS[b1 & 0xff] << 16) + | (((long) DIGITS[b2 & 0xff]) << 32) + | (((long) DIGITS[b3 & 0xff]) << 48); } @Override @@ -129,15 +91,15 @@ public int digits(long value, byte[] buffer, int index, while ((value & ~0xFF) != 0) { int digits = DIGITS[(int) (value & 0xFF)]; value >>>= 8; - putCharMH.invokeExact(buffer, --index, digits & 0xFF); putCharMH.invokeExact(buffer, --index, digits >> 8); + putCharMH.invokeExact(buffer, --index, digits & 0xFF); } int digits = DIGITS[(int) (value & 0xFF)]; - putCharMH.invokeExact(buffer, --index, digits & 0xFF); + putCharMH.invokeExact(buffer, --index, digits >> 8); if (0xF < value) { - putCharMH.invokeExact(buffer, --index, digits >> 8); + putCharMH.invokeExact(buffer, --index, digits & 0xFF); } return index; diff --git a/src/java.base/share/classes/java/util/UUID.java b/src/java.base/share/classes/java/util/UUID.java index 253833de4aaa9..733413a4e45f2 100644 --- a/src/java.base/share/classes/java/util/UUID.java +++ b/src/java.base/share/classes/java/util/UUID.java @@ -31,9 +31,7 @@ import jdk.internal.access.JavaLangAccess; import jdk.internal.access.SharedSecrets; -import jdk.internal.misc.Unsafe; - -import static jdk.internal.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET; +import jdk.internal.util.ByteArrayLittleEndian; /** * A class that represents an immutable universally unique identifier (UUID). @@ -78,8 +76,6 @@ * @since 1.5 */ public final class UUID implements java.io.Serializable, Comparable { - private static final Unsafe UNSAFE = Unsafe.getUnsafe(); - /** * Explicit serialVersionUID for interoperability. */ @@ -472,40 +468,34 @@ public String toString() { long lsb = leastSigBits; long msb = mostSigBits; byte[] buf = new byte[36]; - UNSAFE.putLongUnaligned( + ByteArrayLittleEndian.setLong( buf, - ARRAY_BYTE_BASE_OFFSET, - HexDigits.packDigits((int) (msb >> 56), (int) (msb >> 48), (int) (msb >> 40), (int) (msb >> 32)), - true); + 0, + HexDigits.packDigits((int) (msb >> 56), (int) (msb >> 48), (int) (msb >> 40), (int) (msb >> 32))); buf[8] = '-'; - UNSAFE.putIntUnaligned( + ByteArrayLittleEndian.setInt( buf, - ARRAY_BYTE_BASE_OFFSET + 9, - HexDigits.packDigits(((int) msb) >> 24, ((int) msb) >> 16), - true); + 9, + HexDigits.packDigits(((int) msb) >> 24, ((int) msb) >> 16)); buf[13] = '-'; - UNSAFE.putIntUnaligned( + ByteArrayLittleEndian.setInt( buf, - ARRAY_BYTE_BASE_OFFSET + 14, - HexDigits.packDigits(((int) msb) >> 8, (int) msb), - true); + 14, + HexDigits.packDigits(((int) msb) >> 8, (int) msb)); buf[18] = '-'; - UNSAFE.putIntUnaligned( + ByteArrayLittleEndian.setInt( buf, - ARRAY_BYTE_BASE_OFFSET + 19, - HexDigits.packDigits((int) (lsb >> 56), (int) (lsb >> 48)), - true); + 19, + HexDigits.packDigits((int) (lsb >> 56), (int) (lsb >> 48))); buf[23] = '-'; - UNSAFE.putLongUnaligned( + ByteArrayLittleEndian.setLong( buf, - ARRAY_BYTE_BASE_OFFSET + 24, - HexDigits.packDigits(((int) (lsb >> 40)), (int) (lsb >> 32), ((int) lsb) >> 24, ((int) lsb) >> 16), - true); - UNSAFE.putIntUnaligned( + 24, + HexDigits.packDigits(((int) (lsb >> 40)), (int) (lsb >> 32), ((int) lsb) >> 24, ((int) lsb) >> 16)); + ByteArrayLittleEndian.setInt( buf, - ARRAY_BYTE_BASE_OFFSET + 32, - HexDigits.packDigits(((int) lsb) >> 8, (int) lsb), - true); + 32, + HexDigits.packDigits(((int) lsb) >> 8, (int) lsb)); try { return jla.newStringNoRepl(buf, StandardCharsets.ISO_8859_1); From 141880f79ff21400a47f6555df78347c11229829 Mon Sep 17 00:00:00 2001 From: "shaojin.wensj" Date: Tue, 5 Sep 2023 12:21:18 +0800 Subject: [PATCH 10/15] fix java doc, big-endian -> little-endian --- src/java.base/share/classes/java/util/HexDigits.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/util/HexDigits.java b/src/java.base/share/classes/java/util/HexDigits.java index ca9f6c1157706..65fb0c4c0c821 100644 --- a/src/java.base/share/classes/java/util/HexDigits.java +++ b/src/java.base/share/classes/java/util/HexDigits.java @@ -65,7 +65,7 @@ private HexDigits() { } /** - * Return a big-endian packed integer for the 4 ASCII bytes for an input unsigned 2-byte integer. + * Return a little-endian packed integer for the 4 ASCII bytes for an input unsigned 2-byte integer. * {@code b0} is the most significant byte and {@code b1} is the least significant byte. * The integer is passed byte-wise to allow reordering of execution. */ @@ -74,7 +74,7 @@ static int packDigits(int b0, int b1) { } /** - * Return a big-endian packed long for the 8 ASCII bytes for an input unsigned 4-byte integer. + * Return a little-endian packed long for the 8 ASCII bytes for an input unsigned 4-byte integer. * {@code b0} is the most significant byte and {@code b3} is the least significant byte. * The integer is passed byte-wise to allow reordering of execution. */ From 3f6d35df91b87f825d95531b3d1e6df3b38caf43 Mon Sep 17 00:00:00 2001 From: "shaojin.wensj" Date: Tue, 5 Sep 2023 12:29:54 +0800 Subject: [PATCH 11/15] remove redundant parentheses --- src/java.base/share/classes/java/util/UUID.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/util/UUID.java b/src/java.base/share/classes/java/util/UUID.java index 733413a4e45f2..5b2dfbe46be99 100644 --- a/src/java.base/share/classes/java/util/UUID.java +++ b/src/java.base/share/classes/java/util/UUID.java @@ -491,7 +491,7 @@ public String toString() { ByteArrayLittleEndian.setLong( buf, 24, - HexDigits.packDigits(((int) (lsb >> 40)), (int) (lsb >> 32), ((int) lsb) >> 24, ((int) lsb) >> 16)); + HexDigits.packDigits((int) (lsb >> 40), (int) (lsb >> 32), ((int) lsb) >> 24, ((int) lsb) >> 16)); ByteArrayLittleEndian.setInt( buf, 32, From 747e81359761f553bbe946b8521c8c8679c4f3d9 Mon Sep 17 00:00:00 2001 From: "shaojin.wensj" Date: Fri, 8 Sep 2023 07:55:03 +0800 Subject: [PATCH 12/15] reversed how & hi --- src/java.base/share/classes/java/util/HexDigits.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/classes/java/util/HexDigits.java b/src/java.base/share/classes/java/util/HexDigits.java index 65fb0c4c0c821..0b2c96740683c 100644 --- a/src/java.base/share/classes/java/util/HexDigits.java +++ b/src/java.base/share/classes/java/util/HexDigits.java @@ -47,11 +47,11 @@ final class HexDigits implements Digits { short[] digits = new short[16 * 16]; for (int i = 0; i < 16; i++) { - short hi = (short) (i < 10 ? i + '0' : i - 10 + 'a'); + short lo = (short) (i < 10 ? i + '0' : i - 10 + 'a'); for (int j = 0; j < 16; j++) { - short lo = (short) ((j < 10 ? j + '0' : j - 10 + 'a') << 8); - digits[(i << 4) + j] = (short) (hi | lo); + short hi = (short) ((j < 10 ? j + '0' : j - 10 + 'a') << 8); + digits[(i << 4) + j] = (short) (lo | hi); } } From 384354d9929e3e938c9cf66379cff14e1bef8ef3 Mon Sep 17 00:00:00 2001 From: "shaojin.wensj" Date: Sat, 9 Sep 2023 03:51:43 +0800 Subject: [PATCH 13/15] add DIGITS description --- .../share/classes/java/util/HexDigits.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/java.base/share/classes/java/util/HexDigits.java b/src/java.base/share/classes/java/util/HexDigits.java index 0b2c96740683c..d8b0012cddb1b 100644 --- a/src/java.base/share/classes/java/util/HexDigits.java +++ b/src/java.base/share/classes/java/util/HexDigits.java @@ -35,6 +35,33 @@ * @since 21 */ final class HexDigits implements Digits { + /** + * Each element of the array represents the ascii encoded + * hex relative to its index, for example:

+ *

+     *       0 -> '00' -> '0' | ('0' << 8) -> 0x3030
+     *       1 -> '01' -> '0' | ('1' << 8) -> 0x3130
+     *       2 -> '02' -> '0' | ('2' << 8) -> 0x3230
+     *
+     *     ...
+     *
+     *      10 -> '0a' -> '0' | ('a' << 8) -> 0x6130
+     *      11 -> '0b' -> '0' | ('b' << 8) -> 0x6230
+     *      12 -> '0c' -> '0' | ('b' << 8) -> 0x6330
+     *
+     *     ...
+     *
+     *      26 -> '1a' -> '1' | ('a' << 8) -> 0x6131
+     *      27 -> '1b' -> '1' | ('b' << 8) -> 0x6231
+     *      28 -> '1c' -> '1' | ('c' << 8) -> 0x6331
+     *
+     *     ...
+     *
+     *     253 -> 'fd' -> 'f' | ('d' << 8) -> 0x6466
+     *     254 -> 'fe' -> 'f' | ('e' << 8) -> 0x6566
+     *     255 -> 'ff' -> 'f' | ('f' << 8) -> 0x6666
+     * 
+ */ @Stable private static final short[] DIGITS; From 46b4b057e65a9c5f1df5f86f82e22afefe003e26 Mon Sep 17 00:00:00 2001 From: "shaojin.wensj" Date: Sat, 9 Sep 2023 04:28:49 +0800 Subject: [PATCH 14/15] lo | hi => hi | lo --- src/java.base/share/classes/java/util/HexDigits.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/util/HexDigits.java b/src/java.base/share/classes/java/util/HexDigits.java index d8b0012cddb1b..f4901ba443598 100644 --- a/src/java.base/share/classes/java/util/HexDigits.java +++ b/src/java.base/share/classes/java/util/HexDigits.java @@ -78,7 +78,7 @@ final class HexDigits implements Digits { for (int j = 0; j < 16; j++) { short hi = (short) ((j < 10 ? j + '0' : j - 10 + 'a') << 8); - digits[(i << 4) + j] = (short) (lo | hi); + digits[(i << 4) + j] = (short) (hi | lo); } } From 4f6ed3e67ee3ec50b6e3b5bb5f15e5691eb10773 Mon Sep 17 00:00:00 2001 From: "shaojin.wensj" Date: Wed, 13 Sep 2023 00:51:52 +0800 Subject: [PATCH 15/15] merge from master --- .../share/classes/java/util/UUID.java | 27 ++++---- .../classes/jdk/internal/util/HexDigits.java | 67 +++++++++---------- 2 files changed, 44 insertions(+), 50 deletions(-) diff --git a/src/java.base/share/classes/java/util/UUID.java b/src/java.base/share/classes/java/util/UUID.java index 78846ba48c23a..a82f523a66ffa 100644 --- a/src/java.base/share/classes/java/util/UUID.java +++ b/src/java.base/share/classes/java/util/UUID.java @@ -31,7 +31,8 @@ import jdk.internal.access.JavaLangAccess; import jdk.internal.access.SharedSecrets; -import jdk.internal.util.ByteArray; +import jdk.internal.util.ByteArrayLittleEndian; +import jdk.internal.util.HexDigits; /** * A class that represents an immutable universally unique identifier (UUID). @@ -469,34 +470,34 @@ public String toString() { long lsb = leastSigBits; long msb = mostSigBits; byte[] buf = new byte[36]; - ByteArray.setLong( + ByteArrayLittleEndian.setLong( buf, 0, - HexDigits.digit((int) (msb >> 56), (int) (msb >> 48), (int) (msb >> 40), (int) (msb >> 32))); + HexDigits.packDigits((int) (msb >> 56), (int) (msb >> 48), (int) (msb >> 40), (int) (msb >> 32))); buf[8] = '-'; - ByteArray.setInt( + ByteArrayLittleEndian.setInt( buf, 9, - HexDigits.digit(((int) msb) >> 24, ((int) msb) >> 16)); + HexDigits.packDigits(((int) msb) >> 24, ((int) msb) >> 16)); buf[13] = '-'; - ByteArray.setInt( + ByteArrayLittleEndian.setInt( buf, 14, - HexDigits.digit(((int) msb) >> 8, (int) msb)); + HexDigits.packDigits(((int) msb) >> 8, (int) msb)); buf[18] = '-'; - ByteArray.setInt( + ByteArrayLittleEndian.setInt( buf, 19, - HexDigits.digit((int) (lsb >> 56), (int) (lsb >> 48))); + HexDigits.packDigits((int) (lsb >> 56), (int) (lsb >> 48))); buf[23] = '-'; - ByteArray.setLong( + ByteArrayLittleEndian.setLong( buf, 24, - HexDigits.digit(((int) (lsb >> 40)), (int) (lsb >> 32), ((int) lsb) >> 24, ((int) lsb) >> 16)); - ByteArray.setInt( + HexDigits.packDigits((int) (lsb >> 40), (int) (lsb >> 32), ((int) lsb) >> 24, ((int) lsb) >> 16)); + ByteArrayLittleEndian.setInt( buf, 32, - HexDigits.digit(((int) lsb) >> 8, (int) lsb)); + HexDigits.packDigits(((int) lsb) >> 8, (int) lsb)); try { return jla.newStringNoRepl(buf, StandardCharsets.ISO_8859_1); diff --git a/src/java.base/share/classes/jdk/internal/util/HexDigits.java b/src/java.base/share/classes/jdk/internal/util/HexDigits.java index d04d8719e8347..5ffb454ae007d 100644 --- a/src/java.base/share/classes/jdk/internal/util/HexDigits.java +++ b/src/java.base/share/classes/jdk/internal/util/HexDigits.java @@ -39,38 +39,27 @@ public final class HexDigits implements Digits { * Each element of the array represents the ascii encoded * hex relative to its index, for example:

*

-     *       0 -> '00' -> ('0' << 8) | '0' -> 12336
-     *       1 -> '01' -> ('0' << 8) | '1' -> 12337
-     *       2 -> '02' -> ('0' << 8) | '2' -> 12338
+     *       0 -> '00' -> '0' | ('0' << 8) -> 0x3030
+     *       1 -> '01' -> '0' | ('1' << 8) -> 0x3130
+     *       2 -> '02' -> '0' | ('2' << 8) -> 0x3230
      *
      *     ...
      *
-     *      10 -> '0a' -> ('0' << 8) | 'a' -> 12385
-     *      11 -> '0b' -> ('0' << 8) | 'b' -> 12386
-     *      12 -> '0c' -> ('0' << 8) | 'b' -> 12387
+     *      10 -> '0a' -> '0' | ('a' << 8) -> 0x6130
+     *      11 -> '0b' -> '0' | ('b' << 8) -> 0x6230
+     *      12 -> '0c' -> '0' | ('b' << 8) -> 0x6330
      *
      *     ...
      *
-     *      26 -> '1a' -> ('1' << 8) | 'a' -> 12641
-     *      27 -> '1b' -> ('1' << 8) | 'b' -> 12642
-     *      28 -> '1c' -> ('1' << 8) | 'c' -> 12643
+     *      26 -> '1a' -> '1' | ('a' << 8) -> 0x6131
+     *      27 -> '1b' -> '1' | ('b' << 8) -> 0x6231
+     *      28 -> '1c' -> '1' | ('c' << 8) -> 0x6331
      *
      *     ...
      *
-     *     253 -> 'fd' -> ('f' << 8) | 'd' -> 26212
-     *     254 -> 'fe' -> ('f' << 8) | 'e' -> 26213
-     *     255 -> 'ff' -> ('f' << 8) | 'f' -> 26214
-     * 
- *

use like this: - *

-     *     int v = 254;
-     *
-     *     char[] chars = new char[2];
-     *
-     *     short i = DIGITS[v]; // 26213
-     *
-     *     chars[0] = (char) (byte) (i >> 8); // 'f'
-     *     chars[1] = (char) (byte) i;        // 'e'
+     *     253 -> 'fd' -> 'f' | ('d' << 8) -> 0x6466
+     *     254 -> 'fe' -> 'f' | ('e' << 8) -> 0x6566
+     *     255 -> 'ff' -> 'f' | ('f' << 8) -> 0x6666
      * 
*/ @Stable @@ -85,10 +74,10 @@ public final class HexDigits implements Digits { short[] digits = new short[16 * 16]; for (int i = 0; i < 16; i++) { - short hi = (short) ((i < 10 ? i + '0' : i - 10 + 'a') << 8); + short lo = (short) (i < 10 ? i + '0' : i - 10 + 'a'); for (int j = 0; j < 16; j++) { - short lo = (short) (j < 10 ? j + '0' : j - 10 + 'a'); + short hi = (short) ((j < 10 ? j + '0' : j - 10 + 'a') << 8); digits[(i << 4) + j] = (short) (hi | lo); } } @@ -103,20 +92,24 @@ private HexDigits() { } /** - * Combine two hex shorts into one int based on big endian + * Return a little-endian packed integer for the 4 ASCII bytes for an input unsigned 2-byte integer. + * {@code b0} is the most significant byte and {@code b1} is the least significant byte. + * The integer is passed byte-wise to allow reordering of execution. */ - public static int digit(int b0, int b1) { - return (DIGITS[b0 & 0xff] << 16) | DIGITS[b1 & 0xff]; + public static int packDigits(int b0, int b1) { + return DIGITS[b0 & 0xff] | (DIGITS[b1 & 0xff] << 16); } /** - * Combine four hex shorts into one long based on big endian + * Return a little-endian packed long for the 8 ASCII bytes for an input unsigned 4-byte integer. + * {@code b0} is the most significant byte and {@code b3} is the least significant byte. + * The integer is passed byte-wise to allow reordering of execution. */ - public static long digit(int b0, int b1, int b2, int b3) { - return (((long) DIGITS[b0 & 0xff]) << 48) - | (((long) DIGITS[b1 & 0xff]) << 32) - | (DIGITS[b2 & 0xff] << 16) - | DIGITS[b3 & 0xff]; + public static long packDigits(int b0, int b1, int b2, int b3) { + return DIGITS[b0 & 0xff] + | (DIGITS[b1 & 0xff] << 16) + | (((long) DIGITS[b2 & 0xff]) << 32) + | (((long) DIGITS[b3 & 0xff]) << 48); } @Override @@ -125,15 +118,15 @@ public int digits(long value, byte[] buffer, int index, while ((value & ~0xFF) != 0) { int digits = DIGITS[(int) (value & 0xFF)]; value >>>= 8; - putCharMH.invokeExact(buffer, --index, digits & 0xFF); putCharMH.invokeExact(buffer, --index, digits >> 8); + putCharMH.invokeExact(buffer, --index, digits & 0xFF); } int digits = DIGITS[(int) (value & 0xFF)]; - putCharMH.invokeExact(buffer, --index, digits & 0xFF); + putCharMH.invokeExact(buffer, --index, digits >> 8); if (0xF < value) { - putCharMH.invokeExact(buffer, --index, digits >> 8); + putCharMH.invokeExact(buffer, --index, digits & 0xFF); } return index;