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 6e320c82067651a5cf5390b6de17656d3ca8e9fa..b362e4be19a2c7d1c1c18e56e4c67771a9ead3c4 100644 |
| --- a/components/metrics/call_stack_profile_metrics_provider.cc |
| +++ b/components/metrics/call_stack_profile_metrics_provider.cc |
| @@ -33,6 +33,21 @@ namespace metrics { |
| namespace { |
| +// Provide a mapping from the C++ "enum" definition of various process phases |
| +// to the equivalent protobuf "enum" definition. This table-lookup conversion |
| +// allows for the implementation to evolve and still be compatible with the |
| +// protobuf -- even if there are ever more than 32 defined proto values, though |
| +// never more than 32 could be in-use in a given C++ version of the code. |
| +const ProcessPhase |
| + kProtoPhases[CallStackProfileMetricsProvider::PHASES_MAX_VALUE] = { |
| + ProcessPhase::MAIN_LOOP_START, |
| + ProcessPhase::MAIN_NAVIGATION_START, |
| + ProcessPhase::MAIN_NAVIGATION_FINISHED, |
| + ProcessPhase::FIRST_NONEMPTY_PAINT, |
| + |
| + ProcessPhase::SHUTDOWN_START, |
| +}; |
| + |
| // ProfilesState -------------------------------------------------------------- |
| // A set of profiles and the CallStackProfileMetricsProvider state associated |
| @@ -223,7 +238,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 |
| @@ -239,6 +254,26 @@ void CopySampleToProto( |
| } |
| } |
| +// Transcode Sample annotations into protobuf fields. The C++ code uses a bit- |
| +// field with each bit correspondirg to an entry in an enumeration while the |
|
Mike Wittman
2016/11/16 22:36:09
nit: corresponding
bcwhite
2016/11/16 23:10:49
Done.
|
| +// protobuf uses a repeated field of individual values. Conversion tables |
| +// allow for arbitrary mapping, though no more than 32 in any given version |
| +// of the code. |
| +void CopyAnnotationsToProto(uint32_t new_phases, |
| + CallStackProfile::Sample* sample_proto) { |
| + for (size_t bit = 0; new_phases != 0 && bit < sizeof(new_phases) * 8; ++bit) { |
| + const uint32_t flag = 1U << bit; |
| + if (new_phases & flag) { |
| + if (bit >= arraysize(kProtoPhases)) { |
| + NOTREACHED(); |
| + continue; |
| + } |
| + sample_proto->add_process_phase(kProtoPhases[bit]); |
| + new_phases ^= flag; // Bit is set so XOR will clear it. |
| + } |
| + } |
| +} |
| + |
| // Transcode |profile| into |proto_profile|. |
| void CopyProfileToProto( |
| const StackSamplingProfiler::CallStackProfile& profile, |
| @@ -250,11 +285,15 @@ void CopyProfileToProto( |
| if (ordering_spec == CallStackProfileParams::PRESERVE_ORDER) { |
| // Collapse only consecutive repeated samples together. |
| CallStackProfile::Sample* current_sample_proto = nullptr; |
| + uint32_t phases = 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, |
| + current_sample_proto); |
| + phases = it->process_phases; |
| } else { |
| current_sample_proto->set_count(current_sample_proto->count() + 1); |
| } |
| @@ -268,6 +307,7 @@ 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, sample_proto); |
| sample_index.insert( |
| std::make_pair( |
| *it, static_cast<int>(proto_profile->sample().size()) - 1)); |