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 "base/trace_event/memory_profiler_allocation_context.h" | 5 #include "base/trace_event/memory_profiler_allocation_context.h" |
6 | 6 |
7 #include <algorithm> | |
8 | |
7 #include "base/threading/thread_local_storage.h" | 9 #include "base/threading/thread_local_storage.h" |
8 | 10 |
9 namespace base { | 11 namespace base { |
10 namespace trace_event { | 12 namespace trace_event { |
11 | 13 |
12 subtle::Atomic32 AllocationContextTracker::capture_enabled_ = 0; | 14 subtle::Atomic32 AllocationContextTracker::capture_enabled_ = 0; |
13 | 15 |
14 namespace { | 16 namespace { |
15 ThreadLocalStorage::StaticSlot g_tls_alloc_ctx_tracker = TLS_INITIALIZER; | 17 ThreadLocalStorage::StaticSlot g_tls_alloc_ctx_tracker = TLS_INITIALIZER; |
16 } | 18 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
68 auto tracker = AllocationContextTracker::GetThreadLocalTracker(); | 70 auto tracker = AllocationContextTracker::GetThreadLocalTracker(); |
69 tracker->context_[key] = value; | 71 tracker->context_[key] = value; |
70 } | 72 } |
71 | 73 |
72 // static | 74 // static |
73 void AllocationContextTracker::UnsetContextField(const char* key) { | 75 void AllocationContextTracker::UnsetContextField(const char* key) { |
74 auto tracker = AllocationContextTracker::GetThreadLocalTracker(); | 76 auto tracker = AllocationContextTracker::GetThreadLocalTracker(); |
75 tracker->context_.erase(key); | 77 tracker->context_.erase(key); |
76 } | 78 } |
77 | 79 |
78 // static | 80 // Returns a pointer past the end of the fixed-size array |array| of |T| of |
Primiano Tucci (use gerrit)
2015/10/05 12:35:38
Hmm all this template magic makes this file very h
Ruud van Asseldonk
2015/10/05 14:20:44
Agreed, done, though see also comment #4. I did ke
| |
79 AllocationStack* AllocationContextTracker::GetPseudoStackForTesting() { | 81 // length |N|, identical to C++11 |std::end|. |
80 auto tracker = AllocationContextTracker::GetThreadLocalTracker(); | 82 template <typename T, int N> |
81 return &tracker->pseudo_stack_; | 83 T* End(T(&array)[N]) { |
84 return array + N; | |
85 } | |
86 | |
87 // Copies elements from the range (src, src_end) to (dst, dst_end) until either | |
88 // the source range is exhausted, or until the destination range is full. Takes | |
89 // |src| and |dst| by reference so that after calling this function they are | |
90 // both advanced by the number of elements copied. | |
91 template <typename SrcIterator, typename DstIterator> | |
92 void Copy(SrcIterator& src, SrcIterator src_end, | |
93 DstIterator& dst, DstIterator dst_end) { | |
94 for (; src != src_end && dst != dst_end; src++, dst++) | |
95 *dst = *src; | |
82 } | 96 } |
83 | 97 |
84 // static | 98 // static |
85 AllocationContext AllocationContextTracker::GetContext() { | 99 AllocationContext AllocationContextTracker::GetContext() { |
Primiano Tucci (use gerrit)
2015/10/05 12:35:38
Maybe you could rename this to GetContextSnapshot(
Ruud van Asseldonk
2015/10/05 14:20:44
Done.
| |
86 // TODO(ruuda): Implement this in a follow-up CL. | 100 auto tracker = GetThreadLocalTracker(); |
Primiano Tucci (use gerrit)
2015/10/05 12:35:38
AllocationContextTracker* tracker = GetThreadLocal
Ruud van Asseldonk
2015/10/05 14:20:44
Done.
| |
87 return AllocationContext(); | 101 AllocationContext ctx; |
102 | |
103 // Fill the backtrace. | |
104 { | |
105 auto src = tracker->pseudo_stack_.top(); | |
106 auto dst = ctx.backtrace.frames; | |
107 auto src_end = tracker->pseudo_stack_.bottom(); | |
108 auto dst_end = End(ctx.backtrace.frames); | |
109 | |
110 // Copy as much of the top of the pseudo stack into the backtrace as | |
111 // possible. | |
112 Copy(src, src_end, dst, dst_end); | |
113 | |
114 // If there is room for more, fill the remaining slots with empty frames. | |
115 std::fill(dst, dst_end, nullptr); | |
116 } | |
117 | |
118 // Fill the context fields. | |
119 { | |
120 auto src = tracker->context_.begin(); | |
121 auto dst = ctx.fields; | |
122 auto src_end = tracker->context_.end(); | |
123 auto dst_end = End(ctx.fields); | |
124 | |
125 // Copy as much (key, value) pairs as possible. | |
126 Copy(src, src_end, dst, dst_end); | |
127 | |
128 // If there is room for more, fill the remaining slots with nullptr keys. | |
129 for (; dst != dst_end; dst++) | |
130 dst->first = nullptr; | |
131 } | |
132 | |
133 return ctx; | |
88 } | 134 } |
89 | 135 |
90 } // namespace trace_event | 136 } // namespace trace_event |
91 } // namespace base | 137 } // namespace base |
OLD | NEW |