diff options
Diffstat (limited to 'third_party')
-rw-r--r-- | third_party/tcmalloc/chromium/src/heap-profile-table.cc | 61 | ||||
-rw-r--r-- | third_party/tcmalloc/chromium/src/heap-profile-table.h | 30 | ||||
-rw-r--r-- | third_party/tcmalloc/chromium/src/heap-profiler.cc | 14 |
3 files changed, 105 insertions, 0 deletions
diff --git a/third_party/tcmalloc/chromium/src/heap-profile-table.cc b/third_party/tcmalloc/chromium/src/heap-profile-table.cc index dc7fc9c..0a2cf66 100644 --- a/third_party/tcmalloc/chromium/src/heap-profile-table.cc +++ b/third_party/tcmalloc/chromium/src/heap-profile-table.cc @@ -92,6 +92,9 @@ DEFINE_int32(heap_check_max_leaks, // header of the dumped heap profile static const char kProfileHeader[] = "heap profile: "; static const char kProcSelfMapsHeader[] = "\nMAPPED_LIBRARIES:\n"; +#if defined(TYPE_PROFILING) +static const char kTypeProfileStatsHeader[] = "type statistics:\n"; +#endif // defined(TYPE_PROFILING) //---------------------------------------------------------------------- @@ -418,6 +421,29 @@ void HeapProfileTable::DumpMarkedObjects(AllocationMark mark, RawClose(fd); } +#if defined(TYPE_PROFILING) +void HeapProfileTable::DumpTypeStatistics(const char* file_name) const { + RawFD fd = RawOpenForWriting(file_name); + if (fd == kIllegalRawFD) { + RAW_LOG(ERROR, "Failed dumping type statistics to %s", file_name); + return; + } + + AddressMap<TypeCount>* type_size_map; + type_size_map = new(alloc_(sizeof(AddressMap<TypeCount>))) + AddressMap<TypeCount>(alloc_, dealloc_); + alloc_address_map_->Iterate(TallyTypesItererator, type_size_map); + + RawWrite(fd, kTypeProfileStatsHeader, strlen(kTypeProfileStatsHeader)); + const DumpArgs args(fd, NULL); + type_size_map->Iterate<const DumpArgs&>(DumpTypesIterator, args); + RawClose(fd); + + type_size_map->~AddressMap<TypeCount>(); + dealloc_(type_size_map); +} +#endif // defined(TYPE_PROFILING) + void HeapProfileTable::IterateOrderedAllocContexts( AllocContextIterator callback) const { Bucket** list = MakeSortedBucketList(); @@ -475,6 +501,41 @@ int HeapProfileTable::FillOrderedProfile(char buf[], int size) const { return bucket_length + map_length; } +#if defined(TYPE_PROFILING) +// static +void HeapProfileTable::TallyTypesItererator( + const void* ptr, + AllocValue* value, + AddressMap<TypeCount>* type_size_map) { + const std::type_info* type = LookupType(ptr); + + const void* key = NULL; + if (type) + key = type->name(); + + TypeCount* count = type_size_map->FindMutable(key); + if (count) { + count->bytes += value->bytes; + ++count->objects; + } else { + type_size_map->Insert(key, TypeCount(value->bytes, 1)); + } +} + +// static +void HeapProfileTable::DumpTypesIterator(const void* ptr, + TypeCount* count, + const DumpArgs& args) { + char buf[1024]; + int len; + const char* mangled_type_name = static_cast<const char*>(ptr); + len = snprintf(buf, sizeof(buf), "%6d: %8"PRId64" @ %s\n", + count->objects, count->bytes, + mangled_type_name ? mangled_type_name : "(no_typeinfo)"); + RawWrite(args.fd, buf, len); +} +#endif // defined(TYPE_PROFILING) + inline void HeapProfileTable::DumpNonLiveIterator(const void* ptr, AllocValue* v, const DumpArgs& args) { diff --git a/third_party/tcmalloc/chromium/src/heap-profile-table.h b/third_party/tcmalloc/chromium/src/heap-profile-table.h index 34697a0..6a502c0 100644 --- a/third_party/tcmalloc/chromium/src/heap-profile-table.h +++ b/third_party/tcmalloc/chromium/src/heap-profile-table.h @@ -39,6 +39,10 @@ #include "base/basictypes.h" #include "base/logging.h" // for RawFD +#if defined(TYPE_PROFILING) +#include <gperftools/type_profiler_map.h> +#endif // defined(TYPE_PROFILING) + // Table to maintain a heap profile data inside, // i.e. the set of currently active heap memory allocations. // thread-unsafe and non-reentrant code: @@ -238,6 +242,10 @@ class HeapProfileTable { // used for leak checking (using HeapLeakChecker). void DumpMarkedObjects(AllocationMark mark, const char* file_name); +#if defined(TYPE_PROFILING) + void DumpTypeStatistics(const char* file_name) const; +#endif // defined(TYPE_PROFILING) + private: friend class DeepHeapProfile; @@ -321,6 +329,18 @@ class HeapProfileTable { MarkArgs(AllocationMark m, bool a) : mark(m), mark_all(a) { } }; +#if defined(TYPE_PROFILING) + struct TypeCount { + size_t bytes; + unsigned int objects; + + TypeCount(size_t bytes_arg, unsigned int objects_arg) + : bytes(bytes_arg), + objects(objects_arg) { + } + }; +#endif // defined(TYPE_PROFILING) + // helpers ---------------------------- // Unparse bucket b and print its portion of profile dump into buf. @@ -383,6 +403,16 @@ class HeapProfileTable { inline static void ZeroBucketCountsIterator( const void* ptr, AllocValue* v, HeapProfileTable* heap_profile); +#if defined(TYPE_PROFILING) + inline static void TallyTypesItererator(const void* ptr, + AllocValue* value, + AddressMap<TypeCount>* type_size_map); + + inline static void DumpTypesIterator(const void* ptr, + TypeCount* size, + const DumpArgs& args); +#endif // defined(TYPE_PROFILING) + // Helper for IterateOrderedAllocContexts and FillOrderedProfile. // Creates a sorted list of Buckets whose length is num_alloc_buckets_ + // num_avaliable_mmap_buckets_. diff --git a/third_party/tcmalloc/chromium/src/heap-profiler.cc b/third_party/tcmalloc/chromium/src/heap-profiler.cc index 1c5fcf0..04704f2 100644 --- a/third_party/tcmalloc/chromium/src/heap-profiler.cc +++ b/third_party/tcmalloc/chromium/src/heap-profiler.cc @@ -125,6 +125,11 @@ DEFINE_bool(only_mmap_profile, DEFINE_bool(deep_heap_profile, EnvToBool("DEEP_HEAP_PROFILE", false), "If heap-profiling is on, profile deeper (only on Linux)"); +#if defined(TYPE_PROFILING) +DEFINE_bool(heap_profile_type_statistics, + EnvToBool("HEAP_PROFILE_TYPE_STATISTICS", false), + "If heap-profiling is on, dump type statistics."); +#endif // defined(TYPE_PROFILING) //---------------------------------------------------------------------- @@ -305,6 +310,15 @@ static void DumpProfileLocked(const char* reason) { RawWrite(fd, profile, strlen(profile)); RawClose(fd); +#if defined(TYPE_PROFILING) + if (FLAGS_heap_profile_type_statistics) { + snprintf(file_name, sizeof(file_name), "%s.%05d.%04d.type", + filename_prefix, getpid(), dump_count); + RAW_VLOG(0, "Dumping type statistics to %s", file_name); + heap_profile->DumpTypeStatistics(file_name); + } +#endif // defined(TYPE_PROFILING) + dumping = false; } |