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

Side by Side Diff: base/profiler/stack_sampling_profiler.cc

Issue 2444143002: Add process lifetime annotations to stack samples. (Closed)
Patch Set: added comments and fixed some build problems Created 4 years, 1 month 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/profiler/stack_sampling_profiler.h" 5 #include "base/profiler/stack_sampling_profiler.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 void AsyncRunner::RunCallbackAndDeleteInstance( 74 void AsyncRunner::RunCallbackAndDeleteInstance(
75 std::unique_ptr<AsyncRunner> object_to_be_deleted, 75 std::unique_ptr<AsyncRunner> object_to_be_deleted,
76 const StackSamplingProfiler::CompletedCallback& callback, 76 const StackSamplingProfiler::CompletedCallback& callback,
77 scoped_refptr<SingleThreadTaskRunner> task_runner, 77 scoped_refptr<SingleThreadTaskRunner> task_runner,
78 const StackSamplingProfiler::CallStackProfiles& profiles) { 78 const StackSamplingProfiler::CallStackProfiles& profiles) {
79 callback.Run(profiles); 79 callback.Run(profiles);
80 // Delete the instance on the original calling thread. 80 // Delete the instance on the original calling thread.
81 task_runner->DeleteSoon(FROM_HERE, object_to_be_deleted.release()); 81 task_runner->DeleteSoon(FROM_HERE, object_to_be_deleted.release());
82 } 82 }
83 83
84 void ChangeAtomicFlags(subtle::Atomic32* flags,
85 subtle::Atomic32 set,
86 subtle::Atomic32 clear) {
87 DCHECK(set != 0 || clear != 0);
88 DCHECK_EQ(0, set & clear);
89
90 subtle::Atomic32 bits = subtle::NoBarrier_Load(flags);
91 while (true) {
92 subtle::Atomic32 existing =
93 subtle::NoBarrier_CompareAndSwap(flags, bits, (bits | set) & ~clear);
94 if (existing == bits)
95 break;
96 bits = existing;
97 }
98 }
99
84 } // namespace 100 } // namespace
85 101
86 // StackSamplingProfiler::Module ---------------------------------------------- 102 // StackSamplingProfiler::Module ----------------------------------------------
87 103
88 StackSamplingProfiler::Module::Module() : base_address(0u) {} 104 StackSamplingProfiler::Module::Module() : base_address(0u) {}
89 StackSamplingProfiler::Module::Module(uintptr_t base_address, 105 StackSamplingProfiler::Module::Module(uintptr_t base_address,
90 const std::string& id, 106 const std::string& id,
91 const FilePath& filename) 107 const FilePath& filename)
92 : base_address(base_address), id(id), filename(filename) {} 108 : base_address(base_address), id(id), filename(filename) {}
93 109
94 StackSamplingProfiler::Module::~Module() {} 110 StackSamplingProfiler::Module::~Module() {}
95 111
96 // StackSamplingProfiler::Frame ----------------------------------------------- 112 // StackSamplingProfiler::Frame -----------------------------------------------
97 113
98 StackSamplingProfiler::Frame::Frame(uintptr_t instruction_pointer, 114 StackSamplingProfiler::Frame::Frame(uintptr_t instruction_pointer,
99 size_t module_index) 115 size_t module_index)
100 : instruction_pointer(instruction_pointer), module_index(module_index) {} 116 : instruction_pointer(instruction_pointer), module_index(module_index) {}
101 117
102 StackSamplingProfiler::Frame::~Frame() {} 118 StackSamplingProfiler::Frame::~Frame() {}
103 119
104 StackSamplingProfiler::Frame::Frame() 120 StackSamplingProfiler::Frame::Frame()
105 : instruction_pointer(0), module_index(kUnknownModuleIndex) { 121 : instruction_pointer(0), module_index(kUnknownModuleIndex) {
106 } 122 }
107 123
124 // StackSamplingProfiler::Sample ----------------------------------------------
125
126 StackSamplingProfiler::Sample::Sample() {}
127
128 StackSamplingProfiler::Sample::Sample(const Sample& sample) = default;
129
130 StackSamplingProfiler::Sample::~Sample() {}
131
132 StackSamplingProfiler::Sample::Sample(const Frame& frame) {
133 frames.push_back(std::move(frame));
134 }
135
136 StackSamplingProfiler::Sample::Sample(const std::vector<Frame>& frames)
137 : frames(frames) {}
138
108 // StackSamplingProfiler::CallStackProfile ------------------------------------ 139 // StackSamplingProfiler::CallStackProfile ------------------------------------
109 140
110 StackSamplingProfiler::CallStackProfile::CallStackProfile() {} 141 StackSamplingProfiler::CallStackProfile::CallStackProfile() {}
111 142
112 StackSamplingProfiler::CallStackProfile::CallStackProfile( 143 StackSamplingProfiler::CallStackProfile::CallStackProfile(
113 const CallStackProfile& other) = default; 144 const CallStackProfile& other) = default;
114 145
115 StackSamplingProfiler::CallStackProfile::~CallStackProfile() {} 146 StackSamplingProfiler::CallStackProfile::~CallStackProfile() {}
116 147
117 // StackSamplingProfiler::SamplingThread -------------------------------------- 148 // StackSamplingProfiler::SamplingThread --------------------------------------
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 // stop_event_. 195 // stop_event_.
165 if (stop_event_.TimedWait( 196 if (stop_event_.TimedWait(
166 std::max(params_.sampling_interval - previous_elapsed_sample_time, 197 std::max(params_.sampling_interval - previous_elapsed_sample_time,
167 TimeDelta()))) { 198 TimeDelta()))) {
168 *was_stopped = true; 199 *was_stopped = true;
169 break; 200 break;
170 } 201 }
171 } 202 }
172 ElapsedTimer sample_timer; 203 ElapsedTimer sample_timer;
173 profile->samples.push_back(Sample()); 204 profile->samples.push_back(Sample());
174 native_sampler_->RecordStackSample(&profile->samples.back()); 205 Sample& sample = profile->samples.back();
206 native_sampler_->RecordStackSample(&sample);
207 sample.process_phases = subtle::NoBarrier_Load(&process_phases_);
208 sample.current_activities = subtle::NoBarrier_Load(&current_activities_);
175 previous_elapsed_sample_time = sample_timer.Elapsed(); 209 previous_elapsed_sample_time = sample_timer.Elapsed();
176 } 210 }
177 211
178 *elapsed_time = profile_timer.Elapsed(); 212 *elapsed_time = profile_timer.Elapsed();
179 profile->profile_duration = *elapsed_time; 213 profile->profile_duration = *elapsed_time;
180 native_sampler_->ProfileRecordingStopped(); 214 native_sampler_->ProfileRecordingStopped();
181 } 215 }
182 216
183 // In an analogous manner to CollectProfile() and samples exceeding the expected 217 // In an analogous manner to CollectProfile() and samples exceeding the expected
184 // total sampling time, bursts may also exceed the burst_interval. We adopt the 218 // total sampling time, bursts may also exceed the burst_interval. We adopt the
(...skipping 22 matching lines...) Expand all
207 241
208 if (was_stopped) 242 if (was_stopped)
209 return; 243 return;
210 } 244 }
211 } 245 }
212 246
213 void StackSamplingProfiler::SamplingThread::Stop() { 247 void StackSamplingProfiler::SamplingThread::Stop() {
214 stop_event_.Signal(); 248 stop_event_.Signal();
215 } 249 }
216 250
251 // static
252 void StackSamplingProfiler::SetProcessPhase(ProcessPhase phase) {
253 DCHECK_EQ(0, subtle::NoBarrier_Load(&process_phases_) & (1 << phase));
254 ChangeAtomicFlags(&process_phases_, 1 << phase, 0);
255 }
256
257 // static
258 void StackSamplingProfiler::RecordActivityBegin(ProcessActivity activity) {
259 ChangeAtomicFlags(&current_activities_, 1 << activity, 0);
260 }
261
262 // static
263 void StackSamplingProfiler::RecordActivityEnd(ProcessActivity activity) {
264 ChangeAtomicFlags(&current_activities_, 0, 1 << activity);
265 }
266
217 // StackSamplingProfiler ------------------------------------------------------ 267 // StackSamplingProfiler ------------------------------------------------------
218 268
269 subtle::Atomic32 StackSamplingProfiler::process_phases_ = 0;
270 subtle::Atomic32 StackSamplingProfiler::current_activities_ = 0;
271
219 StackSamplingProfiler::SamplingParams::SamplingParams() 272 StackSamplingProfiler::SamplingParams::SamplingParams()
220 : initial_delay(TimeDelta::FromMilliseconds(0)), 273 : initial_delay(TimeDelta::FromMilliseconds(0)),
221 bursts(1), 274 bursts(1),
222 burst_interval(TimeDelta::FromMilliseconds(10000)), 275 burst_interval(TimeDelta::FromMilliseconds(10000)),
223 samples_per_burst(300), 276 samples_per_burst(300),
224 sampling_interval(TimeDelta::FromMilliseconds(100)) { 277 sampling_interval(TimeDelta::FromMilliseconds(100)) {
225 } 278 }
226 279
227 StackSamplingProfiler::StackSamplingProfiler( 280 StackSamplingProfiler::StackSamplingProfiler(
228 PlatformThreadId thread_id, 281 PlatformThreadId thread_id,
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 } 329 }
277 330
278 // StackSamplingProfiler::Frame global functions ------------------------------ 331 // StackSamplingProfiler::Frame global functions ------------------------------
279 332
280 bool operator==(const StackSamplingProfiler::Module& a, 333 bool operator==(const StackSamplingProfiler::Module& a,
281 const StackSamplingProfiler::Module& b) { 334 const StackSamplingProfiler::Module& b) {
282 return a.base_address == b.base_address && a.id == b.id && 335 return a.base_address == b.base_address && a.id == b.id &&
283 a.filename == b.filename; 336 a.filename == b.filename;
284 } 337 }
285 338
339 bool operator==(const StackSamplingProfiler::Sample& a,
340 const StackSamplingProfiler::Sample& b) {
341 return a.process_phases == b.process_phases &&
342 a.current_activities == b.current_activities && a.frames == b.frames;
343 }
344
345 bool operator!=(const StackSamplingProfiler::Sample& a,
346 const StackSamplingProfiler::Sample& b) {
347 return !(a == b);
348 }
349
350 bool operator<(const StackSamplingProfiler::Sample& a,
351 const StackSamplingProfiler::Sample& b) {
352 if (a.process_phases < b.process_phases)
353 return true;
354 if (a.process_phases > b.process_phases)
355 return false;
356
357 if (a.current_activities < b.current_activities)
358 return true;
359 if (a.current_activities > b.current_activities)
360 return false;
361
362 return a.frames < b.frames;
363 }
364
286 bool operator==(const StackSamplingProfiler::Frame &a, 365 bool operator==(const StackSamplingProfiler::Frame &a,
287 const StackSamplingProfiler::Frame &b) { 366 const StackSamplingProfiler::Frame &b) {
288 return a.instruction_pointer == b.instruction_pointer && 367 return a.instruction_pointer == b.instruction_pointer &&
289 a.module_index == b.module_index; 368 a.module_index == b.module_index;
290 } 369 }
291 370
292 bool operator<(const StackSamplingProfiler::Frame &a, 371 bool operator<(const StackSamplingProfiler::Frame &a,
293 const StackSamplingProfiler::Frame &b) { 372 const StackSamplingProfiler::Frame &b) {
294 return (a.module_index < b.module_index) || 373 return (a.module_index < b.module_index) ||
295 (a.module_index == b.module_index && 374 (a.module_index == b.module_index &&
296 a.instruction_pointer < b.instruction_pointer); 375 a.instruction_pointer < b.instruction_pointer);
297 } 376 }
298 377
299 } // namespace base 378 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698