Chromium Code Reviews| 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..a4f64a79b3a5830d1c7874cdf1feba87c7af7e56 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 |
| @@ -256,11 +256,46 @@ 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); |
| + |
| + // Phases are "set only" so current is always superset of last-seen. |
|
Mike Wittman
2016/11/02 21:44:04
Also, this logic could stand to be extracted into
Mike Wittman
2016/11/02 21:44:04
The process phase/activities encoding should have
bcwhite
2016/11/03 18:29:50
OMG the existing tests are ugly! <shudder>
Done.
bcwhite
2016/11/03 18:29:50
Done.
|
| + uint32_t bits = it->process_phases & ~phases; |
| + for (size_t bit = 0; bits != 0 && bit < sizeof(phases) * 8; |
| + ++bit, bits >>= 1) { |
| + if (bits & 1) { |
| + current_sample_proto->add_process_phase( |
| + static_cast<metrics::ProcessPhase>(1 << bit)); |
| + } |
| + } |
| + |
| + // New activities can begin. |
| + bits = it->current_activities & ~activities; |
| + for (size_t bit = 0; bits != 0 && bit < sizeof(phases) * 8; |
| + ++bit, bits >>= 1) { |
| + if (bits & 1) { |
| + current_sample_proto->add_activities_begun( |
| + static_cast<metrics::ProcessActivity>(1 << bit)); |
| + } |
| + } |
| + |
| + // And existing activities can end. |
| + bits = activities & ~it->current_activities; |
| + for (size_t bit = 0; bits != 0 && bit < sizeof(phases) * 8; |
| + ++bit, bits >>= 1) { |
| + if (bits & 1) { |
| + current_sample_proto->add_activities_ended( |
| + static_cast<metrics::ProcessActivity>(1 << bit)); |
| + } |
| + } |
| + |
| + phases = it->process_phases; |
| + activities = it->current_activities; |
| } else { |
| current_sample_proto->set_count(current_sample_proto->count() + 1); |
| } |