Index: runtime/vm/pages.cc |
=================================================================== |
--- runtime/vm/pages.cc (revision 31654) |
+++ runtime/vm/pages.cc (working copy) |
@@ -115,7 +115,8 @@ |
prot = VirtualMemory::kReadWrite; |
} |
} |
- memory_->Protect(prot); |
+ bool status = memory_->Protect(prot); |
+ ASSERT(status); |
} |
@@ -153,7 +154,14 @@ |
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; |
@@ -219,7 +227,8 @@ |
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) && |
@@ -432,6 +441,22 @@ |
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_); |
@@ -481,6 +506,22 @@ |
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; |