| OLD | NEW |
| 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 "components/metrics/call_stack_profile_metrics_provider.h" | 5 #include "components/metrics/call_stack_profile_metrics_provider.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 memcpy(&name_bytes[0], &basename[0], basename_length_in_bytes); | 213 memcpy(&name_bytes[0], &basename[0], basename_length_in_bytes); |
| 214 return base::HashMetricName(name_bytes); | 214 return base::HashMetricName(name_bytes); |
| 215 } | 215 } |
| 216 | 216 |
| 217 // Transcode |sample| into |proto_sample|, using base addresses in |modules| to | 217 // Transcode |sample| into |proto_sample|, using base addresses in |modules| to |
| 218 // compute module instruction pointer offsets. | 218 // compute module instruction pointer offsets. |
| 219 void CopySampleToProto( | 219 void CopySampleToProto( |
| 220 const StackSamplingProfiler::Sample& sample, | 220 const StackSamplingProfiler::Sample& sample, |
| 221 const std::vector<StackSamplingProfiler::Module>& modules, | 221 const std::vector<StackSamplingProfiler::Module>& modules, |
| 222 CallStackProfile::Sample* proto_sample) { | 222 CallStackProfile::Sample* proto_sample) { |
| 223 for (const StackSamplingProfiler::Frame& frame : sample) { | 223 for (const StackSamplingProfiler::Frame& frame : sample.frames) { |
| 224 CallStackProfile::Entry* entry = proto_sample->add_entry(); | 224 CallStackProfile::Entry* entry = proto_sample->add_entry(); |
| 225 // A frame may not have a valid module. If so, we can't compute the | 225 // A frame may not have a valid module. If so, we can't compute the |
| 226 // instruction pointer offset, and we don't want to send bare pointers, so | 226 // instruction pointer offset, and we don't want to send bare pointers, so |
| 227 // leave call_stack_entry empty. | 227 // leave call_stack_entry empty. |
| 228 if (frame.module_index == StackSamplingProfiler::Frame::kUnknownModuleIndex) | 228 if (frame.module_index == StackSamplingProfiler::Frame::kUnknownModuleIndex) |
| 229 continue; | 229 continue; |
| 230 int64_t module_offset = | 230 int64_t module_offset = |
| 231 reinterpret_cast<const char*>(frame.instruction_pointer) - | 231 reinterpret_cast<const char*>(frame.instruction_pointer) - |
| 232 reinterpret_cast<const char*>(modules[frame.module_index].base_address); | 232 reinterpret_cast<const char*>(modules[frame.module_index].base_address); |
| 233 DCHECK_GE(module_offset, 0); | 233 DCHECK_GE(module_offset, 0); |
| 234 entry->set_address(static_cast<uint64_t>(module_offset)); | 234 entry->set_address(static_cast<uint64_t>(module_offset)); |
| 235 entry->set_module_id_index(frame.module_index); | 235 entry->set_module_id_index(frame.module_index); |
| 236 } | 236 } |
| 237 } | 237 } |
| 238 | 238 |
| 239 // Transcode |profile| into |proto_profile|. | 239 // Transcode |profile| into |proto_profile|. |
| 240 void CopyProfileToProto( | 240 void CopyProfileToProto( |
| 241 const StackSamplingProfiler::CallStackProfile& profile, | 241 const StackSamplingProfiler::CallStackProfile& profile, |
| 242 CallStackProfileParams::SampleOrderingSpec ordering_spec, | 242 CallStackProfileParams::SampleOrderingSpec ordering_spec, |
| 243 CallStackProfile* proto_profile) { | 243 CallStackProfile* proto_profile) { |
| 244 if (profile.samples.empty()) | 244 if (profile.samples.empty()) |
| 245 return; | 245 return; |
| 246 | 246 |
| 247 if (ordering_spec == CallStackProfileParams::PRESERVE_ORDER) { | 247 if (ordering_spec == CallStackProfileParams::PRESERVE_ORDER) { |
| 248 // Collapse only consecutive repeated samples together. | 248 // Collapse only consecutive repeated samples together. |
| 249 CallStackProfile::Sample* current_sample_proto = nullptr; | 249 CallStackProfile::Sample* current_sample_proto = nullptr; |
| 250 int32_t phases = 0; |
| 251 int32_t activities = 0; |
| 250 for (auto it = profile.samples.begin(); it != profile.samples.end(); ++it) { | 252 for (auto it = profile.samples.begin(); it != profile.samples.end(); ++it) { |
| 251 if (!current_sample_proto || *it != *(it - 1)) { | 253 if (!current_sample_proto || *it != *(it - 1)) { |
| 252 current_sample_proto = proto_profile->add_sample(); | 254 current_sample_proto = proto_profile->add_sample(); |
| 253 CopySampleToProto(*it, profile.modules, current_sample_proto); | 255 CopySampleToProto(*it, profile.modules, current_sample_proto); |
| 254 current_sample_proto->set_count(1); | 256 current_sample_proto->set_count(1); |
| 257 if (it->process_phases != phases) { |
| 258 phases = it->process_phases; |
| 259 current_sample_proto->set_process_phases(phases); |
| 260 } |
| 261 if (it->current_activities != activities) { |
| 262 activities = it->current_activities; |
| 263 current_sample_proto->set_current_activities(activities); |
| 264 } |
| 255 } else { | 265 } else { |
| 256 current_sample_proto->set_count(current_sample_proto->count() + 1); | 266 current_sample_proto->set_count(current_sample_proto->count() + 1); |
| 257 } | 267 } |
| 258 } | 268 } |
| 259 } else { | 269 } else { |
| 260 // Collapse all repeated samples together. | 270 // Collapse all repeated samples together. |
| 261 std::map<StackSamplingProfiler::Sample, int> sample_index; | 271 std::map<StackSamplingProfiler::Sample, int> sample_index; |
| 262 for (auto it = profile.samples.begin(); it != profile.samples.end(); ++it) { | 272 for (auto it = profile.samples.begin(); it != profile.samples.end(); ++it) { |
| 263 auto location = sample_index.find(*it); | 273 auto location = sample_index.find(*it); |
| 264 if (location == sample_index.end()) { | 274 if (location == sample_index.end()) { |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 | 450 |
| 441 // static | 451 // static |
| 442 bool CallStackProfileMetricsProvider::IsReportingEnabledByFieldTrial() { | 452 bool CallStackProfileMetricsProvider::IsReportingEnabledByFieldTrial() { |
| 443 const std::string group_name = base::FieldTrialList::FindFullName( | 453 const std::string group_name = base::FieldTrialList::FindFullName( |
| 444 CallStackProfileMetricsProvider::kFieldTrialName); | 454 CallStackProfileMetricsProvider::kFieldTrialName); |
| 445 return group_name == | 455 return group_name == |
| 446 CallStackProfileMetricsProvider::kReportProfilesGroupName; | 456 CallStackProfileMetricsProvider::kReportProfilesGroupName; |
| 447 } | 457 } |
| 448 | 458 |
| 449 } // namespace metrics | 459 } // namespace metrics |
| OLD | NEW |