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/heap_profiler_allocation_context_tracker.h" | 5 #include "base/trace_event/heap_profiler_allocation_context_tracker.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <iterator> | 8 #include <iterator> |
9 | 9 |
10 #include "base/atomicops.h" | 10 #include "base/atomicops.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 ThreadLocalStorage::StaticSlot g_tls_alloc_ctx_tracker = TLS_INITIALIZER; | 25 ThreadLocalStorage::StaticSlot g_tls_alloc_ctx_tracker = TLS_INITIALIZER; |
26 | 26 |
27 // This function is added to the TLS slot to clean up the instance when the | 27 // This function is added to the TLS slot to clean up the instance when the |
28 // thread exits. | 28 // thread exits. |
29 void DestructAllocationContextTracker(void* alloc_ctx_tracker) { | 29 void DestructAllocationContextTracker(void* alloc_ctx_tracker) { |
30 delete static_cast<AllocationContextTracker*>(alloc_ctx_tracker); | 30 delete static_cast<AllocationContextTracker*>(alloc_ctx_tracker); |
31 } | 31 } |
32 | 32 |
33 } // namespace | 33 } // namespace |
34 | 34 |
35 AllocationContextTracker::AllocationContextTracker() { | 35 AllocationContextTracker::AllocationContextTracker() |
| 36 : current_task_file_name_(nullptr) { |
36 pseudo_stack_.reserve(kMaxStackDepth); | 37 pseudo_stack_.reserve(kMaxStackDepth); |
37 } | 38 } |
| 39 |
38 AllocationContextTracker::~AllocationContextTracker() {} | 40 AllocationContextTracker::~AllocationContextTracker() {} |
39 | 41 |
40 // static | 42 // static |
41 AllocationContextTracker::InitializationState | 43 AllocationContextTracker::InitializationState |
42 AllocationContextTracker::GetStateForCurrentThread() { | 44 AllocationContextTracker::GetStateForCurrentThread() { |
43 auto tracker = | 45 auto tracker = |
44 static_cast<AllocationContextTracker*>(g_tls_alloc_ctx_tracker.Get()); | 46 static_cast<AllocationContextTracker*>(g_tls_alloc_ctx_tracker.Get()); |
45 if (!tracker) | 47 if (!tracker) |
46 return kNotInitialized; | 48 return kNotInitialized; |
47 if (tracker == kInitializingSentinel) | 49 if (tracker == kInitializingSentinel) |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 // Assert that pushes and pops are nested correctly. This DCHECK can be | 108 // Assert that pushes and pops are nested correctly. This DCHECK can be |
107 // hit if some TRACE_EVENT macro is unbalanced (a TRACE_EVENT_END* call | 109 // hit if some TRACE_EVENT macro is unbalanced (a TRACE_EVENT_END* call |
108 // without a corresponding TRACE_EVENT_BEGIN). | 110 // without a corresponding TRACE_EVENT_BEGIN). |
109 DCHECK_EQ(frame, tracker->pseudo_stack_.back()) | 111 DCHECK_EQ(frame, tracker->pseudo_stack_.back()) |
110 << "Encountered an unmatched TRACE_EVENT_END"; | 112 << "Encountered an unmatched TRACE_EVENT_END"; |
111 | 113 |
112 tracker->pseudo_stack_.pop_back(); | 114 tracker->pseudo_stack_.pop_back(); |
113 } | 115 } |
114 | 116 |
115 // static | 117 // static |
| 118 void AllocationContextTracker::SetThreadName(const char* name) { |
| 119 auto tracker = AllocationContextTracker::GetThreadLocalTracker(); |
| 120 |
| 121 // The thread name is added as the first entry in the psuedo stack. This is |
| 122 // not removed until the tls is destroyed when thread dies. |
| 123 tracker->pseudo_stack_.insert(tracker->pseudo_stack_.begin(), |
| 124 static_cast<StackFrame>(name)); |
| 125 } |
| 126 |
| 127 // static |
| 128 void AllocationContextTracker::SetCurrentTaskFileName(const char* file_name) { |
| 129 AllocationContextTracker* tracker = GetThreadLocalTracker(); |
| 130 tracker->current_task_file_name_ = file_name; |
| 131 } |
| 132 |
| 133 // static |
116 AllocationContext AllocationContextTracker::GetContextSnapshot() { | 134 AllocationContext AllocationContextTracker::GetContextSnapshot() { |
117 AllocationContextTracker* tracker = GetThreadLocalTracker(); | 135 AllocationContextTracker* tracker = GetThreadLocalTracker(); |
118 AllocationContext ctx; | 136 AllocationContext ctx; |
119 | 137 |
120 // Fill the backtrace. | 138 // Fill the backtrace. |
121 { | 139 { |
122 auto src = tracker->pseudo_stack_.begin(); | 140 auto src = tracker->pseudo_stack_.begin(); |
123 auto dst = std::begin(ctx.backtrace.frames); | 141 auto dst = std::begin(ctx.backtrace.frames); |
124 auto src_end = tracker->pseudo_stack_.end(); | 142 auto src_end = tracker->pseudo_stack_.end(); |
125 auto dst_end = std::end(ctx.backtrace.frames); | 143 auto dst_end = std::end(ctx.backtrace.frames); |
126 | 144 |
127 // Copy as much of the bottom of the pseudo stack into the backtrace as | 145 // Copy as much of the bottom of the pseudo stack into the backtrace as |
128 // possible. | 146 // possible. |
129 for (; src != src_end && dst != dst_end; src++, dst++) | 147 for (; src != src_end && dst != dst_end; src++, dst++) |
130 *dst = *src; | 148 *dst = *src; |
131 | 149 |
132 // If there is room for more, fill the remaining slots with empty frames. | 150 // If there is room for more, fill the remaining slots with empty frames. |
133 std::fill(dst, dst_end, nullptr); | 151 std::fill(dst, dst_end, nullptr); |
134 } | 152 } |
135 | 153 |
136 ctx.type_name = nullptr; | 154 // Set the default type name to file name where the task was posted from. |
| 155 // TODO(ssid): Fix crbug.com/594803 to add file name as 3rd dimension |
| 156 // (component name) in the heap profiler and not piggy back on the type name. |
| 157 ctx.type_name = tracker->current_task_file_name_; |
137 | 158 |
138 return ctx; | 159 return ctx; |
139 } | 160 } |
140 | 161 |
141 } // namespace trace_event | 162 } // namespace trace_event |
142 } // namespace base | 163 } // namespace base |
OLD | NEW |