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

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(const Frame& frame) {
131 frames.push_back(std::move(frame));
132 }
133
134 StackSamplingProfiler::Sample::Sample(const std::vector<Frame>& frames)
135 : frames(frames) {}
136
108 // StackSamplingProfiler::CallStackProfile ------------------------------------ 137 // StackSamplingProfiler::CallStackProfile ------------------------------------
109 138
110 StackSamplingProfiler::CallStackProfile::CallStackProfile() {} 139 StackSamplingProfiler::CallStackProfile::CallStackProfile() {}
111 140
112 StackSamplingProfiler::CallStackProfile::CallStackProfile( 141 StackSamplingProfiler::CallStackProfile::CallStackProfile(
113 const CallStackProfile& other) = default; 142 const CallStackProfile& other) = default;
114 143
115 StackSamplingProfiler::CallStackProfile::~CallStackProfile() {} 144 StackSamplingProfiler::CallStackProfile::~CallStackProfile() {}
116 145
117 // StackSamplingProfiler::SamplingThread -------------------------------------- 146 // StackSamplingProfiler::SamplingThread --------------------------------------
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 // stop_event_. 193 // stop_event_.
165 if (stop_event_.TimedWait( 194 if (stop_event_.TimedWait(
166 std::max(params_.sampling_interval - previous_elapsed_sample_time, 195 std::max(params_.sampling_interval - previous_elapsed_sample_time,
167 TimeDelta()))) { 196 TimeDelta()))) {
168 *was_stopped = true; 197 *was_stopped = true;
169 break; 198 break;
170 } 199 }
171 } 200 }
172 ElapsedTimer sample_timer; 201 ElapsedTimer sample_timer;
173 profile->samples.push_back(Sample()); 202 profile->samples.push_back(Sample());
174 native_sampler_->RecordStackSample(&profile->samples.back()); 203 Sample& sample = profile->samples.back();
204 native_sampler_->RecordStackSample(&sample);
205 sample.process_phases = subtle::NoBarrier_Load(&process_phases_);
206 sample.current_activities = subtle::NoBarrier_Load(&current_activities_);
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 22 matching lines...) Expand all
207 239
208 if (was_stopped) 240 if (was_stopped)
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
249 // static
250 void StackSamplingProfiler::SetProcessPhase(ProcessPhase phase) {
251 DCHECK_EQ(0, subtle::NoBarrier_Load(&process_phases_) & (1 << phase));
252 ChangeAtomicFlags(&process_phases_, 1 << phase, 0);
253 }
254
255 // static
256 void StackSamplingProfiler::RecordActivityBegin(ProcessActivity activity) {
257 ChangeAtomicFlags(&current_activities_, 1 << activity, 0);
258 }
259
260 // static
261 void StackSamplingProfiler::RecordActivityEnd(ProcessActivity activity) {
262 ChangeAtomicFlags(&current_activities_, 0, 1 << activity);
263 }
264
217 // StackSamplingProfiler ------------------------------------------------------ 265 // StackSamplingProfiler ------------------------------------------------------
218 266
267 subtle::Atomic32 StackSamplingProfiler::process_phases_ = 0;
268 subtle::Atomic32 StackSamplingProfiler::current_activities_ = 0;
269
219 StackSamplingProfiler::SamplingParams::SamplingParams() 270 StackSamplingProfiler::SamplingParams::SamplingParams()
220 : initial_delay(TimeDelta::FromMilliseconds(0)), 271 : initial_delay(TimeDelta::FromMilliseconds(0)),
221 bursts(1), 272 bursts(1),
222 burst_interval(TimeDelta::FromMilliseconds(10000)), 273 burst_interval(TimeDelta::FromMilliseconds(10000)),
223 samples_per_burst(300), 274 samples_per_burst(300),
224 sampling_interval(TimeDelta::FromMilliseconds(100)) { 275 sampling_interval(TimeDelta::FromMilliseconds(100)) {
225 } 276 }
226 277
227 StackSamplingProfiler::StackSamplingProfiler( 278 StackSamplingProfiler::StackSamplingProfiler(
228 PlatformThreadId thread_id, 279 PlatformThreadId thread_id,
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 } 327 }
277 328
278 // StackSamplingProfiler::Frame global functions ------------------------------ 329 // StackSamplingProfiler::Frame global functions ------------------------------
279 330
280 bool operator==(const StackSamplingProfiler::Module& a, 331 bool operator==(const StackSamplingProfiler::Module& a,
281 const StackSamplingProfiler::Module& b) { 332 const StackSamplingProfiler::Module& b) {
282 return a.base_address == b.base_address && a.id == b.id && 333 return a.base_address == b.base_address && a.id == b.id &&
283 a.filename == b.filename; 334 a.filename == b.filename;
284 } 335 }
285 336
337 bool operator==(const StackSamplingProfiler::Sample& a,
338 const StackSamplingProfiler::Sample& b) {
339 return a.process_phases == b.process_phases &&
340 a.current_activities == b.current_activities && a.frames == b.frames;
341 }
342
343 bool operator!=(const StackSamplingProfiler::Sample& a,
344 const StackSamplingProfiler::Sample& b) {
345 return !(a == b);
346 }
347
348 bool operator<(const StackSamplingProfiler::Sample& a,
349 const StackSamplingProfiler::Sample& b) {
350 if (a.process_phases < b.process_phases)
351 return true;
352 if (a.process_phases > b.process_phases)
353 return false;
354
355 if (a.current_activities < b.current_activities)
356 return true;
357 if (a.current_activities > b.current_activities)
358 return false;
359
360 return a.frames < b.frames;
361 }
362
286 bool operator==(const StackSamplingProfiler::Frame &a, 363 bool operator==(const StackSamplingProfiler::Frame &a,
287 const StackSamplingProfiler::Frame &b) { 364 const StackSamplingProfiler::Frame &b) {
288 return a.instruction_pointer == b.instruction_pointer && 365 return a.instruction_pointer == b.instruction_pointer &&
289 a.module_index == b.module_index; 366 a.module_index == b.module_index;
290 } 367 }
291 368
292 bool operator<(const StackSamplingProfiler::Frame &a, 369 bool operator<(const StackSamplingProfiler::Frame &a,
293 const StackSamplingProfiler::Frame &b) { 370 const StackSamplingProfiler::Frame &b) {
294 return (a.module_index < b.module_index) || 371 return (a.module_index < b.module_index) ||
295 (a.module_index == b.module_index && 372 (a.module_index == b.module_index &&
296 a.instruction_pointer < b.instruction_pointer); 373 a.instruction_pointer < b.instruction_pointer);
297 } 374 }
298 375
299 } // namespace base 376 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698