| Index: base/profiler/stack_sampling_profiler.cc
|
| diff --git a/base/profiler/stack_sampling_profiler.cc b/base/profiler/stack_sampling_profiler.cc
|
| index 538368bd23f6fd63d25dfefa6e6ea68f5a785208..2b7ea893e84040100da9a0d101ec6397816f5a4c 100644
|
| --- a/base/profiler/stack_sampling_profiler.cc
|
| +++ b/base/profiler/stack_sampling_profiler.cc
|
| @@ -81,6 +81,22 @@ void AsyncRunner::RunCallbackAndDeleteInstance(
|
| task_runner->DeleteSoon(FROM_HERE, object_to_be_deleted.release());
|
| }
|
|
|
| +void ChangeAtomicFlags(subtle::Atomic32* flags,
|
| + subtle::Atomic32 set,
|
| + subtle::Atomic32 clear) {
|
| + DCHECK(set != 0 || clear != 0);
|
| + DCHECK_EQ(0, set & clear);
|
| +
|
| + subtle::Atomic32 bits = subtle::NoBarrier_Load(flags);
|
| + while (true) {
|
| + subtle::Atomic32 existing =
|
| + subtle::NoBarrier_CompareAndSwap(flags, bits, (bits | set) & ~clear);
|
| + if (existing == bits)
|
| + break;
|
| + bits = existing;
|
| + }
|
| +}
|
| +
|
| } // namespace
|
|
|
| // StackSamplingProfiler::Module ----------------------------------------------
|
| @@ -105,6 +121,21 @@ StackSamplingProfiler::Frame::Frame()
|
| : instruction_pointer(0), module_index(kUnknownModuleIndex) {
|
| }
|
|
|
| +// StackSamplingProfiler::Sample ----------------------------------------------
|
| +
|
| +StackSamplingProfiler::Sample::Sample() {}
|
| +
|
| +StackSamplingProfiler::Sample::Sample(const Sample& sample) = default;
|
| +
|
| +StackSamplingProfiler::Sample::~Sample() {}
|
| +
|
| +StackSamplingProfiler::Sample::Sample(const Frame& frame) {
|
| + frames.push_back(std::move(frame));
|
| +}
|
| +
|
| +StackSamplingProfiler::Sample::Sample(const std::vector<Frame>& frames)
|
| + : frames(frames) {}
|
| +
|
| // StackSamplingProfiler::CallStackProfile ------------------------------------
|
|
|
| StackSamplingProfiler::CallStackProfile::CallStackProfile() {}
|
| @@ -171,7 +202,10 @@ void StackSamplingProfiler::SamplingThread::CollectProfile(
|
| }
|
| ElapsedTimer sample_timer;
|
| profile->samples.push_back(Sample());
|
| - native_sampler_->RecordStackSample(&profile->samples.back());
|
| + Sample& sample = profile->samples.back();
|
| + native_sampler_->RecordStackSample(&sample);
|
| + sample.process_phases = subtle::NoBarrier_Load(&process_phases_);
|
| + sample.current_activities = subtle::NoBarrier_Load(¤t_activities_);
|
| previous_elapsed_sample_time = sample_timer.Elapsed();
|
| }
|
|
|
| @@ -214,8 +248,27 @@ void StackSamplingProfiler::SamplingThread::Stop() {
|
| stop_event_.Signal();
|
| }
|
|
|
| +// static
|
| +void StackSamplingProfiler::SetProcessPhase(ProcessPhase phase) {
|
| + DCHECK_EQ(0, subtle::NoBarrier_Load(&process_phases_) & (1 << phase));
|
| + ChangeAtomicFlags(&process_phases_, 1 << phase, 0);
|
| +}
|
| +
|
| +// static
|
| +void StackSamplingProfiler::RecordActivityBegin(ProcessActivity activity) {
|
| + ChangeAtomicFlags(¤t_activities_, 1 << activity, 0);
|
| +}
|
| +
|
| +// static
|
| +void StackSamplingProfiler::RecordActivityEnd(ProcessActivity activity) {
|
| + ChangeAtomicFlags(¤t_activities_, 0, 1 << activity);
|
| +}
|
| +
|
| // StackSamplingProfiler ------------------------------------------------------
|
|
|
| +subtle::Atomic32 StackSamplingProfiler::process_phases_ = 0;
|
| +subtle::Atomic32 StackSamplingProfiler::current_activities_ = 0;
|
| +
|
| StackSamplingProfiler::SamplingParams::SamplingParams()
|
| : initial_delay(TimeDelta::FromMilliseconds(0)),
|
| bursts(1),
|
| @@ -283,6 +336,32 @@ bool operator==(const StackSamplingProfiler::Module& a,
|
| a.filename == b.filename;
|
| }
|
|
|
| +bool operator==(const StackSamplingProfiler::Sample& a,
|
| + const StackSamplingProfiler::Sample& b) {
|
| + return a.process_phases == b.process_phases &&
|
| + a.current_activities == b.current_activities && a.frames == b.frames;
|
| +}
|
| +
|
| +bool operator!=(const StackSamplingProfiler::Sample& a,
|
| + const StackSamplingProfiler::Sample& b) {
|
| + return !(a == b);
|
| +}
|
| +
|
| +bool operator<(const StackSamplingProfiler::Sample& a,
|
| + const StackSamplingProfiler::Sample& b) {
|
| + if (a.process_phases < b.process_phases)
|
| + return true;
|
| + if (a.process_phases > b.process_phases)
|
| + return false;
|
| +
|
| + if (a.current_activities < b.current_activities)
|
| + return true;
|
| + if (a.current_activities > b.current_activities)
|
| + return false;
|
| +
|
| + return a.frames < b.frames;
|
| +}
|
| +
|
| bool operator==(const StackSamplingProfiler::Frame &a,
|
| const StackSamplingProfiler::Frame &b) {
|
| return a.instruction_pointer == b.instruction_pointer &&
|
|
|