| Index: src/heap.cc
|
| diff --git a/src/heap.cc b/src/heap.cc
|
| index 02635ad356a0d945f3b2f062dcbbfda32a01092a..75ccc44d128ccf90118244644891e967231ee787 100644
|
| --- a/src/heap.cc
|
| +++ b/src/heap.cc
|
| @@ -404,7 +404,7 @@ intptr_t Heap::SizeOfObjects() {
|
| intptr_t total = 0;
|
| AllSpaces spaces;
|
| for (Space* space = spaces.next(); space != NULL; space = spaces.next()) {
|
| - total += space->Size();
|
| + total += space->SizeOfObjects();
|
| }
|
| return total;
|
| }
|
| @@ -4408,13 +4408,10 @@ void Heap::RecordStats(HeapStats* stats, bool take_snapshot) {
|
| MemoryAllocator::Size() + MemoryAllocator::Available();
|
| *stats->os_error = OS::GetLastError();
|
| if (take_snapshot) {
|
| - HeapIterator iterator;
|
| + HeapIterator iterator(HeapIterator::kPreciseFiltering);
|
| for (HeapObject* obj = iterator.next();
|
| obj != NULL;
|
| obj = iterator.next()) {
|
| - // Note: snapshot won't be precise because IsFreeListNode returns true
|
| - // for any bytearray.
|
| - if (FreeListNode::IsFreeListNode(obj)) continue;
|
| InstanceType type = obj->map()->instance_type();
|
| ASSERT(0 <= type && type <= LAST_TYPE);
|
| stats->objects_per_type[type]++;
|
| @@ -4769,7 +4766,17 @@ OldSpace* OldSpaces::next() {
|
| }
|
|
|
|
|
| -SpaceIterator::SpaceIterator() : current_space_(FIRST_SPACE), iterator_(NULL) {
|
| +SpaceIterator::SpaceIterator()
|
| + : current_space_(FIRST_SPACE),
|
| + iterator_(NULL),
|
| + size_func_(NULL) {
|
| +}
|
| +
|
| +
|
| +SpaceIterator::SpaceIterator(HeapObjectCallback size_func)
|
| + : current_space_(FIRST_SPACE),
|
| + iterator_(NULL),
|
| + size_func_(size_func) {
|
| }
|
|
|
|
|
| @@ -4807,25 +4814,25 @@ ObjectIterator* SpaceIterator::CreateIterator() {
|
|
|
| switch (current_space_) {
|
| case NEW_SPACE:
|
| - iterator_ = new SemiSpaceIterator(Heap::new_space());
|
| + iterator_ = new SemiSpaceIterator(Heap::new_space(), size_func_);
|
| break;
|
| case OLD_POINTER_SPACE:
|
| - iterator_ = new HeapObjectIterator(Heap::old_pointer_space());
|
| + iterator_ = new HeapObjectIterator(Heap::old_pointer_space(), size_func_);
|
| break;
|
| case OLD_DATA_SPACE:
|
| - iterator_ = new HeapObjectIterator(Heap::old_data_space());
|
| + iterator_ = new HeapObjectIterator(Heap::old_data_space(), size_func_);
|
| break;
|
| case CODE_SPACE:
|
| - iterator_ = new HeapObjectIterator(Heap::code_space());
|
| + iterator_ = new HeapObjectIterator(Heap::code_space(), size_func_);
|
| break;
|
| case MAP_SPACE:
|
| - iterator_ = new HeapObjectIterator(Heap::map_space());
|
| + iterator_ = new HeapObjectIterator(Heap::map_space(), size_func_);
|
| break;
|
| case CELL_SPACE:
|
| - iterator_ = new HeapObjectIterator(Heap::cell_space());
|
| + iterator_ = new HeapObjectIterator(Heap::cell_space(), size_func_);
|
| break;
|
| case LO_SPACE:
|
| - iterator_ = new LargeObjectIterator(Heap::lo_space());
|
| + iterator_ = new LargeObjectIterator(Heap::lo_space(), size_func_);
|
| break;
|
| }
|
|
|
| @@ -4835,7 +4842,54 @@ ObjectIterator* SpaceIterator::CreateIterator() {
|
| }
|
|
|
|
|
| -HeapIterator::HeapIterator() {
|
| +class FreeListNodesFilter {
|
| + public:
|
| + FreeListNodesFilter() {
|
| + MarkFreeListNodes();
|
| + }
|
| +
|
| + inline bool IsFreeListNode(HeapObject* object) {
|
| + if (object->IsMarked()) {
|
| + object->ClearMark();
|
| + return true;
|
| + } else {
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + private:
|
| + void MarkFreeListNodes() {
|
| + Heap::old_pointer_space()->MarkFreeListNodes();
|
| + Heap::old_data_space()->MarkFreeListNodes();
|
| + MarkCodeSpaceFreeListNodes();
|
| + Heap::map_space()->MarkFreeListNodes();
|
| + Heap::cell_space()->MarkFreeListNodes();
|
| + }
|
| +
|
| + void MarkCodeSpaceFreeListNodes() {
|
| + // For code space, using FreeListNode::IsFreeListNode is OK.
|
| + HeapObjectIterator iter(Heap::code_space());
|
| + for (HeapObject* obj = iter.next_object();
|
| + obj != NULL;
|
| + obj = iter.next_object()) {
|
| + if (FreeListNode::IsFreeListNode(obj)) obj->SetMark();
|
| + }
|
| + }
|
| +
|
| + AssertNoAllocation no_alloc;
|
| +};
|
| +
|
| +
|
| +HeapIterator::HeapIterator()
|
| + : filtering_(HeapIterator::kNoFiltering),
|
| + filter_(NULL) {
|
| + Init();
|
| +}
|
| +
|
| +
|
| +HeapIterator::HeapIterator(HeapIterator::FreeListNodesFiltering filtering)
|
| + : filtering_(filtering),
|
| + filter_(NULL) {
|
| Init();
|
| }
|
|
|
| @@ -4847,20 +4901,44 @@ HeapIterator::~HeapIterator() {
|
|
|
| void HeapIterator::Init() {
|
| // Start the iteration.
|
| - space_iterator_ = new SpaceIterator();
|
| + if (filtering_ == kPreciseFiltering) {
|
| + filter_ = new FreeListNodesFilter;
|
| + space_iterator_ =
|
| + new SpaceIterator(MarkCompactCollector::SizeOfMarkedObject);
|
| + } else {
|
| + space_iterator_ = new SpaceIterator;
|
| + }
|
| object_iterator_ = space_iterator_->next();
|
| }
|
|
|
|
|
| void HeapIterator::Shutdown() {
|
| +#ifdef DEBUG
|
| + // Assert that in precise mode we have iterated through all
|
| + // objects. Otherwise, heap will be left in an inconsistent state.
|
| + if (filtering_ == kPreciseFiltering) {
|
| + ASSERT(object_iterator_ == NULL);
|
| + }
|
| +#endif
|
| // Make sure the last iterator is deallocated.
|
| delete space_iterator_;
|
| space_iterator_ = NULL;
|
| object_iterator_ = NULL;
|
| + delete filter_;
|
| + filter_ = NULL;
|
| }
|
|
|
|
|
| HeapObject* HeapIterator::next() {
|
| + if (filter_ == NULL) return NextObject();
|
| +
|
| + HeapObject* obj = NextObject();
|
| + while (obj != NULL && filter_->IsFreeListNode(obj)) obj = NextObject();
|
| + return obj;
|
| +}
|
| +
|
| +
|
| +HeapObject* HeapIterator::NextObject() {
|
| // No iterator means we are done.
|
| if (object_iterator_ == NULL) return NULL;
|
|
|
|
|