| Index: runtime/vm/pages.cc
|
| diff --git a/runtime/vm/pages.cc b/runtime/vm/pages.cc
|
| index be05e9781aeae7e7e87cac7bc8e3a71eb30f778a..b6cc61fe162eb2ede2b00e8c4aba1b960d75e00e 100644
|
| --- a/runtime/vm/pages.cc
|
| +++ b/runtime/vm/pages.cc
|
| @@ -111,7 +111,8 @@ void HeapPage::WriteProtect(bool read_only) {
|
| prot = VirtualMemory::kReadWrite;
|
| }
|
| }
|
| - memory_->Protect(prot);
|
| + bool status = memory_->Protect(prot);
|
| + ASSERT(status);
|
| }
|
|
|
|
|
| @@ -149,7 +150,14 @@ HeapPage* PageSpace::AllocatePage(HeapPage::PageType type) {
|
| if (pages_ == NULL) {
|
| pages_ = page;
|
| } else {
|
| + const bool is_protected = (pages_tail_->type() == HeapPage::kExecutable);
|
| + if (is_protected) {
|
| + pages_tail_->WriteProtect(false);
|
| + }
|
| pages_tail_->set_next(page);
|
| + if (is_protected) {
|
| + pages_tail_->WriteProtect(true);
|
| + }
|
| }
|
| pages_tail_ = page;
|
| capacity_in_words_ += kPageSizeInWords;
|
| @@ -215,7 +223,8 @@ uword PageSpace::TryAllocate(intptr_t size,
|
| ASSERT(Utils::IsAligned(size, kObjectAlignment));
|
| uword result = 0;
|
| if (size < kAllocatablePageSize) {
|
| - result = freelist_[type].TryAllocate(size);
|
| + const bool is_protected = (type == HeapPage::kExecutable);
|
| + result = freelist_[type].TryAllocate(size, is_protected);
|
| if ((result == 0) &&
|
| (page_space_controller_.CanGrowPageSpace(size) ||
|
| growth_policy == kForceGrowth) &&
|
| @@ -428,6 +437,22 @@ void PageSpace::MarkSweep(bool invoke_api_callbacks) {
|
|
|
| const int64_t start = OS::GetCurrentTimeMicros();
|
|
|
| + // Make code pages writable.
|
| + HeapPage* current_page = pages_;
|
| + while (current_page != NULL) {
|
| + if (current_page->type() == HeapPage::kExecutable) {
|
| + current_page->WriteProtect(false);
|
| + }
|
| + current_page = current_page->next();
|
| + }
|
| + current_page = large_pages_;
|
| + while (current_page != NULL) {
|
| + if (current_page->type() == HeapPage::kExecutable) {
|
| + current_page->WriteProtect(false);
|
| + }
|
| + current_page = current_page->next();
|
| + }
|
| +
|
| // Mark all reachable old-gen objects.
|
| bool collect_code = FLAG_collect_code && ShouldCollectCode();
|
| GCMarker marker(heap_);
|
| @@ -477,6 +502,22 @@ void PageSpace::MarkSweep(bool invoke_api_callbacks) {
|
| page = next_page;
|
| }
|
|
|
| + // Make code pages read-only.
|
| + current_page = pages_;
|
| + while (current_page != NULL) {
|
| + if (current_page->type() == HeapPage::kExecutable) {
|
| + current_page->WriteProtect(true);
|
| + }
|
| + current_page = current_page->next();
|
| + }
|
| + current_page = large_pages_;
|
| + while (current_page != NULL) {
|
| + if (current_page->type() == HeapPage::kExecutable) {
|
| + current_page->WriteProtect(true);
|
| + }
|
| + current_page = current_page->next();
|
| + }
|
| +
|
| // Record data and print if requested.
|
| intptr_t used_before_in_words = used_in_words_;
|
| used_in_words_ = used_in_words;
|
|
|