Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Side by Side Diff: runtime/vm/pages.cc

Issue 106593002: Write protect executable pages in the VM. Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/object.cc ('k') | runtime/vm/virtual_memory.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/pages.h" 5 #include "vm/pages.h"
6 6
7 #include "platform/assert.h" 7 #include "platform/assert.h"
8 #include "vm/compiler_stats.h" 8 #include "vm/compiler_stats.h"
9 #include "vm/gc_marker.h" 9 #include "vm/gc_marker.h"
10 #include "vm/gc_sweeper.h" 10 #include "vm/gc_sweeper.h"
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 } else { 104 } else {
105 prot = VirtualMemory::kReadOnly; 105 prot = VirtualMemory::kReadOnly;
106 } 106 }
107 } else { 107 } else {
108 if (executable_) { 108 if (executable_) {
109 prot = VirtualMemory::kReadWriteExecute; 109 prot = VirtualMemory::kReadWriteExecute;
110 } else { 110 } else {
111 prot = VirtualMemory::kReadWrite; 111 prot = VirtualMemory::kReadWrite;
112 } 112 }
113 } 113 }
114 memory_->Protect(prot); 114 bool status = memory_->Protect(prot);
115 ASSERT(status);
115 } 116 }
116 117
117 118
118 PageSpace::PageSpace(Heap* heap, intptr_t max_capacity_in_words) 119 PageSpace::PageSpace(Heap* heap, intptr_t max_capacity_in_words)
119 : freelist_(), 120 : freelist_(),
120 heap_(heap), 121 heap_(heap),
121 pages_(NULL), 122 pages_(NULL),
122 pages_tail_(NULL), 123 pages_tail_(NULL),
123 large_pages_(NULL), 124 large_pages_(NULL),
124 max_capacity_in_words_(max_capacity_in_words), 125 max_capacity_in_words_(max_capacity_in_words),
(...skipping 17 matching lines...) Expand all
142 VirtualMemory::PageSize()); 143 VirtualMemory::PageSize());
143 return page_size >> kWordSizeLog2; 144 return page_size >> kWordSizeLog2;
144 } 145 }
145 146
146 147
147 HeapPage* PageSpace::AllocatePage(HeapPage::PageType type) { 148 HeapPage* PageSpace::AllocatePage(HeapPage::PageType type) {
148 HeapPage* page = HeapPage::Allocate(kPageSizeInWords, type); 149 HeapPage* page = HeapPage::Allocate(kPageSizeInWords, type);
149 if (pages_ == NULL) { 150 if (pages_ == NULL) {
150 pages_ = page; 151 pages_ = page;
151 } else { 152 } else {
153 const bool is_protected = (pages_tail_->type() == HeapPage::kExecutable);
154 if (is_protected) {
155 pages_tail_->WriteProtect(false);
156 }
152 pages_tail_->set_next(page); 157 pages_tail_->set_next(page);
158 if (is_protected) {
159 pages_tail_->WriteProtect(true);
160 }
153 } 161 }
154 pages_tail_ = page; 162 pages_tail_ = page;
155 capacity_in_words_ += kPageSizeInWords; 163 capacity_in_words_ += kPageSizeInWords;
156 page->set_object_end(page->memory_->end()); 164 page->set_object_end(page->memory_->end());
157 return page; 165 return page;
158 } 166 }
159 167
160 168
161 HeapPage* PageSpace::AllocateLargePage(intptr_t size, HeapPage::PageType type) { 169 HeapPage* PageSpace::AllocateLargePage(intptr_t size, HeapPage::PageType type) {
162 intptr_t page_size_in_words = LargePageSizeInWordsFor(size); 170 intptr_t page_size_in_words = LargePageSizeInWordsFor(size);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 } 216 }
209 217
210 218
211 uword PageSpace::TryAllocate(intptr_t size, 219 uword PageSpace::TryAllocate(intptr_t size,
212 HeapPage::PageType type, 220 HeapPage::PageType type,
213 GrowthPolicy growth_policy) { 221 GrowthPolicy growth_policy) {
214 ASSERT(size >= kObjectAlignment); 222 ASSERT(size >= kObjectAlignment);
215 ASSERT(Utils::IsAligned(size, kObjectAlignment)); 223 ASSERT(Utils::IsAligned(size, kObjectAlignment));
216 uword result = 0; 224 uword result = 0;
217 if (size < kAllocatablePageSize) { 225 if (size < kAllocatablePageSize) {
218 result = freelist_[type].TryAllocate(size); 226 const bool is_protected = (type == HeapPage::kExecutable);
227 result = freelist_[type].TryAllocate(size, is_protected);
219 if ((result == 0) && 228 if ((result == 0) &&
220 (page_space_controller_.CanGrowPageSpace(size) || 229 (page_space_controller_.CanGrowPageSpace(size) ||
221 growth_policy == kForceGrowth) && 230 growth_policy == kForceGrowth) &&
222 CanIncreaseCapacityInWords(kPageSizeInWords)) { 231 CanIncreaseCapacityInWords(kPageSizeInWords)) {
223 HeapPage* page = AllocatePage(type); 232 HeapPage* page = AllocatePage(type);
224 ASSERT(page != NULL); 233 ASSERT(page != NULL);
225 // Start of the newly allocated page is the allocated object. 234 // Start of the newly allocated page is the allocated object.
226 result = page->object_start(); 235 result = page->object_start();
227 // Enqueue the remainder in the free list. 236 // Enqueue the remainder in the free list.
228 uword free_start = result + size; 237 uword free_start = result + size;
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 } 430 }
422 431
423 if (FLAG_verify_before_gc) { 432 if (FLAG_verify_before_gc) {
424 OS::PrintErr("Verifying before MarkSweep..."); 433 OS::PrintErr("Verifying before MarkSweep...");
425 heap_->Verify(); 434 heap_->Verify();
426 OS::PrintErr(" done.\n"); 435 OS::PrintErr(" done.\n");
427 } 436 }
428 437
429 const int64_t start = OS::GetCurrentTimeMicros(); 438 const int64_t start = OS::GetCurrentTimeMicros();
430 439
440 // Make code pages writable.
441 HeapPage* current_page = pages_;
442 while (current_page != NULL) {
443 if (current_page->type() == HeapPage::kExecutable) {
444 current_page->WriteProtect(false);
445 }
446 current_page = current_page->next();
447 }
448 current_page = large_pages_;
449 while (current_page != NULL) {
450 if (current_page->type() == HeapPage::kExecutable) {
451 current_page->WriteProtect(false);
452 }
453 current_page = current_page->next();
454 }
455
431 // Mark all reachable old-gen objects. 456 // Mark all reachable old-gen objects.
432 bool collect_code = FLAG_collect_code && ShouldCollectCode(); 457 bool collect_code = FLAG_collect_code && ShouldCollectCode();
433 GCMarker marker(heap_); 458 GCMarker marker(heap_);
434 marker.MarkObjects(isolate, this, invoke_api_callbacks, collect_code); 459 marker.MarkObjects(isolate, this, invoke_api_callbacks, collect_code);
435 460
436 int64_t mid1 = OS::GetCurrentTimeMicros(); 461 int64_t mid1 = OS::GetCurrentTimeMicros();
437 462
438 // Reset the bump allocation page to unused. 463 // Reset the bump allocation page to unused.
439 // Reset the freelists and setup sweeping. 464 // Reset the freelists and setup sweeping.
440 freelist_[HeapPage::kData].Reset(); 465 freelist_[HeapPage::kData].Reset();
(...skipping 29 matching lines...) Expand all
470 if (page_in_use == 0) { 495 if (page_in_use == 0) {
471 FreeLargePage(page, prev_page); 496 FreeLargePage(page, prev_page);
472 } else { 497 } else {
473 used_in_words += (page_in_use >> kWordSizeLog2); 498 used_in_words += (page_in_use >> kWordSizeLog2);
474 prev_page = page; 499 prev_page = page;
475 } 500 }
476 // Advance to the next page. 501 // Advance to the next page.
477 page = next_page; 502 page = next_page;
478 } 503 }
479 504
505 // Make code pages read-only.
506 current_page = pages_;
507 while (current_page != NULL) {
508 if (current_page->type() == HeapPage::kExecutable) {
509 current_page->WriteProtect(true);
510 }
511 current_page = current_page->next();
512 }
513 current_page = large_pages_;
514 while (current_page != NULL) {
515 if (current_page->type() == HeapPage::kExecutable) {
516 current_page->WriteProtect(true);
517 }
518 current_page = current_page->next();
519 }
520
480 // Record data and print if requested. 521 // Record data and print if requested.
481 intptr_t used_before_in_words = used_in_words_; 522 intptr_t used_before_in_words = used_in_words_;
482 used_in_words_ = used_in_words; 523 used_in_words_ = used_in_words;
483 524
484 int64_t end = OS::GetCurrentTimeMicros(); 525 int64_t end = OS::GetCurrentTimeMicros();
485 526
486 // Record signals for growth control. 527 // Record signals for growth control.
487 page_space_controller_.EvaluateGarbageCollection(used_before_in_words, 528 page_space_controller_.EvaluateGarbageCollection(used_before_in_words,
488 used_in_words, 529 used_in_words,
489 start, end); 530 start, end);
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 return 0; 663 return 0;
623 } else { 664 } else {
624 ASSERT(total_time >= gc_time); 665 ASSERT(total_time >= gc_time);
625 int result= static_cast<int>((static_cast<double>(gc_time) / 666 int result= static_cast<int>((static_cast<double>(gc_time) /
626 static_cast<double>(total_time)) * 100); 667 static_cast<double>(total_time)) * 100);
627 return result; 668 return result;
628 } 669 }
629 } 670 }
630 671
631 } // namespace dart 672 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.cc ('k') | runtime/vm/virtual_memory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698