Commit 0fd7c2a7 authored by ulan@chromium.org's avatar ulan@chromium.org

Add counters to track the maximum amount of memory committed by the heap.

BUG=None
R=bmeurer@chromium.org, ulan@chromium.org

Review URL: https://chromiumcodereview.appspot.com/29203003

Patch from Ross McIlroy <rmcilroy@chromium.org>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17478 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent ada13dfc
...@@ -502,6 +502,9 @@ DEFINE_bool(trace_gc_ignore_scavenger, false, ...@@ -502,6 +502,9 @@ DEFINE_bool(trace_gc_ignore_scavenger, false,
"do not print trace line after scavenger collection") "do not print trace line after scavenger collection")
DEFINE_bool(print_cumulative_gc_stat, false, DEFINE_bool(print_cumulative_gc_stat, false,
"print cumulative GC statistics in name=value format on exit") "print cumulative GC statistics in name=value format on exit")
DEFINE_bool(print_max_heap_committed, false,
"print statistics of the maximum memory committed for the heap "
"in name=value format on exit")
DEFINE_bool(trace_gc_verbose, false, DEFINE_bool(trace_gc_verbose, false,
"print more details following each garbage collection") "print more details following each garbage collection")
DEFINE_bool(trace_fragmentation, false, DEFINE_bool(trace_fragmentation, false,
......
...@@ -79,6 +79,7 @@ Heap::Heap() ...@@ -79,6 +79,7 @@ Heap::Heap()
// ConfigureHeap (survived_since_last_expansion_, external_allocation_limit_) // ConfigureHeap (survived_since_last_expansion_, external_allocation_limit_)
// Will be 4 * reserved_semispace_size_ to ensure that young // Will be 4 * reserved_semispace_size_ to ensure that young
// generation can be aligned to its size. // generation can be aligned to its size.
maximum_committed_(0),
survived_since_last_expansion_(0), survived_since_last_expansion_(0),
sweep_generation_(0), sweep_generation_(0),
always_allocate_scope_depth_(0), always_allocate_scope_depth_(0),
...@@ -232,6 +233,16 @@ intptr_t Heap::CommittedMemoryExecutable() { ...@@ -232,6 +233,16 @@ intptr_t Heap::CommittedMemoryExecutable() {
} }
void Heap::UpdateMaximumCommitted() {
if (!HasBeenSetUp()) return;
intptr_t current_committed_memory = CommittedMemory();
if (current_committed_memory > maximum_committed_) {
maximum_committed_ = current_committed_memory;
}
}
intptr_t Heap::Available() { intptr_t Heap::Available() {
if (!HasBeenSetUp()) return 0; if (!HasBeenSetUp()) return 0;
...@@ -441,6 +452,8 @@ void Heap::GarbageCollectionPrologue() { ...@@ -441,6 +452,8 @@ void Heap::GarbageCollectionPrologue() {
#endif #endif
} }
UpdateMaximumCommitted();
#ifdef DEBUG #ifdef DEBUG
ASSERT(!AllowHeapAllocation::IsAllowed() && gc_state_ == NOT_IN_GC); ASSERT(!AllowHeapAllocation::IsAllowed() && gc_state_ == NOT_IN_GC);
...@@ -506,6 +519,8 @@ void Heap::GarbageCollectionEpilogue() { ...@@ -506,6 +519,8 @@ void Heap::GarbageCollectionEpilogue() {
} }
} }
UpdateMaximumCommitted();
isolate_->counters()->alive_after_last_gc()->Set( isolate_->counters()->alive_after_last_gc()->Set(
static_cast<int>(SizeOfObjects())); static_cast<int>(SizeOfObjects()));
...@@ -567,6 +582,9 @@ void Heap::GarbageCollectionEpilogue() { ...@@ -567,6 +582,9 @@ void Heap::GarbageCollectionEpilogue() {
property_cell_space()->CommittedMemory() / KB)); property_cell_space()->CommittedMemory() / KB));
isolate_->counters()->heap_sample_code_space_committed()->AddSample( isolate_->counters()->heap_sample_code_space_committed()->AddSample(
static_cast<int>(code_space()->CommittedMemory() / KB)); static_cast<int>(code_space()->CommittedMemory() / KB));
isolate_->counters()->heap_sample_maximum_committed()->AddSample(
static_cast<int>(MaximumCommittedMemory() / KB));
} }
#define UPDATE_COUNTERS_FOR_SPACE(space) \ #define UPDATE_COUNTERS_FOR_SPACE(space) \
...@@ -6812,6 +6830,8 @@ void Heap::TearDown() { ...@@ -6812,6 +6830,8 @@ void Heap::TearDown() {
} }
#endif #endif
UpdateMaximumCommitted();
if (FLAG_print_cumulative_gc_stat) { if (FLAG_print_cumulative_gc_stat) {
PrintF("\n"); PrintF("\n");
PrintF("gc_count=%d ", gc_count_); PrintF("gc_count=%d ", gc_count_);
...@@ -6826,6 +6846,31 @@ void Heap::TearDown() { ...@@ -6826,6 +6846,31 @@ void Heap::TearDown() {
PrintF("\n\n"); PrintF("\n\n");
} }
if (FLAG_print_max_heap_committed) {
PrintF("\n");
PrintF("maximum_committed_by_heap=%" V8_PTR_PREFIX "d ",
MaximumCommittedMemory());
PrintF("maximum_committed_by_new_space=%" V8_PTR_PREFIX "d ",
new_space_.MaximumCommittedMemory());
PrintF("maximum_committed_by_old_pointer_space=%" V8_PTR_PREFIX "d ",
old_data_space_->MaximumCommittedMemory());
PrintF("maximum_committed_by_old_data_space=%" V8_PTR_PREFIX "d ",
old_pointer_space_->MaximumCommittedMemory());
PrintF("maximum_committed_by_old_data_space=%" V8_PTR_PREFIX "d ",
old_pointer_space_->MaximumCommittedMemory());
PrintF("maximum_committed_by_code_space=%" V8_PTR_PREFIX "d ",
code_space_->MaximumCommittedMemory());
PrintF("maximum_committed_by_map_space=%" V8_PTR_PREFIX "d ",
map_space_->MaximumCommittedMemory());
PrintF("maximum_committed_by_cell_space=%" V8_PTR_PREFIX "d ",
cell_space_->MaximumCommittedMemory());
PrintF("maximum_committed_by_property_space=%" V8_PTR_PREFIX "d ",
property_cell_space_->MaximumCommittedMemory());
PrintF("maximum_committed_by_lo_space=%" V8_PTR_PREFIX "d ",
lo_space_->MaximumCommittedMemory());
PrintF("\n\n");
}
TearDownArrayBuffers(); TearDownArrayBuffers();
isolate_->global_handles()->TearDown(); isolate_->global_handles()->TearDown();
......
...@@ -533,6 +533,13 @@ class Heap { ...@@ -533,6 +533,13 @@ class Heap {
// Returns the amount of phyical memory currently committed for the heap. // Returns the amount of phyical memory currently committed for the heap.
size_t CommittedPhysicalMemory(); size_t CommittedPhysicalMemory();
// Returns the maximum amount of memory ever committed for the heap.
intptr_t MaximumCommittedMemory() { return maximum_committed_; }
// Updates the maximum committed memory for the heap. Should be called
// whenever a space grows.
void UpdateMaximumCommitted();
// Returns the available bytes in space w/o growing. // Returns the available bytes in space w/o growing.
// Heap doesn't guarantee that it can allocate an object that requires // Heap doesn't guarantee that it can allocate an object that requires
// all available bytes. Check MaxHeapObjectSize() instead. // all available bytes. Check MaxHeapObjectSize() instead.
...@@ -1888,6 +1895,7 @@ class Heap { ...@@ -1888,6 +1895,7 @@ class Heap {
int initial_semispace_size_; int initial_semispace_size_;
intptr_t max_old_generation_size_; intptr_t max_old_generation_size_;
intptr_t max_executable_size_; intptr_t max_executable_size_;
intptr_t maximum_committed_;
// For keeping track of how much data has survived // For keeping track of how much data has survived
// scavenge since last new space expansion. // scavenge since last new space expansion.
......
...@@ -1122,6 +1122,11 @@ void PagedSpace::ResetFreeListStatistics() { ...@@ -1122,6 +1122,11 @@ void PagedSpace::ResetFreeListStatistics() {
} }
void PagedSpace::IncreaseCapacity(int size) {
accounting_stats_.ExpandSpace(size);
}
void PagedSpace::ReleasePage(Page* page, bool unlink) { void PagedSpace::ReleasePage(Page* page, bool unlink) {
ASSERT(page->LiveBytes() == 0); ASSERT(page->LiveBytes() == 0);
ASSERT(AreaSize() == page->area_size()); ASSERT(AreaSize() == page->area_size());
...@@ -1511,6 +1516,7 @@ void SemiSpace::SetUp(Address start, ...@@ -1511,6 +1516,7 @@ void SemiSpace::SetUp(Address start,
initial_capacity_ = RoundDown(initial_capacity, Page::kPageSize); initial_capacity_ = RoundDown(initial_capacity, Page::kPageSize);
capacity_ = initial_capacity; capacity_ = initial_capacity;
maximum_capacity_ = RoundDown(maximum_capacity, Page::kPageSize); maximum_capacity_ = RoundDown(maximum_capacity, Page::kPageSize);
maximum_committed_ = 0;
committed_ = false; committed_ = false;
start_ = start; start_ = start;
address_mask_ = ~(maximum_capacity - 1); address_mask_ = ~(maximum_capacity - 1);
...@@ -1543,6 +1549,7 @@ bool SemiSpace::Commit() { ...@@ -1543,6 +1549,7 @@ bool SemiSpace::Commit() {
current = new_page; current = new_page;
} }
SetCapacity(capacity_);
committed_ = true; committed_ = true;
Reset(); Reset();
return true; return true;
...@@ -1591,7 +1598,7 @@ bool SemiSpace::GrowTo(int new_capacity) { ...@@ -1591,7 +1598,7 @@ bool SemiSpace::GrowTo(int new_capacity) {
start_ + capacity_, delta, executable())) { start_ + capacity_, delta, executable())) {
return false; return false;
} }
capacity_ = new_capacity; SetCapacity(new_capacity);
NewSpacePage* last_page = anchor()->prev_page(); NewSpacePage* last_page = anchor()->prev_page();
ASSERT(last_page != anchor()); ASSERT(last_page != anchor());
for (int i = pages_before; i < pages_after; i++) { for (int i = pages_before; i < pages_after; i++) {
...@@ -1631,7 +1638,7 @@ bool SemiSpace::ShrinkTo(int new_capacity) { ...@@ -1631,7 +1638,7 @@ bool SemiSpace::ShrinkTo(int new_capacity) {
ASSERT((current_page_ >= first_page()) && (current_page_ <= new_last_page)); ASSERT((current_page_ >= first_page()) && (current_page_ <= new_last_page));
} }
capacity_ = new_capacity; SetCapacity(new_capacity);
return true; return true;
} }
...@@ -1694,6 +1701,14 @@ void SemiSpace::Swap(SemiSpace* from, SemiSpace* to) { ...@@ -1694,6 +1701,14 @@ void SemiSpace::Swap(SemiSpace* from, SemiSpace* to) {
} }
void SemiSpace::SetCapacity(int new_capacity) {
capacity_ = new_capacity;
if (capacity_ > maximum_committed_) {
maximum_committed_ = capacity_;
}
}
void SemiSpace::set_age_mark(Address mark) { void SemiSpace::set_age_mark(Address mark) {
ASSERT(NewSpacePage::FromLimit(mark)->semi_space() == this); ASSERT(NewSpacePage::FromLimit(mark)->semi_space() == this);
age_mark_ = mark; age_mark_ = mark;
...@@ -2938,6 +2953,7 @@ LargeObjectSpace::LargeObjectSpace(Heap* heap, ...@@ -2938,6 +2953,7 @@ LargeObjectSpace::LargeObjectSpace(Heap* heap,
bool LargeObjectSpace::SetUp() { bool LargeObjectSpace::SetUp() {
first_page_ = NULL; first_page_ = NULL;
size_ = 0; size_ = 0;
maximum_committed_ = 0;
page_count_ = 0; page_count_ = 0;
objects_size_ = 0; objects_size_ = 0;
chunk_map_.Clear(); chunk_map_.Clear();
...@@ -2984,6 +3000,10 @@ MaybeObject* LargeObjectSpace::AllocateRaw(int object_size, ...@@ -2984,6 +3000,10 @@ MaybeObject* LargeObjectSpace::AllocateRaw(int object_size,
page->set_next_page(first_page_); page->set_next_page(first_page_);
first_page_ = page; first_page_ = page;
if (size_ > maximum_committed_) {
maximum_committed_ = size_;
}
// Register all MemoryChunk::kAlignment-aligned chunks covered by // Register all MemoryChunk::kAlignment-aligned chunks covered by
// this large page in the chunk map. // this large page in the chunk map.
uintptr_t base = reinterpret_cast<uintptr_t>(page) / MemoryChunk::kAlignment; uintptr_t base = reinterpret_cast<uintptr_t>(page) / MemoryChunk::kAlignment;
......
...@@ -1388,6 +1388,7 @@ class AllocationStats BASE_EMBEDDED { ...@@ -1388,6 +1388,7 @@ class AllocationStats BASE_EMBEDDED {
// Zero out all the allocation statistics (i.e., no capacity). // Zero out all the allocation statistics (i.e., no capacity).
void Clear() { void Clear() {
capacity_ = 0; capacity_ = 0;
max_capacity_ = 0;
size_ = 0; size_ = 0;
waste_ = 0; waste_ = 0;
} }
...@@ -1406,6 +1407,7 @@ class AllocationStats BASE_EMBEDDED { ...@@ -1406,6 +1407,7 @@ class AllocationStats BASE_EMBEDDED {
// Accessors for the allocation statistics. // Accessors for the allocation statistics.
intptr_t Capacity() { return capacity_; } intptr_t Capacity() { return capacity_; }
intptr_t MaxCapacity() { return max_capacity_; }
intptr_t Size() { return size_; } intptr_t Size() { return size_; }
intptr_t Waste() { return waste_; } intptr_t Waste() { return waste_; }
...@@ -1415,6 +1417,9 @@ class AllocationStats BASE_EMBEDDED { ...@@ -1415,6 +1417,9 @@ class AllocationStats BASE_EMBEDDED {
void ExpandSpace(int size_in_bytes) { void ExpandSpace(int size_in_bytes) {
capacity_ += size_in_bytes; capacity_ += size_in_bytes;
size_ += size_in_bytes; size_ += size_in_bytes;
if (capacity_ > max_capacity_) {
max_capacity_ = capacity_;
}
ASSERT(size_ >= 0); ASSERT(size_ >= 0);
} }
...@@ -1448,6 +1453,7 @@ class AllocationStats BASE_EMBEDDED { ...@@ -1448,6 +1453,7 @@ class AllocationStats BASE_EMBEDDED {
private: private:
intptr_t capacity_; intptr_t capacity_;
intptr_t max_capacity_;
intptr_t size_; intptr_t size_;
intptr_t waste_; intptr_t waste_;
}; };
...@@ -1689,6 +1695,9 @@ class PagedSpace : public Space { ...@@ -1689,6 +1695,9 @@ class PagedSpace : public Space {
// spaces this equals the capacity. // spaces this equals the capacity.
intptr_t CommittedMemory() { return Capacity(); } intptr_t CommittedMemory() { return Capacity(); }
// The maximum amount of memory ever committed for this space.
intptr_t MaximumCommittedMemory() { return accounting_stats_.MaxCapacity(); }
// Approximate amount of physical memory committed for this space. // Approximate amount of physical memory committed for this space.
size_t CommittedPhysicalMemory(); size_t CommittedPhysicalMemory();
...@@ -1795,9 +1804,7 @@ class PagedSpace : public Space { ...@@ -1795,9 +1804,7 @@ class PagedSpace : public Space {
accounting_stats_.AllocateBytes(bytes); accounting_stats_.AllocateBytes(bytes);
} }
void IncreaseCapacity(int size) { void IncreaseCapacity(int size);
accounting_stats_.ExpandSpace(size);
}
// Releases an unused page and shrinks the space. // Releases an unused page and shrinks the space.
void ReleasePage(Page* page, bool unlink); void ReleasePage(Page* page, bool unlink);
...@@ -2207,6 +2214,9 @@ class SemiSpace : public Space { ...@@ -2207,6 +2214,9 @@ class SemiSpace : public Space {
static void Swap(SemiSpace* from, SemiSpace* to); static void Swap(SemiSpace* from, SemiSpace* to);
// Returns the maximum amount of memory ever committed by the semi space.
size_t MaximumCommittedMemory() { return maximum_committed_; }
// Approximate amount of physical memory committed for this space. // Approximate amount of physical memory committed for this space.
size_t CommittedPhysicalMemory(); size_t CommittedPhysicalMemory();
...@@ -2215,6 +2225,9 @@ class SemiSpace : public Space { ...@@ -2215,6 +2225,9 @@ class SemiSpace : public Space {
// Copies the flags into the masked positions on all pages in the space. // Copies the flags into the masked positions on all pages in the space.
void FlipPages(intptr_t flags, intptr_t flag_mask); void FlipPages(intptr_t flags, intptr_t flag_mask);
// Updates Capacity and MaximumCommitted based on new capacity.
void SetCapacity(int new_capacity);
NewSpacePage* anchor() { return &anchor_; } NewSpacePage* anchor() { return &anchor_; }
// The current and maximum capacity of the space. // The current and maximum capacity of the space.
...@@ -2222,6 +2235,8 @@ class SemiSpace : public Space { ...@@ -2222,6 +2235,8 @@ class SemiSpace : public Space {
int maximum_capacity_; int maximum_capacity_;
int initial_capacity_; int initial_capacity_;
intptr_t maximum_committed_;
// The start address of the space. // The start address of the space.
Address start_; Address start_;
// Used to govern object promotion during mark-compact collection. // Used to govern object promotion during mark-compact collection.
...@@ -2407,6 +2422,12 @@ class NewSpace : public Space { ...@@ -2407,6 +2422,12 @@ class NewSpace : public Space {
return Capacity(); return Capacity();
} }
// Return the total amount of memory committed for new space.
intptr_t MaximumCommittedMemory() {
return to_space_.MaximumCommittedMemory() +
from_space_.MaximumCommittedMemory();
}
// Approximate amount of physical memory committed for this space. // Approximate amount of physical memory committed for this space.
size_t CommittedPhysicalMemory(); size_t CommittedPhysicalMemory();
...@@ -2802,6 +2823,10 @@ class LargeObjectSpace : public Space { ...@@ -2802,6 +2823,10 @@ class LargeObjectSpace : public Space {
return objects_size_; return objects_size_;
} }
intptr_t MaximumCommittedMemory() {
return maximum_committed_;
}
intptr_t CommittedMemory() { intptr_t CommittedMemory() {
return Size(); return Size();
} }
...@@ -2853,6 +2878,7 @@ class LargeObjectSpace : public Space { ...@@ -2853,6 +2878,7 @@ class LargeObjectSpace : public Space {
private: private:
intptr_t max_capacity_; intptr_t max_capacity_;
intptr_t maximum_committed_;
// The head of the linked list of large object chunks. // The head of the linked list of large object chunks.
LargePage* first_page_; LargePage* first_page_;
intptr_t size_; // allocated bytes intptr_t size_; // allocated bytes
......
...@@ -101,6 +101,8 @@ namespace internal { ...@@ -101,6 +101,8 @@ namespace internal {
V8.MemoryHeapSamplePropertyCellSpaceCommitted) \ V8.MemoryHeapSamplePropertyCellSpaceCommitted) \
HM(heap_sample_code_space_committed, \ HM(heap_sample_code_space_committed, \
V8.MemoryHeapSampleCodeSpaceCommitted) \ V8.MemoryHeapSampleCodeSpaceCommitted) \
HM(heap_sample_maximum_committed, \
V8.MemoryHeapSampleMaximumCommitted) \
// WARNING: STATS_COUNTER_LIST_* is a very large macro that is causing MSVC // WARNING: STATS_COUNTER_LIST_* is a very large macro that is causing MSVC
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment