[heap] Add CHECKs for empty worklists in scavenger
Shrink life range of worklists and add IsEmpty-CHECKs for them. Also move some logic into its own method ProcessChunksWithEmptyBuckets. Bug: chromium:1336158 Change-Id: Ia2f34c824f5b1c5d61391a1a1243a46881040de1 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3704511 Commit-Queue: Dominik Inführ <dinfuehr@chromium.org> Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Cr-Commit-Position: refs/heads/main@{#81158}
This commit is contained in:
parent
18f388a6e9
commit
3366abb218
@ -269,11 +269,12 @@ void ScavengerCollector::CollectGarbage() {
|
||||
std::vector<std::unique_ptr<Scavenger>> scavengers;
|
||||
Scavenger::EmptyChunksList empty_chunks;
|
||||
const int num_scavenge_tasks = NumberOfScavengeTasks();
|
||||
Scavenger::CopiedList copied_list;
|
||||
Scavenger::PromotionList promotion_list;
|
||||
EphemeronTableList ephemeron_table_list;
|
||||
|
||||
{
|
||||
Scavenger::CopiedList copied_list;
|
||||
Scavenger::PromotionList promotion_list;
|
||||
|
||||
Sweeper* sweeper = heap_->mark_compact_collector()->sweeper();
|
||||
|
||||
// Pause the concurrent sweeper.
|
||||
@ -336,15 +337,15 @@ void ScavengerCollector::CollectGarbage() {
|
||||
std::move(memory_chunks),
|
||||
&copied_list, &promotion_list))
|
||||
->Join();
|
||||
DCHECK(copied_list.IsEmpty());
|
||||
DCHECK(promotion_list.IsEmpty());
|
||||
CHECK(copied_list.IsEmpty());
|
||||
CHECK(promotion_list.IsEmpty());
|
||||
}
|
||||
|
||||
if (V8_UNLIKELY(FLAG_scavenge_separate_stack_scanning)) {
|
||||
IterateStackAndScavenge(&root_scavenge_visitor, &scavengers,
|
||||
kMainThreadId);
|
||||
DCHECK(copied_list.IsEmpty());
|
||||
DCHECK(promotion_list.IsEmpty());
|
||||
CHECK(copied_list.IsEmpty());
|
||||
CHECK(promotion_list.IsEmpty());
|
||||
}
|
||||
|
||||
{
|
||||
@ -353,8 +354,8 @@ void ScavengerCollector::CollectGarbage() {
|
||||
GCTracer::Scope::SCAVENGER_SCAVENGE_WEAK_GLOBAL_HANDLES_PROCESS);
|
||||
isolate_->global_handles()->ProcessWeakYoungObjects(
|
||||
&root_scavenge_visitor, &IsUnscavengedHeapObjectSlot);
|
||||
DCHECK(copied_list.IsEmpty());
|
||||
DCHECK(promotion_list.IsEmpty());
|
||||
CHECK(copied_list.IsEmpty());
|
||||
CHECK(promotion_list.IsEmpty());
|
||||
}
|
||||
|
||||
{
|
||||
@ -411,27 +412,7 @@ void ScavengerCollector::CollectGarbage() {
|
||||
// TODO(hpayer): Don't free all as soon as we have an intermediate generation.
|
||||
heap_->new_lo_space()->FreeDeadObjects([](HeapObject) { return true; });
|
||||
|
||||
{
|
||||
TRACE_GC(heap_->tracer(), GCTracer::Scope::SCAVENGER_FREE_REMEMBERED_SET);
|
||||
Scavenger::EmptyChunksList::Local empty_chunks_local(&empty_chunks);
|
||||
MemoryChunk* chunk;
|
||||
while (empty_chunks_local.Pop(&chunk)) {
|
||||
// Since sweeping was already restarted only check chunks that already got
|
||||
// swept.
|
||||
if (chunk->SweepingDone()) {
|
||||
RememberedSet<OLD_TO_NEW>::CheckPossiblyEmptyBuckets(chunk);
|
||||
} else {
|
||||
chunk->possibly_empty_buckets()->Release();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
RememberedSet<OLD_TO_NEW>::IterateMemoryChunks(
|
||||
heap_, [](MemoryChunk* chunk) {
|
||||
DCHECK(chunk->possibly_empty_buckets()->IsEmpty());
|
||||
});
|
||||
#endif
|
||||
}
|
||||
ProcessChunksWithEmptyBuckets(&empty_chunks);
|
||||
|
||||
{
|
||||
TRACE_GC(heap_->tracer(), GCTracer::Scope::SCAVENGER_SWEEP_ARRAY_BUFFERS);
|
||||
@ -444,8 +425,31 @@ void ScavengerCollector::CollectGarbage() {
|
||||
heap_->IncrementYoungSurvivorsCounter(heap_->SurvivedYoungObjectSize());
|
||||
}
|
||||
|
||||
void ScavengerCollector::IterateStackAndScavenge(
|
||||
void ScavengerCollector::ProcessChunksWithEmptyBuckets(
|
||||
Scavenger::EmptyChunksList* empty_chunks) {
|
||||
TRACE_GC(heap_->tracer(), GCTracer::Scope::SCAVENGER_FREE_REMEMBERED_SET);
|
||||
Scavenger::EmptyChunksList::Local empty_chunks_local(empty_chunks);
|
||||
MemoryChunk* chunk;
|
||||
while (empty_chunks_local.Pop(&chunk)) {
|
||||
// Since sweeping was already restarted only check chunks that already got
|
||||
// swept.
|
||||
if (chunk->SweepingDone()) {
|
||||
RememberedSet<OLD_TO_NEW>::CheckPossiblyEmptyBuckets(chunk);
|
||||
} else {
|
||||
chunk->possibly_empty_buckets()->Release();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
RememberedSet<OLD_TO_NEW>::IterateMemoryChunks(heap_, [](MemoryChunk* chunk) {
|
||||
DCHECK(chunk->possibly_empty_buckets()->IsEmpty());
|
||||
});
|
||||
#endif
|
||||
|
||||
CHECK(empty_chunks->IsEmpty());
|
||||
}
|
||||
|
||||
void ScavengerCollector::IterateStackAndScavenge(
|
||||
RootScavengeVisitor* root_scavenge_visitor,
|
||||
std::vector<std::unique_ptr<Scavenger>>* scavengers, int main_thread_id) {
|
||||
// Scan the stack, scavenge the newly discovered objects, and report
|
||||
|
@ -302,6 +302,8 @@ class ScavengerCollector {
|
||||
void ClearOldEphemerons();
|
||||
void HandleSurvivingNewLargeObjects();
|
||||
|
||||
void ProcessChunksWithEmptyBuckets(Scavenger::EmptyChunksList* empty_chunks);
|
||||
|
||||
void SweepArrayBufferExtensions();
|
||||
|
||||
void IterateStackAndScavenge(
|
||||
|
Loading…
Reference in New Issue
Block a user