Commit 35720342 authored by mlippautz's avatar mlippautz Committed by Commit bot

[heap] Use PageIterator in HeapObjectIterator

BUG=chromium:581412
LOG=N
R=jochen@chromium.org

Review-Url: https://codereview.chromium.org/2094753002
Cr-Commit-Position: refs/heads/master@{#37284}
parent a1debda6
...@@ -5937,14 +5937,14 @@ HeapObject* HeapIterator::NextObject() { ...@@ -5937,14 +5937,14 @@ HeapObject* HeapIterator::NextObject() {
// No iterator means we are done. // No iterator means we are done.
if (object_iterator_ == nullptr) return nullptr; if (object_iterator_ == nullptr) return nullptr;
if (HeapObject* obj = object_iterator_->next_object()) { if (HeapObject* obj = object_iterator_->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();
if (HeapObject* obj = object_iterator_->next_object()) { if (HeapObject* obj = object_iterator_->Next()) {
return obj; return obj;
} }
} }
......
...@@ -29,7 +29,8 @@ PageIteratorImpl<PAGE_TYPE> PageIteratorImpl<PAGE_TYPE>::operator++(int) { ...@@ -29,7 +29,8 @@ PageIteratorImpl<PAGE_TYPE> PageIteratorImpl<PAGE_TYPE>::operator++(int) {
} }
NewSpacePageRange::NewSpacePageRange(Address start, Address limit) NewSpacePageRange::NewSpacePageRange(Address start, Address limit)
: start_(start), limit_(limit) { : range_(Page::FromAddress(start),
Page::FromAllocationAreaAddress(limit)->next_page()) {
SemiSpace::AssertValidRange(start, limit); SemiSpace::AssertValidRange(start, limit);
} }
...@@ -70,25 +71,17 @@ HeapObject* SemiSpaceIterator::Next() { ...@@ -70,25 +71,17 @@ HeapObject* SemiSpaceIterator::Next() {
return nullptr; return nullptr;
} }
HeapObject* SemiSpaceIterator::next_object() { return Next(); }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// HeapObjectIterator // HeapObjectIterator
HeapObject* HeapObjectIterator::Next() { HeapObject* HeapObjectIterator::Next() {
do { do {
HeapObject* next_obj = FromCurrentPage(); HeapObject* next_obj = FromCurrentPage();
if (next_obj != NULL) return next_obj; if (next_obj != nullptr) return next_obj;
} while (AdvanceToNextPage()); } while (AdvanceToNextPage());
return NULL; return nullptr;
} }
HeapObject* HeapObjectIterator::next_object() { return Next(); }
HeapObject* HeapObjectIterator::FromCurrentPage() { HeapObject* HeapObjectIterator::FromCurrentPage() {
while (cur_addr_ != cur_end_) { while (cur_addr_ != cur_end_) {
if (cur_addr_ == space_->top() && cur_addr_ != space_->limit()) { if (cur_addr_ == space_->top() && cur_addr_ != space_->limit()) {
...@@ -96,15 +89,9 @@ HeapObject* HeapObjectIterator::FromCurrentPage() { ...@@ -96,15 +89,9 @@ HeapObject* HeapObjectIterator::FromCurrentPage() {
continue; continue;
} }
HeapObject* obj = HeapObject::FromAddress(cur_addr_); HeapObject* obj = HeapObject::FromAddress(cur_addr_);
int obj_size = obj->Size(); const int obj_size = obj->Size();
cur_addr_ += obj_size; cur_addr_ += obj_size;
DCHECK(cur_addr_ <= cur_end_); DCHECK_LE(cur_addr_, cur_end_);
// TODO(hpayer): Remove the debugging code.
if (cur_addr_ > cur_end_) {
space_->heap()->isolate()->PushStackTraceAndDie(0xaaaaaaaa, obj, NULL,
obj_size);
}
if (!obj->IsFiller()) { if (!obj->IsFiller()) {
if (obj->IsCode()) { if (obj->IsCode()) {
DCHECK_EQ(space_, space_->heap()->code_space()); DCHECK_EQ(space_, space_->heap()->code_space());
...@@ -115,7 +102,7 @@ HeapObject* HeapObjectIterator::FromCurrentPage() { ...@@ -115,7 +102,7 @@ HeapObject* HeapObjectIterator::FromCurrentPage() {
return obj; return obj;
} }
} }
return NULL; return nullptr;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
......
...@@ -22,50 +22,34 @@ namespace internal { ...@@ -22,50 +22,34 @@ namespace internal {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// HeapObjectIterator // HeapObjectIterator
HeapObjectIterator::HeapObjectIterator(PagedSpace* space) { HeapObjectIterator::HeapObjectIterator(PagedSpace* space)
// You can't actually iterate over the anchor page. It is not a real page, : cur_addr_(nullptr),
// just an anchor for the double linked page list. Initialize as if we have cur_end_(nullptr),
// reached the end of the anchor page, then the first iteration will move on space_(space),
// to the first page. page_range_(space->anchor()->next_page(), space->anchor()),
Initialize(space, NULL, NULL, kAllPagesInSpace); current_page_(page_range_.begin()) {}
}
HeapObjectIterator::HeapObjectIterator(Page* page)
: cur_addr_(nullptr),
HeapObjectIterator::HeapObjectIterator(Page* page) { cur_end_(nullptr),
space_(reinterpret_cast<PagedSpace*>(page->owner())),
page_range_(page),
current_page_(page_range_.begin()) {
#ifdef DEBUG
Space* owner = page->owner(); Space* owner = page->owner();
DCHECK(owner == page->heap()->old_space() || DCHECK(owner == page->heap()->old_space() ||
owner == page->heap()->map_space() || owner == page->heap()->map_space() ||
owner == page->heap()->code_space()); owner == page->heap()->code_space());
Initialize(reinterpret_cast<PagedSpace*>(owner), page->area_start(), #endif // DEBUG
page->area_end(), kOnePageOnly);
DCHECK(page->SweepingDone());
}
void HeapObjectIterator::Initialize(PagedSpace* space, Address cur, Address end,
HeapObjectIterator::PageMode mode) {
space_ = space;
cur_addr_ = cur;
cur_end_ = end;
page_mode_ = mode;
} }
// We have hit the end of the page and should advance to the next block of // We have hit the end of the page and should advance to the next block of
// objects. This happens at the end of the page. // objects. This happens at the end of the page.
bool HeapObjectIterator::AdvanceToNextPage() { bool HeapObjectIterator::AdvanceToNextPage() {
DCHECK(cur_addr_ == cur_end_); DCHECK_EQ(cur_addr_, cur_end_);
if (page_mode_ == kOnePageOnly) return false; if (current_page_ == page_range_.end()) return false;
Page* cur_page; Page* cur_page = *(current_page_++);
if (cur_addr_ == NULL) { space_->heap()
cur_page = space_->anchor();
} else {
cur_page = Page::FromAddress(cur_addr_ - 1);
DCHECK(cur_addr_ == cur_page->area_end());
}
cur_page = cur_page->next_page();
if (cur_page == space_->anchor()) return false;
cur_page->heap()
->mark_compact_collector() ->mark_compact_collector()
->sweeper() ->sweeper()
.SweepOrWaitUntilSweepingCompleted(cur_page); .SweepOrWaitUntilSweepingCompleted(cur_page);
......
...@@ -1572,10 +1572,44 @@ class MemoryAllocator { ...@@ -1572,10 +1572,44 @@ class MemoryAllocator {
class ObjectIterator : public Malloced { class ObjectIterator : public Malloced {
public: public:
virtual ~ObjectIterator() {} virtual ~ObjectIterator() {}
virtual HeapObject* Next() = 0;
};
template <class PAGE_TYPE>
class PageIteratorImpl
: public std::iterator<std::forward_iterator_tag, PAGE_TYPE> {
public:
explicit PageIteratorImpl(PAGE_TYPE* p) : p_(p) {}
PageIteratorImpl(const PageIteratorImpl<PAGE_TYPE>& other) : p_(other.p_) {}
PAGE_TYPE* operator*() { return p_; }
bool operator==(const PageIteratorImpl<PAGE_TYPE>& rhs) {
return rhs.p_ == p_;
}
bool operator!=(const PageIteratorImpl<PAGE_TYPE>& rhs) {
return rhs.p_ != p_;
}
inline PageIteratorImpl<PAGE_TYPE>& operator++();
inline PageIteratorImpl<PAGE_TYPE> operator++(int);
virtual HeapObject* next_object() = 0; private:
PAGE_TYPE* p_;
}; };
typedef PageIteratorImpl<Page> PageIterator;
typedef PageIteratorImpl<LargePage> LargePageIterator;
class PageRange {
public:
typedef PageIterator iterator;
PageRange(Page* begin, Page* end) : begin_(begin), end_(end) {}
explicit PageRange(Page* page) : PageRange(page, page->next_page()) {}
iterator begin() { return iterator(begin_); }
iterator end() { return iterator(end_); }
private:
Page* begin_;
Page* end_;
};
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Heap object iterator in new/old/map spaces. // Heap object iterator in new/old/map spaces.
...@@ -1594,18 +1628,10 @@ class HeapObjectIterator : public ObjectIterator { ...@@ -1594,18 +1628,10 @@ class HeapObjectIterator : public ObjectIterator {
// Advance to the next object, skipping free spaces and other fillers and // Advance to the next object, skipping free spaces and other fillers and
// skipping the special garbage section of which there is one per space. // skipping the special garbage section of which there is one per space.
// Returns NULL when the iteration has ended. // Returns nullptr when the iteration has ended.
inline HeapObject* Next(); inline HeapObject* Next() override;
inline HeapObject* next_object() override;
private: private:
enum PageMode { kOnePageOnly, kAllPagesInSpace };
Address cur_addr_; // Current iteration point.
Address cur_end_; // End iteration point.
PagedSpace* space_;
PageMode page_mode_;
// Fast (inlined) path of next(). // Fast (inlined) path of next().
inline HeapObject* FromCurrentPage(); inline HeapObject* FromCurrentPage();
...@@ -1613,9 +1639,11 @@ class HeapObjectIterator : public ObjectIterator { ...@@ -1613,9 +1639,11 @@ class HeapObjectIterator : public ObjectIterator {
// iteration has ended. // iteration has ended.
bool AdvanceToNextPage(); bool AdvanceToNextPage();
// Initializes fields. Address cur_addr_; // Current iteration point.
inline void Initialize(PagedSpace* owner, Address start, Address end, Address cur_end_; // End iteration point.
PageMode mode); PagedSpace* space_;
PageRange page_range_;
PageRange::iterator current_page_;
}; };
...@@ -2067,43 +2095,15 @@ class LocalAllocationBuffer { ...@@ -2067,43 +2095,15 @@ class LocalAllocationBuffer {
AllocationInfo allocation_info_; AllocationInfo allocation_info_;
}; };
template <class PAGE_TYPE>
class PageIteratorImpl
: public std::iterator<std::forward_iterator_tag, PAGE_TYPE> {
public:
explicit PageIteratorImpl(PAGE_TYPE* p) : p_(p) {}
PageIteratorImpl(const PageIteratorImpl<PAGE_TYPE>& other) : p_(other.p_) {}
PAGE_TYPE* operator*() { return p_; }
bool operator==(const PageIteratorImpl<PAGE_TYPE>& rhs) {
return rhs.p_ == p_;
}
bool operator!=(const PageIteratorImpl<PAGE_TYPE>& rhs) {
return rhs.p_ != p_;
}
inline PageIteratorImpl<PAGE_TYPE>& operator++();
inline PageIteratorImpl<PAGE_TYPE> operator++(int);
private:
PAGE_TYPE* p_;
};
typedef PageIteratorImpl<Page> PageIterator;
typedef PageIteratorImpl<LargePage> LargePageIterator;
class NewSpacePageRange { class NewSpacePageRange {
public: public:
typedef PageIterator iterator; typedef PageRange::iterator iterator;
inline NewSpacePageRange(Address start, Address limit); inline NewSpacePageRange(Address start, Address limit);
iterator begin() { return range_.begin(); }
iterator begin() { return iterator(Page::FromAddress(start_)); } iterator end() { return range_.end(); }
iterator end() {
return iterator(Page::FromAllocationAreaAddress(limit_)->next_page());
}
private: private:
Address start_; PageRange range_;
Address limit_;
}; };
class PagedSpace : public Space { class PagedSpace : public Space {
...@@ -2598,10 +2598,7 @@ class SemiSpaceIterator : public ObjectIterator { ...@@ -2598,10 +2598,7 @@ class SemiSpaceIterator : public ObjectIterator {
// Create an iterator over the allocated objects in the given to-space. // Create an iterator over the allocated objects in the given to-space.
explicit SemiSpaceIterator(NewSpace* space); explicit SemiSpaceIterator(NewSpace* space);
inline HeapObject* Next(); inline HeapObject* Next() override;
// Implementation of the ObjectIterator functions.
inline HeapObject* next_object() override;
private: private:
void Initialize(Address start, Address end); void Initialize(Address start, Address end);
...@@ -3123,10 +3120,7 @@ class LargeObjectIterator : public ObjectIterator { ...@@ -3123,10 +3120,7 @@ class LargeObjectIterator : public ObjectIterator {
public: public:
explicit LargeObjectIterator(LargeObjectSpace* space); explicit LargeObjectIterator(LargeObjectSpace* space);
HeapObject* Next(); HeapObject* Next() override;
// implementation of ObjectIterator.
virtual HeapObject* next_object() { return Next(); }
private: private:
LargePage* current_; LargePage* current_;
......
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