Commit 55dd687a authored by ulan's avatar ulan Committed by Commit bot

[heap] Decouple SpaceIterator from ObjectIterator.

BUG=

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