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; |
} |