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..74224b908428a88a5e694e3dbb1503cd9d55201c 100644 |
--- a/third_party/tcmalloc/chromium/src/heap-profile-table.cc |
+++ b/third_party/tcmalloc/chromium/src/heap-profile-table.cc |
@@ -328,6 +328,53 @@ int HeapProfileTable::UnparseBucket(const Bucket& b, |
return buflen; |
} |
+int HeapProfileTable::UnparsePseudoStackBucket( |
+ const Bucket& bucket, |
+ char* buffer, int written, int buffer_size, |
+ Stats* profile_stats) { |
+ if (profile_stats != NULL) { |
+ profile_stats->allocs += bucket.allocs; |
+ profile_stats->alloc_size += bucket.alloc_size; |
+ profile_stats->frees += bucket.frees; |
+ profile_stats->free_size += bucket.free_size; |
+ } |
+ int printed = snprintf(buffer + written, |
dsinclair
2013/06/18 15:30:15
Would it be possible, instead of converting to JSO
Dai Mikurube (NOT FULLTIME)
2013/06/19 04:34:03
Agreed with dsinclair. Would it be possible to ke
|
+ buffer_size - written, |
+ "{" |
+ "\"trace\": \""); |
+ written += printed; |
+ RAW_DCHECK(bucket.depth <= HeapProfileBucket::kMaxStackDepth, |
+ "stack depth too deep"); |
+ for (int d = 0; d < bucket.depth; d++) { |
+ printed = snprintf(buffer + written, buffer_size - written, "%s ", |
+ reinterpret_cast<const char*>(bucket.stack[d])); |
+ // Brute-force replace any " with ' to keep the JSON correct. |
+ for (int i = 0; i < printed; ++i) { |
+ char* c = buffer + written + i; |
+ if (*c == '"') |
+ *c = '\''; |
+ } |
+ if (printed < 0 || printed >= buffer_size - written) return written; |
+ written += printed; |
+ } |
+ printed = snprintf(buffer + written, |
+ buffer_size - written, |
+ "\", " |
+ "\"current_allocs\": %d, " |
+ "\"current_bytes\": %" PRId64 ", " |
+ "\"total_allocs\": %d, " |
+ "\"total_bytes\": %" PRId64 |
+ "}", |
+ bucket.allocs - bucket.frees, |
+ bucket.alloc_size - bucket.free_size, |
+ bucket.allocs, |
+ bucket.alloc_size); |
+ // If it looks like the snprintf failed, ignore the fact we printed anything |
+ if (printed < 0 || printed >= buffer_size - written) return written; |
+ written += printed; |
+ return written; |
+} |
+ |
HeapProfileTable::Bucket** |
HeapProfileTable::MakeSortedBucketList() const { |
Bucket** list = static_cast<Bucket**>(alloc_(sizeof(Bucket) * num_buckets_)); |
@@ -440,6 +487,30 @@ int HeapProfileTable::FillOrderedProfile(char buf[], int size) const { |
return bucket_length + map_length; |
} |
+int HeapProfileTable::FillPseudoStackProfile(char buffer[], |
+ int buffer_size) const { |
+ Bucket** list = MakeSortedBucketList(); |
+ |
+ Stats stats; |
+ memset(&stats, 0, sizeof(stats)); |
+ int written = snprintf(buffer, buffer_size, "[\n"); |
+ written = UnparsePseudoStackBucket( |
+ total_, buffer, written, buffer_size, &stats); |
+ |
+ for (int i = 0; i < num_buckets_; i++) { |
+ written += snprintf(buffer + written, buffer_size - written, ",\n"); |
+ written = UnparsePseudoStackBucket( |
+ *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) { |