Chromium Code Reviews| Index: src/heap.cc |
| diff --git a/src/heap.cc b/src/heap.cc |
| index ccf9b47a35c56f48f4d6a5beb8f03da7392a469b..1e9999164ccf2a9394fbca35a37737e27a4f6729 100644 |
| --- a/src/heap.cc |
| +++ b/src/heap.cc |
| @@ -4483,7 +4483,7 @@ void Heap::RecordStats(HeapStats* stats, bool take_snapshot) { |
| MemoryAllocator::Size() + MemoryAllocator::Available(); |
| *stats->os_error = OS::GetLastError(); |
| if (take_snapshot) { |
| - HeapIterator iterator(HeapIterator::kPreciseFiltering); |
| + HeapIterator iterator(HeapIterator::kFilterFreeListNodes); |
| for (HeapObject* obj = iterator.next(); |
| obj != NULL; |
| obj = iterator.next()) { |
| @@ -4917,13 +4917,20 @@ ObjectIterator* SpaceIterator::CreateIterator() { |
| } |
| -class FreeListNodesFilter { |
| +class HeapObjectsFilter { |
| + public: |
| + virtual ~HeapObjectsFilter() {} |
| + virtual bool SkipObject(HeapObject* object) = 0; |
| +}; |
| + |
| + |
| +class FreeListNodesFilter : public HeapObjectsFilter { |
| public: |
| FreeListNodesFilter() { |
| MarkFreeListNodes(); |
| } |
| - inline bool IsFreeListNode(HeapObject* object) { |
| + bool SkipObject(HeapObject* object) { |
| if (object->IsMarked()) { |
| object->ClearMark(); |
| return true; |
| @@ -4955,6 +4962,65 @@ class FreeListNodesFilter { |
| }; |
| +class UnreachableObjectsFilter : public HeapObjectsFilter { |
|
Søren Thygesen Gjesse
2010/12/21 09:04:44
Regarding the marking of unreachable objects - can
mnaganov (inactive)
2010/12/21 10:48:00
The problem is: once an object is marked, it doesn
|
| + public: |
| + UnreachableObjectsFilter() { |
| + MarkUnreachableObjects(); |
| + } |
| + |
| + bool SkipObject(HeapObject* object) { |
| + if (object->IsMarked()) { |
| + object->ClearMark(); |
| + return true; |
| + } else { |
| + return false; |
| + } |
| + } |
| + |
| + private: |
| + class UnmarkingVisitor : public ObjectVisitor { |
| + public: |
| + UnmarkingVisitor() : list_(10) {} |
| + |
| + void VisitPointers(Object** start, Object** end) { |
| + for (Object** p = start; p < end; p++) { |
| + if (!(*p)->IsHeapObject()) continue; |
| + HeapObject* obj = HeapObject::cast(*p); |
| + if (obj->IsMarked()) { |
| + obj->ClearMark(); |
| + list_.Add(obj); |
| + } |
| + } |
| + } |
| + |
| + bool can_process() { return !list_.is_empty(); } |
| + |
| + void ProcessNext() { |
| + HeapObject* obj = list_.RemoveLast(); |
| + obj->Iterate(this); |
| + } |
| + |
| + private: |
| + List<HeapObject*> list_; |
| + }; |
| + |
| + void MarkUnreachableObjects() { |
| + HeapIterator iterator; |
| + for (HeapObject* obj = iterator.next(); |
| + obj != NULL; |
| + obj = iterator.next()) { |
| + obj->SetMark(); |
| + } |
| + UnmarkingVisitor visitor; |
| + Heap::IterateRoots(&visitor, VISIT_ONLY_STRONG); |
| + while (visitor.can_process()) |
| + visitor.ProcessNext(); |
| + } |
| + |
| + AssertNoAllocation no_alloc; |
| +}; |
| + |
| + |
| HeapIterator::HeapIterator() |
| : filtering_(HeapIterator::kNoFiltering), |
| filter_(NULL) { |
| @@ -4962,7 +5028,7 @@ HeapIterator::HeapIterator() |
| } |
| -HeapIterator::HeapIterator(HeapIterator::FreeListNodesFiltering filtering) |
| +HeapIterator::HeapIterator(HeapIterator::HeapObjectsFiltering filtering) |
| : filtering_(filtering), |
| filter_(NULL) { |
| Init(); |
| @@ -4976,12 +5042,17 @@ HeapIterator::~HeapIterator() { |
| void HeapIterator::Init() { |
| // Start the iteration. |
| - if (filtering_ == kPreciseFiltering) { |
| - filter_ = new FreeListNodesFilter; |
| - space_iterator_ = |
| - new SpaceIterator(MarkCompactCollector::SizeOfMarkedObject); |
| - } else { |
| - space_iterator_ = new SpaceIterator; |
| + space_iterator_ = filtering_ == kNoFiltering ? new SpaceIterator : |
| + new SpaceIterator(MarkCompactCollector::SizeOfMarkedObject); |
| + switch (filtering_) { |
| + case kFilterFreeListNodes: |
| + filter_ = new FreeListNodesFilter; |
| + break; |
| + case kFilterUnreachable: |
| + filter_ = new UnreachableObjectsFilter; |
| + break; |
| + default: |
| + break; |
| } |
| object_iterator_ = space_iterator_->next(); |
| } |
| @@ -4989,9 +5060,9 @@ void HeapIterator::Init() { |
| void HeapIterator::Shutdown() { |
| #ifdef DEBUG |
| - // Assert that in precise mode we have iterated through all |
| + // Assert that in filtering mode we have iterated through all |
| // objects. Otherwise, heap will be left in an inconsistent state. |
| - if (filtering_ == kPreciseFiltering) { |
| + if (filtering_ != kNoFiltering) { |
| ASSERT(object_iterator_ == NULL); |
| } |
| #endif |
| @@ -5008,7 +5079,7 @@ HeapObject* HeapIterator::next() { |
| if (filter_ == NULL) return NextObject(); |
| HeapObject* obj = NextObject(); |
| - while (obj != NULL && filter_->IsFreeListNode(obj)) obj = NextObject(); |
| + while (obj != NULL && filter_->SkipObject(obj)) obj = NextObject(); |
| return obj; |
| } |