mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8335182: Consolidate and streamline String concat code shapes
Reviewed-by: liach, jvernee
This commit is contained in:
parent
4c7b3e7fc3
commit
e83b4b236e
6 changed files with 452 additions and 154 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -119,91 +119,64 @@ final class StringConcatHelper {
|
|||
*/
|
||||
static long mix(long lengthCoder, String value) {
|
||||
lengthCoder += value.length();
|
||||
if (value.coder() == String.UTF16) {
|
||||
if (!value.isLatin1()) {
|
||||
lengthCoder |= UTF16;
|
||||
}
|
||||
return checkOverflow(lengthCoder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepends the stringly representation of boolean value into buffer,
|
||||
* Prepends constant and the stringly representation of value into buffer,
|
||||
* given the coder and final index. Index is measured in chars, not in bytes!
|
||||
*
|
||||
* @param indexCoder final char index in the buffer, along with coder packed
|
||||
* into higher bits.
|
||||
* @param buf buffer to append to
|
||||
* @param value boolean value to encode
|
||||
* @param prefix a constant to prepend before value
|
||||
* @return updated index (coder value retained)
|
||||
*/
|
||||
static long prepend(long indexCoder, byte[] buf, boolean value) {
|
||||
static long prepend(long indexCoder, byte[] buf, boolean value, String prefix) {
|
||||
int index = (int)indexCoder;
|
||||
if (indexCoder < UTF16) {
|
||||
if (value) {
|
||||
buf[--index] = 'e';
|
||||
buf[--index] = 'u';
|
||||
buf[--index] = 'r';
|
||||
buf[--index] = 't';
|
||||
index -= 4;
|
||||
buf[index] = 't';
|
||||
buf[index + 1] = 'r';
|
||||
buf[index + 2] = 'u';
|
||||
buf[index + 3] = 'e';
|
||||
} else {
|
||||
buf[--index] = 'e';
|
||||
buf[--index] = 's';
|
||||
buf[--index] = 'l';
|
||||
buf[--index] = 'a';
|
||||
buf[--index] = 'f';
|
||||
index -= 5;
|
||||
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);
|
||||
return index;
|
||||
} else {
|
||||
if (value) {
|
||||
StringUTF16.putChar(buf, --index, 'e');
|
||||
StringUTF16.putChar(buf, --index, 'u');
|
||||
StringUTF16.putChar(buf, --index, 'r');
|
||||
StringUTF16.putChar(buf, --index, 't');
|
||||
index -= 4;
|
||||
StringUTF16.putChar(buf, index, 't');
|
||||
StringUTF16.putChar(buf, index + 1, 'r');
|
||||
StringUTF16.putChar(buf, index + 2, 'u');
|
||||
StringUTF16.putChar(buf, index + 3, 'e');
|
||||
} else {
|
||||
StringUTF16.putChar(buf, --index, 'e');
|
||||
StringUTF16.putChar(buf, --index, 's');
|
||||
StringUTF16.putChar(buf, --index, 'l');
|
||||
StringUTF16.putChar(buf, --index, 'a');
|
||||
StringUTF16.putChar(buf, --index, 'f');
|
||||
index -= 5;
|
||||
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);
|
||||
return index | UTF16;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepends constant and the stringly representation of value into buffer,
|
||||
* given the coder and final index. Index is measured in chars, not in bytes!
|
||||
*
|
||||
* @param indexCoder final char index in the buffer, along with coder packed
|
||||
* into higher bits.
|
||||
* @param buf buffer to append to
|
||||
* @param value boolean value to encode
|
||||
* @param prefix a constant to prepend before value
|
||||
* @return updated index (coder value retained)
|
||||
*/
|
||||
static long prepend(long indexCoder, byte[] buf, boolean value, String prefix) {
|
||||
indexCoder = prepend(indexCoder, buf, value);
|
||||
indexCoder = prepend(indexCoder, buf, prefix);
|
||||
return indexCoder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepends the stringly representation of char value into buffer,
|
||||
* given the coder and final index. Index is measured in chars, not in bytes!
|
||||
*
|
||||
* @param indexCoder final char index in the buffer, along with coder packed
|
||||
* into higher bits.
|
||||
* @param buf buffer to append to
|
||||
* @param value char value to encode
|
||||
* @return updated index (coder value retained)
|
||||
*/
|
||||
static long prepend(long indexCoder, byte[] buf, char value) {
|
||||
if (indexCoder < UTF16) {
|
||||
buf[(int)(--indexCoder)] = (byte) (value & 0xFF);
|
||||
} else {
|
||||
StringUTF16.putChar(buf, (int)(--indexCoder), value);
|
||||
}
|
||||
return indexCoder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepends constant and the stringly representation of value into buffer,
|
||||
* given the coder and final index. Index is measured in chars, not in bytes!
|
||||
|
@ -216,26 +189,17 @@ final class StringConcatHelper {
|
|||
* @return updated index (coder value retained)
|
||||
*/
|
||||
static long prepend(long indexCoder, byte[] buf, char value, String prefix) {
|
||||
indexCoder = prepend(indexCoder, buf, value);
|
||||
indexCoder = prepend(indexCoder, buf, prefix);
|
||||
return indexCoder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepends the stringly representation of integer value into buffer,
|
||||
* given the coder and final index. Index is measured in chars, not in bytes!
|
||||
*
|
||||
* @param indexCoder final char index in the buffer, along with coder packed
|
||||
* into higher bits.
|
||||
* @param buf buffer to append to
|
||||
* @param value integer value to encode
|
||||
* @return updated index (coder value retained)
|
||||
*/
|
||||
static long prepend(long indexCoder, byte[] buf, int value) {
|
||||
int index = (int)indexCoder;
|
||||
if (indexCoder < UTF16) {
|
||||
return StringLatin1.getChars(value, (int)indexCoder, buf);
|
||||
buf[--index] = (byte) (value & 0xFF);
|
||||
index -= prefix.length();
|
||||
prefix.getBytes(buf, index, String.LATIN1);
|
||||
return index;
|
||||
} else {
|
||||
return StringUTF16.getChars(value, (int)indexCoder, buf) | UTF16;
|
||||
StringUTF16.putChar(buf, --index, value);
|
||||
index -= prefix.length();
|
||||
prefix.getBytes(buf, index, String.UTF16);
|
||||
return index | UTF16;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -251,26 +215,17 @@ final class StringConcatHelper {
|
|||
* @return updated index (coder value retained)
|
||||
*/
|
||||
static long prepend(long indexCoder, byte[] buf, int value, String prefix) {
|
||||
indexCoder = prepend(indexCoder, buf, value);
|
||||
indexCoder = prepend(indexCoder, buf, prefix);
|
||||
return indexCoder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepends the stringly representation of long value into buffer,
|
||||
* given the coder and final index. Index is measured in chars, not in bytes!
|
||||
*
|
||||
* @param indexCoder final char index in the buffer, along with coder packed
|
||||
* into higher bits.
|
||||
* @param buf buffer to append to
|
||||
* @param value long value to encode
|
||||
* @return updated index (coder value retained)
|
||||
*/
|
||||
static long prepend(long indexCoder, byte[] buf, long value) {
|
||||
int index = (int)indexCoder;
|
||||
if (indexCoder < UTF16) {
|
||||
return StringLatin1.getChars(value, (int)indexCoder, buf);
|
||||
index = StringLatin1.getChars(value, index, buf);
|
||||
index -= prefix.length();
|
||||
prefix.getBytes(buf, index, String.LATIN1);
|
||||
return index;
|
||||
} else {
|
||||
return StringUTF16.getChars(value, (int)indexCoder, buf) | UTF16;
|
||||
index = StringUTF16.getChars(value, index, buf);
|
||||
index -= prefix.length();
|
||||
prefix.getBytes(buf, index, String.UTF16);
|
||||
return index | UTF16;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -286,29 +241,18 @@ final class StringConcatHelper {
|
|||
* @return updated index (coder value retained)
|
||||
*/
|
||||
static long prepend(long indexCoder, byte[] buf, long value, String prefix) {
|
||||
indexCoder = prepend(indexCoder, buf, value);
|
||||
indexCoder = prepend(indexCoder, buf, prefix);
|
||||
return indexCoder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepends the stringly representation of String value into buffer,
|
||||
* given the coder and final index. Index is measured in chars, not in bytes!
|
||||
*
|
||||
* @param indexCoder final char index in the buffer, along with coder packed
|
||||
* into higher bits.
|
||||
* @param buf buffer to append to
|
||||
* @param value String value to encode
|
||||
* @return updated index (coder value retained)
|
||||
*/
|
||||
static long prepend(long indexCoder, byte[] buf, String value) {
|
||||
indexCoder -= value.length();
|
||||
int index = (int)indexCoder;
|
||||
if (indexCoder < UTF16) {
|
||||
value.getBytes(buf, (int)indexCoder, String.LATIN1);
|
||||
index = StringLatin1.getChars(value, index, buf);
|
||||
index -= prefix.length();
|
||||
prefix.getBytes(buf, index, String.LATIN1);
|
||||
return index;
|
||||
} else {
|
||||
value.getBytes(buf, (int)indexCoder, String.UTF16);
|
||||
index = StringUTF16.getChars(value, index, buf);
|
||||
index -= prefix.length();
|
||||
prefix.getBytes(buf, index, String.UTF16);
|
||||
return index | UTF16;
|
||||
}
|
||||
return indexCoder;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -323,9 +267,18 @@ final class StringConcatHelper {
|
|||
* @return updated index (coder value retained)
|
||||
*/
|
||||
static long prepend(long indexCoder, byte[] buf, String value, String prefix) {
|
||||
indexCoder = prepend(indexCoder, buf, value);
|
||||
indexCoder = prepend(indexCoder, buf, prefix);
|
||||
return indexCoder;
|
||||
int index = ((int)indexCoder) - value.length();
|
||||
if (indexCoder < UTF16) {
|
||||
value.getBytes(buf, index, String.LATIN1);
|
||||
index -= prefix.length();
|
||||
prefix.getBytes(buf, index, String.LATIN1);
|
||||
return index;
|
||||
} else {
|
||||
value.getBytes(buf, index, String.UTF16);
|
||||
index -= prefix.length();
|
||||
prefix.getBytes(buf, index, String.UTF16);
|
||||
return index | UTF16;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -375,8 +328,7 @@ final class StringConcatHelper {
|
|||
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);
|
||||
indexCoder = prepend(indexCoder, buf, s1);
|
||||
indexCoder = prepend(indexCoder, buf, s2, s1);
|
||||
return newString(buf, indexCoder);
|
||||
}
|
||||
|
||||
|
@ -443,8 +395,10 @@ final class StringConcatHelper {
|
|||
*/
|
||||
@ForceInline
|
||||
static byte[] newArray(long indexCoder) {
|
||||
byte coder = (byte)(indexCoder >> 32);
|
||||
int index = ((int)indexCoder) << coder;
|
||||
int index = (int)indexCoder;
|
||||
if (indexCoder >= UTF16) {
|
||||
index <<= 1;
|
||||
}
|
||||
if (index < 0) {
|
||||
throw new OutOfMemoryError("Overflow: String length out of range");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue