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/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 CHECK(tracker); | |
|
Primiano Tucci (use gerrit)
2016/03/15 16:44:33
NO need for this CHECK. If tracker is nullptr, thi
ssid
2016/03/17 00:11:47
Done.
| |
| 121 | |
| 122 // The thread name is added as the first entry in the psuedo stack. This is | |
| 123 // not removed until the tls is destroyed when thread dies. | |
| 124 tracker->pseudo_stack_.insert(tracker->pseudo_stack_.begin(), | |
| 125 static_cast<StackFrame>(name)); | |
| 126 } | |
| 127 | |
| 128 // static | |
| 129 void AllocationContextTracker::SetCurrentTaskFileName(const char* file_name) { | |
| 130 AllocationContextTracker* tracker = GetThreadLocalTracker(); | |
| 131 CHECK(tracker); | |
| 132 tracker->current_task_file_name_ = file_name; | |
| 133 } | |
| 134 | |
| 135 // static | |
| 116 AllocationContext AllocationContextTracker::GetContextSnapshot() { | 136 AllocationContext AllocationContextTracker::GetContextSnapshot() { |
| 117 AllocationContextTracker* tracker = GetThreadLocalTracker(); | 137 AllocationContextTracker* tracker = GetThreadLocalTracker(); |
| 118 AllocationContext ctx; | 138 AllocationContext ctx; |
| 119 | 139 |
| 120 // Fill the backtrace. | 140 // Fill the backtrace. |
| 121 { | 141 { |
| 122 auto src = tracker->pseudo_stack_.begin(); | 142 auto src = tracker->pseudo_stack_.begin(); |
| 123 auto dst = std::begin(ctx.backtrace.frames); | 143 auto dst = std::begin(ctx.backtrace.frames); |
| 124 auto src_end = tracker->pseudo_stack_.end(); | 144 auto src_end = tracker->pseudo_stack_.end(); |
| 125 auto dst_end = std::end(ctx.backtrace.frames); | 145 auto dst_end = std::end(ctx.backtrace.frames); |
| 126 | 146 |
| 127 // Copy as much of the bottom of the pseudo stack into the backtrace as | 147 // Copy as much of the bottom of the pseudo stack into the backtrace as |
| 128 // possible. | 148 // possible. |
| 129 for (; src != src_end && dst != dst_end; src++, dst++) | 149 for (; src != src_end && dst != dst_end; src++, dst++) |
| 130 *dst = *src; | 150 *dst = *src; |
| 131 | 151 |
| 132 // If there is room for more, fill the remaining slots with empty frames. | 152 // If there is room for more, fill the remaining slots with empty frames. |
| 133 std::fill(dst, dst_end, nullptr); | 153 std::fill(dst, dst_end, nullptr); |
| 134 } | 154 } |
| 135 | 155 |
| 136 ctx.type_name = nullptr; | 156 // Set the default type name to file name where the task was posted from. |
|
Primiano Tucci (use gerrit)
2016/03/15 16:44:33
Can you add a TODO: this should be a 3rd dimension
ssid
2016/03/17 00:11:47
Done.
| |
| 157 // Trace viewer uses the file name to categorize allocation by file name. | |
| 158 ctx.type_name = tracker->current_task_file_name_; | |
| 137 | 159 |
| 138 return ctx; | 160 return ctx; |
| 139 } | 161 } |
| 140 | 162 |
| 141 } // namespace trace_event | 163 } // namespace trace_event |
| 142 } // namespace base | 164 } // namespace base |
| OLD | NEW |