X Tutup
Skip to content

Commit 67b9414

Browse files
committed
fix(benchpress): make benchpress fit for chrome 45
Closes #3411 Closes #3982
1 parent d8c5ab2 commit 67b9414

File tree

3 files changed

+404
-160
lines changed

3 files changed

+404
-160
lines changed

modules/benchpress/src/webdriver/chrome_driver_extension.ts

Lines changed: 132 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ import {
1313
import {WebDriverExtension, PerfLogFeatures} from '../web_driver_extension';
1414
import {WebDriverAdapter} from '../web_driver_adapter';
1515
import {Promise} from 'angular2/src/core/facade/async';
16+
import {Options} from '../common_options';
1617

1718
/**
1819
* Set the following 'traceCategories' to collect metrics in Chrome:
19-
* 'v8,blink.console,disabled-by-default-devtools.timeline'
20+
* 'v8,blink.console,disabled-by-default-devtools.timeline,devtools.timeline'
2021
*
2122
* In order to collect the frame rate related metrics, add 'benchmark'
2223
* to the list above.
@@ -25,7 +26,27 @@ export class ChromeDriverExtension extends WebDriverExtension {
2526
// TODO(tbosch): use static values when our transpiler supports them
2627
static get BINDINGS(): Binding[] { return _BINDINGS; }
2728

28-
constructor(private _driver: WebDriverAdapter) { super(); }
29+
private _majorChromeVersion: number;
30+
31+
constructor(private _driver: WebDriverAdapter, userAgent: string) {
32+
super();
33+
this._majorChromeVersion = this._parseChromeVersion(userAgent);
34+
}
35+
36+
private _parseChromeVersion(userAgent: string): number {
37+
if (isBlank(userAgent)) {
38+
return -1;
39+
}
40+
var v = StringWrapper.split(userAgent, /Chrom(e|ium)\//g)[2];
41+
if (isBlank(v)) {
42+
return -1;
43+
}
44+
v = StringWrapper.split(v, /\./g)[0];
45+
if (isBlank(v)) {
46+
return -1;
47+
}
48+
return NumberWrapper.parseInt(v, 10);
49+
}
2950

3051
gc() { return this._driver.executeScript('window.gc()'); }
3152

@@ -63,81 +84,138 @@ export class ChromeDriverExtension extends WebDriverExtension {
6384
});
6485
}
6586

66-
_convertPerfRecordsToEvents(chromeEvents: Array<StringMap<string, any>>,
67-
normalizedEvents: Array<StringMap<string, any>> = null) {
87+
private _convertPerfRecordsToEvents(chromeEvents: Array<StringMap<string, any>>,
88+
normalizedEvents: Array<StringMap<string, any>> = null) {
6889
if (isBlank(normalizedEvents)) {
6990
normalizedEvents = [];
7091
}
7192
var majorGCPids = {};
7293
chromeEvents.forEach((event) => {
73-
var cat = event['cat'];
94+
var categories = this._parseCategories(event['cat']);
7495
var name = event['name'];
75-
var args = event['args'];
76-
var pid = event['pid'];
77-
var ph = event['ph'];
78-
if (StringWrapper.equals(cat, 'disabled-by-default-devtools.timeline')) {
79-
if (StringWrapper.equals(name, 'FunctionCall') &&
80-
(isBlank(args) || isBlank(args['data']) ||
81-
!StringWrapper.equals(args['data']['scriptName'], 'InjectedScript'))) {
82-
normalizedEvents.push(normalizeEvent(event, {'name': 'script'}));
83-
84-
} else if (StringWrapper.equals(name, 'RecalculateStyles') ||
85-
StringWrapper.equals(name, 'Layout') ||
86-
StringWrapper.equals(name, 'UpdateLayerTree') ||
87-
StringWrapper.equals(name, 'Paint') || StringWrapper.equals(name, 'Rasterize') ||
88-
StringWrapper.equals(name, 'CompositeLayers')) {
89-
normalizedEvents.push(normalizeEvent(event, {'name': 'render'}));
90-
91-
} else if (StringWrapper.equals(name, 'GCEvent')) {
92-
var normArgs = {
93-
'usedHeapSize': isPresent(args['usedHeapSizeAfter']) ? args['usedHeapSizeAfter'] :
94-
args['usedHeapSizeBefore']
95-
};
96-
if (StringWrapper.equals(event['ph'], 'E')) {
97-
normArgs['majorGc'] = isPresent(majorGCPids[pid]) && majorGCPids[pid];
98-
}
99-
majorGCPids[pid] = false;
100-
normalizedEvents.push(normalizeEvent(event, {'name': 'gc', 'args': normArgs}));
101-
}
102-
103-
} else if (StringWrapper.equals(cat, 'blink.console')) {
96+
if (this._isEvent(categories, name, ['blink.console'])) {
10497
normalizedEvents.push(normalizeEvent(event, {'name': name}));
105-
106-
} else if (StringWrapper.equals(cat, 'v8')) {
107-
if (StringWrapper.equals(name, 'majorGC')) {
108-
if (StringWrapper.equals(ph, 'B')) {
109-
majorGCPids[pid] = true;
110-
}
111-
}
112-
113-
} else if (StringWrapper.equals(cat, 'benchmark')) {
98+
} else if (this._isEvent(categories, name, ['benchmark'],
99+
'BenchmarkInstrumentation::ImplThreadRenderingStats')) {
114100
// TODO(goderbauer): Instead of BenchmarkInstrumentation::ImplThreadRenderingStats the
115101
// following events should be used (if available) for more accurate measurments:
116102
// 1st choice: vsync_before - ground truth on Android
117103
// 2nd choice: BenchmarkInstrumentation::DisplayRenderingStats - available on systems with
118104
// new surfaces framework (not broadly enabled yet)
119105
// 3rd choice: BenchmarkInstrumentation::ImplThreadRenderingStats - fallback event that is
120106
// allways available if something is rendered
121-
if (StringWrapper.equals(name, 'BenchmarkInstrumentation::ImplThreadRenderingStats')) {
122-
var frameCount = event['args']['data']['frame_count'];
123-
if (frameCount > 1) {
124-
throw new BaseException('multi-frame render stats not supported');
125-
}
126-
if (frameCount == 1) {
127-
normalizedEvents.push(normalizeEvent(event, {'name': 'frame'}));
128-
}
107+
var frameCount = event['args']['data']['frame_count'];
108+
if (frameCount > 1) {
109+
throw new BaseException('multi-frame render stats not supported');
129110
}
111+
if (frameCount == 1) {
112+
normalizedEvents.push(normalizeEvent(event, {'name': 'frame'}));
113+
}
114+
} else if (this._isEvent(categories, name, ['disabled-by-default-devtools.timeline'],
115+
'Rasterize') ||
116+
this._isEvent(categories, name, ['disabled-by-default-devtools.timeline'],
117+
'CompositeLayers')) {
118+
normalizedEvents.push(normalizeEvent(event, {'name': 'render'}));
119+
} else if (this._majorChromeVersion < 45) {
120+
var normalizedEvent = this._processAsPreChrome45Event(event, categories, majorGCPids);
121+
if (normalizedEvent != null) normalizedEvents.push(normalizedEvent);
122+
} else {
123+
var normalizedEvent = this._processAsPostChrome44Event(event, categories);
124+
if (normalizedEvent != null) normalizedEvents.push(normalizedEvent);
130125
}
131126
});
132127
return normalizedEvents;
133128
}
134129

130+
private _processAsPreChrome45Event(event, categories, majorGCPids) {
131+
var name = event['name'];
132+
var args = event['args'];
133+
var pid = event['pid'];
134+
var ph = event['ph'];
135+
if (this._isEvent(categories, name, ['disabled-by-default-devtools.timeline'],
136+
'FunctionCall') &&
137+
(isBlank(args) || isBlank(args['data']) ||
138+
!StringWrapper.equals(args['data']['scriptName'], 'InjectedScript'))) {
139+
return normalizeEvent(event, {'name': 'script'});
140+
} else if (this._isEvent(categories, name, ['disabled-by-default-devtools.timeline'],
141+
'RecalculateStyles') ||
142+
this._isEvent(categories, name, ['disabled-by-default-devtools.timeline'],
143+
'Layout') ||
144+
this._isEvent(categories, name, ['disabled-by-default-devtools.timeline'],
145+
'UpdateLayerTree') ||
146+
this._isEvent(categories, name, ['disabled-by-default-devtools.timeline'],
147+
'Paint')) {
148+
return normalizeEvent(event, {'name': 'render'});
149+
} else if (this._isEvent(categories, name, ['disabled-by-default-devtools.timeline'],
150+
'GCEvent')) {
151+
var normArgs = {
152+
'usedHeapSize': isPresent(args['usedHeapSizeAfter']) ? args['usedHeapSizeAfter'] :
153+
args['usedHeapSizeBefore']
154+
};
155+
if (StringWrapper.equals(ph, 'E')) {
156+
normArgs['majorGc'] = isPresent(majorGCPids[pid]) && majorGCPids[pid];
157+
}
158+
majorGCPids[pid] = false;
159+
return normalizeEvent(event, {'name': 'gc', 'args': normArgs});
160+
} else if (this._isEvent(categories, name, ['v8'], 'majorGC') &&
161+
StringWrapper.equals(ph, 'B')) {
162+
majorGCPids[pid] = true;
163+
}
164+
return null; // nothing useful in this event
165+
}
166+
167+
private _processAsPostChrome44Event(event, categories) {
168+
var name = event['name'];
169+
var args = event['args'];
170+
if (this._isEvent(categories, name, ['devtools.timeline', 'v8'], 'MajorGC')) {
171+
var normArgs = {
172+
'majorGc': true,
173+
'usedHeapSize': isPresent(args['usedHeapSizeAfter']) ? args['usedHeapSizeAfter'] :
174+
args['usedHeapSizeBefore']
175+
};
176+
return normalizeEvent(event, {'name': 'gc', 'args': normArgs});
177+
} else if (this._isEvent(categories, name, ['devtools.timeline', 'v8'], 'MinorGC')) {
178+
var normArgs = {
179+
'majorGc': false,
180+
'usedHeapSize': isPresent(args['usedHeapSizeAfter']) ? args['usedHeapSizeAfter'] :
181+
args['usedHeapSizeBefore']
182+
};
183+
return normalizeEvent(event, {'name': 'gc', 'args': normArgs});
184+
} else if (this._isEvent(categories, name, ['devtools.timeline', 'v8'], 'FunctionCall') &&
185+
(isBlank(args) || isBlank(args['data']) ||
186+
!StringWrapper.equals(args['data']['scriptName'], 'InjectedScript'))) {
187+
return normalizeEvent(event, {'name': 'script'});
188+
} else if (this._isEvent(categories, name, ['devtools.timeline', 'blink'],
189+
'UpdateLayoutTree')) {
190+
return normalizeEvent(event, {'name': 'render'});
191+
} else if (this._isEvent(categories, name, ['devtools.timeline'], 'UpdateLayerTree') ||
192+
this._isEvent(categories, name, ['devtools.timeline'], 'Layout') ||
193+
this._isEvent(categories, name, ['devtools.timeline'], 'Paint')) {
194+
return normalizeEvent(event, {'name': 'render'});
195+
}
196+
return null; // nothing useful in this event
197+
}
198+
199+
private _parseCategories(categories: string): string[] {
200+
return StringWrapper.split(categories, /,/g);
201+
}
202+
203+
private _isEvent(eventCategories: string[], eventName: string, expectedCategories: string[],
204+
expectedName: string = null): boolean {
205+
var hasCategories = ListWrapper.reduce(expectedCategories, (value, cat) => {
206+
return value && ListWrapper.contains(eventCategories, cat);
207+
}, true);
208+
return isBlank(expectedName) ? hasCategories :
209+
hasCategories && StringWrapper.equals(eventName, expectedName);
210+
}
211+
135212
perfLogFeatures(): PerfLogFeatures {
136213
return new PerfLogFeatures({render: true, gc: true, frameCapture: true});
137214
}
138215

139216
supports(capabilities: StringMap<string, any>): boolean {
140-
return StringWrapper.equals(capabilities['browserName'].toLowerCase(), 'chrome');
217+
return this._majorChromeVersion != -1 &&
218+
StringWrapper.equals(capabilities['browserName'].toLowerCase(), 'chrome');
141219
}
142220
}
143221

@@ -164,5 +242,6 @@ function normalizeEvent(chromeEvent: StringMap<string, any>, data: StringMap<str
164242

165243
var _BINDINGS = [
166244
bind(ChromeDriverExtension)
167-
.toFactory((driver) => new ChromeDriverExtension(driver), [WebDriverAdapter])
245+
.toFactory((driver, userAgent) => new ChromeDriverExtension(driver, userAgent),
246+
[WebDriverAdapter, Options.USER_AGENT])
168247
];

0 commit comments

Comments
 (0)
X Tutup