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

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

Issue 1891543003: [tracing] Turn StackFrame into struct. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 8 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 // When enabling capturing, also initialize the TLS slot. This does not create 68 // When enabling capturing, also initialize the TLS slot. This does not create
69 // a TLS instance yet. 69 // a TLS instance yet.
70 if (enabled && !g_tls_alloc_ctx_tracker.initialized()) 70 if (enabled && !g_tls_alloc_ctx_tracker.initialized())
71 g_tls_alloc_ctx_tracker.Initialize(DestructAllocationContextTracker); 71 g_tls_alloc_ctx_tracker.Initialize(DestructAllocationContextTracker);
72 72
73 // Release ordering ensures that when a thread observes |capture_enabled_| to 73 // Release ordering ensures that when a thread observes |capture_enabled_| to
74 // be true through an acquire load, the TLS slot has been initialized. 74 // be true through an acquire load, the TLS slot has been initialized.
75 subtle::Release_Store(&capture_enabled_, enabled); 75 subtle::Release_Store(&capture_enabled_, enabled);
76 } 76 }
77 77
78 void AllocationContextTracker::PushPseudoStackFrame(StackFrame frame) { 78 void AllocationContextTracker::PushPseudoStackFrame(
79 const char* trace_event_name) {
79 // Impose a limit on the height to verify that every push is popped, because 80 // Impose a limit on the height to verify that every push is popped, because
80 // in practice the pseudo stack never grows higher than ~20 frames. 81 // in practice the pseudo stack never grows higher than ~20 frames.
81 if (pseudo_stack_.size() < kMaxStackDepth) 82 if (pseudo_stack_.size() < kMaxStackDepth)
82 pseudo_stack_.push_back(frame); 83 pseudo_stack_.push_back(trace_event_name);
83 else 84 else
84 NOTREACHED(); 85 NOTREACHED();
85 } 86 }
86 87
87 // static 88 void AllocationContextTracker::PopPseudoStackFrame(
88 void AllocationContextTracker::PopPseudoStackFrame(StackFrame frame) { 89 const char* trace_event_name) {
89 // Guard for stack underflow. If tracing was started with a TRACE_EVENT in 90 // Guard for stack underflow. If tracing was started with a TRACE_EVENT in
90 // scope, the frame was never pushed, so it is possible that pop is called 91 // scope, the frame was never pushed, so it is possible that pop is called
91 // on an empty stack. 92 // on an empty stack.
92 if (pseudo_stack_.empty()) 93 if (pseudo_stack_.empty())
93 return; 94 return;
94 95
95 // Assert that pushes and pops are nested correctly. This DCHECK can be 96 // Assert that pushes and pops are nested correctly. This DCHECK can be
96 // hit if some TRACE_EVENT macro is unbalanced (a TRACE_EVENT_END* call 97 // hit if some TRACE_EVENT macro is unbalanced (a TRACE_EVENT_END* call
97 // without a corresponding TRACE_EVENT_BEGIN). 98 // without a corresponding TRACE_EVENT_BEGIN).
98 DCHECK_EQ(frame, pseudo_stack_.back()) 99 DCHECK_EQ(trace_event_name, pseudo_stack_.back())
99 << "Encountered an unmatched TRACE_EVENT_END"; 100 << "Encountered an unmatched TRACE_EVENT_END";
100 101
101 pseudo_stack_.pop_back(); 102 pseudo_stack_.pop_back();
102 } 103 }
103 104
104 void AllocationContextTracker::PushCurrentTaskContext(const char* context) { 105 void AllocationContextTracker::PushCurrentTaskContext(const char* context) {
105 DCHECK(context); 106 DCHECK(context);
106 if (task_contexts_.size() < kMaxTaskDepth) 107 if (task_contexts_.size() < kMaxTaskDepth)
107 task_contexts_.push_back(context); 108 task_contexts_.push_back(context);
108 else 109 else
109 NOTREACHED(); 110 NOTREACHED();
110 } 111 }
111 112
112 void AllocationContextTracker::PopCurrentTaskContext(const char* context) { 113 void AllocationContextTracker::PopCurrentTaskContext(const char* context) {
113 DCHECK_EQ(context, task_contexts_.back()) 114 DCHECK_EQ(context, task_contexts_.back())
114 << "Encountered an unmatched context end"; 115 << "Encountered an unmatched context end";
115 task_contexts_.pop_back(); 116 task_contexts_.pop_back();
116 } 117 }
117 118
118 // static 119 // static
119 AllocationContext AllocationContextTracker::GetContextSnapshot() { 120 AllocationContext AllocationContextTracker::GetContextSnapshot() {
120 AllocationContext ctx; 121 AllocationContext ctx;
121 122
122 // Fill the backtrace. 123 // Fill the backtrace.
123 { 124 {
124 auto src = pseudo_stack_.begin(); 125 auto backtrace = std::begin(ctx.backtrace.frames);
125 auto dst = std::begin(ctx.backtrace.frames); 126 auto backtrace_end = std::end(ctx.backtrace.frames);
126 auto src_end = pseudo_stack_.end();
127 auto dst_end = std::end(ctx.backtrace.frames);
128 127
129 // Add the thread name as the first enrty in the backtrace. 128 // Add the thread name as the first entry
130 if (thread_name_) { 129 if (thread_name_) {
131 DCHECK(dst < dst_end); 130 *backtrace++ = StackFrame::FromThreadName(thread_name_);
132 *dst = thread_name_;
133 ++dst;
134 } 131 }
135 132
136 // Copy as much of the bottom of the pseudo stack into the backtrace as 133 for (const auto& event_name: pseudo_stack_) {
Primiano Tucci (use gerrit) 2016/04/19 19:45:06 to be honest this would probably be more readable
Dmitry Skiba 2016/04/19 22:14:14 Done.
137 // possible. 134 if (backtrace == backtrace_end) {
138 for (; src != src_end && dst != dst_end; src++, dst++) 135 break;
139 *dst = *src; 136 }
137 *backtrace++ = StackFrame::FromTraceEventName(event_name);
138 }
140 139
141 // If there is room for more, fill the remaining slots with empty frames. 140 ctx.backtrace.frame_count = backtrace - std::begin(ctx.backtrace.frames);
142 std::fill(dst, dst_end, nullptr);
143 } 141 }
144 142
145 // TODO(ssid): Fix crbug.com/594803 to add file name as 3rd dimension 143 // TODO(ssid): Fix crbug.com/594803 to add file name as 3rd dimension
146 // (component name) in the heap profiler and not piggy back on the type name. 144 // (component name) in the heap profiler and not piggy back on the type name.
147 ctx.type_name = task_contexts_.empty() ? nullptr : task_contexts_.back(); 145 ctx.type_name = task_contexts_.empty() ? nullptr : task_contexts_.back();
148 146
149 return ctx; 147 return ctx;
150 } 148 }
151 149
152 } // namespace trace_event 150 } // namespace trace_event
153 } // namespace base 151 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698