Chromium Code Reviews| Index: runtime/vm/pages.cc |
| diff --git a/runtime/vm/pages.cc b/runtime/vm/pages.cc |
| index 30d98628a26d55652ca41d7d88999b00dc19272f..277835b1a0057556cbd1a18e35edfcf224f509cf 100644 |
| --- a/runtime/vm/pages.cc |
| +++ b/runtime/vm/pages.cc |
| @@ -415,7 +415,7 @@ void PageSpace::FreeExternal(intptr_t size) { |
| } |
| -// Provides exclusive access to the pages, and ensures they are walkable. |
| +// Provides exclusive access to all pages, and ensures they are walkable. |
| class ExclusivePageIterator : ValueObject { |
| public: |
| explicit ExclusivePageIterator(const PageSpace* space) |
| @@ -443,6 +443,50 @@ class ExclusivePageIterator : ValueObject { |
| }; |
| +// Provides exclusive access to code pages, and ensures they are walkable. |
|
Ivan Posva
2015/01/07 21:35:04
Please make a note in the comment that this iterat
Cutch
2015/01/07 21:38:03
Done.
|
| +class ExclusiveCodePageIterator : ValueObject { |
| + public: |
| + explicit ExclusiveCodePageIterator(const PageSpace* space) |
| + : space_(space), ml_(space->pages_lock_) { |
| + space_->MakeIterable(); |
| + page_ = space_->exec_pages_; |
| + } |
| + HeapPage* page() const { return page_; } |
| + bool Done() const { return page_ == NULL; } |
| + void Advance() { |
| + ASSERT(!Done()); |
| + page_ = page_->next(); |
| + } |
| + private: |
| + const PageSpace* space_; |
| + MutexLocker ml_; |
| + NoGCScope no_gc; |
| + HeapPage* page_; |
| +}; |
| + |
| + |
| +// Provides exclusive access to large pages, and ensures they are walkable. |
| +class ExclusiveLargePageIterator : ValueObject { |
| + public: |
| + explicit ExclusiveLargePageIterator(const PageSpace* space) |
| + : space_(space), ml_(space->pages_lock_) { |
| + space_->MakeIterable(); |
| + page_ = space_->large_pages_; |
| + } |
| + HeapPage* page() const { return page_; } |
| + bool Done() const { return page_ == NULL; } |
| + void Advance() { |
| + ASSERT(!Done()); |
| + page_ = page_->next(); |
| + } |
| + private: |
| + const PageSpace* space_; |
| + MutexLocker ml_; |
| + NoGCScope no_gc; |
| + HeapPage* page_; |
| +}; |
| + |
| + |
| void PageSpace::MakeIterable() const { |
| // TODO(koda): Assert not called from concurrent sweeper task. |
| if (bump_top_ < bump_end_) { |
| @@ -462,6 +506,21 @@ bool PageSpace::Contains(uword addr) const { |
| bool PageSpace::Contains(uword addr, HeapPage::PageType type) const { |
| + if (type == HeapPage::kExecutable) { |
| + // Fast path executable pages. |
| + for (ExclusiveCodePageIterator it(this); !it.Done(); it.Advance()) { |
| + if (it.page()->Contains(addr)) { |
| + return true; |
| + } |
| + } |
| + // Large pages can be executable, walk them too. |
| + for (ExclusiveLargePageIterator it(this); !it.Done(); it.Advance()) { |
| + if ((it.page()->type() == type) && it.page()->Contains(addr)) { |
| + return true; |
| + } |
| + } |
| + return false; |
| + } |
| for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) { |
| if ((it.page()->type() == type) && it.page()->Contains(addr)) { |
| return true; |
| @@ -500,6 +559,26 @@ void PageSpace::VisitObjectPointers(ObjectPointerVisitor* visitor) const { |
| RawObject* PageSpace::FindObject(FindObjectVisitor* visitor, |
| HeapPage::PageType type) const { |
| + if (type == HeapPage::kExecutable) { |
| + // Fast path executable pages. |
| + for (ExclusiveCodePageIterator it(this); !it.Done(); it.Advance()) { |
| + RawObject* obj = it.page()->FindObject(visitor); |
| + if (obj != Object::null()) { |
| + return obj; |
| + } |
| + } |
| + // Large pages can be executable, walk them too. |
| + for (ExclusiveLargePageIterator it(this); !it.Done(); it.Advance()) { |
| + if (it.page()->type() == type) { |
| + RawObject* obj = it.page()->FindObject(visitor); |
| + if (obj != Object::null()) { |
| + return obj; |
| + } |
| + } |
| + } |
| + return Object::null(); |
| + } |
| + |
| for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) { |
| if (it.page()->type() == type) { |
| RawObject* obj = it.page()->FindObject(visitor); |