| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/tracked_objects.h" | 5 #include "base/tracked_objects.h" |
| 6 | 6 |
| 7 #include <math.h> | 7 #include <math.h> |
| 8 | 8 |
| 9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| 11 #include "base/string_util.h" | 11 #include "base/string_util.h" |
| 12 #include "base/stringprintf.h" |
| 12 | 13 |
| 13 using base::TimeDelta; | 14 using base::TimeDelta; |
| 14 | 15 |
| 15 namespace tracked_objects { | 16 namespace tracked_objects { |
| 16 | 17 |
| 17 // A TLS slot to the TrackRegistry for the current thread. | 18 // A TLS slot to the TrackRegistry for the current thread. |
| 18 // static | 19 // static |
| 19 TLSSlot ThreadData::tls_index_(base::LINKER_INITIALIZED); | 20 TLSSlot ThreadData::tls_index_(base::LINKER_INITIALIZED); |
| 20 | 21 |
| 21 // A global state variable to prevent repeated initialization during tests. | 22 // A global state variable to prevent repeated initialization during tests. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 46 | 47 |
| 47 void DeathData::AddDeathData(const DeathData& other) { | 48 void DeathData::AddDeathData(const DeathData& other) { |
| 48 count_ += other.count_; | 49 count_ += other.count_; |
| 49 life_duration_ += other.life_duration_; | 50 life_duration_ += other.life_duration_; |
| 50 square_duration_ += other.square_duration_; | 51 square_duration_ += other.square_duration_; |
| 51 } | 52 } |
| 52 | 53 |
| 53 void DeathData::Write(std::string* output) const { | 54 void DeathData::Write(std::string* output) const { |
| 54 if (!count_) | 55 if (!count_) |
| 55 return; | 56 return; |
| 56 if (1 == count_) | 57 if (1 == count_) { |
| 57 StringAppendF(output, "(1)Life in %dms ", AverageMsDuration()); | 58 base::StringAppendF(output, "(1)Life in %dms ", AverageMsDuration()); |
| 58 else | 59 } else { |
| 59 StringAppendF(output, "(%d)Lives %dms/life ", count_, AverageMsDuration()); | 60 base::StringAppendF(output, "(%d)Lives %dms/life ", |
| 61 count_, AverageMsDuration()); |
| 62 } |
| 60 } | 63 } |
| 61 | 64 |
| 62 void DeathData::Clear() { | 65 void DeathData::Clear() { |
| 63 count_ = 0; | 66 count_ = 0; |
| 64 life_duration_ = TimeDelta(); | 67 life_duration_ = TimeDelta(); |
| 65 square_duration_ = 0; | 68 square_duration_ = 0; |
| 66 } | 69 } |
| 67 | 70 |
| 68 //------------------------------------------------------------------------------ | 71 //------------------------------------------------------------------------------ |
| 69 BirthOnThread::BirthOnThread(const Location& location) | 72 BirthOnThread::BirthOnThread(const Location& location) |
| (...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 } | 534 } |
| 532 | 535 |
| 533 const std::string Snapshot::DeathThreadName() const { | 536 const std::string Snapshot::DeathThreadName() const { |
| 534 if (death_thread_) | 537 if (death_thread_) |
| 535 return death_thread_->ThreadName(); | 538 return death_thread_->ThreadName(); |
| 536 return "Still_Alive"; | 539 return "Still_Alive"; |
| 537 } | 540 } |
| 538 | 541 |
| 539 void Snapshot::Write(std::string* output) const { | 542 void Snapshot::Write(std::string* output) const { |
| 540 death_data_.Write(output); | 543 death_data_.Write(output); |
| 541 StringAppendF(output, "%s->%s ", | 544 base::StringAppendF(output, "%s->%s ", |
| 542 birth_->birth_thread()->ThreadName().c_str(), | 545 birth_->birth_thread()->ThreadName().c_str(), |
| 543 death_thread_->ThreadName().c_str()); | 546 death_thread_->ThreadName().c_str()); |
| 544 birth_->location().Write(true, true, output); | 547 birth_->location().Write(true, true, output); |
| 545 } | 548 } |
| 546 | 549 |
| 547 void Snapshot::Add(const Snapshot& other) { | 550 void Snapshot::Add(const Snapshot& other) { |
| 548 death_data_.AddDeathData(other.death_data_); | 551 death_data_.AddDeathData(other.death_data_); |
| 549 } | 552 } |
| 550 | 553 |
| 551 //------------------------------------------------------------------------------ | 554 //------------------------------------------------------------------------------ |
| 552 // DataCollector | 555 // DataCollector |
| 553 | 556 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 641 | 644 |
| 642 void Aggregation::AddBirthPlace(const Location& location) { | 645 void Aggregation::AddBirthPlace(const Location& location) { |
| 643 locations_[location]++; | 646 locations_[location]++; |
| 644 birth_files_[location.file_name()]++; | 647 birth_files_[location.file_name()]++; |
| 645 } | 648 } |
| 646 | 649 |
| 647 void Aggregation::Write(std::string* output) const { | 650 void Aggregation::Write(std::string* output) const { |
| 648 if (locations_.size() == 1) { | 651 if (locations_.size() == 1) { |
| 649 locations_.begin()->first.Write(true, true, output); | 652 locations_.begin()->first.Write(true, true, output); |
| 650 } else { | 653 } else { |
| 651 StringAppendF(output, "%" PRIuS " Locations. ", locations_.size()); | 654 base::StringAppendF(output, "%" PRIuS " Locations. ", locations_.size()); |
| 652 if (birth_files_.size() > 1) | 655 if (birth_files_.size() > 1) { |
| 653 StringAppendF(output, "%" PRIuS " Files. ", birth_files_.size()); | 656 base::StringAppendF(output, "%" PRIuS " Files. ", birth_files_.size()); |
| 654 else | 657 } else { |
| 655 StringAppendF(output, "All born in %s. ", | 658 base::StringAppendF(output, "All born in %s. ", |
| 656 birth_files_.begin()->first.c_str()); | 659 birth_files_.begin()->first.c_str()); |
| 660 } |
| 657 } | 661 } |
| 658 | 662 |
| 659 if (birth_threads_.size() > 1) | 663 if (birth_threads_.size() > 1) { |
| 660 StringAppendF(output, "%" PRIuS " BirthingThreads. ", | 664 base::StringAppendF(output, "%" PRIuS " BirthingThreads. ", |
| 661 birth_threads_.size()); | 665 birth_threads_.size()); |
| 662 else | 666 } else { |
| 663 StringAppendF(output, "All born on %s. ", | 667 base::StringAppendF(output, "All born on %s. ", |
| 664 birth_threads_.begin()->first->ThreadName().c_str()); | 668 birth_threads_.begin()->first->ThreadName().c_str()); |
| 669 } |
| 665 | 670 |
| 666 if (death_threads_.size() > 1) { | 671 if (death_threads_.size() > 1) { |
| 667 StringAppendF(output, "%" PRIuS " DeathThreads. ", death_threads_.size()); | 672 base::StringAppendF(output, "%" PRIuS " DeathThreads. ", |
| 673 death_threads_.size()); |
| 668 } else { | 674 } else { |
| 669 if (death_threads_.begin()->first) | 675 if (death_threads_.begin()->first) { |
| 670 StringAppendF(output, "All deleted on %s. ", | 676 base::StringAppendF(output, "All deleted on %s. ", |
| 671 death_threads_.begin()->first->ThreadName().c_str()); | 677 death_threads_.begin()->first->ThreadName().c_str()); |
| 672 else | 678 } else { |
| 673 output->append("All these objects are still alive."); | 679 output->append("All these objects are still alive."); |
| 680 } |
| 674 } | 681 } |
| 675 | 682 |
| 676 if (birth_count_ > 1) | 683 if (birth_count_ > 1) |
| 677 StringAppendF(output, "Births=%d ", birth_count_); | 684 base::StringAppendF(output, "Births=%d ", birth_count_); |
| 678 | 685 |
| 679 DeathData::Write(output); | 686 DeathData::Write(output); |
| 680 } | 687 } |
| 681 | 688 |
| 682 void Aggregation::Clear() { | 689 void Aggregation::Clear() { |
| 683 birth_count_ = 0; | 690 birth_count_ = 0; |
| 684 birth_files_.clear(); | 691 birth_files_.clear(); |
| 685 locations_.clear(); | 692 locations_.clear(); |
| 686 birth_threads_.clear(); | 693 birth_threads_.clear(); |
| 687 DeathData::Clear(); | 694 DeathData::Clear(); |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 962 SetSubgroupTiebreaker(BIRTH_LINE); | 969 SetSubgroupTiebreaker(BIRTH_LINE); |
| 963 | 970 |
| 964 return true; | 971 return true; |
| 965 } | 972 } |
| 966 | 973 |
| 967 bool Comparator::WriteSortGrouping(const Snapshot& sample, | 974 bool Comparator::WriteSortGrouping(const Snapshot& sample, |
| 968 std::string* output) const { | 975 std::string* output) const { |
| 969 bool wrote_data = false; | 976 bool wrote_data = false; |
| 970 switch (selector_) { | 977 switch (selector_) { |
| 971 case BIRTH_THREAD: | 978 case BIRTH_THREAD: |
| 972 StringAppendF(output, "All new on %s ", | 979 base::StringAppendF(output, "All new on %s ", |
| 973 sample.birth_thread()->ThreadName().c_str()); | 980 sample.birth_thread()->ThreadName().c_str()); |
| 974 wrote_data = true; | 981 wrote_data = true; |
| 975 break; | 982 break; |
| 976 | 983 |
| 977 case DEATH_THREAD: | 984 case DEATH_THREAD: |
| 978 if (sample.death_thread()) | 985 if (sample.death_thread()) { |
| 979 StringAppendF(output, "All deleted on %s ", | 986 base::StringAppendF(output, "All deleted on %s ", |
| 980 sample.DeathThreadName().c_str()); | 987 sample.DeathThreadName().c_str()); |
| 981 else | 988 } else { |
| 982 output->append("All still alive "); | 989 output->append("All still alive "); |
| 990 } |
| 983 wrote_data = true; | 991 wrote_data = true; |
| 984 break; | 992 break; |
| 985 | 993 |
| 986 case BIRTH_FILE: | 994 case BIRTH_FILE: |
| 987 StringAppendF(output, "All born in %s ", | 995 base::StringAppendF(output, "All born in %s ", |
| 988 sample.location().file_name()); | 996 sample.location().file_name()); |
| 989 break; | 997 break; |
| 990 | 998 |
| 991 case BIRTH_FUNCTION: | 999 case BIRTH_FUNCTION: |
| 992 output->append("All born in "); | 1000 output->append("All born in "); |
| 993 sample.location().WriteFunctionName(output); | 1001 sample.location().WriteFunctionName(output); |
| 994 output->push_back(' '); | 1002 output->push_back(' '); |
| 995 break; | 1003 break; |
| 996 | 1004 |
| 997 default: | 1005 default: |
| 998 break; | 1006 break; |
| 999 } | 1007 } |
| 1000 if (tiebreaker_ && !use_tiebreaker_for_sort_only_) { | 1008 if (tiebreaker_ && !use_tiebreaker_for_sort_only_) { |
| 1001 wrote_data |= tiebreaker_->WriteSortGrouping(sample, output); | 1009 wrote_data |= tiebreaker_->WriteSortGrouping(sample, output); |
| 1002 } | 1010 } |
| 1003 return wrote_data; | 1011 return wrote_data; |
| 1004 } | 1012 } |
| 1005 | 1013 |
| 1006 void Comparator::WriteSnapshot(const Snapshot& sample, | 1014 void Comparator::WriteSnapshot(const Snapshot& sample, |
| 1007 std::string* output) const { | 1015 std::string* output) const { |
| 1008 sample.death_data().Write(output); | 1016 sample.death_data().Write(output); |
| 1009 if (!(combined_selectors_ & BIRTH_THREAD) || | 1017 if (!(combined_selectors_ & BIRTH_THREAD) || |
| 1010 !(combined_selectors_ & DEATH_THREAD)) | 1018 !(combined_selectors_ & DEATH_THREAD)) |
| 1011 StringAppendF(output, "%s->%s ", | 1019 base::StringAppendF(output, "%s->%s ", |
| 1012 (combined_selectors_ & BIRTH_THREAD) ? "*" : | 1020 (combined_selectors_ & BIRTH_THREAD) ? "*" : |
| 1013 sample.birth().birth_thread()->ThreadName().c_str(), | 1021 sample.birth().birth_thread()->ThreadName().c_str(), |
| 1014 (combined_selectors_ & DEATH_THREAD) ? "*" : | 1022 (combined_selectors_ & DEATH_THREAD) ? "*" : |
| 1015 sample.DeathThreadName().c_str()); | 1023 sample.DeathThreadName().c_str()); |
| 1016 sample.birth().location().Write(!(combined_selectors_ & BIRTH_FILE), | 1024 sample.birth().location().Write(!(combined_selectors_ & BIRTH_FILE), |
| 1017 !(combined_selectors_ & BIRTH_FUNCTION), | 1025 !(combined_selectors_ & BIRTH_FUNCTION), |
| 1018 output); | 1026 output); |
| 1019 } | 1027 } |
| 1020 | 1028 |
| 1021 } // namespace tracked_objects | 1029 } // namespace tracked_objects |
| OLD | NEW |