Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(457)

Side by Side Diff: components/metrics/call_stack_profile_metrics_provider.cc

Issue 2444143002: Add process lifetime annotations to stack samples. (Closed)
Patch Set: updated proto to pass individual repeated enumeration values Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 memcpy(&name_bytes[0], &basename[0], basename_length_in_bytes); 222 memcpy(&name_bytes[0], &basename[0], basename_length_in_bytes);
223 return base::HashMetricName(name_bytes); 223 return base::HashMetricName(name_bytes);
224 } 224 }
225 225
226 // Transcode |sample| into |proto_sample|, using base addresses in |modules| to 226 // Transcode |sample| into |proto_sample|, using base addresses in |modules| to
227 // compute module instruction pointer offsets. 227 // compute module instruction pointer offsets.
228 void CopySampleToProto( 228 void CopySampleToProto(
229 const StackSamplingProfiler::Sample& sample, 229 const StackSamplingProfiler::Sample& sample,
230 const std::vector<StackSamplingProfiler::Module>& modules, 230 const std::vector<StackSamplingProfiler::Module>& modules,
231 CallStackProfile::Sample* proto_sample) { 231 CallStackProfile::Sample* proto_sample) {
232 for (const StackSamplingProfiler::Frame& frame : sample) { 232 for (const StackSamplingProfiler::Frame& frame : sample.frames) {
233 CallStackProfile::Entry* entry = proto_sample->add_entry(); 233 CallStackProfile::Entry* entry = proto_sample->add_entry();
234 // A frame may not have a valid module. If so, we can't compute the 234 // A frame may not have a valid module. If so, we can't compute the
235 // instruction pointer offset, and we don't want to send bare pointers, so 235 // instruction pointer offset, and we don't want to send bare pointers, so
236 // leave call_stack_entry empty. 236 // leave call_stack_entry empty.
237 if (frame.module_index == StackSamplingProfiler::Frame::kUnknownModuleIndex) 237 if (frame.module_index == StackSamplingProfiler::Frame::kUnknownModuleIndex)
238 continue; 238 continue;
239 int64_t module_offset = 239 int64_t module_offset =
240 reinterpret_cast<const char*>(frame.instruction_pointer) - 240 reinterpret_cast<const char*>(frame.instruction_pointer) -
241 reinterpret_cast<const char*>(modules[frame.module_index].base_address); 241 reinterpret_cast<const char*>(modules[frame.module_index].base_address);
242 DCHECK_GE(module_offset, 0); 242 DCHECK_GE(module_offset, 0);
243 entry->set_address(static_cast<uint64_t>(module_offset)); 243 entry->set_address(static_cast<uint64_t>(module_offset));
244 entry->set_module_id_index(frame.module_index); 244 entry->set_module_id_index(frame.module_index);
245 } 245 }
246 } 246 }
247 247
248 // Transcode |profile| into |proto_profile|. 248 // Transcode |profile| into |proto_profile|.
249 void CopyProfileToProto( 249 void CopyProfileToProto(
250 const StackSamplingProfiler::CallStackProfile& profile, 250 const StackSamplingProfiler::CallStackProfile& profile,
251 CallStackProfileParams::SampleOrderingSpec ordering_spec, 251 CallStackProfileParams::SampleOrderingSpec ordering_spec,
252 CallStackProfile* proto_profile) { 252 CallStackProfile* proto_profile) {
253 if (profile.samples.empty()) 253 if (profile.samples.empty())
254 return; 254 return;
255 255
256 if (ordering_spec == CallStackProfileParams::PRESERVE_ORDER) { 256 if (ordering_spec == CallStackProfileParams::PRESERVE_ORDER) {
257 // Collapse only consecutive repeated samples together. 257 // Collapse only consecutive repeated samples together.
258 CallStackProfile::Sample* current_sample_proto = nullptr; 258 CallStackProfile::Sample* current_sample_proto = nullptr;
259 uint32_t phases = 0;
260 uint32_t activities = 0;
259 for (auto it = profile.samples.begin(); it != profile.samples.end(); ++it) { 261 for (auto it = profile.samples.begin(); it != profile.samples.end(); ++it) {
260 if (!current_sample_proto || *it != *(it - 1)) { 262 if (!current_sample_proto || *it != *(it - 1)) {
261 current_sample_proto = proto_profile->add_sample(); 263 current_sample_proto = proto_profile->add_sample();
262 CopySampleToProto(*it, profile.modules, current_sample_proto); 264 CopySampleToProto(*it, profile.modules, current_sample_proto);
263 current_sample_proto->set_count(1); 265 current_sample_proto->set_count(1);
266
267 // 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.
268 uint32_t bits = it->process_phases & ~phases;
269 for (size_t bit = 0; bits != 0 && bit < sizeof(phases) * 8;
270 ++bit, bits >>= 1) {
271 if (bits & 1) {
272 current_sample_proto->add_process_phase(
273 static_cast<metrics::ProcessPhase>(1 << bit));
274 }
275 }
276
277 // New activities can begin.
278 bits = it->current_activities & ~activities;
279 for (size_t bit = 0; bits != 0 && bit < sizeof(phases) * 8;
280 ++bit, bits >>= 1) {
281 if (bits & 1) {
282 current_sample_proto->add_activities_begun(
283 static_cast<metrics::ProcessActivity>(1 << bit));
284 }
285 }
286
287 // And existing activities can end.
288 bits = activities & ~it->current_activities;
289 for (size_t bit = 0; bits != 0 && bit < sizeof(phases) * 8;
290 ++bit, bits >>= 1) {
291 if (bits & 1) {
292 current_sample_proto->add_activities_ended(
293 static_cast<metrics::ProcessActivity>(1 << bit));
294 }
295 }
296
297 phases = it->process_phases;
298 activities = it->current_activities;
264 } else { 299 } else {
265 current_sample_proto->set_count(current_sample_proto->count() + 1); 300 current_sample_proto->set_count(current_sample_proto->count() + 1);
266 } 301 }
267 } 302 }
268 } else { 303 } else {
269 // Collapse all repeated samples together. 304 // Collapse all repeated samples together.
270 std::map<StackSamplingProfiler::Sample, int> sample_index; 305 std::map<StackSamplingProfiler::Sample, int> sample_index;
271 for (auto it = profile.samples.begin(); it != profile.samples.end(); ++it) { 306 for (auto it = profile.samples.begin(); it != profile.samples.end(); ++it) {
272 auto location = sample_index.find(*it); 307 auto location = sample_index.find(*it);
273 if (location == sample_index.end()) { 308 if (location == sample_index.end()) {
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 484
450 // static 485 // static
451 bool CallStackProfileMetricsProvider::IsReportingEnabledByFieldTrial() { 486 bool CallStackProfileMetricsProvider::IsReportingEnabledByFieldTrial() {
452 const std::string group_name = base::FieldTrialList::FindFullName( 487 const std::string group_name = base::FieldTrialList::FindFullName(
453 CallStackProfileMetricsProvider::kFieldTrialName); 488 CallStackProfileMetricsProvider::kFieldTrialName);
454 return group_name == 489 return group_name ==
455 CallStackProfileMetricsProvider::kReportProfilesGroupName; 490 CallStackProfileMetricsProvider::kReportProfilesGroupName;
456 } 491 }
457 492
458 } // namespace metrics 493 } // namespace metrics
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698