blob: 01180e748bc9b5453d21588a6ea3833a79c60855 [file] [log] [blame]
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import os
from telemetry.page import legacy_page_test
from telemetry.timeline.model import TimelineModel
from telemetry.timeline import tracing_config
from telemetry.value import list_of_scalar_values
from telemetry.value import scalar
_CR_RENDERER_MAIN = 'CrRendererMain'
_RUN_SMOOTH_ACTIONS = 'RunSmoothAllActions'
def _AddTracingResults(thread, results):
_GC_REASONS = ['precise', 'conservative', 'idle', 'forced']
_GC_STAGES = ['mark', 'lazy_sweep', 'complete_sweep']
def GetGcReason(event, async_slices):
args = event.args
# Old format
if 'precise' in args:
if args['forced']:
return 'forced'
return 'precise' if args['precise'] else 'conservative'
if args['gcReason'] == 'ConservativeGC':
return 'conservative'
if args['gcReason'] == 'PreciseGC':
return 'precise'
if args['gcReason'] == 'ForcedGCForTesting':
for s in async_slices:
if s.start <= event.start and event.end <= s.end:
return 'forced'
# Ignore this forced GC being out of target ranges
return None
if args['gcReason'] == 'IdleGC':
return 'idle'
return None # Unknown
def DumpMetric(page, name, values, unit, results):
if values[name]:
results.AddValue(list_of_scalar_values.ListOfScalarValues(
page, name, unit, values[name]))
results.AddValue(scalar.ScalarValue(
page, name + '_max', unit, max(values[name])))
results.AddValue(scalar.ScalarValue(
page, name + '_total', unit, sum(values[name])))
events = thread.all_slices
async_slices = [s for s in thread.async_slices
if s.name == 'BlinkGCTimeMeasurement']
# Prepare
values = {}
for reason in _GC_REASONS:
for stage in _GC_STAGES:
values['oilpan_%s_%s' % (reason, stage)] = []
# Parse trace events
reason = None
mark_time = 0
lazy_sweep_time = 0
complete_sweep_time = 0
for event in events:
duration = event.thread_duration or event.duration
if event.name == 'BlinkGC.AtomicPhaseMarking':
if reason is not None:
values['oilpan_%s_mark' % reason].append(mark_time)
values['oilpan_%s_lazy_sweep' % reason].append(lazy_sweep_time)
values['oilpan_%s_complete_sweep' % reason].append(complete_sweep_time)
reason = GetGcReason(event, async_slices)
mark_time = duration
lazy_sweep_time = 0
complete_sweep_time = 0
continue
if event.name == 'BlinkGC.LazySweepInIdle':
lazy_sweep_time += duration
continue
if event.name == 'BlinkGC.CompleteSweep':
complete_sweep_time += duration
continue
if reason is not None:
values['oilpan_%s_mark' % reason].append(mark_time)
values['oilpan_%s_lazy_sweep' % reason].append(lazy_sweep_time)
values['oilpan_%s_complete_sweep' % reason].append(complete_sweep_time)
page = results.current_page
unit = 'ms'
# Dump each metric
for reason in _GC_REASONS:
for stage in _GC_STAGES:
DumpMetric(page, 'oilpan_%s_%s' % (reason, stage), values, unit, results)
# Summarize each stage
for stage in _GC_STAGES:
total_time = 0
for reason in _GC_REASONS:
total_time += sum(values['oilpan_%s_%s' % (reason, stage)])
results.AddValue(
scalar.ScalarValue(page, 'oilpan_%s' % stage, unit, total_time))
# Summarize sweeping time
total_sweep_time = 0
for stage in ['lazy_sweep', 'complete_sweep']:
sweep_time = 0
for reason in _GC_REASONS:
sweep_time += sum(values['oilpan_%s_%s' % (reason, stage)])
key = 'oilpan_%s' % stage
results.AddValue(scalar.ScalarValue(page, key, unit, sweep_time))
total_sweep_time += sweep_time
results.AddValue(
scalar.ScalarValue(page, 'oilpan_sweep', unit, total_sweep_time))
gc_time = 0
for key in values:
gc_time += sum(values[key])
results.AddValue(scalar.ScalarValue(page, 'oilpan_gc', unit, gc_time))
class _OilpanGCTimesBase(legacy_page_test.LegacyPageTest):
def __init__(self, action_name=''):
super(_OilpanGCTimesBase, self).__init__(action_name)
def WillNavigateToPage(self, page, tab):
del page # unused
# FIXME: Remove webkit.console when blink.console lands in chromium and
# the ref builds are updated. crbug.com/386847
config = tracing_config.TracingConfig()
for c in ['webkit.console', 'blink.console', 'blink_gc']:
config.chrome_trace_config.category_filter.AddIncludedCategory(c)
config.enable_chrome_trace = True
tab.browser.platform.tracing_controller.StartTracing(config, timeout=1000)
def ValidateAndMeasurePage(self, page, tab, results):
del page # unused
timeline_data = tab.browser.platform.tracing_controller.StopTracing()
timeline_model = TimelineModel(timeline_data)
threads = timeline_model.GetAllThreads()
for thread in threads:
if thread.name == _CR_RENDERER_MAIN:
_AddTracingResults(thread, results)
def DidRunPage(self, platform):
if platform.tracing_controller.is_tracing_running:
platform.tracing_controller.StopTracing()
class OilpanGCTimesForSmoothness(_OilpanGCTimesBase):
def __init__(self):
super(OilpanGCTimesForSmoothness, self).__init__()
self._interaction = None
def DidNavigateToPage(self, page, tab):
del page # unused
self._interaction = tab.action_runner.CreateInteraction(_RUN_SMOOTH_ACTIONS)
self._interaction.Begin()
def ValidateAndMeasurePage(self, page, tab, results):
self._interaction.End()
super(OilpanGCTimesForSmoothness, self).ValidateAndMeasurePage(
page, tab, results)
class OilpanGCTimesForBlinkPerf(_OilpanGCTimesBase):
def __init__(self):
super(OilpanGCTimesForBlinkPerf, self).__init__()
with open(os.path.join(os.path.dirname(__file__), '..', '..', 'benchmarks',
'blink_perf.js'), 'r') as f:
self._blink_perf_js = f.read()
def WillNavigateToPage(self, page, tab):
page.script_to_evaluate_on_commit = self._blink_perf_js
super(OilpanGCTimesForBlinkPerf, self).WillNavigateToPage(page, tab)
def ValidateAndMeasurePage(self, page, tab, results):
tab.WaitForJavaScriptCondition('testRunner.isDone', timeout=600)
super(OilpanGCTimesForBlinkPerf, self).ValidateAndMeasurePage(
page, tab, results)
class OilpanGCTimesForInternals(OilpanGCTimesForBlinkPerf):
def __init__(self):
super(OilpanGCTimesForInternals, self).__init__()
@classmethod
def CustomizeBrowserOptions(cls, options):
# 'expose-internals-for-testing' can be enabled on content shell.
assert 'content-shell' in options.browser_type
options.AppendExtraBrowserArgs(['--expose-internals-for-testing',
'--js-flags=--expose-gc'])