Commit ef2ba534 authored by Simon Zünd's avatar Simon Zünd Committed by Commit Bot

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: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62075}
parent 56329019
......@@ -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.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment