Index: src/heap.cc |
diff --git a/src/heap.cc b/src/heap.cc |
index 0d2cc42402f4b3457b1d28340984069d452dbd7d..61d5a60353b5d75c85e099bb126372ede38f2b09 100644 |
--- a/src/heap.cc |
+++ b/src/heap.cc |
@@ -1331,6 +1331,14 @@ void Heap::Scavenge() { |
scavenge_visitor.VisitPointer(BitCast<Object**>(&native_contexts_list_)); |
new_space_front = DoScavenge(&scavenge_visitor, new_space_front); |
+ |
+ while (1) { |
+ if (!IterateObjectGroups(&scavenge_visitor)) |
+ break; |
+ new_space_front = DoScavenge(&scavenge_visitor, new_space_front); |
+ } |
+ isolate()->global_handles()->RemoveObjectGroups(); |
+ |
isolate_->global_handles()->IdentifyNewSpaceWeakIndependentHandles( |
&IsUnscavengedHeapObject); |
isolate_->global_handles()->IterateNewSpaceWeakIndependentRoots( |
@@ -1371,6 +1379,53 @@ void Heap::Scavenge() { |
} |
+bool Heap::IterateObjectGroups(ObjectVisitor* scavenge_visitor) { |
+ List<ObjectGroup*>* object_groups = |
+ isolate()->global_handles()->object_groups(); |
+ |
+ int last = 0; |
+ bool changed = false; |
+ for (int i = 0; i < object_groups->length(); i++) { |
+ ObjectGroup* entry = object_groups->at(i); |
+ ASSERT(entry != NULL); |
+ |
+ Object*** objects = entry->objects_; |
+ bool group_marked = false; |
+ for (size_t j = 0; j < entry->length_; j++) { |
+ Object* object = *objects[j]; |
+ if (object->IsHeapObject()) { |
+ if (!IsUnscavengedHeapObject(this, &object)) { |
+ group_marked = true; |
+ break; |
+ } |
+ } |
+ } |
+ |
+ if (!group_marked) { |
+ (*object_groups)[last++] = entry; |
+ continue; |
+ } |
+ |
+ // An object in the group is marked, so mark as grey all white heap |
+ // objects in the group. |
+ for (size_t j = 0; j < entry->length_; ++j) { |
+ Object* object = *objects[j]; |
+ if (object->IsHeapObject()) { |
+ scavenge_visitor->VisitPointer(&object); |
+ changed = true; |
+ } |
+ } |
+ |
+ // Once the entire group has been colored grey, set the object group |
+ // to NULL so it won't be processed again. |
+ entry->Dispose(); |
+ object_groups->at(i) = NULL; |
+ } |
+ object_groups->Rewind(last); |
+ return changed; |
+} |
+ |
+ |
String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap, |
Object** p) { |
MapWord first_word = HeapObject::cast(*p)->map_word(); |