Index: src/heap/mark-compact.cc |
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc |
index 00110796bdfb3567cf2c18ba8c42d416fd680f76..51a650a09930bd70af2d196beebe1e6b97abcc37 100644 |
--- a/src/heap/mark-compact.cc |
+++ b/src/heap/mark-compact.cc |
@@ -2088,13 +2088,16 @@ void MarkCompactCollector::ProcessMarkingDeque() { |
// Mark all objects reachable (transitively) from objects on the marking |
// stack including references only considered in the atomic marking pause. |
-void MarkCompactCollector::ProcessEphemeralMarking(ObjectVisitor* visitor) { |
+void MarkCompactCollector::ProcessEphemeralMarking( |
+ ObjectVisitor* visitor, bool only_process_harmony_weak_collections) { |
bool work_to_do = true; |
DCHECK(marking_deque_.IsEmpty()); |
while (work_to_do) { |
- isolate()->global_handles()->IterateObjectGroups( |
- visitor, &IsUnmarkedHeapObjectWithHeap); |
- MarkImplicitRefGroups(); |
+ if (!only_process_harmony_weak_collections) { |
+ isolate()->global_handles()->IterateObjectGroups( |
+ visitor, &IsUnmarkedHeapObjectWithHeap); |
+ MarkImplicitRefGroups(); |
+ } |
ProcessWeakCollections(); |
work_to_do = !marking_deque_.IsEmpty(); |
ProcessMarkingDeque(); |
@@ -2222,26 +2225,26 @@ void MarkCompactCollector::MarkLiveObjects() { |
// The objects reachable from the roots are marked, yet unreachable |
// objects are unmarked. Mark objects reachable due to host |
// application specific logic or through Harmony weak maps. |
- ProcessEphemeralMarking(&root_visitor); |
+ ProcessEphemeralMarking(&root_visitor, false); |
// The objects reachable from the roots, weak maps or object groups |
- // are marked, yet unreachable objects are unmarked. Mark objects |
- // reachable only from weak global handles. |
+ // are marked. Objects pointed to only by weak global handles cannot be |
+ // immediately reclaimed. Instead, we have to mark them as pending and mark |
+ // objects reachable from them. |
// |
// First we identify nonlive weak handles and mark them as pending |
// destruction. |
heap()->isolate()->global_handles()->IdentifyWeakHandles( |
&IsUnmarkedHeapObject); |
- // Then we mark the objects and process the transitive closure. |
+ // Then we mark the objects. |
heap()->isolate()->global_handles()->IterateWeakRoots(&root_visitor); |
- while (marking_deque_.overflowed()) { |
- RefillMarkingDeque(); |
- EmptyMarkingDeque(); |
- } |
- // Repeat host application specific and Harmony weak maps marking to |
- // mark unmarked objects reachable from the weak roots. |
- ProcessEphemeralMarking(&root_visitor); |
+ // Repeat Harmony weak maps marking to mark unmarked objects reachable from |
+ // the weak roots we just marked as pending destruction. |
+ // |
+ // We only process harmony collections, as all object groups have been fully |
+ // processed and no weakly reachable node can discover new objects groups. |
+ ProcessEphemeralMarking(&root_visitor, true); |
AfterMarking(); |