| 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 dc7fc9c167fd289bbdf0cdc2c66d0565d48e0401..0a2cf66dab5ff32b3c824e77fd2686b649335455 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) {
|
|
|