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

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: Rebase. 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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 g_tls_alloc_ctx_tracker.Set(tracker); 78 g_tls_alloc_ctx_tracker.Set(tracker);
79 } 79 }
80 80
81 return tracker; 81 return tracker;
82 } 82 }
83 83
84 AllocationContextTracker::AllocationContextTracker() 84 AllocationContextTracker::AllocationContextTracker()
85 : thread_name_(nullptr), ignore_scope_depth_(0) { 85 : thread_name_(nullptr), ignore_scope_depth_(0) {
86 pseudo_stack_.reserve(kMaxStackDepth); 86 pseudo_stack_.reserve(kMaxStackDepth);
87 task_contexts_.reserve(kMaxTaskDepth); 87 task_contexts_.reserve(kMaxTaskDepth);
88 trace_categories_.reserve(kMaxStackDepth);
88 } 89 }
89 AllocationContextTracker::~AllocationContextTracker() {} 90 AllocationContextTracker::~AllocationContextTracker() {}
90 91
91 // static 92 // static
92 void AllocationContextTracker::SetCurrentThreadName(const char* name) { 93 void AllocationContextTracker::SetCurrentThreadName(const char* name) {
93 if (name && capture_mode() != CaptureMode::DISABLED) { 94 if (name && capture_mode() != CaptureMode::DISABLED) {
94 GetInstanceForCurrentThread()->thread_name_ = name; 95 GetInstanceForCurrentThread()->thread_name_ = name;
95 } 96 }
96 } 97 }
97 98
98 // static 99 // static
99 void AllocationContextTracker::SetCaptureMode(CaptureMode mode) { 100 void AllocationContextTracker::SetCaptureMode(CaptureMode mode) {
100 // When enabling capturing, also initialize the TLS slot. This does not create 101 // When enabling capturing, also initialize the TLS slot. This does not create
101 // a TLS instance yet. 102 // a TLS instance yet.
102 if (mode != CaptureMode::DISABLED && !g_tls_alloc_ctx_tracker.initialized()) 103 if (mode != CaptureMode::DISABLED && !g_tls_alloc_ctx_tracker.initialized())
103 g_tls_alloc_ctx_tracker.Initialize(DestructAllocationContextTracker); 104 g_tls_alloc_ctx_tracker.Initialize(DestructAllocationContextTracker);
104 105
105 // Release ordering ensures that when a thread observes |capture_mode_| to 106 // Release ordering ensures that when a thread observes |capture_mode_| to
106 // be true through an acquire load, the TLS slot has been initialized. 107 // be true through an acquire load, the TLS slot has been initialized.
107 subtle::Release_Store(&capture_mode_, static_cast<int32_t>(mode)); 108 subtle::Release_Store(&capture_mode_, static_cast<int32_t>(mode));
108 } 109 }
109 110
110 void AllocationContextTracker::PushPseudoStackFrame( 111 void AllocationContextTracker::PushPseudoStackFrame(
112 const char* category,
Primiano Tucci (use gerrit) 2016/08/25 16:31:15 s/category/trace_event_category/ for consistency w
ssid 2016/08/25 19:05:39 I just wanted the declaration in header file to fi
111 const char* trace_event_name) { 113 const char* trace_event_name) {
112 // Impose a limit on the height to verify that every push is popped, because 114 // 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. 115 // in practice the pseudo stack never grows higher than ~20 frames.
114 if (pseudo_stack_.size() < kMaxStackDepth) 116 if (pseudo_stack_.size() < kMaxStackDepth)
115 pseudo_stack_.push_back(trace_event_name); 117 pseudo_stack_.push_back(trace_event_name);
116 else 118 else
117 NOTREACHED(); 119 NOTREACHED();
120
121 // Ignore the category name if it has "," since it is confusing in UI.
122 if (strchr(category, ',') == nullptr &&
Primiano Tucci (use gerrit) 2016/08/25 16:31:15 Can we do this check in the UI? This is going to s
ssid 2016/08/25 19:05:39 Yess, that is the reason I have a separate stack f
123 trace_categories_.size() < kMaxStackDepth) {
124 trace_categories_.push_back(category);
125 } else {
126 DCHECK_LE(trace_categories_.size(), kMaxStackDepth);
127 }
118 } 128 }
119 129
120 void AllocationContextTracker::PopPseudoStackFrame( 130 void AllocationContextTracker::PopPseudoStackFrame(
131 const char* category,
121 const char* trace_event_name) { 132 const char* trace_event_name) {
122 // Guard for stack underflow. If tracing was started with a TRACE_EVENT in 133 // 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 134 // scope, the frame was never pushed, so it is possible that pop is called
124 // on an empty stack. 135 // on an empty stack.
125 if (pseudo_stack_.empty()) 136 if (pseudo_stack_.empty())
126 return; 137 return;
127 138
128 // Assert that pushes and pops are nested correctly. This DCHECK can be 139 // 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 140 // hit if some TRACE_EVENT macro is unbalanced (a TRACE_EVENT_END* call
130 // without a corresponding TRACE_EVENT_BEGIN). 141 // without a corresponding TRACE_EVENT_BEGIN).
131 DCHECK_EQ(trace_event_name, pseudo_stack_.back()) 142 DCHECK_EQ(trace_event_name, pseudo_stack_.back())
132 << "Encountered an unmatched TRACE_EVENT_END"; 143 << "Encountered an unmatched TRACE_EVENT_END";
133 144
134 pseudo_stack_.pop_back(); 145 pseudo_stack_.pop_back();
146
147 if (!trace_categories_.empty() && trace_categories_.back() == category)
148 trace_categories_.pop_back();
149 else
150 DCHECK(strchr(category, ','));
135 } 151 }
136 152
137 void AllocationContextTracker::PushCurrentTaskContext(const char* context) { 153 void AllocationContextTracker::PushCurrentTaskContext(const char* context) {
138 DCHECK(context); 154 DCHECK(context);
139 if (task_contexts_.size() < kMaxTaskDepth) 155 if (task_contexts_.size() < kMaxTaskDepth)
140 task_contexts_.push_back(context); 156 task_contexts_.push_back(context);
141 else 157 else
142 NOTREACHED(); 158 NOTREACHED();
143 } 159 }
144 160
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 *backtrace++ = StackFrame::FromThreadName(thread_name_); 202 *backtrace++ = StackFrame::FromThreadName(thread_name_);
187 } 203 }
188 204
189 switch (mode) { 205 switch (mode) {
190 case CaptureMode::DISABLED: 206 case CaptureMode::DISABLED:
191 { 207 {
192 break; 208 break;
193 } 209 }
194 case CaptureMode::PSEUDO_STACK: 210 case CaptureMode::PSEUDO_STACK:
195 { 211 {
196 for (const char* event_name: pseudo_stack_) { 212 for (const char* event_name : pseudo_stack_) {
197 if (backtrace == backtrace_end) { 213 if (backtrace == backtrace_end) {
198 break; 214 break;
199 } 215 }
200 *backtrace++ = StackFrame::FromTraceEventName(event_name); 216 *backtrace++ = StackFrame::FromTraceEventName(event_name);
201 } 217 }
202 break; 218 break;
203 } 219 }
204 case CaptureMode::NATIVE_STACK: 220 case CaptureMode::NATIVE_STACK:
205 { 221 {
206 // Backtrace contract requires us to return bottom frames, i.e. 222 // Backtrace contract requires us to return bottom frames, i.e.
(...skipping 23 matching lines...) Expand all
230 *backtrace++ = StackFrame::FromProgramCounter(frame); 246 *backtrace++ = StackFrame::FromProgramCounter(frame);
231 } 247 }
232 break; 248 break;
233 } 249 }
234 } 250 }
235 251
236 ctx.backtrace.frame_count = backtrace - std::begin(ctx.backtrace.frames); 252 ctx.backtrace.frame_count = backtrace - std::begin(ctx.backtrace.frames);
237 253
238 // TODO(ssid): Fix crbug.com/594803 to add file name as 3rd dimension 254 // 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. 255 // (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(); 256 if (!task_contexts_.empty()) {
257 ctx.type_name = task_contexts_.back();
258 } else if (!trace_categories_.empty()) {
259 ctx.type_name = trace_categories_.back();
260 }
241 261
242 return ctx; 262 return ctx;
243 } 263 }
244 264
245 } // namespace trace_event 265 } // namespace trace_event
246 } // namespace base 266 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698