[heap] Finish sweeping without refilling free lists on shutdown

Help sweeper tasks complete sweeping sooner but do not refill free
lists on shutdown.

This races with allocating background threads. Background threads will
refill free lists themselves if more memory is required.

Bug: v8:10315
Change-Id: Ie615983229701e8c9434b4352bd055e9dbbb8671
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2297466
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68842}
diff --git a/src/execution/isolate.cc b/src/execution/isolate.cc
index eb47296..7b0beeb3 100644
--- a/src/execution/isolate.cc
+++ b/src/execution/isolate.cc
@@ -2955,7 +2955,10 @@
 
   BackingStore::RemoveSharedWasmMemoryObjects(this);
 
-  heap_.mark_compact_collector()->EnsureSweepingCompleted();
+  // Help sweeper threads complete sweeping to stop faster.
+  heap_.mark_compact_collector()->DrainSweepingWorklists();
+  heap_.mark_compact_collector()->sweeper()->EnsureIterabilityCompleted();
+
   heap_.memory_allocator()->unmapper()->EnsureUnmappingCompleted();
 
   DumpAndResetStats();
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc
index 5491970..8182111 100644
--- a/src/heap/mark-compact.cc
+++ b/src/heap/mark-compact.cc
@@ -622,6 +622,11 @@
 #endif
 }
 
+void MarkCompactCollector::DrainSweepingWorklists() {
+  if (!sweeper()->sweeping_in_progress()) return;
+  sweeper()->DrainSweepingWorklists();
+}
+
 void MarkCompactCollector::DrainSweepingWorklistForSpace(
     AllocationSpace space) {
   if (!sweeper()->sweeping_in_progress()) return;
diff --git a/src/heap/mark-compact.h b/src/heap/mark-compact.h
index 2c283a3..cd20ba7 100644
--- a/src/heap/mark-compact.h
+++ b/src/heap/mark-compact.h
@@ -516,6 +516,8 @@
   //
   // Note: Can only be called safely from main thread.
   V8_EXPORT_PRIVATE void EnsureSweepingCompleted();
+
+  void DrainSweepingWorklists();
   void DrainSweepingWorklistForSpace(AllocationSpace space);
 
   // Checks if sweeping is in progress right now on any space.
diff --git a/src/heap/sweeper.cc b/src/heap/sweeper.cc
index 3e8e60f..fff7684 100644
--- a/src/heap/sweeper.cc
+++ b/src/heap/sweeper.cc
@@ -247,6 +247,13 @@
   sweeping_in_progress_ = false;
 }
 
+void Sweeper::DrainSweepingWorklists() {
+  if (!sweeping_in_progress_) return;
+
+  ForAllSweepingSpaces(
+      [this](AllocationSpace space) { DrainSweepingWorklistForSpace(space); });
+}
+
 void Sweeper::DrainSweepingWorklistForSpace(AllocationSpace space) {
   if (!sweeping_in_progress_) return;
   ParallelSweepSpace(space, 0);
diff --git a/src/heap/sweeper.h b/src/heap/sweeper.h
index 0c2d58c..e1c6c11 100644
--- a/src/heap/sweeper.h
+++ b/src/heap/sweeper.h
@@ -106,6 +106,7 @@
   void StartSweeping();
   V8_EXPORT_PRIVATE void StartSweeperTasks();
   void EnsureCompleted();
+  void DrainSweepingWorklists();
   void DrainSweepingWorklistForSpace(AllocationSpace space);
   bool AreSweeperTasksRunning();