diff options
author | dmikurube@chromium.org <dmikurube@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-17 09:20:22 +0000 |
---|---|---|
committer | dmikurube@chromium.org <dmikurube@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-17 09:20:22 +0000 |
commit | 2a6a0e4be8da7911fdbc9f42fb3d35589539e13d (patch) | |
tree | 6d082f41374222d5297cbb488317453a8808d519 /third_party | |
parent | 3fec04dee87975edeeda743ca7190cd610385e6a (diff) | |
download | chromium_src-2a6a0e4be8da7911fdbc9f42fb3d35589539e13d.zip chromium_src-2a6a0e4be8da7911fdbc9f42fb3d35589539e13d.tar.gz chromium_src-2a6a0e4be8da7911fdbc9f42fb3d35589539e13d.tar.bz2 |
Store mmap-or-not information in DeepBucket.
The profiler's dump format and the analyzer script dmprof are changed, too. Old dump formats get obsolete.
BUG=123758
TEST=Run the deep memory profiler.
Review URL: https://chromiumcodereview.appspot.com/10694130
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@146968 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party')
-rw-r--r-- | third_party/tcmalloc/chromium/src/deep-heap-profile.cc | 100 | ||||
-rw-r--r-- | third_party/tcmalloc/chromium/src/deep-heap-profile.h | 13 |
2 files changed, 55 insertions, 58 deletions
diff --git a/third_party/tcmalloc/chromium/src/deep-heap-profile.cc b/third_party/tcmalloc/chromium/src/deep-heap-profile.cc index bf9af05..fb2143c 100644 --- a/third_party/tcmalloc/chromium/src/deep-heap-profile.cc +++ b/third_party/tcmalloc/chromium/src/deep-heap-profile.cc @@ -30,10 +30,9 @@ static const uint64 MAX_ADDRESS = kuint64max; // Header strings of the dumped heap profile. static const char kProfileHeader[] = "heap profile: "; -static const char kProfileVersion[] = "DUMP_DEEP_4"; +static const char kProfileVersion[] = "DUMP_DEEP_5"; static const char kGlobalStatsHeader[] = "GLOBAL_STATS:\n"; -static const char kMMapStacktraceHeader[] = "MMAP_STACKTRACES:\n"; -static const char kAllocStacktraceHeader[] = "MALLOC_STACKTRACES:\n"; +static const char kStacktraceHeader[] = "STACKTRACES:\n"; static const char kProcSelfMapsHeader[] = "\nMAPPED_LIBRARIES:\n"; static const char kVirtualLabel[] = "virtual"; @@ -96,8 +95,7 @@ int DeepHeapProfile::FillOrderedProfile(char buffer[], int buffer_size) { } // Reset committed sizes of buckets. - ResetCommittedSize(heap_profile_->alloc_table_); - ResetCommittedSize(heap_profile_->mmap_table_); + ResetCommittedSize(deep_table_); // Allocate a list for mmap'ed regions. num_mmap_allocations_ = 0; @@ -159,9 +157,8 @@ int DeepHeapProfile::FillOrderedProfile(char buffer[], int buffer_size) { used_in_buffer = UnparseGlobalStats(used_in_buffer, buffer_size, buffer); - // Fill buffer with the header for buckets of mmap'ed regions. printed = snprintf(buffer + used_in_buffer, buffer_size - used_in_buffer, - kMMapStacktraceHeader); + kStacktraceHeader); if (IsPrintedStringValid(printed, buffer_size, used_in_buffer)) { return used_in_buffer; } @@ -174,29 +171,8 @@ int DeepHeapProfile::FillOrderedProfile(char buffer[], int buffer_size) { } used_in_buffer += printed; - // Fill buffer with stack trace buckets of mmap'ed regions. - used_in_buffer = SnapshotBucketTableWithoutMalloc(heap_profile_->mmap_table_, - used_in_buffer, - buffer_size, - buffer); - - // Fill buffer with the header for buckets of allocated regions. - printed = snprintf(buffer + used_in_buffer, buffer_size - used_in_buffer, - kAllocStacktraceHeader); - if (IsPrintedStringValid(printed, buffer_size, used_in_buffer)) { - return used_in_buffer; - } - used_in_buffer += printed; - - printed = snprintf(buffer + used_in_buffer, buffer_size - used_in_buffer, - "%10s %10s\n", kVirtualLabel, kCommittedLabel); - if (IsPrintedStringValid(printed, buffer_size, used_in_buffer)) { - return used_in_buffer; - } - used_in_buffer += printed; - - // Fill buffer with stack trace buckets of allocated regions. - used_in_buffer = SnapshotBucketTableWithoutMalloc(heap_profile_->alloc_table_, + // Fill buffer. + used_in_buffer = SnapshotBucketTableWithoutMalloc(deep_table_, used_in_buffer, buffer_size, buffer); @@ -445,19 +421,29 @@ void DeepHeapProfile::SnapshotGlobalStatsWithoutMalloc(int pagemap_fd, } } +// This hash function is from heap-profile-table:GetBucket. +// static +void DeepHeapProfile::AddIntegerToHashValue( + uintptr_t add, uintptr_t* hash_value) { + *hash_value += add; + *hash_value += *hash_value << 10; + *hash_value ^= *hash_value >> 6; +} + // GetDeepBucket is implemented as almost copy of heap-profile-table:GetBucket. // It's to avoid modifying heap-profile-table. Performance issues can be // ignored in usual Chromium runs. Another hash function can be tried in an // easy way in future. DeepHeapProfile::DeepBucket* DeepHeapProfile::GetDeepBucket( - Bucket* bucket, DeepBucket **table) { + Bucket* bucket, bool is_mmap, DeepBucket **table) { // Make hash-value uintptr_t h = 0; - h += reinterpret_cast<uintptr_t>(bucket); - h += h << 10; - h ^= h >> 6; - // Repeat the three lines for other values if required. + AddIntegerToHashValue(reinterpret_cast<uintptr_t>(bucket), &h); + if (is_mmap) + AddIntegerToHashValue(1, &h); + else + AddIntegerToHashValue(0, &h); h += h << 3; h ^= h >> 11; @@ -476,6 +462,7 @@ DeepHeapProfile::DeepBucket* DeepHeapProfile::GetDeepBucket( memset(db, 0, sizeof(*db)); db->bucket = bucket; db->committed_size = 0; + db->is_mmap = is_mmap; db->id = (bucket_id_++); db->is_logged = false; db->next = table[buck]; @@ -483,30 +470,29 @@ DeepHeapProfile::DeepBucket* DeepHeapProfile::GetDeepBucket( return db; } -void DeepHeapProfile::ResetCommittedSize(Bucket** bucket_table) { +void DeepHeapProfile::ResetCommittedSize(DeepBucket** deep_table) { for (int i = 0; i < kHashTableSize; i++) { - for (Bucket* bucket = bucket_table[i]; - bucket != NULL; - bucket = bucket->next) { - DeepBucket* deep_bucket = GetDeepBucket(bucket, deep_table_); + for (DeepBucket* deep_bucket = deep_table[i]; + deep_bucket != NULL; + deep_bucket = deep_bucket->next) { deep_bucket->committed_size = 0; } } } // TODO(dmikurube): Eliminate dynamic memory allocation caused by snprintf. -int DeepHeapProfile::SnapshotBucketTableWithoutMalloc(Bucket** bucket_table, +int DeepHeapProfile::SnapshotBucketTableWithoutMalloc(DeepBucket** deep_table, int used_in_buffer, int buffer_size, char buffer[]) { for (int i = 0; i < kHashTableSize; i++) { - for (Bucket* bucket = bucket_table[i]; - bucket != NULL; - bucket = bucket->next) { + for (DeepBucket* deep_bucket = deep_table[i]; + deep_bucket != NULL; + deep_bucket = deep_bucket->next) { + Bucket* bucket = deep_bucket->bucket; if (bucket->alloc_size - bucket->free_size == 0) { continue; // Skip empty buckets. } - const DeepBucket* deep_bucket = GetDeepBucket(bucket, deep_table_); used_in_buffer = UnparseBucket( *deep_bucket, "", used_in_buffer, buffer_size, buffer, NULL); } @@ -535,7 +521,7 @@ void DeepHeapProfile::RecordAlloc(const void* pointer, address, address + alloc_value->bytes - 1); DeepBucket* deep_bucket = deep_profile->GetDeepBucket( - alloc_value->bucket(), deep_profile->deep_table_); + alloc_value->bucket(), /* is_mmap */ false, deep_profile->deep_table_); deep_bucket->committed_size += committed; deep_profile->stats_.profiled_malloc.AddToVirtualBytes(alloc_value->bytes); deep_profile->stats_.profiled_malloc.AddToCommittedBytes(committed); @@ -549,7 +535,7 @@ void DeepHeapProfile::RecordMMap(const void* pointer, address, address + alloc_value->bytes - 1); DeepBucket* deep_bucket = deep_profile->GetDeepBucket( - alloc_value->bucket(), deep_profile->deep_table_); + alloc_value->bucket(), /* is_mmap */ true, deep_profile->deep_table_); deep_bucket->committed_size += committed; deep_profile->stats_.profiled_mmap.AddToVirtualBytes(alloc_value->bytes); deep_profile->stats_.profiled_mmap.AddToCommittedBytes(committed); @@ -590,6 +576,13 @@ int DeepHeapProfile::FillBucketForBucketFile(const DeepBucket* deep_bucket, } int used_in_buffer = printed; + printed = snprintf(buffer + used_in_buffer, buffer_size - used_in_buffer, + " %s", deep_bucket->is_mmap ? "mmap" : "malloc"); + if (IsPrintedStringValid(printed, buffer_size, used_in_buffer)) { + return used_in_buffer; + } + used_in_buffer += printed; + for (int depth = 0; depth < bucket->depth; depth++) { printed = snprintf(buffer + used_in_buffer, buffer_size - used_in_buffer, " 0x%08" PRIxPTR, @@ -609,7 +602,7 @@ int DeepHeapProfile::FillBucketForBucketFile(const DeepBucket* deep_bucket, return used_in_buffer; } -void DeepHeapProfile::WriteBucketsTableToBucketFile(Bucket** bucket_table, +void DeepHeapProfile::WriteBucketsTableToBucketFile(DeepBucket** deep_table, RawFD bucket_fd) { // We will use the global buffer here. char* buffer = profiler_buffer_; @@ -617,10 +610,10 @@ void DeepHeapProfile::WriteBucketsTableToBucketFile(Bucket** bucket_table, int used_in_buffer = 0; for (int i = 0; i < kHashTableSize; i++) { - for (Bucket* bucket = bucket_table[i]; - bucket != NULL; - bucket = bucket->next) { - DeepBucket* deep_bucket = GetDeepBucket(bucket, deep_table_); + for (DeepBucket* deep_bucket = deep_table[i]; + deep_bucket != NULL; + deep_bucket = deep_bucket->next) { + Bucket* bucket = deep_bucket->bucket; if (deep_bucket->is_logged) { continue; // Skip the bucket if it is already logged. } @@ -650,8 +643,7 @@ void DeepHeapProfile::WriteBucketsToBucketFile() { RawFD bucket_fd = RawOpenForWriting(filename); RAW_DCHECK(bucket_fd != kIllegalRawFD, ""); - WriteBucketsTableToBucketFile(heap_profile_->alloc_table_, bucket_fd); - WriteBucketsTableToBucketFile(heap_profile_->mmap_table_, bucket_fd); + WriteBucketsTableToBucketFile(deep_table_, bucket_fd); RawClose(bucket_fd); } diff --git a/third_party/tcmalloc/chromium/src/deep-heap-profile.h b/third_party/tcmalloc/chromium/src/deep-heap-profile.h index 6e65a0b..5a5ae8e 100644 --- a/third_party/tcmalloc/chromium/src/deep-heap-profile.h +++ b/third_party/tcmalloc/chromium/src/deep-heap-profile.h @@ -88,6 +88,7 @@ class DeepHeapProfile { struct DeepBucket { Bucket* bucket; size_t committed_size; + bool is_mmap; int id; // Unique ID of the bucket. bool is_logged; // True if the stracktrace is logged to a file. DeepBucket* next; // Next entry in hash-table. @@ -201,17 +202,21 @@ class DeepHeapProfile { MMapListEntry* mmap_list, int mmap_list_length); + // Add a uintptr_t integer to a hash-value for GetDeepBucket. + inline static void AddIntegerToHashValue( + uintptr_t add, uintptr_t* hash_value); + // Get the DeepBucket object corresponding to the given |bucket|. // DeepBucket is an extension to Bucket which is declared above. - DeepBucket* GetDeepBucket(Bucket* bucket, DeepBucket** table); + DeepBucket* GetDeepBucket(Bucket* bucket, bool is_mmap, DeepBucket** table); // Reset committed_size member variables in DeepBucket objects to 0. - void ResetCommittedSize(Bucket** bucket_table); + void ResetCommittedSize(DeepBucket** deep_table); // Fill bucket data in |bucket_table| into buffer |buffer| of size // |buffer_size|, and return the size occupied by the bucket data in // |buffer|. |bucket_length| is the offset for |buffer| to start filling. - int SnapshotBucketTableWithoutMalloc(Bucket** bucket_table, + int SnapshotBucketTableWithoutMalloc(DeepBucket** deep_table, int used_in_buffer, int buffer_size, char buffer[]); @@ -241,7 +246,7 @@ class DeepHeapProfile { char buffer[]); // Write a |bucket_table| into a file of |bucket_fd|. - void WriteBucketsTableToBucketFile(Bucket** bucket_table, RawFD bucket_fd); + void WriteBucketsTableToBucketFile(DeepBucket** deep_table, RawFD bucket_fd); // Write both malloc and mmap bucket tables into a "bucket file". void WriteBucketsToBucketFile(); |