Index: src/global-handles.cc |
diff --git a/src/global-handles.cc b/src/global-handles.cc |
index a3e7f1e7c7141679a580a060370b15fe1bad8e62..cb3115abfca7db7ce9baec4a29c9da134437c223 100644 |
--- a/src/global-handles.cc |
+++ b/src/global-handles.cc |
@@ -36,6 +36,11 @@ namespace v8 { |
namespace internal { |
+ObjectGroup::~ObjectGroup() { |
+ if (info_ != NULL) info_->Dispose(); |
+} |
+ |
+ |
class GlobalHandles::Node { |
public: |
// State transition diagram: |
@@ -573,77 +578,45 @@ void GlobalHandles::IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v) { |
bool GlobalHandles::IterateObjectGroups(ObjectVisitor* v, |
WeakSlotCallbackWithHeap can_skip) { |
- if (object_groups_.length() == 0) |
- return false; |
- |
- object_groups_.Sort(); |
- retainer_infos_.Sort(); |
- |
- // During the iteration, some of the elements of object_groups are |
- // deleted. This is done by moving surviving elements at the front of the list |
- // and deleting from the end. This index tracks where the next surviving |
- // element should be moved. |
- int surviving_element_index = 0; |
- int info_index = 0; // For iterating retainer_infos_. |
- int surviving_info_index = 0; |
- |
- UniqueId current_group_id(0); |
- int current_group_start = 0; |
+ int last = 0; |
bool any_group_was_visited = false; |
- |
- for (int i = 0; i <= object_groups_.length(); ++i) { |
- if (i == 0) |
- current_group_id = object_groups_[i].id; |
- if (i == object_groups_.length() || |
- current_group_id != object_groups_[i].id) { |
- // Group detected: objects in indices [current_group_start, i[. |
- bool group_should_be_visited = false; |
- for (int j = current_group_start; j < i; ++j) { |
- Object* object = *(object_groups_[j].object); |
- if (object->IsHeapObject()) { |
- if (!can_skip(isolate_->heap(), &object)) { |
- group_should_be_visited = true; |
- break; |
- } |
+ for (int i = 0; i < object_groups_.length(); i++) { |
+ ObjectGroup* entry = object_groups_.at(i); |
+ ASSERT(entry != NULL); |
+ |
+ Object*** objects = entry->objects_; |
+ bool group_should_be_visited = false; |
+ for (size_t j = 0; j < entry->length_; j++) { |
+ Object* object = *objects[j]; |
+ if (object->IsHeapObject()) { |
+ if (!can_skip(isolate_->heap(), &object)) { |
+ group_should_be_visited = true; |
+ break; |
} |
} |
+ } |
- if (!group_should_be_visited) { |
- for (int j = current_group_start; j < i; ++j) |
- object_groups_[surviving_element_index++] = object_groups_[j]; |
- } else { |
- // An object in the group requires visiting, so iterate over all |
- // objects in the group. |
- for (int j = current_group_start; j < i; ++j) { |
- Object* object = *(object_groups_[j].object); |
- if (object->IsHeapObject()) { |
- v->VisitPointer(&object); |
- any_group_was_visited = true; |
- } |
- } |
- } |
+ if (!group_should_be_visited) { |
+ object_groups_[last++] = entry; |
+ continue; |
+ } |
- if (info_index < retainer_infos_.length() && |
- retainer_infos_[info_index].id == |
- object_groups_[current_group_start].id) { |
- // This object group has an associated ObjectGroupRetainerInfo. |
- if (!group_should_be_visited) { |
- retainer_infos_[surviving_info_index++] = |
- retainer_infos_[info_index]; |
- } else if (retainer_infos_[info_index].info != NULL) { |
- retainer_infos_[info_index].info->Dispose(); |
- retainer_infos_[info_index].info = NULL; |
- } |
- ++info_index; |
- } |
- if (i < object_groups_.length()) { |
- current_group_id = object_groups_[i].id; |
- current_group_start = i; |
+ // An object in the group requires visiting, so iterate over all |
+ // objects in the group. |
+ for (size_t j = 0; j < entry->length_; ++j) { |
+ Object* object = *objects[j]; |
+ if (object->IsHeapObject()) { |
+ v->VisitPointer(&object); |
+ any_group_was_visited = true; |
} |
} |
+ |
+ // Once the entire group has been iterated over, set the object |
+ // group to NULL so it won't be processed again. |
+ entry->Dispose(); |
+ object_groups_.at(i) = NULL; |
} |
- object_groups_.Rewind(surviving_element_index); |
- retainer_infos_.Rewind(surviving_info_index); |
+ object_groups_.Rewind(last); |
return any_group_was_visited; |
} |
@@ -851,42 +824,9 @@ void GlobalHandles::AddObjectGroup(Object*** handles, |
if (info != NULL) info->Dispose(); |
return; |
} |
- for (size_t i = 0; i < length; ++i) { |
- object_groups_.Add(ObjectGroupConnection( |
- UniqueId(reinterpret_cast<intptr_t>(handles[0])), handles[i])); |
- } |
- for (size_t i = 0; i < length; ++i) { |
- if ((*handles[i])->IsHeapObject()) { |
- representative_objects_.Add(ObjectGroupRepresentative( |
- UniqueId(reinterpret_cast<intptr_t>(handles[0])), |
- reinterpret_cast<HeapObject**>(handles[i]))); |
- break; |
- } |
- } |
- if (info != NULL) { |
- retainer_infos_.Add(ObjectGroupRetainerInfo( |
- UniqueId(reinterpret_cast<intptr_t>(handles[0])), info)); |
- } |
+ object_groups_.Add(ObjectGroup::New(handles, length, info)); |
} |
-void GlobalHandles::SetObjectGroupId(Object** handle, |
- UniqueId id) { |
- object_groups_.Add(ObjectGroupConnection(id, handle)); |
-} |
- |
- |
-void GlobalHandles::SetRetainedObjectInfo(UniqueId id, |
- RetainedObjectInfo* info) { |
- retainer_infos_.Add(ObjectGroupRetainerInfo(id, info)); |
-} |
- |
- |
-void GlobalHandles::SetObjectGroupRepresentative( |
- UniqueId id, |
- HeapObject** representative_object) { |
- representative_objects_.Add( |
- ObjectGroupRepresentative(id, representative_object)); |
-} |
void GlobalHandles::AddImplicitReferences(HeapObject** parent, |
Object*** children, |
@@ -897,31 +837,23 @@ void GlobalHandles::AddImplicitReferences(HeapObject** parent, |
ASSERT(!Node::FromLocation(children[i])->is_independent()); |
} |
#endif |
- for (size_t i = 0; i < length; ++i) { |
- implicit_ref_groups_.Add(ObjectGroupConnection( |
- UniqueId(reinterpret_cast<intptr_t>(parent)), children[i])); |
- } |
-} |
- |
- |
-void GlobalHandles::AddImplicitReference(UniqueId id, Object** child) { |
- ASSERT(!Node::FromLocation(child)->is_independent()); |
- implicit_ref_groups_.Add(ObjectGroupConnection(id, child)); |
+ if (length == 0) return; |
+ implicit_ref_groups_.Add(ImplicitRefGroup::New(parent, children, length)); |
} |
void GlobalHandles::RemoveObjectGroups() { |
- object_groups_.Clear(); |
- for (int i = 0; i < retainer_infos_.length(); ++i) { |
- if (retainer_infos_[i].info != NULL) |
- retainer_infos_[i].info->Dispose(); |
+ for (int i = 0; i < object_groups_.length(); i++) { |
+ object_groups_.at(i)->Dispose(); |
} |
- retainer_infos_.Clear(); |
+ object_groups_.Clear(); |
} |
void GlobalHandles::RemoveImplicitRefGroups() { |
- representative_objects_.Clear(); |
+ for (int i = 0; i < implicit_ref_groups_.length(); i++) { |
+ implicit_ref_groups_.at(i)->Dispose(); |
+ } |
implicit_ref_groups_.Clear(); |
} |