Index: third_party/tcmalloc/chromium/src/heap-profile-table.cc |
diff --git a/third_party/tcmalloc/chromium/src/heap-profile-table.cc b/third_party/tcmalloc/chromium/src/heap-profile-table.cc |
index 68ec5735026f8feced50e6612c760ced6915b809..632fa659f9e62a8e1189cba7716cdb1fb129ba95 100644 |
--- a/third_party/tcmalloc/chromium/src/heap-profile-table.cc |
+++ b/third_party/tcmalloc/chromium/src/heap-profile-table.cc |
@@ -328,6 +328,45 @@ int HeapProfileTable::UnparseBucket(const Bucket& b, |
return buflen; |
} |
+int HeapProfileTable::UnparseBucket2(const Bucket& b, |
+ char* buf, int buflen, int bufsize, |
+ Stats* profile_stats) { |
+ if (profile_stats != NULL) { |
+ profile_stats->allocs += b.allocs; |
+ profile_stats->alloc_size += b.alloc_size; |
+ profile_stats->frees += b.frees; |
+ profile_stats->free_size += b.free_size; |
+ } |
+ int printed = snprintf(buf + buflen, |
+ bufsize - buflen, |
+ "{" |
+ "\"trace\": \""); |
+ buflen += printed; |
+ for (int d = 0; d < b.depth; d++) { |
+ // OMG what a hack |
+ printed = snprintf(buf + buflen, bufsize - buflen, "%s ", |
+ reinterpret_cast<const char*>(b.stack[d])); |
+ if (printed < 0 || printed >= bufsize - buflen) return buflen; |
+ buflen += printed; |
+ } |
+ printed = snprintf(buf + buflen, |
+ bufsize - buflen, |
+ "\", " |
+ "\"current_allocs\": %d, " |
+ "\"current_bytes\": %" PRId64 ", " |
+ "\"total_allocs\": %d, " |
+ "\"total_bytes\": %" PRId64 |
+ "}", |
+ b.allocs - b.frees, |
+ b.alloc_size - b.free_size, |
+ b.allocs, |
+ b.alloc_size); |
+ // If it looks like the snprintf failed, ignore the fact we printed anything |
+ if (printed < 0 || printed >= bufsize - buflen) return buflen; |
+ buflen += printed; |
+ return buflen; |
+} |
+ |
HeapProfileTable::Bucket** |
HeapProfileTable::MakeSortedBucketList() const { |
Bucket** list = static_cast<Bucket**>(alloc_(sizeof(Bucket) * num_buckets_)); |
@@ -440,6 +479,29 @@ int HeapProfileTable::FillOrderedProfile(char buf[], int size) const { |
return bucket_length + map_length; |
} |
+// TODO(jamescook): Make a subclass and override this method. |
+int HeapProfileTable::FillOrderedProfile2(char buffer[], |
+ int buffer_size) const { |
+ Bucket** list = MakeSortedBucketList(); |
+ |
+ Stats stats; |
+ memset(&stats, 0, sizeof(stats)); |
+ int written = snprintf(buffer, buffer_size, "[\n"); |
+ written = UnparseBucket2(total_, buffer, written, buffer_size, &stats); |
+ |
+ for (int i = 0; i < num_buckets_; i++) { |
+ written += snprintf(buffer + written, buffer_size - written, ",\n"); |
+ written = UnparseBucket2(*list[i], buffer, written, buffer_size, &stats); |
+ } |
+ RAW_DCHECK(written < buffer_size, ""); |
+ |
+ written += snprintf(buffer + written, buffer_size - written, "\n]\n"); |
+ |
+ dealloc_(list); |
+ |
+ return written; |
+} |
+ |
// static |
void HeapProfileTable::DumpBucketIterator(const Bucket* bucket, |
BufferArgs* args) { |