Chromium Code Reviews| Index: base/trace_event/memory_profiler_allocation_context.cc |
| diff --git a/base/trace_event/memory_profiler_allocation_context.cc b/base/trace_event/memory_profiler_allocation_context.cc |
| index 3aea93518c633aa667d1b21f0ff028ce1f117819..4d25d0f312a91af35c28b5bda16418694821d1b7 100644 |
| --- a/base/trace_event/memory_profiler_allocation_context.cc |
| +++ b/base/trace_event/memory_profiler_allocation_context.cc |
| @@ -4,6 +4,8 @@ |
| #include "base/trace_event/memory_profiler_allocation_context.h" |
| +#include <algorithm> |
| + |
| #include "base/threading/thread_local_storage.h" |
| namespace base { |
| @@ -75,16 +77,60 @@ void AllocationContextTracker::UnsetContextField(const char* key) { |
| tracker->context_.erase(key); |
| } |
| -// static |
| -AllocationStack* AllocationContextTracker::GetPseudoStackForTesting() { |
| - auto tracker = AllocationContextTracker::GetThreadLocalTracker(); |
| - return &tracker->pseudo_stack_; |
| +// 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
|
| +// length |N|, identical to C++11 |std::end|. |
| +template <typename T, int N> |
| +T* End(T(&array)[N]) { |
| + return array + N; |
| +} |
| + |
| +// Copies elements from the range (src, src_end) to (dst, dst_end) until either |
| +// the source range is exhausted, or until the destination range is full. Takes |
| +// |src| and |dst| by reference so that after calling this function they are |
| +// both advanced by the number of elements copied. |
| +template <typename SrcIterator, typename DstIterator> |
| +void Copy(SrcIterator& src, SrcIterator src_end, |
| + DstIterator& dst, DstIterator dst_end) { |
| + for (; src != src_end && dst != dst_end; src++, dst++) |
| + *dst = *src; |
| } |
| // static |
| 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.
|
| - // TODO(ruuda): Implement this in a follow-up CL. |
| - return AllocationContext(); |
| + 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.
|
| + AllocationContext ctx; |
| + |
| + // Fill the backtrace. |
| + { |
| + auto src = tracker->pseudo_stack_.top(); |
| + auto dst = ctx.backtrace.frames; |
| + auto src_end = tracker->pseudo_stack_.bottom(); |
| + auto dst_end = End(ctx.backtrace.frames); |
| + |
| + // Copy as much of the top of the pseudo stack into the backtrace as |
| + // possible. |
| + Copy(src, src_end, dst, dst_end); |
| + |
| + // If there is room for more, fill the remaining slots with empty frames. |
| + std::fill(dst, dst_end, nullptr); |
| + } |
| + |
| + // Fill the context fields. |
| + { |
| + auto src = tracker->context_.begin(); |
| + auto dst = ctx.fields; |
| + auto src_end = tracker->context_.end(); |
| + auto dst_end = End(ctx.fields); |
| + |
| + // Copy as much (key, value) pairs as possible. |
| + Copy(src, src_end, dst, dst_end); |
| + |
| + // If there is room for more, fill the remaining slots with nullptr keys. |
| + for (; dst != dst_end; dst++) |
| + dst->first = nullptr; |
| + } |
| + |
| + return ctx; |
| } |
| } // namespace trace_event |