[heap] Decouple SpaceIterator from ObjectIterator.

BUG=

Review-Url: https://codereview.chromium.org/2377513007
Cr-Commit-Position: refs/heads/master@{#39781}
This commit is contained in:
ulan 2016-09-27 09:23:30 -07:00 committed by Commit bot
parent 74145159af
commit 55dd687a43
6 changed files with 61 additions and 95 deletions

View File

@ -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<PagedSpace*>(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();

View File

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

View File

@ -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<ObjectIterator> object_iterator_;
};
// Abstract base class for checking whether a weak object should be retained.

View File

@ -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<ObjectIterator> it(space_it.next()->GetObjectIterator());
ObjectIterator* obj_it = it.get();
while ((obj = obj_it->Next()) != nullptr) {
visitor->Visit(obj);
}
}

View File

@ -1431,6 +1431,10 @@ void PagedSpace::ReleasePage(Page* page) {
heap()->memory_allocator()->Free<MemoryAllocator::kPreFreeAndQueue>(page);
}
std::unique_ptr<ObjectIterator> PagedSpace::GetObjectIterator() {
return std::unique_ptr<ObjectIterator>(new HeapObjectIterator(this));
}
#ifdef DEBUG
void PagedSpace::Print() {}
#endif
@ -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
// 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<ObjectIterator> SemiSpace::GetObjectIterator() {
// Use the NewSpace::NewObjectIterator to iterate the ToSpace.
UNREACHABLE();
return std::unique_ptr<ObjectIterator>();
}
#ifdef DEBUG
void SemiSpace::Print() {}
#endif
@ -3170,6 +3184,9 @@ bool LargeObjectSpace::Contains(HeapObject* object) {
return owned;
}
std::unique_ptr<ObjectIterator> LargeObjectSpace::GetObjectIterator() {
return std::unique_ptr<ObjectIterator>(new LargeObjectIterator(this));
}
#ifdef VERIFY_HEAP
// We do not assume that the large object iterator works, because it depends

View File

@ -943,6 +943,8 @@ class Space : public Malloced {
}
}
virtual std::unique_ptr<ObjectIterator> 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<ObjectIterator> 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<ObjectIterator> 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<ObjectIterator> 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<ObjectIterator> GetObjectIterator() override;
#ifdef VERIFY_HEAP
virtual void Verify();
#endif