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_manager.h" | 5 #include "components/metrics/leak_detector/call_stack_manager.h" |
6 | 6 |
7 #include <algorithm> // For std::copy. | 7 #include <algorithm> // For std::copy. |
8 #include <new> | 8 #include <new> |
9 | 9 |
10 #include "base/hash.h" | 10 #include "base/hash.h" |
11 #include "components/metrics/leak_detector/custom_allocator.h" | 11 #include "components/metrics/leak_detector/custom_allocator.h" |
12 | 12 |
13 namespace metrics { | 13 namespace metrics { |
14 namespace leak_detector { | 14 namespace leak_detector { |
15 | 15 |
16 CallStackManager::CallStackManager() {} | 16 CallStackManager::CallStackManager() {} |
17 | 17 |
18 CallStackManager::~CallStackManager() { | 18 CallStackManager::~CallStackManager() { |
19 for (CallStack* call_stack : call_stacks_) { | 19 // Free all call stack objects and clear |call_stacks_|. Make sure to save the |
| 20 // CallStack object pointer and remove it from the container before freeing |
| 21 // the CallStack memory. |
| 22 while (!call_stacks_.empty()) { |
| 23 CallStack* call_stack = *call_stacks_.begin(); |
| 24 call_stacks_.erase(call_stacks_.begin()); |
| 25 |
20 CustomAllocator::Free(call_stack->stack, | 26 CustomAllocator::Free(call_stack->stack, |
21 call_stack->depth * sizeof(*call_stack->stack)); | 27 call_stack->depth * sizeof(*call_stack->stack)); |
22 call_stack->stack = nullptr; | 28 call_stack->stack = nullptr; |
23 call_stack->depth = 0; | 29 call_stack->depth = 0; |
24 | 30 |
25 CustomAllocator::Free(call_stack, sizeof(CallStack)); | 31 CustomAllocator::Free(call_stack, sizeof(CallStack)); |
26 } | 32 } |
27 call_stacks_.clear(); | |
28 } | 33 } |
29 | 34 |
30 const CallStack* CallStackManager::GetCallStack(size_t depth, | 35 const CallStack* CallStackManager::GetCallStack(size_t depth, |
31 const void* const stack[]) { | 36 const void* const stack[]) { |
32 // Temporarily create a call stack object for lookup in |call_stacks_|. | 37 // Temporarily create a call stack object for lookup in |call_stacks_|. |
33 CallStack temp; | 38 CallStack temp; |
34 temp.depth = depth; | 39 temp.depth = depth; |
35 temp.stack = const_cast<const void**>(stack); | 40 temp.stack = const_cast<const void**>(stack); |
36 // This is the only place where the call stack's hash is computed. This value | 41 // This is the only place where the call stack's hash is computed. This value |
37 // can be reused in the created object to avoid further hash computation. | 42 // can be reused in the created object to avoid further hash computation. |
(...skipping 20 matching lines...) Expand all Loading... |
58 | 63 |
59 bool CallStackManager::CallStackPointerEqual::operator()( | 64 bool CallStackManager::CallStackPointerEqual::operator()( |
60 const CallStack* c1, | 65 const CallStack* c1, |
61 const CallStack* c2) const { | 66 const CallStack* c2) const { |
62 return c1->depth == c2->depth && c1->hash == c2->hash && | 67 return c1->depth == c2->depth && c1->hash == c2->hash && |
63 std::equal(c1->stack, c1->stack + c1->depth, c2->stack); | 68 std::equal(c1->stack, c1->stack + c1->depth, c2->stack); |
64 } | 69 } |
65 | 70 |
66 } // namespace leak_detector | 71 } // namespace leak_detector |
67 } // namespace metrics | 72 } // namespace metrics |
OLD | NEW |