Append short strings by copying in string builder
This CL changes IncrementalStringBuilder to write short strings directly to {current_part_} instead of shortening {current_part}, allocating a new part and concatenate everything using ConsString. This optimization requires the IncrementalStringBuilder to either use two byte encoding, or the incoming string is flat with one byte representation. This CL improves stack trace serialization micro benchmarks up to 10%. Bug: v8:8742 Change-Id: I5cc8339be8035c42438381883544d108591fb945 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1647696 Commit-Queue: Simon Zünd <szuend@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#62075}
This commit is contained in:
parent
563290194f
commit
ef2ba53449
@ -284,6 +284,9 @@ class IncrementalStringBuilder {
|
||||
Handle<SeqString>::cast(current_part()), current_index_));
|
||||
}
|
||||
|
||||
void AppendStringByCopy(Handle<String> string);
|
||||
bool CanAppendByCopy(Handle<String> string);
|
||||
|
||||
static const int kInitialPartLength = 32;
|
||||
static const int kMaxPartLength = 16 * 1024;
|
||||
static const int kPartLengthGrowthFactor = 2;
|
||||
|
@ -284,7 +284,41 @@ MaybeHandle<String> IncrementalStringBuilder::Finish() {
|
||||
return accumulator();
|
||||
}
|
||||
|
||||
// Short strings can be copied directly to {current_part_}.
|
||||
// Requires the IncrementalStringBuilder to either have two byte encoding or
|
||||
// the incoming string to have one byte representation "underneath" (The
|
||||
// one byte check requires the string to be flat).
|
||||
bool IncrementalStringBuilder::CanAppendByCopy(Handle<String> string) {
|
||||
constexpr int kMaxStringLengthForCopy = 16;
|
||||
const bool representation_ok =
|
||||
encoding_ == String::TWO_BYTE_ENCODING ||
|
||||
(string->IsFlat() && String::IsOneByteRepresentationUnderneath(*string));
|
||||
|
||||
return representation_ok && string->length() <= kMaxStringLengthForCopy &&
|
||||
CurrentPartCanFit(string->length());
|
||||
}
|
||||
|
||||
void IncrementalStringBuilder::AppendStringByCopy(Handle<String> string) {
|
||||
DCHECK(CanAppendByCopy(string));
|
||||
|
||||
Handle<SeqOneByteString> part =
|
||||
Handle<SeqOneByteString>::cast(current_part());
|
||||
{
|
||||
DisallowHeapAllocation no_gc;
|
||||
String::WriteToFlat(*string, part->GetChars(no_gc) + current_index_, 0,
|
||||
string->length());
|
||||
}
|
||||
current_index_ += string->length();
|
||||
DCHECK(current_index_ <= part_length_);
|
||||
if (current_index_ == part_length_) Extend();
|
||||
}
|
||||
|
||||
void IncrementalStringBuilder::AppendString(Handle<String> string) {
|
||||
if (CanAppendByCopy(string)) {
|
||||
AppendStringByCopy(string);
|
||||
return;
|
||||
}
|
||||
|
||||
ShrinkCurrentPart();
|
||||
part_length_ = kInitialPartLength; // Allocate conservatively.
|
||||
Extend(); // Attach current part and allocate new part.
|
||||
|
Loading…
Reference in New Issue
Block a user