Chromium Code Reviews| 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 |