Chromium Code Reviews| 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 #ifndef COMPONENTS_METRICS_LEAK_DETECTOR_LEAK_DETECTOR_IMPL_H_ | 5 #ifndef COMPONENTS_METRICS_LEAK_DETECTOR_LEAK_DETECTOR_IMPL_H_ |
| 6 #define COMPONENTS_METRICS_LEAK_DETECTOR_LEAK_DETECTOR_IMPL_H_ | 6 #define COMPONENTS_METRICS_LEAK_DETECTOR_LEAK_DETECTOR_IMPL_H_ |
| 7 | 7 |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 #include <stdint.h> | 9 #include <stdint.h> |
| 10 | 10 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 60 ~LeakReport(); | 60 ~LeakReport(); |
| 61 | 61 |
| 62 size_t alloc_size_bytes() const { return alloc_size_bytes_; } | 62 size_t alloc_size_bytes() const { return alloc_size_bytes_; } |
| 63 | 63 |
| 64 const InternalVector<uintptr_t>& call_stack() const { return call_stack_; } | 64 const InternalVector<uintptr_t>& call_stack() const { return call_stack_; } |
| 65 | 65 |
| 66 const InternalVector<AllocationBreakdown>& alloc_breakdown_history() const { | 66 const InternalVector<AllocationBreakdown>& alloc_breakdown_history() const { |
| 67 return alloc_breakdown_history_; | 67 return alloc_breakdown_history_; |
| 68 } | 68 } |
| 69 | 69 |
| 70 size_t num_rising_intervals() const { return num_rising_intervals_; } | |
| 71 | |
| 72 uint32_t num_allocs_increase() const { return num_allocs_increase_; } | |
| 73 | |
| 74 // Transform number of allocation events into number of analysis intervals. | |
| 75 void normalize_num_rising_intervals(size_t timeslot_size) { | |
|
Simon Que
2016/10/11 01:11:06
This is a bad design pattern because you could cal
mwlodar
2016/10/11 07:13:24
Done.
| |
| 76 num_rising_intervals_ /= timeslot_size; | |
| 77 } | |
| 78 | |
| 70 // Used to compare the contents of two leak reports. | 79 // Used to compare the contents of two leak reports. |
| 71 bool operator<(const LeakReport& other) const; | 80 bool operator<(const LeakReport& other) const; |
| 72 | 81 |
| 73 private: | 82 private: |
| 74 // LeakDetectorImpl needs access to class members when creating a new leak | 83 // LeakDetectorImpl needs access to class members when creating a new leak |
| 75 // report. | 84 // report. |
| 76 friend class LeakDetectorImpl; | 85 friend class LeakDetectorImpl; |
| 77 | 86 |
| 78 // Number of bytes allocated by the leak site during each allocation. | 87 // Number of bytes allocated by the leak site during each allocation. |
| 79 size_t alloc_size_bytes_; | 88 size_t alloc_size_bytes_; |
| 80 | 89 |
| 90 // Number of intervals in the last uptrend. | |
| 91 size_t num_rising_intervals_; | |
| 92 | |
| 93 // Net number of bytes allocated in the last uptrend. | |
| 94 uint32_t num_allocs_increase_; | |
| 95 | |
| 81 // Unlike the CallStack struct, which consists of addresses, this call stack | 96 // Unlike the CallStack struct, which consists of addresses, this call stack |
| 82 // will contain offsets in the executable binary. | 97 // will contain offsets in the executable binary. |
| 83 InternalVector<uintptr_t> call_stack_; | 98 InternalVector<uintptr_t> call_stack_; |
| 84 | 99 |
| 85 // Records of allocation bookkeeping over time. The first element is the | 100 // Records of allocation bookkeeping over time. The first element is the |
| 86 // oldest entry and the last element is the newest. | 101 // oldest entry and the last element is the newest. |
| 87 InternalVector<AllocationBreakdown> alloc_breakdown_history_; | 102 InternalVector<AllocationBreakdown> alloc_breakdown_history_; |
| 88 }; | 103 }; |
| 89 | 104 |
| 90 LeakDetectorImpl(uintptr_t mapping_addr, | 105 LeakDetectorImpl(uintptr_t mapping_addr, |
| 91 size_t mapping_size, | 106 size_t mapping_size, |
| 92 int size_suspicion_threshold, | 107 int size_suspicion_threshold, |
| 93 int call_stack_suspicion_threshold); | 108 int call_stack_suspicion_threshold); |
| 94 ~LeakDetectorImpl(); | 109 ~LeakDetectorImpl(); |
| 95 | 110 |
| 96 // Indicates whether the given allocation size has an associated call stack | 111 // Indicates whether the given allocation size has an associated call stack |
| 97 // table, and thus requires a stack unwind. | 112 // table, and thus requires a stack unwind. |
| 98 bool ShouldGetStackTraceForSize(size_t size) const; | 113 bool ShouldGetStackTraceForSize(size_t size) const; |
| 99 | 114 |
| 100 // Record allocs and frees. | 115 // Record allocs and frees. |
| 101 void RecordAlloc(const void* ptr, | 116 void RecordAlloc(const void* ptr, |
| 102 size_t size, | 117 size_t size, |
| 103 int stack_depth, | 118 int stack_depth, |
| 104 const void* const call_stack[]); | 119 const void* const call_stack[]); |
| 105 void RecordFree(const void* ptr); | 120 void RecordFree(const void* ptr); |
| 106 | 121 |
| 107 // Run check for possible leaks based on the current profiling data. | 122 // Run check for possible leaks based on the current profiling data. |
| 108 void TestForLeaks(InternalVector<LeakReport>* reports); | 123 void TestForLeaks(InternalVector<LeakReport>* reports, size_t timestamp); |
|
Simon Que
2016/10/11 01:11:06
Explain the role of |timestamp| in the comments.
mwlodar
2016/10/11 07:13:24
I have added comments below.
| |
| 109 | 124 |
| 110 private: | 125 private: |
| 111 // A record of allocations for a particular size. | 126 // A record of allocations for a particular size. |
| 112 struct AllocSizeEntry { | 127 struct AllocSizeEntry { |
| 113 // Number of allocations and frees for this size. | 128 // Number of allocations and frees for this size. |
| 114 uint32_t num_allocs; | 129 uint32_t num_allocs; |
| 115 uint32_t num_frees; | 130 uint32_t num_frees; |
| 116 | 131 |
| 117 // A stack table, if this size is being profiled for stack as well. | 132 // A stack table, if this size is being profiled for stack as well. |
| 118 CallStackTable* stack_table; | 133 CallStackTable* stack_table; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 157 uintptr_t GetOffset(const void* ptr) const; | 172 uintptr_t GetOffset(const void* ptr) const; |
| 158 | 173 |
| 159 // Record some of the current allocation bookkeeping. The net number of allocs | 174 // Record some of the current allocation bookkeeping. The net number of allocs |
| 160 // per size is recorded in |size_breakdown_history_|. The net number of allocs | 175 // per size is recorded in |size_breakdown_history_|. The net number of allocs |
| 161 // per call site for each size is recorded in | 176 // per call site for each size is recorded in |
| 162 // |AllocSizeEntry::call_site_breakdown_history|. | 177 // |AllocSizeEntry::call_site_breakdown_history|. |
| 163 // | 178 // |
| 164 // Not all the net alloc counts are recorded. And the number of historical | 179 // Not all the net alloc counts are recorded. And the number of historical |
| 165 // records kept is capped. If adding a new record exceeds that limit, the | 180 // records kept is capped. If adding a new record exceeds that limit, the |
| 166 // oldest record is discarded. See the function definition for more details. | 181 // oldest record is discarded. See the function definition for more details. |
| 167 void RecordCurrentAllocationDataInHistory(); | 182 void RecordCurrentAllocationDataInHistory(size_t timestamp); |
| 168 | 183 |
| 169 // Store the data collected by RecordCurrentAllocationDataInHistory() in | 184 // Store the data collected by RecordCurrentAllocationDataInHistory() in |
| 170 // |*report|. Not all net alloc counts per call site will be stored, only the | 185 // |*report|. Not all net alloc counts per call site will be stored, only the |
| 171 // count for size=|size| and made from |call_site|. | 186 // count for size=|size| and made from |call_site|. |
| 172 void StoreHistoricalDataInReport(size_t size, const CallStack* call_site, | 187 void StoreHistoricalDataInReport(size_t size, const CallStack* call_site, |
| 173 LeakReport* report); | 188 LeakReport* report, size_t timestamp); |
| 174 | 189 |
| 175 // Decrements the cooldown counter (value) for each entry in | 190 // Decrements the cooldown counter (value) for each entry in |
| 176 // |cooldowns_per_leak_|. If the cooldown counter reaches 0, the entry is | 191 // |cooldowns_per_leak_|. If the cooldown counter reaches 0, the entry is |
| 177 // removed. Thus, all extantentries in |cooldowns_per_leak_| maintain a | 192 // removed. Thus, all extantentries in |cooldowns_per_leak_| maintain a |
| 178 // positive count. | 193 // positive count. |
| 179 void UpdateLeakCooldowns(); | 194 void UpdateLeakCooldowns(); |
| 180 | 195 |
| 181 // Returns true if a particular leak signature (alloc size + call site) does | 196 // Returns true if a particular leak signature (alloc size + call site) does |
| 182 // not have an active cooldown counter (i.e. does not have an entry in | 197 // not have an active cooldown counter (i.e. does not have an entry in |
| 183 // |cooldowns_per_leak_|. | 198 // |cooldowns_per_leak_|. |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 235 // considered a leak suspect. | 250 // considered a leak suspect. |
| 236 int call_stack_suspicion_threshold_; | 251 int call_stack_suspicion_threshold_; |
| 237 | 252 |
| 238 DISALLOW_COPY_AND_ASSIGN(LeakDetectorImpl); | 253 DISALLOW_COPY_AND_ASSIGN(LeakDetectorImpl); |
| 239 }; | 254 }; |
| 240 | 255 |
| 241 } // namespace leak_detector | 256 } // namespace leak_detector |
| 242 } // namespace metrics | 257 } // namespace metrics |
| 243 | 258 |
| 244 #endif // COMPONENTS_METRICS_LEAK_DETECTOR_LEAK_DETECTOR_IMPL_H_ | 259 #endif // COMPONENTS_METRICS_LEAK_DETECTOR_LEAK_DETECTOR_IMPL_H_ |
| OLD | NEW |