| Index: src/spaces.cc
|
| ===================================================================
|
| --- src/spaces.cc (revision 5397)
|
| +++ src/spaces.cc (working copy)
|
| @@ -274,6 +274,9 @@
|
| int MemoryAllocator::size_ = 0;
|
| int MemoryAllocator::size_executable_ = 0;
|
|
|
| +List<MemoryAllocator::MemoryAllocationCallbackRegistration>
|
| + MemoryAllocator::memory_allocation_callbacks_;
|
| +
|
| VirtualMemory* MemoryAllocator::initial_chunk_ = NULL;
|
|
|
| // 270 is an estimate based on the static default heap size of a pair of 256K
|
| @@ -299,8 +302,6 @@
|
| }
|
|
|
|
|
| -void *executable_memory_histogram = NULL;
|
| -
|
| bool MemoryAllocator::Setup(int capacity) {
|
| capacity_ = RoundUp(capacity, Page::kPageSize);
|
|
|
| @@ -318,8 +319,6 @@
|
|
|
| size_ = 0;
|
| size_executable_ = 0;
|
| - executable_memory_histogram =
|
| - StatsTable::CreateHistogram("V8.ExecutableMemoryMax", 0, MB * 512, 50);
|
| ChunkInfo info; // uninitialized element.
|
| for (int i = max_nof_chunks_ - 1; i >= 0; i--) {
|
| chunks_.Add(info);
|
| @@ -366,15 +365,7 @@
|
| int alloced = static_cast<int>(*allocated);
|
| size_ += alloced;
|
|
|
| - if (executable == EXECUTABLE) {
|
| - size_executable_ += alloced;
|
| - 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_);
|
| - }
|
| - }
|
| + if (executable == EXECUTABLE) size_executable_ += alloced;
|
| #ifdef DEBUG
|
| ZapBlock(reinterpret_cast<Address>(mem), alloced);
|
| #endif
|
| @@ -397,10 +388,56 @@
|
| Counters::memory_allocated.Decrement(static_cast<int>(length));
|
| size_ -= static_cast<int>(length);
|
| if (executable == EXECUTABLE) size_executable_ -= static_cast<int>(length);
|
| +
|
| ASSERT(size_ >= 0);
|
| }
|
|
|
|
|
| +void MemoryAllocator::PerformAllocationCallback(ObjectSpace space,
|
| + AllocationAction action,
|
| + int size) {
|
| + for (int i = 0; i < memory_allocation_callbacks_.length(); ++i) {
|
| + MemoryAllocationCallbackRegistration registration =
|
| + memory_allocation_callbacks_[i];
|
| + if ((registration.space & space) == space &&
|
| + (registration.action & action) == action)
|
| + registration.callback(space, action, static_cast<int>(size));
|
| + }
|
| +}
|
| +
|
| +
|
| +bool MemoryAllocator::MemoryAllocationCallbackRegistered(
|
| + MemoryAllocationCallback callback) {
|
| + for (int i = 0; i < memory_allocation_callbacks_.length(); ++i) {
|
| + if (memory_allocation_callbacks_[i].callback == callback) return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +
|
| +void MemoryAllocator::AddMemoryAllocationCallback(
|
| + MemoryAllocationCallback callback,
|
| + ObjectSpace space,
|
| + AllocationAction action) {
|
| + ASSERT(callback != NULL);
|
| + MemoryAllocationCallbackRegistration registration(callback, space, action);
|
| + ASSERT(!MemoryAllocator::MemoryAllocationCallbackRegistered(callback));
|
| + return memory_allocation_callbacks_.Add(registration);
|
| +}
|
| +
|
| +
|
| +void MemoryAllocator::RemoveMemoryAllocationCallback(
|
| + MemoryAllocationCallback callback) {
|
| + ASSERT(callback != NULL);
|
| + for (int i = 0; i < memory_allocation_callbacks_.length(); ++i) {
|
| + if (memory_allocation_callbacks_[i].callback == callback) {
|
| + memory_allocation_callbacks_.Remove(i);
|
| + return;
|
| + }
|
| + }
|
| + UNREACHABLE();
|
| +}
|
| +
|
| void* MemoryAllocator::ReserveInitialChunk(const size_t requested) {
|
| ASSERT(initial_chunk_ == NULL);
|
|
|
| @@ -458,6 +495,8 @@
|
| int chunk_id = Pop();
|
| chunks_[chunk_id].init(static_cast<Address>(chunk), chunk_size, owner);
|
|
|
| + ObjectSpace space = static_cast<ObjectSpace>(1 << owner->identity());
|
| + PerformAllocationCallback(space, kAllocationActionAllocate, chunk_size);
|
| return InitializePagesInChunk(chunk_id, *allocated_pages, owner);
|
| }
|
|
|
| @@ -616,7 +655,10 @@
|
| Counters::memory_allocated.Decrement(static_cast<int>(c.size()));
|
| } else {
|
| LOG(DeleteEvent("PagedChunk", c.address()));
|
| + ObjectSpace space = static_cast<ObjectSpace>(1 << c.owner()->identity());
|
| + int size = c.size();
|
| FreeRawMemory(c.address(), c.size(), c.owner()->executable());
|
| + PerformAllocationCallback(space, kAllocationActionFree, size);
|
| }
|
| c.init(NULL, 0, NULL);
|
| Push(chunk_id);
|
| @@ -2614,6 +2656,11 @@
|
| LOG(DeleteEvent("LargeObjectChunk", mem));
|
| return NULL;
|
| }
|
| + ObjectSpace space =
|
| + (executable == EXECUTABLE) ? kObjectSpaceCodeSpace : kObjectSpaceLoSpace;
|
| + MemoryAllocator::PerformAllocationCallback(space,
|
| + kAllocationActionAllocate,
|
| + *chunk_size);
|
| return reinterpret_cast<LargeObjectChunk*>(mem);
|
| }
|
|
|
| @@ -2651,9 +2698,14 @@
|
| Page* page = Page::FromAddress(RoundUp(chunk->address(), Page::kPageSize));
|
| Executability executable =
|
| page->IsPageExecutable() ? EXECUTABLE : NOT_EXECUTABLE;
|
| + ObjectSpace space = kObjectSpaceLoSpace;
|
| + if (executable == EXECUTABLE) space = kObjectSpaceCodeSpace;
|
| + int size = chunk->size();
|
| MemoryAllocator::FreeRawMemory(chunk->address(),
|
| chunk->size(),
|
| executable);
|
| + MemoryAllocator::PerformAllocationCallback(space, kAllocationActionFree,
|
| + size);
|
| }
|
|
|
| size_ = 0;
|
| @@ -2867,7 +2919,11 @@
|
| MarkCompactCollector::ReportDeleteIfNeeded(object);
|
| size_ -= static_cast<int>(chunk_size);
|
| page_count_--;
|
| + ObjectSpace space = kObjectSpaceLoSpace;
|
| + if (executable == EXECUTABLE) space = kObjectSpaceCodeSpace;
|
| MemoryAllocator::FreeRawMemory(chunk_address, chunk_size, executable);
|
| + MemoryAllocator::PerformAllocationCallback(space, kAllocationActionFree,
|
| + size_);
|
| LOG(DeleteEvent("LargeObjectChunk", chunk_address));
|
| }
|
| }
|
|
|