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
3 # found in the LICENSE file.
7 from measurements
import smoothness_controller
8 from measurements
import timeline_controller
9 from telemetry
import benchmark
10 from telemetry
.core
.platform
import tracing_category_filter
11 from telemetry
.core
.platform
import tracing_options
12 from telemetry
.page
import action_runner
13 from telemetry
.page
import page_test
14 from telemetry
.results
import results_options
15 from telemetry
.timeline
.model
import TimelineModel
16 from telemetry
.util
import statistics
17 from telemetry
.value
import list_of_scalar_values
18 from telemetry
.value
import scalar
19 from telemetry
.value
import trace
22 _CR_RENDERER_MAIN
= 'CrRendererMain'
23 _RUN_SMOOTH_ACTIONS
= 'RunSmoothAllActions'
26 def _AddTracingResults(events
, results
):
27 _GC_REASONS
= ['precise', 'conservative', 'idle', 'forced']
28 _GC_STAGES
= ['mark', 'lazy_sweep', 'complete_sweep']
30 def GetGcReason(args
):
35 return 'precise' if args
['precise'] else 'conservative'
37 if args
['gcReason'] == 'ConservativeGC':
39 if args
['gcReason'] == 'PreciseGC':
41 if args
['gcReason'] == 'ForcedGCForTesting':
43 if args
['gcReason'] == 'IdleGC':
47 def DumpMetric(page
, name
, values
, unit
, results
):
49 results
.AddValue(list_of_scalar_values
.ListOfScalarValues(
50 page
, name
, unit
, values
[name
]))
51 results
.AddValue(scalar
.ScalarValue(
52 page
, name
+ '_max', unit
, max(values
[name
])))
53 results
.AddValue(scalar
.ScalarValue(
54 page
, name
+ '_total', unit
, sum(values
[name
])))
57 values
= {'oilpan_coalesce': []}
58 for reason
in _GC_REASONS
:
59 for stage
in _GC_STAGES
:
60 values
['oilpan_%s_%s' % (reason
, stage
)] = []
66 complete_sweep_time
= 0
68 duration
= event
.thread_duration
or event
.duration
69 if event
.name
== 'ThreadHeap::coalesce':
70 values
['oilpan_coalesce'].append(duration
)
72 if event
.name
== 'Heap::collectGarbage':
73 if reason
is not None:
74 values
['oilpan_%s_mark' % reason
].append(mark_time
)
75 values
['oilpan_%s_lazy_sweep' % reason
].append(lazy_sweep_time
)
76 values
['oilpan_%s_complete_sweep' % reason
].append(complete_sweep_time
)
78 reason
= GetGcReason(event
.args
)
81 complete_sweep_time
= 0
83 if event
.name
== 'ThreadHeap::lazySweepPages':
84 lazy_sweep_time
+= duration
86 if event
.name
== 'ThreadState::completeSweep':
87 complete_sweep_time
+= duration
90 if reason
is not None:
91 values
['oilpan_%s_mark' % reason
].append(mark_time
)
92 values
['oilpan_%s_lazy_sweep' % reason
].append(lazy_sweep_time
)
93 values
['oilpan_%s_complete_sweep' % reason
].append(complete_sweep_time
)
95 page
= results
.current_page
99 DumpMetric(page
, 'oilpan_coalesce', values
, unit
, results
)
100 for reason
in _GC_REASONS
:
101 for stage
in _GC_STAGES
:
102 DumpMetric(page
, 'oilpan_%s_%s' % (reason
, stage
), values
, unit
, results
)
104 # Summarize each stage
105 for stage
in _GC_STAGES
:
107 for reason
in _GC_REASONS
:
108 total_time
+= sum(values
['oilpan_%s_%s' % (reason
, stage
)])
110 scalar
.ScalarValue(page
, 'oilpan_%s' % stage
, unit
, total_time
))
112 # Summarize sweeping time
114 for stage
in ['lazy_sweep', 'complete_sweep']:
116 for reason
in _GC_REASONS
:
117 sweep_time
+= sum(values
['oilpan_%s_%s' % (reason
, stage
)])
118 key
= 'oilpan_%s' % stage
119 results
.AddValue(scalar
.ScalarValue(page
, key
, unit
, sweep_time
))
120 total_sweep_time
+= sweep_time
122 scalar
.ScalarValue(page
, 'oilpan_sweep', unit
, total_sweep_time
))
126 gc_time
+= sum(values
[key
])
127 results
.AddValue(scalar
.ScalarValue(page
, 'oilpan_gc', unit
, gc_time
))
130 class _OilpanGCTimesBase(page_test
.PageTest
):
131 def __init__(self
, action_name
=''):
132 super(_OilpanGCTimesBase
, self
).__init
__(action_name
)
133 self
._timeline
_model
= None
135 def WillNavigateToPage(self
, page
, tab
):
136 # FIXME: Remove webkit.console when blink.console lands in chromium and
137 # the ref builds are updated. crbug.com/386847
138 categories
= ['webkit.console', 'blink.console', 'blink_gc']
139 category_filter
= tracing_category_filter
.TracingCategoryFilter()
141 category_filter
.AddIncludedCategory(c
)
142 options
= tracing_options
.TracingOptions()
143 options
.enable_chrome_trace
= True
144 tab
.browser
.platform
.tracing_controller
.Start(options
, category_filter
,
147 def DidRunActions(self
, page
, tab
):
148 timeline_data
= tab
.browser
.platform
.tracing_controller
.Stop()
149 self
._timeline
_model
= TimelineModel(timeline_data
)
151 def ValidateAndMeasurePage(self
, page
, tab
, results
):
152 threads
= self
._timeline
_model
.GetAllThreads()
153 for thread
in threads
:
154 if thread
.name
== _CR_RENDERER_MAIN
:
155 _AddTracingResults(thread
.all_slices
, results
)
157 def CleanUpAfterPage(self
, page
, tab
):
158 if tab
.browser
.platform
.tracing_controller
.is_tracing_running
:
159 tab
.browser
.platform
.tracing_controller
.Stop()
162 class OilpanGCTimesForSmoothness(_OilpanGCTimesBase
):
164 super(OilpanGCTimesForSmoothness
, self
).__init
__()
165 self
._interaction
= None
167 def WillRunActions(self
, page
, tab
):
168 runner
= action_runner
.ActionRunner(tab
)
169 self
._interaction
= runner
.BeginInteraction(_RUN_SMOOTH_ACTIONS
)
171 def DidRunActions(self
, page
, tab
):
172 self
._interaction
.End()
173 super(OilpanGCTimesForSmoothness
, self
).DidRunActions(page
, tab
)
176 class OilpanGCTimesForBlinkPerf(_OilpanGCTimesBase
):
178 super(OilpanGCTimesForBlinkPerf
, self
).__init
__()
179 with
open(os
.path
.join(os
.path
.dirname(__file__
), '..', 'benchmarks',
180 'blink_perf.js'), 'r') as f
:
181 self
._blink
_perf
_js
= f
.read()
183 def WillNavigateToPage(self
, page
, tab
):
184 page
.script_to_evaluate_on_commit
= self
._blink
_perf
_js
185 super(OilpanGCTimesForBlinkPerf
, self
).WillNavigateToPage(page
, tab
)
187 def DidRunActions(self
, page
, tab
):
188 tab
.WaitForJavaScriptExpression('testRunner.isDone', 600)
189 super(OilpanGCTimesForBlinkPerf
, self
).DidRunActions(page
, tab
)
192 class OilpanGCTimesForInternals(_OilpanGCTimesBase
):
194 super(OilpanGCTimesForInternals
, self
).__init
__()
197 def CustomizeBrowserOptions(cls
, options
):
198 # 'expose-internals-for-testing' can be enabled on content shell.
199 assert 'content-shell' in options
.browser_type
200 options
.AppendExtraBrowserArgs(['--expose-internals-for-testing',
201 '--js-flags=--expose-gc'])