summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/devtools/front_end/profiler
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/devtools/front_end/profiler')
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/profiler/CPUProfileView.js24
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapProfileView.js223
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotView.js3
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapTimelineOverview.js59
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileView.js31
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfilesPanel.js9
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/profiler/heapProfiler.css4
7 files changed, 272 insertions, 81 deletions
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/CPUProfileView.js b/chromium/third_party/blink/renderer/devtools/front_end/profiler/CPUProfileView.js
index 5b9025df6ae..a901ccf0174 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/CPUProfileView.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/CPUProfileView.js
@@ -34,10 +34,11 @@ Profiler.CPUProfileView = class extends Profiler.ProfileView {
constructor(profileHeader) {
super();
this._profileHeader = profileHeader;
- this.profile = profileHeader.profileModel();
- this.adjustedTotal = this.profile.profileHead.total;
- this.adjustedTotal -= this.profile.idleNode ? this.profile.idleNode.total : 0;
this.initialize(new Profiler.CPUProfileView.NodeFormatter(this));
+ const profile = profileHeader.profileModel();
+ this.adjustedTotal = profile.profileHead.total;
+ this.adjustedTotal -= profile.idleNode ? profile.idleNode.total : 0;
+ this.setProfile(profile);
}
/**
@@ -47,7 +48,7 @@ Profiler.CPUProfileView = class extends Profiler.ProfileView {
super.wasShown();
const lineLevelProfile = PerfUI.LineLevelProfile.instance();
lineLevelProfile.reset();
- lineLevelProfile.appendCPUProfile(this.profile);
+ lineLevelProfile.appendCPUProfile(this._profileHeader.profileModel());
}
/**
@@ -70,7 +71,8 @@ Profiler.CPUProfileView = class extends Profiler.ProfileView {
* @return {!PerfUI.FlameChartDataProvider}
*/
createFlameChartDataProvider() {
- return new Profiler.CPUFlameChartDataProvider(this.profile, this._profileHeader._cpuProfilerModel);
+ return new Profiler.CPUFlameChartDataProvider(
+ this._profileHeader.profileModel(), this._profileHeader._cpuProfilerModel);
}
};
@@ -121,10 +123,10 @@ Profiler.CPUProfileType = class extends Profiler.ProfileType {
*/
buttonClicked() {
if (this._recording) {
- this.stopRecordingProfile();
+ this._stopRecordingProfile();
return false;
} else {
- this.startRecordingProfile();
+ this._startRecordingProfile();
return true;
}
}
@@ -148,7 +150,7 @@ Profiler.CPUProfileType = class extends Profiler.ProfileType {
this.addProfile(profile);
}
- startRecordingProfile() {
+ _startRecordingProfile() {
const cpuProfilerModel = UI.context.flavor(SDK.CPUProfilerModel);
if (this.profileBeingRecorded() || !cpuProfilerModel)
return;
@@ -162,7 +164,7 @@ Profiler.CPUProfileType = class extends Profiler.ProfileType {
Host.userMetrics.actionTaken(Host.UserMetrics.Action.ProfilesCPUProfileTaken);
}
- async stopRecordingProfile() {
+ async _stopRecordingProfile() {
this._recording = false;
if (!this.profileBeingRecorded() || !this.profileBeingRecorded()._cpuProfilerModel)
return;
@@ -193,7 +195,7 @@ Profiler.CPUProfileType = class extends Profiler.ProfileType {
* @override
*/
profileBeingRecordedRemoved() {
- this.stopRecordingProfile();
+ this._stopRecordingProfile();
}
};
@@ -272,7 +274,7 @@ Profiler.CPUProfileView.NodeFormatter = class {
* @return {string}
*/
formatPercent(value, node) {
- return node.profileNode === this._profileView.profile.idleNode ? '' : Common.UIString('%.2f\xa0%%', value);
+ return node.profileNode === this._profileView.profile().idleNode ? '' : Common.UIString('%.2f\xa0%%', value);
}
/**
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapProfileView.js b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapProfileView.js
index 56604554831..3c220b1d759 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapProfileView.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapProfileView.js
@@ -1,6 +1,7 @@
// Copyright 2016 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.
+
/**
* @implements {UI.Searchable}
* @unrestricted
@@ -11,18 +12,110 @@ Profiler.HeapProfileView = class extends Profiler.ProfileView {
*/
constructor(profileHeader) {
super();
+
this._profileHeader = profileHeader;
- this.profile = new Profiler.SamplingHeapProfileModel(profileHeader._profile || profileHeader.protocolProfile());
- this.adjustedTotal = this.profile.total;
+ this._profileType = profileHeader.profileType();
const views = [
Profiler.ProfileView.ViewTypes.Flame, Profiler.ProfileView.ViewTypes.Heavy, Profiler.ProfileView.ViewTypes.Tree
];
- const isNativeProfile = [
- Profiler.SamplingNativeHeapProfileType.TypeId, Profiler.SamplingNativeHeapSnapshotType.TypeId
- ].includes(profileHeader.profileType().id);
+
+ const isNativeProfile = this._profileType.id === Profiler.SamplingNativeHeapProfileType.TypeId ||
+ this._profileType.id === Profiler.SamplingNativeHeapSnapshotType.TypeId;
if (isNativeProfile)
views.push(Profiler.ProfileView.ViewTypes.Text);
+
this.initialize(new Profiler.HeapProfileView.NodeFormatter(this), views);
+ const profile = new Profiler.SamplingHeapProfileModel(profileHeader._profile || profileHeader.protocolProfile());
+ this.adjustedTotal = profile.total;
+ this.setProfile(profile);
+
+ this._selectedSizeText = new UI.ToolbarText();
+
+ if (Runtime.experiments.isEnabled('samplingHeapProfilerTimeline')) {
+ this._timelineOverview = new Profiler.HeapTimelineOverview();
+ this._timelineOverview.addEventListener(
+ Profiler.HeapTimelineOverview.IdsRangeChanged, this._onIdsRangeChanged.bind(this));
+ this._timelineOverview.show(this.element, this.element.firstChild);
+ this._timelineOverview.start();
+
+ this._profileType.addEventListener(
+ Profiler.SamplingHeapProfileType.Events.StatsUpdate, this._onStatsUpdate, this);
+ this._profileType.once(Profiler.ProfileType.Events.ProfileComplete).then(() => {
+ this._profileType.removeEventListener(
+ Profiler.SamplingHeapProfileType.Events.StatsUpdate, this._onStatsUpdate, this);
+ this._timelineOverview.stop();
+ this._timelineOverview.updateGrid();
+ });
+ }
+ }
+
+ /**
+ * @override
+ * @return {!Array<!UI.ToolbarItem>}
+ */
+ syncToolbarItems() {
+ return [...super.syncToolbarItems(), this._selectedSizeText];
+ }
+
+ /**
+ * @param {!Common.Event} event
+ */
+ _onIdsRangeChanged(event) {
+ const minId = /** @type {number} */ (event.data.minId);
+ const maxId = /** @type {number} */ (event.data.maxId);
+ this._selectedSizeText.setText(ls`Selected size: ${Number.bytesToString(event.data.size)}`);
+ this._setSelectionRange(minId, maxId);
+ }
+
+ /**
+ * @param {number} minId
+ * @param {number} maxId
+ */
+ _setSelectionRange(minId, maxId) {
+ const profile = new Profiler.SamplingHeapProfileModel(
+ this._profileHeader._profile || this._profileHeader.protocolProfile(), minId, maxId);
+ this.adjustedTotal = profile.total;
+ this.setProfile(profile);
+ }
+
+ /**
+ * @param {!Common.Event} event
+ */
+ _onStatsUpdate(event) {
+ const profile = event.data;
+
+ if (!this._totalTime) {
+ this._timestamps = [];
+ this._sizes = [];
+ this._max = [];
+ this._ordinals = [];
+ this._totalTime = 30000;
+ this._lastOrdinal = 0;
+ }
+
+ this._sizes.fill(0);
+ this._sizes.push(0);
+ this._timestamps.push(Date.now());
+ this._ordinals.push(this._lastOrdinal + 1);
+ this._lastOrdinal = profile.samples.reduce((res, sample) => Math.max(res, sample.ordinal), this._lastOrdinal);
+ for (const sample of profile.samples) {
+ const bucket = this._ordinals.upperBound(sample.ordinal) - 1;
+ this._sizes[bucket] += sample.size;
+ }
+ this._max.push(this._sizes.peekLast());
+
+ if (this._timestamps.peekLast() - this._timestamps[0] > this._totalTime)
+ this._totalTime *= 2;
+
+ const samples = /** @type {!Profiler.HeapTimelineOverview.Samples} */ ({
+ sizes: this._sizes,
+ max: this._max,
+ ids: this._ordinals,
+ timestamps: this._timestamps,
+ totalTime: this._totalTime
+ });
+
+ this._timelineOverview.setSamples(samples);
}
/**
@@ -45,7 +138,8 @@ Profiler.HeapProfileView = class extends Profiler.ProfileView {
* @return {!PerfUI.FlameChartDataProvider}
*/
createFlameChartDataProvider() {
- return new Profiler.HeapFlameChartDataProvider(this.profile, this._profileHeader.heapProfilerModel());
+ return new Profiler.HeapFlameChartDataProvider(
+ /** @type {!Profiler.SamplingHeapProfileModel} */ (this.profile()), this._profileHeader.heapProfilerModel());
}
/**
@@ -58,10 +152,10 @@ Profiler.HeapProfileView = class extends Profiler.ProfileView {
`Report Version: 7\n` +
`App Version: ${/Chrom\S*/.exec(navigator.appVersion)[0] || 'Unknown'}\n` +
`Node Weight: 1 KiB\n` +
- `Total Size: ${Math.round(this.profile.root.total / 1024)} KiB\n` +
+ `Total Size: ${Math.round(this.profile().root.total / 1024)} KiB\n` +
`----\n\nCall graph:\n`;
- const sortedChildren = this.profile.root.children.sort((a, b) => b.total - a.total);
- const modules = this.profile.modules.map(
+ const sortedChildren = this.profile().root.children.sort((a, b) => b.total - a.total);
+ const modules = this.profile().modules.map(
m => Object.assign({address: BigInt(m.baseAddress), endAddress: BigInt(m.baseAddress) + BigInt(m.size)}, m));
modules.sort((m1, m2) => m1.address > m2.address ? 1 : m1.address < m2.address ? -1 : 0);
for (const child of sortedChildren)
@@ -121,6 +215,10 @@ Profiler.HeapProfileView = class extends Profiler.ProfileView {
* @unrestricted
*/
Profiler.SamplingHeapProfileTypeBase = class extends Profiler.ProfileType {
+ /**
+ * @param {string} typeId
+ * @param {string} description
+ */
constructor(typeId, description) {
super(typeId, description);
this._recording = false;
@@ -151,7 +249,7 @@ Profiler.SamplingHeapProfileTypeBase = class extends Profiler.ProfileType {
}
get buttonTooltip() {
- return this._recording ? Common.UIString('Stop heap profiling') : Common.UIString('Start heap profiling');
+ return this._recording ? ls`Stop heap profiling` : ls`Start heap profiling`;
}
/**
@@ -159,37 +257,36 @@ Profiler.SamplingHeapProfileTypeBase = class extends Profiler.ProfileType {
* @return {boolean}
*/
buttonClicked() {
- const wasRecording = this._recording;
- if (wasRecording)
- this.stopRecordingProfile();
+ if (this._recording)
+ this._stopRecordingProfile();
else
- this.startRecordingProfile();
- return !wasRecording;
+ this._startRecordingProfile();
+ return this._recording;
}
- startRecordingProfile() {
+ _startRecordingProfile() {
const heapProfilerModel = UI.context.flavor(SDK.HeapProfilerModel);
if (this.profileBeingRecorded() || !heapProfilerModel)
return;
- const profile = new Profiler.SamplingHeapProfileHeader(heapProfilerModel, this);
- this.setProfileBeingRecorded(profile);
- this.addProfile(profile);
- profile.updateStatus(Common.UIString('Recording\u2026'));
+ const profileHeader = new Profiler.SamplingHeapProfileHeader(heapProfilerModel, this);
+ this.setProfileBeingRecorded(profileHeader);
+ this.addProfile(profileHeader);
+ profileHeader.updateStatus(ls`Recording\u2026`);
const icon = UI.Icon.create('smallicon-warning');
- icon.title = Common.UIString('Heap profiler is recording');
+ icon.title = ls`Heap profiler is recording`;
UI.inspectorView.setPanelIcon('heap_profiler', icon);
this._recording = true;
this._startSampling();
}
- async stopRecordingProfile() {
+ async _stopRecordingProfile() {
this._recording = false;
if (!this.profileBeingRecorded() || !this.profileBeingRecorded().heapProfilerModel())
return;
- this.profileBeingRecorded().updateStatus(Common.UIString('Stopping\u2026'));
+ this.profileBeingRecorded().updateStatus(ls`Stopping\u2026`);
const profile = await this._stopSampling();
const recordedProfile = this.profileBeingRecorded();
if (recordedProfile) {
@@ -215,7 +312,7 @@ Profiler.SamplingHeapProfileTypeBase = class extends Profiler.ProfileType {
* @override
*/
profileBeingRecordedRemoved() {
- this.stopRecordingProfile();
+ this._stopRecordingProfile();
}
_startSampling() {
@@ -230,7 +327,6 @@ Profiler.SamplingHeapProfileTypeBase = class extends Profiler.ProfileType {
}
};
-
/**
* @unrestricted
*/
@@ -238,6 +334,8 @@ Profiler.SamplingHeapProfileType = class extends Profiler.SamplingHeapProfileTyp
constructor() {
super(Profiler.SamplingHeapProfileType.TypeId, ls`Allocation sampling`);
Profiler.SamplingHeapProfileType.instance = this;
+ this._updateTimer = null;
+ this._updateIntervalMs = 200;
}
get treeItemTitle() {
@@ -252,9 +350,19 @@ Profiler.SamplingHeapProfileType = class extends Profiler.SamplingHeapProfileTyp
/**
* @override
+ * @return {boolean}
+ */
+ hasTemporaryView() {
+ return Runtime.experiments.isEnabled('samplingHeapProfilerTimeline');
+ }
+
+ /**
+ * @override
*/
_startSampling() {
this.profileBeingRecorded().heapProfilerModel().startSampling();
+ if (Runtime.experiments.isEnabled('samplingHeapProfilerTimeline'))
+ this._updateTimer = setTimeout(this._updateStats.bind(this), this._updateIntervalMs);
}
/**
@@ -262,12 +370,29 @@ Profiler.SamplingHeapProfileType = class extends Profiler.SamplingHeapProfileTyp
* return {!Promise<!Protocol.HeapProfiler.SamplingHeapProfile>}
*/
_stopSampling() {
+ clearTimeout(this._updateTimer);
+ this._updateTimer = null;
+ this.dispatchEventToListeners(Profiler.SamplingHeapProfileType.Events.RecordingStopped);
return this.profileBeingRecorded().heapProfilerModel().stopSampling();
}
+
+ async _updateStats() {
+ const profile = await this.profileBeingRecorded().heapProfilerModel().getSamplingProfile();
+ if (!this._updateTimer)
+ return;
+ this.dispatchEventToListeners(Profiler.SamplingHeapProfileType.Events.StatsUpdate, profile);
+ this._updateTimer = setTimeout(this._updateStats.bind(this), this._updateIntervalMs);
+ }
};
Profiler.SamplingHeapProfileType.TypeId = 'SamplingHeap';
+/** @enum {symbol} */
+Profiler.SamplingHeapProfileType.Events = {
+ RecordingStopped: Symbol('RecordingStopped'),
+ StatsUpdate: Symbol('StatsUpdate')
+};
+
/**
* @unrestricted
*/
@@ -426,6 +551,8 @@ Profiler.SamplingHeapProfileHeader = class extends Profiler.WritableProfileHeade
heapProfilerModel && heapProfilerModel.debuggerModel(), type,
title || Common.UIString('Profile %d', type.nextProfileUid()));
this._heapProfilerModel = heapProfilerModel;
+ this._protocolProfile =
+ /** @type {!Protocol.HeapProfiler.SamplingHeapProfile} */ ({head: {callFrame: {}, children: []}});
}
/**
@@ -478,29 +605,61 @@ Profiler.SamplingHeapProfileNode = class extends SDK.ProfileNode {
Profiler.SamplingHeapProfileModel = class extends SDK.ProfileTreeModel {
/**
* @param {!Protocol.HeapProfiler.SamplingHeapProfile} profile
+ * @param {number=} minOrdinal
+ * @param {number=} maxOrdinal
*/
- constructor(profile) {
+ constructor(profile, minOrdinal, maxOrdinal) {
super();
- this.initialize(translateProfileTree(profile.head));
this.modules = profile.modules || [];
+ /** @type {?Map<number, number>} */
+ let nodeIdToSizeMap = null;
+ if (minOrdinal || maxOrdinal) {
+ nodeIdToSizeMap = new Map();
+ minOrdinal = minOrdinal || 0;
+ maxOrdinal = maxOrdinal || Infinity;
+ for (const sample of profile.samples) {
+ if (sample.ordinal < minOrdinal || sample.ordinal > maxOrdinal)
+ continue;
+ const size = nodeIdToSizeMap.get(sample.nodeId) || 0;
+ nodeIdToSizeMap.set(sample.nodeId, size + sample.size);
+ }
+ }
+
+ this.initialize(translateProfileTree(profile.head));
+
/**
* @param {!Protocol.HeapProfiler.SamplingHeapProfileNode} root
* @return {!Profiler.SamplingHeapProfileNode}
*/
function translateProfileTree(root) {
const resultRoot = new Profiler.SamplingHeapProfileNode(root);
- const targetNodeStack = [resultRoot];
const sourceNodeStack = [root];
+ const targetNodeStack = [resultRoot];
while (sourceNodeStack.length) {
const sourceNode = sourceNodeStack.pop();
- const parentNode = targetNodeStack.pop();
- parentNode.children = sourceNode.children.map(child => new Profiler.SamplingHeapProfileNode(child));
- sourceNodeStack.push.apply(sourceNodeStack, sourceNode.children);
- targetNodeStack.push.apply(targetNodeStack, parentNode.children);
+ const targetNode = targetNodeStack.pop();
+ targetNode.children = sourceNode.children.map(child => {
+ const targetChild = new Profiler.SamplingHeapProfileNode(child);
+ if (nodeIdToSizeMap)
+ targetChild.self = nodeIdToSizeMap.get(child.id) || 0;
+ return targetChild;
+ });
+ sourceNodeStack.pushAll(sourceNode.children);
+ targetNodeStack.pushAll(targetNode.children);
}
+ pruneEmptyBranches(resultRoot);
return resultRoot;
}
+
+ /**
+ * @param {!SDK.ProfileNode} node
+ * @return {boolean}
+ */
+ function pruneEmptyBranches(node) {
+ node.children = node.children.filter(pruneEmptyBranches);
+ return !!(node.children.length || node.self);
+ }
}
};
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotView.js b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotView.js
index 482e79554c3..c33e9506279 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotView.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotView.js
@@ -180,6 +180,7 @@ Profiler.HeapSnapshotView = class extends UI.SimpleView {
Profiler.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._onHeapStatsUpdate, this);
profileType.addEventListener(
Profiler.TrackingHeapSnapshotProfileType.TrackingStopped, this._onStopTracking, this);
+ this._trackingOverviewGrid.start();
}
}
@@ -188,6 +189,8 @@ Profiler.HeapSnapshotView = class extends UI.SimpleView {
Profiler.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._onHeapStatsUpdate, this);
this._profile.profileType().removeEventListener(
Profiler.TrackingHeapSnapshotProfileType.TrackingStopped, this._onStopTracking, this);
+ if (this._trackingOverviewGrid)
+ this._trackingOverviewGrid.stop();
}
/**
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapTimelineOverview.js b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapTimelineOverview.js
index 6b3826573eb..e60c72bfab1 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapTimelineOverview.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapTimelineOverview.js
@@ -29,12 +29,27 @@ Profiler.HeapTimelineOverview = class extends UI.VBox {
this._profileSamples = new Profiler.HeapTimelineOverview.Samples();
}
+ start() {
+ this._running = true;
+ const drawFrame = () => {
+ this.update();
+ if (this._running)
+ this.element.window().requestAnimationFrame(drawFrame);
+ };
+ drawFrame();
+ }
+
+ stop() {
+ this._running = false;
+ }
+
/**
* @param {!Profiler.HeapTimelineOverview.Samples} samples
*/
setSamples(samples) {
this._profileSamples = samples;
- this.update();
+ if (!this._running)
+ this.update();
}
/**
@@ -49,7 +64,6 @@ Profiler.HeapTimelineOverview = class extends UI.VBox {
const topSizes = profileSamples.max;
const timestamps = profileSamples.timestamps;
const startTime = timestamps[0];
- const endTime = timestamps[timestamps.length - 1];
const scaleFactor = this._xScale.nextScale(width / profileSamples.totalTime);
let maxSize = 0;
@@ -93,14 +107,16 @@ Profiler.HeapTimelineOverview = class extends UI.VBox {
const context = this._overviewCanvas.getContext('2d');
context.scale(window.devicePixelRatio, window.devicePixelRatio);
- context.beginPath();
- context.lineWidth = 2;
- context.strokeStyle = 'rgba(192, 192, 192, 0.6)';
- const currentX = (endTime - startTime) * scaleFactor;
- context.moveTo(currentX, height - 1);
- context.lineTo(currentX, 0);
- context.stroke();
- context.closePath();
+ if (this._running) {
+ context.beginPath();
+ context.lineWidth = 2;
+ context.strokeStyle = 'rgba(192, 192, 192, 0.6)';
+ const currentX = (Date.now() - startTime) * scaleFactor;
+ context.moveTo(currentX, height - 1);
+ context.lineTo(currentX, 0);
+ context.stroke();
+ context.closePath();
+ }
let gridY;
let gridValue;
@@ -204,30 +220,23 @@ Profiler.HeapTimelineOverview = class extends UI.VBox {
this._updateGridTimerId = 0;
this._updateBoundaries();
const ids = this._profileSamples.ids;
+ if (!ids.length)
+ return;
const timestamps = this._profileSamples.timestamps;
const sizes = this._profileSamples.sizes;
const startTime = timestamps[0];
const totalTime = this._profileSamples.totalTime;
const timeLeft = startTime + totalTime * this._windowLeft;
const timeRight = startTime + totalTime * this._windowRight;
- let minId = 0;
- let maxId = ids[ids.length - 1] + 1;
+ const minIndex = timestamps.lowerBound(timeLeft);
+ const maxIndex = timestamps.upperBound(timeRight);
let size = 0;
- for (let i = 0; i < timestamps.length; ++i) {
- if (!timestamps[i])
- continue;
- if (timestamps[i] > timeRight)
- break;
- maxId = ids[i];
- if (timestamps[i] < timeLeft) {
- minId = ids[i];
- continue;
- }
+ for (let i = minIndex; i < maxIndex; ++i)
size += sizes[i];
- }
+ const minId = minIndex < ids.length ? ids[minIndex] : Infinity;
+ const maxId = maxIndex < ids.length ? ids[maxIndex] : Infinity;
- this.dispatchEventToListeners(
- Profiler.HeapTimelineOverview.IdsRangeChanged, {minId: minId, maxId: maxId, size: size});
+ this.dispatchEventToListeners(Profiler.HeapTimelineOverview.IdsRangeChanged, {minId, maxId, size});
}
};
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileView.js b/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileView.js
index c61e126719b..ab3c2e8183d 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileView.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileView.js
@@ -1,6 +1,7 @@
// Copyright 2016 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.
+
/**
* @implements {UI.Searchable}
* @unrestricted
@@ -9,6 +10,8 @@ Profiler.ProfileView = class extends UI.SimpleView {
constructor() {
super(Common.UIString('Profile'));
+ this._profile = null;
+
this._searchableView = new UI.SearchableView(this);
this._searchableView.setPlaceholder(Common.UIString('Find by cost (>50ms), name or file'));
this._searchableView.show(this.element);
@@ -62,6 +65,24 @@ Profiler.ProfileView = class extends UI.SimpleView {
}
/**
+ * @param {!SDK.ProfileTreeModel} profile
+ */
+ setProfile(profile) {
+ this._profile = profile;
+ this._bottomUpProfileDataGridTree = null;
+ this._topDownProfileDataGridTree = null;
+ this._changeView();
+ this.refresh();
+ }
+
+ /**
+ * @return {?SDK.ProfileTreeModel}
+ */
+ profile() {
+ return this._profile;
+ }
+
+ /**
* @param {!Profiler.ProfileDataGridNode.Formatter} nodeFormatter
* @param {!Array<string>=} viewTypes
* @protected
@@ -122,7 +143,7 @@ Profiler.ProfileView = class extends UI.SimpleView {
/**
* @override
- * @return {!Array.<!UI.ToolbarItem>}
+ * @return {!Array<!UI.ToolbarItem>}
*/
syncToolbarItems() {
return [this.viewSelectComboBox, this.focusButton, this.excludeButton, this.resetButton];
@@ -134,7 +155,7 @@ Profiler.ProfileView = class extends UI.SimpleView {
_getBottomUpProfileDataGridTree() {
if (!this._bottomUpProfileDataGridTree) {
this._bottomUpProfileDataGridTree = new Profiler.BottomUpProfileDataGridTree(
- this._nodeFormatter, this._searchableView, this.profile.root, this.adjustedTotal);
+ this._nodeFormatter, this._searchableView, this._profile.root, this.adjustedTotal);
}
return this._bottomUpProfileDataGridTree;
}
@@ -145,7 +166,7 @@ Profiler.ProfileView = class extends UI.SimpleView {
_getTopDownProfileDataGridTree() {
if (!this._topDownProfileDataGridTree) {
this._topDownProfileDataGridTree = new Profiler.TopDownProfileDataGridTree(
- this._nodeFormatter, this._searchableView, this.profile.root, this.adjustedTotal);
+ this._nodeFormatter, this._searchableView, this._profile.root, this.adjustedTotal);
}
return this._topDownProfileDataGridTree;
}
@@ -158,6 +179,8 @@ Profiler.ProfileView = class extends UI.SimpleView {
}
refresh() {
+ if (!this.profileDataGridTree)
+ return;
const selectedProfileNode = this.dataGrid.selectedNode ? this.dataGrid.selectedNode.profileNode : null;
this.dataGrid.rootNode().removeChildren();
@@ -288,7 +311,7 @@ Profiler.ProfileView = class extends UI.SimpleView {
}
_changeView() {
- if (!this.profile)
+ if (!this._profile)
return;
this._searchableView.closeSearch();
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfilesPanel.js b/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfilesPanel.js
index d7d5ffe0aec..eb7ffe825b1 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfilesPanel.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfilesPanel.js
@@ -328,8 +328,7 @@ Profiler.ProfilesPanel = class extends UI.PanelWithSidebar {
if (i !== -1)
this._profileToView.splice(i, 1);
- const profileType = profile.profileType();
- const typeId = profileType.id;
+ const typeId = profile.profileType().id;
const sectionIsEmpty = this._typeIdToSidebarSection[typeId].removeProfileHeader(profile);
// No other item will be selected if there aren't any other profiles, so
@@ -410,11 +409,7 @@ Profiler.ProfilesPanel = class extends UI.PanelWithSidebar {
* @return {number}
*/
_indexOfViewForProfile(profile) {
- for (let i = 0; i < this._profileToView.length; i++) {
- if (this._profileToView[i].profile === profile)
- return i;
- }
- return -1;
+ return this._profileToView.findIndex(item => item.profile === profile);
}
closeVisibleView() {
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/heapProfiler.css b/chromium/third_party/blink/renderer/devtools/front_end/profiler/heapProfiler.css
index c5f604461b5..7e5ce499e7f 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/heapProfiler.css
+++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/heapProfiler.css
@@ -70,7 +70,7 @@
flex: auto;
}
-.heap-snapshot-view .heap-tracking-overview {
+.profile-view .heap-tracking-overview {
flex: 0 0 80px;
height: 80px;
}
@@ -145,7 +145,7 @@
opacity: 0.6;
}
-#heap-recording-view .heap-snapshot-view {
+#heap-recording-view .profile-view {
top: 80px;
}