| Index: src/mark-compact.cc
|
| ===================================================================
|
| --- src/mark-compact.cc (revision 1851)
|
| +++ src/mark-compact.cc (working copy)
|
| @@ -562,19 +562,58 @@
|
| }
|
|
|
|
|
| -void MarkCompactCollector::ProcessRoots(RootMarkingVisitor* visitor) {
|
| - // Mark the heap roots gray, including global variables, stack variables,
|
| - // etc.
|
| - Heap::IterateStrongRoots(visitor);
|
| +class SymbolMarkingVisitor : public ObjectVisitor {
|
| + public:
|
| + void VisitPointers(Object** start, Object** end) {
|
| + MarkingVisitor marker;
|
| + for (Object** p = start; p < end; p++) {
|
| + if (!(*p)->IsHeapObject()) continue;
|
|
|
| - // Take care of the symbol table specially.
|
| + HeapObject* object = HeapObject::cast(*p);
|
| + // If the object is marked, we have marked or are in the process
|
| + // of marking subparts.
|
| + if (object->IsMarked()) continue;
|
| +
|
| + // The object is unmarked, we do not need to unmark to use its
|
| + // map.
|
| + Map* map = object->map();
|
| + object->IterateBody(map->instance_type(),
|
| + object->SizeFromMap(map),
|
| + &marker);
|
| + }
|
| + }
|
| +};
|
| +
|
| +
|
| +void MarkCompactCollector::MarkSymbolTable() {
|
| + // Objects reachable from symbols are marked as live so as to ensure
|
| + // that if the symbol itself remains alive after GC for any reason,
|
| + // and if it is a sliced string or a cons string backed by an
|
| + // external string (even indirectly), then the external string does
|
| + // not receive a weak reference callback.
|
| SymbolTable* symbol_table = SymbolTable::cast(Heap::symbol_table());
|
| - // 1. Mark the prefix of the symbol table gray.
|
| - symbol_table->IteratePrefix(visitor);
|
| - // 2. Mark the symbol table black (ie, do not push it on the marking stack
|
| - // or mark it overflowed).
|
| + // Mark the symbol table itself.
|
| SetMark(symbol_table);
|
| + // Explicitly mark the prefix.
|
| + MarkingVisitor marker;
|
| + symbol_table->IteratePrefix(&marker);
|
| + ProcessMarkingStack(&marker);
|
| + // Mark subparts of the symbols but not the symbols themselves
|
| + // (unless reachable from another symbol).
|
| + SymbolMarkingVisitor symbol_marker;
|
| + symbol_table->IterateElements(&symbol_marker);
|
| + ProcessMarkingStack(&marker);
|
| +}
|
|
|
| +
|
| +void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) {
|
| + // Mark the heap roots including global variables, stack variables,
|
| + // etc., and all objects reachable from them.
|
| + Heap::IterateStrongRoots(visitor);
|
| +
|
| + // Handle the symbol table specially.
|
| + MarkSymbolTable();
|
| +
|
| // There may be overflowed objects in the heap. Visit them now.
|
| while (marking_stack.overflowed()) {
|
| RefillMarkingStack();
|
| @@ -715,7 +754,7 @@
|
| ASSERT(!marking_stack.overflowed());
|
|
|
| RootMarkingVisitor root_visitor;
|
| - ProcessRoots(&root_visitor);
|
| + MarkRoots(&root_visitor);
|
|
|
| // The objects reachable from the roots are marked black, unreachable
|
| // objects are white. Mark objects reachable from object groups with at
|
| @@ -762,21 +801,22 @@
|
|
|
|
|
| #ifdef DEBUG
|
| -void MarkCompactCollector::UpdateLiveObjectCount(HeapObject* obj) {
|
| - live_bytes_ += obj->Size();
|
| +void MarkCompactCollector::UpdateLiveObjectCount(HeapObject* obj, int scale) {
|
| + ASSERT(scale == -1 || scale == 1);
|
| + live_bytes_ += obj->Size() * scale;
|
| if (Heap::new_space()->Contains(obj)) {
|
| - live_young_objects_++;
|
| + live_young_objects_ += scale;
|
| } else if (Heap::map_space()->Contains(obj)) {
|
| ASSERT(obj->IsMap());
|
| - live_map_objects_++;
|
| + live_map_objects_ += scale;
|
| } else if (Heap::old_pointer_space()->Contains(obj)) {
|
| - live_old_pointer_objects_++;
|
| + live_old_pointer_objects_ += scale;
|
| } else if (Heap::old_data_space()->Contains(obj)) {
|
| - live_old_data_objects_++;
|
| + live_old_data_objects_ += scale;
|
| } else if (Heap::code_space()->Contains(obj)) {
|
| - live_code_objects_++;
|
| + live_code_objects_ += scale;
|
| } else if (Heap::lo_space()->Contains(obj)) {
|
| - live_lo_objects_++;
|
| + live_lo_objects_ +=scale;
|
| } else {
|
| UNREACHABLE();
|
| }
|
|
|