| OLD | NEW |
| (Empty) |
| 1 # Copyright 2013 The Chromium Authors. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 import optparse | |
| 6 import time | |
| 7 | |
| 8 from metrics import v8_object_stats | |
| 9 from telemetry.page import page_test | |
| 10 from telemetry.value import scalar | |
| 11 | |
| 12 # V8 statistics counter names. These can be retrieved using | |
| 13 # v8_object_stats.V8ObjectStatsMetric.GetV8StatsTable. | |
| 14 _V8_BYTES_COMMITTED = [ | |
| 15 'V8.MemoryNewSpaceBytesCommitted', | |
| 16 'V8.MemoryOldPointerSpaceBytesCommitted', | |
| 17 'V8.MemoryOldDataSpaceBytesCommitted', | |
| 18 'V8.MemoryCodeSpaceBytesCommitted', | |
| 19 'V8.MemoryMapSpaceBytesCommitted', | |
| 20 'V8.MemoryCellSpaceBytesCommitted', | |
| 21 'V8.MemoryPropertyCellSpaceBytesCommitted', | |
| 22 'V8.MemoryLoSpaceBytesCommitted', | |
| 23 ] | |
| 24 _V8_BYTES_USED = [ | |
| 25 'V8.MemoryNewSpaceBytesUsed', | |
| 26 'V8.MemoryOldPointerSpaceBytesUsed', | |
| 27 'V8.MemoryOldDataSpaceBytesUsed', | |
| 28 'V8.MemoryCodeSpaceBytesUsed', | |
| 29 'V8.MemoryMapSpaceBytesUsed', | |
| 30 'V8.MemoryCellSpaceBytesUsed', | |
| 31 'V8.MemoryPropertyCellSpaceBytesUsed', | |
| 32 'V8.MemoryLoSpaceBytesUsed', | |
| 33 ] | |
| 34 _V8_MEMORY_ALLOCATED = [ | |
| 35 'V8.OsMemoryAllocated', | |
| 36 ] | |
| 37 | |
| 38 | |
| 39 # NOTE(chrishenry): This measurement does NOT work anymore. The | |
| 40 # feature it depends on has been removed from telemetry. The benchmark | |
| 41 # has been disabled on bot. | |
| 42 class Endure(page_test.PageTest): | |
| 43 | |
| 44 def __init__(self): | |
| 45 super(Endure, self).__init__('RunEndure') | |
| 46 # Browser object, saved so that browser.memory_stats can be accessed. | |
| 47 self._browser = None | |
| 48 | |
| 49 # Dictionary of trace name to lists of y-values, for making summary values. | |
| 50 self._y_values = {} | |
| 51 | |
| 52 # Number of page repetitions since the start of the test. | |
| 53 self._iterations_elapsed = 0 | |
| 54 | |
| 55 # Start time of the test, used to report total time. | |
| 56 self._start_time = None | |
| 57 | |
| 58 @classmethod | |
| 59 def AddCommandLineArgs(cls, parser): | |
| 60 group = optparse.OptionGroup(parser, 'Endure options') | |
| 61 group.add_option('--perf-stats-interval', | |
| 62 dest='perf_stats_interval', | |
| 63 default=1, | |
| 64 type='int', | |
| 65 help='Number of iterations per sampling of statistics.') | |
| 66 parser.add_option_group(group) | |
| 67 | |
| 68 def DidStartBrowser(self, browser): | |
| 69 """Initializes the measurement after the browser is started.""" | |
| 70 self._browser = browser | |
| 71 self._start_time = time.time() | |
| 72 | |
| 73 def CustomizeBrowserOptions(self, options): | |
| 74 """Adds extra command-line options to the browser.""" | |
| 75 v8_object_stats.V8ObjectStatsMetric.CustomizeBrowserOptions(options) | |
| 76 | |
| 77 def ValidateAndMeasurePage(self, page, tab, results): | |
| 78 """Takes a sample and adds a result if enough time has passed.""" | |
| 79 self._iterations_elapsed += 1 | |
| 80 if self._iterations_elapsed % int(self.options.perf_stats_interval) == 0: | |
| 81 self._SampleStats(tab, results) | |
| 82 | |
| 83 def _SampleStats(self, tab, results): | |
| 84 """Records information and add it to the results.""" | |
| 85 | |
| 86 def AddPoint(trace_name, units_y, value_y, chart_name=None): | |
| 87 """Adds one data point to the results object.""" | |
| 88 if chart_name: | |
| 89 trace_name = '%s.%s' % (chart_name, trace_name) | |
| 90 else: | |
| 91 assert '.' not in trace_name, ( | |
| 92 'Trace names cannot contain "." with an empty chart_name since this' | |
| 93 ' is used to delimit chart_name.trace_name.') | |
| 94 results.AddValue(scalar.ScalarValue( | |
| 95 results.current_page, trace_name + '_X', 'iterations', | |
| 96 self._iterations_elapsed, important=False)) | |
| 97 results.AddValue(scalar.ScalarValue( | |
| 98 results.current_page, trace_name + '_Y', units_y, value_y, | |
| 99 important=False)) | |
| 100 | |
| 101 # Save the value so that summary stats can be calculated. | |
| 102 if trace_name not in self._y_values: | |
| 103 self._y_values[trace_name] = { | |
| 104 'units': units_y, | |
| 105 'chart_name': chart_name, | |
| 106 'values': [], | |
| 107 } | |
| 108 self._y_values[trace_name]['values'].append(value_y) | |
| 109 | |
| 110 # DOM nodes and event listeners. | |
| 111 dom_stats = tab.dom_stats | |
| 112 dom_node_count = dom_stats['node_count'] | |
| 113 event_listener_count = dom_stats['event_listener_count'] | |
| 114 AddPoint('dom_nodes', 'count', dom_node_count, chart_name='object_counts') | |
| 115 AddPoint('event_listeners', 'count', event_listener_count, | |
| 116 chart_name='object_counts') | |
| 117 | |
| 118 # Browser and renderer virtual memory stats. | |
| 119 memory_stats = self._browser.memory_stats | |
| 120 def BrowserVMStats(statistic_name): | |
| 121 """Get VM stats from the Browser object in KB.""" | |
| 122 return memory_stats[statistic_name].get('VM', 0) / 1024.0 | |
| 123 AddPoint('browser_vm', 'KB', BrowserVMStats('Browser'), | |
| 124 chart_name='vm_stats') | |
| 125 AddPoint('renderer_vm', 'KB', BrowserVMStats('Renderer'), | |
| 126 chart_name='vm_stats') | |
| 127 AddPoint('gpu_vm', 'KB', BrowserVMStats('Gpu'), chart_name='vm_stats') | |
| 128 | |
| 129 # V8 counter stats. | |
| 130 def V8StatsSum(counters): | |
| 131 """Given a list of V8 counter names, get the sum of the values in KB.""" | |
| 132 stats = v8_object_stats.V8ObjectStatsMetric.GetV8StatsTable(tab, counters) | |
| 133 return sum(stats.values()) / 1024.0 | |
| 134 AddPoint('v8_memory_committed', 'KB', V8StatsSum(_V8_BYTES_COMMITTED), | |
| 135 chart_name='v8_counter_stats') | |
| 136 AddPoint('v8_memory_used', 'KB', V8StatsSum(_V8_BYTES_USED), | |
| 137 chart_name='v8_counter_stats') | |
| 138 AddPoint('v8_memory_allocated', 'KB', V8StatsSum(_V8_MEMORY_ALLOCATED), | |
| 139 chart_name='v8_counter_stats') | |
| 140 | |
| 141 def DidRunTest(self, browser, results): | |
| 142 """Adds summary results (single number for one test run).""" | |
| 143 # Report test run length. | |
| 144 results.AddSummaryValue(scalar.ScalarValue(None, 'total_iterations', | |
| 145 'iterations', | |
| 146 self._iterations_elapsed, | |
| 147 important=False)) | |
| 148 results.AddSummaryValue(scalar.ScalarValue(None, 'total_time', 'seconds', | |
| 149 time.time() - self._start_time, | |
| 150 important=False)) | |
| 151 | |
| 152 # Add summary stats which could be monitored for anomalies. | |
| 153 for trace_name in self._y_values: | |
| 154 units = self._y_values[trace_name]['units'] | |
| 155 chart_name = self._y_values[trace_name]['chart_name'] | |
| 156 values = self._y_values[trace_name]['values'] | |
| 157 value_name = '%s.%s_max' % (chart_name, trace_name) | |
| 158 results.AddSummaryValue( | |
| 159 scalar.ScalarValue(None, value_name, units, max(values))) | |
| OLD | NEW |