[heap] Update StringForwardingTable after evacuation in MC

With the flag --always-use-string-forwarding-table (only used for
testing), we can have young generation strings in the
StringForwardingTable.
We need to update references to these strings when they are evacuated
during mark compact (previously this was only done after scavenge).

Bug: v8:12877, v8:12007
Change-Id: Ie108add176f71dcdf296bd94bdffa664cb75ae02
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3650719
Reviewed-by: Dominik Inführ <dinfuehr@chromium.org>
Commit-Queue: Patrick Thier <pthier@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80575}
This commit is contained in:
Patrick Thier 2022-05-16 14:57:30 +00:00 committed by V8 LUCI CQ
parent b6b785815d
commit 98f65ffcdf
4 changed files with 15 additions and 11 deletions

View File

@ -4793,6 +4793,10 @@ void MarkCompactCollector::UpdatePointersAfterEvacuation() {
heap_->UpdateReferencesInExternalStringTable(
&UpdateReferenceInExternalStringTableEntry);
if (V8_UNLIKELY(FLAG_always_use_string_forwarding_table)) {
isolate()->string_forwarding_table()->UpdateAfterEvacuation();
}
EvacuationWeakObjectRetainer evacuation_object_retainer;
heap()->ProcessWeakListRoots(&evacuation_object_retainer);
}

View File

@ -400,7 +400,7 @@ void ScavengerCollector::CollectGarbage() {
}
if (V8_UNLIKELY(FLAG_always_use_string_forwarding_table)) {
isolate_->string_forwarding_table()->UpdateAfterScavenge();
isolate_->string_forwarding_table()->UpdateAfterEvacuation();
}
}

View File

@ -847,8 +847,8 @@ class StringForwardingTable::Block {
visitor->VisitRootPointers(Root::kStringForwardingTable, nullptr,
first_slot, end_slot);
}
void UpdateAfterScavenge(Isolate* isolate);
void UpdateAfterScavenge(Isolate* isolate, int up_to_index);
void UpdateAfterEvacuation(Isolate* isolate);
void UpdateAfterEvacuation(Isolate* isolate, int up_to_index);
private:
static constexpr int kRecordSize = 2;
@ -911,12 +911,12 @@ std::unique_ptr<StringForwardingTable::Block> StringForwardingTable::Block::New(
return std::unique_ptr<Block>(new (capacity) Block(capacity));
}
void StringForwardingTable::Block::UpdateAfterScavenge(Isolate* isolate) {
UpdateAfterScavenge(isolate, capacity_);
void StringForwardingTable::Block::UpdateAfterEvacuation(Isolate* isolate) {
UpdateAfterEvacuation(isolate, capacity_);
}
void StringForwardingTable::Block::UpdateAfterScavenge(Isolate* isolate,
int up_to_index) {
void StringForwardingTable::Block::UpdateAfterEvacuation(Isolate* isolate,
int up_to_index) {
DCHECK(FLAG_always_use_string_forwarding_table);
for (int index = 0; index < up_to_index; ++index) {
Object original = Get(isolate, IndexOfOriginalString(index));
@ -1111,7 +1111,7 @@ void StringForwardingTable::Reset() {
next_free_index_ = 0;
}
void StringForwardingTable::UpdateAfterScavenge() {
void StringForwardingTable::UpdateAfterEvacuation() {
DCHECK(FLAG_always_use_string_forwarding_table);
if (next_free_index_ == 0) return; // Early exit if table is empty.
@ -1120,12 +1120,12 @@ void StringForwardingTable::UpdateAfterScavenge() {
const unsigned int last_block = static_cast<unsigned int>(blocks->size() - 1);
for (unsigned int block = 0; block < last_block; ++block) {
Block* data = blocks->LoadBlock(block, kAcquireLoad);
data->UpdateAfterScavenge(isolate_);
data->UpdateAfterEvacuation(isolate_);
}
// Handle last block separately, as it is not filled to capacity.
const int max_index = IndexInBlock(next_free_index_ - 1, last_block) + 1;
blocks->LoadBlock(last_block, kAcquireLoad)
->UpdateAfterScavenge(isolate_, max_index);
->UpdateAfterEvacuation(isolate_, max_index);
}
} // namespace internal

View File

@ -123,7 +123,7 @@ class StringForwardingTable {
static Address GetForwardStringAddress(Isolate* isolate, int index);
void IterateElements(RootVisitor* visitor);
void Reset();
void UpdateAfterScavenge();
void UpdateAfterEvacuation();
private:
class Block;