}
+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(
GarbageCollector collector) {
// Process weak global handle callbacks. This must be done after the
// See the note above.
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.
// Should be only used in GC callback function before a collection.
// All groups are destroyed after a garbage collection.
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);
}
isolate()->global_handles()->RemoveObjectGroups();
}
-// 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,
Object** p) {
MapWord first_word = HeapObject::cast(*p)->map_word();
bool PerformGarbageCollection(GarbageCollector collector,
GCTracer* tracer);
- bool IterateObjectGroups(ObjectVisitor* scavenge_visitor);
-
inline void UpdateOldSpaceLimits();
// Allocate an uninitialized object in map space. The behavior is identical
}
+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() {
SymbolTable* symbol_table = heap()->symbol_table();
// Mark the symbol table itself.
}
-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() {
List<ImplicitRefGroup*>* ref_groups =
heap()->isolate()->global_handles()->implicit_ref_groups();
}
-void MarkCompactCollector::ProcessExternalMarking() {
+void MarkCompactCollector::ProcessExternalMarking(RootMarkingVisitor* visitor) {
bool work_to_do = true;
ASSERT(marking_deque_.IsEmpty());
while (work_to_do) {
- MarkObjectGroups();
+ heap()->isolate()->global_handles()->IterateObjectGroups(
+ visitor, &IsUnmarkedHeapObjectWithHeap);
MarkImplicitRefGroups();
work_to_do = !marking_deque_.IsEmpty();
ProcessMarkingDeque();
// The objects reachable from the roots are marked, yet unreachable
// objects are unmarked. Mark objects reachable due to host
// application specific logic.
- ProcessExternalMarking();
+ ProcessExternalMarking(&root_visitor);
// The objects reachable from the roots or object groups are marked,
// yet unreachable objects are unmarked. Mark objects reachable
// Repeat host application specific marking to mark unmarked objects
// reachable from the weak roots.
- ProcessExternalMarking();
+ ProcessExternalMarking(&root_visitor);
AfterMarking();
}
// symbol table are weak.
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
// is marked.
void MarkImplicitRefGroups();
// Mark all objects which are reachable due to host application
// logic like object groups or implicit references' groups.
- void ProcessExternalMarking();
+ void ProcessExternalMarking(RootMarkingVisitor* visitor);
// Mark objects reachable (transitively) from objects in the marking stack
// or overflowed in the heap.
// Callback function for telling whether the object *p is an unmarked
// heap object.
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.
// We replace them with a null descriptor, with the same key.