Index: src/mark-compact.cc |
=================================================================== |
--- src/mark-compact.cc (revision 1845) |
+++ src/mark-compact.cc (working copy) |
@@ -562,19 +562,48 @@ |
} |
+// Helper class to unmark marked objects in a range of pointers but |
+// not recursively. |
+class UnmarkingVisitor : public ObjectVisitor { |
+ public: |
+ void VisitPointers(Object** start, Object** end) { |
+ for (Object** p = start; p < end; p++) { |
+ if ((*p)->IsHeapObject() && HeapObject::cast(*p)->IsMarked()) { |
+ MarkCompactCollector::ClearMark(HeapObject::cast(*p)); |
+ } |
+ } |
+ } |
+}; |
+ |
+ |
void MarkCompactCollector::ProcessRoots(RootMarkingVisitor* visitor) { |
- // Mark the heap roots gray, including global variables, stack variables, |
- // etc. |
- Heap::IterateStrongRoots(visitor); |
- |
- // Take care of the symbol table specially. |
+ // Handle the symbol table specially. Mark the prefix and the |
+ // symbol table itself. Do not mark the symbol table entries, but |
+ // do explicitly mark all other objects reachable from them. |
+ // |
+ // 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. |
iposva
2009/05/04 17:54:47
In retrospect was that not always a problem even w
Kevin Millikin (Chromium)
2009/05/04 18:34:52
I don't think so. The problem was that the weak r
|
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). |
+ // First mark everything reachable from the symbol table, then |
+ // unmark just the elements themselves. |
+ symbol_table->Iterate(visitor); |
+ // There may be overflowed objects in the heap. Visit them now. |
+ while (marking_stack.overflowed()) { |
+ RefillMarkingStack(); |
+ EmptyMarkingStack(visitor->stack_visitor()); |
+ } |
+ UnmarkingVisitor unmarking_visitor; |
+ symbol_table->IterateElements(&unmarking_visitor); |
+ // Mark the symbol table itself. |
SetMark(symbol_table); |
iposva
2009/05/04 17:54:47
The flipping of mark bits to marked and back to un
Kevin Millikin (Chromium)
2009/05/04 18:34:52
This was just the simplest implementation to get a
|
+ // Mark the heap roots including global variables, stack variables, |
+ // etc., and all objects reachable from them. |
+ Heap::IterateStrongRoots(visitor); |
+ |
// There may be overflowed objects in the heap. Visit them now. |
while (marking_stack.overflowed()) { |
RefillMarkingStack(); |
@@ -762,21 +791,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(); |
} |