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

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

Issue 2444143002: Add process lifetime annotations to stack samples. (Closed)
Patch Set: addressed review comments by wittman 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);
175 previous_elapsed_sample_time = sample_timer.Elapsed(); 207 previous_elapsed_sample_time = sample_timer.Elapsed();
176 } 208 }
177 209
178 *elapsed_time = profile_timer.Elapsed(); 210 *elapsed_time = profile_timer.Elapsed();
179 profile->profile_duration = *elapsed_time; 211 profile->profile_duration = *elapsed_time;
180 native_sampler_->ProfileRecordingStopped(); 212 native_sampler_->ProfileRecordingStopped();
181 } 213 }
182 214
183 // In an analogous manner to CollectProfile() and samples exceeding the expected 215 // 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 216 // total sampling time, bursts may also exceed the burst_interval. We adopt the
(...skipping 24 matching lines...) Expand all
209 return; 241 return;
210 } 242 }
211 } 243 }
212 244
213 void StackSamplingProfiler::SamplingThread::Stop() { 245 void StackSamplingProfiler::SamplingThread::Stop() {
214 stop_event_.Signal(); 246 stop_event_.Signal();
215 } 247 }
216 248
217 // StackSamplingProfiler ------------------------------------------------------ 249 // StackSamplingProfiler ------------------------------------------------------
218 250
251 subtle::Atomic32 StackSamplingProfiler::process_phases_ = 0;
252 subtle::Atomic32 StackSamplingProfiler::current_activities_ = 0;
253
219 StackSamplingProfiler::SamplingParams::SamplingParams() 254 StackSamplingProfiler::SamplingParams::SamplingParams()
220 : initial_delay(TimeDelta::FromMilliseconds(0)), 255 : initial_delay(TimeDelta::FromMilliseconds(0)),
221 bursts(1), 256 bursts(1),
222 burst_interval(TimeDelta::FromMilliseconds(10000)), 257 burst_interval(TimeDelta::FromMilliseconds(10000)),
223 samples_per_burst(300), 258 samples_per_burst(300),
224 sampling_interval(TimeDelta::FromMilliseconds(100)) { 259 sampling_interval(TimeDelta::FromMilliseconds(100)) {
225 } 260 }
226 261
227 StackSamplingProfiler::StackSamplingProfiler( 262 StackSamplingProfiler::StackSamplingProfiler(
228 PlatformThreadId thread_id, 263 PlatformThreadId thread_id,
(...skipping 23 matching lines...) Expand all
252 const CompletedCallback& callback) { 287 const CompletedCallback& callback) {
253 CHECK(ThreadTaskRunnerHandle::Get()); 288 CHECK(ThreadTaskRunnerHandle::Get());
254 AsyncRunner::Run(thread_id, params, callback); 289 AsyncRunner::Run(thread_id, params, callback);
255 } 290 }
256 291
257 void StackSamplingProfiler::Start() { 292 void StackSamplingProfiler::Start() {
258 if (completed_callback_.is_null()) 293 if (completed_callback_.is_null())
259 return; 294 return;
260 295
261 std::unique_ptr<NativeStackSampler> native_sampler = 296 std::unique_ptr<NativeStackSampler> native_sampler =
262 NativeStackSampler::Create(thread_id_, test_delegate_); 297 NativeStackSampler::Create(thread_id_, Bind(&RecordAnnotations),
298 test_delegate_);
263 if (!native_sampler) 299 if (!native_sampler)
264 return; 300 return;
265 301
266 sampling_thread_.reset(new SamplingThread(std::move(native_sampler), params_, 302 sampling_thread_.reset(new SamplingThread(std::move(native_sampler), params_,
267 completed_callback_)); 303 completed_callback_));
268 if (!PlatformThread::Create(0, sampling_thread_.get(), 304 if (!PlatformThread::Create(0, sampling_thread_.get(),
269 &sampling_thread_handle_)) 305 &sampling_thread_handle_))
270 sampling_thread_.reset(); 306 sampling_thread_.reset();
271 } 307 }
272 308
273 void StackSamplingProfiler::Stop() { 309 void StackSamplingProfiler::Stop() {
274 if (sampling_thread_) 310 if (sampling_thread_)
275 sampling_thread_->Stop(); 311 sampling_thread_->Stop();
276 } 312 }
277 313
314 // static
315 void StackSamplingProfiler::SetProcessPhase(ProcessPhase phase) {
316 DCHECK_EQ(0, subtle::NoBarrier_Load(&process_phases_) & (1 << phase));
317 ChangeAtomicFlags(&process_phases_, 1 << phase, 0);
318 }
319
320 // static
321 void StackSamplingProfiler::RecordActivityBegin(ProcessActivity activity) {
322 ChangeAtomicFlags(&current_activities_, 1 << activity, 0);
323 }
324
325 // static
326 void StackSamplingProfiler::RecordActivityEnd(ProcessActivity activity) {
327 ChangeAtomicFlags(&current_activities_, 0, 1 << activity);
328 }
329
330 // static
331 void StackSamplingProfiler::RecordAnnotations(Sample* sample) {
332 sample->process_phases = subtle::NoBarrier_Load(&process_phases_);
333 sample->current_activities = subtle::NoBarrier_Load(&current_activities_);
334 }
335
278 // StackSamplingProfiler::Frame global functions ------------------------------ 336 // StackSamplingProfiler::Frame global functions ------------------------------
279 337
280 bool operator==(const StackSamplingProfiler::Module& a, 338 bool operator==(const StackSamplingProfiler::Module& a,
281 const StackSamplingProfiler::Module& b) { 339 const StackSamplingProfiler::Module& b) {
282 return a.base_address == b.base_address && a.id == b.id && 340 return a.base_address == b.base_address && a.id == b.id &&
283 a.filename == b.filename; 341 a.filename == b.filename;
284 } 342 }
285 343
344 bool operator==(const StackSamplingProfiler::Sample& a,
345 const StackSamplingProfiler::Sample& b) {
346 return a.process_phases == b.process_phases &&
347 a.current_activities == b.current_activities && a.frames == b.frames;
348 }
349
350 bool operator!=(const StackSamplingProfiler::Sample& a,
351 const StackSamplingProfiler::Sample& b) {
352 return !(a == b);
353 }
354
355 bool operator<(const StackSamplingProfiler::Sample& a,
356 const StackSamplingProfiler::Sample& b) {
357 if (a.process_phases < b.process_phases)
358 return true;
359 if (a.process_phases > b.process_phases)
360 return false;
361
362 if (a.current_activities < b.current_activities)
363 return true;
364 if (a.current_activities > b.current_activities)
365 return false;
366
367 return a.frames < b.frames;
368 }
369
286 bool operator==(const StackSamplingProfiler::Frame &a, 370 bool operator==(const StackSamplingProfiler::Frame &a,
287 const StackSamplingProfiler::Frame &b) { 371 const StackSamplingProfiler::Frame &b) {
288 return a.instruction_pointer == b.instruction_pointer && 372 return a.instruction_pointer == b.instruction_pointer &&
289 a.module_index == b.module_index; 373 a.module_index == b.module_index;
290 } 374 }
291 375
292 bool operator<(const StackSamplingProfiler::Frame &a, 376 bool operator<(const StackSamplingProfiler::Frame &a,
293 const StackSamplingProfiler::Frame &b) { 377 const StackSamplingProfiler::Frame &b) {
294 return (a.module_index < b.module_index) || 378 return (a.module_index < b.module_index) ||
295 (a.module_index == b.module_index && 379 (a.module_index == b.module_index &&
296 a.instruction_pointer < b.instruction_pointer); 380 a.instruction_pointer < b.instruction_pointer);
297 } 381 }
298 382
299 } // namespace base 383 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698