| OLD | NEW |
| 1 # Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 import json | 5 import json |
| 6 import logging | 6 import logging |
| 7 | 7 |
| 8 from metrics import Metric | 8 from metrics import Metric |
| 9 from telemetry.value import scalar | 9 from telemetry.value import scalar |
| 10 | 10 |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 'V8.SizeOf_SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE', | 147 'V8.SizeOf_SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE', |
| 148 'V8.SizeOf_SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE', | 148 'V8.SizeOf_SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE', |
| 149 'V8.SizeOf_SHORT_EXTERNAL_STRING_TYPE', | 149 'V8.SizeOf_SHORT_EXTERNAL_STRING_TYPE', |
| 150 'V8.SizeOf_SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE', | 150 'V8.SizeOf_SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE', |
| 151 'V8.SizeOf_SIGNATURE_INFO_TYPE', | 151 'V8.SizeOf_SIGNATURE_INFO_TYPE', |
| 152 'V8.SizeOf_SLICED_ASCII_STRING_TYPE', | 152 'V8.SizeOf_SLICED_ASCII_STRING_TYPE', |
| 153 'V8.SizeOf_SLICED_STRING_TYPE', | 153 'V8.SizeOf_SLICED_STRING_TYPE', |
| 154 'V8.SizeOf_STRING_TYPE', | 154 'V8.SizeOf_STRING_TYPE', |
| 155 'V8.SizeOf_SYMBOL_TYPE', | 155 'V8.SizeOf_SYMBOL_TYPE', |
| 156 'V8.SizeOf_TYPE_FEEDBACK_INFO_TYPE', | 156 'V8.SizeOf_TYPE_FEEDBACK_INFO_TYPE', |
| 157 'V8.SizeOf_TYPE_SWITCH_INFO_TYPE' | 157 'V8.SizeOf_TYPE_SWITCH_INFO_TYPE', |
| 158 ] | 158 ] |
| 159 |
| 160 # Descriptions for what different counter names represent. |
| 161 DESCRIPTIONS = { |
| 162 'V8.MemoryExternalFragmentationTotal': |
| 163 'Total external memory fragmentation after each GC in percent.', |
| 164 'V8.MemoryHeapSampleTotalCommitted': |
| 165 'The total size of committed memory used by V8 after each GC in KB.', |
| 166 'V8.MemoryHeapSampleTotalUsed': |
| 167 'The total size of live memory used by V8 after each GC in KB.', |
| 168 } |
| 169 |
| 159 | 170 |
| 160 class V8ObjectStatsMetric(Metric): | 171 class V8ObjectStatsMetric(Metric): |
| 161 """V8ObjectStatsMetric gathers statistics on the size of types in the V8 heap. | 172 """V8ObjectStatsMetric gathers statistics on the size of types in the V8 heap. |
| 162 | 173 |
| 163 It does this by enabling the --track_gc_object_stats flag on V8 and reading | 174 It does this by enabling the --track_gc_object_stats flag on V8 and reading |
| 164 these statistics from the StatsTableMetric. | 175 these statistics from the StatsTableMetric. |
| 165 """ | 176 """ |
| 166 | 177 |
| 167 def __init__(self, counters=None): | 178 def __init__(self, counters=None): |
| 168 super(V8ObjectStatsMetric, self).__init__() | 179 super(V8ObjectStatsMetric, self).__init__() |
| 169 self._results = None | 180 self._results = None |
| 170 self._counters = counters or _COUNTER_NAMES | 181 self._counters = counters or _COUNTER_NAMES |
| 171 | 182 |
| 172 @classmethod | 183 @classmethod |
| 173 def CustomizeBrowserOptions(cls, options): | 184 def CustomizeBrowserOptions(cls, options): |
| 174 options.AppendExtraBrowserArgs([ | 185 options.AppendExtraBrowserArgs([ |
| 175 '--enable-stats-table', | 186 '--enable-stats-table', |
| 176 '--enable-benchmarking', | 187 '--enable-benchmarking', |
| 177 '--js-flags=--track_gc_object_stats --expose_gc', | 188 '--js-flags=--track_gc_object_stats --expose_gc', |
| 178 # TODO(rmcilroy): This is needed for --enable-stats-table. Update once | 189 # TODO(rmcilroy): This is needed for --enable-stats-table. Update once |
| 179 # https://codereview.chromium.org/22911027/ lands. | 190 # https://codereview.chromium.org/22911027/ lands. |
| 180 '--no-sandbox' | 191 '--no-sandbox' |
| 181 ]) | 192 ]) |
| 182 | 193 |
| 183 @staticmethod | 194 @staticmethod |
| 184 def GetV8StatsTable(tab, counters): | 195 def GetV8StatsTable(tab, counters): |
| 185 | 196 |
| 186 return tab.EvaluateJavaScript(""" | 197 return tab.EvaluateJavaScript(""" |
| 187 (function(counters) { | 198 (function(counters) { |
| 188 var results = {}; | 199 var results = {}; |
| 189 if (!window.chrome || !window.chrome.benchmarking) | 200 if (!window.chrome || !window.chrome.benchmarking) |
| 190 return results; | 201 return results; |
| 191 try { | 202 try { |
| 192 window.gc(); // Trigger GC to ensure stats are checkpointed. | 203 window.gc(); // Trigger GC to ensure stats are checkpointed. |
| 193 } catch(e) { | 204 } catch(e) { |
| 194 // window.gc() could have been mapped to something else, just continue. | 205 // window.gc() could have been mapped to something else, |
| 195 } | 206 // just continue. |
| 196 for (var i = 0; i < counters.length; i++) | 207 } |
| 197 results[counters[i]] = | 208 for (var i = 0; i < counters.length; i++) |
| 198 chrome.benchmarking.counterForRenderer(counters[i]); | 209 results[counters[i]] = |
| 199 return results; | 210 chrome.benchmarking.counterForRenderer(counters[i]); |
| 200 })(%s); | 211 return results; |
| 201 """ % json.dumps(counters)) | 212 })(%s); |
| 213 """ % json.dumps(counters)) |
| 202 | 214 |
| 203 def Start(self, page, tab): | 215 def Start(self, page, tab): |
| 204 """Do Nothing.""" | 216 """Do Nothing.""" |
| 205 pass | 217 pass |
| 206 | 218 |
| 207 def Stop(self, page, tab): | 219 def Stop(self, page, tab): |
| 208 """Get the values in the stats table after the page is loaded.""" | 220 """Get the values in the stats table after the page is loaded.""" |
| 209 self._results = V8ObjectStatsMetric.GetV8StatsTable(tab, self._counters) | 221 self._results = V8ObjectStatsMetric.GetV8StatsTable(tab, self._counters) |
| 210 if not self._results: | 222 if not self._results: |
| 211 logging.warning('No V8 object stats from website: ' + page.display_name) | 223 logging.warning('No V8 object stats from website: ' + page.display_name) |
| 212 | 224 |
| 213 def AddResults(self, tab, results): | 225 def AddResults(self, tab, results): |
| 214 """Add results for this page to the results object.""" | 226 """Add results for this page to the results object.""" |
| 215 assert self._results != None, 'Must call Stop() first' | 227 assert self._results != None, 'Must call Stop() first' |
| 216 for counter_name in self._results: | 228 for counter_name in self._results: |
| 229 description = DESCRIPTIONS.get(counter_name) |
| 217 display_name = counter_name.replace('.', '_') | 230 display_name = counter_name.replace('.', '_') |
| 218 results.AddValue(scalar.ScalarValue( | 231 results.AddValue(scalar.ScalarValue( |
| 219 results.current_page, display_name, 'kb', | 232 results.current_page, display_name, 'kb', |
| 220 self._results[counter_name] / 1024.0)) | 233 self._results[counter_name] / 1024.0, description=description)) |
| OLD | NEW |