8349183: [BACKOUT] Optimization for StringBuilder append boolean & null

8349239: [BACKOUT] Reuse StringLatin1::putCharsAt and StringUTF16::putCharsAt

Reviewed-by: redestad, liach
This commit is contained in:
Jaikiran Pai 2025-02-03 18:21:33 +00:00
parent bb837d2f9b
commit 618c5eb27b
6 changed files with 88 additions and 121 deletions

View file

@ -640,11 +640,14 @@ abstract sealed class AbstractStringBuilder implements Appendable, CharSequence
int count = this.count;
byte[] val = this.value;
if (isLatin1()) {
StringLatin1.putCharsAt(val, count, 'n', 'u', 'l', 'l');
val[count++] = 'n';
val[count++] = 'u';
val[count++] = 'l';
val[count++] = 'l';
} else {
StringUTF16.putCharsAt(val, count, 'n', 'u', 'l', 'l');
count = StringUTF16.putCharsAt(val, count, 'n', 'u', 'l', 'l');
}
this.count = count + 4;
this.count = count;
return this;
}
@ -769,18 +772,25 @@ abstract sealed class AbstractStringBuilder implements Appendable, CharSequence
byte[] val = this.value;
if (isLatin1()) {
if (b) {
StringLatin1.putCharsAt(val, count, 't', 'r', 'u', 'e');
val[count++] = 't';
val[count++] = 'r';
val[count++] = 'u';
val[count++] = 'e';
} else {
StringLatin1.putCharsAt(val, count, 'f', 'a', 'l', 's', 'e');
val[count++] = 'f';
val[count++] = 'a';
val[count++] = 'l';
val[count++] = 's';
val[count++] = 'e';
}
} else {
if (b) {
StringUTF16.putCharsAt(val, count, 't', 'r', 'u', 'e');
count = StringUTF16.putCharsAt(val, count, 't', 'r', 'u', 'e');
} else {
StringUTF16.putCharsAt(val, count, 'f', 'a', 'l', 's', 'e');
count = StringUTF16.putCharsAt(val, count, 'f', 'a', 'l', 's', 'e');
}
}
this.count = count + (b ? 4 : 5);
this.count = count;
return this;
}

View file

@ -236,10 +236,17 @@ final class StringConcatHelper {
if (indexCoder < UTF16) {
if (value) {
index -= 4;
StringLatin1.putCharsAt(buf, index, 't', 'r', 'u', 'e');
buf[index] = 't';
buf[index + 1] = 'r';
buf[index + 2] = 'u';
buf[index + 3] = 'e';
} else {
index -= 5;
StringLatin1.putCharsAt(buf, index, 'f', 'a', 'l', 's', 'e');
buf[index] = 'f';
buf[index + 1] = 'a';
buf[index + 2] = 'l';
buf[index + 3] = 's';
buf[index + 4] = 'e';
}
index -= prefix.length();
prefix.getBytes(buf, index, String.LATIN1);
@ -247,10 +254,17 @@ final class StringConcatHelper {
} else {
if (value) {
index -= 4;
StringUTF16.putCharsAt(buf, index, 't', 'r', 'u', 'e');
StringUTF16.putChar(buf, index, 't');
StringUTF16.putChar(buf, index + 1, 'r');
StringUTF16.putChar(buf, index + 2, 'u');
StringUTF16.putChar(buf, index + 3, 'e');
} else {
index -= 5;
StringUTF16.putCharsAt(buf, index, 'f', 'a', 'l', 's', 'e');
StringUTF16.putChar(buf, index, 'f');
StringUTF16.putChar(buf, index + 1, 'a');
StringUTF16.putChar(buf, index + 2, 'l');
StringUTF16.putChar(buf, index + 3, 's');
StringUTF16.putChar(buf, index + 4, 'e');
}
index -= prefix.length();
prefix.getBytes(buf, index, String.UTF16);
@ -624,20 +638,34 @@ final class StringConcatHelper {
if (coder == String.LATIN1) {
if (value) {
index -= 4;
StringLatin1.putCharsAt(buf, index, 't', 'r', 'u', 'e');
buf[index] = 't';
buf[index + 1] = 'r';
buf[index + 2] = 'u';
buf[index + 3] = 'e';
} else {
index -= 5;
StringLatin1.putCharsAt(buf, index, 'f', 'a', 'l', 's', 'e');
buf[index] = 'f';
buf[index + 1] = 'a';
buf[index + 2] = 'l';
buf[index + 3] = 's';
buf[index + 4] = 'e';
}
index -= prefix.length();
prefix.getBytes(buf, index, String.LATIN1);
} else {
if (value) {
index -= 4;
StringUTF16.putCharsAt(buf, index, 't', 'r', 'u', 'e');
StringUTF16.putChar(buf, index, 't');
StringUTF16.putChar(buf, index + 1, 'r');
StringUTF16.putChar(buf, index + 2, 'u');
StringUTF16.putChar(buf, index + 3, 'e');
} else {
index -= 5;
StringUTF16.putCharsAt(buf, index, 'f', 'a', 'l', 's', 'e');
StringUTF16.putChar(buf, index, 'f');
StringUTF16.putChar(buf, index + 1, 'a');
StringUTF16.putChar(buf, index + 2, 'l');
StringUTF16.putChar(buf, index + 3, 's');
StringUTF16.putChar(buf, index + 4, 'e');
}
index -= prefix.length();
prefix.getBytes(buf, index, String.UTF16);

View file

@ -32,7 +32,6 @@ import java.util.function.Consumer;
import java.util.function.IntConsumer;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import jdk.internal.misc.Unsafe;
import jdk.internal.util.ArraysSupport;
import jdk.internal.vm.annotation.IntrinsicCandidate;
@ -42,8 +41,6 @@ import static java.lang.String.checkIndex;
import static java.lang.String.checkOffset;
final class StringLatin1 {
private static final Unsafe UNSAFE = Unsafe.getUnsafe();
public static char charAt(byte[] value, int index) {
checkIndex(index, value.length);
return (char)(value[index] & 0xff);
@ -712,27 +709,6 @@ final class StringLatin1 {
return StreamSupport.stream(LinesSpliterator.spliterator(value), false);
}
static void putCharsAt(byte[] val, int index, int c1, int c2, int c3, int c4) {
assert index >= 0 && index + 3 < length(val) : "Trusted caller missed bounds check";
// Don't use the putChar method, Its instrinsic will cause C2 unable to combining values into larger stores.
long offset = Unsafe.ARRAY_BYTE_BASE_OFFSET + index;
UNSAFE.putByte(val, offset , (byte)(c1));
UNSAFE.putByte(val, offset + 1, (byte)(c2));
UNSAFE.putByte(val, offset + 2, (byte)(c3));
UNSAFE.putByte(val, offset + 3, (byte)(c4));
}
static void putCharsAt(byte[] val, int index, int c1, int c2, int c3, int c4, int c5) {
assert index >= 0 && index + 4 < length(val) : "Trusted caller missed bounds check";
// Don't use the putChar method, Its instrinsic will cause C2 unable to combining values into larger stores.
long offset = Unsafe.ARRAY_BYTE_BASE_OFFSET + index;
UNSAFE.putByte(val, offset , (byte)(c1));
UNSAFE.putByte(val, offset + 1, (byte)(c2));
UNSAFE.putByte(val, offset + 2, (byte)(c3));
UNSAFE.putByte(val, offset + 3, (byte)(c4));
UNSAFE.putByte(val, offset + 4, (byte)(c5));
}
public static void putChar(byte[] val, int index, int c) {
//assert (canEncode(c));
val[index] = (byte)(c);

View file

@ -42,6 +42,7 @@ import static java.lang.String.UTF16;
import static java.lang.String.LATIN1;
final class StringUTF16 {
// Return a new byte array for a UTF16-coded string for len chars
// Throw an exception if out of range
public static byte[] newBytesFor(int len) {
@ -1532,20 +1533,27 @@ final class StringUTF16 {
return true;
}
static void putCharsAt(byte[] val, int index, int c1, int c2, int c3, int c4) {
assert index >= 0 && index + 3 < length(val) : "Trusted caller missed bounds check";
putChar(val, index , c1);
putChar(val, index + 1, c2);
putChar(val, index + 2, c3);
putChar(val, index + 3, c4);
public static int putCharsAt(byte[] value, int i, char c1, char c2, char c3, char c4) {
int end = i + 4;
checkBoundsBeginEnd(i, end, value);
putChar(value, i++, c1);
putChar(value, i++, c2);
putChar(value, i++, c3);
putChar(value, i++, c4);
assert(i == end);
return end;
}
static void putCharsAt(byte[] val, int index, int c1, int c2, int c3, int c4, int c5) {
putChar(val, index , c1);
putChar(val, index + 1, c2);
putChar(val, index + 2, c3);
putChar(val, index + 3, c4);
putChar(val, index + 4, c5);
public static int putCharsAt(byte[] value, int i, char c1, char c2, char c3, char c4, char c5) {
int end = i + 5;
checkBoundsBeginEnd(i, end, value);
putChar(value, i++, c1);
putChar(value, i++, c2);
putChar(value, i++, c3);
putChar(value, i++, c4);
putChar(value, i++, c5);
assert(i == end);
return end;
}
public static char charAt(byte[] value, int index) {