Commit 16146df5 authored by Jakob Kummerow's avatar Jakob Kummerow Committed by V8 LUCI CQ

[heap] Don't create fillers in LO space

LargeObjectSpace doesn't make use of filler objects, so if we
create them when right-trimming objects, then that's a waste
of time at best, and causes a segfault in a SLOW_DCHECK at worst,
namely when CreateFillerObjectAt calls GetHeapFromWritableObject
on what's effectively an inner pointer (on some random LO page).

Change-Id: I91bbcaa219db78a0f98660590d5156c4b4a5414e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2972914Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75325}
parent c93c2f8e
......@@ -3163,6 +3163,10 @@ void Heap::CreateFillerObjectAtBackground(
HeapObject Heap::CreateFillerObjectAt(Address addr, int size,
ClearRecordedSlots clear_slots_mode) {
// TODO(mlippautz): It would be nice to DCHECK that we never call this
// with {addr} pointing into large object space; however we currently
// initialize LO allocations with a filler, see
// LargeObjectSpace::AllocateLargePage.
if (size == 0) return HeapObject();
HeapObject filler = CreateFillerObjectAtImpl(
ReadOnlyRoots(this), addr, size,
......
......@@ -1978,7 +1978,7 @@ MaybeHandle<String> MutableBigInt::ToStringGeneric(Isolate* isolate,
int string_size =
SeqOneByteString::SizeFor(static_cast<int>(chars_required));
int needed_size = SeqOneByteString::SizeFor(pos);
if (needed_size < string_size) {
if (needed_size < string_size && !heap->IsLargeObject(*result)) {
Address new_end = result->address() + needed_size;
heap->CreateFillerObjectAt(new_end, (string_size - needed_size),
ClearRecordedSlots::kNo);
......
......@@ -132,9 +132,15 @@ void String::MakeThin(Isolate* isolate, String internalized) {
int size_delta = old_size - ThinString::kSize;
if (size_delta != 0) {
Heap* heap = isolate->heap();
heap->CreateFillerObjectAt(
thin_end, size_delta,
has_pointers ? ClearRecordedSlots::kYes : ClearRecordedSlots::kNo);
if (!heap->IsLargeObject(thin)) {
heap->CreateFillerObjectAt(
thin_end, size_delta,
has_pointers ? ClearRecordedSlots::kYes : ClearRecordedSlots::kNo);
} else {
// We don't need special handling for the combination IsLargeObject &&
// has_pointers, because indirect strings never get that large.
DCHECK(!has_pointers);
}
}
}
......@@ -194,9 +200,15 @@ bool String::MakeExternal(v8::String::ExternalStringResource* resource) {
// Byte size of the external String object.
int new_size = this->SizeFromMap(new_map);
isolate->heap()->CreateFillerObjectAt(
this->address() + new_size, size - new_size,
has_pointers ? ClearRecordedSlots::kYes : ClearRecordedSlots::kNo);
if (!isolate->heap()->IsLargeObject(*this)) {
isolate->heap()->CreateFillerObjectAt(
this->address() + new_size, size - new_size,
has_pointers ? ClearRecordedSlots::kYes : ClearRecordedSlots::kNo);
} else {
// We don't need special handling for the combination IsLargeObject &&
// has_pointers, because indirect strings never get that large.
DCHECK(!has_pointers);
}
// We are storing the new map using release store after creating a filler for
// the left-over space to avoid races with the sweeper thread.
......@@ -269,11 +281,18 @@ bool String::MakeExternal(v8::String::ExternalOneByteStringResource* resource) {
: roots.external_one_byte_string_map();
}
// Byte size of the external String object.
int new_size = this->SizeFromMap(new_map);
isolate->heap()->CreateFillerObjectAt(
this->address() + new_size, size - new_size,
has_pointers ? ClearRecordedSlots::kYes : ClearRecordedSlots::kNo);
if (!isolate->heap()->IsLargeObject(*this)) {
// Byte size of the external String object.
int new_size = this->SizeFromMap(new_map);
isolate->heap()->CreateFillerObjectAt(
this->address() + new_size, size - new_size,
has_pointers ? ClearRecordedSlots::kYes : ClearRecordedSlots::kNo);
} else {
// We don't need special handling for the combination IsLargeObject &&
// has_pointers, because indirect strings never get that large.
DCHECK(!has_pointers);
}
// We are storing the new map using release store after creating a filler for
// the left-over space to avoid races with the sweeper thread.
......@@ -1430,10 +1449,12 @@ Handle<String> SeqString::Truncate(Handle<SeqString> string, int new_length) {
DCHECK(IsAligned(start_of_string + new_size, kObjectAlignment));
Heap* heap = Heap::FromWritableHeapObject(*string);
// Sizes are pointer size aligned, so that we can use filler objects
// that are a multiple of pointer size.
heap->CreateFillerObjectAt(start_of_string + new_size, delta,
ClearRecordedSlots::kNo);
if (!heap->IsLargeObject(*string)) {
// Sizes are pointer size aligned, so that we can use filler objects
// that are a multiple of pointer size.
heap->CreateFillerObjectAt(start_of_string + new_size, delta,
ClearRecordedSlots::kNo);
}
// 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);
......
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