Implement heap profiler memory usage reporting.
authoralexeif@chromium.org <alexeif@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 13 Jun 2012 11:02:24 +0000 (11:02 +0000)
committeralexeif@chromium.org <alexeif@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 13 Jun 2012 11:02:24 +0000 (11:02 +0000)
Review URL: https://chromiumcodereview.appspot.com/10535096

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11793 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

include/v8-profiler.h
src/api.cc
src/heap-profiler.cc
src/heap-profiler.h
src/profile-generator.cc
src/profile-generator.h

index 5f560c37eae8425cca4553f6fa01be21e3de3ead..cda2463362e199dc855240412dd251026eaaee44 100644 (file)
@@ -482,6 +482,9 @@ class V8EXPORT HeapProfiler {
 
   /** Returns the number of currently existing persistent handles. */
   static int GetPersistentHandleCount();
+
+  /** Returns memory used for profiler internal data and snapshots. */
+  static size_t GetMemorySizeUsedByProfiler();
 };
 
 
index 0148be56827ece0ead5f7f3f9dae6ccffed85be9..0d88047aa212f4d0abcba489cae3247774e6e397 100644 (file)
@@ -6270,6 +6270,11 @@ int HeapProfiler::GetPersistentHandleCount() {
 }
 
 
+size_t HeapProfiler::GetMemorySizeUsedByProfiler() {
+  return i::HeapProfiler::GetMemorySizeUsedByProfiler();
+}
+
+
 v8::Testing::StressType internal::Testing::stress_type_ =
     v8::Testing::kStressTypeOpt;
 
index 975d6f4221c9162a79ae37413bb2362839f78108..301b09993e7eb094703736747f8deb51e4f51775 100644 (file)
@@ -168,6 +168,14 @@ void HeapProfiler::StopHeapObjectsTrackingImpl() {
 }
 
 
+size_t HeapProfiler::GetMemorySizeUsedByProfiler() {
+  HeapProfiler* profiler = Isolate::Current()->heap_profiler();
+  ASSERT(profiler != NULL);
+  size_t size = profiler->snapshots_->GetUsedMemorySize();
+  return size;
+}
+
+
 int HeapProfiler::GetSnapshotsCount() {
   HeapProfiler* profiler = Isolate::Current()->heap_profiler();
   ASSERT(profiler != NULL);
index 4a811573ac1764742432d4e87852682e802d5291..346177b8ba0712ddb2ed1eb95f368accf9205d0d 100644 (file)
@@ -49,6 +49,8 @@ class HeapProfiler {
   static void SetUp();
   static void TearDown();
 
+  static size_t GetMemorySizeUsedByProfiler();
+
   static HeapSnapshot* TakeSnapshot(const char* name,
                                     int type,
                                     v8::ActivityControl* control);
index b172bd8f623bb7ea3a92914796617a6dbb748d18..216dc8dcec8c62d79f2ac156ffe4980926f2983f 100644 (file)
@@ -169,6 +169,15 @@ const char* StringsStorage::GetName(int index) {
 }
 
 
+size_t StringsStorage::GetUsedMemorySize() const {
+  size_t size = sizeof(*this);
+  size += sizeof(HashMap::Entry) * names_.capacity();
+  for (HashMap::Entry* p = names_.Start(); p != NULL; p = names_.Next(p)) {
+    size += strlen(reinterpret_cast<const char*>(p->value)) + 1;
+  }
+  return size;
+}
+
 const char* const CodeEntry::kEmptyNamePrefix = "";
 
 
@@ -1083,12 +1092,16 @@ template <size_t ptr_size> struct SnapshotSizeConstants;
 template <> struct SnapshotSizeConstants<4> {
   static const int kExpectedHeapGraphEdgeSize = 12;
   static const int kExpectedHeapEntrySize = 24;
+  static const int kExpectedHeapSnapshotsCollectionSize = 96;
+  static const int kExpectedHeapSnapshotSize = 136;
   static const size_t kMaxSerializableSnapshotRawSize = 256 * MB;
 };
 
 template <> struct SnapshotSizeConstants<8> {
   static const int kExpectedHeapGraphEdgeSize = 24;
   static const int kExpectedHeapEntrySize = 32;
+  static const int kExpectedHeapSnapshotsCollectionSize = 144;
+  static const int kExpectedHeapSnapshotSize = 168;
   static const uint64_t kMaxSerializableSnapshotRawSize =
       static_cast<uint64_t>(6000) * MB;
 };
@@ -1243,12 +1256,15 @@ void HeapSnapshot::Print(int max_depth) {
 
 template<typename T, class P>
 static size_t GetMemoryUsedByList(const List<T, P>& list) {
-  return list.capacity() * sizeof(T);
+  return list.length() * sizeof(T) + sizeof(list);
 }
 
 
 size_t HeapSnapshot::RawSnapshotSize() const {
+  STATIC_CHECK(sizeof(*this) ==
+      SnapshotSizeConstants<kPointerSize>::kExpectedHeapSnapshotSize);
   return
+      sizeof(*this) +
       GetMemoryUsedByList(entries_) +
       GetMemoryUsedByList(edges_) +
       GetMemoryUsedByList(children_) +
@@ -1446,6 +1462,15 @@ SnapshotObjectId HeapObjectsMap::GenerateId(v8::RetainedObjectInfo* info) {
 }
 
 
+size_t HeapObjectsMap::GetUsedMemorySize() const {
+  return
+      sizeof(*this) +
+      sizeof(HashMap::Entry) * entries_map_.capacity() +
+      GetMemoryUsedByList(entries_) +
+      GetMemoryUsedByList(time_intervals_);
+}
+
+
 HeapSnapshotsCollection::HeapSnapshotsCollection()
     : is_tracking_objects_(false),
       snapshots_uids_(HeapSnapshotsMatch),
@@ -1525,6 +1550,22 @@ Handle<HeapObject> HeapSnapshotsCollection::FindHeapObjectById(
 }
 
 
+size_t HeapSnapshotsCollection::GetUsedMemorySize() const {
+  STATIC_CHECK(
+      sizeof(*this) == SnapshotSizeConstants<kPointerSize>::
+          kExpectedHeapSnapshotsCollectionSize);
+  size_t size = sizeof(*this);
+  size += names_.GetUsedMemorySize();
+  size += ids_.GetUsedMemorySize();
+  size += sizeof(HashMap::Entry) * snapshots_uids_.capacity();
+  size += GetMemoryUsedByList(snapshots_);
+  for (int i = 0; i < snapshots_.length(); ++i) {
+    size += snapshots_[i]->RawSnapshotSize();
+  }
+  return size;
+}
+
+
 HeapEntriesMap::HeapEntriesMap()
     : entries_(HeapThingsMatch) {
 }
index 45dc9a4a44daca80969eb70e7c19b9c7e1a0be84..d56d874705da50fa7320ab01dd5f0cfe808b09eb 100644 (file)
@@ -72,6 +72,7 @@ class StringsStorage {
   const char* GetName(int index);
   inline const char* GetFunctionName(String* name);
   inline const char* GetFunctionName(const char* name);
+  size_t GetUsedMemorySize() const;
 
  private:
   static const int kMaxNameSize = 1024;
@@ -650,6 +651,7 @@ class HeapObjectsMap {
 
   void StopHeapObjectsTracking();
   SnapshotObjectId PushHeapObjectsStats(OutputStream* stream);
+  size_t GetUsedMemorySize() const;
 
   static SnapshotObjectId GenerateId(v8::RetainedObjectInfo* info);
   static inline SnapshotObjectId GetNthGcSubrootId(int delta);
@@ -734,6 +736,7 @@ class HeapSnapshotsCollection {
   SnapshotObjectId last_assigned_id() const {
     return ids_.last_assigned_id();
   }
+  size_t GetUsedMemorySize() const;
 
  private:
   INLINE(static bool HeapSnapshotsMatch(void* key1, void* key2)) {