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

Unified Diff: src/spaces.cc

Issue 9535013: Merge r10809 from the bleeding_edge to the 3.8 branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/3.8/
Patch Set: Created 8 years, 10 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/spaces.h ('k') | src/spaces-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/spaces.cc
===================================================================
--- src/spaces.cc (revision 10877)
+++ src/spaces.cc (working copy)
@@ -75,8 +75,8 @@
owner == HEAP->cell_space() ||
owner == HEAP->code_space());
Initialize(reinterpret_cast<PagedSpace*>(owner),
- page->ObjectAreaStart(),
- page->ObjectAreaEnd(),
+ page->area_start(),
+ page->area_end(),
kOnePageOnly,
size_func);
ASSERT(page->WasSweptPrecisely());
@@ -108,12 +108,12 @@
cur_page = space_->anchor();
} else {
cur_page = Page::FromAddress(cur_addr_ - 1);
- ASSERT(cur_addr_ == cur_page->ObjectAreaEnd());
+ ASSERT(cur_addr_ == cur_page->area_end());
}
cur_page = cur_page->next_page();
if (cur_page == space_->anchor()) return false;
- cur_addr_ = cur_page->ObjectAreaStart();
- cur_end_ = cur_page->ObjectAreaEnd();
+ cur_addr_ = cur_page->area_start();
+ cur_end_ = cur_page->area_end();
ASSERT(cur_page->WasSweptPrecisely());
return true;
}
@@ -227,7 +227,9 @@
}
ASSERT(*allocated <= current.size);
ASSERT(IsAddressAligned(current.start, MemoryChunk::kAlignment));
- if (!code_range_->Commit(current.start, *allocated, true)) {
+ if (!MemoryAllocator::CommitCodePage(code_range_,
+ current.start,
+ *allocated)) {
*allocated = 0;
return NULL;
}
@@ -358,11 +360,17 @@
VirtualMemory reservation;
Address base = ReserveAlignedMemory(size, alignment, &reservation);
if (base == NULL) return NULL;
- if (!reservation.Commit(base,
- size,
- executable == EXECUTABLE)) {
- return NULL;
+
+ if (executable == EXECUTABLE) {
+ CommitCodePage(&reservation, base, size);
+ } else {
+ if (!reservation.Commit(base,
+ size,
+ executable == EXECUTABLE)) {
+ return NULL;
+ }
}
+
controller->TakeControl(&reservation);
return base;
}
@@ -378,9 +386,14 @@
NewSpacePage* NewSpacePage::Initialize(Heap* heap,
Address start,
SemiSpace* semi_space) {
+ Address area_start = start + NewSpacePage::kObjectStartOffset;
+ Address area_end = start + Page::kPageSize;
+
MemoryChunk* chunk = MemoryChunk::Initialize(heap,
start,
Page::kPageSize,
+ area_start,
+ area_end,
NOT_EXECUTABLE,
semi_space);
chunk->set_next_chunk(NULL);
@@ -410,6 +423,8 @@
MemoryChunk* MemoryChunk::Initialize(Heap* heap,
Address base,
size_t size,
+ Address area_start,
+ Address area_end,
Executability executable,
Space* owner) {
MemoryChunk* chunk = FromAddress(base);
@@ -418,6 +433,8 @@
chunk->heap_ = heap;
chunk->size_ = size;
+ chunk->area_start_ = area_start;
+ chunk->area_end_ = area_end;
chunk->flags_ = 0;
chunk->set_owner(owner);
chunk->InitializeReservedMemory();
@@ -431,9 +448,13 @@
ASSERT(OFFSET_OF(MemoryChunk, flags_) == kFlagsOffset);
ASSERT(OFFSET_OF(MemoryChunk, live_byte_count_) == kLiveBytesOffset);
- if (executable == EXECUTABLE) chunk->SetFlag(IS_EXECUTABLE);
+ if (executable == EXECUTABLE) {
+ chunk->SetFlag(IS_EXECUTABLE);
+ }
- if (owner == heap->old_data_space()) chunk->SetFlag(CONTAINS_ONLY_DATA);
+ if (owner == heap->old_data_space()) {
+ chunk->SetFlag(CONTAINS_ONLY_DATA);
+ }
return chunk;
}
@@ -462,11 +483,16 @@
MemoryChunk* MemoryAllocator::AllocateChunk(intptr_t body_size,
Executability executable,
Space* owner) {
- size_t chunk_size = MemoryChunk::kObjectStartOffset + body_size;
+ size_t chunk_size;
Heap* heap = isolate_->heap();
Address base = NULL;
VirtualMemory reservation;
+ Address area_start = NULL;
+ Address area_end = NULL;
if (executable == EXECUTABLE) {
+ chunk_size = RoundUp(CodePageAreaStartOffset() + body_size,
+ OS::CommitPageSize()) + CodePageGuardSize();
+
// Check executable memory limit.
if (size_executable_ + chunk_size > capacity_executable_) {
LOG(isolate_,
@@ -494,18 +520,30 @@
// Update executable memory size.
size_executable_ += reservation.size();
}
+
+#ifdef DEBUG
+ ZapBlock(base, CodePageGuardStartOffset());
+ ZapBlock(base + CodePageAreaStartOffset(), body_size);
+#endif
+ area_start = base + CodePageAreaStartOffset();
+ area_end = area_start + body_size;
} else {
+ chunk_size = MemoryChunk::kObjectStartOffset + body_size;
base = AllocateAlignedMemory(chunk_size,
MemoryChunk::kAlignment,
executable,
&reservation);
if (base == NULL) return NULL;
- }
#ifdef DEBUG
- ZapBlock(base, chunk_size);
+ ZapBlock(base, chunk_size);
#endif
+
+ area_start = base + Page::kObjectStartOffset;
+ area_end = base + chunk_size;
+ }
+
isolate_->counters()->memory_allocated()->
Increment(static_cast<int>(chunk_size));
@@ -518,6 +556,8 @@
MemoryChunk* result = MemoryChunk::Initialize(heap,
base,
chunk_size,
+ area_start,
+ area_end,
executable,
owner);
result->set_reserved_memory(&reservation);
@@ -527,7 +567,9 @@
Page* MemoryAllocator::AllocatePage(PagedSpace* owner,
Executability executable) {
- MemoryChunk* chunk = AllocateChunk(Page::kObjectAreaSize, executable, owner);
+ MemoryChunk* chunk = AllocateChunk(owner->AreaSize(),
+ executable,
+ owner);
if (chunk == NULL) return NULL;
@@ -648,6 +690,65 @@
}
#endif
+
+int MemoryAllocator::CodePageGuardStartOffset() {
+ // We are guarding code pages: the first OS page after the header
+ // will be protected as non-writable.
+ return RoundUp(Page::kObjectStartOffset, OS::CommitPageSize());
+}
+
+
+int MemoryAllocator::CodePageGuardSize() {
+ return OS::CommitPageSize();
+}
+
+
+int MemoryAllocator::CodePageAreaStartOffset() {
+ // We are guarding code pages: the first OS page after the header
+ // will be protected as non-writable.
+ return CodePageGuardStartOffset() + CodePageGuardSize();
+}
+
+
+int MemoryAllocator::CodePageAreaEndOffset() {
+ // We are guarding code pages: the last OS page will be protected as
+ // non-writable.
+ return Page::kPageSize - OS::CommitPageSize();
+}
+
+
+bool MemoryAllocator::CommitCodePage(VirtualMemory* vm,
+ Address start,
+ size_t size) {
+ // Commit page header (not executable).
+ if (!vm->Commit(start,
+ CodePageGuardStartOffset(),
+ false)) {
+ return false;
+ }
+
+ // Create guard page after the header.
+ if (!vm->Guard(start + CodePageGuardStartOffset())) {
+ return false;
+ }
+
+ // Commit page body (executable).
+ size_t area_size = size - CodePageAreaStartOffset() - CodePageGuardSize();
+ if (!vm->Commit(start + CodePageAreaStartOffset(),
+ area_size,
+ true)) {
+ return false;
+ }
+
+ // Create guard page after the allocatable area.
+ if (!vm->Guard(start + CodePageAreaStartOffset() + area_size)) {
+ return false;
+ }
+
+ return true;
+}
+
+
// -----------------------------------------------------------------------------
// MemoryChunk implementation
@@ -671,8 +772,14 @@
was_swept_conservatively_(false),
first_unswept_page_(Page::FromAddress(NULL)),
unswept_free_bytes_(0) {
+ if (id == CODE_SPACE) {
+ area_size_ = heap->isolate()->memory_allocator()->
+ CodePageAreaSize();
+ } else {
+ area_size_ = Page::kPageSize - Page::kObjectStartOffset;
+ }
max_capacity_ = (RoundDown(max_capacity, Page::kPageSize) / Page::kPageSize)
- * Page::kObjectAreaSize;
+ * AreaSize();
accounting_stats_.Clear();
allocation_info_.top = NULL;
@@ -722,8 +829,8 @@
}
bool PagedSpace::CanExpand() {
- ASSERT(max_capacity_ % Page::kObjectAreaSize == 0);
- ASSERT(Capacity() % Page::kObjectAreaSize == 0);
+ ASSERT(max_capacity_ % AreaSize() == 0);
+ ASSERT(Capacity() % AreaSize() == 0);
if (Capacity() == max_capacity_) return false;
@@ -763,6 +870,7 @@
void PagedSpace::ReleasePage(Page* page) {
ASSERT(page->LiveBytes() == 0);
+ ASSERT(AreaSize() == page->area_size());
// Adjust list of unswept pages if the page is the head of the list.
if (first_unswept_page_ == page) {
@@ -775,7 +883,7 @@
if (page->WasSwept()) {
intptr_t size = free_list_.EvictFreeListItems(page);
accounting_stats_.AllocateBytes(size);
- ASSERT_EQ(Page::kObjectAreaSize, static_cast<int>(size));
+ ASSERT_EQ(AreaSize(), static_cast<int>(size));
} else {
DecreaseUnsweptFreeBytes(page);
}
@@ -792,8 +900,8 @@
}
ASSERT(Capacity() > 0);
- ASSERT(Capacity() % Page::kObjectAreaSize == 0);
- accounting_stats_.ShrinkSpace(Page::kObjectAreaSize);
+ ASSERT(Capacity() % AreaSize() == 0);
+ accounting_stats_.ShrinkSpace(AreaSize());
}
@@ -804,9 +912,9 @@
if (!page->WasSwept()) {
if (page->LiveBytes() == 0) ReleasePage(page);
} else {
- HeapObject* obj = HeapObject::FromAddress(page->body());
+ HeapObject* obj = HeapObject::FromAddress(page->area_start());
if (obj->IsFreeSpace() &&
- FreeSpace::cast(obj)->size() == Page::kObjectAreaSize) {
+ FreeSpace::cast(obj)->size() == AreaSize()) {
// Sometimes we allocate memory from free list but don't
// immediately initialize it (e.g. see PagedSpace::ReserveSpace
// called from Heap::ReserveSpace that can cause GC before
@@ -817,7 +925,7 @@
// by free list items.
FreeList::SizeStats sizes;
free_list_.CountFreeListItems(page, &sizes);
- if (sizes.Total() == Page::kObjectAreaSize) {
+ if (sizes.Total() == AreaSize()) {
ReleasePage(page);
}
}
@@ -848,8 +956,8 @@
}
ASSERT(page->WasSweptPrecisely());
HeapObjectIterator it(page, NULL);
- Address end_of_previous_object = page->ObjectAreaStart();
- Address top = page->ObjectAreaEnd();
+ Address end_of_previous_object = page->area_start();
+ Address top = page->area_end();
int black_size = 0;
for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) {
ASSERT(end_of_previous_object <= object->address());
@@ -1061,7 +1169,7 @@
}
// Clear remainder of current page.
- Address limit = NewSpacePage::FromLimit(top)->body_limit();
+ Address limit = NewSpacePage::FromLimit(top)->area_end();
if (heap()->gc_state() == Heap::SCAVENGE) {
heap()->promotion_queue()->SetNewLimit(limit);
heap()->promotion_queue()->ActivateGuardIfOnTheSamePage();
@@ -1111,7 +1219,7 @@
// There should be objects packed in from the low address up to the
// allocation pointer.
- Address current = to_space_.first_page()->body();
+ Address current = to_space_.first_page()->area_start();
CHECK_EQ(current, to_space_.space_start());
while (current != top()) {
@@ -1146,7 +1254,7 @@
NewSpacePage* page = NewSpacePage::FromLimit(current)->next_page();
// Next page should be valid.
CHECK(!page->is_anchor());
- current = page->body();
+ current = page->area_start();
}
}
@@ -1932,7 +2040,7 @@
void FreeList::CountFreeListItems(Page* p, SizeStats* sizes) {
sizes->huge_size_ = CountFreeListItemsInList(huge_list_, p);
- if (sizes->huge_size_ < Page::kObjectAreaSize) {
+ if (sizes->huge_size_ < p->area_size()) {
sizes->small_size_ = CountFreeListItemsInList(small_list_, p);
sizes->medium_size_ = CountFreeListItemsInList(medium_list_, p);
sizes->large_size_ = CountFreeListItemsInList(large_list_, p);
@@ -1962,7 +2070,7 @@
intptr_t FreeList::EvictFreeListItems(Page* p) {
intptr_t sum = EvictFreeListItemsInList(&huge_list_, p);
- if (sum < Page::kObjectAreaSize) {
+ if (sum < p->area_size()) {
sum += EvictFreeListItemsInList(&small_list_, p) +
EvictFreeListItemsInList(&medium_list_, p) +
EvictFreeListItemsInList(&large_list_, p);
@@ -2084,7 +2192,7 @@
bool PagedSpace::ReserveSpace(int size_in_bytes) {
- ASSERT(size_in_bytes <= Page::kMaxHeapObjectSize);
+ ASSERT(size_in_bytes <= AreaSize());
ASSERT(size_in_bytes == RoundSizeDownToObjectAlignment(size_in_bytes));
Address current_top = allocation_info_.top;
Address new_top = current_top + size_in_bytes;
@@ -2464,7 +2572,7 @@
LargePage* page = heap()->isolate()->memory_allocator()->
AllocateLargePage(object_size, executable, this);
if (page == NULL) return Failure::RetryAfterGC(identity());
- ASSERT(page->body_size() >= object_size);
+ ASSERT(page->area_size() >= object_size);
size_ += static_cast<int>(page->size());
objects_size_ += object_size;
@@ -2580,7 +2688,7 @@
// object area start.
HeapObject* object = chunk->GetObject();
Page* page = Page::FromAddress(object->address());
- ASSERT(object->address() == page->ObjectAreaStart());
+ ASSERT(object->address() == page->area_start());
// The first word should be a map, and we expect all map pointers to be
// in map space.
« no previous file with comments | « src/spaces.h ('k') | src/spaces-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698