mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-25 22:04:51 +02:00
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:
parent
bb837d2f9b
commit
618c5eb27b
6 changed files with 88 additions and 121 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue