Skip to content

Commit 07871cd

Browse files
committed
8357063: Document preconditions for DecimalDigits methods
Reviewed-by: vyazici, liach, rriggs
1 parent f687cac commit 07871cd

File tree

7 files changed

+69
-58
lines changed

7 files changed

+69
-58
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
@@ -924,9 +924,9 @@ public AbstractStringBuilder append(int i) {
924924
int spaceNeeded = count + DecimalDigits.stringSize(i);
925925
byte[] value = ensureCapacitySameCoder(this.value, coder, spaceNeeded);
926926
if (isLatin1(coder)) {
927-
DecimalDigits.getCharsLatin1(i, spaceNeeded, value);
927+
DecimalDigits.uncheckedGetCharsLatin1(i, spaceNeeded, value);
928928
} else {
929-
DecimalDigits.getCharsUTF16(i, spaceNeeded, value);
929+
DecimalDigits.uncheckedGetCharsUTF16(i, spaceNeeded, value);
930930
}
931931
this.value = value;
932932
this.count = spaceNeeded;
@@ -951,9 +951,9 @@ public AbstractStringBuilder append(long l) {
951951
int spaceNeeded = count + DecimalDigits.stringSize(l);
952952
byte[] value = ensureCapacitySameCoder(this.value, coder, spaceNeeded);
953953
if (isLatin1(coder)) {
954-
DecimalDigits.getCharsLatin1(l, spaceNeeded, value);
954+
DecimalDigits.uncheckedGetCharsLatin1(l, spaceNeeded, value);
955955
} else {
956-
DecimalDigits.getCharsUTF16(l, spaceNeeded, value);
956+
DecimalDigits.uncheckedGetCharsUTF16(l, spaceNeeded, value);
957957
}
958958
this.value = value;
959959
this.count = spaceNeeded;

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+
DecimalDigits.uncheckedGetCharsLatin1(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+
DecimalDigits.uncheckedGetCharsUTF16(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+
DecimalDigits.uncheckedGetCharsLatin1(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+
DecimalDigits.uncheckedGetCharsUTF16(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
@@ -315,12 +315,12 @@ static long prepend(long indexCoder, byte[] buf, char value, String prefix) {
315315
static long prepend(long indexCoder, byte[] buf, int value, String prefix) {
316316
int index = (int)indexCoder;
317317
if (indexCoder < UTF16) {
318-
index = DecimalDigits.getCharsLatin1(value, index, buf);
318+
index = DecimalDigits.uncheckedGetCharsLatin1(value, index, buf);
319319
index -= prefix.length();
320320
prefix.getBytes(buf, index, String.LATIN1);
321321
return index;
322322
} else {
323-
index = DecimalDigits.getCharsUTF16(value, index, buf);
323+
index = DecimalDigits.uncheckedGetCharsUTF16(value, index, buf);
324324
index -= prefix.length();
325325
prefix.getBytes(buf, index, String.UTF16);
326326
return index | UTF16;
@@ -341,12 +341,12 @@ static long prepend(long indexCoder, byte[] buf, int value, String prefix) {
341341
static long prepend(long indexCoder, byte[] buf, long value, String prefix) {
342342
int index = (int)indexCoder;
343343
if (indexCoder < UTF16) {
344-
index = DecimalDigits.getCharsLatin1(value, index, buf);
344+
index = DecimalDigits.uncheckedGetCharsLatin1(value, index, buf);
345345
index -= prefix.length();
346346
prefix.getBytes(buf, index, String.LATIN1);
347347
return index;
348348
} else {
349-
index = DecimalDigits.getCharsUTF16(value, index, buf);
349+
index = DecimalDigits.uncheckedGetCharsUTF16(value, index, buf);
350350
index -= prefix.length();
351351
prefix.getBytes(buf, index, String.UTF16);
352352
return index | UTF16;
@@ -713,11 +713,11 @@ static int prepend(int index, byte coder, byte[] buf, char value, String prefix)
713713
*/
714714
static int prepend(int index, byte coder, byte[] buf, int value, String prefix) {
715715
if (coder == String.LATIN1) {
716-
index = DecimalDigits.getCharsLatin1(value, index, buf);
716+
index = DecimalDigits.uncheckedGetCharsLatin1(value, index, buf);
717717
index -= prefix.length();
718718
prefix.getBytes(buf, index, String.LATIN1);
719719
} else {
720-
index = DecimalDigits.getCharsUTF16(value, index, buf);
720+
index = DecimalDigits.uncheckedGetCharsUTF16(value, index, buf);
721721
index -= prefix.length();
722722
prefix.getBytes(buf, index, String.UTF16);
723723
}
@@ -737,11 +737,11 @@ static int prepend(int index, byte coder, byte[] buf, int value, String prefix)
737737
*/
738738
static int prepend(int index, byte coder, byte[] buf, long value, String prefix) {
739739
if (coder == String.LATIN1) {
740-
index = DecimalDigits.getCharsLatin1(value, index, buf);
740+
index = DecimalDigits.uncheckedGetCharsLatin1(value, index, buf);
741741
index -= prefix.length();
742742
prefix.getBytes(buf, index, String.LATIN1);
743743
} else {
744-
index = DecimalDigits.getCharsUTF16(value, index, buf);
744+
index = DecimalDigits.uncheckedGetCharsUTF16(value, index, buf);
745745
index -= prefix.length();
746746
prefix.getBytes(buf, index, String.UTF16);
747747
}

src/java.base/share/classes/java/math/BigDecimal.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4146,9 +4146,9 @@ private String layoutChars(boolean sci) {
41464146
int highInt = (int)intCompact / 100;
41474147
int highIntSize = DecimalDigits.stringSize(highInt);
41484148
byte[] buf = new byte[highIntSize + 3];
4149-
DecimalDigits.getCharsLatin1(highInt, highIntSize, buf);
4149+
DecimalDigits.uncheckedGetCharsLatin1(highInt, highIntSize, buf);
41504150
buf[highIntSize] = '.';
4151-
DecimalDigits.putPairLatin1(buf, highIntSize + 1, lowInt);
4151+
DecimalDigits.uncheckedPutPairLatin1(buf, highIntSize + 1, lowInt);
41524152
try {
41534153
return JLA.uncheckedNewStringNoRepl(buf, StandardCharsets.ISO_8859_1);
41544154
} catch (CharacterCodingException cce) {

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

Lines changed: 49 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -143,14 +143,15 @@ public static int stringSize(long x) {
143143
* values, to cover the Integer.MIN_VALUE case. Converting otherwise
144144
* (negative to positive) will expose -Integer.MIN_VALUE that overflows
145145
* integer.
146+
* <p>
147+
* <b>WARNING: This method does not perform any bound checks. </b>
146148
*
147149
* @param i value to convert
148150
* @param index next index, after the least significant digit
149151
* @param buf target buffer, Latin1-encoded
150152
* @return index of the most significant digit or minus sign, if present
151153
*/
152-
public static int getCharsLatin1(int i, int index, byte[] buf) {
153-
// Used by trusted callers. Assumes all necessary bounds checks have been done by the caller.
154+
public static int uncheckedGetCharsLatin1(int i, int index, byte[] buf) {
154155
int q;
155156
int charPos = index;
156157

@@ -163,20 +164,20 @@ public static int getCharsLatin1(int i, int index, byte[] buf) {
163164
while (i <= -100) {
164165
q = i / 100;
165166
charPos -= 2;
166-
putPairLatin1(buf, charPos, (q * 100) - i);
167+
uncheckedPutPairLatin1(buf, charPos, (q * 100) - i);
167168
i = q;
168169
}
169170

170171
// We know there are at most two digits left at this point.
171172
if (i <= -10) {
172173
charPos -= 2;
173-
putPairLatin1(buf, charPos, -i);
174+
uncheckedPutPairLatin1(buf, charPos, -i);
174175
} else {
175-
putCharLatin1(buf, --charPos, '0' - i);
176+
uncheckedPutCharLatin1(buf, --charPos, '0' - i);
176177
}
177178

178179
if (negative) {
179-
putCharLatin1(buf, --charPos, '-');
180+
uncheckedPutCharLatin1(buf, --charPos, '-');
180181
}
181182
return charPos;
182183
}
@@ -193,14 +194,15 @@ public static int getCharsLatin1(int i, int index, byte[] buf) {
193194
* values, to cover the Long.MIN_VALUE case. Converting otherwise
194195
* (negative to positive) will expose -Long.MIN_VALUE that overflows
195196
* long.
197+
* <p>
198+
* <b>WARNING: This method does not perform any bound checks. </b>
196199
*
197200
* @param i value to convert
198201
* @param index next index, after the least significant digit
199202
* @param buf target buffer, Latin1-encoded
200203
* @return index of the most significant digit or minus sign, if present
201204
*/
202-
public static int getCharsLatin1(long i, int index, byte[] buf) {
203-
// Used by trusted callers. Assumes all necessary bounds checks have been done by the caller.
205+
public static int uncheckedGetCharsLatin1(long i, int index, byte[] buf) {
204206
long q;
205207
int charPos = index;
206208

@@ -213,7 +215,7 @@ public static int getCharsLatin1(long i, int index, byte[] buf) {
213215
while (i < Integer.MIN_VALUE) {
214216
q = i / 100;
215217
charPos -= 2;
216-
putPairLatin1(buf, charPos, (int)((q * 100) - i));
218+
uncheckedPutPairLatin1(buf, charPos, (int)((q * 100) - i));
217219
i = q;
218220
}
219221

@@ -223,36 +225,37 @@ public static int getCharsLatin1(long i, int index, byte[] buf) {
223225
while (i2 <= -100) {
224226
q2 = i2 / 100;
225227
charPos -= 2;
226-
putPairLatin1(buf, charPos, (q2 * 100) - i2);
228+
uncheckedPutPairLatin1(buf, charPos, (q2 * 100) - i2);
227229
i2 = q2;
228230
}
229231

230232
// We know there are at most two digits left at this point.
231233
if (i2 <= -10) {
232234
charPos -= 2;
233-
putPairLatin1(buf, charPos, -i2);
235+
uncheckedPutPairLatin1(buf, charPos, -i2);
234236
} else {
235-
putCharLatin1(buf, --charPos, '0' - i2);
237+
uncheckedPutCharLatin1(buf, --charPos, '0' - i2);
236238
}
237239

238240
if (negative) {
239-
putCharLatin1(buf, --charPos, '-');
241+
uncheckedPutCharLatin1(buf, --charPos, '-');
240242
}
241243
return charPos;
242244
}
243245

244246

245247
/**
246-
* This is a variant of {@link DecimalDigits#getCharsLatin1(int, int, byte[])}, but for
248+
* This is a variant of {@link DecimalDigits#uncheckedGetCharsLatin1(int, int, byte[])}, but for
247249
* UTF-16 coder.
250+
* <p>
251+
* <b>WARNING: This method does not perform any bound checks.</b>
248252
*
249253
* @param i value to convert
250254
* @param index next index, after the least significant digit
251255
* @param buf target buffer, UTF16-coded.
252256
* @return index of the most significant digit or minus sign, if present
253257
*/
254-
public static int getCharsUTF16(int i, int index, byte[] buf) {
255-
// Used by trusted callers. Assumes all necessary bounds checks have been done by the caller.
258+
public static int uncheckedGetCharsUTF16(int i, int index, byte[] buf) {
256259
int q;
257260
int charPos = index;
258261

@@ -265,36 +268,37 @@ public static int getCharsUTF16(int i, int index, byte[] buf) {
265268
while (i <= -100) {
266269
q = i / 100;
267270
charPos -= 2;
268-
putPairUTF16(buf, charPos, (q * 100) - i);
271+
uncheckedPutPairUTF16(buf, charPos, (q * 100) - i);
269272
i = q;
270273
}
271274

272275
// We know there are at most two digits left at this point.
273276
if (i <= -10) {
274277
charPos -= 2;
275-
putPairUTF16(buf, charPos, -i);
278+
uncheckedPutPairUTF16(buf, charPos, -i);
276279
} else {
277-
putCharUTF16(buf, --charPos, '0' - i);
280+
uncheckedPutCharUTF16(buf, --charPos, '0' - i);
278281
}
279282

280283
if (negative) {
281-
putCharUTF16(buf, --charPos, '-');
284+
uncheckedPutCharUTF16(buf, --charPos, '-');
282285
}
283286
return charPos;
284287
}
285288

286289

287290
/**
288-
* This is a variant of {@link DecimalDigits#getCharsLatin1(long, int, byte[])}, but for
291+
* This is a variant of {@link DecimalDigits#uncheckedGetCharsLatin1(long, int, byte[])}, but for
289292
* UTF-16 coder.
293+
* <p>
294+
* <b>WARNING: This method does not perform any bound checks.</b>
290295
*
291296
* @param i value to convert
292297
* @param index next index, after the least significant digit
293298
* @param buf target buffer, UTF16-coded.
294299
* @return index of the most significant digit or minus sign, if present
295300
*/
296-
public static int getCharsUTF16(long i, int index, byte[] buf) {
297-
// Used by trusted callers. Assumes all necessary bounds checks have been done by the caller.
301+
public static int uncheckedGetCharsUTF16(long i, int index, byte[] buf) {
298302
long q;
299303
int charPos = index;
300304

@@ -307,7 +311,7 @@ public static int getCharsUTF16(long i, int index, byte[] buf) {
307311
while (i < Integer.MIN_VALUE) {
308312
q = i / 100;
309313
charPos -= 2;
310-
putPairUTF16(buf, charPos, (int)((q * 100) - i));
314+
uncheckedPutPairUTF16(buf, charPos, (int)((q * 100) - i));
311315
i = q;
312316
}
313317

@@ -317,26 +321,26 @@ public static int getCharsUTF16(long i, int index, byte[] buf) {
317321
while (i2 <= -100) {
318322
q2 = i2 / 100;
319323
charPos -= 2;
320-
putPairUTF16(buf, charPos, (q2 * 100) - i2);
324+
uncheckedPutPairUTF16(buf, charPos, (q2 * 100) - i2);
321325
i2 = q2;
322326
}
323327

324328
// We know there are at most two digits left at this point.
325329
if (i2 <= -10) {
326330
charPos -= 2;
327-
putPairUTF16(buf, charPos, -i2);
331+
uncheckedPutPairUTF16(buf, charPos, -i2);
328332
} else {
329-
putCharUTF16(buf, --charPos, '0' - i2);
333+
uncheckedPutCharUTF16(buf, --charPos, '0' - i2);
330334
}
331335

332336
if (negative) {
333-
putCharUTF16(buf, --charPos, '-');
337+
uncheckedPutCharUTF16(buf, --charPos, '-');
334338
}
335339
return charPos;
336340
}
337341

338342
/**
339-
* This is a variant of {@link DecimalDigits#getCharsUTF16(long, int, byte[])}, but for
343+
* This is a variant of {@link DecimalDigits#uncheckedGetCharsUTF16(long, int, byte[])}, but for
340344
* UTF-16 coder.
341345
*
342346
* @param i value to convert
@@ -345,7 +349,6 @@ public static int getCharsUTF16(long i, int index, byte[] buf) {
345349
* @return index of the most significant digit or minus sign, if present
346350
*/
347351
public static int getChars(long i, int index, char[] buf) {
348-
// Used by trusted callers. Assumes all necessary bounds checks have been done by the caller.
349352
long q;
350353
int charPos = index;
351354

@@ -402,34 +405,42 @@ public static void putPair(char[] buf, int charPos, int v) {
402405
/**
403406
* Insert the 2-bytes integer into the buf as 2 decimal digit ASCII bytes,
404407
* only least significant 16 bits of {@code v} are used.
408+
* <p>
409+
* <b>WARNING: This method does not perform any bound checks.</b>
410+
*
405411
* @param buf byte buffer to copy into
406412
* @param charPos insert point
407413
* @param v to convert
408414
*/
409-
public static void putPairLatin1(byte[] buf, int charPos, int v) {
415+
public static void uncheckedPutPairLatin1(byte[] buf, int charPos, int v) {
410416
int packed = DIGITS[v & 0x7f];
411-
putCharLatin1(buf, charPos, packed & 0xFF);
412-
putCharLatin1(buf, charPos + 1, packed >> 8);
417+
uncheckedPutCharLatin1(buf, charPos, packed & 0xFF);
418+
uncheckedPutCharLatin1(buf, charPos + 1, packed >> 8);
413419
}
414420

415421
/**
416422
* Insert the 2-chars integer into the buf as 2 decimal digit UTF16 bytes,
417423
* only least significant 16 bits of {@code v} are used.
424+
* <p>
425+
* <b>WARNING: This method does not perform any bound checks.</b>
426+
*
418427
* @param buf byte buffer to copy into
419428
* @param charPos insert point
420429
* @param v to convert
421430
*/
422-
public static void putPairUTF16(byte[] buf, int charPos, int v) {
431+
public static void uncheckedPutPairUTF16(byte[] buf, int charPos, int v) {
423432
int packed = DIGITS[v & 0x7f];
424-
putCharUTF16(buf, charPos, packed & 0xFF);
425-
putCharUTF16(buf, charPos + 1, packed >> 8);
433+
uncheckedPutCharUTF16(buf, charPos, packed & 0xFF);
434+
uncheckedPutCharUTF16(buf, charPos + 1, packed >> 8);
426435
}
427436

428-
private static void putCharLatin1(byte[] buf, int charPos, int c) {
437+
private static void uncheckedPutCharLatin1(byte[] buf, int charPos, int c) {
438+
assert charPos >= 0 && charPos < buf.length;
429439
UNSAFE.putByte(buf, ARRAY_BYTE_BASE_OFFSET + charPos, (byte) c);
430440
}
431441

432-
private static void putCharUTF16(byte[] buf, int charPos, int c) {
442+
private static void uncheckedPutCharUTF16(byte[] buf, int charPos, int c) {
443+
assert charPos >= 0 && charPos < (buf.length >> 1);
433444
UNSAFE.putCharUnaligned(buf, ARRAY_BYTE_BASE_OFFSET + ((long) charPos << 1), (char) c);
434445
}
435446
}

test/hotspot/jtreg/compiler/patches/java.base/java/lang/Helper.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,14 @@ public static int codePointCountSB(byte[] val, int beginIndex, int endIndex) {
120120

121121
public static int getChars(int i, int begin, int end, byte[] value) {
122122
StringUTF16.checkBoundsBeginEnd(begin, end, value);
123-
int pos = DecimalDigits.getCharsUTF16(i, end, value);
123+
int pos = DecimalDigits.uncheckedGetCharsUTF16(i, end, value);
124124
assert begin == pos;
125125
return pos;
126126
}
127127

128128
public static int getChars(long l, int begin, int end, byte[] value) {
129129
StringUTF16.checkBoundsBeginEnd(begin, end, value);
130-
int pos = DecimalDigits.getCharsUTF16(l, end, value);
130+
int pos = DecimalDigits.uncheckedGetCharsUTF16(l, end, value);
131131
assert begin == pos;
132132
return pos;
133133
}

0 commit comments

Comments
 (0)