Skip to content

Commit b550366

Browse files
committed
vector uuid toString
1 parent dfaa891 commit b550366

File tree

2 files changed

+43
-30
lines changed

2 files changed

+43
-30
lines changed

src/java.base/share/classes/java/util/UUID.java

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
import jdk.internal.access.JavaLangAccess;
3333
import jdk.internal.access.SharedSecrets;
34-
import jdk.internal.util.HexDigits;
34+
import jdk.internal.misc.Unsafe;
3535

3636
/**
3737
* A class that represents an immutable universally unique identifier (UUID).
@@ -76,6 +76,7 @@
7676
* @since 1.5
7777
*/
7878
public final class UUID implements java.io.Serializable, Comparable<UUID> {
79+
private static final Unsafe UNSAFE = Unsafe.getUnsafe();
7980

8081
/**
8182
* Explicit serialVersionUID for interoperability.
@@ -466,31 +467,59 @@ public long node() {
466467
*/
467468
@Override
468469
public String toString() {
469-
int i0 = (int) (mostSigBits >> 32);
470-
int i1 = (int) mostSigBits;
471-
int i2 = (int) (leastSigBits >> 32);
472-
int i3 = (int) leastSigBits;
473-
470+
long lsb = leastSigBits;
471+
long msb = mostSigBits;
474472
byte[] buf = new byte[36];
475-
HexDigits.put4(buf, 0, i0 >> 16);
476-
HexDigits.put4(buf, 4, i0);
477473
buf[8] = '-';
478-
HexDigits.put4(buf, 9, i1 >> 16);
479474
buf[13] = '-';
480-
HexDigits.put4(buf, 14, i1);
481475
buf[18] = '-';
482-
HexDigits.put4(buf, 19, i2 >> 16);
483476
buf[23] = '-';
484-
HexDigits.put4(buf, 24, i2);
485-
HexDigits.put4(buf, 28, i3 >> 16);
486-
HexDigits.put4(buf, 32, i3);
477+
putHex8(buf, 0, msb >> 32, false);
478+
putHex8(buf, 9, msb, true);
479+
putHex8(buf, 19, lsb >> 32, true);
480+
putHex8(buf, 28, lsb, false);
481+
487482
try {
488483
return jla.newStringNoRepl(buf, StandardCharsets.ISO_8859_1);
489484
} catch (CharacterCodingException cce) {
490485
throw new AssertionError(cce);
491486
}
492487
}
493488

489+
private static void putHex8(byte[] bytes, int off, long i, boolean separator) {
490+
long e = Long.expand(i, 0x0F0F_0F0F_0F0F_0F0FL);
491+
/*
492+
Use long to simulate vector operations and generate 8 hexadecimal characters at a time.
493+
------------
494+
0 = 0b0000_0000 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 0 + 0x30 + (i & 0xF) => '0'
495+
1 = 0b0000_0001 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 0 + 0x30 + (i & 0xF) => '1'
496+
2 = 0b0000_0010 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 0 + 0x30 + (i & 0xF) => '2'
497+
3 = 0b0000_0011 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 0 + 0x30 + (i & 0xF) => '3'
498+
4 = 0b0000_0100 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 0 + 0x30 + (i & 0xF) => '4'
499+
5 = 0b0000_0101 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 0 + 0x30 + (i & 0xF) => '5'
500+
6 = 0b0000_0110 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 0 + 0x30 + (i & 0xF) => '6'
501+
7 = 0b0000_0111 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 0 + 0x30 + (i & 0xF) => '7'
502+
8 = 0b0000_1000 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 0 + 0x30 + (i & 0xF) => '8'
503+
9 = 0b0000_1001 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 0 + 0x30 + (i & 0xF) => '9'
504+
10 = 0b0000_1010 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 39 + 0x30 + (i & 0xF) => 'a'
505+
11 = 0b0000_1011 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 39 + 0x30 + (i & 0xF) => 'b'
506+
12 = 0b0000_1100 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 39 + 0x30 + (i & 0xF) => 'c'
507+
13 = 0b0000_1101 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 39 + 0x30 + (i & 0xF) => 'd'
508+
14 = 0b0000_1110 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 39 + 0x30 + (i & 0xF) => 'e'
509+
15 = 0b0000_1111 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 39 + 0x30 + (i & 0xF) => 'f'
510+
*/
511+
long m = (e + 0x0606_0606_0606_0606L) & 0x1010_1010_1010_1010L;
512+
long x = ((m << 1) + (m >> 1) - (m >> 4))
513+
+ 0x3030_3030_3030_3030L
514+
+ (e & 0x0F0F_0F0F_0F0F_0F0FL);
515+
if (separator) {
516+
UNSAFE.putIntUnaligned(bytes, Unsafe.ARRAY_BYTE_BASE_OFFSET + off, (int) x, true);
517+
UNSAFE.putIntUnaligned(bytes, Unsafe.ARRAY_BYTE_BASE_OFFSET + off + 5, (int) (x >>> 32), true);
518+
} else {
519+
UNSAFE.putLongUnaligned(bytes, Unsafe.ARRAY_BYTE_BASE_OFFSET + off, x, true);
520+
}
521+
}
522+
494523
/**
495524
* Returns a hash code for this {@code UUID}.
496525
*

src/java.base/share/classes/jdk/internal/util/HexDigits.java

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -113,22 +113,6 @@ public static short digitPair(int i, boolean ucase) {
113113
: v;
114114
}
115115

116-
/**
117-
* Insert the unsigned 2-byte integer into the buffer as 4 hexadecimal digit ASCII bytes,
118-
* only least significant 16 bits of {@code value} are used.
119-
* @param buffer byte buffer to copy into
120-
* @param index insert point
121-
* @param value to convert
122-
*/
123-
public static void put4(byte[] buffer, int index, int value) {
124-
// Prepare an int value so C2 generates a 4-byte write instead of two 2-byte writes
125-
int v = (DIGITS[value & 0xff] << 16) | DIGITS[(value >> 8) & 0xff];
126-
buffer[index] = (byte) v;
127-
buffer[index + 1] = (byte) (v >> 8);
128-
buffer[index + 2] = (byte) (v >> 16);
129-
buffer[index + 3] = (byte) (v >> 24);
130-
}
131-
132116
/**
133117
* Insert digits for long value in buffer from high index to low index.
134118
*

0 commit comments

Comments
 (0)