Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 6 additions & 40 deletions src/java.base/share/classes/java/lang/StringLatin1.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import jdk.internal.util.ArraysSupport;
import jdk.internal.util.DecimalDigits;
import jdk.internal.util.ByteArrayLittleEndian;
import jdk.internal.vm.annotation.IntrinsicCandidate;
import jdk.internal.vm.annotation.Stable;
Expand All @@ -43,41 +44,6 @@
import static java.lang.String.checkOffset;

final class StringLatin1 {

/**
* Each element of the array represents the packaging of two ascii characters based on little endian:<p>
* <pre>
* 00 -> '0' | ('0' << 8) -> 0x3030
* 01 -> '1' | ('0' << 8) -> 0x3130
* 02 -> '2' | ('0' << 8) -> 0x3230
*
* ...
*
* 10 -> '0' | ('1' << 8) -> 0x3031
* 11 -> '1' | ('1' << 8) -> 0x3131
* 12 -> '2' | ('1' << 8) -> 0x3231
*
* ...
*
* 97 -> '7' | ('9' << 8) -> 0x3739
* 98 -> '8' | ('9' << 8) -> 0x3839
* 99 -> '9' | ('9' << 8) -> 0x3939
* </pre>
*/
@Stable
static final short[] PACKED_DIGITS = new short[] {
0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530, 0x3630, 0x3730, 0x3830, 0x3930,
0x3031, 0x3131, 0x3231, 0x3331, 0x3431, 0x3531, 0x3631, 0x3731, 0x3831, 0x3931,
0x3032, 0x3132, 0x3232, 0x3332, 0x3432, 0x3532, 0x3632, 0x3732, 0x3832, 0x3932,
0x3033, 0x3133, 0x3233, 0x3333, 0x3433, 0x3533, 0x3633, 0x3733, 0x3833, 0x3933,
0x3034, 0x3134, 0x3234, 0x3334, 0x3434, 0x3534, 0x3634, 0x3734, 0x3834, 0x3934,
0x3035, 0x3135, 0x3235, 0x3335, 0x3435, 0x3535, 0x3635, 0x3735, 0x3835, 0x3935,
0x3036, 0x3136, 0x3236, 0x3336, 0x3436, 0x3536, 0x3636, 0x3736, 0x3836, 0x3936,
0x3037, 0x3137, 0x3237, 0x3337, 0x3437, 0x3537, 0x3637, 0x3737, 0x3837, 0x3937,
0x3038, 0x3138, 0x3238, 0x3338, 0x3438, 0x3538, 0x3638, 0x3738, 0x3838, 0x3938,
0x3039, 0x3139, 0x3239, 0x3339, 0x3439, 0x3539, 0x3639, 0x3739, 0x3839, 0x3939
};

public static char charAt(byte[] value, int index) {
checkIndex(index, value.length);
return (char)(value[index] & 0xff);
Expand Down Expand Up @@ -148,13 +114,13 @@ static int getChars(int i, int index, byte[] buf) {
r = (q * 100) - i;
i = q;
charPos -= 2;
ByteArrayLittleEndian.setShort(buf, charPos, PACKED_DIGITS[r]);
ByteArrayLittleEndian.setShort(buf, charPos, DecimalDigits.digitPair(r));
}

// We know there are at most two digits left at this point.
if (i < -9) {
charPos -= 2;
ByteArrayLittleEndian.setShort(buf, charPos, PACKED_DIGITS[-i]);
ByteArrayLittleEndian.setShort(buf, charPos, DecimalDigits.digitPair(-i));
} else {
buf[--charPos] = (byte)('0' - i);
}
Expand Down Expand Up @@ -196,7 +162,7 @@ static int getChars(long i, int index, byte[] buf) {
while (i <= Integer.MIN_VALUE) {
q = i / 100;
charPos -= 2;
ByteArrayLittleEndian.setShort(buf, charPos, PACKED_DIGITS[(int)((q * 100) - i)]);
ByteArrayLittleEndian.setShort(buf, charPos, DecimalDigits.digitPair((int)((q * 100) - i)));
i = q;
}

Expand All @@ -206,14 +172,14 @@ static int getChars(long i, int index, byte[] buf) {
while (i2 <= -100) {
q2 = i2 / 100;
charPos -= 2;
ByteArrayLittleEndian.setShort(buf, charPos, PACKED_DIGITS[(q2 * 100) - i2]);
ByteArrayLittleEndian.setShort(buf, charPos, DecimalDigits.digitPair((q2 * 100) - i2));
i2 = q2;
}

// We know there are at most two digits left at this point.
if (i2 < -9) {
charPos -= 2;
ByteArrayLittleEndian.setShort(buf, charPos, PACKED_DIGITS[-i2]);
ByteArrayLittleEndian.setShort(buf, charPos, DecimalDigits.digitPair(-i2));
} else {
buf[--charPos] = (byte)('0' - i2);
}
Expand Down
3 changes: 2 additions & 1 deletion src/java.base/share/classes/java/lang/StringUTF16.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import jdk.internal.util.ArraysSupport;
import jdk.internal.util.DecimalDigits;
import jdk.internal.vm.annotation.DontInline;
import jdk.internal.vm.annotation.ForceInline;
import jdk.internal.vm.annotation.IntrinsicCandidate;
Expand Down Expand Up @@ -1612,7 +1613,7 @@ static int getChars(long i, int index, byte[] buf) {
}

private static void putPair(byte[] buf, int charPos, int v) {
int packed = (int) StringLatin1.PACKED_DIGITS[v];
int packed = (int) DecimalDigits.digitPair(v);
putChar(buf, charPos, packed & 0xFF);
putChar(buf, charPos + 1, packed >> 8);
}
Expand Down
3 changes: 3 additions & 0 deletions src/java.base/share/classes/java/util/FormatItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
import jdk.internal.access.JavaLangAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.util.FormatConcatItem;
import jdk.internal.util.DecimalDigits;
import jdk.internal.util.HexDigits;
import jdk.internal.util.OctalDigits;

import static java.lang.invoke.MethodType.methodType;

Expand Down
1 change: 1 addition & 0 deletions src/java.base/share/classes/java/util/UUID.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import jdk.internal.access.JavaLangAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.util.ByteArray;
import jdk.internal.util.HexDigits;

/**
* A class that represents an immutable universally unique identifier (UUID).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
* questions.
*/

package java.util;
package jdk.internal.util;

import java.lang.invoke.MethodHandle;

Expand All @@ -34,29 +34,46 @@
*
* @since 21
*/
final class DecimalDigits implements Digits {
public final class DecimalDigits implements Digits {

/**
* Each element of the array represents the packaging of two ascii characters based on little endian:<p>
* <pre>
* 00 -> '0' | ('0' << 8) -> 0x3030
* 01 -> '1' | ('0' << 8) -> 0x3130
* 02 -> '2' | ('0' << 8) -> 0x3230
*
* ...
*
* 10 -> '0' | ('1' << 8) -> 0x3031
* 11 -> '1' | ('1' << 8) -> 0x3131
* 12 -> '2' | ('1' << 8) -> 0x3231
*
* ...
*
* 97 -> '7' | ('9' << 8) -> 0x3739
* 98 -> '8' | ('9' << 8) -> 0x3839
* 99 -> '9' | ('9' << 8) -> 0x3939
* </pre>
*/
@Stable
private static final short[] DIGITS;
private static final short[] DIGITS = new short[] {
0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530, 0x3630, 0x3730, 0x3830, 0x3930,
0x3031, 0x3131, 0x3231, 0x3331, 0x3431, 0x3531, 0x3631, 0x3731, 0x3831, 0x3931,
0x3032, 0x3132, 0x3232, 0x3332, 0x3432, 0x3532, 0x3632, 0x3732, 0x3832, 0x3932,
0x3033, 0x3133, 0x3233, 0x3333, 0x3433, 0x3533, 0x3633, 0x3733, 0x3833, 0x3933,
0x3034, 0x3134, 0x3234, 0x3334, 0x3434, 0x3534, 0x3634, 0x3734, 0x3834, 0x3934,
0x3035, 0x3135, 0x3235, 0x3335, 0x3435, 0x3535, 0x3635, 0x3735, 0x3835, 0x3935,
0x3036, 0x3136, 0x3236, 0x3336, 0x3436, 0x3536, 0x3636, 0x3736, 0x3836, 0x3936,
0x3037, 0x3137, 0x3237, 0x3337, 0x3437, 0x3537, 0x3637, 0x3737, 0x3837, 0x3937,
0x3038, 0x3138, 0x3238, 0x3338, 0x3438, 0x3538, 0x3638, 0x3738, 0x3838, 0x3938,
0x3039, 0x3139, 0x3239, 0x3339, 0x3439, 0x3539, 0x3639, 0x3739, 0x3839, 0x3939
};

/**
* Singleton instance of DecimalDigits.
*/
static final Digits INSTANCE = new DecimalDigits();

static {
short[] digits = new short[10 * 10];

for (int i = 0; i < 10; i++) {
short hi = (short) ((i + '0') << 8);

for (int j = 0; j < 10; j++) {
short lo = (short) (j + '0');
digits[i * 10 + j] = (short) (hi | lo);
}
}

DIGITS = digits;
}
public static final Digits INSTANCE = new DecimalDigits();

/**
* Constructor.
Expand All @@ -80,8 +97,8 @@ public int digits(long value, byte[] buffer, int index,
value = q;
int digits = DIGITS[r];

putCharMH.invokeExact(buffer, --index, digits & 0xFF);
putCharMH.invokeExact(buffer, --index, digits >> 8);
putCharMH.invokeExact(buffer, --index, digits & 0xFF);
}

int iq, ivalue = (int)value;
Expand All @@ -90,19 +107,19 @@ public int digits(long value, byte[] buffer, int index,
r = (iq * 100) - ivalue;
ivalue = iq;
int digits = DIGITS[r];
putCharMH.invokeExact(buffer, --index, digits & 0xFF);
putCharMH.invokeExact(buffer, --index, digits >> 8);
putCharMH.invokeExact(buffer, --index, digits & 0xFF);
}

if (ivalue < 0) {
ivalue = -ivalue;
}

int digits = DIGITS[ivalue];
putCharMH.invokeExact(buffer, --index, digits & 0xFF);
putCharMH.invokeExact(buffer, --index, digits >> 8);

if (9 < ivalue) {
putCharMH.invokeExact(buffer, --index, digits >> 8);
putCharMH.invokeExact(buffer, --index, digits & 0xFF);
}

if (negative) {
Expand Down Expand Up @@ -131,4 +148,13 @@ public int size(long value) {

return 19 + sign;
}

/**
* For values from 0 to 99 return a short encoding a pair of ASCII-encoded digit characters in little-endian
* @param i value to convert
* @return a short encoding a pair of ASCII-encoded digit characters
*/
public static short digitPair(int i) {
return DIGITS[i];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
* questions.
*/

package java.util;
package jdk.internal.util;

import java.lang.invoke.MethodHandle;

Expand All @@ -33,7 +33,7 @@
*
* @since 21
*/
sealed interface Digits permits DecimalDigits, HexDigits, OctalDigits {
public sealed interface Digits permits DecimalDigits, HexDigits, OctalDigits {
/**
* Insert digits for long value in buffer from high index to low index.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
* questions.
*/

package java.util;
package jdk.internal.util;

import java.lang.invoke.MethodHandle;

Expand All @@ -34,7 +34,7 @@
*
* @since 21
*/
final class HexDigits implements Digits {
public final class HexDigits implements Digits {
/**
* Each element of the array represents the ascii encoded
* hex relative to its index, for example:<p>
Expand Down Expand Up @@ -79,7 +79,7 @@ final class HexDigits implements Digits {
/**
* Singleton instance of HexDigits.
*/
static final Digits INSTANCE = new HexDigits();
public static final Digits INSTANCE = new HexDigits();

static {
short[] digits = new short[16 * 16];
Expand All @@ -105,14 +105,14 @@ private HexDigits() {
/**
* Combine two hex shorts into one int based on big endian
*/
static int digit(int b0, int b1) {
public static int digit(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) {
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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
* questions.
*/

package java.util;
package jdk.internal.util;

import java.lang.invoke.MethodHandle;

Expand All @@ -34,23 +34,23 @@
*
* @since 21
*/
final class OctalDigits implements Digits {
public final class OctalDigits implements Digits {
@Stable
private static final short[] DIGITS;

/**
* Singleton instance of OctalDigits.
*/
static final Digits INSTANCE = new OctalDigits();
public static final Digits INSTANCE = new OctalDigits();

static {
short[] digits = new short[8 * 8];

for (int i = 0; i < 8; i++) {
short hi = (short) ((i + '0') << 8);
short lo = (short) (i + '0');

for (int j = 0; j < 8; j++) {
short lo = (short) (j + '0');
short hi = (short) ((j + '0') << 8);
digits[(i << 3) + j] = (short) (hi | lo);
}
}
Expand All @@ -70,15 +70,15 @@ public int digits(long value, byte[] buffer, int index,
while ((value & ~0x3F) != 0) {
int digits = DIGITS[(int) (value & 0x3F)];
value >>>= 6;
putCharMH.invokeExact(buffer, --index, digits & 0xFF);
putCharMH.invokeExact(buffer, --index, digits >> 8);
putCharMH.invokeExact(buffer, --index, digits & 0xFF);
}

int digits = DIGITS[(int) (value & 0x3F)];
putCharMH.invokeExact(buffer, --index, digits & 0xFF);
putCharMH.invokeExact(buffer, --index, digits >> 8);

if (7 < value) {
putCharMH.invokeExact(buffer, --index, digits >> 8);
putCharMH.invokeExact(buffer, --index, digits & 0xFF);
}

return index;
Expand Down