Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(56)

Side by Side Diff: third_party/tcmalloc/chromium/src/heap-profile-table.cc

Issue 10830113: Dump type statistics of malloc'ed objects. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2006, Google Inc. 1 // Copyright (c) 2006, Google Inc.
2 // All rights reserved. 2 // All rights reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // * Redistributions of source code must retain the above copyright 8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer. 9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above 10 // * Redistributions in binary form must reproduce the above
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 85
86 DEFINE_int32(heap_check_max_leaks, 86 DEFINE_int32(heap_check_max_leaks,
87 EnvToInt("HEAP_CHECK_MAX_LEAKS", 20), 87 EnvToInt("HEAP_CHECK_MAX_LEAKS", 20),
88 "The maximum number of leak reports to print."); 88 "The maximum number of leak reports to print.");
89 89
90 //---------------------------------------------------------------------- 90 //----------------------------------------------------------------------
91 91
92 // header of the dumped heap profile 92 // header of the dumped heap profile
93 static const char kProfileHeader[] = "heap profile: "; 93 static const char kProfileHeader[] = "heap profile: ";
94 static const char kProcSelfMapsHeader[] = "\nMAPPED_LIBRARIES:\n"; 94 static const char kProcSelfMapsHeader[] = "\nMAPPED_LIBRARIES:\n";
95 #if defined(TYPE_PROFILING)
96 static const char kTypeProfileStatsHeader[] = "type statistics:\n";
97 #endif // defined(TYPE_PROFILING)
95 98
96 //---------------------------------------------------------------------- 99 //----------------------------------------------------------------------
97 100
98 const char HeapProfileTable::kFileExt[] = ".heap"; 101 const char HeapProfileTable::kFileExt[] = ".heap";
99 102
100 //---------------------------------------------------------------------- 103 //----------------------------------------------------------------------
101 104
102 // Size for alloc_table_ and mmap_table_. 105 // Size for alloc_table_ and mmap_table_.
103 static const int kHashTableSize = 179999; 106 static const int kHashTableSize = 179999;
104 /*static*/ const int HeapProfileTable::kMaxStackDepth; 107 /*static*/ const int HeapProfileTable::kMaxStackDepth;
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 RawFD fd = RawOpenForWriting(file_name); 414 RawFD fd = RawOpenForWriting(file_name);
412 if (fd == kIllegalRawFD) { 415 if (fd == kIllegalRawFD) {
413 RAW_LOG(ERROR, "Failed dumping live objects to %s", file_name); 416 RAW_LOG(ERROR, "Failed dumping live objects to %s", file_name);
414 return; 417 return;
415 } 418 }
416 const DumpMarkedArgs args(fd, mark); 419 const DumpMarkedArgs args(fd, mark);
417 alloc_address_map_->Iterate<const DumpMarkedArgs&>(DumpMarkedIterator, args); 420 alloc_address_map_->Iterate<const DumpMarkedArgs&>(DumpMarkedIterator, args);
418 RawClose(fd); 421 RawClose(fd);
419 } 422 }
420 423
424 #if defined(TYPE_PROFILING)
425 void HeapProfileTable::DumpTypeStatistics(
426 const char* file_name) const {
jar (doing other things) 2012/10/01 21:59:44 nit: does this need to wrap here?
Dai Mikurube (NOT FULLTIME) 2012/10/02 06:35:12 Ah, not. Removed the newline.
427 AddressMap<TypeCount>* type_size_map;
428 type_size_map = new(alloc_(sizeof(AddressMap<TypeCount>)))
429 AddressMap<TypeCount>(alloc_, dealloc_);
430
431 alloc_address_map_->Iterate(CountUpTypeIterator, type_size_map);
432
433 RawFD fd = RawOpenForWriting(file_name);
434 if (fd == kIllegalRawFD) {
435 RAW_LOG(ERROR, "Failed dumping type statistics to %s", file_name);
436 return;
jar (doing other things) 2012/10/01 21:59:44 probably want to destructor and dealloc_(type_size
Dai Mikurube (NOT FULLTIME) 2012/10/02 06:35:12 Chose your suggestion. Thanks.
437 }
438 RawWrite(fd, kTypeProfileStatsHeader, strlen(kTypeProfileStatsHeader));
439 const DumpArgs args(fd, NULL);
440 type_size_map->Iterate<const DumpArgs&>(DumpTypeIterator, args);
441 RawClose(fd);
442
443 type_size_map->~AddressMap<TypeCount>();
444 dealloc_(type_size_map);
445 }
446 #endif // defined(TYPE_PROFILING)
447
421 void HeapProfileTable::IterateOrderedAllocContexts( 448 void HeapProfileTable::IterateOrderedAllocContexts(
422 AllocContextIterator callback) const { 449 AllocContextIterator callback) const {
423 Bucket** list = MakeSortedBucketList(); 450 Bucket** list = MakeSortedBucketList();
424 AllocContextInfo info; 451 AllocContextInfo info;
425 for (int i = 0; i < num_alloc_buckets_; ++i) { 452 for (int i = 0; i < num_alloc_buckets_; ++i) {
426 *static_cast<Stats*>(&info) = *static_cast<Stats*>(list[i]); 453 *static_cast<Stats*>(&info) = *static_cast<Stats*>(list[i]);
427 info.stack_depth = list[i]->depth; 454 info.stack_depth = list[i]->depth;
428 info.call_stack = list[i]->stack; 455 info.call_stack = list[i]->stack;
429 callback(info); 456 callback(info);
430 } 457 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 RAW_DCHECK(bucket_length < size, ""); 495 RAW_DCHECK(bucket_length < size, "");
469 496
470 dealloc_(list); 497 dealloc_(list);
471 498
472 RAW_DCHECK(buf + bucket_length <= map_start, ""); 499 RAW_DCHECK(buf + bucket_length <= map_start, "");
473 memmove(buf + bucket_length, map_start, map_length); // close the gap 500 memmove(buf + bucket_length, map_start, map_length); // close the gap
474 501
475 return bucket_length + map_length; 502 return bucket_length + map_length;
476 } 503 }
477 504
505 #if defined(TYPE_PROFILING)
506 // static
507 void HeapProfileTable::CountUpTypeIterator(
508 const void* ptr,
509 AllocValue* value,
510 AddressMap<TypeCount>* type_size_map) {
511 const std::type_info* type = LookupType(ptr);
512
513 const void* key;
jar (doing other things) 2012/10/01 21:59:44 nit: initialize key to NULL here... then you don't
Dai Mikurube (NOT FULLTIME) 2012/10/02 06:35:12 Done.
514 if (type) {
515 // In new Application Binary Interface (ABI),
516 // type_info's Null-Terminated Byte String (NTBS) is unique.
jar (doing other things) 2012/10/01 21:59:44 I don't understand the significance of this commen
Dai Mikurube (NOT FULLTIME) 2012/10/02 06:35:12 Done.
517 key = type->name();
518 } else {
519 key = NULL;
520 }
521
522 TypeCount* count = type_size_map->FindMutable(key);
523 if (count) {
524 count->bytes += value->bytes;
525 ++count->objects;
526 } else {
527 type_size_map->Insert(key, TypeCount(value->bytes, 1));
528 }
529 }
530
531 // static
532 void HeapProfileTable::DumpTypeIterator(const void* ptr,
533 TypeCount* count,
534 const DumpArgs& args) {
535 char buf[1024];
536 int len;
537 const char* mangled_type_name = static_cast<const char*>(ptr);
538 len = snprintf(buf, sizeof(buf), "%6d: %8"PRId64" @ %s\n",
539 count->objects, count->bytes,
540 mangled_type_name ? mangled_type_name : "(no_typeinfo)");
541 RawWrite(args.fd, buf, len);
542 }
543 #endif // defined(TYPE_PROFILING)
544
478 inline 545 inline
479 void HeapProfileTable::DumpNonLiveIterator(const void* ptr, AllocValue* v, 546 void HeapProfileTable::DumpNonLiveIterator(const void* ptr, AllocValue* v,
480 const DumpArgs& args) { 547 const DumpArgs& args) {
481 if (v->live()) { 548 if (v->live()) {
482 v->set_live(false); 549 v->set_live(false);
483 return; 550 return;
484 } 551 }
485 if (v->ignore()) { 552 if (v->ignore()) {
486 return; 553 return;
487 } 554 }
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 char* unused) { 804 char* unused) {
738 // Perhaps also log the allocation stack trace (unsymbolized) 805 // Perhaps also log the allocation stack trace (unsymbolized)
739 // on this line in case somebody finds it useful. 806 // on this line in case somebody finds it useful.
740 RAW_LOG(ERROR, "leaked %"PRIuS" byte object %p", v->bytes, ptr); 807 RAW_LOG(ERROR, "leaked %"PRIuS" byte object %p", v->bytes, ptr);
741 } 808 }
742 809
743 void HeapProfileTable::Snapshot::ReportIndividualObjects() { 810 void HeapProfileTable::Snapshot::ReportIndividualObjects() {
744 char unused; 811 char unused;
745 map_.Iterate(ReportObject, &unused); 812 map_.Iterate(ReportObject, &unused);
746 } 813 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698