mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-23 20:44:41 +02:00
8076758: new StringBuilder().append(String).toString() should be recognized by OptimizeStringConcat
Reviewed-by: kvn, thartmann
This commit is contained in:
parent
7b6480cfa4
commit
e3007b79ad
1 changed files with 48 additions and 41 deletions
|
@ -1576,51 +1576,58 @@ void PhaseStringOpts::replace_string_concat(StringConcat* sc) {
|
||||||
|
|
||||||
Node* result;
|
Node* result;
|
||||||
if (!kit.stopped()) {
|
if (!kit.stopped()) {
|
||||||
|
|
||||||
// length now contains the number of characters needed for the
|
|
||||||
// char[] so create a new AllocateArray for the char[]
|
|
||||||
Node* char_array = NULL;
|
Node* char_array = NULL;
|
||||||
{
|
if (sc->num_arguments() == 1 &&
|
||||||
PreserveReexecuteState preexecs(&kit);
|
(sc->mode(0) == StringConcat::StringMode ||
|
||||||
// The original jvms is for an allocation of either a String or
|
sc->mode(0) == StringConcat::StringNullCheckMode)) {
|
||||||
// StringBuffer so no stack adjustment is necessary for proper
|
// Handle the case when there is only a single String argument.
|
||||||
// reexecution. If we deoptimize in the slow path the bytecode
|
// In this case, we can just pull the value from the String itself.
|
||||||
// will be reexecuted and the char[] allocation will be thrown away.
|
char_array = kit.load_String_value(kit.control(), sc->argument(0));
|
||||||
kit.jvms()->set_should_reexecute(true);
|
} else {
|
||||||
char_array = kit.new_array(__ makecon(TypeKlassPtr::make(ciTypeArrayKlass::make(T_CHAR))),
|
// length now contains the number of characters needed for the
|
||||||
length, 1);
|
// char[] so create a new AllocateArray for the char[]
|
||||||
}
|
{
|
||||||
|
PreserveReexecuteState preexecs(&kit);
|
||||||
|
// The original jvms is for an allocation of either a String or
|
||||||
|
// StringBuffer so no stack adjustment is necessary for proper
|
||||||
|
// reexecution. If we deoptimize in the slow path the bytecode
|
||||||
|
// will be reexecuted and the char[] allocation will be thrown away.
|
||||||
|
kit.jvms()->set_should_reexecute(true);
|
||||||
|
char_array = kit.new_array(__ makecon(TypeKlassPtr::make(ciTypeArrayKlass::make(T_CHAR))),
|
||||||
|
length, 1);
|
||||||
|
}
|
||||||
|
|
||||||
// Mark the allocation so that zeroing is skipped since the code
|
// Mark the allocation so that zeroing is skipped since the code
|
||||||
// below will overwrite the entire array
|
// below will overwrite the entire array
|
||||||
AllocateArrayNode* char_alloc = AllocateArrayNode::Ideal_array_allocation(char_array, _gvn);
|
AllocateArrayNode* char_alloc = AllocateArrayNode::Ideal_array_allocation(char_array, _gvn);
|
||||||
char_alloc->maybe_set_complete(_gvn);
|
char_alloc->maybe_set_complete(_gvn);
|
||||||
|
|
||||||
// Now copy the string representations into the final char[]
|
// Now copy the string representations into the final char[]
|
||||||
Node* start = __ intcon(0);
|
Node* start = __ intcon(0);
|
||||||
for (int argi = 0; argi < sc->num_arguments(); argi++) {
|
for (int argi = 0; argi < sc->num_arguments(); argi++) {
|
||||||
Node* arg = sc->argument(argi);
|
Node* arg = sc->argument(argi);
|
||||||
switch (sc->mode(argi)) {
|
switch (sc->mode(argi)) {
|
||||||
case StringConcat::IntMode: {
|
case StringConcat::IntMode: {
|
||||||
Node* end = __ AddI(start, string_sizes->in(argi));
|
Node* end = __ AddI(start, string_sizes->in(argi));
|
||||||
// getChars words backwards so pass the ending point as well as the start
|
// getChars words backwards so pass the ending point as well as the start
|
||||||
int_getChars(kit, arg, char_array, start, end);
|
int_getChars(kit, arg, char_array, start, end);
|
||||||
start = end;
|
start = end;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
case StringConcat::StringNullCheckMode:
|
||||||
|
case StringConcat::StringMode: {
|
||||||
|
start = copy_string(kit, arg, char_array, start);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case StringConcat::CharMode: {
|
||||||
|
__ store_to_memory(kit.control(), kit.array_element_address(char_array, start, T_CHAR),
|
||||||
|
arg, T_CHAR, char_adr_idx, MemNode::unordered);
|
||||||
|
start = __ AddI(start, __ intcon(1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
ShouldNotReachHere();
|
||||||
}
|
}
|
||||||
case StringConcat::StringNullCheckMode:
|
|
||||||
case StringConcat::StringMode: {
|
|
||||||
start = copy_string(kit, arg, char_array, start);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case StringConcat::CharMode: {
|
|
||||||
__ store_to_memory(kit.control(), kit.array_element_address(char_array, start, T_CHAR),
|
|
||||||
arg, T_CHAR, char_adr_idx, MemNode::unordered);
|
|
||||||
start = __ AddI(start, __ intcon(1));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
ShouldNotReachHere();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue