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> | 7 #include <algorithm> |
8 #include <cstring> | 8 #include <cstring> |
9 | 9 |
10 #include "base/hash.h" | 10 #include "base/hash.h" |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 auto tracker = AllocationContextTracker::GetThreadLocalTracker(); | 146 auto tracker = AllocationContextTracker::GetThreadLocalTracker(); |
147 tracker->pseudo_stack_.push(frame); | 147 tracker->pseudo_stack_.push(frame); |
148 } | 148 } |
149 | 149 |
150 // static | 150 // static |
151 void AllocationContextTracker::PopPseudoStackFrame(StackFrame frame) { | 151 void AllocationContextTracker::PopPseudoStackFrame(StackFrame frame) { |
152 auto tracker = AllocationContextTracker::GetThreadLocalTracker(); | 152 auto tracker = AllocationContextTracker::GetThreadLocalTracker(); |
153 tracker->pseudo_stack_.pop(frame); | 153 tracker->pseudo_stack_.pop(frame); |
154 } | 154 } |
155 | 155 |
156 // static | |
157 void AllocationContextTracker::SetContextField(const char* key, | |
158 const char* value) { | |
159 auto tracker = AllocationContextTracker::GetThreadLocalTracker(); | |
160 tracker->context_[key] = value; | |
161 } | |
162 | |
163 // static | |
164 void AllocationContextTracker::UnsetContextField(const char* key) { | |
165 auto tracker = AllocationContextTracker::GetThreadLocalTracker(); | |
166 tracker->context_.erase(key); | |
167 } | |
168 | |
169 // Returns a pointer past the end of the fixed-size array |array| of |T| of | 156 // Returns a pointer past the end of the fixed-size array |array| of |T| of |
170 // length |N|, identical to C++11 |std::end|. | 157 // length |N|, identical to C++11 |std::end|. |
171 template <typename T, int N> | 158 template <typename T, int N> |
172 T* End(T(&array)[N]) { | 159 T* End(T(&array)[N]) { |
173 return array + N; | 160 return array + N; |
174 } | 161 } |
175 | 162 |
176 // static | 163 // static |
177 AllocationContext AllocationContextTracker::GetContextSnapshot() { | 164 AllocationContext AllocationContextTracker::GetContextSnapshot() { |
178 AllocationContextTracker* tracker = GetThreadLocalTracker(); | 165 AllocationContextTracker* tracker = GetThreadLocalTracker(); |
179 AllocationContext ctx; | 166 AllocationContext ctx; |
180 | 167 |
181 // Fill the backtrace. | 168 // Fill the backtrace. |
182 { | 169 { |
183 auto src = tracker->pseudo_stack_.bottom(); | 170 auto src = tracker->pseudo_stack_.bottom(); |
184 auto dst = ctx.backtrace.frames; | 171 auto dst = ctx.backtrace.frames; |
185 auto src_end = tracker->pseudo_stack_.top(); | 172 auto src_end = tracker->pseudo_stack_.top(); |
186 auto dst_end = End(ctx.backtrace.frames); | 173 auto dst_end = End(ctx.backtrace.frames); |
187 | 174 |
188 // Copy as much of the bottom of the pseudo stack into the backtrace as | 175 // Copy as much of the bottom of the pseudo stack into the backtrace as |
189 // possible. | 176 // possible. |
190 for (; src != src_end && dst != dst_end; src++, dst++) | 177 for (; src != src_end && dst != dst_end; src++, dst++) |
191 *dst = *src; | 178 *dst = *src; |
192 | 179 |
193 // If there is room for more, fill the remaining slots with empty frames. | 180 // If there is room for more, fill the remaining slots with empty frames. |
194 std::fill(dst, dst_end, nullptr); | 181 std::fill(dst, dst_end, nullptr); |
195 } | 182 } |
196 | 183 |
197 // Fill the context fields. | |
198 { | |
199 auto src = tracker->context_.begin(); | |
200 auto dst = ctx.fields; | |
201 auto src_end = tracker->context_.end(); | |
202 auto dst_end = End(ctx.fields); | |
203 | |
204 // Copy as much (key, value) pairs as possible. | |
205 for (; src != src_end && dst != dst_end; src++, dst++) | |
206 *dst = *src; | |
207 | |
208 // If there is room for more, fill the remaining slots with nullptr keys. | |
209 for (; dst != dst_end; dst++) | |
210 dst->first = nullptr; | |
211 } | |
212 | |
213 return ctx; | 184 return ctx; |
214 } | 185 } |
215 | 186 |
216 } // namespace trace_event | 187 } // namespace trace_event |
217 } // namespace base | 188 } // namespace base |
218 | 189 |
219 namespace BASE_HASH_NAMESPACE { | 190 namespace BASE_HASH_NAMESPACE { |
220 using base::trace_event::Backtrace; | 191 using base::trace_event::Backtrace; |
221 | 192 |
222 size_t hash<Backtrace>::operator()(const Backtrace& backtrace) const { | 193 size_t hash<Backtrace>::operator()(const Backtrace& backtrace) const { |
223 return base::SuperFastHash(reinterpret_cast<const char*>(backtrace.frames), | 194 return base::SuperFastHash(reinterpret_cast<const char*>(backtrace.frames), |
224 sizeof(backtrace.frames)); | 195 sizeof(backtrace.frames)); |
225 } | 196 } |
226 | 197 |
227 } // BASE_HASH_NAMESPACE | 198 } // BASE_HASH_NAMESPACE |
OLD | NEW |