8336831: Optimize StringConcatHelper.simpleConcat

Reviewed-by: liach, redestad, rriggs
This commit is contained in:
Shaojin Wen 2024-07-23 20:21:08 +00:00 committed by Chen Liang
parent 4c91d5cb41
commit 476d2ae69d
2 changed files with 33 additions and 16 deletions

View File

@ -2987,7 +2987,7 @@ public final class String
if (str.isEmpty()) {
return this;
}
return StringConcatHelper.simpleConcat(this, str);
return StringConcatHelper.doConcat(this, str);
}
/**

View File

@ -321,15 +321,24 @@ final class StringConcatHelper {
// newly created string required, see JLS 15.18.1
return new String(s1);
}
// start "mixing" in length and coder or arguments, order is not
// important
long indexCoder = mix(initialCoder(), s1);
indexCoder = mix(indexCoder, s2);
byte[] buf = newArray(indexCoder);
// prepend each argument in reverse order, since we prepending
// from the end of the byte array
indexCoder = prepend(indexCoder, buf, s2, s1);
return newString(buf, indexCoder);
return doConcat(s1, s2);
}
/**
* Perform a simple concatenation between two non-empty strings.
*
* @param s1 first argument
* @param s2 second argument
* @return String resulting string
*/
@ForceInline
static String doConcat(String s1, String s2) {
byte coder = (byte) (s1.coder() | s2.coder());
int newLength = (s1.length() + s2.length()) << coder;
byte[] buf = newArray(newLength);
s1.getBytes(buf, 0, coder);
s2.getBytes(buf, s1.length(), coder);
return new String(buf, coder);
}
/**
@ -395,14 +404,22 @@ final class StringConcatHelper {
*/
@ForceInline
static byte[] newArray(long indexCoder) {
int index = (int)indexCoder;
if (indexCoder >= UTF16) {
index <<= 1;
}
if (index < 0) {
byte coder = (byte)(indexCoder >> 32);
int index = ((int)indexCoder) << coder;
return newArray(index);
}
/**
* Allocates an uninitialized byte array based on the length
* @param length
* @return the newly allocated byte array
*/
@ForceInline
static byte[] newArray(int length) {
if (length < 0) {
throw new OutOfMemoryError("Overflow: String length out of range");
}
return (byte[]) UNSAFE.allocateUninitializedArray(byte.class, index);
return (byte[]) UNSAFE.allocateUninitializedArray(byte.class, length);
}
/**