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