Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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(const char* file_name) const { | |
| 426 RawFD fd = RawOpenForWriting(file_name); | |
| 427 if (fd == kIllegalRawFD) { | |
| 428 RAW_LOG(ERROR, "Failed dumping type statistics to %s", file_name); | |
| 429 return; | |
| 430 } | |
| 431 | |
| 432 AddressMap<TypeCount>* type_size_map; | |
| 433 type_size_map = new(alloc_(sizeof(AddressMap<TypeCount>))) | |
| 434 AddressMap<TypeCount>(alloc_, dealloc_); | |
| 435 alloc_address_map_->Iterate(CountUpTypeIterator, type_size_map); | |
| 436 | |
| 437 RawWrite(fd, kTypeProfileStatsHeader, strlen(kTypeProfileStatsHeader)); | |
| 438 const DumpArgs args(fd, NULL); | |
| 439 type_size_map->Iterate<const DumpArgs&>(DumpTypeIterator, args); | |
| 440 RawClose(fd); | |
| 441 | |
| 442 type_size_map->~AddressMap<TypeCount>(); | |
| 443 dealloc_(type_size_map); | |
| 444 } | |
| 445 #endif // defined(TYPE_PROFILING) | |
| 446 | |
| 421 void HeapProfileTable::IterateOrderedAllocContexts( | 447 void HeapProfileTable::IterateOrderedAllocContexts( |
| 422 AllocContextIterator callback) const { | 448 AllocContextIterator callback) const { |
| 423 Bucket** list = MakeSortedBucketList(); | 449 Bucket** list = MakeSortedBucketList(); |
| 424 AllocContextInfo info; | 450 AllocContextInfo info; |
| 425 for (int i = 0; i < num_alloc_buckets_; ++i) { | 451 for (int i = 0; i < num_alloc_buckets_; ++i) { |
| 426 *static_cast<Stats*>(&info) = *static_cast<Stats*>(list[i]); | 452 *static_cast<Stats*>(&info) = *static_cast<Stats*>(list[i]); |
| 427 info.stack_depth = list[i]->depth; | 453 info.stack_depth = list[i]->depth; |
| 428 info.call_stack = list[i]->stack; | 454 info.call_stack = list[i]->stack; |
| 429 callback(info); | 455 callback(info); |
| 430 } | 456 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 468 RAW_DCHECK(bucket_length < size, ""); | 494 RAW_DCHECK(bucket_length < size, ""); |
| 469 | 495 |
| 470 dealloc_(list); | 496 dealloc_(list); |
| 471 | 497 |
| 472 RAW_DCHECK(buf + bucket_length <= map_start, ""); | 498 RAW_DCHECK(buf + bucket_length <= map_start, ""); |
| 473 memmove(buf + bucket_length, map_start, map_length); // close the gap | 499 memmove(buf + bucket_length, map_start, map_length); // close the gap |
| 474 | 500 |
| 475 return bucket_length + map_length; | 501 return bucket_length + map_length; |
| 476 } | 502 } |
| 477 | 503 |
| 504 #if defined(TYPE_PROFILING) | |
| 505 // static | |
| 506 void HeapProfileTable::CountUpTypeIterator( | |
|
jar (doing other things)
2012/10/02 16:43:10
This name bothered me... and I finally have sugges
Dai Mikurube (NOT FULLTIME)
2012/10/03 03:41:28
Done.
| |
| 507 const void* ptr, | |
| 508 AllocValue* value, | |
| 509 AddressMap<TypeCount>* type_size_map) { | |
| 510 const std::type_info* type = LookupType(ptr); | |
| 511 | |
| 512 const void* key = NULL; | |
| 513 if (type) | |
| 514 key = type->name(); | |
| 515 | |
| 516 TypeCount* count = type_size_map->FindMutable(key); | |
| 517 if (count) { | |
| 518 count->bytes += value->bytes; | |
| 519 ++count->objects; | |
| 520 } else { | |
| 521 type_size_map->Insert(key, TypeCount(value->bytes, 1)); | |
| 522 } | |
| 523 } | |
| 524 | |
| 525 // static | |
| 526 void HeapProfileTable::DumpTypeIterator(const void* ptr, | |
|
jar (doing other things)
2012/10/02 16:43:10
Here just add an "s" to "Types" to create:
DumpTy
Dai Mikurube (NOT FULLTIME)
2012/10/03 03:41:28
Done.
| |
| 527 TypeCount* count, | |
| 528 const DumpArgs& args) { | |
| 529 char buf[1024]; | |
| 530 int len; | |
| 531 const char* mangled_type_name = static_cast<const char*>(ptr); | |
| 532 len = snprintf(buf, sizeof(buf), "%6d: %8"PRId64" @ %s\n", | |
| 533 count->objects, count->bytes, | |
| 534 mangled_type_name ? mangled_type_name : "(no_typeinfo)"); | |
| 535 RawWrite(args.fd, buf, len); | |
| 536 } | |
| 537 #endif // defined(TYPE_PROFILING) | |
| 538 | |
| 478 inline | 539 inline |
| 479 void HeapProfileTable::DumpNonLiveIterator(const void* ptr, AllocValue* v, | 540 void HeapProfileTable::DumpNonLiveIterator(const void* ptr, AllocValue* v, |
| 480 const DumpArgs& args) { | 541 const DumpArgs& args) { |
| 481 if (v->live()) { | 542 if (v->live()) { |
| 482 v->set_live(false); | 543 v->set_live(false); |
| 483 return; | 544 return; |
| 484 } | 545 } |
| 485 if (v->ignore()) { | 546 if (v->ignore()) { |
| 486 return; | 547 return; |
| 487 } | 548 } |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 737 char* unused) { | 798 char* unused) { |
| 738 // Perhaps also log the allocation stack trace (unsymbolized) | 799 // Perhaps also log the allocation stack trace (unsymbolized) |
| 739 // on this line in case somebody finds it useful. | 800 // on this line in case somebody finds it useful. |
| 740 RAW_LOG(ERROR, "leaked %"PRIuS" byte object %p", v->bytes, ptr); | 801 RAW_LOG(ERROR, "leaked %"PRIuS" byte object %p", v->bytes, ptr); |
| 741 } | 802 } |
| 742 | 803 |
| 743 void HeapProfileTable::Snapshot::ReportIndividualObjects() { | 804 void HeapProfileTable::Snapshot::ReportIndividualObjects() { |
| 744 char unused; | 805 char unused; |
| 745 map_.Iterate(ReportObject, &unused); | 806 map_.Iterate(ReportObject, &unused); |
| 746 } | 807 } |
| OLD | NEW |