| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "components/metrics/leak_detector/call_stack_table.h" | 5 #include "components/metrics/leak_detector/call_stack_table.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "components/metrics/leak_detector/call_stack_manager.h" | 9 #include "components/metrics/leak_detector/call_stack_manager.h" |
| 10 | 10 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 CallStackTable::CallStackTable(int call_stack_suspicion_threshold) | 35 CallStackTable::CallStackTable(int call_stack_suspicion_threshold) |
| 36 : num_allocs_(0), | 36 : num_allocs_(0), |
| 37 num_frees_(0), | 37 num_frees_(0), |
| 38 entry_map_(kInitialHashTableSize), | 38 entry_map_(kInitialHashTableSize), |
| 39 leak_analyzer_(kMaxCountOfSuspciousStacks, | 39 leak_analyzer_(kMaxCountOfSuspciousStacks, |
| 40 call_stack_suspicion_threshold) {} | 40 call_stack_suspicion_threshold) {} |
| 41 | 41 |
| 42 CallStackTable::~CallStackTable() {} | 42 CallStackTable::~CallStackTable() {} |
| 43 | 43 |
| 44 void CallStackTable::Add(const CallStack* call_stack) { | 44 void CallStackTable::Add(const CallStack* call_stack) { |
| 45 ++entry_map_[call_stack].count; | 45 ++entry_map_[call_stack]; |
| 46 ++num_allocs_; | 46 ++num_allocs_; |
| 47 } | 47 } |
| 48 | 48 |
| 49 void CallStackTable::Remove(const CallStack* call_stack) { | 49 void CallStackTable::Remove(const CallStack* call_stack) { |
| 50 auto iter = entry_map_.find(call_stack); | 50 auto iter = entry_map_.find(call_stack); |
| 51 if (iter == entry_map_.end()) | 51 if (iter == entry_map_.end()) |
| 52 return; | 52 return; |
| 53 uint32_t& count_for_call_stack = iter->second.count; | 53 uint32_t& count_for_call_stack = iter->second; |
| 54 --count_for_call_stack; | 54 --count_for_call_stack; |
| 55 ++num_frees_; | 55 ++num_frees_; |
| 56 | 56 |
| 57 // Delete zero-alloc entries to free up space. | 57 // Delete zero-alloc entries to free up space. |
| 58 if (count_for_call_stack == 0) | 58 if (count_for_call_stack == 0) |
| 59 entry_map_.erase(iter); | 59 entry_map_.erase(iter); |
| 60 } | 60 } |
| 61 | 61 |
| 62 void CallStackTable::TestForLeaks() { | 62 void CallStackTable::TestForLeaks() { |
| 63 // Add all entries to the ranked list. | 63 // Add all entries to the ranked list. |
| 64 RankedSet ranked_entries(kMaxCountOfSuspciousStacks); | 64 RankedSet ranked_entries(kMaxCountOfSuspciousStacks); |
| 65 GetTopCallStacks(&ranked_entries); | 65 GetTopCallStacks(&ranked_entries); |
| 66 leak_analyzer_.AddSample(std::move(ranked_entries)); | 66 leak_analyzer_.AddSample(std::move(ranked_entries)); |
| 67 } | 67 } |
| 68 | 68 |
| 69 void CallStackTable::GetTopCallStacks(RankedSet* top_entries) const { | 69 void CallStackTable::GetTopCallStacks(RankedSet* top_entries) const { |
| 70 for (const auto& call_stack_count_info : entry_map_) { | 70 for (const auto& call_stack_and_count : entry_map_) { |
| 71 top_entries->AddCallStack(call_stack_count_info.first, | 71 top_entries->AddCallStack(call_stack_and_count.first, |
| 72 call_stack_count_info.second.count); | 72 call_stack_and_count.second); |
| 73 } | 73 } |
| 74 } | 74 } |
| 75 | 75 |
| 76 void CallStackTable::UpdateLastDropInfo(size_t timestamp) { | |
| 77 for (auto& call_stack_and_info : entry_map_) { | |
| 78 auto& count_info = call_stack_and_info.second; | |
| 79 | |
| 80 // If the |previous_count| is 0 then we need to initialize info. | |
| 81 if (count_info.previous_count == 0 || | |
| 82 count_info.count < count_info.previous_count) { | |
| 83 count_info.last_drop_timestamp = timestamp; | |
| 84 count_info.last_drop_count = count_info.count; | |
| 85 } | |
| 86 count_info.previous_count = count_info.count; | |
| 87 } | |
| 88 } | |
| 89 | |
| 90 void CallStackTable::GetLastUptrendInfo( | |
| 91 const CallStack* call_stack, size_t timestamp, size_t* timestamp_delta, | |
| 92 uint32_t* count_delta) const { | |
| 93 const auto& call_stack_count_info_iter = entry_map_.find(call_stack); | |
| 94 | |
| 95 if (call_stack_count_info_iter != entry_map_.end()) { | |
| 96 const auto& count_info = call_stack_count_info_iter->second; | |
| 97 *timestamp_delta = timestamp - count_info.last_drop_timestamp; | |
| 98 *count_delta = count_info.count - count_info.last_drop_count; | |
| 99 } else { | |
| 100 DLOG(WARNING) << "Accessing information about a call stack that has not " | |
| 101 << "been recorded"; | |
| 102 *timestamp_delta = timestamp; | |
| 103 *count_delta = 0; | |
| 104 } | |
| 105 } | |
| 106 | |
| 107 } // namespace leak_detector | 76 } // namespace leak_detector |
| 108 } // namespace metrics | 77 } // namespace metrics |
| OLD | NEW |