| 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..771662813f0032c1154ce43d5c0643b5f3370fdc 100644
|
| --- a/third_party/tcmalloc/chromium/src/heap-profile-table.cc
|
| +++ b/third_party/tcmalloc/chromium/src/heap-profile-table.cc
|
| @@ -328,6 +328,51 @@ int HeapProfileTable::UnparseBucket(const Bucket& b,
|
| return buflen;
|
| }
|
|
|
| +int HeapProfileTable::UnparsePseudoStackBucket(
|
| + const Bucket& bucket,
|
| + char* buf, int buflen, int bufsize,
|
| + 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(buf + buflen,
|
| + bufsize - buflen,
|
| + "{"
|
| + "\"trace\": \"");
|
| + buflen += printed;
|
| + for (int d = 0; d < bucket.depth; d++) {
|
| + printed = snprintf(buf + buflen, bufsize - buflen, "%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 = buf + buflen + i;
|
| + if (*c == '"')
|
| + *c = '\'';
|
| + }
|
| + 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
|
| + "}",
|
| + 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 >= 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 +485,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) {
|
|
|