| Index: components/metrics/call_stack_profile_metrics_provider.cc
|
| diff --git a/components/metrics/call_stack_profile_metrics_provider.cc b/components/metrics/call_stack_profile_metrics_provider.cc
|
| index 9f323fdc28a48f2708826ddd768e1a8118dc8367..d17992fceb35837ef0949b8ef4076060f7c387f8 100644
|
| --- a/components/metrics/call_stack_profile_metrics_provider.cc
|
| +++ b/components/metrics/call_stack_profile_metrics_provider.cc
|
| @@ -229,7 +229,7 @@ void CopySampleToProto(
|
| const StackSamplingProfiler::Sample& sample,
|
| const std::vector<StackSamplingProfiler::Module>& modules,
|
| CallStackProfile::Sample* proto_sample) {
|
| - for (const StackSamplingProfiler::Frame& frame : sample) {
|
| + for (const StackSamplingProfiler::Frame& frame : sample.frames) {
|
| CallStackProfile::Entry* entry = proto_sample->add_entry();
|
| // A frame may not have a valid module. If so, we can't compute the
|
| // instruction pointer offset, and we don't want to send bare pointers, so
|
| @@ -245,6 +245,38 @@ void CopySampleToProto(
|
| }
|
| }
|
|
|
| +// Transcode Sample annotations into protobuf fields.
|
| +void CopyAnnotationsToProto(uint32_t new_phases,
|
| + uint32_t activities_begun,
|
| + uint32_t activities_ended,
|
| + CallStackProfile::Sample* sample_proto) {
|
| + for (size_t bit = 0; new_phases != 0 && bit < sizeof(new_phases) * 8;
|
| + ++bit, new_phases >>= 1) {
|
| + if (new_phases & 1) {
|
| + sample_proto->add_process_phase(
|
| + static_cast<metrics::ProcessPhase>(bit));
|
| + }
|
| + }
|
| +
|
| + for (size_t bit = 0;
|
| + activities_begun != 0 && bit < sizeof(activities_begun) * 8;
|
| + ++bit, activities_begun >>= 1) {
|
| + if (activities_begun & 1) {
|
| + sample_proto->add_activities_begun(
|
| + static_cast<metrics::ProcessActivity>(bit));
|
| + }
|
| + }
|
| +
|
| + for (size_t bit = 0;
|
| + activities_ended != 0 && bit < sizeof(activities_ended) * 8;
|
| + ++bit, activities_ended >>= 1) {
|
| + if (activities_ended & 1) {
|
| + sample_proto->add_activities_ended(
|
| + static_cast<metrics::ProcessActivity>(bit));
|
| + }
|
| + }
|
| +}
|
| +
|
| // Transcode |profile| into |proto_profile|.
|
| void CopyProfileToProto(
|
| const StackSamplingProfiler::CallStackProfile& profile,
|
| @@ -256,11 +288,20 @@ void CopyProfileToProto(
|
| if (ordering_spec == CallStackProfileParams::PRESERVE_ORDER) {
|
| // Collapse only consecutive repeated samples together.
|
| CallStackProfile::Sample* current_sample_proto = nullptr;
|
| + uint32_t phases = 0;
|
| + uint32_t activities = 0;
|
| for (auto it = profile.samples.begin(); it != profile.samples.end(); ++it) {
|
| if (!current_sample_proto || *it != *(it - 1)) {
|
| current_sample_proto = proto_profile->add_sample();
|
| CopySampleToProto(*it, profile.modules, current_sample_proto);
|
| current_sample_proto->set_count(1);
|
| + CopyAnnotationsToProto(
|
| + it->process_phases & ~phases, // Phases are "set only".
|
| + it->current_activities & ~activities, // Activities can begin
|
| + activities & ~it->current_activities, // and end.
|
| + current_sample_proto);
|
| + phases = it->process_phases;
|
| + activities = it->current_activities;
|
| } else {
|
| current_sample_proto->set_count(current_sample_proto->count() + 1);
|
| }
|
| @@ -274,6 +315,8 @@ void CopyProfileToProto(
|
| CallStackProfile::Sample* sample_proto = proto_profile->add_sample();
|
| CopySampleToProto(*it, profile.modules, sample_proto);
|
| sample_proto->set_count(1);
|
| + CopyAnnotationsToProto(it->process_phases, it->current_activities, 0,
|
| + sample_proto);
|
| sample_index.insert(
|
| std::make_pair(
|
| *it, static_cast<int>(proto_profile->sample().size()) - 1));
|
|
|