[vm, gc] Don't hold PageSpace::tasks_lock_ while visiting remembered cards.
The scavenger may abort while visiting the remembered cards if we run out of memory. The longjmp implementing this abort would skip ~MonitorLocker, leaving the monitor locked and (in debug mode) Thread::no_safepoint_scope_ unbalanced.
TEST=fragmentation_test
Bug: https://github.com/dart-lang/sdk/issues/45059
Change-Id: I63d77709c8d8948b5827f7ecde5b0ecb3af9a245
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/186640
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Liam Appelbe <liama@google.com>
diff --git a/runtime/vm/heap/pages.cc b/runtime/vm/heap/pages.cc
index 8070a58..192c3df 100644
--- a/runtime/vm/heap/pages.cc
+++ b/runtime/vm/heap/pages.cc
@@ -804,9 +804,11 @@
(Thread::Current()->task_kind() == Thread::kScavengerTask));
// Wait for the sweeper to finish mutating the large page list.
- MonitorLocker ml(tasks_lock());
- while (phase() == kSweepingLarge) {
- ml.Wait(); // No safepoint check.
+ {
+ MonitorLocker ml(tasks_lock());
+ while (phase() == kSweepingLarge) {
+ ml.Wait(); // No safepoint check.
+ }
}
// Large pages may be added concurrently due to promotion in another scavenge
diff --git a/runtime/vm/heap/scavenger.cc b/runtime/vm/heap/scavenger.cc
index 5a8c0d5..e4807d5 100644
--- a/runtime/vm/heap/scavenger.cc
+++ b/runtime/vm/heap/scavenger.cc
@@ -1710,6 +1710,7 @@
// Reverse the partial forwarding from the aborted scavenge. This also
// rebuilds the remembered set.
+ heap_->WaitForSweeperTasksAtSafepoint(thread);
Become::FollowForwardingPointers(thread);
// Don't scavenge again until the next old-space GC has occurred. Prevents