| Index: src/heap.cc
|
| ===================================================================
|
| --- src/heap.cc (revision 6095)
|
| +++ src/heap.cc (working copy)
|
| @@ -4471,7 +4471,7 @@
|
| 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()) {
|
| @@ -4905,13 +4905,20 @@
|
| }
|
|
|
|
|
| -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;
|
| @@ -4943,6 +4950,65 @@
|
| };
|
|
|
|
|
| +class UnreachableObjectsFilter : public HeapObjectsFilter {
|
| + 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) {
|
| @@ -4950,7 +5016,7 @@
|
| }
|
|
|
|
|
| -HeapIterator::HeapIterator(HeapIterator::FreeListNodesFiltering filtering)
|
| +HeapIterator::HeapIterator(HeapIterator::HeapObjectsFiltering filtering)
|
| : filtering_(filtering),
|
| filter_(NULL) {
|
| Init();
|
| @@ -4964,12 +5030,17 @@
|
|
|
| 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();
|
| }
|
| @@ -4977,9 +5048,9 @@
|
|
|
| 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
|
| @@ -4996,7 +5067,7 @@
|
| 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;
|
| }
|
|
|
|
|