Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 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 import collections | 4 import collections |
| 5 import itertools | 5 import itertools |
| 6 | 6 |
| 7 from metrics import Metric | 7 from metrics import Metric |
| 8 from telemetry.core.timeline import bounds | 8 from telemetry.core.timeline import bounds |
| 9 from telemetry.page import page_measurement | 9 from telemetry.page import page_measurement |
| 10 | 10 |
| 11 TRACING_MODE = 'tracing-mode' | 11 TRACING_MODE = 'tracing-mode' |
| 12 TIMELINE_MODE = 'timeline-mode' | 12 TIMELINE_MODE = 'timeline-mode' |
| 13 | 13 |
| 14 # All tracing categories not disabled-by-default | |
| 15 DEFAULT_TRACE_CATEGORIES = None | |
| 16 | |
| 17 # Categories for absolute minimum overhead tracing. This contains no | |
| 18 # sub-traces of thread tasks, so it's only useful for capturing the | |
| 19 # cpu-time spent on threads (as well as needed benchmark traces) | |
| 20 # "disabled-by-default-topall," | |
|
ernstm
2014/02/19 22:18:16
In the comment: disabled-by-default-topall -> disa
| |
| 21 MINIMAL_TRACE_CATEGORIES = ("disabled-by-default-poll_cpu," | |
| 22 "benchmark," | |
| 23 "webkit.console," | |
| 24 "trace_event_overhead") | |
| 14 | 25 |
| 15 class MissingFramesError(page_measurement.MeasurementFailure): | 26 class MissingFramesError(page_measurement.MeasurementFailure): |
| 16 def __init__(self): | 27 def __init__(self): |
| 17 super(MissingFramesError, self).__init__( | 28 super(MissingFramesError, self).__init__( |
| 18 'No frames found in trace. Unable to normalize results.') | 29 'No frames found in trace. Unable to normalize results.') |
| 19 | 30 |
| 20 | 31 |
| 21 class TimelineMetric(Metric): | 32 class TimelineMetric(Metric): |
| 22 def __init__(self, mode): | 33 def __init__(self, mode): |
| 23 """ Initializes a TimelineMetric object. | 34 """ Initializes a TimelineMetric object. |
| 24 """ | 35 """ |
| 25 super(TimelineMetric, self).__init__() | 36 super(TimelineMetric, self).__init__() |
| 26 assert mode in (TRACING_MODE, TIMELINE_MODE) | 37 assert mode in (TRACING_MODE, TIMELINE_MODE) |
| 38 self.trace_categories = DEFAULT_TRACE_CATEGORIES | |
| 27 self._mode = mode | 39 self._mode = mode |
| 28 self._model = None | 40 self._model = None |
| 29 self._renderer_process = None | 41 self._renderer_process = None |
| 30 self._actions = [] | 42 self._actions = [] |
| 31 self._action_ranges = [] | 43 self._action_ranges = [] |
| 32 | 44 |
| 33 def Start(self, page, tab): | 45 def Start(self, page, tab): |
| 34 """Starts gathering timeline data. | 46 """Starts gathering timeline data. |
| 35 | 47 |
| 36 mode: TRACING_MODE or TIMELINE_MODE | 48 mode: TRACING_MODE or TIMELINE_MODE |
| 37 """ | 49 """ |
| 38 self._model = None | 50 self._model = None |
| 39 if self._mode == TRACING_MODE: | 51 if self._mode == TRACING_MODE: |
| 40 if not tab.browser.supports_tracing: | 52 if not tab.browser.supports_tracing: |
| 41 raise Exception('Not supported') | 53 raise Exception('Not supported') |
| 42 tab.browser.StartTracing() | 54 tab.browser.StartTracing(self.trace_categories) |
| 43 else: | 55 else: |
| 44 assert self._mode == TIMELINE_MODE | 56 assert self._mode == TIMELINE_MODE |
| 45 tab.StartTimelineRecording() | 57 tab.StartTimelineRecording() |
| 46 | 58 |
| 47 def Stop(self, page, tab): | 59 def Stop(self, page, tab): |
| 48 if self._mode == TRACING_MODE: | 60 if self._mode == TRACING_MODE: |
| 49 trace_result = tab.browser.StopTracing() | 61 trace_result = tab.browser.StopTracing() |
| 50 self._model = trace_result.AsTimelineModel() | 62 self._model = trace_result.AsTimelineModel() |
| 51 self._renderer_process = self._model.GetRendererProcessFromTab(tab) | 63 self._renderer_process = self._model.GetRendererProcessFromTab(tab) |
| 52 self._action_ranges = [ action.GetActiveRangeOnTimeline(self._model) | 64 self._action_ranges = [ action.GetActiveRangeOnTimeline(self._model) |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 274 all_action_time = sum([action.bounds for action in self.action_ranges]) | 286 all_action_time = sum([action.bounds for action in self.action_ranges]) |
| 275 idle_time = max(0, all_action_time - all_measured_time) | 287 idle_time = max(0, all_action_time - all_measured_time) |
| 276 idle_time_result = (float(idle_time) / num_frames) if num_frames else 0 | 288 idle_time_result = (float(idle_time) / num_frames) if num_frames else 0 |
| 277 results.Add(ThreadDetailResultName(self.name, "idle"), | 289 results.Add(ThreadDetailResultName(self.name, "idle"), |
| 278 'ms', idle_time_result) | 290 'ms', idle_time_result) |
| 279 | 291 |
| 280 | 292 |
| 281 class ThreadTimesTimelineMetric(TimelineMetric): | 293 class ThreadTimesTimelineMetric(TimelineMetric): |
| 282 def __init__(self): | 294 def __init__(self): |
| 283 super(ThreadTimesTimelineMetric, self).__init__(TRACING_MODE) | 295 super(ThreadTimesTimelineMetric, self).__init__(TRACING_MODE) |
| 284 self.results_to_report = AllThreads | 296 # Minimal traces, for minimum noise in CPU-time measurements. |
| 285 self.details_to_report = NoThreads | 297 self.trace_categories = MINIMAL_TRACE_CATEGORIES |
| 298 self._results_to_report = AllThreads | |
| 299 self._details_to_report = NoThreads | |
| 300 | |
| 301 @property | |
| 302 def results_to_report(self): | |
| 303 return self._results_to_report | |
| 304 | |
| 305 @results_to_report.setter | |
| 306 def results_to_report(self, results_to_report): | |
| 307 self._results_to_report = results_to_report | |
| 308 | |
| 309 @property | |
| 310 def details_to_report(self): | |
| 311 return self._details_to_report | |
| 312 | |
| 313 @details_to_report.setter | |
| 314 def details_to_report(self, details_to_report): | |
| 315 self._details_to_report = details_to_report | |
| 316 # We need the other traces in order to have any details to report. | |
| 317 if not details_to_report == NoThreads: | |
| 318 self.trace_categories = DEFAULT_TRACE_CATEGORIES | |
| 286 | 319 |
| 287 def CountSlices(self, slices, substring): | 320 def CountSlices(self, slices, substring): |
| 288 count = 0 | 321 count = 0 |
| 289 for event in slices: | 322 for event in slices: |
| 290 if substring in event.name: | 323 if substring in event.name: |
| 291 count += 1 | 324 count += 1 |
| 292 return count | 325 return count |
| 293 | 326 |
| 294 def AddResults(self, tab, results): | 327 def AddResults(self, tab, results): |
| 295 # We need at least one action or we won't count any slices. | 328 # We need at least one action or we won't count any slices. |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 315 for thread in self._model.GetAllThreads(): | 348 for thread in self._model.GetAllThreads(): |
| 316 if ThreadCategoryName(thread.name) in FastPathThreads: | 349 if ThreadCategoryName(thread.name) in FastPathThreads: |
| 317 thread_category_results['total_fast_path'].AppendThreadSlices(thread) | 350 thread_category_results['total_fast_path'].AppendThreadSlices(thread) |
| 318 | 351 |
| 319 # Calculate the number of frames. | 352 # Calculate the number of frames. |
| 320 frame_slices = thread_category_results[FrameTraceThreadName].all_slices | 353 frame_slices = thread_category_results[FrameTraceThreadName].all_slices |
| 321 num_frames = self.CountSlices(frame_slices, FrameTraceName) | 354 num_frames = self.CountSlices(frame_slices, FrameTraceName) |
| 322 | 355 |
| 323 # Report the desired results and details. | 356 # Report the desired results and details. |
| 324 for thread_results in thread_category_results.values(): | 357 for thread_results in thread_category_results.values(): |
| 325 if thread_results.name in self.results_to_report: | 358 if thread_results.name in self._results_to_report: |
| 326 thread_results.AddResults(num_frames, results) | 359 thread_results.AddResults(num_frames, results) |
| 327 # TOOD(nduca): When generic results objects are done, this special case | 360 # TOOD(nduca): When generic results objects are done, this special case |
| 328 # can be replaced with a generic UI feature. | 361 # can be replaced with a generic UI feature. |
| 329 if thread_results.name in self.details_to_report: | 362 if thread_results.name in self._details_to_report: |
| 330 thread_results.AddDetailedResults(num_frames, results) | 363 thread_results.AddDetailedResults(num_frames, results) |
| OLD | NEW |