[static-roots] Clear string padding faster
Clearing the exact amount of padding bytes apparently measurably regresses some string operations. For freshly allocated strings we can write into the payload area too, since that one is being written later. This allows us to clear a statically known amount of padding bytes which greatly speeds up the initialization. Bug: chromium:1402898 Bug: v8:13466 Change-Id: Ib5fd4877a88c88fbf5247ed0e2c4b2de1775623d Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4118772 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Reviewed-by: Jakob Linke <jgruber@chromium.org> Commit-Queue: Olivier Flückiger <olivf@chromium.org> Cr-Commit-Position: refs/heads/main@{#84980}
This commit is contained in:
parent
dc950c32bd
commit
bbe24f16c6
@ -674,10 +674,10 @@ MaybeHandle<SeqStringT> FactoryBase<Impl>::NewRawStringWithMap(
|
||||
SeqStringT string =
|
||||
SeqStringT::cast(AllocateRawWithImmortalMap(size, allocation, map));
|
||||
DisallowGarbageCollection no_gc;
|
||||
string.clear_padding_destructively(length);
|
||||
string.set_length(length);
|
||||
string.set_raw_hash_field(String::kEmptyHashField);
|
||||
DCHECK_EQ(size, string.Size());
|
||||
string.clear_padding();
|
||||
return handle(string, isolate());
|
||||
}
|
||||
|
||||
@ -1055,10 +1055,10 @@ FactoryBase<Impl>::AllocateRawOneByteInternalizedString(
|
||||
map);
|
||||
SeqOneByteString answer = SeqOneByteString::cast(result);
|
||||
DisallowGarbageCollection no_gc;
|
||||
answer.clear_padding_destructively(length);
|
||||
answer.set_length(length);
|
||||
answer.set_raw_hash_field(raw_hash_field);
|
||||
DCHECK_EQ(size, answer.Size());
|
||||
answer.clear_padding();
|
||||
return handle(answer, isolate());
|
||||
}
|
||||
|
||||
@ -1077,10 +1077,10 @@ FactoryBase<Impl>::AllocateRawTwoByteInternalizedString(
|
||||
map),
|
||||
map));
|
||||
DisallowGarbageCollection no_gc;
|
||||
answer.clear_padding_destructively(length);
|
||||
answer.set_length(length);
|
||||
answer.set_raw_hash_field(raw_hash_field);
|
||||
DCHECK_EQ(size, answer.Size());
|
||||
answer.clear_padding();
|
||||
return handle(answer, isolate());
|
||||
}
|
||||
|
||||
|
@ -1476,24 +1476,20 @@ SubStringRange::iterator SubStringRange::end() {
|
||||
return SubStringRange::iterator(string_, first_ + length_, no_gc_);
|
||||
}
|
||||
|
||||
void SeqOneByteString::clear_padding() {
|
||||
const int data_size = SeqString::kHeaderSize + length() * kOneByteSize;
|
||||
const int padding_size = SizeFor(length()) - data_size;
|
||||
DCHECK_EQ((DataAndPaddingSizes{data_size, padding_size}),
|
||||
GetDataAndPaddingSizes());
|
||||
DCHECK_EQ(address() + data_size + padding_size, address() + Size());
|
||||
if (padding_size == 0) return;
|
||||
memset(reinterpret_cast<void*>(address() + data_size), 0, padding_size);
|
||||
void SeqOneByteString::clear_padding_destructively(int length) {
|
||||
// Ensure we are not killing the map word, which is already set at this point
|
||||
static_assert(SizeFor(0) >= kObjectAlignment + kTaggedSize);
|
||||
memset(
|
||||
reinterpret_cast<void*>(address() + SizeFor(length) - kObjectAlignment),
|
||||
0, kObjectAlignment);
|
||||
}
|
||||
|
||||
void SeqTwoByteString::clear_padding() {
|
||||
const int data_size = SeqString::kHeaderSize + length() * base::kUC16Size;
|
||||
const int padding_size = SizeFor(length()) - data_size;
|
||||
DCHECK_EQ((DataAndPaddingSizes{data_size, padding_size}),
|
||||
GetDataAndPaddingSizes());
|
||||
DCHECK_EQ(address() + data_size + padding_size, address() + Size());
|
||||
if (padding_size == 0) return;
|
||||
memset(reinterpret_cast<void*>(address() + data_size), 0, padding_size);
|
||||
void SeqTwoByteString::clear_padding_destructively(int length) {
|
||||
// Ensure we are not killing the map word, which is already set at this point
|
||||
static_assert(SizeFor(0) >= kObjectAlignment + kTaggedSize);
|
||||
memset(
|
||||
reinterpret_cast<void*>(address() + SizeFor(length) - kObjectAlignment),
|
||||
0, kObjectAlignment);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -1824,7 +1824,7 @@ Handle<String> SeqString::Truncate(Isolate* isolate, Handle<SeqString> string,
|
||||
// We are storing the new length using release store after creating a filler
|
||||
// for the left-over space to avoid races with the sweeper thread.
|
||||
string->set_length(new_length, kReleaseStore);
|
||||
string->clear_padding();
|
||||
string->ClearPadding();
|
||||
|
||||
return string;
|
||||
}
|
||||
@ -1850,11 +1850,11 @@ SeqString::DataAndPaddingSizes SeqTwoByteString::GetDataAndPaddingSizes()
|
||||
return DataAndPaddingSizes{data_size, padding_size};
|
||||
}
|
||||
|
||||
void SeqString::clear_padding() {
|
||||
if (IsSeqOneByteString()) {
|
||||
return SeqOneByteString::cast(*this).clear_padding();
|
||||
}
|
||||
return SeqTwoByteString::cast(*this).clear_padding();
|
||||
void SeqString::ClearPadding() {
|
||||
DataAndPaddingSizes sz = GetDataAndPaddingSizes();
|
||||
DCHECK_EQ(address() + sz.data_size + sz.padding_size, address() + Size());
|
||||
if (sz.padding_size == 0) return;
|
||||
memset(reinterpret_cast<void*>(address() + sz.data_size), 0, sz.padding_size);
|
||||
}
|
||||
|
||||
uint16_t ConsString::Get(
|
||||
|
@ -714,8 +714,8 @@ class SeqString : public TorqueGeneratedSeqString<SeqString, String> {
|
||||
};
|
||||
DataAndPaddingSizes GetDataAndPaddingSizes() const;
|
||||
|
||||
// Zero out the padding bytes of this string.
|
||||
void clear_padding();
|
||||
// Zero out only the padding bytes of this string.
|
||||
void ClearPadding();
|
||||
|
||||
TQ_OBJECT_CONSTRUCTORS(SeqString)
|
||||
};
|
||||
@ -761,8 +761,8 @@ class SeqOneByteString
|
||||
|
||||
DataAndPaddingSizes GetDataAndPaddingSizes() const;
|
||||
|
||||
// Zero out the padding bytes of this string.
|
||||
inline void clear_padding();
|
||||
// Initializes padding bytes. Potentially zeros tail of the payload too!
|
||||
inline void clear_padding_destructively(int length);
|
||||
|
||||
// Maximal memory usage for a single sequential one-byte string.
|
||||
static const int kMaxCharsSize = kMaxLength;
|
||||
@ -808,8 +808,8 @@ class SeqTwoByteString
|
||||
|
||||
DataAndPaddingSizes GetDataAndPaddingSizes() const;
|
||||
|
||||
// Zero out the padding bytes of this string.
|
||||
inline void clear_padding();
|
||||
// Initializes padding bytes. Potentially zeros tail of the payload too!
|
||||
inline void clear_padding_destructively(int length);
|
||||
|
||||
// Maximal memory usage for a single sequential two-byte string.
|
||||
static const int kMaxCharsSize = kMaxLength * 2;
|
||||
|
Loading…
Reference in New Issue
Block a user