8262994: Refactor String.split to help method inlining

Reviewed-by: plevart
This commit is contained in:
Christian Wimmer 2023-01-30 23:33:11 +00:00 committed by Peter Levart
parent 2d7690b2e5
commit 622b6594d1

View file

@ -3129,43 +3129,52 @@ public final class String
(ch < Character.MIN_HIGH_SURROGATE || (ch < Character.MIN_HIGH_SURROGATE ||
ch > Character.MAX_LOW_SURROGATE)) ch > Character.MAX_LOW_SURROGATE))
{ {
int off = 0; // All the checks above can potentially be constant folded by
int next = 0; // a JIT/AOT compiler when the regex is a constant string.
boolean limited = limit > 0; // That requires method inlining of the checks, which is only
ArrayList<String> list = new ArrayList<>(); // possible when the actual split logic is in a separate method
while ((next = indexOf(ch, off)) != -1) { // because the large split loop can usually not be inlined.
if (!limited || list.size() < limit - 1) { return split(ch, limit);
list.add(substring(off, next));
off = next + 1;
} else { // last one
//assert (list.size() == limit - 1);
int last = length();
list.add(substring(off, last));
off = last;
break;
}
}
// If no match was found, return this
if (off == 0)
return new String[]{this};
// Add remaining segment
if (!limited || list.size() < limit)
list.add(substring(off, length()));
// Construct result
int resultSize = list.size();
if (limit == 0) {
while (resultSize > 0 && list.get(resultSize - 1).isEmpty()) {
resultSize--;
}
}
String[] result = new String[resultSize];
return list.subList(0, resultSize).toArray(result);
} }
return Pattern.compile(regex).split(this, limit); return Pattern.compile(regex).split(this, limit);
} }
private String[] split(char ch, int limit) {
int off = 0;
int next = 0;
boolean limited = limit > 0;
ArrayList<String> list = new ArrayList<>();
while ((next = indexOf(ch, off)) != -1) {
if (!limited || list.size() < limit - 1) {
list.add(substring(off, next));
off = next + 1;
} else { // last one
//assert (list.size() == limit - 1);
int last = length();
list.add(substring(off, last));
off = last;
break;
}
}
// If no match was found, return this
if (off == 0)
return new String[]{this};
// Add remaining segment
if (!limited || list.size() < limit)
list.add(substring(off, length()));
// Construct result
int resultSize = list.size();
if (limit == 0) {
while (resultSize > 0 && list.get(resultSize - 1).isEmpty()) {
resultSize--;
}
}
String[] result = new String[resultSize];
return list.subList(0, resultSize).toArray(result);
}
/** /**
* Splits this string around matches of the given <a * Splits this string around matches of the given <a
* href="../util/regex/Pattern.html#sum">regular expression</a>. * href="../util/regex/Pattern.html#sum">regular expression</a>.