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 11 matching lines...) Expand all Loading... | |
| 22 | 22 |
| 23 subtle::Atomic32 AllocationContextTracker::capture_mode_ = | 23 subtle::Atomic32 AllocationContextTracker::capture_mode_ = |
| 24 static_cast<int32_t>(AllocationContextTracker::CaptureMode::DISABLED); | 24 static_cast<int32_t>(AllocationContextTracker::CaptureMode::DISABLED); |
| 25 | 25 |
| 26 namespace { | 26 namespace { |
| 27 | 27 |
| 28 const size_t kMaxStackDepth = 128u; | 28 const size_t kMaxStackDepth = 128u; |
| 29 const size_t kMaxTaskDepth = 16u; | 29 const size_t kMaxTaskDepth = 16u; |
| 30 AllocationContextTracker* const kInitializingSentinel = | 30 AllocationContextTracker* const kInitializingSentinel = |
| 31 reinterpret_cast<AllocationContextTracker*>(-1); | 31 reinterpret_cast<AllocationContextTracker*>(-1); |
| 32 const char kTracingOverhead[] = "tracing_overhead"; | |
| 33 | 32 |
| 34 ThreadLocalStorage::StaticSlot g_tls_alloc_ctx_tracker = TLS_INITIALIZER; | 33 ThreadLocalStorage::StaticSlot g_tls_alloc_ctx_tracker = TLS_INITIALIZER; |
| 35 | 34 |
| 36 // This function is added to the TLS slot to clean up the instance when the | 35 // This function is added to the TLS slot to clean up the instance when the |
| 37 // thread exits. | 36 // thread exits. |
| 38 void DestructAllocationContextTracker(void* alloc_ctx_tracker) { | 37 void DestructAllocationContextTracker(void* alloc_ctx_tracker) { |
| 39 delete static_cast<AllocationContextTracker*>(alloc_ctx_tracker); | 38 delete static_cast<AllocationContextTracker*>(alloc_ctx_tracker); |
| 40 } | 39 } |
| 41 | 40 |
| 42 // Cannot call ThreadIdNameManager::GetName because it holds a lock and causes | 41 // Cannot call ThreadIdNameManager::GetName because it holds a lock and causes |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 150 // on an empty stack. | 149 // on an empty stack. |
| 151 if (task_contexts_.empty()) | 150 if (task_contexts_.empty()) |
| 152 return; | 151 return; |
| 153 | 152 |
| 154 DCHECK_EQ(context, task_contexts_.back()) | 153 DCHECK_EQ(context, task_contexts_.back()) |
| 155 << "Encountered an unmatched context end"; | 154 << "Encountered an unmatched context end"; |
| 156 task_contexts_.pop_back(); | 155 task_contexts_.pop_back(); |
| 157 } | 156 } |
| 158 | 157 |
| 159 // static | 158 // static |
| 160 AllocationContext AllocationContextTracker::GetContextSnapshot() { | 159 bool AllocationContextTracker::GetContextSnapshot(AllocationContext* ctx) { |
| 161 AllocationContext ctx; | |
| 162 | |
| 163 if (ignore_scope_depth_) { | 160 if (ignore_scope_depth_) { |
|
Primiano Tucci (use gerrit)
2017/01/17 17:54:09
drop the braces at this point
| |
| 164 ctx.backtrace.frames[0] = StackFrame::FromTraceEventName(kTracingOverhead); | 161 return false; |
| 165 ctx.type_name = kTracingOverhead; | |
| 166 ctx.backtrace.frame_count = 1; | |
| 167 return ctx; | |
| 168 } | 162 } |
| 169 | 163 |
| 170 CaptureMode mode = static_cast<CaptureMode>( | 164 CaptureMode mode = static_cast<CaptureMode>( |
| 171 subtle::NoBarrier_Load(&capture_mode_)); | 165 subtle::NoBarrier_Load(&capture_mode_)); |
| 172 | 166 |
| 173 auto* backtrace = std::begin(ctx.backtrace.frames); | 167 auto* backtrace = std::begin(ctx->backtrace.frames); |
| 174 auto* backtrace_end = std::end(ctx.backtrace.frames); | 168 auto* backtrace_end = std::end(ctx->backtrace.frames); |
| 175 | 169 |
| 176 if (!thread_name_) { | 170 if (!thread_name_) { |
| 177 // Ignore the string allocation made by GetAndLeakThreadName to avoid | 171 // Ignore the string allocation made by GetAndLeakThreadName to avoid |
| 178 // reentrancy. | 172 // reentrancy. |
| 179 ignore_scope_depth_++; | 173 ignore_scope_depth_++; |
| 180 thread_name_ = GetAndLeakThreadName(); | 174 thread_name_ = GetAndLeakThreadName(); |
| 181 ANNOTATE_LEAKING_OBJECT_PTR(thread_name_); | 175 ANNOTATE_LEAKING_OBJECT_PTR(thread_name_); |
| 182 DCHECK(thread_name_); | 176 DCHECK(thread_name_); |
| 183 ignore_scope_depth_--; | 177 ignore_scope_depth_--; |
| 184 } | 178 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 229 0 : | 223 0 : |
| 230 frame_count - backtrace_capacity; | 224 frame_count - backtrace_capacity; |
| 231 for (size_t i = frame_count; i > top_frame_index;) { | 225 for (size_t i = frame_count; i > top_frame_index;) { |
| 232 const void* frame = frames[--i]; | 226 const void* frame = frames[--i]; |
| 233 *backtrace++ = StackFrame::FromProgramCounter(frame); | 227 *backtrace++ = StackFrame::FromProgramCounter(frame); |
| 234 } | 228 } |
| 235 break; | 229 break; |
| 236 } | 230 } |
| 237 } | 231 } |
| 238 | 232 |
| 239 ctx.backtrace.frame_count = backtrace - std::begin(ctx.backtrace.frames); | 233 ctx->backtrace.frame_count = backtrace - std::begin(ctx->backtrace.frames); |
| 240 | 234 |
| 241 // TODO(ssid): Fix crbug.com/594803 to add file name as 3rd dimension | 235 // TODO(ssid): Fix crbug.com/594803 to add file name as 3rd dimension |
| 242 // (component name) in the heap profiler and not piggy back on the type name. | 236 // (component name) in the heap profiler and not piggy back on the type name. |
| 243 if (!task_contexts_.empty()) { | 237 if (!task_contexts_.empty()) { |
| 244 ctx.type_name = task_contexts_.back(); | 238 ctx->type_name = task_contexts_.back(); |
| 245 } else if (!pseudo_stack_.empty()) { | 239 } else if (!pseudo_stack_.empty()) { |
| 246 // If task context was unavailable, then the category names are taken from | 240 // If task context was unavailable, then the category names are taken from |
| 247 // trace events. | 241 // trace events. |
| 248 ctx.type_name = pseudo_stack_.back().trace_event_category; | 242 ctx->type_name = pseudo_stack_.back().trace_event_category; |
| 249 } | 243 } |
| 250 | 244 |
| 251 return ctx; | 245 return true; |
| 252 } | 246 } |
| 253 | 247 |
| 254 } // namespace trace_event | 248 } // namespace trace_event |
| 255 } // namespace base | 249 } // namespace base |
| OLD | NEW |