blob: 10e696ce21a6def7753f2faff01c70e1a58567ba [file] [log] [blame]
Blink Reformat4c46d092018-04-07 15:32:371// Copyright 2016 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.
Alexei Filippov6d2eb592018-10-25 21:48:564
Tim van der Lippee54f66e2020-02-03 18:20:325import * as Bindings from '../bindings/bindings.js';
6import * as Common from '../common/common.js';
7import * as Components from '../components/components.js';
8import * as DataGrid from '../data_grid/data_grid.js'; // eslint-disable-line no-unused-vars
9import * as Host from '../host/host.js';
Tim van der Lippe8ef250c2020-02-20 16:29:2510import * as PerfUI from '../perf_ui/perf_ui.js';
Tim van der Lippee54f66e2020-02-03 18:20:3211import * as SDK from '../sdk/sdk.js'; // eslint-disable-line no-unused-vars
12import * as UI from '../ui/ui.js';
13
Paul Lewis0d43b802020-01-14 13:34:2314import {BottomUpProfileDataGridTree} from './BottomUpProfileDataGrid.js';
15import {CPUProfileFlameChart, ProfileFlameChartDataProvider} from './CPUProfileFlameChart.js'; // eslint-disable-line no-unused-vars
16import {Formatter, ProfileDataGridNode, ProfileDataGridTree} from './ProfileDataGrid.js'; // eslint-disable-line no-unused-vars
17import {DataDisplayDelegate, Events, ProfileHeader, ProfileType} from './ProfileHeader.js'; // eslint-disable-line no-unused-vars
18import {ProfileSidebarTreeElement} from './ProfileSidebarTreeElement.js';
19import {TopDownProfileDataGridTree} from './TopDownProfileDataGrid.js';
20
Blink Reformat4c46d092018-04-07 15:32:3721/**
Tim van der Lippee54f66e2020-02-03 18:20:3222 * @implements {UI.SearchableView.Searchable}
Blink Reformat4c46d092018-04-07 15:32:3723 * @unrestricted
24 */
Tim van der Lippee54f66e2020-02-03 18:20:3225export class ProfileView extends UI.View.SimpleView {
Blink Reformat4c46d092018-04-07 15:32:3726 constructor() {
Tim van der Lippee54f66e2020-02-03 18:20:3227 super(Common.UIString.UIString('Profile'));
Blink Reformat4c46d092018-04-07 15:32:3728
Alexei Filippov6d2eb592018-10-25 21:48:5629 this._profile = null;
30
Tim van der Lippee54f66e2020-02-03 18:20:3231 this._searchableView = new UI.SearchableView.SearchableView(this);
32 this._searchableView.setPlaceholder(Common.UIString.UIString('Find by cost (>50ms), name or file'));
Blink Reformat4c46d092018-04-07 15:32:3733 this._searchableView.show(this.element);
34
Tim van der Lippe9a9aba82020-02-14 14:52:2935 const columns = /** @type {!Array<!DataGrid.DataGrid.ColumnDescriptor>} */ ([]);
Blink Reformat4c46d092018-04-07 15:32:3736 columns.push({
37 id: 'self',
38 title: this.columnHeader('self'),
39 width: '120px',
40 fixedWidth: true,
41 sortable: true,
42 sort: DataGrid.DataGrid.Order.Descending
43 });
44 columns.push({id: 'total', title: this.columnHeader('total'), width: '120px', fixedWidth: true, sortable: true});
Tim van der Lippee54f66e2020-02-03 18:20:3245 columns.push({id: 'function', title: Common.UIString.UIString('Function'), disclosure: true, sortable: true});
Blink Reformat4c46d092018-04-07 15:32:3746
Tim van der Lippee54f66e2020-02-03 18:20:3247 this.dataGrid = new DataGrid.DataGrid.DataGridImpl({displayName: ls`Profiler`, columns});
Blink Reformat4c46d092018-04-07 15:32:3748 this.dataGrid.addEventListener(DataGrid.DataGrid.Events.SortingChanged, this._sortProfile, this);
49 this.dataGrid.addEventListener(DataGrid.DataGrid.Events.SelectedNode, this._nodeSelected.bind(this, true));
50 this.dataGrid.addEventListener(DataGrid.DataGrid.Events.DeselectedNode, this._nodeSelected.bind(this, false));
Brandon Goddardbfe54a62019-10-16 20:52:0851 this.dataGrid.setRowContextMenuCallback(this._populateContextMenu.bind(this));
Blink Reformat4c46d092018-04-07 15:32:3752
Tim van der Lippee54f66e2020-02-03 18:20:3253 this.viewSelectComboBox = new UI.Toolbar.ToolbarComboBox(this._changeView.bind(this), ls`Profile view mode`);
Blink Reformat4c46d092018-04-07 15:32:3754
Tim van der Lippee54f66e2020-02-03 18:20:3255 this.focusButton =
56 new UI.Toolbar.ToolbarButton(Common.UIString.UIString('Focus selected function'), 'largeicon-visibility');
Blink Reformat4c46d092018-04-07 15:32:3757 this.focusButton.setEnabled(false);
Tim van der Lippee54f66e2020-02-03 18:20:3258 this.focusButton.addEventListener(UI.Toolbar.ToolbarButton.Events.Click, this._focusClicked, this);
Blink Reformat4c46d092018-04-07 15:32:3759
Tim van der Lippee54f66e2020-02-03 18:20:3260 this.excludeButton =
61 new UI.Toolbar.ToolbarButton(Common.UIString.UIString('Exclude selected function'), 'largeicon-delete');
Blink Reformat4c46d092018-04-07 15:32:3762 this.excludeButton.setEnabled(false);
Tim van der Lippee54f66e2020-02-03 18:20:3263 this.excludeButton.addEventListener(UI.Toolbar.ToolbarButton.Events.Click, this._excludeClicked, this);
Blink Reformat4c46d092018-04-07 15:32:3764
Tim van der Lippee54f66e2020-02-03 18:20:3265 this.resetButton =
66 new UI.Toolbar.ToolbarButton(Common.UIString.UIString('Restore all functions'), 'largeicon-refresh');
Blink Reformat4c46d092018-04-07 15:32:3767 this.resetButton.setEnabled(false);
Tim van der Lippee54f66e2020-02-03 18:20:3268 this.resetButton.addEventListener(UI.Toolbar.ToolbarButton.Events.Click, this._resetClicked, this);
Blink Reformat4c46d092018-04-07 15:32:3769
Tim van der Lippee54f66e2020-02-03 18:20:3270 this._linkifier = new Components.Linkifier.Linkifier(maxLinkLength);
Blink Reformat4c46d092018-04-07 15:32:3771 }
72
73 /**
74 * @param {!Array<!{title: string, value: string}>} entryInfo
75 * @return {!Element}
76 */
77 static buildPopoverTable(entryInfo) {
78 const table = createElement('table');
79 for (const entry of entryInfo) {
80 const row = table.createChild('tr');
81 row.createChild('td').textContent = entry.title;
82 row.createChild('td').textContent = entry.value;
83 }
84 return table;
85 }
86
87 /**
Tim van der Lippee54f66e2020-02-03 18:20:3288 * @param {!SDK.ProfileTreeModel.ProfileTreeModel} profile
Alexei Filippov6d2eb592018-10-25 21:48:5689 */
90 setProfile(profile) {
91 this._profile = profile;
92 this._bottomUpProfileDataGridTree = null;
93 this._topDownProfileDataGridTree = null;
94 this._changeView();
95 this.refresh();
96 }
97
98 /**
Tim van der Lippee54f66e2020-02-03 18:20:3299 * @return {?SDK.ProfileTreeModel.ProfileTreeModel}
Alexei Filippov6d2eb592018-10-25 21:48:56100 */
101 profile() {
102 return this._profile;
103 }
104
105 /**
Paul Lewis0d43b802020-01-14 13:34:23106 * @param {!Formatter} nodeFormatter
Blink Reformat4c46d092018-04-07 15:32:37107 * @param {!Array<string>=} viewTypes
108 * @protected
109 */
110 initialize(nodeFormatter, viewTypes) {
111 this._nodeFormatter = nodeFormatter;
112
Paul Lewis6bcdb182020-01-23 11:08:05113 this._viewType = self.Common.settings.createSetting('profileView', ViewTypes.Heavy);
Tim van der Lippe6288cf32020-01-07 16:58:40114 viewTypes = viewTypes || [ViewTypes.Flame, ViewTypes.Heavy, ViewTypes.Tree];
Blink Reformat4c46d092018-04-07 15:32:37115
116 const optionNames = new Map([
Tim van der Lippe6288cf32020-01-07 16:58:40117 [ViewTypes.Flame, ls`Chart`],
118 [ViewTypes.Heavy, ls`Heavy (Bottom Up)`],
119 [ViewTypes.Tree, ls`Tree (Top Down)`],
120 [ViewTypes.Text, ls`Text (Top Down)`],
Blink Reformat4c46d092018-04-07 15:32:37121 ]);
122
123 const options =
Sigurd Schneider8a6ad9c2019-09-23 08:45:52124 new Map(viewTypes.map(type => [type, this.viewSelectComboBox.createOption(optionNames.get(type), type)]));
Blink Reformat4c46d092018-04-07 15:32:37125 const optionName = this._viewType.get() || viewTypes[0];
126 const option = options.get(optionName) || options.get(viewTypes[0]);
127 this.viewSelectComboBox.select(option);
128
129 this._changeView();
Tim van der Lippe1d6e57a2019-09-30 11:55:34130 if (this._flameChart) {
Blink Reformat4c46d092018-04-07 15:32:37131 this._flameChart.update();
Tim van der Lippe1d6e57a2019-09-30 11:55:34132 }
Blink Reformat4c46d092018-04-07 15:32:37133 }
134
135 /**
136 * @override
137 */
138 focus() {
Tim van der Lippe1d6e57a2019-09-30 11:55:34139 if (this._flameChart) {
Blink Reformat4c46d092018-04-07 15:32:37140 this._flameChart.focus();
Tim van der Lippe1d6e57a2019-09-30 11:55:34141 } else {
Blink Reformat4c46d092018-04-07 15:32:37142 super.focus();
Tim van der Lippe1d6e57a2019-09-30 11:55:34143 }
Blink Reformat4c46d092018-04-07 15:32:37144 }
145
146 /**
147 * @param {string} columnId
148 * @return {string}
149 */
150 columnHeader(columnId) {
151 throw 'Not implemented';
152 }
153
154 /**
155 * @param {number} timeLeft
156 * @param {number} timeRight
157 */
158 selectRange(timeLeft, timeRight) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34159 if (!this._flameChart) {
Blink Reformat4c46d092018-04-07 15:32:37160 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34161 }
Blink Reformat4c46d092018-04-07 15:32:37162 this._flameChart.selectRange(timeLeft, timeRight);
163 }
164
165 /**
166 * @override
Tim van der Lippee54f66e2020-02-03 18:20:32167 * @return {!Promise<!Array<!UI.Toolbar.ToolbarItem>>}
Blink Reformat4c46d092018-04-07 15:32:37168 */
Simon ZĂĽnd308c74f2020-01-16 06:53:37169 async toolbarItems() {
Blink Reformat4c46d092018-04-07 15:32:37170 return [this.viewSelectComboBox, this.focusButton, this.excludeButton, this.resetButton];
171 }
172
173 /**
Paul Lewis0d43b802020-01-14 13:34:23174 * @return {!ProfileDataGridTree}
Blink Reformat4c46d092018-04-07 15:32:37175 */
176 _getBottomUpProfileDataGridTree() {
177 if (!this._bottomUpProfileDataGridTree) {
Paul Lewis0d43b802020-01-14 13:34:23178 this._bottomUpProfileDataGridTree = new BottomUpProfileDataGridTree(
Alexei Filippov6d2eb592018-10-25 21:48:56179 this._nodeFormatter, this._searchableView, this._profile.root, this.adjustedTotal);
Blink Reformat4c46d092018-04-07 15:32:37180 }
181 return this._bottomUpProfileDataGridTree;
182 }
183
184 /**
Paul Lewis0d43b802020-01-14 13:34:23185 * @return {!ProfileDataGridTree}
Blink Reformat4c46d092018-04-07 15:32:37186 */
187 _getTopDownProfileDataGridTree() {
188 if (!this._topDownProfileDataGridTree) {
Paul Lewis0d43b802020-01-14 13:34:23189 this._topDownProfileDataGridTree = new TopDownProfileDataGridTree(
Alexei Filippov6d2eb592018-10-25 21:48:56190 this._nodeFormatter, this._searchableView, this._profile.root, this.adjustedTotal);
Blink Reformat4c46d092018-04-07 15:32:37191 }
192 return this._topDownProfileDataGridTree;
193 }
194
195 /**
Tim van der Lippee54f66e2020-02-03 18:20:32196 * @param {!UI.ContextMenu.ContextMenu} contextMenu
197 * @param {!DataGrid.DataGrid.DataGridNode} gridNode
Brandon Goddardbfe54a62019-10-16 20:52:08198 */
199 _populateContextMenu(contextMenu, gridNode) {
Paul Lewis0d43b802020-01-14 13:34:23200 const node = /** @type {!ProfileDataGridNode} */ (gridNode);
Brandon Goddardbfe54a62019-10-16 20:52:08201 if (node.linkElement && !contextMenu.containsTarget(node.linkElement)) {
202 contextMenu.appendApplicableItems(node.linkElement);
203 }
204 }
205
206 /**
Blink Reformat4c46d092018-04-07 15:32:37207 * @override
208 */
209 willHide() {
210 this._currentSearchResultIndex = -1;
211 }
212
213 refresh() {
Tim van der Lippe1d6e57a2019-09-30 11:55:34214 if (!this.profileDataGridTree) {
Alexei Filippov6d2eb592018-10-25 21:48:56215 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34216 }
Blink Reformat4c46d092018-04-07 15:32:37217 const selectedProfileNode = this.dataGrid.selectedNode ? this.dataGrid.selectedNode.profileNode : null;
218
219 this.dataGrid.rootNode().removeChildren();
220
221 const children = this.profileDataGridTree.children;
222 const count = children.length;
223
Tim van der Lippe1d6e57a2019-09-30 11:55:34224 for (let index = 0; index < count; ++index) {
Blink Reformat4c46d092018-04-07 15:32:37225 this.dataGrid.rootNode().appendChild(children[index]);
Tim van der Lippe1d6e57a2019-09-30 11:55:34226 }
Blink Reformat4c46d092018-04-07 15:32:37227
Tim van der Lippe1d6e57a2019-09-30 11:55:34228 if (selectedProfileNode) {
Blink Reformat4c46d092018-04-07 15:32:37229 selectedProfileNode.selected = true;
Tim van der Lippe1d6e57a2019-09-30 11:55:34230 }
Blink Reformat4c46d092018-04-07 15:32:37231 }
232
233 refreshVisibleData() {
234 let child = this.dataGrid.rootNode().children[0];
235 while (child) {
236 child.refresh();
237 child = child.traverseNextNode(false, null, true);
238 }
239 }
240
241 /**
Tim van der Lippee54f66e2020-02-03 18:20:32242 * @return {!UI.SearchableView.SearchableView}
Blink Reformat4c46d092018-04-07 15:32:37243 */
244 searchableView() {
245 return this._searchableView;
246 }
247
248 /**
249 * @override
250 * @return {boolean}
251 */
252 supportsCaseSensitiveSearch() {
253 return true;
254 }
255
256 /**
257 * @override
258 * @return {boolean}
259 */
260 supportsRegexSearch() {
261 return false;
262 }
263
264 /**
265 * @override
266 */
267 searchCanceled() {
268 this._searchableElement.searchCanceled();
269 }
270
271 /**
272 * @override
273 * @param {!UI.SearchableView.SearchConfig} searchConfig
274 * @param {boolean} shouldJump
275 * @param {boolean=} jumpBackwards
276 */
277 performSearch(searchConfig, shouldJump, jumpBackwards) {
278 this._searchableElement.performSearch(searchConfig, shouldJump, jumpBackwards);
279 }
280
281 /**
282 * @override
283 */
284 jumpToNextSearchResult() {
285 this._searchableElement.jumpToNextSearchResult();
286 }
287
288 /**
289 * @override
290 */
291 jumpToPreviousSearchResult() {
292 this._searchableElement.jumpToPreviousSearchResult();
293 }
294
295 /**
Tim van der Lippee54f66e2020-02-03 18:20:32296 * @return {!Components.Linkifier.Linkifier}
Blink Reformat4c46d092018-04-07 15:32:37297 */
298 linkifier() {
299 return this._linkifier;
300 }
301
Alexei Filippov8ad16d42018-07-10 00:17:48302 _ensureTextViewCreated() {
Tim van der Lippe1d6e57a2019-09-30 11:55:34303 if (this._textView) {
Alexei Filippov8ad16d42018-07-10 00:17:48304 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34305 }
Tim van der Lippee54f66e2020-02-03 18:20:32306 this._textView = new UI.View.SimpleView(ls`Call tree`);
Alexei Filippov8ad16d42018-07-10 00:17:48307 this._textView.registerRequiredCSS('profiler/profilesPanel.css');
308 this.populateTextView(this._textView);
309 }
310
311 /**
Tim van der Lippee54f66e2020-02-03 18:20:32312 * @param {!UI.View.SimpleView} view
Alexei Filippov8ad16d42018-07-10 00:17:48313 */
314 populateTextView(view) {
315 }
316
Blink Reformat4c46d092018-04-07 15:32:37317 /**
Paul Lewis0d43b802020-01-14 13:34:23318 * @return {!ProfileFlameChartDataProvider}
Blink Reformat4c46d092018-04-07 15:32:37319 */
320 createFlameChartDataProvider() {
321 throw 'Not implemented';
322 }
323
324 _ensureFlameChartCreated() {
Tim van der Lippe1d6e57a2019-09-30 11:55:34325 if (this._flameChart) {
Blink Reformat4c46d092018-04-07 15:32:37326 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34327 }
Blink Reformat4c46d092018-04-07 15:32:37328 this._dataProvider = this.createFlameChartDataProvider();
Paul Lewis0d43b802020-01-14 13:34:23329 this._flameChart = new CPUProfileFlameChart(this._searchableView, this._dataProvider);
Michael Liao712bbc22019-10-15 19:21:51330 this._flameChart.addEventListener(PerfUI.FlameChart.Events.EntryInvoked, this._onEntryInvoked.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37331 }
332
333 /**
Tim van der Lippec02a97c2020-02-14 14:39:27334 * @param {!Common.EventTarget.EventTargetEvent} event
Blink Reformat4c46d092018-04-07 15:32:37335 */
Simon ZĂĽnd3cb141b2020-02-26 13:29:41336 async _onEntryInvoked(event) {
Blink Reformat4c46d092018-04-07 15:32:37337 const entryIndex = event.data;
338 const node = this._dataProvider._entryNodes[entryIndex];
339 const debuggerModel = this._profileHeader._debuggerModel;
Tim van der Lippe1d6e57a2019-09-30 11:55:34340 if (!node || !node.scriptId || !debuggerModel) {
Blink Reformat4c46d092018-04-07 15:32:37341 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34342 }
Blink Reformat4c46d092018-04-07 15:32:37343 const script = debuggerModel.scriptForId(node.scriptId);
Tim van der Lippe1d6e57a2019-09-30 11:55:34344 if (!script) {
Blink Reformat4c46d092018-04-07 15:32:37345 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34346 }
Blink Reformat4c46d092018-04-07 15:32:37347 const location = /** @type {!SDK.DebuggerModel.Location} */ (
348 debuggerModel.createRawLocation(script, node.lineNumber, node.columnNumber));
Simon ZĂĽnd3cb141b2020-02-26 13:29:41349 const uiLocation = await self.Bindings.DebuggerWorkspaceBinding.rawLocationToUILocation(location);
350 Common.Revealer.reveal(uiLocation);
Blink Reformat4c46d092018-04-07 15:32:37351 }
352
353 _changeView() {
Tim van der Lippe1d6e57a2019-09-30 11:55:34354 if (!this._profile) {
Blink Reformat4c46d092018-04-07 15:32:37355 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34356 }
Blink Reformat4c46d092018-04-07 15:32:37357
358 this._searchableView.closeSearch();
359
Tim van der Lippe1d6e57a2019-09-30 11:55:34360 if (this._visibleView) {
Blink Reformat4c46d092018-04-07 15:32:37361 this._visibleView.detach();
Tim van der Lippe1d6e57a2019-09-30 11:55:34362 }
Blink Reformat4c46d092018-04-07 15:32:37363
364 this._viewType.set(this.viewSelectComboBox.selectedOption().value);
365 switch (this._viewType.get()) {
Tim van der Lippe6288cf32020-01-07 16:58:40366 case ViewTypes.Flame:
Blink Reformat4c46d092018-04-07 15:32:37367 this._ensureFlameChartCreated();
368 this._visibleView = this._flameChart;
369 this._searchableElement = this._flameChart;
370 break;
Tim van der Lippe6288cf32020-01-07 16:58:40371 case ViewTypes.Tree:
Blink Reformat4c46d092018-04-07 15:32:37372 this.profileDataGridTree = this._getTopDownProfileDataGridTree();
373 this._sortProfile();
374 this._visibleView = this.dataGrid.asWidget();
375 this._searchableElement = this.profileDataGridTree;
376 break;
Tim van der Lippe6288cf32020-01-07 16:58:40377 case ViewTypes.Heavy:
Blink Reformat4c46d092018-04-07 15:32:37378 this.profileDataGridTree = this._getBottomUpProfileDataGridTree();
379 this._sortProfile();
380 this._visibleView = this.dataGrid.asWidget();
381 this._searchableElement = this.profileDataGridTree;
382 break;
Tim van der Lippe6288cf32020-01-07 16:58:40383 case ViewTypes.Text:
Alexei Filippov8ad16d42018-07-10 00:17:48384 this._ensureTextViewCreated();
385 this._visibleView = this._textView;
386 this._searchableElement = this._textView;
387 break;
Blink Reformat4c46d092018-04-07 15:32:37388 }
389
Tim van der Lippe6288cf32020-01-07 16:58:40390 const isFlame = this._viewType.get() === ViewTypes.Flame;
Blink Reformat4c46d092018-04-07 15:32:37391 this.focusButton.setVisible(!isFlame);
392 this.excludeButton.setVisible(!isFlame);
393 this.resetButton.setVisible(!isFlame);
394
395 this._visibleView.show(this._searchableView.element);
396 }
397
398 /**
399 * @param {boolean} selected
400 */
401 _nodeSelected(selected) {
402 this.focusButton.setEnabled(selected);
403 this.excludeButton.setEnabled(selected);
404 }
405
406 /**
Tim van der Lippec02a97c2020-02-14 14:39:27407 * @param {!Common.EventTarget.EventTargetEvent} event
Blink Reformat4c46d092018-04-07 15:32:37408 */
409 _focusClicked(event) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34410 if (!this.dataGrid.selectedNode) {
Blink Reformat4c46d092018-04-07 15:32:37411 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34412 }
Blink Reformat4c46d092018-04-07 15:32:37413
414 this.resetButton.setEnabled(true);
Tony Ross88fd1322020-02-21 16:46:41415 this.resetButton.element.focus();
Blink Reformat4c46d092018-04-07 15:32:37416 this.profileDataGridTree.focus(this.dataGrid.selectedNode);
417 this.refresh();
418 this.refreshVisibleData();
419 Host.userMetrics.actionTaken(Host.UserMetrics.Action.CpuProfileNodeFocused);
420 }
421
422 /**
Tim van der Lippec02a97c2020-02-14 14:39:27423 * @param {!Common.EventTarget.EventTargetEvent} event
Blink Reformat4c46d092018-04-07 15:32:37424 */
425 _excludeClicked(event) {
426 const selectedNode = this.dataGrid.selectedNode;
427
Tim van der Lippe1d6e57a2019-09-30 11:55:34428 if (!selectedNode) {
Blink Reformat4c46d092018-04-07 15:32:37429 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34430 }
Blink Reformat4c46d092018-04-07 15:32:37431
Tony Ross88fd1322020-02-21 16:46:41432 this.resetButton.setEnabled(true);
433 this.resetButton.element.focus();
434
Blink Reformat4c46d092018-04-07 15:32:37435 selectedNode.deselect();
436
Blink Reformat4c46d092018-04-07 15:32:37437 this.profileDataGridTree.exclude(selectedNode);
438 this.refresh();
439 this.refreshVisibleData();
440 Host.userMetrics.actionTaken(Host.UserMetrics.Action.CpuProfileNodeExcluded);
441 }
442
443 /**
Tim van der Lippec02a97c2020-02-14 14:39:27444 * @param {!Common.EventTarget.EventTargetEvent} event
Blink Reformat4c46d092018-04-07 15:32:37445 */
446 _resetClicked(event) {
Tony Ross88fd1322020-02-21 16:46:41447 this.viewSelectComboBox.selectElement().focus();
Blink Reformat4c46d092018-04-07 15:32:37448 this.resetButton.setEnabled(false);
449 this.profileDataGridTree.restore();
450 this._linkifier.reset();
451 this.refresh();
452 this.refreshVisibleData();
453 }
454
455 _sortProfile() {
456 const sortAscending = this.dataGrid.isSortOrderAscending();
457 const sortColumnId = this.dataGrid.sortColumnId();
458 const sortProperty = sortColumnId === 'function' ? 'functionName' : sortColumnId || '';
Paul Lewis0d43b802020-01-14 13:34:23459 this.profileDataGridTree.sort(ProfileDataGridTree.propertyComparator(sortProperty, sortAscending));
Blink Reformat4c46d092018-04-07 15:32:37460
461 this.refresh();
462 }
Tim van der Lippe6288cf32020-01-07 16:58:40463}
Blink Reformat4c46d092018-04-07 15:32:37464
Paul Lewis0d43b802020-01-14 13:34:23465export const maxLinkLength = 30;
Blink Reformat4c46d092018-04-07 15:32:37466
467/** @enum {string} */
Tim van der Lippe6288cf32020-01-07 16:58:40468export const ViewTypes = {
Blink Reformat4c46d092018-04-07 15:32:37469 Flame: 'Flame',
470 Tree: 'Tree',
Alexei Filippov8ad16d42018-07-10 00:17:48471 Heavy: 'Heavy',
472 Text: 'Text'
Blink Reformat4c46d092018-04-07 15:32:37473};
474
Blink Reformat4c46d092018-04-07 15:32:37475/**
Tim van der Lippee54f66e2020-02-03 18:20:32476 * @implements {Common.StringOutputStream.OutputStream}
Blink Reformat4c46d092018-04-07 15:32:37477 * @unrestricted
478 */
Paul Lewis0d43b802020-01-14 13:34:23479export class WritableProfileHeader extends ProfileHeader {
Blink Reformat4c46d092018-04-07 15:32:37480 /**
Tim van der Lippee54f66e2020-02-03 18:20:32481 * @param {?SDK.DebuggerModel.DebuggerModel} debuggerModel
Paul Lewis0d43b802020-01-14 13:34:23482 * @param {!ProfileType} type
Blink Reformat4c46d092018-04-07 15:32:37483 * @param {string=} title
484 */
485 constructor(debuggerModel, type, title) {
Tim van der Lippee54f66e2020-02-03 18:20:32486 super(type, title || Common.UIString.UIString('Profile %d', type.nextProfileUid()));
Blink Reformat4c46d092018-04-07 15:32:37487 this._debuggerModel = debuggerModel;
488 this._tempFile = null;
489 }
490
491 /**
Tim van der Lippee54f66e2020-02-03 18:20:32492 * @param {!Bindings.FileUtils.ChunkedReader} reader
Blink Reformat4c46d092018-04-07 15:32:37493 */
494 _onChunkTransferred(reader) {
Tim van der Lippee54f66e2020-02-03 18:20:32495 this.updateStatus(
Mathias Bynens23ee1aa2020-03-02 12:06:38496 Common.UIString.UIString('Loading… %d%%', Number.bytesToString(this._jsonifiedProfile.length)));
Blink Reformat4c46d092018-04-07 15:32:37497 }
498
499 /**
Tim van der Lippee54f66e2020-02-03 18:20:32500 * @param {!Bindings.FileUtils.ChunkedReader} reader
Blink Reformat4c46d092018-04-07 15:32:37501 */
502 _onError(reader) {
Mathias Bynens23ee1aa2020-03-02 12:06:38503 this.updateStatus(Common.UIString.UIString('File \'%s\' read error: %s', reader.fileName(), reader.error().message));
Blink Reformat4c46d092018-04-07 15:32:37504 }
505
506 /**
507 * @override
508 * @param {string} text
509 * @return {!Promise}
510 */
511 async write(text) {
512 this._jsonifiedProfile += text;
513 }
514
515 /**
516 * @override
517 */
518 close() {
519 }
520
521 /**
522 * @override
523 */
524 dispose() {
525 this.removeTempFile();
526 }
527
528 /**
529 * @override
Paul Lewis0d43b802020-01-14 13:34:23530 * @param {!DataDisplayDelegate} panel
531 * @return {!ProfileSidebarTreeElement}
Blink Reformat4c46d092018-04-07 15:32:37532 */
533 createSidebarTreeElement(panel) {
Paul Lewis0d43b802020-01-14 13:34:23534 return new ProfileSidebarTreeElement(panel, this, 'profile-sidebar-tree-item');
Blink Reformat4c46d092018-04-07 15:32:37535 }
536
537 /**
538 * @override
539 * @return {boolean}
540 */
541 canSaveToFile() {
542 return !this.fromFile() && this._protocolProfile;
543 }
544
545 /**
546 * @override
547 */
548 async saveToFile() {
Tim van der Lippee54f66e2020-02-03 18:20:32549 const fileOutputStream = new Bindings.FileUtils.FileOutputStream();
Blink Reformat4c46d092018-04-07 15:32:37550 this._fileName = this._fileName ||
551 `${this.profileType().typeName()}-${new Date().toISO8601Compact()}${this.profileType().fileExtension()}`;
552 const accepted = await fileOutputStream.open(this._fileName);
Tim van der Lippe1d6e57a2019-09-30 11:55:34553 if (!accepted || !this._tempFile) {
Blink Reformat4c46d092018-04-07 15:32:37554 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34555 }
Blink Reformat4c46d092018-04-07 15:32:37556 const data = await this._tempFile.read();
Tim van der Lippe1d6e57a2019-09-30 11:55:34557 if (data) {
Blink Reformat4c46d092018-04-07 15:32:37558 await fileOutputStream.write(data);
Tim van der Lippe1d6e57a2019-09-30 11:55:34559 }
Blink Reformat4c46d092018-04-07 15:32:37560 fileOutputStream.close();
561 }
562
563 /**
564 * @override
565 * @param {!File} file
566 * @return {!Promise<?Error>}
567 */
568 async loadFromFile(file) {
Mathias Bynens23ee1aa2020-03-02 12:06:38569 this.updateStatus(Common.UIString.UIString('Loading…'), true);
Tim van der Lippee54f66e2020-02-03 18:20:32570 const fileReader = new Bindings.FileUtils.ChunkedFileReader(file, 10000000, this._onChunkTransferred.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37571 this._jsonifiedProfile = '';
572
573 const success = await fileReader.read(this);
574 if (!success) {
575 this._onError(fileReader);
Tim van der Lippee54f66e2020-02-03 18:20:32576 return new Error(Common.UIString.UIString('Failed to read file'));
Blink Reformat4c46d092018-04-07 15:32:37577 }
578
Mathias Bynens23ee1aa2020-03-02 12:06:38579 this.updateStatus(Common.UIString.UIString('Parsing…'), true);
Blink Reformat4c46d092018-04-07 15:32:37580 let error = null;
581 try {
582 this._profile = /** @type {!Protocol.Profiler.Profile} */ (JSON.parse(this._jsonifiedProfile));
583 this.setProfile(this._profile);
Tim van der Lippee54f66e2020-02-03 18:20:32584 this.updateStatus(Common.UIString.UIString('Loaded'), false);
Blink Reformat4c46d092018-04-07 15:32:37585 } catch (e) {
586 error = e;
587 this.profileType().removeProfile(this);
588 }
589 this._jsonifiedProfile = null;
590
Tim van der Lippe1d6e57a2019-09-30 11:55:34591 if (this.profileType().profileBeingRecorded() === this) {
Blink Reformat4c46d092018-04-07 15:32:37592 this.profileType().setProfileBeingRecorded(null);
Tim van der Lippe1d6e57a2019-09-30 11:55:34593 }
Blink Reformat4c46d092018-04-07 15:32:37594 return error;
595 }
596
597 /**
598 * @param {!Protocol.Profiler.Profile} profile
599 */
600 setProtocolProfile(profile) {
601 this.setProfile(profile);
602 this._protocolProfile = profile;
Tim van der Lippee54f66e2020-02-03 18:20:32603 this._tempFile = new Bindings.TempFile.TempFile();
Blink Reformat4c46d092018-04-07 15:32:37604 this._tempFile.write([JSON.stringify(profile)]);
Tim van der Lippe1d6e57a2019-09-30 11:55:34605 if (this.canSaveToFile()) {
Paul Lewis0d43b802020-01-14 13:34:23606 this.dispatchEventToListeners(Events.ProfileReceived);
Tim van der Lippe1d6e57a2019-09-30 11:55:34607 }
Blink Reformat4c46d092018-04-07 15:32:37608 }
Tim van der Lippe6288cf32020-01-07 16:58:40609}