Chromium Code Reviews| Index: src/spaces.cc |
| =================================================================== |
| --- src/spaces.cc (revision 13384) |
| +++ src/spaces.cc (working copy) |
| @@ -207,9 +207,10 @@ |
| } |
| - |
| Address CodeRange::AllocateRawMemory(const size_t requested, |
| - size_t* allocated) { |
| + size_t* allocated, |
| + size_t commit_body_size) { |
| + ASSERT(commit_body_size <= requested); |
| ASSERT(current_allocation_block_index_ < allocation_list_.length()); |
| if (requested > allocation_list_[current_allocation_block_index_].size) { |
| // Find an allocation block large enough. This function call may |
| @@ -229,7 +230,8 @@ |
| ASSERT(IsAddressAligned(current.start, MemoryChunk::kAlignment)); |
| if (!MemoryAllocator::CommitCodePage(code_range_, |
| current.start, |
| - *allocated)) { |
| + *allocated, |
| + commit_body_size)) { |
| *allocated = 0; |
| return NULL; |
| } |
| @@ -242,6 +244,13 @@ |
| } |
| +bool CodeRange::CommitRawMemory(Address start, size_t length) { |
| + // Commit page body (executable). |
| + if (!code_range_->Commit(start, length, true)) return false; |
|
danno
2013/01/17 10:49:55
how about just:
return code_range_->Commit(start,
haitao.feng
2013/01/17 14:20:33
Done.
|
| + return true; |
| +} |
| + |
| + |
| void CodeRange::FreeRawMemory(Address address, size_t length) { |
| ASSERT(IsAddressAligned(address, MemoryChunk::kAlignment)); |
| free_list_.Add(FreeBlock(address, length)); |
| @@ -346,8 +355,7 @@ |
| if (!reservation.IsReserved()) return NULL; |
| size_ += reservation.size(); |
| - Address base = RoundUp(static_cast<Address>(reservation.address()), |
| - alignment); |
| + Address base = static_cast<Address>(reservation.address()); |
| controller->TakeControl(&reservation); |
| return base; |
| } |
| @@ -355,18 +363,21 @@ |
| Address MemoryAllocator::AllocateAlignedMemory(size_t size, |
|
danno
2013/01/17 10:49:55
nit: "requested_size" is a better name
haitao.feng
2013/01/17 14:20:33
Done.
|
| size_t alignment, |
| + size_t commit_body_size, |
|
danno
2013/01/17 10:49:55
nit: "commit_size" is a better name
nit: could you
haitao.feng
2013/01/17 14:20:33
Done.
haitao.feng
2013/01/17 14:20:33
Done.
|
| Executability executable, |
| VirtualMemory* controller) { |
| + ASSERT(commit_body_size <= size); |
| VirtualMemory reservation; |
| Address base = ReserveAlignedMemory(size, alignment, &reservation); |
| if (base == NULL) return NULL; |
| if (executable == EXECUTABLE) { |
| - if (!CommitCodePage(&reservation, base, size)) { |
| + if (!CommitCodePage(&reservation, base, size, commit_body_size)) { |
| base = NULL; |
| } |
| } else { |
| - if (!reservation.Commit(base, size, false)) { |
| + size_t commit_size = MemoryChunk::kObjectStartOffset + commit_body_size; |
| + if (!reservation.Commit(base, commit_size, false)) { |
| base = NULL; |
| } |
| } |
| @@ -470,6 +481,31 @@ |
| } |
| +bool MemoryChunk::CommitBody(size_t body_size, Executability executable) { |
| + // Already committed, no uncommitment |
| + if (body_size <= (area_end_ - area_start_)) return true; |
|
danno
2013/01/17 10:49:55
The problem with using area_end is that you change
haitao.feng
2013/01/17 14:20:33
How about "ASSERT(body_size <= static_cast<size_t>
|
| + |
| + size_t length = body_size - (area_end_ - area_start_); |
| + if (reservation_.IsReserved()) { |
| + if (!reservation_.Commit(area_end_, length, executable == EXECUTABLE)) { |
| + return false; |
| + } |
| + } else { |
| + CodeRange* code_range = heap_->isolate()->code_range(); |
| + ASSERT(code_range->exists() && (executable == EXECUTABLE)); |
| + if (!code_range->CommitRawMemory(area_end_, length)) return false; |
| + } |
| + |
| + if (Heap::ShouldZapGarbage()) { |
| + heap_->isolate()->memory_allocator()->ZapBlock(area_end_, length); |
| + } |
| + |
| + area_end_ = area_start_ + body_size; |
| + |
| + return true; |
| +} |
| + |
| + |
| void MemoryChunk::InsertAfter(MemoryChunk* other) { |
| next_chunk_ = other->next_chunk_; |
| prev_chunk_ = other; |
| @@ -490,9 +526,12 @@ |
| } |
| -MemoryChunk* MemoryAllocator::AllocateChunk(intptr_t body_size, |
| +MemoryChunk* MemoryAllocator::AllocateChunk(intptr_t reserve_body_size, |
| + intptr_t commit_body_size, |
| Executability executable, |
| Space* owner) { |
| + ASSERT(commit_body_size <= reserve_body_size); |
| + |
| size_t chunk_size; |
| Heap* heap = isolate_->heap(); |
| Address base = NULL; |
| @@ -501,7 +540,7 @@ |
| Address area_end = NULL; |
| if (executable == EXECUTABLE) { |
| - chunk_size = RoundUp(CodePageAreaStartOffset() + body_size, |
| + chunk_size = RoundUp(CodePageAreaStartOffset() + reserve_body_size, |
| OS::CommitPageSize()) + CodePageGuardSize(); |
| // Check executable memory limit. |
| @@ -515,7 +554,9 @@ |
| // Allocate executable memory either from code range or from the |
| // OS. |
| if (isolate_->code_range()->exists()) { |
| - base = isolate_->code_range()->AllocateRawMemory(chunk_size, &chunk_size); |
| + base = isolate_->code_range()->AllocateRawMemory(chunk_size, |
| + &chunk_size, |
| + commit_body_size); |
| ASSERT(IsAligned(reinterpret_cast<intptr_t>(base), |
| MemoryChunk::kAlignment)); |
| if (base == NULL) return NULL; |
| @@ -525,6 +566,7 @@ |
| } else { |
| base = AllocateAlignedMemory(chunk_size, |
| MemoryChunk::kAlignment, |
| + commit_body_size, |
| executable, |
| &reservation); |
| if (base == NULL) return NULL; |
| @@ -534,28 +576,32 @@ |
| if (Heap::ShouldZapGarbage()) { |
| ZapBlock(base, CodePageGuardStartOffset()); |
| - ZapBlock(base + CodePageAreaStartOffset(), body_size); |
| + ZapBlock(base + CodePageAreaStartOffset(), commit_body_size); |
| } |
| area_start = base + CodePageAreaStartOffset(); |
| - area_end = area_start + body_size; |
| + area_end = area_start + commit_body_size; |
|
danno
2013/01/17 10:49:55
area_end should always be the end of the reserved
haitao.feng
2013/01/17 14:20:33
The end could be calculated by address() + size_.
|
| } else { |
| - chunk_size = MemoryChunk::kObjectStartOffset + body_size; |
| + chunk_size = MemoryChunk::kObjectStartOffset + reserve_body_size; |
| base = AllocateAlignedMemory(chunk_size, |
| MemoryChunk::kAlignment, |
| + commit_body_size, |
| executable, |
| &reservation); |
| if (base == NULL) return NULL; |
| if (Heap::ShouldZapGarbage()) { |
| - ZapBlock(base, chunk_size); |
| + ZapBlock(base, MemoryChunk::kObjectStartOffset + commit_body_size); |
| } |
| area_start = base + Page::kObjectStartOffset; |
| - area_end = base + chunk_size; |
| + area_end = area_start + commit_body_size; |
| } |
| + // Use chunk_size for statistics and callbacks as the reserved |
| + // but uncommitted memory regions are only meaningful for this allocated |
| + // memory trunk. |
|
danno
2013/01/17 10:49:55
nit: I don't know what you mean by "allocated memo
haitao.feng
2013/01/17 14:20:33
Done.
|
| isolate_->counters()->memory_allocated()-> |
| Increment(static_cast<int>(chunk_size)); |
| @@ -580,7 +626,7 @@ |
| Page* MemoryAllocator::AllocatePage(intptr_t size, |
| PagedSpace* owner, |
| Executability executable) { |
| - MemoryChunk* chunk = AllocateChunk(size, executable, owner); |
| + MemoryChunk* chunk = AllocateChunk(size, size, executable, owner); |
| if (chunk == NULL) return NULL; |
| @@ -591,7 +637,10 @@ |
| LargePage* MemoryAllocator::AllocateLargePage(intptr_t object_size, |
| Space* owner, |
| Executability executable) { |
| - MemoryChunk* chunk = AllocateChunk(object_size, executable, owner); |
| + MemoryChunk* chunk = AllocateChunk(object_size, |
| + object_size, |
| + executable, |
| + owner); |
| if (chunk == NULL) return NULL; |
| return LargePage::Initialize(isolate_->heap(), chunk); |
| } |
| @@ -735,7 +784,8 @@ |
| bool MemoryAllocator::CommitCodePage(VirtualMemory* vm, |
| Address start, |
| - size_t size) { |
| + size_t size, |
|
danno
2013/01/17 10:49:55
I think it's clearer if you swap the order of the
haitao.feng
2013/01/17 14:20:33
Done.
|
| + size_t body_size) { |
| // Commit page header (not executable). |
| if (!vm->Commit(start, |
| CodePageGuardStartOffset(), |
| @@ -749,15 +799,14 @@ |
| } |
| // Commit page body (executable). |
| - size_t area_size = size - CodePageAreaStartOffset() - CodePageGuardSize(); |
| if (!vm->Commit(start + CodePageAreaStartOffset(), |
| - area_size, |
| + body_size, |
| true)) { |
| return false; |
| } |
| - // Create guard page after the allocatable area. |
| - if (!vm->Guard(start + CodePageAreaStartOffset() + area_size)) { |
| + // Create guard page before the end. |
| + if (!vm->Guard(start + size - CodePageGuardSize())) { |
| return false; |
| } |