Skip to content

Commit b0a371b

Browse files
committed
8343925: [BACKOUT] JDK-8342650 Move getChars to DecimalDigits
Reviewed-by: jpai, alanb, liach
1 parent 0759224 commit b0a371b

File tree

12 files changed

+376
-405
lines changed

12 files changed

+376
-405
lines changed

src/java.base/share/classes/java/lang/AbstractStringBuilder.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -830,9 +830,9 @@ public AbstractStringBuilder append(int i) {
830830
int spaceNeeded = count + DecimalDigits.stringSize(i);
831831
ensureCapacityInternal(spaceNeeded);
832832
if (isLatin1()) {
833-
DecimalDigits.getCharsLatin1(i, spaceNeeded, value);
833+
StringLatin1.getChars(i, spaceNeeded, value);
834834
} else {
835-
DecimalDigits.getCharsUTF16(i, spaceNeeded, value);
835+
StringUTF16.getChars(i, count, spaceNeeded, value);
836836
}
837837
this.count = spaceNeeded;
838838
return this;
@@ -855,9 +855,9 @@ public AbstractStringBuilder append(long l) {
855855
int spaceNeeded = count + DecimalDigits.stringSize(l);
856856
ensureCapacityInternal(spaceNeeded);
857857
if (isLatin1()) {
858-
DecimalDigits.getCharsLatin1(l, spaceNeeded, value);
858+
StringLatin1.getChars(l, spaceNeeded, value);
859859
} else {
860-
DecimalDigits.getCharsUTF16(l, spaceNeeded, value);
860+
StringUTF16.getChars(l, count, spaceNeeded, value);
861861
}
862862
this.count = spaceNeeded;
863863
return this;

src/java.base/share/classes/java/lang/Integer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -432,11 +432,11 @@ public static String toString(int i) {
432432
int size = DecimalDigits.stringSize(i);
433433
if (COMPACT_STRINGS) {
434434
byte[] buf = new byte[size];
435-
DecimalDigits.getCharsLatin1(i, size, buf);
435+
StringLatin1.getChars(i, size, buf);
436436
return new String(buf, LATIN1);
437437
} else {
438438
byte[] buf = new byte[size * 2];
439-
DecimalDigits.getCharsUTF16(i, size, buf);
439+
StringUTF16.getChars(i, size, buf);
440440
return new String(buf, UTF16);
441441
}
442442
}

src/java.base/share/classes/java/lang/Long.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -462,11 +462,11 @@ public static String toString(long i) {
462462
int size = DecimalDigits.stringSize(i);
463463
if (COMPACT_STRINGS) {
464464
byte[] buf = new byte[size];
465-
DecimalDigits.getCharsLatin1(i, size, buf);
465+
StringLatin1.getChars(i, size, buf);
466466
return new String(buf, LATIN1);
467467
} else {
468468
byte[] buf = new byte[size * 2];
469-
DecimalDigits.getCharsUTF16(i, size, buf);
469+
StringUTF16.getChars(i, size, buf);
470470
return new String(buf, UTF16);
471471
}
472472
}

src/java.base/share/classes/java/lang/StringConcatHelper.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -298,12 +298,12 @@ static long prepend(long indexCoder, byte[] buf, char value, String prefix) {
298298
static long prepend(long indexCoder, byte[] buf, int value, String prefix) {
299299
int index = (int)indexCoder;
300300
if (indexCoder < UTF16) {
301-
index = DecimalDigits.getCharsLatin1(value, index, buf);
301+
index = StringLatin1.getChars(value, index, buf);
302302
index -= prefix.length();
303303
prefix.getBytes(buf, index, String.LATIN1);
304304
return index;
305305
} else {
306-
index = DecimalDigits.getCharsUTF16(value, index, buf);
306+
index = StringUTF16.getChars(value, index, buf);
307307
index -= prefix.length();
308308
prefix.getBytes(buf, index, String.UTF16);
309309
return index | UTF16;
@@ -324,12 +324,12 @@ static long prepend(long indexCoder, byte[] buf, int value, String prefix) {
324324
static long prepend(long indexCoder, byte[] buf, long value, String prefix) {
325325
int index = (int)indexCoder;
326326
if (indexCoder < UTF16) {
327-
index = DecimalDigits.getCharsLatin1(value, index, buf);
327+
index = StringLatin1.getChars(value, index, buf);
328328
index -= prefix.length();
329329
prefix.getBytes(buf, index, String.LATIN1);
330330
return index;
331331
} else {
332-
index = DecimalDigits.getCharsUTF16(value, index, buf);
332+
index = StringUTF16.getChars(value, index, buf);
333333
index -= prefix.length();
334334
prefix.getBytes(buf, index, String.UTF16);
335335
return index | UTF16;
@@ -682,11 +682,11 @@ static int prepend(int index, byte coder, byte[] buf, char value, String prefix)
682682
*/
683683
static int prepend(int index, byte coder, byte[] buf, int value, String prefix) {
684684
if (coder == String.LATIN1) {
685-
index = DecimalDigits.getCharsLatin1(value, index, buf);
685+
index = StringLatin1.getChars(value, index, buf);
686686
index -= prefix.length();
687687
prefix.getBytes(buf, index, String.LATIN1);
688688
} else {
689-
index = DecimalDigits.getCharsUTF16(value, index, buf);
689+
index = StringUTF16.getChars(value, index, buf);
690690
index -= prefix.length();
691691
prefix.getBytes(buf, index, String.UTF16);
692692
}
@@ -706,11 +706,11 @@ static int prepend(int index, byte coder, byte[] buf, int value, String prefix)
706706
*/
707707
static int prepend(int index, byte coder, byte[] buf, long value, String prefix) {
708708
if (coder == String.LATIN1) {
709-
index = DecimalDigits.getCharsLatin1(value, index, buf);
709+
index = StringLatin1.getChars(value, index, buf);
710710
index -= prefix.length();
711711
prefix.getBytes(buf, index, String.LATIN1);
712712
} else {
713-
index = DecimalDigits.getCharsUTF16(value, index, buf);
713+
index = StringUTF16.getChars(value, index, buf);
714714
index -= prefix.length();
715715
prefix.getBytes(buf, index, String.UTF16);
716716
}

src/java.base/share/classes/java/lang/StringLatin1.java

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import java.util.stream.StreamSupport;
3535
import jdk.internal.misc.Unsafe;
3636
import jdk.internal.util.ArraysSupport;
37+
import jdk.internal.util.DecimalDigits;
3738
import jdk.internal.vm.annotation.IntrinsicCandidate;
3839

3940
import static java.lang.String.LATIN1;
@@ -85,6 +86,120 @@ public static byte[] inflate(byte[] value, int off, int len) {
8586
return ret;
8687
}
8788

89+
/**
90+
* Places characters representing the integer i into the
91+
* character array buf. The characters are placed into
92+
* the buffer backwards starting with the least significant
93+
* digit at the specified index (exclusive), and working
94+
* backwards from there.
95+
*
96+
* @implNote This method converts positive inputs into negative
97+
* values, to cover the Integer.MIN_VALUE case. Converting otherwise
98+
* (negative to positive) will expose -Integer.MIN_VALUE that overflows
99+
* integer.
100+
*
101+
* @param i value to convert
102+
* @param index next index, after the least significant digit
103+
* @param buf target buffer, Latin1-encoded
104+
* @return index of the most significant digit or minus sign, if present
105+
*/
106+
static int getChars(int i, int index, byte[] buf) {
107+
// Used by trusted callers. Assumes all necessary bounds checks have been done by the caller.
108+
int q;
109+
int charPos = index;
110+
111+
boolean negative = i < 0;
112+
if (!negative) {
113+
i = -i;
114+
}
115+
116+
// Generate two digits per iteration
117+
while (i <= -100) {
118+
q = i / 100;
119+
charPos -= 2;
120+
writeDigitPair(buf, charPos, (q * 100) - i);
121+
i = q;
122+
}
123+
124+
// We know there are at most two digits left at this point.
125+
if (i < -9) {
126+
charPos -= 2;
127+
writeDigitPair(buf, charPos, -i);
128+
} else {
129+
buf[--charPos] = (byte)('0' - i);
130+
}
131+
132+
if (negative) {
133+
buf[--charPos] = (byte)'-';
134+
}
135+
return charPos;
136+
}
137+
138+
/**
139+
* Places characters representing the long i into the
140+
* character array buf. The characters are placed into
141+
* the buffer backwards starting with the least significant
142+
* digit at the specified index (exclusive), and working
143+
* backwards from there.
144+
*
145+
* @implNote This method converts positive inputs into negative
146+
* values, to cover the Long.MIN_VALUE case. Converting otherwise
147+
* (negative to positive) will expose -Long.MIN_VALUE that overflows
148+
* long.
149+
*
150+
* @param i value to convert
151+
* @param index next index, after the least significant digit
152+
* @param buf target buffer, Latin1-encoded
153+
* @return index of the most significant digit or minus sign, if present
154+
*/
155+
static int getChars(long i, int index, byte[] buf) {
156+
// Used by trusted callers. Assumes all necessary bounds checks have been done by the caller.
157+
long q;
158+
int charPos = index;
159+
160+
boolean negative = (i < 0);
161+
if (!negative) {
162+
i = -i;
163+
}
164+
165+
// Get 2 digits/iteration using longs until quotient fits into an int
166+
while (i <= Integer.MIN_VALUE) {
167+
q = i / 100;
168+
charPos -= 2;
169+
writeDigitPair(buf, charPos, (int)((q * 100) - i));
170+
i = q;
171+
}
172+
173+
// Get 2 digits/iteration using ints
174+
int q2;
175+
int i2 = (int)i;
176+
while (i2 <= -100) {
177+
q2 = i2 / 100;
178+
charPos -= 2;
179+
writeDigitPair(buf, charPos, (q2 * 100) - i2);
180+
i2 = q2;
181+
}
182+
183+
// We know there are at most two digits left at this point.
184+
if (i2 < -9) {
185+
charPos -= 2;
186+
writeDigitPair(buf, charPos, -i2);
187+
} else {
188+
buf[--charPos] = (byte)('0' - i2);
189+
}
190+
191+
if (negative) {
192+
buf[--charPos] = (byte)'-';
193+
}
194+
return charPos;
195+
}
196+
197+
private static void writeDigitPair(byte[] buf, int charPos, int value) {
198+
short pair = DecimalDigits.digitPair(value);
199+
buf[charPos] = (byte)(pair);
200+
buf[charPos + 1] = (byte)(pair >> 8);
201+
}
202+
88203
public static void getChars(byte[] value, int srcBegin, int srcEnd, char[] dst, int dstBegin) {
89204
inflate(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
90205
}

src/java.base/share/classes/java/lang/StringUTF16.java

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535

3636
import jdk.internal.misc.Unsafe;
3737
import jdk.internal.util.ArraysSupport;
38+
import jdk.internal.util.DecimalDigits;
3839
import jdk.internal.vm.annotation.ForceInline;
3940
import jdk.internal.vm.annotation.IntrinsicCandidate;
4041

@@ -1512,6 +1513,20 @@ public static int codePointCountSB(byte[] val, int beginIndex, int endIndex) {
15121513
return codePointCount(val, beginIndex, endIndex, true /* checked */);
15131514
}
15141515

1516+
public static int getChars(int i, int begin, int end, byte[] value) {
1517+
checkBoundsBeginEnd(begin, end, value);
1518+
int pos = getChars(i, end, value);
1519+
assert begin == pos;
1520+
return pos;
1521+
}
1522+
1523+
public static int getChars(long l, int begin, int end, byte[] value) {
1524+
checkBoundsBeginEnd(begin, end, value);
1525+
int pos = getChars(l, end, value);
1526+
assert begin == pos;
1527+
return pos;
1528+
}
1529+
15151530
public static boolean contentEquals(byte[] v1, byte[] v2, int len) {
15161531
checkBoundsOffCount(0, len, v2);
15171532
for (int i = 0; i < len; i++) {
@@ -1647,6 +1662,109 @@ public static int lastIndexOfLatin1(byte[] src, int srcCount,
16471662

16481663
static final int MAX_LENGTH = Integer.MAX_VALUE >> 1;
16491664

1665+
// Used by trusted callers. Assumes all necessary bounds checks have
1666+
// been done by the caller.
1667+
1668+
/**
1669+
* This is a variant of {@link StringLatin1#getChars(int, int, byte[])}, but for
1670+
* UTF-16 coder.
1671+
*
1672+
* @param i value to convert
1673+
* @param index next index, after the least significant digit
1674+
* @param buf target buffer, UTF16-coded.
1675+
* @return index of the most significant digit or minus sign, if present
1676+
*/
1677+
static int getChars(int i, int index, byte[] buf) {
1678+
// Used by trusted callers. Assumes all necessary bounds checks have been done by the caller.
1679+
int q, r;
1680+
int charPos = index;
1681+
1682+
boolean negative = (i < 0);
1683+
if (!negative) {
1684+
i = -i;
1685+
}
1686+
1687+
// Get 2 digits/iteration using ints
1688+
while (i <= -100) {
1689+
q = i / 100;
1690+
r = (q * 100) - i;
1691+
i = q;
1692+
charPos -= 2;
1693+
putPair(buf, charPos, r);
1694+
}
1695+
1696+
// We know there are at most two digits left at this point.
1697+
if (i < -9) {
1698+
charPos -= 2;
1699+
putPair(buf, charPos, -i);
1700+
} else {
1701+
putChar(buf, --charPos, '0' - i);
1702+
}
1703+
1704+
if (negative) {
1705+
putChar(buf, --charPos, '-');
1706+
}
1707+
return charPos;
1708+
}
1709+
1710+
/**
1711+
* This is a variant of {@link StringLatin1#getChars(long, int, byte[])}, but for
1712+
* UTF-16 coder.
1713+
*
1714+
* @param i value to convert
1715+
* @param index next index, after the least significant digit
1716+
* @param buf target buffer, UTF16-coded.
1717+
* @return index of the most significant digit or minus sign, if present
1718+
*/
1719+
static int getChars(long i, int index, byte[] buf) {
1720+
// Used by trusted callers. Assumes all necessary bounds checks have been done by the caller.
1721+
long q;
1722+
int charPos = index;
1723+
1724+
boolean negative = (i < 0);
1725+
if (!negative) {
1726+
i = -i;
1727+
}
1728+
1729+
// Get 2 digits/iteration using longs until quotient fits into an int
1730+
while (i <= Integer.MIN_VALUE) {
1731+
q = i / 100;
1732+
charPos -= 2;
1733+
putPair(buf, charPos, (int)((q * 100) - i));
1734+
i = q;
1735+
}
1736+
1737+
// Get 2 digits/iteration using ints
1738+
int q2;
1739+
int i2 = (int)i;
1740+
while (i2 <= -100) {
1741+
q2 = i2 / 100;
1742+
charPos -= 2;
1743+
putPair(buf, charPos, (q2 * 100) - i2);
1744+
i2 = q2;
1745+
}
1746+
1747+
// We know there are at most two digits left at this point.
1748+
if (i2 < -9) {
1749+
charPos -= 2;
1750+
putPair(buf, charPos, -i2);
1751+
} else {
1752+
putChar(buf, --charPos, '0' - i2);
1753+
}
1754+
1755+
if (negative) {
1756+
putChar(buf, --charPos, '-');
1757+
}
1758+
return charPos;
1759+
}
1760+
1761+
private static void putPair(byte[] buf, int charPos, int v) {
1762+
int packed = (int) DecimalDigits.digitPair(v);
1763+
putChar(buf, charPos, packed & 0xFF);
1764+
putChar(buf, charPos + 1, packed >> 8);
1765+
}
1766+
// End of trusted methods.
1767+
16501768
public static void checkIndex(int off, byte[] val) {
16511769
String.checkIndex(off, length(val));
16521770
}

src/java.base/share/classes/java/lang/System.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2648,6 +2648,14 @@ public byte stringCoder(String str) {
26482648
return str.coder();
26492649
}
26502650

2651+
public int getCharsLatin1(long i, int index, byte[] buf) {
2652+
return StringLatin1.getChars(i, index, buf);
2653+
}
2654+
2655+
public int getCharsUTF16(long i, int index, byte[] buf) {
2656+
return StringUTF16.getChars(i, index, buf);
2657+
}
2658+
26512659
public String join(String prefix, String suffix, String delimiter, String[] elements, int size) {
26522660
return String.join(prefix, suffix, delimiter, elements, size);
26532661
}

0 commit comments

Comments
 (0)