Add counters to track the maximum amount of memory committed by the heap.
authorulan@chromium.org <ulan@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 5 Nov 2013 11:59:42 +0000 (11:59 +0000)
committerulan@chromium.org <ulan@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 5 Nov 2013 11:59:42 +0000 (11:59 +0000)
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

src/flag-definitions.h
src/heap.cc
src/heap.h
src/spaces.cc
src/spaces.h
src/v8-counters.h

index f8a800d..9228944 100644 (file)
@@ -502,6 +502,9 @@ DEFINE_bool(trace_gc_ignore_scavenger, false,
             "do not print trace line after scavenger collection")
 DEFINE_bool(print_cumulative_gc_stat, false,
             "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,
             "print more details following each garbage collection")
 DEFINE_bool(trace_fragmentation, false,
index dfe9c84..f7751c1 100644 (file)
@@ -79,6 +79,7 @@ Heap::Heap()
 // ConfigureHeap (survived_since_last_expansion_, external_allocation_limit_)
 // Will be 4 * reserved_semispace_size_ to ensure that young
 // generation can be aligned to its size.
+      maximum_committed_(0),
       survived_since_last_expansion_(0),
       sweep_generation_(0),
       always_allocate_scope_depth_(0),
@@ -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() {
   if (!HasBeenSetUp()) return 0;
 
@@ -441,6 +452,8 @@ void Heap::GarbageCollectionPrologue() {
 #endif
   }
 
+  UpdateMaximumCommitted();
+
 #ifdef DEBUG
   ASSERT(!AllowHeapAllocation::IsAllowed() && gc_state_ == NOT_IN_GC);
 
@@ -506,6 +519,8 @@ void Heap::GarbageCollectionEpilogue() {
     }
   }
 
+  UpdateMaximumCommitted();
+
   isolate_->counters()->alive_after_last_gc()->Set(
       static_cast<int>(SizeOfObjects()));
 
@@ -567,6 +582,9 @@ void Heap::GarbageCollectionEpilogue() {
                 property_cell_space()->CommittedMemory() / KB));
     isolate_->counters()->heap_sample_code_space_committed()->AddSample(
         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)                                       \
@@ -6812,6 +6830,8 @@ void Heap::TearDown() {
   }
 #endif
 
+  UpdateMaximumCommitted();
+
   if (FLAG_print_cumulative_gc_stat) {
     PrintF("\n");
     PrintF("gc_count=%d ", gc_count_);
@@ -6826,6 +6846,31 @@ void Heap::TearDown() {
     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();
 
   isolate_->global_handles()->TearDown();
index 96cda58..3a02955 100644 (file)
@@ -533,6 +533,13 @@ class Heap {
   // Returns the amount of phyical memory currently committed for the heap.
   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.
   // Heap doesn't guarantee that it can allocate an object that requires
   // all available bytes. Check MaxHeapObjectSize() instead.
@@ -1888,6 +1895,7 @@ class Heap {
   int initial_semispace_size_;
   intptr_t max_old_generation_size_;
   intptr_t max_executable_size_;
+  intptr_t maximum_committed_;
 
   // For keeping track of how much data has survived
   // scavenge since last new space expansion.
index fe5eeb5..f35db69 100644 (file)
@@ -1122,6 +1122,11 @@ void PagedSpace::ResetFreeListStatistics() {
 }
 
 
+void PagedSpace::IncreaseCapacity(int size) {
+  accounting_stats_.ExpandSpace(size);
+}
+
+
 void PagedSpace::ReleasePage(Page* page, bool unlink) {
   ASSERT(page->LiveBytes() == 0);
   ASSERT(AreaSize() == page->area_size());
@@ -1511,6 +1516,7 @@ void SemiSpace::SetUp(Address start,
   initial_capacity_ = RoundDown(initial_capacity, Page::kPageSize);
   capacity_ = initial_capacity;
   maximum_capacity_ = RoundDown(maximum_capacity, Page::kPageSize);
+  maximum_committed_ = 0;
   committed_ = false;
   start_ = start;
   address_mask_ = ~(maximum_capacity - 1);
@@ -1543,6 +1549,7 @@ bool SemiSpace::Commit() {
     current = new_page;
   }
 
+  SetCapacity(capacity_);
   committed_ = true;
   Reset();
   return true;
@@ -1591,7 +1598,7 @@ bool SemiSpace::GrowTo(int new_capacity) {
       start_ + capacity_, delta, executable())) {
     return false;
   }
-  capacity_ = new_capacity;
+  SetCapacity(new_capacity);
   NewSpacePage* last_page = anchor()->prev_page();
   ASSERT(last_page != anchor());
   for (int i = pages_before; i < pages_after; i++) {
@@ -1631,7 +1638,7 @@ bool SemiSpace::ShrinkTo(int new_capacity) {
     ASSERT((current_page_ >= first_page()) && (current_page_ <= new_last_page));
   }
 
-  capacity_ = new_capacity;
+  SetCapacity(new_capacity);
 
   return true;
 }
@@ -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) {
   ASSERT(NewSpacePage::FromLimit(mark)->semi_space() == this);
   age_mark_ = mark;
@@ -2938,6 +2953,7 @@ LargeObjectSpace::LargeObjectSpace(Heap* heap,
 bool LargeObjectSpace::SetUp() {
   first_page_ = NULL;
   size_ = 0;
+  maximum_committed_ = 0;
   page_count_ = 0;
   objects_size_ = 0;
   chunk_map_.Clear();
@@ -2984,6 +3000,10 @@ MaybeObject* LargeObjectSpace::AllocateRaw(int object_size,
   page->set_next_page(first_page_);
   first_page_ = page;
 
+  if (size_ > maximum_committed_) {
+    maximum_committed_ = size_;
+  }
+
   // Register all MemoryChunk::kAlignment-aligned chunks covered by
   // this large page in the chunk map.
   uintptr_t base = reinterpret_cast<uintptr_t>(page) / MemoryChunk::kAlignment;
index 2cd92c5..db0415b 100644 (file)
@@ -1388,6 +1388,7 @@ class AllocationStats BASE_EMBEDDED {
   // Zero out all the allocation statistics (i.e., no capacity).
   void Clear() {
     capacity_ = 0;
+    max_capacity_ = 0;
     size_ = 0;
     waste_ = 0;
   }
@@ -1406,6 +1407,7 @@ class AllocationStats BASE_EMBEDDED {
 
   // Accessors for the allocation statistics.
   intptr_t Capacity() { return capacity_; }
+  intptr_t MaxCapacity() { return max_capacity_; }
   intptr_t Size() { return size_; }
   intptr_t Waste() { return waste_; }
 
@@ -1415,6 +1417,9 @@ class AllocationStats BASE_EMBEDDED {
   void ExpandSpace(int size_in_bytes) {
     capacity_ += size_in_bytes;
     size_ += size_in_bytes;
+    if (capacity_ > max_capacity_) {
+      max_capacity_ = capacity_;
+    }
     ASSERT(size_ >= 0);
   }
 
@@ -1448,6 +1453,7 @@ class AllocationStats BASE_EMBEDDED {
 
  private:
   intptr_t capacity_;
+  intptr_t max_capacity_;
   intptr_t size_;
   intptr_t waste_;
 };
@@ -1689,6 +1695,9 @@ class PagedSpace : public Space {
   // spaces this equals the 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.
   size_t CommittedPhysicalMemory();
 
@@ -1795,9 +1804,7 @@ class PagedSpace : public Space {
     accounting_stats_.AllocateBytes(bytes);
   }
 
-  void IncreaseCapacity(int size) {
-    accounting_stats_.ExpandSpace(size);
-  }
+  void IncreaseCapacity(int size);
 
   // Releases an unused page and shrinks the space.
   void ReleasePage(Page* page, bool unlink);
@@ -2207,6 +2214,9 @@ class SemiSpace : public Space {
 
   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.
   size_t CommittedPhysicalMemory();
 
@@ -2215,6 +2225,9 @@ class SemiSpace : public Space {
   // Copies the flags into the masked positions on all pages in the space.
   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_; }
 
   // The current and maximum capacity of the space.
@@ -2222,6 +2235,8 @@ class SemiSpace : public Space {
   int maximum_capacity_;
   int initial_capacity_;
 
+  intptr_t maximum_committed_;
+
   // The start address of the space.
   Address start_;
   // Used to govern object promotion during mark-compact collection.
@@ -2407,6 +2422,12 @@ class NewSpace : public Space {
     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.
   size_t CommittedPhysicalMemory();
 
@@ -2802,6 +2823,10 @@ class LargeObjectSpace : public Space {
     return objects_size_;
   }
 
+  intptr_t MaximumCommittedMemory() {
+    return maximum_committed_;
+  }
+
   intptr_t CommittedMemory() {
     return Size();
   }
@@ -2853,6 +2878,7 @@ class LargeObjectSpace : public Space {
 
  private:
   intptr_t max_capacity_;
+  intptr_t maximum_committed_;
   // The head of the linked list of large object chunks.
   LargePage* first_page_;
   intptr_t size_;  // allocated bytes
index 476021c..3fb659e 100644 (file)
@@ -101,6 +101,8 @@ namespace internal {
      V8.MemoryHeapSamplePropertyCellSpaceCommitted)                   \
   HM(heap_sample_code_space_committed,                                \
      V8.MemoryHeapSampleCodeSpaceCommitted)                           \
+  HM(heap_sample_maximum_committed,                                   \
+     V8.MemoryHeapSampleMaximumCommitted)                             \
 
 
 // WARNING: STATS_COUNTER_LIST_* is a very large macro that is causing MSVC