Unify object groups iteration in global handles.

This unifies the iteration logic of objects groups iteration in global
handles. The scavenger as well as mark-and-compact now rely on the same
underlying logic.

R=ulan@chromium.org

Review URL: https://codereview.chromium.org/11299248

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13128 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
mstarzinger@chromium.org 2012-12-04 10:23:43 +00:00
parent b01282710f
commit a4c4862ed8
6 changed files with 69 additions and 105 deletions

View File

@ -551,6 +551,51 @@ void GlobalHandles::IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v) {
} }
bool GlobalHandles::IterateObjectGroups(ObjectVisitor* v,
WeakSlotCallbackWithHeap can_skip) {
int last = 0;
bool any_group_was_visited = 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_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) {
object_groups_[last++] = entry;
continue;
}
// 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(last);
return any_group_was_visited;
}
bool GlobalHandles::PostGarbageCollectionProcessing( bool GlobalHandles::PostGarbageCollectionProcessing(
GarbageCollector collector) { GarbageCollector collector) {
// Process weak global handle callbacks. This must be done after the // Process weak global handle callbacks. This must be done after the

View File

@ -206,6 +206,11 @@ class GlobalHandles {
// See the note above. // See the note above.
void IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v); void IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v);
// Iterate over objects in object groups that have at least one object
// which requires visiting. The callback has to return true if objects
// can be skipped and false otherwise.
bool IterateObjectGroups(ObjectVisitor* v, WeakSlotCallbackWithHeap can_skip);
// Add an object group. // Add an object group.
// Should be only used in GC callback function before a collection. // Should be only used in GC callback function before a collection.
// All groups are destroyed after a garbage collection. // All groups are destroyed after a garbage collection.

View File

@ -1338,7 +1338,8 @@ void Heap::Scavenge() {
new_space_front = DoScavenge(&scavenge_visitor, new_space_front); new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
while (IterateObjectGroups(&scavenge_visitor)) { while (isolate()->global_handles()->IterateObjectGroups(
&scavenge_visitor, &IsUnscavengedHeapObject)) {
new_space_front = DoScavenge(&scavenge_visitor, new_space_front); new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
} }
isolate()->global_handles()->RemoveObjectGroups(); isolate()->global_handles()->RemoveObjectGroups();
@ -1383,51 +1384,6 @@ void Heap::Scavenge() {
} }
// TODO(mstarzinger): Unify this method with
// MarkCompactCollector::MarkObjectGroups().
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;
}
for (size_t j = 0; j < entry->length_; ++j) {
Object* object = *objects[j];
if (object->IsHeapObject()) {
scavenge_visitor->VisitPointer(&object);
changed = true;
}
}
entry->Dispose();
object_groups->at(i) = NULL;
}
object_groups->Rewind(last);
return changed;
}
String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap, String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap,
Object** p) { Object** p) {
MapWord first_word = HeapObject::cast(*p)->map_word(); MapWord first_word = HeapObject::cast(*p)->map_word();

View File

@ -1901,8 +1901,6 @@ class Heap {
bool PerformGarbageCollection(GarbageCollector collector, bool PerformGarbageCollection(GarbageCollector collector,
GCTracer* tracer); GCTracer* tracer);
bool IterateObjectGroups(ObjectVisitor* scavenge_visitor);
inline void UpdateOldSpaceLimits(); inline void UpdateOldSpaceLimits();
// Allocate an uninitialized object in map space. The behavior is identical // Allocate an uninitialized object in map space. The behavior is identical

View File

@ -1745,6 +1745,16 @@ bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) {
} }
bool MarkCompactCollector::IsUnmarkedHeapObjectWithHeap(Heap* heap,
Object** p) {
Object* o = *p;
ASSERT(o->IsHeapObject());
HeapObject* heap_object = HeapObject::cast(o);
MarkBit mark = Marking::MarkBitFrom(heap_object);
return !mark.Get();
}
void MarkCompactCollector::MarkSymbolTable() { void MarkCompactCollector::MarkSymbolTable() {
SymbolTable* symbol_table = heap()->symbol_table(); SymbolTable* symbol_table = heap()->symbol_table();
// Mark the symbol table itself. // Mark the symbol table itself.
@ -1773,54 +1783,6 @@ void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) {
} }
void MarkCompactCollector::MarkObjectGroups() {
List<ObjectGroup*>* object_groups =
heap()->isolate()->global_handles()->object_groups();
int last = 0;
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()) {
HeapObject* heap_object = HeapObject::cast(object);
MarkBit mark = Marking::MarkBitFrom(heap_object);
if (mark.Get()) {
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()) {
HeapObject* heap_object = HeapObject::cast(object);
MarkBit mark = Marking::MarkBitFrom(heap_object);
MarkObject(heap_object, mark);
}
}
// 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);
}
void MarkCompactCollector::MarkImplicitRefGroups() { void MarkCompactCollector::MarkImplicitRefGroups() {
List<ImplicitRefGroup*>* ref_groups = List<ImplicitRefGroup*>* ref_groups =
heap()->isolate()->global_handles()->implicit_ref_groups(); heap()->isolate()->global_handles()->implicit_ref_groups();
@ -1939,11 +1901,12 @@ void MarkCompactCollector::ProcessMarkingDeque() {
} }
void MarkCompactCollector::ProcessExternalMarking() { void MarkCompactCollector::ProcessExternalMarking(RootMarkingVisitor* visitor) {
bool work_to_do = true; bool work_to_do = true;
ASSERT(marking_deque_.IsEmpty()); ASSERT(marking_deque_.IsEmpty());
while (work_to_do) { while (work_to_do) {
MarkObjectGroups(); heap()->isolate()->global_handles()->IterateObjectGroups(
visitor, &IsUnmarkedHeapObjectWithHeap);
MarkImplicitRefGroups(); MarkImplicitRefGroups();
work_to_do = !marking_deque_.IsEmpty(); work_to_do = !marking_deque_.IsEmpty();
ProcessMarkingDeque(); ProcessMarkingDeque();
@ -2022,7 +1985,7 @@ void MarkCompactCollector::MarkLiveObjects() {
// The objects reachable from the roots are marked, yet unreachable // The objects reachable from the roots are marked, yet unreachable
// objects are unmarked. Mark objects reachable due to host // objects are unmarked. Mark objects reachable due to host
// application specific logic. // application specific logic.
ProcessExternalMarking(); ProcessExternalMarking(&root_visitor);
// The objects reachable from the roots or object groups are marked, // The objects reachable from the roots or object groups are marked,
// yet unreachable objects are unmarked. Mark objects reachable // yet unreachable objects are unmarked. Mark objects reachable
@ -2041,7 +2004,7 @@ void MarkCompactCollector::MarkLiveObjects() {
// Repeat host application specific marking to mark unmarked objects // Repeat host application specific marking to mark unmarked objects
// reachable from the weak roots. // reachable from the weak roots.
ProcessExternalMarking(); ProcessExternalMarking(&root_visitor);
AfterMarking(); AfterMarking();
} }

View File

@ -756,17 +756,13 @@ class MarkCompactCollector {
// symbol table are weak. // symbol table are weak.
void MarkSymbolTable(); void MarkSymbolTable();
// Mark objects in object groups that have at least one object in the
// group marked.
void MarkObjectGroups();
// Mark objects in implicit references groups if their parent object // Mark objects in implicit references groups if their parent object
// is marked. // is marked.
void MarkImplicitRefGroups(); void MarkImplicitRefGroups();
// Mark all objects which are reachable due to host application // Mark all objects which are reachable due to host application
// logic like object groups or implicit references' groups. // logic like object groups or implicit references' groups.
void ProcessExternalMarking(); void ProcessExternalMarking(RootMarkingVisitor* visitor);
// Mark objects reachable (transitively) from objects in the marking stack // Mark objects reachable (transitively) from objects in the marking stack
// or overflowed in the heap. // or overflowed in the heap.
@ -790,6 +786,7 @@ class MarkCompactCollector {
// Callback function for telling whether the object *p is an unmarked // Callback function for telling whether the object *p is an unmarked
// heap object. // heap object.
static bool IsUnmarkedHeapObject(Object** p); static bool IsUnmarkedHeapObject(Object** p);
static bool IsUnmarkedHeapObjectWithHeap(Heap* heap, Object** p);
// Map transitions from a live map to a dead map must be killed. // Map transitions from a live map to a dead map must be killed.
// We replace them with a null descriptor, with the same key. // We replace them with a null descriptor, with the same key.