[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:
parent
74145159af
commit
55dd687a43
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user