diff --git a/src/heap/heap-inl.h b/src/heap/heap-inl.h index dda9a89c98..b5d785ff8d 100644 --- a/src/heap/heap-inl.h +++ b/src/heap/heap-inl.h @@ -146,30 +146,12 @@ ROOT_LIST(ROOT_ACCESSOR) #undef ROOT_ACCESSOR PagedSpace* Heap::paged_space(int idx) { - switch (idx) { - case OLD_SPACE: - return old_space(); - case MAP_SPACE: - return map_space(); - case CODE_SPACE: - return code_space(); - case NEW_SPACE: - case LO_SPACE: - UNREACHABLE(); - } - return NULL; + DCHECK_NE(idx, LO_SPACE); + DCHECK_NE(idx, NEW_SPACE); + return static_cast(space_[idx]); } -Space* Heap::space(int idx) { - switch (idx) { - case NEW_SPACE: - return new_space(); - case LO_SPACE: - return lo_space(); - default: - return paged_space(idx); - } -} +Space* Heap::space(int idx) { return space_[idx]; } Address* Heap::NewSpaceAllocationTopAddress() { return new_space_->allocation_top_address(); diff --git a/src/heap/heap.cc b/src/heap/heap.cc index 0a4db85e8d..0946d94124 100644 --- a/src/heap/heap.cc +++ b/src/heap/heap.cc @@ -5431,7 +5431,11 @@ bool Heap::SetUp() { // Initialize incremental marking. incremental_marking_ = new IncrementalMarking(this); - new_space_ = new NewSpace(this); + for (int i = 0; i <= LAST_SPACE; i++) { + space_[i] = nullptr; + } + + space_[NEW_SPACE] = new_space_ = new NewSpace(this); if (new_space_ == nullptr) return false; // Set up new space. @@ -5441,25 +5445,26 @@ bool Heap::SetUp() { new_space_top_after_last_gc_ = new_space()->top(); // Initialize old space. - old_space_ = new OldSpace(this, OLD_SPACE, NOT_EXECUTABLE); + space_[OLD_SPACE] = old_space_ = + new OldSpace(this, OLD_SPACE, NOT_EXECUTABLE); if (old_space_ == NULL) return false; if (!old_space_->SetUp()) return false; // Initialize the code space, set its maximum capacity to the old // generation size. It needs executable memory. - code_space_ = new OldSpace(this, CODE_SPACE, EXECUTABLE); + space_[CODE_SPACE] = code_space_ = new OldSpace(this, CODE_SPACE, EXECUTABLE); if (code_space_ == NULL) return false; if (!code_space_->SetUp()) return false; // Initialize map space. - map_space_ = new MapSpace(this, MAP_SPACE); + space_[MAP_SPACE] = map_space_ = new MapSpace(this, MAP_SPACE); if (map_space_ == NULL) return false; if (!map_space_->SetUp()) return false; // The large object code space may contain code or data. We set the memory // to be non-executable here for safety, but this means we need to enable it // explicitly when allocating large code objects. - lo_space_ = new LargeObjectSpace(this, LO_SPACE); + space_[LO_SPACE] = lo_space_ = new LargeObjectSpace(this, LO_SPACE); if (lo_space_ == NULL) return false; if (!lo_space_->SetUp()) return false; @@ -5988,14 +5993,10 @@ OldSpace* OldSpaces::next() { } } - SpaceIterator::SpaceIterator(Heap* heap) - : heap_(heap), current_space_(FIRST_SPACE), iterator_(NULL) {} - + : heap_(heap), current_space_(FIRST_SPACE - 1) {} SpaceIterator::~SpaceIterator() { - // Delete active iterator if any. - delete iterator_; } @@ -6004,48 +6005,9 @@ bool SpaceIterator::has_next() { return current_space_ != LAST_SPACE; } - -ObjectIterator* SpaceIterator::next() { - if (iterator_ != NULL) { - delete iterator_; - iterator_ = NULL; - // Move to the next space - current_space_++; - if (current_space_ > LAST_SPACE) { - return NULL; - } - } - - // Return iterator for the new current space. - return CreateIterator(); -} - - -// Create an iterator for the space to iterate. -ObjectIterator* SpaceIterator::CreateIterator() { - DCHECK(iterator_ == NULL); - - switch (current_space_) { - case NEW_SPACE: - iterator_ = new SemiSpaceIterator(heap_->new_space()); - break; - case OLD_SPACE: - iterator_ = new HeapObjectIterator(heap_->old_space()); - break; - case CODE_SPACE: - iterator_ = new HeapObjectIterator(heap_->code_space()); - break; - case MAP_SPACE: - iterator_ = new HeapObjectIterator(heap_->map_space()); - break; - case LO_SPACE: - iterator_ = new LargeObjectIterator(heap_->lo_space()); - break; - } - - // Return the newly allocated iterator; - DCHECK(iterator_ != NULL); - return iterator_; +Space* SpaceIterator::next() { + DCHECK(has_next()); + return heap_->space(++current_space_); } @@ -6130,7 +6092,7 @@ HeapIterator::HeapIterator(Heap* heap, default: break; } - object_iterator_ = space_iterator_->next(); + object_iterator_ = space_iterator_->next()->GetObjectIterator(); } @@ -6143,8 +6105,6 @@ HeapIterator::~HeapIterator() { DCHECK(object_iterator_ == nullptr); } #endif - // Make sure the last iterator is deallocated. - delete object_iterator_; delete space_iterator_; delete filter_; } @@ -6161,22 +6121,22 @@ HeapObject* HeapIterator::next() { HeapObject* HeapIterator::NextObject() { // No iterator means we are done. - if (object_iterator_ == nullptr) return nullptr; + if (object_iterator_.get() == nullptr) return nullptr; - if (HeapObject* obj = object_iterator_->Next()) { + if (HeapObject* obj = object_iterator_.get()->Next()) { // If the current iterator has more objects we are fine. return obj; } else { // Go though the spaces looking for one that has objects. while (space_iterator_->has_next()) { - object_iterator_ = space_iterator_->next(); - if (HeapObject* obj = object_iterator_->Next()) { + object_iterator_ = space_iterator_->next()->GetObjectIterator(); + if (HeapObject* obj = object_iterator_.get()->Next()) { return obj; } } } // Done with the last space. - object_iterator_ = nullptr; + object_iterator_.reset(nullptr); return nullptr; } diff --git a/src/heap/heap.h b/src/heap/heap.h index b09ed98e14..60c2464f5a 100644 --- a/src/heap/heap.h +++ b/src/heap/heap.h @@ -2120,6 +2120,8 @@ class Heap { OldSpace* code_space_; MapSpace* map_space_; LargeObjectSpace* lo_space_; + // Map from the space id to the space. + Space* space_[LAST_SPACE + 1]; HeapState gc_state_; int gc_post_processing_depth_; Address new_space_top_after_last_gc_; @@ -2428,23 +2430,17 @@ class PagedSpaces BASE_EMBEDDED { }; -// Space iterator for iterating over all spaces of the heap. -// For each space an object iterator is provided. The deallocation of the -// returned object iterators is handled by the space iterator. class SpaceIterator : public Malloced { public: explicit SpaceIterator(Heap* heap); virtual ~SpaceIterator(); bool has_next(); - ObjectIterator* next(); + Space* next(); private: - ObjectIterator* CreateIterator(); - Heap* heap_; int current_space_; // from enum AllocationSpace. - ObjectIterator* iterator_; // object iterator for the current space. }; @@ -2490,7 +2486,7 @@ class HeapIterator BASE_EMBEDDED { // Space iterator for iterating all the spaces. SpaceIterator* space_iterator_; // Object iterator for the space currently being iterated. - ObjectIterator* object_iterator_; + std::unique_ptr object_iterator_; }; // Abstract base class for checking whether a weak object should be retained. diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc index 4ca1443c7a..7c08ea0eb2 100644 --- a/src/heap/mark-compact.cc +++ b/src/heap/mark-compact.cc @@ -2266,8 +2266,9 @@ void MarkCompactCollector::VisitAllObjects(HeapObjectVisitor* visitor) { SpaceIterator space_it(heap()); HeapObject* obj = nullptr; while (space_it.has_next()) { - ObjectIterator* it = space_it.next(); - while ((obj = it->Next()) != nullptr) { + std::unique_ptr it(space_it.next()->GetObjectIterator()); + ObjectIterator* obj_it = it.get(); + while ((obj = obj_it->Next()) != nullptr) { visitor->Visit(obj); } } diff --git a/src/heap/spaces.cc b/src/heap/spaces.cc index 1879e0d44e..a274fddf45 100644 --- a/src/heap/spaces.cc +++ b/src/heap/spaces.cc @@ -1431,6 +1431,10 @@ void PagedSpace::ReleasePage(Page* page) { heap()->memory_allocator()->Free(page); } +std::unique_ptr PagedSpace::GetObjectIterator() { + return std::unique_ptr(new HeapObjectIterator(this)); +} + #ifdef DEBUG void PagedSpace::Print() {} #endif @@ -1826,6 +1830,10 @@ void NewSpace::InlineAllocationStep(Address top, Address new_top, } } +std::unique_ptr NewSpace::GetObjectIterator() { + return std::unique_ptr(new SemiSpaceIterator(this)); +} + #ifdef VERIFY_HEAP // We do not use the SemiSpaceIterator because verification doesn't assume // that it works (it depends on the invariants we are checking). @@ -2119,6 +2127,12 @@ void NewSpace::SealIntermediateGeneration() { } } +std::unique_ptr SemiSpace::GetObjectIterator() { + // Use the NewSpace::NewObjectIterator to iterate the ToSpace. + UNREACHABLE(); + return std::unique_ptr(); +} + #ifdef DEBUG void SemiSpace::Print() {} #endif @@ -3170,6 +3184,9 @@ bool LargeObjectSpace::Contains(HeapObject* object) { return owned; } +std::unique_ptr LargeObjectSpace::GetObjectIterator() { + return std::unique_ptr(new LargeObjectIterator(this)); +} #ifdef VERIFY_HEAP // We do not assume that the large object iterator works, because it depends diff --git a/src/heap/spaces.h b/src/heap/spaces.h index 5832cc6855..99dd378bbe 100644 --- a/src/heap/spaces.h +++ b/src/heap/spaces.h @@ -943,6 +943,8 @@ class Space : public Malloced { } } + virtual std::unique_ptr GetObjectIterator() = 0; + void AccountCommitted(intptr_t bytes) { DCHECK_GE(bytes, 0); committed_ += bytes; @@ -2154,6 +2156,8 @@ class PagedSpace : public Space { // using the high water mark. void ShrinkImmortalImmovablePages(); + std::unique_ptr GetObjectIterator() override; + protected: // PagedSpaces that should be included in snapshots have different, i.e., // smaller, initial pages. @@ -2329,6 +2333,11 @@ class SemiSpace : public Space { return 0; } + iterator begin() { return iterator(anchor_.next_page()); } + iterator end() { return iterator(anchor()); } + + std::unique_ptr GetObjectIterator() override; + #ifdef DEBUG void Print() override; // Validate a range of of addresses in a SemiSpace. @@ -2344,9 +2353,6 @@ class SemiSpace : public Space { virtual void Verify(); #endif - iterator begin() { return iterator(anchor_.next_page()); } - iterator end() { return iterator(anchor()); } - private: void RewindPages(Page* start, int num_pages); @@ -2648,6 +2654,8 @@ class NewSpace : public Space { iterator begin() { return to_space_.begin(); } iterator end() { return to_space_.end(); } + std::unique_ptr GetObjectIterator() override; + private: // Update allocation info to match the current to-space page. void UpdateAllocationInfo(); @@ -2863,6 +2871,8 @@ class LargeObjectSpace : public Space { iterator begin() { return iterator(first_page_); } iterator end() { return iterator(nullptr); } + std::unique_ptr GetObjectIterator() override; + #ifdef VERIFY_HEAP virtual void Verify(); #endif