Chromium Code Reviews| Index: vm/pages.cc |
| =================================================================== |
| --- vm/pages.cc (revision 14048) |
| +++ vm/pages.cc (working copy) |
| @@ -23,22 +23,24 @@ |
| DEFINE_FLAG(bool, print_free_list_after_gc, false, |
| "Print free list statistics after a GC"); |
| -HeapPage* HeapPage::Initialize(VirtualMemory* memory, bool is_executable) { |
| +HeapPage* HeapPage::Initialize(VirtualMemory* memory, PageType type) { |
| ASSERT(memory->size() > VirtualMemory::PageSize()); |
| + bool is_executable = (type == kExecutable); |
| memory->Commit(is_executable); |
| HeapPage* result = reinterpret_cast<HeapPage*>(memory->address()); |
| result->memory_ = memory; |
| result->next_ = NULL; |
| result->used_ = 0; |
| + result->executable_ = is_executable; |
| return result; |
| } |
| -HeapPage* HeapPage::Allocate(intptr_t size, bool is_executable) { |
| +HeapPage* HeapPage::Allocate(intptr_t size, PageType type) { |
| VirtualMemory* memory = |
| VirtualMemory::ReserveAligned(size, PageSpace::kPageAlignment); |
| - return Initialize(memory, is_executable); |
| + return Initialize(memory, type); |
| } |
| @@ -87,12 +89,25 @@ |
| void HeapPage::WriteProtect(bool read_only) { |
| - memory_->Protect( |
| - read_only ? VirtualMemory::kReadOnly : VirtualMemory::kReadWrite); |
| + VirtualMemory::Protection prot; |
| + if (read_only) { |
| + if (executable_) { |
| + prot = VirtualMemory::kReadExecute; |
| + } else { |
| + prot = VirtualMemory::kReadOnly; |
| + } |
| + } else { |
| + if (executable_) { |
| + prot = VirtualMemory::kReadWriteExecute; |
| + } else { |
| + prot = VirtualMemory::kReadWrite; |
| + } |
| + } |
| + memory_->Protect(prot); |
| } |
| -PageSpace::PageSpace(Heap* heap, intptr_t max_capacity, bool is_executable) |
| +PageSpace::PageSpace(Heap* heap, intptr_t max_capacity) |
| : freelist_(), |
| heap_(heap), |
| pages_(NULL), |
| @@ -102,7 +117,6 @@ |
| capacity_(0), |
| in_use_(0), |
| count_(0), |
| - is_executable_(is_executable), |
| sweeping_(false), |
| page_space_controller_(FLAG_heap_growth_space_ratio, |
| FLAG_heap_growth_rate, |
| @@ -123,8 +137,8 @@ |
| } |
| -HeapPage* PageSpace::AllocatePage() { |
| - HeapPage* page = HeapPage::Allocate(kPageSize, is_executable_); |
| +HeapPage* PageSpace::AllocatePage(HeapPage::PageType type) { |
| + HeapPage* page = HeapPage::Allocate(kPageSize, type); |
| if (pages_ == NULL) { |
| pages_ = page; |
| } else { |
| @@ -137,9 +151,9 @@ |
| } |
| -HeapPage* PageSpace::AllocateLargePage(intptr_t size) { |
| +HeapPage* PageSpace::AllocateLargePage(intptr_t size, HeapPage::PageType type) { |
| intptr_t page_size = LargePageSizeFor(size); |
| - HeapPage* page = HeapPage::Allocate(page_size, is_executable_); |
| + HeapPage* page = HeapPage::Allocate(page_size, type); |
| page->set_next(large_pages_); |
| large_pages_ = page; |
| capacity_ += page_size; |
| @@ -187,28 +201,25 @@ |
| } |
| -uword PageSpace::TryAllocate(intptr_t size) { |
| - return TryAllocate(size, kControlGrowth); |
| -} |
| - |
| - |
| -uword PageSpace::TryAllocate(intptr_t size, GrowthPolicy growth_policy) { |
| +uword PageSpace::TryAllocate(intptr_t size, |
| + HeapPage::PageType type, |
| + GrowthPolicy growth_policy) { |
| ASSERT(size >= kObjectAlignment); |
| ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
| uword result = 0; |
| if (size < kAllocatablePageSize) { |
| - result = freelist_.TryAllocate(size); |
| + result = freelist_[type].TryAllocate(size); |
| if ((result == 0) && |
| (page_space_controller_.CanGrowPageSpace(size) || |
| growth_policy == kForceGrowth) && |
| CanIncreaseCapacity(kPageSize)) { |
| - HeapPage* page = AllocatePage(); |
| + HeapPage* page = AllocatePage(type); |
| ASSERT(page != NULL); |
| // Start of the newly allocated page is the allocated object. |
| result = page->object_start(); |
| // Enqueue the remainder in the free list. |
| uword free_start = result + size; |
| - freelist_.Free(free_start, page->object_end() - free_start); |
| + freelist_[type].Free(free_start, page->object_end() - free_start); |
| } |
| } else { |
| // Large page allocation. |
| @@ -218,7 +229,7 @@ |
| return 0; |
| } |
| if (CanIncreaseCapacity(page_size)) { |
| - HeapPage* page = AllocateLargePage(size); |
| + HeapPage* page = AllocateLargePage(size, type); |
| if (page != NULL) { |
| result = page->object_start(); |
| } |
| @@ -252,6 +263,26 @@ |
| } |
| +bool PageSpace::Contains(uword addr, HeapPage::PageType type) const { |
| + HeapPage* page = pages_; |
| + while (page != NULL) { |
| + if ((page->type() == type) && page->Contains(addr)) { |
| + return true; |
| + } |
| + page = page->next(); |
| + } |
| + |
| + page = large_pages_; |
| + while (page != NULL) { |
| + if ((page->type() == type) && page->Contains(addr)) { |
| + return true; |
| + } |
| + page = page->next(); |
| + } |
| + return false; |
| +} |
| + |
| + |
| void PageSpace::StartEndAddress(uword* start, uword* end) const { |
| ASSERT(pages_ != NULL || large_pages_ != NULL); |
| *start = static_cast<uword>(~0); |
| @@ -364,7 +395,10 @@ |
| NoHandleScope no_handles(isolate); |
| if (FLAG_print_free_list_before_gc) { |
| - freelist_.Print(); |
| + OS::Print("Data Freelist:\n"); |
| + freelist_[HeapPage::kData].Print(); |
| + OS::Print("Executable Freelist:\n"); |
| + freelist_[HeapPage::kExecutable].Print(); |
| } |
| if (FLAG_verify_before_gc) { |
| @@ -386,15 +420,16 @@ |
| // Reset the bump allocation page to unused. |
| // Reset the freelists and setup sweeping. |
|
siva
2012/10/25 22:29:52
It is probably more generic to write this as:
for
Ivan Posva
2012/10/25 23:45:41
Yes, once we have more page types.
|
| - freelist_.Reset(); |
| + freelist_[HeapPage::kData].Reset(); |
| + freelist_[HeapPage::kExecutable].Reset(); |
| GCSweeper sweeper(heap_); |
| intptr_t in_use = 0; |
| HeapPage* prev_page = NULL; |
| HeapPage* page = pages_; |
| while (page != NULL) { |
| - intptr_t page_in_use = sweeper.SweepPage(page, &freelist_); |
| HeapPage* next_page = page->next(); |
| + intptr_t page_in_use = sweeper.SweepPage(page, &freelist_[page->type()]); |
| if (page_in_use == 0) { |
| FreePage(page, prev_page); |
| } else { |
| @@ -442,7 +477,10 @@ |
| } |
| if (FLAG_print_free_list_after_gc) { |
| - freelist_.Print(); |
| + OS::Print("Data Freelist:\n"); |
| + freelist_[HeapPage::kData].Print(); |
| + OS::Print("Executable Freelist:\n"); |
| + freelist_[HeapPage::kExecutable].Print(); |
|
siva
2012/10/25 22:29:52
Ditto comment:
It is probably more generic to writ
Ivan Posva
2012/10/25 23:45:41
ditto
|
| } |
| if (FLAG_verify_after_gc) { |