| Index: src/mark-compact.cc
|
| diff --git a/src/mark-compact.cc b/src/mark-compact.cc
|
| index 9df9af1114befca5fed38de2272b637041d960f5..b91f7bc512862795014d4fc041c6ac7a220839a6 100644
|
| --- a/src/mark-compact.cc
|
| +++ b/src/mark-compact.cc
|
| @@ -1190,14 +1190,41 @@ void MarkCompactCollector::MarkObjectGroups() {
|
| MarkObject(HeapObject::cast(*objects[j]));
|
| }
|
| }
|
| +
|
| // Once the entire group has been colored gray, set the object group
|
| // to NULL so it won't be processed again.
|
| - delete object_groups->at(i);
|
| + delete entry;
|
| object_groups->at(i) = NULL;
|
| }
|
| }
|
|
|
|
|
| +void MarkCompactCollector::MarkImplicitRefGroups() {
|
| + List<ImplicitRefGroup*>* ref_groups = GlobalHandles::ImplicitRefGroups();
|
| +
|
| + for (int i = 0; i < ref_groups->length(); i++) {
|
| + ImplicitRefGroup* entry = ref_groups->at(i);
|
| + if (entry == NULL) continue;
|
| +
|
| + if (!entry->parent_->IsMarked()) continue;
|
| +
|
| + List<Object**>& children = entry->children_;
|
| + // A parent object is marked, so mark as gray all child white heap
|
| + // objects.
|
| + for (int j = 0; j < children.length(); ++j) {
|
| + if ((*children[j])->IsHeapObject()) {
|
| + MarkObject(HeapObject::cast(*children[j]));
|
| + }
|
| + }
|
| +
|
| + // Once the entire group has been colored gray, set the group
|
| + // to NULL so it won't be processed again.
|
| + delete entry;
|
| + ref_groups->at(i) = NULL;
|
| + }
|
| +}
|
| +
|
| +
|
| // Mark all objects reachable from the objects on the marking stack.
|
| // Before: the marking stack contains zero or more heap object pointers.
|
| // After: the marking stack is empty, and all objects reachable from the
|
| @@ -1276,11 +1303,12 @@ void MarkCompactCollector::ProcessMarkingStack() {
|
| }
|
|
|
|
|
| -void MarkCompactCollector::ProcessObjectGroups() {
|
| +void MarkCompactCollector::ProcessExternalMarking() {
|
| bool work_to_do = true;
|
| ASSERT(marking_stack.is_empty());
|
| while (work_to_do) {
|
| MarkObjectGroups();
|
| + MarkImplicitRefGroups();
|
| work_to_do = !marking_stack.is_empty();
|
| ProcessMarkingStack();
|
| }
|
| @@ -1311,10 +1339,9 @@ void MarkCompactCollector::MarkLiveObjects() {
|
| MarkRoots(&root_visitor);
|
|
|
| // The objects reachable from the roots are marked, yet unreachable
|
| - // objects are unmarked. Mark objects reachable from object groups
|
| - // containing at least one marked object, and continue until no new
|
| - // objects are reachable from the object groups.
|
| - ProcessObjectGroups();
|
| + // objects are unmarked. Mark objects reachable due to host
|
| + // application specific logic.
|
| + ProcessExternalMarking();
|
|
|
| // The objects reachable from the roots or object groups are marked,
|
| // yet unreachable objects are unmarked. Mark objects reachable
|
| @@ -1330,9 +1357,9 @@ void MarkCompactCollector::MarkLiveObjects() {
|
| EmptyMarkingStack();
|
| }
|
|
|
| - // Repeat the object groups to mark unmarked groups reachable from the
|
| - // weak roots.
|
| - ProcessObjectGroups();
|
| + // Repeat host application specific marking to mark unmarked objects
|
| + // reachable from the weak roots.
|
| + ProcessExternalMarking();
|
|
|
| // Prune the symbol table removing all symbols only pointed to by the
|
| // symbol table. Cannot use symbol_table() here because the symbol
|
| @@ -1350,6 +1377,7 @@ void MarkCompactCollector::MarkLiveObjects() {
|
|
|
| // Remove object groups after marking phase.
|
| GlobalHandles::RemoveObjectGroups();
|
| + GlobalHandles::RemoveImplicitRefGroups();
|
|
|
| // Flush code from collected candidates.
|
| FlushCode::ProcessCandidates();
|
|
|