Index: src/spaces.cc |
=================================================================== |
--- src/spaces.cc (revision 5173) |
+++ src/spaces.cc (working copy) |
@@ -41,7 +41,7 @@ |
&& (info).top <= (space).high() \ |
&& (info).limit == (space).high()) |
-intptr_t Page::watermark_invalidated_mark_ = Page::WATERMARK_INVALIDATED; |
+intptr_t Page::watermark_invalidated_mark_ = 1 << Page::WATERMARK_INVALIDATED; |
// ---------------------------------------------------------------------------- |
// HeapObjectIterator |
@@ -266,6 +266,7 @@ |
// |
int MemoryAllocator::capacity_ = 0; |
int MemoryAllocator::size_ = 0; |
+int MemoryAllocator::size_executable_ = 0; |
VirtualMemory* MemoryAllocator::initial_chunk_ = NULL; |
@@ -292,6 +293,9 @@ |
} |
+#if defined(V8_REPORT_EXECUTABLE_MEMORY_USAGE) |
Søren Thygesen Gjesse
2010/08/18 08:20:01
I don't think we need this conditional compile unl
|
+void *executable_memory_histogram = NULL; |
+#endif |
bool MemoryAllocator::Setup(int capacity) { |
capacity_ = RoundUp(capacity, Page::kPageSize); |
@@ -308,6 +312,11 @@ |
if (max_nof_chunks_ > kMaxNofChunks) return false; |
size_ = 0; |
+ size_executable_ = 0; |
+#if defined(V8_REPORT_EXECUTABLE_MEMORY_USAGE) |
+ executable_memory_histogram = |
+ StatsTable::CreateHistogram("V8.ExecutableMemoryMax", 0, MB * 512, 50); |
+#endif |
ChunkInfo info; // uninitialized element. |
for (int i = max_nof_chunks_ - 1; i >= 0; i--) { |
chunks_.Add(info); |
@@ -353,6 +362,18 @@ |
} |
int alloced = static_cast<int>(*allocated); |
size_ += alloced; |
+ |
+ if (executable == EXECUTABLE) { |
+ size_executable_ += alloced; |
+#if defined(V8_REPORT_EXECUTABLE_MEMORY_USAGE) |
+ static int size_executable_max_observed_ = 0; |
+ if (size_executable_max_observed_ < size_executable_) { |
+ size_executable_max_observed_ = size_executable_; |
+ StatsTable::AddHistogramSample(executable_memory_histogram, |
+ size_executable_); |
+ } |
+#endif |
+ } |
#ifdef DEBUG |
ZapBlock(reinterpret_cast<Address>(mem), alloced); |
#endif |
@@ -361,7 +382,9 @@ |
} |
-void MemoryAllocator::FreeRawMemory(void* mem, size_t length) { |
+void MemoryAllocator::FreeRawMemory(void* mem, |
+ size_t length, |
+ Executability executable) { |
#ifdef DEBUG |
ZapBlock(reinterpret_cast<Address>(mem), length); |
#endif |
@@ -372,6 +395,7 @@ |
} |
Counters::memory_allocated.Decrement(static_cast<int>(length)); |
size_ -= static_cast<int>(length); |
+ if (executable == EXECUTABLE) size_executable_ -= length; |
ASSERT(size_ >= 0); |
} |
@@ -425,7 +449,7 @@ |
*allocated_pages = PagesInChunk(static_cast<Address>(chunk), chunk_size); |
if (*allocated_pages == 0) { |
- FreeRawMemory(chunk, chunk_size); |
+ FreeRawMemory(chunk, chunk_size, owner->executable()); |
LOG(DeleteEvent("PagedChunk", chunk)); |
return Page::FromAddress(NULL); |
} |
@@ -591,7 +615,7 @@ |
Counters::memory_allocated.Decrement(static_cast<int>(c.size())); |
} else { |
LOG(DeleteEvent("PagedChunk", c.address())); |
- FreeRawMemory(c.address(), c.size()); |
+ FreeRawMemory(c.address(), c.size(), c.owner()->executable()); |
} |
c.init(NULL, 0, NULL); |
Push(chunk_id); |
@@ -2552,7 +2576,7 @@ |
if (mem == NULL) return NULL; |
LOG(NewEvent("LargeObjectChunk", mem, *chunk_size)); |
if (*chunk_size < requested) { |
- MemoryAllocator::FreeRawMemory(mem, *chunk_size); |
+ MemoryAllocator::FreeRawMemory(mem, *chunk_size, executable); |
LOG(DeleteEvent("LargeObjectChunk", mem)); |
return NULL; |
} |
@@ -2590,7 +2614,12 @@ |
LargeObjectChunk* chunk = first_chunk_; |
first_chunk_ = first_chunk_->next(); |
LOG(DeleteEvent("LargeObjectChunk", chunk->address())); |
- MemoryAllocator::FreeRawMemory(chunk->address(), chunk->size()); |
+ Page* page = Page::FromAddress(chunk->address()); |
Søren Thygesen Gjesse
2010/08/18 09:36:27
This line should be:
Page* page = Page::FromAddre
|
+ Executability executable = |
+ page->IsPageExecutable() ? EXECUTABLE : NOT_EXECUTABLE; |
+ MemoryAllocator::FreeRawMemory(chunk->address(), |
+ chunk->size(), |
+ executable); |
} |
size_ = 0; |
@@ -2654,6 +2683,7 @@ |
// low order bit should already be clear. |
ASSERT((chunk_size & 0x1) == 0); |
page->SetIsLargeObjectPage(true); |
+ page->SetIsPageExecutable(executable); |
page->SetRegionMarks(Page::kAllRegionsCleanMarks); |
return HeapObject::FromAddress(object_address); |
} |
@@ -2768,6 +2798,10 @@ |
previous = current; |
current = current->next(); |
} else { |
+ Page* page = Page::FromAddress(RoundUp(current->address(), |
+ Page::kPageSize)); |
+ Executability executable = |
+ page->IsPageExecutable() ? EXECUTABLE : NOT_EXECUTABLE; |
Address chunk_address = current->address(); |
size_t chunk_size = current->size(); |
@@ -2783,7 +2817,7 @@ |
MarkCompactCollector::ReportDeleteIfNeeded(object); |
size_ -= static_cast<int>(chunk_size); |
page_count_--; |
- MemoryAllocator::FreeRawMemory(chunk_address, chunk_size); |
+ MemoryAllocator::FreeRawMemory(chunk_address, chunk_size, executable); |
LOG(DeleteEvent("LargeObjectChunk", chunk_address)); |
} |
} |