Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/leak_detector.h" | 5 #include "components/metrics/leak_detector/leak_detector.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <algorithm> // For std::transform | |
|
Ilya Sherman
2016/04/13 00:07:12
nit: I'd omit the comment, since it's likely to dr
Ilya Sherman
2016/04/13 00:07:12
... though, actually, you don't seem to use std::t
Simon Que
2016/04/13 22:41:31
Yes, I forgot to delete it when I no longer used i
| |
| 10 | |
| 9 #include "base/allocator/allocator_extension.h" | 11 #include "base/allocator/allocator_extension.h" |
| 10 #include "base/bind.h" | 12 #include "base/bind.h" |
| 11 #include "base/lazy_instance.h" | 13 #include "base/lazy_instance.h" |
| 12 #include "base/logging.h" | 14 #include "base/logging.h" |
| 13 #include "base/numerics/safe_conversions.h" | 15 #include "base/numerics/safe_conversions.h" |
| 14 #include "base/threading/thread_local.h" | 16 #include "base/threading/thread_local.h" |
| 15 #include "components/metrics/leak_detector/custom_allocator.h" | 17 #include "components/metrics/leak_detector/custom_allocator.h" |
| 16 #include "components/metrics/leak_detector/leak_detector_impl.h" | 18 #include "components/metrics/leak_detector/leak_detector_impl.h" |
| 17 #include "content/public/browser/browser_thread.h" | 19 #include "content/public/browser/browser_thread.h" |
| 18 | 20 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 111 for (const InternalLeakReport& report : leak_reports) { | 113 for (const InternalLeakReport& report : leak_reports) { |
| 112 reports_for_observers->push_back(LeakReport()); | 114 reports_for_observers->push_back(LeakReport()); |
| 113 LeakReport* new_report = &reports_for_observers->back(); | 115 LeakReport* new_report = &reports_for_observers->back(); |
| 114 | 116 |
| 115 new_report->alloc_size_bytes = report.alloc_size_bytes(); | 117 new_report->alloc_size_bytes = report.alloc_size_bytes(); |
| 116 if (!report.call_stack().empty()) { | 118 if (!report.call_stack().empty()) { |
| 117 new_report->call_stack.resize(report.call_stack().size()); | 119 new_report->call_stack.resize(report.call_stack().size()); |
| 118 memcpy(new_report->call_stack.data(), report.call_stack().data(), | 120 memcpy(new_report->call_stack.data(), report.call_stack().data(), |
| 119 report.call_stack().size() * sizeof(report.call_stack()[0])); | 121 report.call_stack().size() * sizeof(report.call_stack()[0])); |
| 120 } | 122 } |
| 123 | |
| 124 new_report->alloc_breakdown_history.reserve( | |
| 125 report.alloc_breakdown_history().size()); | |
|
Ilya Sherman
2016/04/13 00:07:12
I think you can skip this reserve() call, unless t
Simon Que
2016/04/13 22:41:31
Done.
| |
| 126 for (const auto& entry : report.alloc_breakdown_history()) { | |
| 127 LeakReport::AllocationBreakdown new_entry; | |
| 128 new_entry.counts_by_size.reserve(entry.counts_by_size.size()); | |
|
Ilya Sherman
2016/04/13 00:07:12
Ditto here, especially since you write the vector
Simon Que
2016/04/13 22:41:31
Done.
| |
| 129 new_entry.counts_by_size.assign(entry.counts_by_size.begin(), | |
| 130 entry.counts_by_size.end()); | |
| 131 new_entry.count_for_call_stack = entry.count_for_call_stack; | |
| 132 new_report->alloc_breakdown_history.push_back(new_entry); | |
| 133 } | |
| 121 } | 134 } |
| 122 } | 135 } |
| 123 | 136 |
| 124 // The only instance of LeakDetector that should be used. | 137 // The only instance of LeakDetector that should be used. |
| 125 base::LazyInstance<LeakDetector>::Leaky g_instance = LAZY_INSTANCE_INITIALIZER; | 138 base::LazyInstance<LeakDetector>::Leaky g_instance = LAZY_INSTANCE_INITIALIZER; |
| 126 | 139 |
| 127 // Thread-specific data to be used by hook functions. | 140 // Thread-specific data to be used by hook functions. |
| 128 base::LazyInstance<base::ThreadLocalPointer<void>>::Leaky g_hook_data_tls = | 141 base::LazyInstance<base::ThreadLocalPointer<void>>::Leaky g_hook_data_tls = |
| 129 LAZY_INSTANCE_INITIALIZER; | 142 LAZY_INSTANCE_INITIALIZER; |
| 130 | 143 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 146 inline void StoreHookDataToTLS(HookData hook_data) { | 159 inline void StoreHookDataToTLS(HookData hook_data) { |
| 147 // NOTE: |alloc_size| loses its upper bit when it gets stored in the TLS here. | 160 // NOTE: |alloc_size| loses its upper bit when it gets stored in the TLS here. |
| 148 // The effective max value of |alloc_size| is thus half its nominal max value. | 161 // The effective max value of |alloc_size| is thus half its nominal max value. |
| 149 uintptr_t ptr_value = | 162 uintptr_t ptr_value = |
| 150 (hook_data.entered_hook ? 1 : 0) | (hook_data.alloc_size << 1); | 163 (hook_data.entered_hook ? 1 : 0) | (hook_data.alloc_size << 1); |
| 151 g_hook_data_tls.Get().Set(reinterpret_cast<void*>(ptr_value)); | 164 g_hook_data_tls.Get().Set(reinterpret_cast<void*>(ptr_value)); |
| 152 } | 165 } |
| 153 | 166 |
| 154 } // namespace | 167 } // namespace |
| 155 | 168 |
| 169 LeakDetector::LeakReport::AllocationBreakdown::AllocationBreakdown() | |
| 170 : count_for_call_stack(0) {} | |
| 171 | |
| 172 LeakDetector::LeakReport::AllocationBreakdown::~AllocationBreakdown() {} | |
| 173 | |
| 156 LeakDetector::LeakReport::LeakReport() {} | 174 LeakDetector::LeakReport::LeakReport() {} |
| 157 | 175 |
| 158 LeakDetector::LeakReport::~LeakReport() {} | 176 LeakDetector::LeakReport::~LeakReport() {} |
| 159 | 177 |
| 160 // static | 178 // static |
| 161 LeakDetector* LeakDetector::GetInstance() { | 179 LeakDetector* LeakDetector::GetInstance() { |
| 162 return g_instance.Pointer(); | 180 return g_instance.Pointer(); |
| 163 } | 181 } |
| 164 | 182 |
| 165 void LeakDetector::Init(float sampling_rate, | 183 void LeakDetector::Init(float sampling_rate, |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 329 return; | 347 return; |
| 330 } | 348 } |
| 331 | 349 |
| 332 for (const LeakReport& report : reports) { | 350 for (const LeakReport& report : reports) { |
| 333 base::AutoLock lock(observers_lock_); | 351 base::AutoLock lock(observers_lock_); |
| 334 FOR_EACH_OBSERVER(Observer, observers_, OnLeakFound(report)); | 352 FOR_EACH_OBSERVER(Observer, observers_, OnLeakFound(report)); |
| 335 } | 353 } |
| 336 } | 354 } |
| 337 | 355 |
| 338 } // namespace metrics | 356 } // namespace metrics |
| OLD | NEW |