Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Side by Side Diff: base/trace_event/heap_profiler_allocation_context_tracker.cc

Issue 2272843002: Heap Profiler: Add trace category group names as type names for allocations (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@add_filter
Patch Set: use substr and build fix. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 // a TLS instance yet. 101 // a TLS instance yet.
102 if (mode != CaptureMode::DISABLED && !g_tls_alloc_ctx_tracker.initialized()) 102 if (mode != CaptureMode::DISABLED && !g_tls_alloc_ctx_tracker.initialized())
103 g_tls_alloc_ctx_tracker.Initialize(DestructAllocationContextTracker); 103 g_tls_alloc_ctx_tracker.Initialize(DestructAllocationContextTracker);
104 104
105 // Release ordering ensures that when a thread observes |capture_mode_| to 105 // Release ordering ensures that when a thread observes |capture_mode_| to
106 // be true through an acquire load, the TLS slot has been initialized. 106 // be true through an acquire load, the TLS slot has been initialized.
107 subtle::Release_Store(&capture_mode_, static_cast<int32_t>(mode)); 107 subtle::Release_Store(&capture_mode_, static_cast<int32_t>(mode));
108 } 108 }
109 109
110 void AllocationContextTracker::PushPseudoStackFrame( 110 void AllocationContextTracker::PushPseudoStackFrame(
111 const char* trace_event_name) { 111 AllocationContextTracker::PseudoStackFrame stack_frame) {
112 // Impose a limit on the height to verify that every push is popped, because 112 // Impose a limit on the height to verify that every push is popped, because
113 // in practice the pseudo stack never grows higher than ~20 frames. 113 // in practice the pseudo stack never grows higher than ~20 frames.
114 if (pseudo_stack_.size() < kMaxStackDepth) 114 if (pseudo_stack_.size() < kMaxStackDepth)
115 pseudo_stack_.push_back(trace_event_name); 115 pseudo_stack_.push_back(stack_frame);
116 else 116 else
117 NOTREACHED(); 117 NOTREACHED();
118 } 118 }
119 119
120 void AllocationContextTracker::PopPseudoStackFrame( 120 void AllocationContextTracker::PopPseudoStackFrame(
121 const char* trace_event_name) { 121 AllocationContextTracker::PseudoStackFrame stack_frame) {
122 // Guard for stack underflow. If tracing was started with a TRACE_EVENT in 122 // Guard for stack underflow. If tracing was started with a TRACE_EVENT in
123 // scope, the frame was never pushed, so it is possible that pop is called 123 // scope, the frame was never pushed, so it is possible that pop is called
124 // on an empty stack. 124 // on an empty stack.
125 if (pseudo_stack_.empty()) 125 if (pseudo_stack_.empty())
126 return; 126 return;
127 127
128 // Assert that pushes and pops are nested correctly. This DCHECK can be 128 // Assert that pushes and pops are nested correctly. This DCHECK can be
129 // hit if some TRACE_EVENT macro is unbalanced (a TRACE_EVENT_END* call 129 // hit if some TRACE_EVENT macro is unbalanced (a TRACE_EVENT_END* call
130 // without a corresponding TRACE_EVENT_BEGIN). 130 // without a corresponding TRACE_EVENT_BEGIN).
131 DCHECK_EQ(trace_event_name, pseudo_stack_.back()) 131 DCHECK(stack_frame == pseudo_stack_.back())
132 << "Encountered an unmatched TRACE_EVENT_END"; 132 << "Encountered an unmatched TRACE_EVENT_END";
133 133
134 pseudo_stack_.pop_back(); 134 pseudo_stack_.pop_back();
135 } 135 }
136 136
137 void AllocationContextTracker::PushCurrentTaskContext(const char* context) { 137 void AllocationContextTracker::PushCurrentTaskContext(const char* context) {
138 DCHECK(context); 138 DCHECK(context);
139 if (task_contexts_.size() < kMaxTaskDepth) 139 if (task_contexts_.size() < kMaxTaskDepth)
140 task_contexts_.push_back(context); 140 task_contexts_.push_back(context);
141 else 141 else
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 *backtrace++ = StackFrame::FromThreadName(thread_name_); 186 *backtrace++ = StackFrame::FromThreadName(thread_name_);
187 } 187 }
188 188
189 switch (mode) { 189 switch (mode) {
190 case CaptureMode::DISABLED: 190 case CaptureMode::DISABLED:
191 { 191 {
192 break; 192 break;
193 } 193 }
194 case CaptureMode::PSEUDO_STACK: 194 case CaptureMode::PSEUDO_STACK:
195 { 195 {
196 for (const char* event_name: pseudo_stack_) { 196 for (const PseudoStackFrame& stack_frame : pseudo_stack_) {
197 if (backtrace == backtrace_end) { 197 if (backtrace == backtrace_end) {
198 break; 198 break;
199 } 199 }
200 *backtrace++ = StackFrame::FromTraceEventName(event_name); 200 *backtrace++ =
201 StackFrame::FromTraceEventName(stack_frame.trace_event_name);
201 } 202 }
202 break; 203 break;
203 } 204 }
204 case CaptureMode::NATIVE_STACK: 205 case CaptureMode::NATIVE_STACK:
205 { 206 {
206 // Backtrace contract requires us to return bottom frames, i.e. 207 // Backtrace contract requires us to return bottom frames, i.e.
207 // from main() and up. Stack unwinding produces top frames, i.e. 208 // from main() and up. Stack unwinding produces top frames, i.e.
208 // from this point and up until main(). We request many frames to 209 // from this point and up until main(). We request many frames to
209 // make sure we reach main(), and then copy bottom portion of them. 210 // make sure we reach main(), and then copy bottom portion of them.
210 const void* frames[128]; 211 const void* frames[128];
(...skipping 19 matching lines...) Expand all
230 *backtrace++ = StackFrame::FromProgramCounter(frame); 231 *backtrace++ = StackFrame::FromProgramCounter(frame);
231 } 232 }
232 break; 233 break;
233 } 234 }
234 } 235 }
235 236
236 ctx.backtrace.frame_count = backtrace - std::begin(ctx.backtrace.frames); 237 ctx.backtrace.frame_count = backtrace - std::begin(ctx.backtrace.frames);
237 238
238 // TODO(ssid): Fix crbug.com/594803 to add file name as 3rd dimension 239 // TODO(ssid): Fix crbug.com/594803 to add file name as 3rd dimension
239 // (component name) in the heap profiler and not piggy back on the type name. 240 // (component name) in the heap profiler and not piggy back on the type name.
240 ctx.type_name = task_contexts_.empty() ? nullptr : task_contexts_.back(); 241 if (!task_contexts_.empty()) {
242 ctx.type_name = task_contexts_.back();
243 } else if (!pseudo_stack_.empty()) {
244 // If task context was unavailable, then the category names are taken from
245 // trace events.
246 ctx.type_name = pseudo_stack_.back().trace_event_category;
247 }
241 248
242 return ctx; 249 return ctx;
243 } 250 }
244 251
245 } // namespace trace_event 252 } // namespace trace_event
246 } // namespace base 253 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698