|
31 | 31 |
|
32 | 32 | import jdk.internal.access.JavaLangAccess; |
33 | 33 | import jdk.internal.access.SharedSecrets; |
34 | | -import jdk.internal.util.HexDigits; |
| 34 | +import jdk.internal.misc.Unsafe; |
35 | 35 |
|
36 | 36 | /** |
37 | 37 | * A class that represents an immutable universally unique identifier (UUID). |
|
76 | 76 | * @since 1.5 |
77 | 77 | */ |
78 | 78 | public final class UUID implements java.io.Serializable, Comparable<UUID> { |
| 79 | + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); |
79 | 80 |
|
80 | 81 | /** |
81 | 82 | * Explicit serialVersionUID for interoperability. |
@@ -466,31 +467,59 @@ public long node() { |
466 | 467 | */ |
467 | 468 | @Override |
468 | 469 | 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; |
474 | 472 | byte[] buf = new byte[36]; |
475 | | - HexDigits.put4(buf, 0, i0 >> 16); |
476 | | - HexDigits.put4(buf, 4, i0); |
477 | 473 | buf[8] = '-'; |
478 | | - HexDigits.put4(buf, 9, i1 >> 16); |
479 | 474 | buf[13] = '-'; |
480 | | - HexDigits.put4(buf, 14, i1); |
481 | 475 | buf[18] = '-'; |
482 | | - HexDigits.put4(buf, 19, i2 >> 16); |
483 | 476 | 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 | + |
487 | 482 | try { |
488 | 483 | return jla.newStringNoRepl(buf, StandardCharsets.ISO_8859_1); |
489 | 484 | } catch (CharacterCodingException cce) { |
490 | 485 | throw new AssertionError(cce); |
491 | 486 | } |
492 | 487 | } |
493 | 488 |
|
| 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 | + |
494 | 523 | /** |
495 | 524 | * Returns a hash code for this {@code UUID}. |
496 | 525 | * |
|
0 commit comments