Index: third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotView.js |
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotView.js b/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotView.js |
index 1079cc894a2ba5882037cebe788fd7648a90aca0..1c2bc1c1519a0760082451cd93dd0f1646cd314f 100644 |
--- a/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotView.js |
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotView.js |
@@ -27,28 +27,31 @@ |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
- |
/** |
- * @constructor |
* @implements {WebInspector.ProfileType.DataDisplayDelegate} |
* @implements {WebInspector.Searchable} |
- * @extends {WebInspector.SimpleView} |
- * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate |
- * @param {!WebInspector.HeapProfileHeader} profile |
+ * @unrestricted |
*/ |
-WebInspector.HeapSnapshotView = function(dataDisplayDelegate, profile) |
-{ |
- WebInspector.SimpleView.call(this, WebInspector.UIString("Heap Snapshot")); |
+WebInspector.HeapSnapshotView = class extends WebInspector.SimpleView { |
+ /** |
+ * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate |
+ * @param {!WebInspector.HeapProfileHeader} profile |
+ */ |
+ constructor(dataDisplayDelegate, profile) { |
+ super(WebInspector.UIString('Heap Snapshot')); |
- this.element.classList.add("heap-snapshot-view"); |
+ this.element.classList.add('heap-snapshot-view'); |
- profile.profileType().addEventListener(WebInspector.HeapSnapshotProfileType.SnapshotReceived, this._onReceiveSnapshot, this); |
- profile.profileType().addEventListener(WebInspector.ProfileType.Events.RemoveProfileHeader, this._onProfileHeaderRemoved, this); |
+ profile.profileType().addEventListener( |
+ WebInspector.HeapSnapshotProfileType.SnapshotReceived, this._onReceiveSnapshot, this); |
+ profile.profileType().addEventListener( |
+ WebInspector.ProfileType.Events.RemoveProfileHeader, this._onProfileHeaderRemoved, this); |
var isHeapTimeline = profile.profileType().id === WebInspector.TrackingHeapSnapshotProfileType.TypeId; |
if (isHeapTimeline) { |
- this._trackingOverviewGrid = new WebInspector.HeapTrackingOverviewGrid(profile); |
- this._trackingOverviewGrid.addEventListener(WebInspector.HeapTrackingOverviewGrid.IdsRangeChanged, this._onIdsRangeChanged.bind(this)); |
+ this._trackingOverviewGrid = new WebInspector.HeapTrackingOverviewGrid(profile); |
+ this._trackingOverviewGrid.addEventListener( |
+ WebInspector.HeapTrackingOverviewGrid.IdsRangeChanged, this._onIdsRangeChanged.bind(this)); |
} |
this._parentDataDisplayDelegate = dataDisplayDelegate; |
@@ -56,7 +59,7 @@ WebInspector.HeapSnapshotView = function(dataDisplayDelegate, profile) |
this._searchableView = new WebInspector.SearchableView(this); |
this._searchableView.show(this.element); |
- this._splitWidget = new WebInspector.SplitWidget(false, true, "heapSnapshotSplitViewState", 200, 200); |
+ this._splitWidget = new WebInspector.SplitWidget(false, true, 'heapSnapshotSplitViewState', 200, 200); |
this._splitWidget.show(this._searchableView.element); |
this._containmentDataGrid = new WebInspector.HeapSnapshotContainmentDataGrid(this); |
@@ -67,7 +70,8 @@ WebInspector.HeapSnapshotView = function(dataDisplayDelegate, profile) |
this._statisticsView = new WebInspector.HeapSnapshotStatisticsView(); |
this._constructorsDataGrid = new WebInspector.HeapSnapshotConstructorsDataGrid(this); |
- this._constructorsDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._selectionChanged, this); |
+ this._constructorsDataGrid.addEventListener( |
+ WebInspector.DataGrid.Events.SelectedNode, this._selectionChanged, this); |
this._constructorsWidget = this._constructorsDataGrid.asWidget(); |
this._constructorsWidget.setMinimumSize(50, 25); |
@@ -76,61 +80,64 @@ WebInspector.HeapSnapshotView = function(dataDisplayDelegate, profile) |
this._diffWidget = this._diffDataGrid.asWidget(); |
this._diffWidget.setMinimumSize(50, 25); |
- if (isHeapTimeline && WebInspector.moduleSetting("recordAllocationStacks").get()) { |
- this._allocationDataGrid = new WebInspector.AllocationDataGrid(profile.target() , this); |
- this._allocationDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._onSelectAllocationNode, this); |
- this._allocationWidget = this._allocationDataGrid.asWidget(); |
- this._allocationWidget.setMinimumSize(50, 25); |
+ if (isHeapTimeline && WebInspector.moduleSetting('recordAllocationStacks').get()) { |
+ this._allocationDataGrid = new WebInspector.AllocationDataGrid(profile.target(), this); |
+ this._allocationDataGrid.addEventListener( |
+ WebInspector.DataGrid.Events.SelectedNode, this._onSelectAllocationNode, this); |
+ this._allocationWidget = this._allocationDataGrid.asWidget(); |
+ this._allocationWidget.setMinimumSize(50, 25); |
- this._allocationStackView = new WebInspector.HeapAllocationStackView(profile.target()); |
- this._allocationStackView.setMinimumSize(50, 25); |
+ this._allocationStackView = new WebInspector.HeapAllocationStackView(profile.target()); |
+ this._allocationStackView.setMinimumSize(50, 25); |
- this._tabbedPane = new WebInspector.TabbedPane(); |
+ this._tabbedPane = new WebInspector.TabbedPane(); |
} |
this._retainmentDataGrid = new WebInspector.HeapSnapshotRetainmentDataGrid(this); |
this._retainmentWidget = this._retainmentDataGrid.asWidget(); |
this._retainmentWidget.setMinimumSize(50, 21); |
- this._retainmentWidget.element.classList.add("retaining-paths-view"); |
+ this._retainmentWidget.element.classList.add('retaining-paths-view'); |
var splitWidgetResizer; |
if (this._allocationStackView) { |
- this._tabbedPane = new WebInspector.TabbedPane(); |
+ this._tabbedPane = new WebInspector.TabbedPane(); |
- this._tabbedPane.appendTab("retainers", WebInspector.UIString("Retainers"), this._retainmentWidget); |
- this._tabbedPane.appendTab("allocation-stack", WebInspector.UIString("Allocation stack"), this._allocationStackView); |
+ this._tabbedPane.appendTab('retainers', WebInspector.UIString('Retainers'), this._retainmentWidget); |
+ this._tabbedPane.appendTab( |
+ 'allocation-stack', WebInspector.UIString('Allocation stack'), this._allocationStackView); |
- splitWidgetResizer = this._tabbedPane.headerElement(); |
- this._objectDetailsView = this._tabbedPane; |
+ splitWidgetResizer = this._tabbedPane.headerElement(); |
+ this._objectDetailsView = this._tabbedPane; |
} else { |
- var retainmentViewHeader = createElementWithClass("div", "heap-snapshot-view-resizer"); |
- var retainingPathsTitleDiv = retainmentViewHeader.createChild("div", "title"); |
- var retainingPathsTitle = retainingPathsTitleDiv.createChild("span"); |
- retainingPathsTitle.textContent = WebInspector.UIString("Retainers"); |
- |
- splitWidgetResizer = retainmentViewHeader; |
- this._objectDetailsView = new WebInspector.VBox(); |
- this._objectDetailsView.element.appendChild(retainmentViewHeader); |
- this._retainmentWidget.show(this._objectDetailsView.element); |
+ var retainmentViewHeader = createElementWithClass('div', 'heap-snapshot-view-resizer'); |
+ var retainingPathsTitleDiv = retainmentViewHeader.createChild('div', 'title'); |
+ var retainingPathsTitle = retainingPathsTitleDiv.createChild('span'); |
+ retainingPathsTitle.textContent = WebInspector.UIString('Retainers'); |
+ |
+ splitWidgetResizer = retainmentViewHeader; |
+ this._objectDetailsView = new WebInspector.VBox(); |
+ this._objectDetailsView.element.appendChild(retainmentViewHeader); |
+ this._retainmentWidget.show(this._objectDetailsView.element); |
} |
this._splitWidget.hideDefaultResizer(); |
this._splitWidget.installResizer(splitWidgetResizer); |
- this._retainmentDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._inspectedObjectChanged, this); |
+ this._retainmentDataGrid.addEventListener( |
+ WebInspector.DataGrid.Events.SelectedNode, this._inspectedObjectChanged, this); |
this._retainmentDataGrid.reset(); |
this._perspectives = []; |
this._perspectives.push(new WebInspector.HeapSnapshotView.SummaryPerspective()); |
if (profile.profileType() !== WebInspector.ProfileTypeRegistry.instance.trackingHeapSnapshotProfileType) |
- this._perspectives.push(new WebInspector.HeapSnapshotView.ComparisonPerspective()); |
+ this._perspectives.push(new WebInspector.HeapSnapshotView.ComparisonPerspective()); |
this._perspectives.push(new WebInspector.HeapSnapshotView.ContainmentPerspective()); |
if (this._allocationWidget) |
- this._perspectives.push(new WebInspector.HeapSnapshotView.AllocationPerspective()); |
+ this._perspectives.push(new WebInspector.HeapSnapshotView.AllocationPerspective()); |
this._perspectives.push(new WebInspector.HeapSnapshotView.StatisticsPerspective()); |
this._perspectiveSelect = new WebInspector.ToolbarComboBox(this._onSelectedPerspectiveChanged.bind(this)); |
for (var i = 0; i < this._perspectives.length; ++i) |
- this._perspectiveSelect.createOption(this._perspectives[i].title()); |
+ this._perspectiveSelect.createOption(this._perspectives[i].title()); |
this._profile = profile; |
@@ -142,14 +149,15 @@ WebInspector.HeapSnapshotView = function(dataDisplayDelegate, profile) |
this._filterSelect.setVisible(false); |
this._updateFilterOptions(); |
- this._classNameFilter = new WebInspector.ToolbarInput("Class filter"); |
+ this._classNameFilter = new WebInspector.ToolbarInput('Class filter'); |
this._classNameFilter.setVisible(false); |
this._constructorsDataGrid.setNameFilter(this._classNameFilter); |
this._diffDataGrid.setNameFilter(this._classNameFilter); |
this._selectedSizeText = new WebInspector.ToolbarText(); |
- this._popoverHelper = new WebInspector.ObjectPopoverHelper(this.element, this._getHoverAnchor.bind(this), this._resolveObjectForPopover.bind(this), undefined, true); |
+ this._popoverHelper = new WebInspector.ObjectPopoverHelper( |
+ this.element, this._getHoverAnchor.bind(this), this._resolveObjectForPopover.bind(this), undefined, true); |
this._currentPerspectiveIndex = 0; |
this._currentPerspective = this._perspectives[0]; |
@@ -158,1039 +166,1127 @@ WebInspector.HeapSnapshotView = function(dataDisplayDelegate, profile) |
this._populate(); |
this._searchThrottler = new WebInspector.Throttler(0); |
-}; |
- |
-/** |
- * @constructor |
- * @param {string} title |
- */ |
-WebInspector.HeapSnapshotView.Perspective = function(title) |
-{ |
- this._title = title; |
-}; |
+ } |
+ |
+ /** |
+ * @return {!WebInspector.SearchableView} |
+ */ |
+ searchableView() { |
+ return this._searchableView; |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {?WebInspector.ProfileHeader} profile |
+ * @return {?WebInspector.Widget} |
+ */ |
+ showProfile(profile) { |
+ return this._parentDataDisplayDelegate.showProfile(profile); |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {!HeapProfilerAgent.HeapSnapshotObjectId} snapshotObjectId |
+ * @param {string} perspectiveName |
+ */ |
+ showObject(snapshotObjectId, perspectiveName) { |
+ if (snapshotObjectId <= this._profile.maxJSObjectId) |
+ this.selectLiveObject(perspectiveName, snapshotObjectId); |
+ else |
+ this._parentDataDisplayDelegate.showObject(snapshotObjectId, perspectiveName); |
+ } |
+ |
+ _populate() { |
+ this._profile._loadPromise |
+ .then(heapSnapshotProxy => { |
+ heapSnapshotProxy.getStatistics().then(this._gotStatistics.bind(this)); |
+ this._dataGrid.setDataSource(heapSnapshotProxy); |
+ if (this._profile.profileType().id === WebInspector.TrackingHeapSnapshotProfileType.TypeId && |
+ this._profile.fromFile()) |
+ return heapSnapshotProxy.getSamples().then(samples => this._trackingOverviewGrid._setSamples(samples)); |
+ }) |
+ .then(_ => { |
+ var list = this._profiles(); |
+ var profileIndex = list.indexOf(this._profile); |
+ this._baseSelect.setSelectedIndex(Math.max(0, profileIndex - 1)); |
+ if (this._trackingOverviewGrid) |
+ this._trackingOverviewGrid._updateGrid(); |
+ }); |
+ } |
+ |
+ /** |
+ * @param {!WebInspector.HeapSnapshotCommon.Statistics} statistics |
+ */ |
+ _gotStatistics(statistics) { |
+ this._statisticsView.setTotal(statistics.total); |
+ this._statisticsView.addRecord(statistics.code, WebInspector.UIString('Code'), '#f77'); |
+ this._statisticsView.addRecord(statistics.strings, WebInspector.UIString('Strings'), '#5e5'); |
+ this._statisticsView.addRecord(statistics.jsArrays, WebInspector.UIString('JS Arrays'), '#7af'); |
+ this._statisticsView.addRecord(statistics.native, WebInspector.UIString('Typed Arrays'), '#fc5'); |
+ this._statisticsView.addRecord(statistics.system, WebInspector.UIString('System Objects'), '#98f'); |
+ this._statisticsView.addRecord(statistics.total, WebInspector.UIString('Total')); |
+ } |
+ |
+ /** |
+ * @param {!WebInspector.Event} event |
+ */ |
+ _onIdsRangeChanged(event) { |
+ var minId = event.data.minId; |
+ var maxId = event.data.maxId; |
+ this._selectedSizeText.setText(WebInspector.UIString('Selected size: %s', Number.bytesToString(event.data.size))); |
+ if (this._constructorsDataGrid.snapshot) |
+ this._constructorsDataGrid.setSelectionRange(minId, maxId); |
+ } |
+ |
+ /** |
+ * @override |
+ * @return {!Array.<!WebInspector.ToolbarItem>} |
+ */ |
+ syncToolbarItems() { |
+ var result = [this._perspectiveSelect, this._classNameFilter]; |
+ if (this._profile.profileType() !== WebInspector.ProfileTypeRegistry.instance.trackingHeapSnapshotProfileType) |
+ result.push(this._baseSelect, this._filterSelect); |
+ result.push(this._selectedSizeText); |
+ return result; |
+ } |
+ |
+ /** |
+ * @override |
+ */ |
+ wasShown() { |
+ this._profile._loadPromise.then(this._profile._wasShown.bind(this._profile)); |
+ } |
+ |
+ /** |
+ * @override |
+ */ |
+ willHide() { |
+ this._currentSearchResultIndex = -1; |
+ this._popoverHelper.hidePopover(); |
+ if (this.helpPopover && this.helpPopover.isShowing()) |
+ this.helpPopover.hide(); |
+ } |
+ |
+ /** |
+ * @override |
+ * @return {boolean} |
+ */ |
+ supportsCaseSensitiveSearch() { |
+ return true; |
+ } |
+ |
+ /** |
+ * @override |
+ * @return {boolean} |
+ */ |
+ supportsRegexSearch() { |
+ return false; |
+ } |
+ |
+ /** |
+ * @override |
+ */ |
+ searchCanceled() { |
+ this._currentSearchResultIndex = -1; |
+ this._searchResults = []; |
+ } |
+ |
+ /** |
+ * @param {?WebInspector.HeapSnapshotGridNode} node |
+ */ |
+ _selectRevealedNode(node) { |
+ if (node) |
+ node.select(); |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {!WebInspector.SearchableView.SearchConfig} searchConfig |
+ * @param {boolean} shouldJump |
+ * @param {boolean=} jumpBackwards |
+ */ |
+ performSearch(searchConfig, shouldJump, jumpBackwards) { |
+ var nextQuery = new WebInspector.HeapSnapshotCommon.SearchConfig( |
+ searchConfig.query.trim(), searchConfig.caseSensitive, searchConfig.isRegex, shouldJump, |
+ jumpBackwards || false); |
+ |
+ this._searchThrottler.schedule(this._performSearch.bind(this, nextQuery)); |
+ } |
+ |
+ /** |
+ * @param {!WebInspector.HeapSnapshotCommon.SearchConfig} nextQuery |
+ * @return {!Promise<?>} |
+ */ |
+ _performSearch(nextQuery) { |
+ // Call searchCanceled since it will reset everything we need before doing a new search. |
+ this.searchCanceled(); |
+ |
+ if (!this._currentPerspective.supportsSearch()) |
+ return Promise.resolve(); |
+ |
+ this.currentQuery = nextQuery; |
+ var query = nextQuery.query.trim(); |
+ |
+ if (!query) |
+ return Promise.resolve(); |
+ |
+ if (query.charAt(0) === '@') { |
+ var snapshotNodeId = parseInt(query.substring(1), 10); |
+ if (isNaN(snapshotNodeId)) |
+ return Promise.resolve(); |
+ return this._dataGrid.revealObjectByHeapSnapshotId(String(snapshotNodeId)) |
+ .then(this._selectRevealedNode.bind(this)); |
+ } |
-WebInspector.HeapSnapshotView.Perspective.prototype = { |
/** |
- * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
- */ |
- activate: function(heapSnapshotView) { }, |
+ * @param {!Array<number>} entryIds |
+ * @return {!Promise<?>} |
+ * @this {WebInspector.HeapSnapshotView} |
+ */ |
+ function didSearch(entryIds) { |
+ this._searchResults = entryIds; |
+ this._searchableView.updateSearchMatchesCount(this._searchResults.length); |
+ if (this._searchResults.length) |
+ this._currentSearchResultIndex = nextQuery.jumpBackwards ? this._searchResults.length - 1 : 0; |
+ return this._jumpToSearchResult(this._currentSearchResultIndex); |
+ } |
- /** |
- * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
- */ |
- deactivate: function(heapSnapshotView) |
- { |
- heapSnapshotView._baseSelect.setVisible(false); |
- heapSnapshotView._filterSelect.setVisible(false); |
- heapSnapshotView._classNameFilter.setVisible(false); |
- if (heapSnapshotView._trackingOverviewGrid) |
- heapSnapshotView._trackingOverviewGrid.detach(); |
- if (heapSnapshotView._allocationWidget) |
- heapSnapshotView._allocationWidget.detach(); |
- if (heapSnapshotView._statisticsView) |
- heapSnapshotView._statisticsView.detach(); |
- |
- heapSnapshotView._splitWidget.detach(); |
- heapSnapshotView._splitWidget.detachChildWidgets(); |
- }, |
+ return this._profile._snapshotProxy.search(this.currentQuery, this._dataGrid.nodeFilter()) |
+ .then(didSearch.bind(this)); |
+ } |
+ |
+ /** |
+ * @override |
+ */ |
+ jumpToNextSearchResult() { |
+ if (!this._searchResults.length) |
+ return; |
+ this._currentSearchResultIndex = (this._currentSearchResultIndex + 1) % this._searchResults.length; |
+ this._searchThrottler.schedule(this._jumpToSearchResult.bind(this, this._currentSearchResultIndex)); |
+ } |
+ |
+ /** |
+ * @override |
+ */ |
+ jumpToPreviousSearchResult() { |
+ if (!this._searchResults.length) |
+ return; |
+ this._currentSearchResultIndex = |
+ (this._currentSearchResultIndex + this._searchResults.length - 1) % this._searchResults.length; |
+ this._searchThrottler.schedule(this._jumpToSearchResult.bind(this, this._currentSearchResultIndex)); |
+ } |
+ |
+ /** |
+ * @param {number} searchResultIndex |
+ * @return {!Promise<undefined>} |
+ */ |
+ _jumpToSearchResult(searchResultIndex) { |
+ this._searchableView.updateCurrentMatchIndex(searchResultIndex); |
+ return this._dataGrid.revealObjectByHeapSnapshotId(String(this._searchResults[searchResultIndex])) |
+ .then(this._selectRevealedNode.bind(this)); |
+ } |
+ |
+ refreshVisibleData() { |
+ if (!this._dataGrid) |
+ return; |
+ var child = this._dataGrid.rootNode().children[0]; |
+ while (child) { |
+ child.refresh(); |
+ child = child.traverseNextNode(false, null, true); |
+ } |
+ } |
+ |
+ _changeBase() { |
+ if (this._baseProfile === this._profiles()[this._baseSelect.selectedIndex()]) |
+ return; |
+ |
+ this._baseProfile = this._profiles()[this._baseSelect.selectedIndex()]; |
+ var dataGrid = /** @type {!WebInspector.HeapSnapshotDiffDataGrid} */ (this._dataGrid); |
+ // Change set base data source only if main data source is already set. |
+ if (dataGrid.snapshot) |
+ this._baseProfile._loadPromise.then(dataGrid.setBaseDataSource.bind(dataGrid)); |
+ |
+ if (!this.currentQuery || !this._searchResults) |
+ return; |
+ |
+ // The current search needs to be performed again. First negate out previous match |
+ // count by calling the search finished callback with a negative number of matches. |
+ // Then perform the search again with the same query and callback. |
+ this.performSearch(this.currentQuery, false); |
+ } |
+ |
+ _changeFilter() { |
+ var profileIndex = this._filterSelect.selectedIndex() - 1; |
+ this._dataGrid.filterSelectIndexChanged(this._profiles(), profileIndex); |
+ |
+ if (!this.currentQuery || !this._searchResults) |
+ return; |
+ |
+ // The current search needs to be performed again. First negate out previous match |
+ // count by calling the search finished callback with a negative number of matches. |
+ // Then perform the search again with the same query and callback. |
+ this.performSearch(this.currentQuery, false); |
+ } |
+ |
+ /** |
+ * @return {!Array.<!WebInspector.ProfileHeader>} |
+ */ |
+ _profiles() { |
+ return this._profile.profileType().getProfiles(); |
+ } |
+ |
+ /** |
+ * @param {!WebInspector.ContextMenu} contextMenu |
+ * @param {!Event} event |
+ */ |
+ populateContextMenu(contextMenu, event) { |
+ if (this._dataGrid) |
+ this._dataGrid.populateContextMenu(contextMenu, event); |
+ } |
+ |
+ _selectionChanged(event) { |
+ var selectedNode = event.target.selectedNode; |
+ this._setSelectedNodeForDetailsView(selectedNode); |
+ this._inspectedObjectChanged(event); |
+ } |
+ |
+ _onSelectAllocationNode(event) { |
+ var selectedNode = event.target.selectedNode; |
+ this._constructorsDataGrid.setAllocationNodeId(selectedNode.allocationNodeId()); |
+ this._setSelectedNodeForDetailsView(null); |
+ } |
+ |
+ _inspectedObjectChanged(event) { |
+ var selectedNode = event.target.selectedNode; |
+ var target = this._profile.target(); |
+ if (target && selectedNode instanceof WebInspector.HeapSnapshotGenericObjectNode) |
+ target.heapProfilerAgent().addInspectedHeapObject(String(selectedNode.snapshotNodeId)); |
+ } |
+ |
+ /** |
+ * @param {?WebInspector.HeapSnapshotGridNode} nodeItem |
+ */ |
+ _setSelectedNodeForDetailsView(nodeItem) { |
+ var dataSource = nodeItem && nodeItem.retainersDataSource(); |
+ if (dataSource) { |
+ this._retainmentDataGrid.setDataSource(dataSource.snapshot, dataSource.snapshotNodeIndex); |
+ if (this._allocationStackView) |
+ this._allocationStackView.setAllocatedObject(dataSource.snapshot, dataSource.snapshotNodeIndex); |
+ } else { |
+ if (this._allocationStackView) |
+ this._allocationStackView.clear(); |
+ this._retainmentDataGrid.reset(); |
+ } |
+ } |
+ |
+ /** |
+ * @param {string} perspectiveTitle |
+ * @param {function()} callback |
+ */ |
+ _changePerspectiveAndWait(perspectiveTitle, callback) { |
+ var perspectiveIndex = null; |
+ for (var i = 0; i < this._perspectives.length; ++i) { |
+ if (this._perspectives[i].title() === perspectiveTitle) { |
+ perspectiveIndex = i; |
+ break; |
+ } |
+ } |
+ if (this._currentPerspectiveIndex === perspectiveIndex || perspectiveIndex === null) { |
+ setTimeout(callback, 0); |
+ return; |
+ } |
/** |
- * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
- * @return {?WebInspector.DataGrid} |
+ * @this {WebInspector.HeapSnapshotView} |
*/ |
- masterGrid: function(heapSnapshotView) |
- { |
- return null; |
- }, |
+ function dataGridContentShown(event) { |
+ var dataGrid = event.data; |
+ dataGrid.removeEventListener( |
+ WebInspector.HeapSnapshotSortableDataGrid.Events.ContentShown, dataGridContentShown, this); |
+ if (dataGrid === this._dataGrid) |
+ callback(); |
+ } |
+ this._perspectives[perspectiveIndex].masterGrid(this).addEventListener( |
+ WebInspector.HeapSnapshotSortableDataGrid.Events.ContentShown, dataGridContentShown, this); |
- /** |
- * @return {string} |
- */ |
- title: function() |
- { |
- return this._title; |
- }, |
+ this._perspectiveSelect.setSelectedIndex(perspectiveIndex); |
+ this._changePerspective(perspectiveIndex); |
+ } |
- /** |
- * @return {boolean} |
- */ |
- supportsSearch: function() |
- { |
- return false; |
- } |
-}; |
+ _updateDataSourceAndView() { |
+ var dataGrid = this._dataGrid; |
+ if (!dataGrid || dataGrid.snapshot) |
+ return; |
-/** |
- * @constructor |
- * @extends {WebInspector.HeapSnapshotView.Perspective} |
- */ |
-WebInspector.HeapSnapshotView.SummaryPerspective = function() |
-{ |
- WebInspector.HeapSnapshotView.Perspective.call(this, WebInspector.UIString("Summary")); |
-}; |
+ this._profile._loadPromise.then(didLoadSnapshot.bind(this)); |
-WebInspector.HeapSnapshotView.SummaryPerspective.prototype = { |
/** |
- * @override |
- * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
+ * @this {WebInspector.HeapSnapshotView} |
*/ |
- activate: function(heapSnapshotView) |
- { |
- heapSnapshotView._splitWidget.setMainWidget(heapSnapshotView._constructorsWidget); |
- heapSnapshotView._splitWidget.setSidebarWidget(heapSnapshotView._objectDetailsView); |
- heapSnapshotView._splitWidget.show(heapSnapshotView._searchableView.element); |
- heapSnapshotView._filterSelect.setVisible(true); |
- heapSnapshotView._classNameFilter.setVisible(true); |
- if (heapSnapshotView._trackingOverviewGrid) { |
- heapSnapshotView._trackingOverviewGrid.show(heapSnapshotView._searchableView.element, heapSnapshotView._splitWidget.element); |
- heapSnapshotView._trackingOverviewGrid.update(); |
- heapSnapshotView._trackingOverviewGrid._updateGrid(); |
- } |
- }, |
+ function didLoadSnapshot(snapshotProxy) { |
+ if (this._dataGrid !== dataGrid) |
+ return; |
+ if (dataGrid.snapshot !== snapshotProxy) |
+ dataGrid.setDataSource(snapshotProxy); |
+ if (dataGrid === this._diffDataGrid) { |
+ if (!this._baseProfile) |
+ this._baseProfile = this._profiles()[this._baseSelect.selectedIndex()]; |
+ this._baseProfile._loadPromise.then(didLoadBaseSnapshot.bind(this)); |
+ } |
+ } |
/** |
- * @override |
- * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
- * @return {?WebInspector.DataGrid} |
+ * @this {WebInspector.HeapSnapshotView} |
*/ |
- masterGrid: function(heapSnapshotView) |
- { |
- return heapSnapshotView._constructorsDataGrid; |
- }, |
+ function didLoadBaseSnapshot(baseSnapshotProxy) { |
+ if (this._diffDataGrid.baseSnapshot !== baseSnapshotProxy) |
+ this._diffDataGrid.setBaseDataSource(baseSnapshotProxy); |
+ } |
+ } |
- /** |
- * @override |
- * @return {boolean} |
- */ |
- supportsSearch: function() |
- { |
- return true; |
- }, |
+ _onSelectedPerspectiveChanged(event) { |
+ this._changePerspective(event.target.selectedIndex); |
+ } |
- __proto__: WebInspector.HeapSnapshotView.Perspective.prototype |
-}; |
+ /** |
+ * @param {number} selectedIndex |
+ */ |
+ _changePerspective(selectedIndex) { |
+ if (selectedIndex === this._currentPerspectiveIndex) |
+ return; |
-/** |
- * @constructor |
- * @extends {WebInspector.HeapSnapshotView.Perspective} |
- */ |
-WebInspector.HeapSnapshotView.ComparisonPerspective = function() |
-{ |
- WebInspector.HeapSnapshotView.Perspective.call(this, WebInspector.UIString("Comparison")); |
-}; |
+ this._currentPerspectiveIndex = selectedIndex; |
-WebInspector.HeapSnapshotView.ComparisonPerspective.prototype = { |
- /** |
- * @override |
- * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
- */ |
- activate: function(heapSnapshotView) |
- { |
- heapSnapshotView._splitWidget.setMainWidget(heapSnapshotView._diffWidget); |
- heapSnapshotView._splitWidget.setSidebarWidget(heapSnapshotView._objectDetailsView); |
- heapSnapshotView._splitWidget.show(heapSnapshotView._searchableView.element); |
- heapSnapshotView._baseSelect.setVisible(true); |
- heapSnapshotView._classNameFilter.setVisible(true); |
- }, |
+ this._currentPerspective.deactivate(this); |
+ var perspective = this._perspectives[selectedIndex]; |
+ this._currentPerspective = perspective; |
+ this._dataGrid = perspective.masterGrid(this); |
+ perspective.activate(this); |
- /** |
- * @override |
- * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
- * @return {?WebInspector.DataGrid} |
- */ |
- masterGrid: function(heapSnapshotView) |
- { |
- return heapSnapshotView._diffDataGrid; |
- }, |
+ this.refreshVisibleData(); |
+ if (this._dataGrid) |
+ this._dataGrid.updateWidths(); |
- /** |
- * @override |
- * @return {boolean} |
- */ |
- supportsSearch: function() |
- { |
- return true; |
- }, |
+ this._updateDataSourceAndView(); |
- __proto__: WebInspector.HeapSnapshotView.Perspective.prototype |
-}; |
+ if (!this.currentQuery || !this._searchResults) |
+ return; |
-/** |
- * @constructor |
- * @extends {WebInspector.HeapSnapshotView.Perspective} |
- */ |
-WebInspector.HeapSnapshotView.ContainmentPerspective = function() |
-{ |
- WebInspector.HeapSnapshotView.Perspective.call(this, WebInspector.UIString("Containment")); |
-}; |
+ // The current search needs to be performed again. First negate out previous match |
+ // count by calling the search finished callback with a negative number of matches. |
+ // Then perform the search again the with same query and callback. |
+ this.performSearch(this.currentQuery, false); |
+ } |
+ |
+ /** |
+ * @param {string} perspectiveName |
+ * @param {!HeapProfilerAgent.HeapSnapshotObjectId} snapshotObjectId |
+ */ |
+ selectLiveObject(perspectiveName, snapshotObjectId) { |
+ this._changePerspectiveAndWait(perspectiveName, didChangePerspective.bind(this)); |
-WebInspector.HeapSnapshotView.ContainmentPerspective.prototype = { |
/** |
- * @override |
- * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
+ * @this {WebInspector.HeapSnapshotView} |
*/ |
- activate: function(heapSnapshotView) |
- { |
- heapSnapshotView._splitWidget.setMainWidget(heapSnapshotView._containmentWidget); |
- heapSnapshotView._splitWidget.setSidebarWidget(heapSnapshotView._objectDetailsView); |
- heapSnapshotView._splitWidget.show(heapSnapshotView._searchableView.element); |
- }, |
+ function didChangePerspective() { |
+ this._dataGrid.revealObjectByHeapSnapshotId(snapshotObjectId, didRevealObject); |
+ } |
/** |
- * @override |
- * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
- * @return {?WebInspector.DataGrid} |
+ * @param {?WebInspector.HeapSnapshotGridNode} node |
*/ |
- masterGrid: function(heapSnapshotView) |
- { |
- return heapSnapshotView._containmentDataGrid; |
- }, |
+ function didRevealObject(node) { |
+ if (node) |
+ node.select(); |
+ else |
+ WebInspector.console.error('Cannot find corresponding heap snapshot node'); |
+ } |
+ } |
+ |
+ _getHoverAnchor(target) { |
+ var span = target.enclosingNodeOrSelfWithNodeName('span'); |
+ if (!span) |
+ return; |
+ var row = target.enclosingNodeOrSelfWithNodeName('tr'); |
+ if (!row) |
+ return; |
+ span.node = row._dataGridNode; |
+ return span; |
+ } |
+ |
+ _resolveObjectForPopover(element, showCallback, objectGroupName) { |
+ if (!this._profile.target()) |
+ return; |
+ if (!element.node) |
+ return; |
+ element.node.queryObjectContent(this._profile.target(), showCallback, objectGroupName); |
+ } |
+ |
+ _updateBaseOptions() { |
+ var list = this._profiles(); |
+ // We're assuming that snapshots can only be added. |
+ if (this._baseSelect.size() === list.length) |
+ return; |
+ |
+ for (var i = this._baseSelect.size(), n = list.length; i < n; ++i) { |
+ var title = list[i].title; |
+ this._baseSelect.createOption(title); |
+ } |
+ } |
+ |
+ _updateFilterOptions() { |
+ var list = this._profiles(); |
+ // We're assuming that snapshots can only be added. |
+ if (this._filterSelect.size() - 1 === list.length) |
+ return; |
+ |
+ if (!this._filterSelect.size()) |
+ this._filterSelect.createOption(WebInspector.UIString('All objects')); |
+ |
+ for (var i = this._filterSelect.size() - 1, n = list.length; i < n; ++i) { |
+ var title = list[i].title; |
+ if (!i) |
+ title = WebInspector.UIString('Objects allocated before %s', title); |
+ else |
+ title = WebInspector.UIString('Objects allocated between %s and %s', list[i - 1].title, title); |
+ this._filterSelect.createOption(title); |
+ } |
+ } |
+ |
+ _updateControls() { |
+ this._updateBaseOptions(); |
+ this._updateFilterOptions(); |
+ } |
+ |
+ /** |
+ * @param {!WebInspector.Event} event |
+ */ |
+ _onReceiveSnapshot(event) { |
+ this._updateControls(); |
+ } |
+ |
+ /** |
+ * @param {!WebInspector.Event} event |
+ */ |
+ _onProfileHeaderRemoved(event) { |
+ var profile = event.data; |
+ if (this._profile === profile) { |
+ this.detach(); |
+ this._profile.profileType().removeEventListener( |
+ WebInspector.HeapSnapshotProfileType.SnapshotReceived, this._onReceiveSnapshot, this); |
+ this._profile.profileType().removeEventListener( |
+ WebInspector.ProfileType.Events.RemoveProfileHeader, this._onProfileHeaderRemoved, this); |
+ this.dispose(); |
+ } else { |
+ this._updateControls(); |
+ } |
+ } |
- __proto__: WebInspector.HeapSnapshotView.Perspective.prototype |
+ dispose() { |
+ if (this._allocationStackView) { |
+ this._allocationStackView.clear(); |
+ this._allocationDataGrid.dispose(); |
+ } |
+ if (this._trackingOverviewGrid) |
+ this._trackingOverviewGrid.dispose(); |
+ } |
}; |
/** |
- * @constructor |
- * @extends {WebInspector.HeapSnapshotView.Perspective} |
+ * @unrestricted |
*/ |
-WebInspector.HeapSnapshotView.AllocationPerspective = function() |
-{ |
- WebInspector.HeapSnapshotView.Perspective.call(this, WebInspector.UIString("Allocation")); |
- this._allocationSplitWidget = new WebInspector.SplitWidget(false, true, "heapSnapshotAllocationSplitViewState", 200, 200); |
- this._allocationSplitWidget.setSidebarWidget(new WebInspector.VBox()); |
- |
+WebInspector.HeapSnapshotView.Perspective = class { |
+ /** |
+ * @param {string} title |
+ */ |
+ constructor(title) { |
+ this._title = title; |
+ } |
+ |
+ /** |
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
+ */ |
+ activate(heapSnapshotView) { |
+ } |
+ |
+ /** |
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
+ */ |
+ deactivate(heapSnapshotView) { |
+ heapSnapshotView._baseSelect.setVisible(false); |
+ heapSnapshotView._filterSelect.setVisible(false); |
+ heapSnapshotView._classNameFilter.setVisible(false); |
+ if (heapSnapshotView._trackingOverviewGrid) |
+ heapSnapshotView._trackingOverviewGrid.detach(); |
+ if (heapSnapshotView._allocationWidget) |
+ heapSnapshotView._allocationWidget.detach(); |
+ if (heapSnapshotView._statisticsView) |
+ heapSnapshotView._statisticsView.detach(); |
+ |
+ heapSnapshotView._splitWidget.detach(); |
+ heapSnapshotView._splitWidget.detachChildWidgets(); |
+ } |
+ |
+ /** |
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
+ * @return {?WebInspector.DataGrid} |
+ */ |
+ masterGrid(heapSnapshotView) { |
+ return null; |
+ } |
+ |
+ /** |
+ * @return {string} |
+ */ |
+ title() { |
+ return this._title; |
+ } |
+ |
+ /** |
+ * @return {boolean} |
+ */ |
+ supportsSearch() { |
+ return false; |
+ } |
}; |
-WebInspector.HeapSnapshotView.AllocationPerspective.prototype = { |
- /** |
- * @override |
- * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
- */ |
- activate: function(heapSnapshotView) |
- { |
- this._allocationSplitWidget.setMainWidget(heapSnapshotView._allocationWidget); |
- heapSnapshotView._splitWidget.setMainWidget(heapSnapshotView._constructorsWidget); |
- heapSnapshotView._splitWidget.setSidebarWidget(heapSnapshotView._objectDetailsView); |
- |
- var allocatedObjectsView = new WebInspector.VBox(); |
- var resizer = createElementWithClass("div", "heap-snapshot-view-resizer"); |
- var title = resizer.createChild("div", "title").createChild("span"); |
- title.textContent = WebInspector.UIString("Live objects"); |
- this._allocationSplitWidget.hideDefaultResizer(); |
- this._allocationSplitWidget.installResizer(resizer); |
- allocatedObjectsView.element.appendChild(resizer); |
- heapSnapshotView._splitWidget.show(allocatedObjectsView.element); |
- this._allocationSplitWidget.setSidebarWidget(allocatedObjectsView); |
- |
- this._allocationSplitWidget.show(heapSnapshotView._searchableView.element); |
- |
- heapSnapshotView._constructorsDataGrid.clear(); |
- var selectedNode = heapSnapshotView._allocationDataGrid.selectedNode; |
- if (selectedNode) |
- heapSnapshotView._constructorsDataGrid.setAllocationNodeId(selectedNode.allocationNodeId()); |
- }, |
- |
- /** |
- * @override |
- * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
- */ |
- deactivate: function(heapSnapshotView) |
- { |
- this._allocationSplitWidget.detach(); |
- WebInspector.HeapSnapshotView.Perspective.prototype.deactivate.call(this, heapSnapshotView); |
- }, |
- |
- /** |
- * @override |
- * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
- * @return {?WebInspector.DataGrid} |
- */ |
- masterGrid: function(heapSnapshotView) |
- { |
- return heapSnapshotView._allocationDataGrid; |
- }, |
- |
- __proto__: WebInspector.HeapSnapshotView.Perspective.prototype |
+/** |
+ * @unrestricted |
+ */ |
+WebInspector.HeapSnapshotView.SummaryPerspective = class extends WebInspector.HeapSnapshotView.Perspective { |
+ constructor() { |
+ super(WebInspector.UIString('Summary')); |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
+ */ |
+ activate(heapSnapshotView) { |
+ heapSnapshotView._splitWidget.setMainWidget(heapSnapshotView._constructorsWidget); |
+ heapSnapshotView._splitWidget.setSidebarWidget(heapSnapshotView._objectDetailsView); |
+ heapSnapshotView._splitWidget.show(heapSnapshotView._searchableView.element); |
+ heapSnapshotView._filterSelect.setVisible(true); |
+ heapSnapshotView._classNameFilter.setVisible(true); |
+ if (heapSnapshotView._trackingOverviewGrid) { |
+ heapSnapshotView._trackingOverviewGrid.show( |
+ heapSnapshotView._searchableView.element, heapSnapshotView._splitWidget.element); |
+ heapSnapshotView._trackingOverviewGrid.update(); |
+ heapSnapshotView._trackingOverviewGrid._updateGrid(); |
+ } |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
+ * @return {?WebInspector.DataGrid} |
+ */ |
+ masterGrid(heapSnapshotView) { |
+ return heapSnapshotView._constructorsDataGrid; |
+ } |
+ |
+ /** |
+ * @override |
+ * @return {boolean} |
+ */ |
+ supportsSearch() { |
+ return true; |
+ } |
}; |
/** |
- * @constructor |
- * @extends {WebInspector.HeapSnapshotView.Perspective} |
+ * @unrestricted |
*/ |
-WebInspector.HeapSnapshotView.StatisticsPerspective = function() |
-{ |
- WebInspector.HeapSnapshotView.Perspective.call(this, WebInspector.UIString("Statistics")); |
+WebInspector.HeapSnapshotView.ComparisonPerspective = class extends WebInspector.HeapSnapshotView.Perspective { |
+ constructor() { |
+ super(WebInspector.UIString('Comparison')); |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
+ */ |
+ activate(heapSnapshotView) { |
+ heapSnapshotView._splitWidget.setMainWidget(heapSnapshotView._diffWidget); |
+ heapSnapshotView._splitWidget.setSidebarWidget(heapSnapshotView._objectDetailsView); |
+ heapSnapshotView._splitWidget.show(heapSnapshotView._searchableView.element); |
+ heapSnapshotView._baseSelect.setVisible(true); |
+ heapSnapshotView._classNameFilter.setVisible(true); |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
+ * @return {?WebInspector.DataGrid} |
+ */ |
+ masterGrid(heapSnapshotView) { |
+ return heapSnapshotView._diffDataGrid; |
+ } |
+ |
+ /** |
+ * @override |
+ * @return {boolean} |
+ */ |
+ supportsSearch() { |
+ return true; |
+ } |
}; |
-WebInspector.HeapSnapshotView.StatisticsPerspective.prototype = { |
- /** |
- * @override |
- * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
- */ |
- activate: function(heapSnapshotView) |
- { |
- heapSnapshotView._statisticsView.show(heapSnapshotView._searchableView.element); |
- }, |
- |
- /** |
- * @override |
- * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
- * @return {?WebInspector.DataGrid} |
- */ |
- masterGrid: function(heapSnapshotView) |
- { |
- return null; |
- }, |
- |
- __proto__: WebInspector.HeapSnapshotView.Perspective.prototype |
+/** |
+ * @unrestricted |
+ */ |
+WebInspector.HeapSnapshotView.ContainmentPerspective = class extends WebInspector.HeapSnapshotView.Perspective { |
+ constructor() { |
+ super(WebInspector.UIString('Containment')); |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
+ */ |
+ activate(heapSnapshotView) { |
+ heapSnapshotView._splitWidget.setMainWidget(heapSnapshotView._containmentWidget); |
+ heapSnapshotView._splitWidget.setSidebarWidget(heapSnapshotView._objectDetailsView); |
+ heapSnapshotView._splitWidget.show(heapSnapshotView._searchableView.element); |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
+ * @return {?WebInspector.DataGrid} |
+ */ |
+ masterGrid(heapSnapshotView) { |
+ return heapSnapshotView._containmentDataGrid; |
+ } |
}; |
+/** |
+ * @unrestricted |
+ */ |
+WebInspector.HeapSnapshotView.AllocationPerspective = class extends WebInspector.HeapSnapshotView.Perspective { |
+ constructor() { |
+ super(WebInspector.UIString('Allocation')); |
+ this._allocationSplitWidget = |
+ new WebInspector.SplitWidget(false, true, 'heapSnapshotAllocationSplitViewState', 200, 200); |
+ this._allocationSplitWidget.setSidebarWidget(new WebInspector.VBox()); |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
+ */ |
+ activate(heapSnapshotView) { |
+ this._allocationSplitWidget.setMainWidget(heapSnapshotView._allocationWidget); |
+ heapSnapshotView._splitWidget.setMainWidget(heapSnapshotView._constructorsWidget); |
+ heapSnapshotView._splitWidget.setSidebarWidget(heapSnapshotView._objectDetailsView); |
+ |
+ var allocatedObjectsView = new WebInspector.VBox(); |
+ var resizer = createElementWithClass('div', 'heap-snapshot-view-resizer'); |
+ var title = resizer.createChild('div', 'title').createChild('span'); |
+ title.textContent = WebInspector.UIString('Live objects'); |
+ this._allocationSplitWidget.hideDefaultResizer(); |
+ this._allocationSplitWidget.installResizer(resizer); |
+ allocatedObjectsView.element.appendChild(resizer); |
+ heapSnapshotView._splitWidget.show(allocatedObjectsView.element); |
+ this._allocationSplitWidget.setSidebarWidget(allocatedObjectsView); |
+ |
+ this._allocationSplitWidget.show(heapSnapshotView._searchableView.element); |
+ |
+ heapSnapshotView._constructorsDataGrid.clear(); |
+ var selectedNode = heapSnapshotView._allocationDataGrid.selectedNode; |
+ if (selectedNode) |
+ heapSnapshotView._constructorsDataGrid.setAllocationNodeId(selectedNode.allocationNodeId()); |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
+ */ |
+ deactivate(heapSnapshotView) { |
+ this._allocationSplitWidget.detach(); |
+ super.deactivate(heapSnapshotView); |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
+ * @return {?WebInspector.DataGrid} |
+ */ |
+ masterGrid(heapSnapshotView) { |
+ return heapSnapshotView._allocationDataGrid; |
+ } |
+}; |
-WebInspector.HeapSnapshotView.prototype = { |
- /** |
- * @return {!WebInspector.SearchableView} |
- */ |
- searchableView: function() |
- { |
- return this._searchableView; |
- }, |
- |
- /** |
- * @override |
- * @param {?WebInspector.ProfileHeader} profile |
- * @return {?WebInspector.Widget} |
- */ |
- showProfile: function(profile) |
- { |
- return this._parentDataDisplayDelegate.showProfile(profile); |
- }, |
- |
- /** |
- * @override |
- * @param {!HeapProfilerAgent.HeapSnapshotObjectId} snapshotObjectId |
- * @param {string} perspectiveName |
- */ |
- showObject: function(snapshotObjectId, perspectiveName) |
- { |
- if (snapshotObjectId <= this._profile.maxJSObjectId) |
- this.selectLiveObject(perspectiveName, snapshotObjectId); |
- else |
- this._parentDataDisplayDelegate.showObject(snapshotObjectId, perspectiveName); |
- }, |
- |
- _populate: function() |
- { |
- this._profile._loadPromise.then(heapSnapshotProxy => { |
- heapSnapshotProxy.getStatistics().then(this._gotStatistics.bind(this)); |
- this._dataGrid.setDataSource(heapSnapshotProxy); |
- if (this._profile.profileType().id === WebInspector.TrackingHeapSnapshotProfileType.TypeId && this._profile.fromFile()) |
- return heapSnapshotProxy.getSamples().then(samples => this._trackingOverviewGrid._setSamples(samples)); |
- }).then(_ => { |
- var list = this._profiles(); |
- var profileIndex = list.indexOf(this._profile); |
- this._baseSelect.setSelectedIndex(Math.max(0, profileIndex - 1)); |
- if (this._trackingOverviewGrid) |
- this._trackingOverviewGrid._updateGrid(); |
- }); |
- }, |
- |
- /** |
- * @param {!WebInspector.HeapSnapshotCommon.Statistics} statistics |
- */ |
- _gotStatistics: function(statistics) |
- { |
- this._statisticsView.setTotal(statistics.total); |
- this._statisticsView.addRecord(statistics.code, WebInspector.UIString("Code"), "#f77"); |
- this._statisticsView.addRecord(statistics.strings, WebInspector.UIString("Strings"), "#5e5"); |
- this._statisticsView.addRecord(statistics.jsArrays, WebInspector.UIString("JS Arrays"), "#7af"); |
- this._statisticsView.addRecord(statistics.native, WebInspector.UIString("Typed Arrays"), "#fc5"); |
- this._statisticsView.addRecord(statistics.system, WebInspector.UIString("System Objects"), "#98f"); |
- this._statisticsView.addRecord(statistics.total, WebInspector.UIString("Total")); |
- }, |
- |
- /** |
- * @param {!WebInspector.Event} event |
- */ |
- _onIdsRangeChanged: function(event) |
- { |
- var minId = event.data.minId; |
- var maxId = event.data.maxId; |
- this._selectedSizeText.setText(WebInspector.UIString("Selected size: %s", Number.bytesToString(event.data.size))); |
- if (this._constructorsDataGrid.snapshot) |
- this._constructorsDataGrid.setSelectionRange(minId, maxId); |
- }, |
- |
- /** |
- * @override |
- * @return {!Array.<!WebInspector.ToolbarItem>} |
- */ |
- syncToolbarItems: function() |
- { |
- var result = [this._perspectiveSelect, this._classNameFilter]; |
- if (this._profile.profileType() !== WebInspector.ProfileTypeRegistry.instance.trackingHeapSnapshotProfileType) |
- result.push(this._baseSelect, this._filterSelect); |
- result.push(this._selectedSizeText); |
- return result; |
- }, |
- |
- /** |
- * @override |
- */ |
- wasShown: function() |
- { |
- this._profile._loadPromise.then(this._profile._wasShown.bind(this._profile)); |
- }, |
- |
- /** |
- * @override |
- */ |
- willHide: function() |
- { |
- this._currentSearchResultIndex = -1; |
- this._popoverHelper.hidePopover(); |
- if (this.helpPopover && this.helpPopover.isShowing()) |
- this.helpPopover.hide(); |
- }, |
- |
- /** |
- * @override |
- * @return {boolean} |
- */ |
- supportsCaseSensitiveSearch: function() |
- { |
- return true; |
- }, |
- |
- /** |
- * @override |
- * @return {boolean} |
- */ |
- supportsRegexSearch: function() |
- { |
- return false; |
- }, |
- |
- /** |
- * @override |
- */ |
- searchCanceled: function() |
- { |
- this._currentSearchResultIndex = -1; |
- this._searchResults = []; |
- }, |
- |
- /** |
- * @param {?WebInspector.HeapSnapshotGridNode} node |
- */ |
- _selectRevealedNode: function(node) |
- { |
- if (node) |
- node.select(); |
- }, |
- |
- /** |
- * @override |
- * @param {!WebInspector.SearchableView.SearchConfig} searchConfig |
- * @param {boolean} shouldJump |
- * @param {boolean=} jumpBackwards |
- */ |
- performSearch: function(searchConfig, shouldJump, jumpBackwards) |
- { |
- var nextQuery = new WebInspector.HeapSnapshotCommon.SearchConfig( |
- searchConfig.query.trim(), |
- searchConfig.caseSensitive, |
- searchConfig.isRegex, |
- shouldJump, |
- jumpBackwards || false |
- ); |
- |
- this._searchThrottler.schedule(this._performSearch.bind(this, nextQuery)); |
- }, |
- |
- /** |
- * @param {!WebInspector.HeapSnapshotCommon.SearchConfig} nextQuery |
- * @return {!Promise<?>} |
- */ |
- _performSearch: function(nextQuery) |
- { |
- // Call searchCanceled since it will reset everything we need before doing a new search. |
- this.searchCanceled(); |
- |
- if (!this._currentPerspective.supportsSearch()) |
- return Promise.resolve(); |
- |
- this.currentQuery = nextQuery; |
- var query = nextQuery.query.trim(); |
- |
- if (!query) |
- return Promise.resolve(); |
- |
- if (query.charAt(0) === "@") { |
- var snapshotNodeId = parseInt(query.substring(1), 10); |
- if (isNaN(snapshotNodeId)) |
- return Promise.resolve(); |
- return this._dataGrid.revealObjectByHeapSnapshotId(String(snapshotNodeId)).then(this._selectRevealedNode.bind(this)); |
- } |
- |
- /** |
- * @param {!Array<number>} entryIds |
- * @return {!Promise<?>} |
- * @this {WebInspector.HeapSnapshotView} |
- */ |
- function didSearch(entryIds) |
- { |
- this._searchResults = entryIds; |
- this._searchableView.updateSearchMatchesCount(this._searchResults.length); |
- if (this._searchResults.length) |
- this._currentSearchResultIndex = nextQuery.jumpBackwards ? this._searchResults.length - 1 : 0; |
- return this._jumpToSearchResult(this._currentSearchResultIndex); |
- } |
- |
- return this._profile._snapshotProxy.search(this.currentQuery, this._dataGrid.nodeFilter()).then(didSearch.bind(this)); |
- }, |
- |
- /** |
- * @override |
- */ |
- jumpToNextSearchResult: function() |
- { |
- if (!this._searchResults.length) |
- return; |
- this._currentSearchResultIndex = (this._currentSearchResultIndex + 1) % this._searchResults.length; |
- this._searchThrottler.schedule(this._jumpToSearchResult.bind(this, this._currentSearchResultIndex)); |
- }, |
- |
- /** |
- * @override |
- */ |
- jumpToPreviousSearchResult: function() |
- { |
- if (!this._searchResults.length) |
- return; |
- this._currentSearchResultIndex = (this._currentSearchResultIndex + this._searchResults.length - 1) % this._searchResults.length; |
- this._searchThrottler.schedule(this._jumpToSearchResult.bind(this, this._currentSearchResultIndex)); |
- }, |
- |
- /** |
- * @param {number} searchResultIndex |
- * @return {!Promise<undefined>} |
- */ |
- _jumpToSearchResult: function(searchResultIndex) |
- { |
- this._searchableView.updateCurrentMatchIndex(searchResultIndex); |
- return this._dataGrid.revealObjectByHeapSnapshotId(String(this._searchResults[searchResultIndex])).then(this._selectRevealedNode.bind(this)); |
- }, |
- |
- refreshVisibleData: function() |
- { |
- if (!this._dataGrid) |
- return; |
- var child = this._dataGrid.rootNode().children[0]; |
- while (child) { |
- child.refresh(); |
- child = child.traverseNextNode(false, null, true); |
- } |
- }, |
- |
- _changeBase: function() |
- { |
- if (this._baseProfile === this._profiles()[this._baseSelect.selectedIndex()]) |
- return; |
- |
- this._baseProfile = this._profiles()[this._baseSelect.selectedIndex()]; |
- var dataGrid = /** @type {!WebInspector.HeapSnapshotDiffDataGrid} */ (this._dataGrid); |
- // Change set base data source only if main data source is already set. |
- if (dataGrid.snapshot) |
- this._baseProfile._loadPromise.then(dataGrid.setBaseDataSource.bind(dataGrid)); |
- |
- if (!this.currentQuery || !this._searchResults) |
- return; |
- |
- // The current search needs to be performed again. First negate out previous match |
- // count by calling the search finished callback with a negative number of matches. |
- // Then perform the search again with the same query and callback. |
- this.performSearch(this.currentQuery, false); |
- }, |
- |
- _changeFilter: function() |
- { |
- var profileIndex = this._filterSelect.selectedIndex() - 1; |
- this._dataGrid.filterSelectIndexChanged(this._profiles(), profileIndex); |
- |
- if (!this.currentQuery || !this._searchResults) |
- return; |
- |
- // The current search needs to be performed again. First negate out previous match |
- // count by calling the search finished callback with a negative number of matches. |
- // Then perform the search again with the same query and callback. |
- this.performSearch(this.currentQuery, false); |
- }, |
- |
- /** |
- * @return {!Array.<!WebInspector.ProfileHeader>} |
- */ |
- _profiles: function() |
- { |
- return this._profile.profileType().getProfiles(); |
- }, |
- |
- /** |
- * @param {!WebInspector.ContextMenu} contextMenu |
- * @param {!Event} event |
- */ |
- populateContextMenu: function(contextMenu, event) |
- { |
- if (this._dataGrid) |
- this._dataGrid.populateContextMenu(contextMenu, event); |
- }, |
- |
- _selectionChanged: function(event) |
- { |
- var selectedNode = event.target.selectedNode; |
- this._setSelectedNodeForDetailsView(selectedNode); |
- this._inspectedObjectChanged(event); |
- }, |
- |
- _onSelectAllocationNode: function(event) |
- { |
- var selectedNode = event.target.selectedNode; |
- this._constructorsDataGrid.setAllocationNodeId(selectedNode.allocationNodeId()); |
- this._setSelectedNodeForDetailsView(null); |
- }, |
- |
- _inspectedObjectChanged: function(event) |
- { |
- var selectedNode = event.target.selectedNode; |
- var target = this._profile.target(); |
- if (target && selectedNode instanceof WebInspector.HeapSnapshotGenericObjectNode) |
- target.heapProfilerAgent().addInspectedHeapObject(String(selectedNode.snapshotNodeId)); |
- }, |
- |
- /** |
- * @param {?WebInspector.HeapSnapshotGridNode} nodeItem |
- */ |
- _setSelectedNodeForDetailsView: function(nodeItem) |
- { |
- var dataSource = nodeItem && nodeItem.retainersDataSource(); |
- if (dataSource) { |
- this._retainmentDataGrid.setDataSource(dataSource.snapshot, dataSource.snapshotNodeIndex); |
- if (this._allocationStackView) |
- this._allocationStackView.setAllocatedObject(dataSource.snapshot, dataSource.snapshotNodeIndex); |
- } else { |
- if (this._allocationStackView) |
- this._allocationStackView.clear(); |
- this._retainmentDataGrid.reset(); |
- } |
- }, |
- |
- /** |
- * @param {string} perspectiveTitle |
- * @param {function()} callback |
- */ |
- _changePerspectiveAndWait: function(perspectiveTitle, callback) |
- { |
- var perspectiveIndex = null; |
- for (var i = 0; i < this._perspectives.length; ++i) { |
- if (this._perspectives[i].title() === perspectiveTitle) { |
- perspectiveIndex = i; |
- break; |
- } |
- } |
- if (this._currentPerspectiveIndex === perspectiveIndex || perspectiveIndex === null) { |
- setTimeout(callback, 0); |
- return; |
- } |
- |
- /** |
- * @this {WebInspector.HeapSnapshotView} |
- */ |
- function dataGridContentShown(event) |
- { |
- var dataGrid = event.data; |
- dataGrid.removeEventListener(WebInspector.HeapSnapshotSortableDataGrid.Events.ContentShown, dataGridContentShown, this); |
- if (dataGrid === this._dataGrid) |
- callback(); |
- } |
- this._perspectives[perspectiveIndex].masterGrid(this).addEventListener(WebInspector.HeapSnapshotSortableDataGrid.Events.ContentShown, dataGridContentShown, this); |
- |
- this._perspectiveSelect.setSelectedIndex(perspectiveIndex); |
- this._changePerspective(perspectiveIndex); |
- }, |
- |
- _updateDataSourceAndView: function() |
- { |
- var dataGrid = this._dataGrid; |
- if (!dataGrid || dataGrid.snapshot) |
- return; |
- |
- this._profile._loadPromise.then(didLoadSnapshot.bind(this)); |
- |
- /** |
- * @this {WebInspector.HeapSnapshotView} |
- */ |
- function didLoadSnapshot(snapshotProxy) |
- { |
- if (this._dataGrid !== dataGrid) |
- return; |
- if (dataGrid.snapshot !== snapshotProxy) |
- dataGrid.setDataSource(snapshotProxy); |
- if (dataGrid === this._diffDataGrid) { |
- if (!this._baseProfile) |
- this._baseProfile = this._profiles()[this._baseSelect.selectedIndex()]; |
- this._baseProfile._loadPromise.then(didLoadBaseSnapshot.bind(this)); |
- } |
- } |
- |
- /** |
- * @this {WebInspector.HeapSnapshotView} |
- */ |
- function didLoadBaseSnapshot(baseSnapshotProxy) |
- { |
- if (this._diffDataGrid.baseSnapshot !== baseSnapshotProxy) |
- this._diffDataGrid.setBaseDataSource(baseSnapshotProxy); |
- } |
- }, |
- |
- _onSelectedPerspectiveChanged: function(event) |
- { |
- this._changePerspective(event.target.selectedIndex); |
- }, |
- |
- /** |
- * @param {number} selectedIndex |
- */ |
- _changePerspective: function(selectedIndex) |
- { |
- if (selectedIndex === this._currentPerspectiveIndex) |
- return; |
- |
- this._currentPerspectiveIndex = selectedIndex; |
- |
- this._currentPerspective.deactivate(this); |
- var perspective = this._perspectives[selectedIndex]; |
- this._currentPerspective = perspective; |
- this._dataGrid = perspective.masterGrid(this); |
- perspective.activate(this); |
- |
- this.refreshVisibleData(); |
- if (this._dataGrid) |
- this._dataGrid.updateWidths(); |
- |
- this._updateDataSourceAndView(); |
- |
- if (!this.currentQuery || !this._searchResults) |
- return; |
- |
- // The current search needs to be performed again. First negate out previous match |
- // count by calling the search finished callback with a negative number of matches. |
- // Then perform the search again the with same query and callback. |
- this.performSearch(this.currentQuery, false); |
- }, |
- |
- /** |
- * @param {string} perspectiveName |
- * @param {!HeapProfilerAgent.HeapSnapshotObjectId} snapshotObjectId |
- */ |
- selectLiveObject: function(perspectiveName, snapshotObjectId) |
- { |
- this._changePerspectiveAndWait(perspectiveName, didChangePerspective.bind(this)); |
- |
- /** |
- * @this {WebInspector.HeapSnapshotView} |
- */ |
- function didChangePerspective() |
- { |
- this._dataGrid.revealObjectByHeapSnapshotId(snapshotObjectId, didRevealObject); |
- } |
- |
- /** |
- * @param {?WebInspector.HeapSnapshotGridNode} node |
- */ |
- function didRevealObject(node) |
- { |
- if (node) |
- node.select(); |
- else |
- WebInspector.console.error("Cannot find corresponding heap snapshot node"); |
- } |
- }, |
- |
- _getHoverAnchor: function(target) |
- { |
- var span = target.enclosingNodeOrSelfWithNodeName("span"); |
- if (!span) |
- return; |
- var row = target.enclosingNodeOrSelfWithNodeName("tr"); |
- if (!row) |
- return; |
- span.node = row._dataGridNode; |
- return span; |
- }, |
- |
- _resolveObjectForPopover: function(element, showCallback, objectGroupName) |
- { |
- if (!this._profile.target()) |
- return; |
- if (!element.node) |
- return; |
- element.node.queryObjectContent(this._profile.target(), showCallback, objectGroupName); |
- }, |
- |
- _updateBaseOptions: function() |
- { |
- var list = this._profiles(); |
- // We're assuming that snapshots can only be added. |
- if (this._baseSelect.size() === list.length) |
- return; |
- |
- for (var i = this._baseSelect.size(), n = list.length; i < n; ++i) { |
- var title = list[i].title; |
- this._baseSelect.createOption(title); |
- } |
- }, |
- |
- _updateFilterOptions: function() |
- { |
- var list = this._profiles(); |
- // We're assuming that snapshots can only be added. |
- if (this._filterSelect.size() - 1 === list.length) |
- return; |
- |
- if (!this._filterSelect.size()) |
- this._filterSelect.createOption(WebInspector.UIString("All objects")); |
- |
- for (var i = this._filterSelect.size() - 1, n = list.length; i < n; ++i) { |
- var title = list[i].title; |
- if (!i) |
- title = WebInspector.UIString("Objects allocated before %s", title); |
- else |
- title = WebInspector.UIString("Objects allocated between %s and %s", list[i - 1].title, title); |
- this._filterSelect.createOption(title); |
- } |
- }, |
- |
- _updateControls: function() |
- { |
- this._updateBaseOptions(); |
- this._updateFilterOptions(); |
- }, |
- |
- /** |
- * @param {!WebInspector.Event} event |
- */ |
- _onReceiveSnapshot: function(event) |
- { |
- this._updateControls(); |
- }, |
- |
- /** |
- * @param {!WebInspector.Event} event |
- */ |
- _onProfileHeaderRemoved: function(event) |
- { |
- var profile = event.data; |
- if (this._profile === profile) { |
- this.detach(); |
- this._profile.profileType().removeEventListener(WebInspector.HeapSnapshotProfileType.SnapshotReceived, this._onReceiveSnapshot, this); |
- this._profile.profileType().removeEventListener(WebInspector.ProfileType.Events.RemoveProfileHeader, this._onProfileHeaderRemoved, this); |
- this.dispose(); |
- } else { |
- this._updateControls(); |
- } |
- }, |
- |
- dispose: function() |
- { |
- if (this._allocationStackView) { |
- this._allocationStackView.clear(); |
- this._allocationDataGrid.dispose(); |
- } |
- if (this._trackingOverviewGrid) |
- this._trackingOverviewGrid.dispose(); |
- }, |
- |
- __proto__: WebInspector.SimpleView.prototype |
+/** |
+ * @unrestricted |
+ */ |
+WebInspector.HeapSnapshotView.StatisticsPerspective = class extends WebInspector.HeapSnapshotView.Perspective { |
+ constructor() { |
+ super(WebInspector.UIString('Statistics')); |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
+ */ |
+ activate(heapSnapshotView) { |
+ heapSnapshotView._statisticsView.show(heapSnapshotView._searchableView.element); |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView |
+ * @return {?WebInspector.DataGrid} |
+ */ |
+ masterGrid(heapSnapshotView) { |
+ return null; |
+ } |
}; |
/** |
- * @constructor |
- * @extends {WebInspector.ProfileType} |
* @implements {WebInspector.TargetManager.Observer} |
- * @param {string=} id |
- * @param {string=} title |
+ * @unrestricted |
*/ |
-WebInspector.HeapSnapshotProfileType = function(id, title) |
-{ |
- WebInspector.ProfileType.call(this, id || WebInspector.HeapSnapshotProfileType.TypeId, title || WebInspector.UIString("Take Heap Snapshot")); |
+WebInspector.HeapSnapshotProfileType = class extends WebInspector.ProfileType { |
+ /** |
+ * @param {string=} id |
+ * @param {string=} title |
+ */ |
+ constructor(id, title) { |
+ super(id || WebInspector.HeapSnapshotProfileType.TypeId, title || WebInspector.UIString('Take Heap Snapshot')); |
WebInspector.targetManager.observeTargets(this); |
- WebInspector.targetManager.addModelListener(WebInspector.HeapProfilerModel, WebInspector.HeapProfilerModel.Events.ResetProfiles, this._resetProfiles, this); |
- WebInspector.targetManager.addModelListener(WebInspector.HeapProfilerModel, WebInspector.HeapProfilerModel.Events.AddHeapSnapshotChunk, this._addHeapSnapshotChunk, this); |
- WebInspector.targetManager.addModelListener(WebInspector.HeapProfilerModel, WebInspector.HeapProfilerModel.Events.ReportHeapSnapshotProgress, this._reportHeapSnapshotProgress, this); |
-}; |
- |
-WebInspector.HeapSnapshotProfileType.TypeId = "HEAP"; |
-WebInspector.HeapSnapshotProfileType.SnapshotReceived = "SnapshotReceived"; |
- |
-WebInspector.HeapSnapshotProfileType.prototype = { |
- /** |
- * @override |
- * @param {!WebInspector.Target} target |
- */ |
- targetAdded: function(target) |
- { |
- target.heapProfilerModel.enable(); |
- }, |
- |
- /** |
- * @override |
- * @param {!WebInspector.Target} target |
- */ |
- targetRemoved: function(target) |
- { |
- }, |
- |
- /** |
- * @override |
- * @return {string} |
- */ |
- fileExtension: function() |
- { |
- return ".heapsnapshot"; |
- }, |
- |
- get buttonTooltip() |
- { |
- return WebInspector.UIString("Take heap snapshot"); |
- }, |
- |
- /** |
- * @override |
- * @return {boolean} |
- */ |
- isInstantProfile: function() |
- { |
- return true; |
- }, |
- |
- /** |
- * @override |
- * @return {boolean} |
- */ |
- buttonClicked: function() |
- { |
- this._takeHeapSnapshot(function() {}); |
- WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.ProfilesHeapProfileTaken); |
- return false; |
- }, |
- |
- get treeItemTitle() |
- { |
- return WebInspector.UIString("HEAP SNAPSHOTS"); |
- }, |
- |
- get description() |
- { |
- return WebInspector.UIString("Heap snapshot profiles show memory distribution among your page's JavaScript objects and related DOM nodes."); |
- }, |
- |
- /** |
- * @override |
- * @param {string} title |
- * @return {!WebInspector.ProfileHeader} |
- */ |
- createProfileLoadedFromFile: function(title) |
- { |
- return new WebInspector.HeapProfileHeader(null, this, title); |
- }, |
- |
- _takeHeapSnapshot: function(callback) |
- { |
- if (this.profileBeingRecorded()) |
- return; |
- var target = /** @type {!WebInspector.Target} */ (WebInspector.context.flavor(WebInspector.Target)); |
- var profile = new WebInspector.HeapProfileHeader(target, this); |
- this.setProfileBeingRecorded(profile); |
- this.addProfile(profile); |
- profile.updateStatus(WebInspector.UIString("Snapshotting\u2026")); |
- |
- /** |
- * @param {?string} error |
- * @this {WebInspector.HeapSnapshotProfileType} |
- */ |
- function didTakeHeapSnapshot(error) |
- { |
- var profile = this._profileBeingRecorded; |
- profile.title = WebInspector.UIString("Snapshot %d", profile.uid); |
- profile._finishLoad(); |
- this.setProfileBeingRecorded(null); |
- this.dispatchEventToListeners(WebInspector.ProfileType.Events.ProfileComplete, profile); |
- callback(); |
- } |
- target.heapProfilerAgent().takeHeapSnapshot(true, didTakeHeapSnapshot.bind(this)); |
- }, |
- |
- /** |
- * @param {!WebInspector.Event} event |
- */ |
- _addHeapSnapshotChunk: function(event) |
- { |
- if (!this.profileBeingRecorded()) |
- return; |
- var chunk = /** @type {string} */(event.data); |
- this.profileBeingRecorded().transferChunk(chunk); |
- }, |
- |
- /** |
- * @param {!WebInspector.Event} event |
- */ |
- _reportHeapSnapshotProgress: function(event) |
- { |
- var profile = this.profileBeingRecorded(); |
- if (!profile) |
- return; |
- var data = /** @type {{done: number, total: number, finished: boolean}} */ (event.data); |
- profile.updateStatus(WebInspector.UIString("%.0f%%", (data.done / data.total) * 100), true); |
- if (data.finished) |
- profile._prepareToLoad(); |
- }, |
- |
- _resetProfiles: function() |
- { |
- this._reset(); |
- }, |
- |
- _snapshotReceived: function(profile) |
- { |
- if (this._profileBeingRecorded === profile) |
- this.setProfileBeingRecorded(null); |
- this.dispatchEventToListeners(WebInspector.HeapSnapshotProfileType.SnapshotReceived, profile); |
- }, |
- |
- __proto__: WebInspector.ProfileType.prototype |
+ WebInspector.targetManager.addModelListener( |
+ WebInspector.HeapProfilerModel, WebInspector.HeapProfilerModel.Events.ResetProfiles, this._resetProfiles, this); |
+ WebInspector.targetManager.addModelListener( |
+ WebInspector.HeapProfilerModel, WebInspector.HeapProfilerModel.Events.AddHeapSnapshotChunk, |
+ this._addHeapSnapshotChunk, this); |
+ WebInspector.targetManager.addModelListener( |
+ WebInspector.HeapProfilerModel, WebInspector.HeapProfilerModel.Events.ReportHeapSnapshotProgress, |
+ this._reportHeapSnapshotProgress, this); |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {!WebInspector.Target} target |
+ */ |
+ targetAdded(target) { |
+ target.heapProfilerModel.enable(); |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {!WebInspector.Target} target |
+ */ |
+ targetRemoved(target) { |
+ } |
+ |
+ /** |
+ * @override |
+ * @return {string} |
+ */ |
+ fileExtension() { |
+ return '.heapsnapshot'; |
+ } |
+ |
+ get buttonTooltip() { |
+ return WebInspector.UIString('Take heap snapshot'); |
+ } |
+ |
+ /** |
+ * @override |
+ * @return {boolean} |
+ */ |
+ isInstantProfile() { |
+ return true; |
+ } |
+ |
+ /** |
+ * @override |
+ * @return {boolean} |
+ */ |
+ buttonClicked() { |
+ this._takeHeapSnapshot(function() {}); |
+ WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.ProfilesHeapProfileTaken); |
+ return false; |
+ } |
+ |
+ get treeItemTitle() { |
+ return WebInspector.UIString('HEAP SNAPSHOTS'); |
+ } |
+ |
+ get description() { |
+ return WebInspector.UIString( |
+ 'Heap snapshot profiles show memory distribution among your page\'s JavaScript objects and related DOM nodes.'); |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {string} title |
+ * @return {!WebInspector.ProfileHeader} |
+ */ |
+ createProfileLoadedFromFile(title) { |
+ return new WebInspector.HeapProfileHeader(null, this, title); |
+ } |
+ |
+ _takeHeapSnapshot(callback) { |
+ if (this.profileBeingRecorded()) |
+ return; |
+ var target = /** @type {!WebInspector.Target} */ (WebInspector.context.flavor(WebInspector.Target)); |
+ var profile = new WebInspector.HeapProfileHeader(target, this); |
+ this.setProfileBeingRecorded(profile); |
+ this.addProfile(profile); |
+ profile.updateStatus(WebInspector.UIString('Snapshotting\u2026')); |
+ |
+ /** |
+ * @param {?string} error |
+ * @this {WebInspector.HeapSnapshotProfileType} |
+ */ |
+ function didTakeHeapSnapshot(error) { |
+ var profile = this._profileBeingRecorded; |
+ profile.title = WebInspector.UIString('Snapshot %d', profile.uid); |
+ profile._finishLoad(); |
+ this.setProfileBeingRecorded(null); |
+ this.dispatchEventToListeners(WebInspector.ProfileType.Events.ProfileComplete, profile); |
+ callback(); |
+ } |
+ target.heapProfilerAgent().takeHeapSnapshot(true, didTakeHeapSnapshot.bind(this)); |
+ } |
+ |
+ /** |
+ * @param {!WebInspector.Event} event |
+ */ |
+ _addHeapSnapshotChunk(event) { |
+ if (!this.profileBeingRecorded()) |
+ return; |
+ var chunk = /** @type {string} */ (event.data); |
+ this.profileBeingRecorded().transferChunk(chunk); |
+ } |
+ |
+ /** |
+ * @param {!WebInspector.Event} event |
+ */ |
+ _reportHeapSnapshotProgress(event) { |
+ var profile = this.profileBeingRecorded(); |
+ if (!profile) |
+ return; |
+ var data = /** @type {{done: number, total: number, finished: boolean}} */ (event.data); |
+ profile.updateStatus(WebInspector.UIString('%.0f%%', (data.done / data.total) * 100), true); |
+ if (data.finished) |
+ profile._prepareToLoad(); |
+ } |
+ |
+ _resetProfiles() { |
+ this._reset(); |
+ } |
+ |
+ _snapshotReceived(profile) { |
+ if (this._profileBeingRecorded === profile) |
+ this.setProfileBeingRecorded(null); |
+ this.dispatchEventToListeners(WebInspector.HeapSnapshotProfileType.SnapshotReceived, profile); |
+ } |
}; |
+WebInspector.HeapSnapshotProfileType.TypeId = 'HEAP'; |
+WebInspector.HeapSnapshotProfileType.SnapshotReceived = 'SnapshotReceived'; |
/** |
- * @constructor |
- * @extends {WebInspector.HeapSnapshotProfileType} |
+ * @unrestricted |
*/ |
-WebInspector.TrackingHeapSnapshotProfileType = function() |
-{ |
- WebInspector.HeapSnapshotProfileType.call(this, WebInspector.TrackingHeapSnapshotProfileType.TypeId, WebInspector.UIString("Record Allocation Timeline")); |
-}; |
+WebInspector.TrackingHeapSnapshotProfileType = class extends WebInspector.HeapSnapshotProfileType { |
+ constructor() { |
+ super(WebInspector.TrackingHeapSnapshotProfileType.TypeId, WebInspector.UIString('Record Allocation Timeline')); |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {!WebInspector.Target} target |
+ */ |
+ targetAdded(target) { |
+ super.targetAdded(target); |
+ target.heapProfilerModel.addEventListener( |
+ WebInspector.HeapProfilerModel.Events.HeapStatsUpdate, this._heapStatsUpdate, this); |
+ target.heapProfilerModel.addEventListener( |
+ WebInspector.HeapProfilerModel.Events.LastSeenObjectId, this._lastSeenObjectId, this); |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {!WebInspector.Target} target |
+ */ |
+ targetRemoved(target) { |
+ super.targetRemoved(target); |
+ target.heapProfilerModel.removeEventListener( |
+ WebInspector.HeapProfilerModel.Events.HeapStatsUpdate, this._heapStatsUpdate, this); |
+ target.heapProfilerModel.removeEventListener( |
+ WebInspector.HeapProfilerModel.Events.LastSeenObjectId, this._lastSeenObjectId, this); |
+ } |
+ |
+ /** |
+ * @param {!WebInspector.Event} event |
+ */ |
+ _heapStatsUpdate(event) { |
+ if (!this._profileSamples) |
+ return; |
+ var samples = /** @type {!Array.<number>} */ (event.data); |
+ var index; |
+ for (var i = 0; i < samples.length; i += 3) { |
+ index = samples[i]; |
+ var size = samples[i + 2]; |
+ this._profileSamples.sizes[index] = size; |
+ if (!this._profileSamples.max[index]) |
+ this._profileSamples.max[index] = size; |
+ } |
+ } |
+ |
+ /** |
+ * @param {!WebInspector.Event} event |
+ */ |
+ _lastSeenObjectId(event) { |
+ var profileSamples = this._profileSamples; |
+ if (!profileSamples) |
+ return; |
+ var data = /** @type {{lastSeenObjectId: number, timestamp: number}} */ (event.data); |
+ var currentIndex = Math.max(profileSamples.ids.length, profileSamples.max.length - 1); |
+ profileSamples.ids[currentIndex] = data.lastSeenObjectId; |
+ if (!profileSamples.max[currentIndex]) { |
+ profileSamples.max[currentIndex] = 0; |
+ profileSamples.sizes[currentIndex] = 0; |
+ } |
+ profileSamples.timestamps[currentIndex] = data.timestamp; |
+ if (profileSamples.totalTime < data.timestamp - profileSamples.timestamps[0]) |
+ profileSamples.totalTime *= 2; |
+ this.dispatchEventToListeners(WebInspector.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._profileSamples); |
+ this._profileBeingRecorded.updateStatus(null, true); |
+ } |
+ |
+ /** |
+ * @override |
+ * @return {boolean} |
+ */ |
+ hasTemporaryView() { |
+ return true; |
+ } |
+ |
+ get buttonTooltip() { |
+ return this._recording ? WebInspector.UIString('Stop recording heap profile') : |
+ WebInspector.UIString('Start recording heap profile'); |
+ } |
+ |
+ /** |
+ * @override |
+ * @return {boolean} |
+ */ |
+ isInstantProfile() { |
+ return false; |
+ } |
+ |
+ /** |
+ * @override |
+ * @return {boolean} |
+ */ |
+ buttonClicked() { |
+ return this._toggleRecording(); |
+ } |
+ |
+ _startRecordingProfile() { |
+ if (this.profileBeingRecorded()) |
+ return; |
+ this._addNewProfile(); |
+ var recordAllocationStacks = WebInspector.moduleSetting('recordAllocationStacks').get(); |
+ this.profileBeingRecorded().target().heapProfilerAgent().startTrackingHeapObjects(recordAllocationStacks); |
+ } |
+ |
+ _addNewProfile() { |
+ var target = WebInspector.context.flavor(WebInspector.Target); |
+ this.setProfileBeingRecorded(new WebInspector.HeapProfileHeader(target, this, undefined)); |
+ this._profileSamples = new WebInspector.TrackingHeapSnapshotProfileType.Samples(); |
+ this._profileBeingRecorded._profileSamples = this._profileSamples; |
+ this._recording = true; |
+ this.addProfile(this._profileBeingRecorded); |
+ this._profileBeingRecorded.updateStatus(WebInspector.UIString('Recording\u2026')); |
+ this.dispatchEventToListeners(WebInspector.TrackingHeapSnapshotProfileType.TrackingStarted); |
+ } |
+ |
+ _stopRecordingProfile() { |
+ this._profileBeingRecorded.updateStatus(WebInspector.UIString('Snapshotting\u2026')); |
+ /** |
+ * @param {?string} error |
+ * @this {WebInspector.HeapSnapshotProfileType} |
+ */ |
+ function didTakeHeapSnapshot(error) { |
+ var profile = this.profileBeingRecorded(); |
+ if (!profile) |
+ return; |
+ profile._finishLoad(); |
+ this._profileSamples = null; |
+ this.setProfileBeingRecorded(null); |
+ this.dispatchEventToListeners(WebInspector.ProfileType.Events.ProfileComplete, profile); |
+ } |
-WebInspector.TrackingHeapSnapshotProfileType.TypeId = "HEAP-RECORD"; |
+ this._profileBeingRecorded.target().heapProfilerAgent().stopTrackingHeapObjects( |
+ true, didTakeHeapSnapshot.bind(this)); |
+ this._recording = false; |
+ this.dispatchEventToListeners(WebInspector.TrackingHeapSnapshotProfileType.TrackingStopped); |
+ } |
+ |
+ _toggleRecording() { |
+ if (this._recording) |
+ this._stopRecordingProfile(); |
+ else |
+ this._startRecordingProfile(); |
+ return this._recording; |
+ } |
+ |
+ /** |
+ * @override |
+ * @return {string} |
+ */ |
+ fileExtension() { |
+ return '.heaptimeline'; |
+ } |
+ |
+ get treeItemTitle() { |
+ return WebInspector.UIString('ALLOCATION TIMELINES'); |
+ } |
+ |
+ get description() { |
+ return WebInspector.UIString( |
+ 'Allocation timelines show memory allocations from your heap over time. Use this profile type to isolate memory leaks.'); |
+ } |
+ |
+ /** |
+ * @override |
+ */ |
+ _resetProfiles() { |
+ var wasRecording = this._recording; |
+ // Clear current profile to avoid stopping backend. |
+ this.setProfileBeingRecorded(null); |
+ super._resetProfiles(); |
+ this._profileSamples = null; |
+ if (wasRecording) |
+ this._addNewProfile(); |
+ } |
+ |
+ /** |
+ * @override |
+ */ |
+ profileBeingRecordedRemoved() { |
+ this._stopRecordingProfile(); |
+ this._profileSamples = null; |
+ } |
+}; |
-WebInspector.TrackingHeapSnapshotProfileType.HeapStatsUpdate = "HeapStatsUpdate"; |
-WebInspector.TrackingHeapSnapshotProfileType.TrackingStarted = "TrackingStarted"; |
-WebInspector.TrackingHeapSnapshotProfileType.TrackingStopped = "TrackingStopped"; |
+WebInspector.TrackingHeapSnapshotProfileType.TypeId = 'HEAP-RECORD'; |
+WebInspector.TrackingHeapSnapshotProfileType.HeapStatsUpdate = 'HeapStatsUpdate'; |
+WebInspector.TrackingHeapSnapshotProfileType.TrackingStarted = 'TrackingStarted'; |
+WebInspector.TrackingHeapSnapshotProfileType.TrackingStopped = 'TrackingStopped'; |
/** |
- * @constructor |
+ * @unrestricted |
*/ |
-WebInspector.TrackingHeapSnapshotProfileType.Samples = function() |
-{ |
+WebInspector.TrackingHeapSnapshotProfileType.Samples = class { |
+ constructor() { |
/** @type {!Array.<number>} */ |
this.sizes = []; |
/** @type {!Array.<number>} */ |
@@ -1201,212 +1297,20 @@ WebInspector.TrackingHeapSnapshotProfileType.Samples = function() |
this.max = []; |
/** @type {number} */ |
this.totalTime = 30000; |
-}; |
- |
-WebInspector.TrackingHeapSnapshotProfileType.prototype = { |
- |
- /** |
- * @override |
- * @param {!WebInspector.Target} target |
- */ |
- targetAdded: function(target) |
- { |
- WebInspector.HeapSnapshotProfileType.prototype.targetAdded.call(this, target); |
- target.heapProfilerModel.addEventListener(WebInspector.HeapProfilerModel.Events.HeapStatsUpdate, this._heapStatsUpdate, this); |
- target.heapProfilerModel.addEventListener(WebInspector.HeapProfilerModel.Events.LastSeenObjectId, this._lastSeenObjectId, this); |
- }, |
- |
- /** |
- * @override |
- * @param {!WebInspector.Target} target |
- */ |
- targetRemoved: function(target) |
- { |
- WebInspector.HeapSnapshotProfileType.prototype.targetRemoved.call(this, target); |
- target.heapProfilerModel.removeEventListener(WebInspector.HeapProfilerModel.Events.HeapStatsUpdate, this._heapStatsUpdate, this); |
- target.heapProfilerModel.removeEventListener(WebInspector.HeapProfilerModel.Events.LastSeenObjectId, this._lastSeenObjectId, this); |
- }, |
- |
- /** |
- * @param {!WebInspector.Event} event |
- */ |
- _heapStatsUpdate: function(event) |
- { |
- if (!this._profileSamples) |
- return; |
- var samples = /** @type {!Array.<number>} */ (event.data); |
- var index; |
- for (var i = 0; i < samples.length; i += 3) { |
- index = samples[i]; |
- var size = samples[i + 2]; |
- this._profileSamples.sizes[index] = size; |
- if (!this._profileSamples.max[index]) |
- this._profileSamples.max[index] = size; |
- } |
- }, |
- |
- /** |
- * @param {!WebInspector.Event} event |
- */ |
- _lastSeenObjectId: function(event) |
- { |
- var profileSamples = this._profileSamples; |
- if (!profileSamples) |
- return; |
- var data = /** @type {{lastSeenObjectId: number, timestamp: number}} */ (event.data); |
- var currentIndex = Math.max(profileSamples.ids.length, profileSamples.max.length - 1); |
- profileSamples.ids[currentIndex] = data.lastSeenObjectId; |
- if (!profileSamples.max[currentIndex]) { |
- profileSamples.max[currentIndex] = 0; |
- profileSamples.sizes[currentIndex] = 0; |
- } |
- profileSamples.timestamps[currentIndex] = data.timestamp; |
- if (profileSamples.totalTime < data.timestamp - profileSamples.timestamps[0]) |
- profileSamples.totalTime *= 2; |
- this.dispatchEventToListeners(WebInspector.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._profileSamples); |
- this._profileBeingRecorded.updateStatus(null, true); |
- }, |
- |
- /** |
- * @override |
- * @return {boolean} |
- */ |
- hasTemporaryView: function() |
- { |
- return true; |
- }, |
- |
- get buttonTooltip() |
- { |
- return this._recording ? WebInspector.UIString("Stop recording heap profile") : WebInspector.UIString("Start recording heap profile"); |
- }, |
- |
- /** |
- * @override |
- * @return {boolean} |
- */ |
- isInstantProfile: function() |
- { |
- return false; |
- }, |
- |
- /** |
- * @override |
- * @return {boolean} |
- */ |
- buttonClicked: function() |
- { |
- return this._toggleRecording(); |
- }, |
- |
- _startRecordingProfile: function() |
- { |
- if (this.profileBeingRecorded()) |
- return; |
- this._addNewProfile(); |
- var recordAllocationStacks = WebInspector.moduleSetting("recordAllocationStacks").get(); |
- this.profileBeingRecorded().target().heapProfilerAgent().startTrackingHeapObjects(recordAllocationStacks); |
- }, |
- |
- _addNewProfile: function() |
- { |
- var target = WebInspector.context.flavor(WebInspector.Target); |
- this.setProfileBeingRecorded(new WebInspector.HeapProfileHeader(target, this, undefined)); |
- this._profileSamples = new WebInspector.TrackingHeapSnapshotProfileType.Samples(); |
- this._profileBeingRecorded._profileSamples = this._profileSamples; |
- this._recording = true; |
- this.addProfile(this._profileBeingRecorded); |
- this._profileBeingRecorded.updateStatus(WebInspector.UIString("Recording\u2026")); |
- this.dispatchEventToListeners(WebInspector.TrackingHeapSnapshotProfileType.TrackingStarted); |
- }, |
- |
- _stopRecordingProfile: function() |
- { |
- this._profileBeingRecorded.updateStatus(WebInspector.UIString("Snapshotting\u2026")); |
- /** |
- * @param {?string} error |
- * @this {WebInspector.HeapSnapshotProfileType} |
- */ |
- function didTakeHeapSnapshot(error) |
- { |
- var profile = this.profileBeingRecorded(); |
- if (!profile) |
- return; |
- profile._finishLoad(); |
- this._profileSamples = null; |
- this.setProfileBeingRecorded(null); |
- this.dispatchEventToListeners(WebInspector.ProfileType.Events.ProfileComplete, profile); |
- } |
- |
- this._profileBeingRecorded.target().heapProfilerAgent().stopTrackingHeapObjects(true, didTakeHeapSnapshot.bind(this)); |
- this._recording = false; |
- this.dispatchEventToListeners(WebInspector.TrackingHeapSnapshotProfileType.TrackingStopped); |
- }, |
- |
- _toggleRecording: function() |
- { |
- if (this._recording) |
- this._stopRecordingProfile(); |
- else |
- this._startRecordingProfile(); |
- return this._recording; |
- }, |
- |
- /** |
- * @override |
- * @return {string} |
- */ |
- fileExtension: function() |
- { |
- return ".heaptimeline"; |
- }, |
- |
- get treeItemTitle() |
- { |
- return WebInspector.UIString("ALLOCATION TIMELINES"); |
- }, |
- |
- get description() |
- { |
- return WebInspector.UIString("Allocation timelines show memory allocations from your heap over time. Use this profile type to isolate memory leaks."); |
- }, |
- |
- /** |
- * @override |
- */ |
- _resetProfiles: function() |
- { |
- var wasRecording = this._recording; |
- // Clear current profile to avoid stopping backend. |
- this.setProfileBeingRecorded(null); |
- WebInspector.HeapSnapshotProfileType.prototype._resetProfiles.call(this); |
- this._profileSamples = null; |
- if (wasRecording) |
- this._addNewProfile(); |
- }, |
- |
- /** |
- * @override |
- */ |
- profileBeingRecordedRemoved: function() |
- { |
- this._stopRecordingProfile(); |
- this._profileSamples = null; |
- }, |
- |
- __proto__: WebInspector.HeapSnapshotProfileType.prototype |
+ } |
}; |
/** |
- * @constructor |
- * @extends {WebInspector.ProfileHeader} |
- * @param {?WebInspector.Target} target |
- * @param {!WebInspector.HeapSnapshotProfileType} type |
- * @param {string=} title |
+ * @unrestricted |
*/ |
-WebInspector.HeapProfileHeader = function(target, type, title) |
-{ |
- WebInspector.ProfileHeader.call(this, target, type, title || WebInspector.UIString("Snapshot %d", type.nextProfileUid())); |
+WebInspector.HeapProfileHeader = class extends WebInspector.ProfileHeader { |
+ /** |
+ * @param {?WebInspector.Target} target |
+ * @param {!WebInspector.HeapSnapshotProfileType} type |
+ * @param {string=} title |
+ */ |
+ constructor(target, type, title) { |
+ super(target, type, title || WebInspector.UIString('Snapshot %d', type.nextProfileUid())); |
this.maxJSObjectId = -1; |
/** |
* @type {?WebInspector.HeapSnapshotWorkerProxy} |
@@ -1431,827 +1335,764 @@ WebInspector.HeapProfileHeader = function(target, type, title) |
* @param {function(!WebInspector.HeapSnapshotProxy)} fulfill |
* @this {WebInspector.HeapProfileHeader} |
*/ |
- function loadResolver(fulfill) |
- { |
- this._fulfillLoad = fulfill; |
+ function loadResolver(fulfill) { |
+ this._fulfillLoad = fulfill; |
} |
-}; |
- |
-WebInspector.HeapProfileHeader.prototype = { |
- /** |
- * @override |
- * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate |
- * @return {!WebInspector.ProfileSidebarTreeElement} |
- */ |
- createSidebarTreeElement: function(dataDisplayDelegate) |
- { |
- return new WebInspector.ProfileSidebarTreeElement(dataDisplayDelegate, this, "heap-snapshot-sidebar-tree-item"); |
- }, |
- |
- /** |
- * @override |
- * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate |
- * @return {!WebInspector.HeapSnapshotView} |
- */ |
- createView: function(dataDisplayDelegate) |
- { |
- return new WebInspector.HeapSnapshotView(dataDisplayDelegate, this); |
- }, |
- |
- _prepareToLoad: function() |
- { |
- console.assert(!this._receiver, "Already loading"); |
- this._setupWorker(); |
- this.updateStatus(WebInspector.UIString("Loading\u2026"), true); |
- }, |
- |
- _finishLoad: function() |
- { |
- if (!this._wasDisposed) |
- this._receiver.close(); |
- if (this._bufferedWriter) { |
- this._bufferedWriter.finishWriting(this._didWriteToTempFile.bind(this)); |
- this._bufferedWriter = null; |
- } |
- }, |
- |
- _didWriteToTempFile: function(tempFile) |
- { |
- if (this._wasDisposed) { |
- if (tempFile) |
- tempFile.remove(); |
- return; |
- } |
- this._tempFile = tempFile; |
- if (!tempFile) |
- this._failedToCreateTempFile = true; |
- if (this._onTempFileReady) { |
- this._onTempFileReady(); |
- this._onTempFileReady = null; |
- } |
- }, |
- |
- _setupWorker: function() |
- { |
- /** |
- * @this {WebInspector.HeapProfileHeader} |
- */ |
- function setProfileWait(event) |
- { |
- this.updateStatus(null, event.data); |
- } |
- console.assert(!this._workerProxy, "HeapSnapshotWorkerProxy already exists"); |
- this._workerProxy = new WebInspector.HeapSnapshotWorkerProxy(this._handleWorkerEvent.bind(this)); |
- this._workerProxy.addEventListener("wait", setProfileWait, this); |
- this._receiver = this._workerProxy.createLoader(this.uid, this._snapshotReceived.bind(this)); |
- }, |
- |
- /** |
- * @param {string} eventName |
- * @param {*} data |
- */ |
- _handleWorkerEvent: function(eventName, data) |
- { |
- if (WebInspector.HeapSnapshotProgressEvent.BrokenSnapshot === eventName) { |
- var error = /** @type {string} */ (data); |
- WebInspector.console.error(error); |
- return; |
- } |
- |
- if (WebInspector.HeapSnapshotProgressEvent.Update !== eventName) |
- return; |
- var subtitle = /** @type {string} */ (data); |
- this.updateStatus(subtitle); |
- }, |
- |
- /** |
- * @override |
- */ |
- dispose: function() |
- { |
- if (this._workerProxy) |
- this._workerProxy.dispose(); |
- this.removeTempFile(); |
- this._wasDisposed = true; |
- }, |
- |
- _didCompleteSnapshotTransfer: function() |
- { |
- if (!this._snapshotProxy) |
- return; |
- this.updateStatus(Number.bytesToString(this._snapshotProxy.totalSize), false); |
- }, |
- |
- /** |
- * @param {string} chunk |
- */ |
- transferChunk: function(chunk) |
- { |
- if (!this._bufferedWriter) |
- this._bufferedWriter = new WebInspector.DeferredTempFile("heap-profiler", String(this.uid)); |
- this._bufferedWriter.write([chunk]); |
- |
- ++this._totalNumberOfChunks; |
- this._receiver.write(chunk); |
- }, |
- |
- _snapshotReceived: function(snapshotProxy) |
- { |
- if (this._wasDisposed) |
- return; |
- this._receiver = null; |
- this._snapshotProxy = snapshotProxy; |
- this.maxJSObjectId = snapshotProxy.maxJSObjectId(); |
- this._didCompleteSnapshotTransfer(); |
- this._workerProxy.startCheckingForLongRunningCalls(); |
- this.notifySnapshotReceived(); |
- }, |
- |
- notifySnapshotReceived: function() |
- { |
- this._fulfillLoad(this._snapshotProxy); |
- this._profileType._snapshotReceived(this); |
- if (this.canSaveToFile()) |
- this.dispatchEventToListeners(WebInspector.ProfileHeader.Events.ProfileReceived); |
- }, |
- |
- // Hook point for tests. |
- _wasShown: function() |
- { |
- }, |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate |
+ * @return {!WebInspector.ProfileSidebarTreeElement} |
+ */ |
+ createSidebarTreeElement(dataDisplayDelegate) { |
+ return new WebInspector.ProfileSidebarTreeElement(dataDisplayDelegate, this, 'heap-snapshot-sidebar-tree-item'); |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate |
+ * @return {!WebInspector.HeapSnapshotView} |
+ */ |
+ createView(dataDisplayDelegate) { |
+ return new WebInspector.HeapSnapshotView(dataDisplayDelegate, this); |
+ } |
+ |
+ _prepareToLoad() { |
+ console.assert(!this._receiver, 'Already loading'); |
+ this._setupWorker(); |
+ this.updateStatus(WebInspector.UIString('Loading\u2026'), true); |
+ } |
+ |
+ _finishLoad() { |
+ if (!this._wasDisposed) |
+ this._receiver.close(); |
+ if (this._bufferedWriter) { |
+ this._bufferedWriter.finishWriting(this._didWriteToTempFile.bind(this)); |
+ this._bufferedWriter = null; |
+ } |
+ } |
- /** |
- * @override |
- * @return {boolean} |
- */ |
- canSaveToFile: function() |
- { |
- return !this.fromFile() && !!this._snapshotProxy; |
- }, |
+ _didWriteToTempFile(tempFile) { |
+ if (this._wasDisposed) { |
+ if (tempFile) |
+ tempFile.remove(); |
+ return; |
+ } |
+ this._tempFile = tempFile; |
+ if (!tempFile) |
+ this._failedToCreateTempFile = true; |
+ if (this._onTempFileReady) { |
+ this._onTempFileReady(); |
+ this._onTempFileReady = null; |
+ } |
+ } |
+ _setupWorker() { |
/** |
- * @override |
+ * @this {WebInspector.HeapProfileHeader} |
*/ |
- saveToFile: function() |
- { |
- var fileOutputStream = new WebInspector.FileOutputStream(); |
- |
- /** |
- * @param {boolean} accepted |
- * @this {WebInspector.HeapProfileHeader} |
- */ |
- function onOpen(accepted) |
- { |
- if (!accepted) |
- return; |
- if (this._failedToCreateTempFile) { |
- WebInspector.console.error("Failed to open temp file with heap snapshot"); |
- fileOutputStream.close(); |
- } else if (this._tempFile) { |
- var delegate = new WebInspector.SaveSnapshotOutputStreamDelegate(this); |
- this._tempFile.copyToOutputStream(fileOutputStream, delegate); |
- } else { |
- this._onTempFileReady = onOpen.bind(this, accepted); |
- this._updateSaveProgress(0, 1); |
- } |
- } |
- this._fileName = this._fileName || "Heap-" + new Date().toISO8601Compact() + this._profileType.fileExtension(); |
- fileOutputStream.open(this._fileName, onOpen.bind(this)); |
- }, |
- |
- _updateSaveProgress: function(value, total) |
- { |
- var percentValue = ((total ? (value / total) : 0) * 100).toFixed(0); |
- this.updateStatus(WebInspector.UIString("Saving\u2026 %d%%", percentValue)); |
- }, |
+ function setProfileWait(event) { |
+ this.updateStatus(null, event.data); |
+ } |
+ console.assert(!this._workerProxy, 'HeapSnapshotWorkerProxy already exists'); |
+ this._workerProxy = new WebInspector.HeapSnapshotWorkerProxy(this._handleWorkerEvent.bind(this)); |
+ this._workerProxy.addEventListener('wait', setProfileWait, this); |
+ this._receiver = this._workerProxy.createLoader(this.uid, this._snapshotReceived.bind(this)); |
+ } |
+ |
+ /** |
+ * @param {string} eventName |
+ * @param {*} data |
+ */ |
+ _handleWorkerEvent(eventName, data) { |
+ if (WebInspector.HeapSnapshotProgressEvent.BrokenSnapshot === eventName) { |
+ var error = /** @type {string} */ (data); |
+ WebInspector.console.error(error); |
+ return; |
+ } |
- /** |
- * @override |
- * @param {!File} file |
+ if (WebInspector.HeapSnapshotProgressEvent.Update !== eventName) |
+ return; |
+ var subtitle = /** @type {string} */ (data); |
+ this.updateStatus(subtitle); |
+ } |
+ |
+ /** |
+ * @override |
+ */ |
+ dispose() { |
+ if (this._workerProxy) |
+ this._workerProxy.dispose(); |
+ this.removeTempFile(); |
+ this._wasDisposed = true; |
+ } |
+ |
+ _didCompleteSnapshotTransfer() { |
+ if (!this._snapshotProxy) |
+ return; |
+ this.updateStatus(Number.bytesToString(this._snapshotProxy.totalSize), false); |
+ } |
+ |
+ /** |
+ * @param {string} chunk |
+ */ |
+ transferChunk(chunk) { |
+ if (!this._bufferedWriter) |
+ this._bufferedWriter = new WebInspector.DeferredTempFile('heap-profiler', String(this.uid)); |
+ this._bufferedWriter.write([chunk]); |
+ |
+ ++this._totalNumberOfChunks; |
+ this._receiver.write(chunk); |
+ } |
+ |
+ _snapshotReceived(snapshotProxy) { |
+ if (this._wasDisposed) |
+ return; |
+ this._receiver = null; |
+ this._snapshotProxy = snapshotProxy; |
+ this.maxJSObjectId = snapshotProxy.maxJSObjectId(); |
+ this._didCompleteSnapshotTransfer(); |
+ this._workerProxy.startCheckingForLongRunningCalls(); |
+ this.notifySnapshotReceived(); |
+ } |
+ |
+ notifySnapshotReceived() { |
+ this._fulfillLoad(this._snapshotProxy); |
+ this._profileType._snapshotReceived(this); |
+ if (this.canSaveToFile()) |
+ this.dispatchEventToListeners(WebInspector.ProfileHeader.Events.ProfileReceived); |
+ } |
+ |
+ // Hook point for tests. |
+ _wasShown() { |
+ } |
+ |
+ /** |
+ * @override |
+ * @return {boolean} |
+ */ |
+ canSaveToFile() { |
+ return !this.fromFile() && !!this._snapshotProxy; |
+ } |
+ |
+ /** |
+ * @override |
+ */ |
+ saveToFile() { |
+ var fileOutputStream = new WebInspector.FileOutputStream(); |
+ |
+ /** |
+ * @param {boolean} accepted |
+ * @this {WebInspector.HeapProfileHeader} |
*/ |
- loadFromFile: function(file) |
- { |
- this.updateStatus(WebInspector.UIString("Loading\u2026"), true); |
- this._setupWorker(); |
- var delegate = new WebInspector.HeapSnapshotLoadFromFileDelegate(this); |
- var fileReader = this._createFileReader(file, delegate); |
- fileReader.start(this._receiver); |
- }, |
- |
- _createFileReader: function(file, delegate) |
- { |
- return new WebInspector.ChunkedFileReader(file, 10000000, delegate); |
- }, |
- |
- __proto__: WebInspector.ProfileHeader.prototype |
+ function onOpen(accepted) { |
+ if (!accepted) |
+ return; |
+ if (this._failedToCreateTempFile) { |
+ WebInspector.console.error('Failed to open temp file with heap snapshot'); |
+ fileOutputStream.close(); |
+ } else if (this._tempFile) { |
+ var delegate = new WebInspector.SaveSnapshotOutputStreamDelegate(this); |
+ this._tempFile.copyToOutputStream(fileOutputStream, delegate); |
+ } else { |
+ this._onTempFileReady = onOpen.bind(this, accepted); |
+ this._updateSaveProgress(0, 1); |
+ } |
+ } |
+ this._fileName = this._fileName || 'Heap-' + new Date().toISO8601Compact() + this._profileType.fileExtension(); |
+ fileOutputStream.open(this._fileName, onOpen.bind(this)); |
+ } |
+ |
+ _updateSaveProgress(value, total) { |
+ var percentValue = ((total ? (value / total) : 0) * 100).toFixed(0); |
+ this.updateStatus(WebInspector.UIString('Saving\u2026 %d%%', percentValue)); |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {!File} file |
+ */ |
+ loadFromFile(file) { |
+ this.updateStatus(WebInspector.UIString('Loading\u2026'), true); |
+ this._setupWorker(); |
+ var delegate = new WebInspector.HeapSnapshotLoadFromFileDelegate(this); |
+ var fileReader = this._createFileReader(file, delegate); |
+ fileReader.start(this._receiver); |
+ } |
+ |
+ _createFileReader(file, delegate) { |
+ return new WebInspector.ChunkedFileReader(file, 10000000, delegate); |
+ } |
}; |
/** |
- * @constructor |
* @implements {WebInspector.OutputStreamDelegate} |
+ * @unrestricted |
*/ |
-WebInspector.HeapSnapshotLoadFromFileDelegate = function(snapshotHeader) |
-{ |
+WebInspector.HeapSnapshotLoadFromFileDelegate = class { |
+ constructor(snapshotHeader) { |
this._snapshotHeader = snapshotHeader; |
-}; |
- |
-WebInspector.HeapSnapshotLoadFromFileDelegate.prototype = { |
- /** |
- * @override |
- */ |
- onTransferStarted: function() |
- { |
- }, |
- |
- /** |
- * @override |
- * @param {!WebInspector.ChunkedReader} reader |
- */ |
- onChunkTransferred: function(reader) |
- { |
- }, |
- |
- /** |
- * @override |
- */ |
- onTransferFinished: function() |
- { |
- }, |
- |
- /** |
- * @override |
- * @param {!WebInspector.ChunkedReader} reader |
- * @param {!Event} e |
- */ |
- onError: function(reader, e) |
- { |
- var subtitle; |
- switch (e.target.error.code) { |
- case e.target.error.NOT_FOUND_ERR: |
- subtitle = WebInspector.UIString("'%s' not found.", reader.fileName()); |
- break; |
- case e.target.error.NOT_READABLE_ERR: |
- subtitle = WebInspector.UIString("'%s' is not readable", reader.fileName()); |
- break; |
- case e.target.error.ABORT_ERR: |
- return; |
- default: |
- subtitle = WebInspector.UIString("'%s' error %d", reader.fileName(), e.target.error.code); |
- } |
- this._snapshotHeader.updateStatus(subtitle); |
+ } |
+ |
+ /** |
+ * @override |
+ */ |
+ onTransferStarted() { |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {!WebInspector.ChunkedReader} reader |
+ */ |
+ onChunkTransferred(reader) { |
+ } |
+ |
+ /** |
+ * @override |
+ */ |
+ onTransferFinished() { |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {!WebInspector.ChunkedReader} reader |
+ * @param {!Event} e |
+ */ |
+ onError(reader, e) { |
+ var subtitle; |
+ switch (e.target.error.code) { |
+ case e.target.error.NOT_FOUND_ERR: |
+ subtitle = WebInspector.UIString('\'%s\' not found.', reader.fileName()); |
+ break; |
+ case e.target.error.NOT_READABLE_ERR: |
+ subtitle = WebInspector.UIString('\'%s\' is not readable', reader.fileName()); |
+ break; |
+ case e.target.error.ABORT_ERR: |
+ return; |
+ default: |
+ subtitle = WebInspector.UIString('\'%s\' error %d', reader.fileName(), e.target.error.code); |
} |
+ this._snapshotHeader.updateStatus(subtitle); |
+ } |
}; |
/** |
- * @constructor |
* @implements {WebInspector.OutputStreamDelegate} |
- * @param {!WebInspector.HeapProfileHeader} profileHeader |
+ * @unrestricted |
*/ |
-WebInspector.SaveSnapshotOutputStreamDelegate = function(profileHeader) |
-{ |
+WebInspector.SaveSnapshotOutputStreamDelegate = class { |
+ /** |
+ * @param {!WebInspector.HeapProfileHeader} profileHeader |
+ */ |
+ constructor(profileHeader) { |
this._profileHeader = profileHeader; |
-}; |
- |
-WebInspector.SaveSnapshotOutputStreamDelegate.prototype = { |
- /** |
- * @override |
- */ |
- onTransferStarted: function() |
- { |
- this._profileHeader._updateSaveProgress(0, 1); |
- }, |
- |
- /** |
- * @override |
- */ |
- onTransferFinished: function() |
- { |
- this._profileHeader._didCompleteSnapshotTransfer(); |
- }, |
- |
- /** |
- * @override |
- * @param {!WebInspector.ChunkedReader} reader |
- */ |
- onChunkTransferred: function(reader) |
- { |
- this._profileHeader._updateSaveProgress(reader.loadedSize(), reader.fileSize()); |
- }, |
- |
- /** |
- * @override |
- * @param {!WebInspector.ChunkedReader} reader |
- * @param {!Event} event |
- */ |
- onError: function(reader, event) |
- { |
- WebInspector.console.error("Failed to read heap snapshot from temp file: " + /** @type {!ErrorEvent} */ (event).message); |
- this.onTransferFinished(); |
- } |
+ } |
+ |
+ /** |
+ * @override |
+ */ |
+ onTransferStarted() { |
+ this._profileHeader._updateSaveProgress(0, 1); |
+ } |
+ |
+ /** |
+ * @override |
+ */ |
+ onTransferFinished() { |
+ this._profileHeader._didCompleteSnapshotTransfer(); |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {!WebInspector.ChunkedReader} reader |
+ */ |
+ onChunkTransferred(reader) { |
+ this._profileHeader._updateSaveProgress(reader.loadedSize(), reader.fileSize()); |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {!WebInspector.ChunkedReader} reader |
+ * @param {!Event} event |
+ */ |
+ onError(reader, event) { |
+ WebInspector.console.error( |
+ 'Failed to read heap snapshot from temp file: ' + /** @type {!ErrorEvent} */ (event).message); |
+ this.onTransferFinished(); |
+ } |
}; |
/** |
- * @constructor |
- * @extends {WebInspector.VBox} |
- * @param {!WebInspector.HeapProfileHeader} heapProfileHeader |
+ * @unrestricted |
*/ |
-WebInspector.HeapTrackingOverviewGrid = function(heapProfileHeader) |
-{ |
- WebInspector.VBox.call(this); |
- this.element.id = "heap-recording-view"; |
- this.element.classList.add("heap-tracking-overview"); |
- |
- this._overviewContainer = this.element.createChild("div", "heap-overview-container"); |
- this._overviewGrid = new WebInspector.OverviewGrid("heap-recording"); |
- this._overviewGrid.element.classList.add("fill"); |
- |
- this._overviewCanvas = this._overviewContainer.createChild("canvas", "heap-recording-overview-canvas"); |
+WebInspector.HeapTrackingOverviewGrid = class extends WebInspector.VBox { |
+ /** |
+ * @param {!WebInspector.HeapProfileHeader} heapProfileHeader |
+ */ |
+ constructor(heapProfileHeader) { |
+ super(); |
+ this.element.id = 'heap-recording-view'; |
+ this.element.classList.add('heap-tracking-overview'); |
+ |
+ this._overviewContainer = this.element.createChild('div', 'heap-overview-container'); |
+ this._overviewGrid = new WebInspector.OverviewGrid('heap-recording'); |
+ this._overviewGrid.element.classList.add('fill'); |
+ |
+ this._overviewCanvas = this._overviewContainer.createChild('canvas', 'heap-recording-overview-canvas'); |
this._overviewContainer.appendChild(this._overviewGrid.element); |
this._overviewCalculator = new WebInspector.HeapTrackingOverviewGrid.OverviewCalculator(); |
this._overviewGrid.addEventListener(WebInspector.OverviewGrid.Events.WindowChanged, this._onWindowChanged, this); |
- this._profileSamples = heapProfileHeader.fromFile() ? new WebInspector.TrackingHeapSnapshotProfileType.Samples() : heapProfileHeader._profileSamples; |
+ this._profileSamples = heapProfileHeader.fromFile() ? new WebInspector.TrackingHeapSnapshotProfileType.Samples() : |
+ heapProfileHeader._profileSamples; |
this._profileType = heapProfileHeader.profileType(); |
if (!heapProfileHeader.fromFile() && heapProfileHeader.profileType().profileBeingRecorded() === heapProfileHeader) { |
- this._profileType.addEventListener(WebInspector.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._onHeapStatsUpdate, this); |
- this._profileType.addEventListener(WebInspector.TrackingHeapSnapshotProfileType.TrackingStopped, this._onStopTracking, this); |
+ this._profileType.addEventListener( |
+ WebInspector.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._onHeapStatsUpdate, this); |
+ this._profileType.addEventListener( |
+ WebInspector.TrackingHeapSnapshotProfileType.TrackingStopped, this._onStopTracking, this); |
} |
this._windowLeft = 0.0; |
this._windowRight = 1.0; |
this._overviewGrid.setWindow(this._windowLeft, this._windowRight); |
this._yScale = new WebInspector.HeapTrackingOverviewGrid.SmoothScale(); |
this._xScale = new WebInspector.HeapTrackingOverviewGrid.SmoothScale(); |
-}; |
- |
-WebInspector.HeapTrackingOverviewGrid.IdsRangeChanged = "IdsRangeChanged"; |
- |
-WebInspector.HeapTrackingOverviewGrid.prototype = { |
- dispose: function() |
- { |
- this._onStopTracking(); |
- }, |
- |
- _onStopTracking: function() |
- { |
- this._profileType.removeEventListener(WebInspector.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._onHeapStatsUpdate, this); |
- this._profileType.removeEventListener(WebInspector.TrackingHeapSnapshotProfileType.TrackingStopped, this._onStopTracking, this); |
- }, |
- |
- _onHeapStatsUpdate: function(event) |
- { |
- this._profileSamples = event.data; |
- this._scheduleUpdate(); |
- }, |
- |
- /** |
- * @param {?WebInspector.HeapSnapshotCommon.Samples} samples |
- */ |
- _setSamples: function(samples) |
- { |
- if (!samples) |
- return; |
- console.assert(!this._profileSamples.timestamps.length, "Should only call this method when loading from file."); |
- console.assert(samples.timestamps.length); |
- this._profileSamples = new WebInspector.TrackingHeapSnapshotProfileType.Samples(); |
- this._profileSamples.sizes = samples.sizes; |
- this._profileSamples.ids = samples.lastAssignedIds; |
- this._profileSamples.timestamps = samples.timestamps; |
- this._profileSamples.max = samples.sizes; |
- this._profileSamples.totalTime = /** @type{number} */(samples.timestamps.peekLast()); |
- this.update(); |
- }, |
- |
- /** |
- * @param {number} width |
- * @param {number} height |
- */ |
- _drawOverviewCanvas: function(width, height) |
- { |
- if (!this._profileSamples) |
- return; |
- var profileSamples = this._profileSamples; |
- var sizes = profileSamples.sizes; |
- var topSizes = profileSamples.max; |
- var timestamps = profileSamples.timestamps; |
- var startTime = timestamps[0]; |
- var endTime = timestamps[timestamps.length - 1]; |
- |
- var scaleFactor = this._xScale.nextScale(width / profileSamples.totalTime); |
- var maxSize = 0; |
- /** |
- * @param {!Array.<number>} sizes |
- * @param {function(number, number):void} callback |
- */ |
- function aggregateAndCall(sizes, callback) |
- { |
- var size = 0; |
- var currentX = 0; |
- for (var i = 1; i < timestamps.length; ++i) { |
- var x = Math.floor((timestamps[i] - startTime) * scaleFactor); |
- if (x !== currentX) { |
- if (size) |
- callback(currentX, size); |
- size = 0; |
- currentX = x; |
- } |
- size += sizes[i]; |
- } |
+ } |
+ |
+ dispose() { |
+ this._onStopTracking(); |
+ } |
+ |
+ _onStopTracking() { |
+ this._profileType.removeEventListener( |
+ WebInspector.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._onHeapStatsUpdate, this); |
+ this._profileType.removeEventListener( |
+ WebInspector.TrackingHeapSnapshotProfileType.TrackingStopped, this._onStopTracking, this); |
+ } |
+ |
+ _onHeapStatsUpdate(event) { |
+ this._profileSamples = event.data; |
+ this._scheduleUpdate(); |
+ } |
+ |
+ /** |
+ * @param {?WebInspector.HeapSnapshotCommon.Samples} samples |
+ */ |
+ _setSamples(samples) { |
+ if (!samples) |
+ return; |
+ console.assert(!this._profileSamples.timestamps.length, 'Should only call this method when loading from file.'); |
+ console.assert(samples.timestamps.length); |
+ this._profileSamples = new WebInspector.TrackingHeapSnapshotProfileType.Samples(); |
+ this._profileSamples.sizes = samples.sizes; |
+ this._profileSamples.ids = samples.lastAssignedIds; |
+ this._profileSamples.timestamps = samples.timestamps; |
+ this._profileSamples.max = samples.sizes; |
+ this._profileSamples.totalTime = /** @type{number} */ (samples.timestamps.peekLast()); |
+ this.update(); |
+ } |
+ |
+ /** |
+ * @param {number} width |
+ * @param {number} height |
+ */ |
+ _drawOverviewCanvas(width, height) { |
+ if (!this._profileSamples) |
+ return; |
+ var profileSamples = this._profileSamples; |
+ var sizes = profileSamples.sizes; |
+ var topSizes = profileSamples.max; |
+ var timestamps = profileSamples.timestamps; |
+ var startTime = timestamps[0]; |
+ var endTime = timestamps[timestamps.length - 1]; |
+ |
+ var scaleFactor = this._xScale.nextScale(width / profileSamples.totalTime); |
+ var maxSize = 0; |
+ /** |
+ * @param {!Array.<number>} sizes |
+ * @param {function(number, number):void} callback |
+ */ |
+ function aggregateAndCall(sizes, callback) { |
+ var size = 0; |
+ var currentX = 0; |
+ for (var i = 1; i < timestamps.length; ++i) { |
+ var x = Math.floor((timestamps[i] - startTime) * scaleFactor); |
+ if (x !== currentX) { |
+ if (size) |
callback(currentX, size); |
+ size = 0; |
+ currentX = x; |
} |
+ size += sizes[i]; |
+ } |
+ callback(currentX, size); |
+ } |
- /** |
- * @param {number} x |
- * @param {number} size |
- */ |
- function maxSizeCallback(x, size) |
- { |
- maxSize = Math.max(maxSize, size); |
- } |
- |
- aggregateAndCall(sizes, maxSizeCallback); |
- |
- var yScaleFactor = this._yScale.nextScale(maxSize ? height / (maxSize * 1.1) : 0.0); |
- |
- this._overviewCanvas.width = width * window.devicePixelRatio; |
- this._overviewCanvas.height = height * window.devicePixelRatio; |
- this._overviewCanvas.style.width = width + "px"; |
- this._overviewCanvas.style.height = height + "px"; |
- |
- var context = this._overviewCanvas.getContext("2d"); |
- context.scale(window.devicePixelRatio, window.devicePixelRatio); |
- |
- context.beginPath(); |
- context.lineWidth = 2; |
- context.strokeStyle = "rgba(192, 192, 192, 0.6)"; |
- var currentX = (endTime - startTime) * scaleFactor; |
- context.moveTo(currentX, height - 1); |
- context.lineTo(currentX, 0); |
- context.stroke(); |
- context.closePath(); |
- |
- var gridY; |
- var gridValue; |
- var gridLabelHeight = 14; |
- if (yScaleFactor) { |
- const maxGridValue = (height - gridLabelHeight) / yScaleFactor; |
- // The round value calculation is a bit tricky, because |
- // it has a form k*10^n*1024^m, where k=[1,5], n=[0..3], m is an integer, |
- // e.g. a round value 10KB is 10240 bytes. |
- gridValue = Math.pow(1024, Math.floor(Math.log(maxGridValue) / Math.log(1024))); |
- gridValue *= Math.pow(10, Math.floor(Math.log(maxGridValue / gridValue) / Math.LN10)); |
- if (gridValue * 5 <= maxGridValue) |
- gridValue *= 5; |
- gridY = Math.round(height - gridValue * yScaleFactor - 0.5) + 0.5; |
- context.beginPath(); |
- context.lineWidth = 1; |
- context.strokeStyle = "rgba(0, 0, 0, 0.2)"; |
- context.moveTo(0, gridY); |
- context.lineTo(width, gridY); |
- context.stroke(); |
- context.closePath(); |
- } |
+ /** |
+ * @param {number} x |
+ * @param {number} size |
+ */ |
+ function maxSizeCallback(x, size) { |
+ maxSize = Math.max(maxSize, size); |
+ } |
- /** |
- * @param {number} x |
- * @param {number} size |
- */ |
- function drawBarCallback(x, size) |
- { |
- context.moveTo(x, height - 1); |
- context.lineTo(x, Math.round(height - size * yScaleFactor - 1)); |
- } |
+ aggregateAndCall(sizes, maxSizeCallback); |
+ |
+ var yScaleFactor = this._yScale.nextScale(maxSize ? height / (maxSize * 1.1) : 0.0); |
+ |
+ this._overviewCanvas.width = width * window.devicePixelRatio; |
+ this._overviewCanvas.height = height * window.devicePixelRatio; |
+ this._overviewCanvas.style.width = width + 'px'; |
+ this._overviewCanvas.style.height = height + 'px'; |
+ |
+ var context = this._overviewCanvas.getContext('2d'); |
+ context.scale(window.devicePixelRatio, window.devicePixelRatio); |
+ |
+ context.beginPath(); |
+ context.lineWidth = 2; |
+ context.strokeStyle = 'rgba(192, 192, 192, 0.6)'; |
+ var currentX = (endTime - startTime) * scaleFactor; |
+ context.moveTo(currentX, height - 1); |
+ context.lineTo(currentX, 0); |
+ context.stroke(); |
+ context.closePath(); |
+ |
+ var gridY; |
+ var gridValue; |
+ var gridLabelHeight = 14; |
+ if (yScaleFactor) { |
+ const maxGridValue = (height - gridLabelHeight) / yScaleFactor; |
+ // The round value calculation is a bit tricky, because |
+ // it has a form k*10^n*1024^m, where k=[1,5], n=[0..3], m is an integer, |
+ // e.g. a round value 10KB is 10240 bytes. |
+ gridValue = Math.pow(1024, Math.floor(Math.log(maxGridValue) / Math.log(1024))); |
+ gridValue *= Math.pow(10, Math.floor(Math.log(maxGridValue / gridValue) / Math.LN10)); |
+ if (gridValue * 5 <= maxGridValue) |
+ gridValue *= 5; |
+ gridY = Math.round(height - gridValue * yScaleFactor - 0.5) + 0.5; |
+ context.beginPath(); |
+ context.lineWidth = 1; |
+ context.strokeStyle = 'rgba(0, 0, 0, 0.2)'; |
+ context.moveTo(0, gridY); |
+ context.lineTo(width, gridY); |
+ context.stroke(); |
+ context.closePath(); |
+ } |
- context.beginPath(); |
- context.lineWidth = 2; |
- context.strokeStyle = "rgba(192, 192, 192, 0.6)"; |
- aggregateAndCall(topSizes, drawBarCallback); |
- context.stroke(); |
- context.closePath(); |
- |
- context.beginPath(); |
- context.lineWidth = 2; |
- context.strokeStyle = "rgba(0, 0, 192, 0.8)"; |
- aggregateAndCall(sizes, drawBarCallback); |
- context.stroke(); |
- context.closePath(); |
- |
- if (gridValue) { |
- var label = Number.bytesToString(gridValue); |
- var labelPadding = 4; |
- var labelX = 0; |
- var labelY = gridY - 0.5; |
- var labelWidth = 2 * labelPadding + context.measureText(label).width; |
- context.beginPath(); |
- context.textBaseline = "bottom"; |
- context.font = "10px " + window.getComputedStyle(this.element, null).getPropertyValue("font-family"); |
- context.fillStyle = "rgba(255, 255, 255, 0.75)"; |
- context.fillRect(labelX, labelY - gridLabelHeight, labelWidth, gridLabelHeight); |
- context.fillStyle = "rgb(64, 64, 64)"; |
- context.fillText(label, labelX + labelPadding, labelY); |
- context.fill(); |
- context.closePath(); |
- } |
- }, |
- |
- onResize: function() |
- { |
- this._updateOverviewCanvas = true; |
- this._scheduleUpdate(); |
- }, |
- |
- _onWindowChanged: function() |
- { |
- if (!this._updateGridTimerId) |
- this._updateGridTimerId = setTimeout(this._updateGrid.bind(this), 10); |
- }, |
- |
- _scheduleUpdate: function() |
- { |
- if (this._updateTimerId) |
- return; |
- this._updateTimerId = setTimeout(this.update.bind(this), 10); |
- }, |
- |
- _updateBoundaries: function() |
- { |
- this._windowLeft = this._overviewGrid.windowLeft(); |
- this._windowRight = this._overviewGrid.windowRight(); |
- this._windowWidth = this._windowRight - this._windowLeft; |
- }, |
- |
- update: function() |
- { |
- this._updateTimerId = null; |
- if (!this.isShowing()) |
- return; |
- this._updateBoundaries(); |
- this._overviewCalculator._updateBoundaries(this); |
- this._overviewGrid.updateDividers(this._overviewCalculator); |
- this._drawOverviewCanvas(this._overviewContainer.clientWidth, this._overviewContainer.clientHeight - 20); |
- }, |
- |
- _updateGrid: function() |
- { |
- this._updateGridTimerId = 0; |
- this._updateBoundaries(); |
- var ids = this._profileSamples.ids; |
- var timestamps = this._profileSamples.timestamps; |
- var sizes = this._profileSamples.sizes; |
- var startTime = timestamps[0]; |
- var totalTime = this._profileSamples.totalTime; |
- var timeLeft = startTime + totalTime * this._windowLeft; |
- var timeRight = startTime + totalTime * this._windowRight; |
- var minId = 0; |
- var maxId = ids[ids.length - 1] + 1; |
- var size = 0; |
- for (var 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; |
- } |
- size += sizes[i]; |
- } |
+ /** |
+ * @param {number} x |
+ * @param {number} size |
+ */ |
+ function drawBarCallback(x, size) { |
+ context.moveTo(x, height - 1); |
+ context.lineTo(x, Math.round(height - size * yScaleFactor - 1)); |
+ } |
- this.dispatchEventToListeners(WebInspector.HeapTrackingOverviewGrid.IdsRangeChanged, {minId: minId, maxId: maxId, size: size}); |
- }, |
+ context.beginPath(); |
+ context.lineWidth = 2; |
+ context.strokeStyle = 'rgba(192, 192, 192, 0.6)'; |
+ aggregateAndCall(topSizes, drawBarCallback); |
+ context.stroke(); |
+ context.closePath(); |
+ |
+ context.beginPath(); |
+ context.lineWidth = 2; |
+ context.strokeStyle = 'rgba(0, 0, 192, 0.8)'; |
+ aggregateAndCall(sizes, drawBarCallback); |
+ context.stroke(); |
+ context.closePath(); |
+ |
+ if (gridValue) { |
+ var label = Number.bytesToString(gridValue); |
+ var labelPadding = 4; |
+ var labelX = 0; |
+ var labelY = gridY - 0.5; |
+ var labelWidth = 2 * labelPadding + context.measureText(label).width; |
+ context.beginPath(); |
+ context.textBaseline = 'bottom'; |
+ context.font = '10px ' + window.getComputedStyle(this.element, null).getPropertyValue('font-family'); |
+ context.fillStyle = 'rgba(255, 255, 255, 0.75)'; |
+ context.fillRect(labelX, labelY - gridLabelHeight, labelWidth, gridLabelHeight); |
+ context.fillStyle = 'rgb(64, 64, 64)'; |
+ context.fillText(label, labelX + labelPadding, labelY); |
+ context.fill(); |
+ context.closePath(); |
+ } |
+ } |
+ |
+ /** |
+ * @override |
+ */ |
+ onResize() { |
+ this._updateOverviewCanvas = true; |
+ this._scheduleUpdate(); |
+ } |
+ |
+ _onWindowChanged() { |
+ if (!this._updateGridTimerId) |
+ this._updateGridTimerId = setTimeout(this._updateGrid.bind(this), 10); |
+ } |
+ |
+ _scheduleUpdate() { |
+ if (this._updateTimerId) |
+ return; |
+ this._updateTimerId = setTimeout(this.update.bind(this), 10); |
+ } |
+ |
+ _updateBoundaries() { |
+ this._windowLeft = this._overviewGrid.windowLeft(); |
+ this._windowRight = this._overviewGrid.windowRight(); |
+ this._windowWidth = this._windowRight - this._windowLeft; |
+ } |
+ |
+ update() { |
+ this._updateTimerId = null; |
+ if (!this.isShowing()) |
+ return; |
+ this._updateBoundaries(); |
+ this._overviewCalculator._updateBoundaries(this); |
+ this._overviewGrid.updateDividers(this._overviewCalculator); |
+ this._drawOverviewCanvas(this._overviewContainer.clientWidth, this._overviewContainer.clientHeight - 20); |
+ } |
+ |
+ _updateGrid() { |
+ this._updateGridTimerId = 0; |
+ this._updateBoundaries(); |
+ var ids = this._profileSamples.ids; |
+ var timestamps = this._profileSamples.timestamps; |
+ var sizes = this._profileSamples.sizes; |
+ var startTime = timestamps[0]; |
+ var totalTime = this._profileSamples.totalTime; |
+ var timeLeft = startTime + totalTime * this._windowLeft; |
+ var timeRight = startTime + totalTime * this._windowRight; |
+ var minId = 0; |
+ var maxId = ids[ids.length - 1] + 1; |
+ var size = 0; |
+ for (var 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; |
+ } |
+ size += sizes[i]; |
+ } |
- __proto__: WebInspector.VBox.prototype |
+ this.dispatchEventToListeners( |
+ WebInspector.HeapTrackingOverviewGrid.IdsRangeChanged, {minId: minId, maxId: maxId, size: size}); |
+ } |
}; |
+WebInspector.HeapTrackingOverviewGrid.IdsRangeChanged = 'IdsRangeChanged'; |
/** |
- * @constructor |
+ * @unrestricted |
*/ |
-WebInspector.HeapTrackingOverviewGrid.SmoothScale = function() |
-{ |
+WebInspector.HeapTrackingOverviewGrid.SmoothScale = class { |
+ constructor() { |
this._lastUpdate = 0; |
this._currentScale = 0.0; |
-}; |
- |
-WebInspector.HeapTrackingOverviewGrid.SmoothScale.prototype = { |
- /** |
- * @param {number} target |
- * @return {number} |
- */ |
- nextScale: function(target) { |
- target = target || this._currentScale; |
- if (this._currentScale) { |
- var now = Date.now(); |
- var timeDeltaMs = now - this._lastUpdate; |
- this._lastUpdate = now; |
- var maxChangePerSec = 20; |
- var maxChangePerDelta = Math.pow(maxChangePerSec, timeDeltaMs / 1000); |
- var scaleChange = target / this._currentScale; |
- this._currentScale *= Number.constrain(scaleChange, 1 / maxChangePerDelta, maxChangePerDelta); |
- } else { |
- this._currentScale = target; |
- } |
- return this._currentScale; |
+ } |
+ |
+ /** |
+ * @param {number} target |
+ * @return {number} |
+ */ |
+ nextScale(target) { |
+ target = target || this._currentScale; |
+ if (this._currentScale) { |
+ var now = Date.now(); |
+ var timeDeltaMs = now - this._lastUpdate; |
+ this._lastUpdate = now; |
+ var maxChangePerSec = 20; |
+ var maxChangePerDelta = Math.pow(maxChangePerSec, timeDeltaMs / 1000); |
+ var scaleChange = target / this._currentScale; |
+ this._currentScale *= Number.constrain(scaleChange, 1 / maxChangePerDelta, maxChangePerDelta); |
+ } else { |
+ this._currentScale = target; |
} |
+ return this._currentScale; |
+ } |
}; |
- |
/** |
- * @constructor |
* @implements {WebInspector.TimelineGrid.Calculator} |
+ * @unrestricted |
*/ |
-WebInspector.HeapTrackingOverviewGrid.OverviewCalculator = function() |
-{ |
-}; |
- |
-WebInspector.HeapTrackingOverviewGrid.OverviewCalculator.prototype = { |
- /** |
- * @override |
- * @return {number} |
- */ |
- paddingLeft: function() |
- { |
- return 0; |
- }, |
- |
- /** |
- * @param {!WebInspector.HeapTrackingOverviewGrid} chart |
- */ |
- _updateBoundaries: function(chart) |
- { |
- this._minimumBoundaries = 0; |
- this._maximumBoundaries = chart._profileSamples.totalTime; |
- this._xScaleFactor = chart._overviewContainer.clientWidth / this._maximumBoundaries; |
- }, |
- |
- /** |
- * @override |
- * @param {number} time |
- * @return {number} |
- */ |
- computePosition: function(time) |
- { |
- return (time - this._minimumBoundaries) * this._xScaleFactor; |
- }, |
- |
- /** |
- * @override |
- * @param {number} value |
- * @param {number=} precision |
- * @return {string} |
- */ |
- formatValue: function(value, precision) |
- { |
- return Number.secondsToString(value / 1000, !!precision); |
- }, |
- |
- /** |
- * @override |
- * @return {number} |
- */ |
- maximumBoundary: function() |
- { |
- return this._maximumBoundaries; |
- }, |
- |
- /** |
- * @override |
- * @return {number} |
- */ |
- minimumBoundary: function() |
- { |
- return this._minimumBoundaries; |
- }, |
- |
- /** |
- * @override |
- * @return {number} |
- */ |
- zeroTime: function() |
- { |
- return this._minimumBoundaries; |
- }, |
- |
- /** |
- * @override |
- * @return {number} |
- */ |
- boundarySpan: function() |
- { |
- return this._maximumBoundaries - this._minimumBoundaries; |
- } |
+WebInspector.HeapTrackingOverviewGrid.OverviewCalculator = class { |
+ /** |
+ * @override |
+ * @return {number} |
+ */ |
+ paddingLeft() { |
+ return 0; |
+ } |
+ |
+ /** |
+ * @param {!WebInspector.HeapTrackingOverviewGrid} chart |
+ */ |
+ _updateBoundaries(chart) { |
+ this._minimumBoundaries = 0; |
+ this._maximumBoundaries = chart._profileSamples.totalTime; |
+ this._xScaleFactor = chart._overviewContainer.clientWidth / this._maximumBoundaries; |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {number} time |
+ * @return {number} |
+ */ |
+ computePosition(time) { |
+ return (time - this._minimumBoundaries) * this._xScaleFactor; |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {number} value |
+ * @param {number=} precision |
+ * @return {string} |
+ */ |
+ formatValue(value, precision) { |
+ return Number.secondsToString(value / 1000, !!precision); |
+ } |
+ |
+ /** |
+ * @override |
+ * @return {number} |
+ */ |
+ maximumBoundary() { |
+ return this._maximumBoundaries; |
+ } |
+ |
+ /** |
+ * @override |
+ * @return {number} |
+ */ |
+ minimumBoundary() { |
+ return this._minimumBoundaries; |
+ } |
+ |
+ /** |
+ * @override |
+ * @return {number} |
+ */ |
+ zeroTime() { |
+ return this._minimumBoundaries; |
+ } |
+ |
+ /** |
+ * @override |
+ * @return {number} |
+ */ |
+ boundarySpan() { |
+ return this._maximumBoundaries - this._minimumBoundaries; |
+ } |
}; |
- |
/** |
- * @constructor |
- * @extends {WebInspector.VBox} |
+ * @unrestricted |
*/ |
-WebInspector.HeapSnapshotStatisticsView = function() |
-{ |
- WebInspector.VBox.call(this); |
+WebInspector.HeapSnapshotStatisticsView = class extends WebInspector.VBox { |
+ constructor() { |
+ super(); |
this.setMinimumSize(50, 25); |
this._pieChart = new WebInspector.PieChart(150, WebInspector.HeapSnapshotStatisticsView._valueFormatter, true); |
- this._pieChart.element.classList.add("heap-snapshot-stats-pie-chart"); |
+ this._pieChart.element.classList.add('heap-snapshot-stats-pie-chart'); |
this.element.appendChild(this._pieChart.element); |
- this._labels = this.element.createChild("div", "heap-snapshot-stats-legend"); |
+ this._labels = this.element.createChild('div', 'heap-snapshot-stats-legend'); |
+ } |
+ |
+ /** |
+ * @param {number} value |
+ * @return {string} |
+ */ |
+ static _valueFormatter(value) { |
+ return WebInspector.UIString('%s KB', Number.withThousandsSeparator(Math.round(value / 1024))); |
+ } |
+ |
+ /** |
+ * @param {number} value |
+ */ |
+ setTotal(value) { |
+ this._pieChart.setTotal(value); |
+ } |
+ |
+ /** |
+ * @param {number} value |
+ * @param {string} name |
+ * @param {string=} color |
+ */ |
+ addRecord(value, name, color) { |
+ if (color) |
+ this._pieChart.addSlice(value, color); |
+ |
+ var node = this._labels.createChild('div'); |
+ var swatchDiv = node.createChild('div', 'heap-snapshot-stats-swatch'); |
+ var nameDiv = node.createChild('div', 'heap-snapshot-stats-name'); |
+ var sizeDiv = node.createChild('div', 'heap-snapshot-stats-size'); |
+ if (color) |
+ swatchDiv.style.backgroundColor = color; |
+ else |
+ swatchDiv.classList.add('heap-snapshot-stats-empty-swatch'); |
+ nameDiv.textContent = name; |
+ sizeDiv.textContent = WebInspector.HeapSnapshotStatisticsView._valueFormatter(value); |
+ } |
}; |
-/** |
- * @param {number} value |
- * @return {string} |
- */ |
-WebInspector.HeapSnapshotStatisticsView._valueFormatter = function(value) |
-{ |
- return WebInspector.UIString("%s KB", Number.withThousandsSeparator(Math.round(value / 1024))); |
-}; |
- |
-WebInspector.HeapSnapshotStatisticsView.prototype = { |
- /** |
- * @param {number} value |
- */ |
- setTotal: function(value) |
- { |
- this._pieChart.setTotal(value); |
- }, |
- |
- /** |
- * @param {number} value |
- * @param {string} name |
- * @param {string=} color |
- */ |
- addRecord: function(value, name, color) |
- { |
- if (color) |
- this._pieChart.addSlice(value, color); |
- |
- var node = this._labels.createChild("div"); |
- var swatchDiv = node.createChild("div", "heap-snapshot-stats-swatch"); |
- var nameDiv = node.createChild("div", "heap-snapshot-stats-name"); |
- var sizeDiv = node.createChild("div", "heap-snapshot-stats-size"); |
- if (color) |
- swatchDiv.style.backgroundColor = color; |
- else |
- swatchDiv.classList.add("heap-snapshot-stats-empty-swatch"); |
- nameDiv.textContent = name; |
- sizeDiv.textContent = WebInspector.HeapSnapshotStatisticsView._valueFormatter(value); |
- }, |
- |
- __proto__: WebInspector.VBox.prototype |
-}; |
/** |
- * @constructor |
- * @extends {WebInspector.Widget} |
- * @param {?WebInspector.Target} target |
+ * @unrestricted |
*/ |
-WebInspector.HeapAllocationStackView = function(target) |
-{ |
- WebInspector.Widget.call(this); |
+WebInspector.HeapAllocationStackView = class extends WebInspector.Widget { |
+ /** |
+ * @param {?WebInspector.Target} target |
+ */ |
+ constructor(target) { |
+ super(); |
this._target = target; |
this._linkifier = new WebInspector.Linkifier(); |
-}; |
- |
-WebInspector.HeapAllocationStackView.prototype = { |
- /** |
- * @param {!WebInspector.HeapSnapshotProxy} snapshot |
- * @param {number} snapshotNodeIndex |
- */ |
- setAllocatedObject: function(snapshot, snapshotNodeIndex) |
- { |
- this.clear(); |
- snapshot.allocationStack(snapshotNodeIndex, this._didReceiveAllocationStack.bind(this)); |
- }, |
- |
- clear: function() |
- { |
- this.element.removeChildren(); |
- this._linkifier.reset(); |
- }, |
- |
- /** |
- * @param {?Array.<!WebInspector.HeapSnapshotCommon.AllocationStackFrame>} frames |
- */ |
- _didReceiveAllocationStack: function(frames) |
- { |
- if (!frames) { |
- var stackDiv = this.element.createChild("div", "no-heap-allocation-stack"); |
- stackDiv.createTextChild(WebInspector.UIString("Stack was not recorded for this object because it had been allocated before this profile recording started.")); |
- return; |
- } |
- |
- var stackDiv = this.element.createChild("div", "heap-allocation-stack"); |
- for (var i = 0; i < frames.length; i++) { |
- var frame = frames[i]; |
- var frameDiv = stackDiv.createChild("div", "stack-frame"); |
- var name = frameDiv.createChild("div"); |
- name.textContent = WebInspector.beautifyFunctionName(frame.functionName); |
- if (frame.scriptId) { |
- var urlElement = this._linkifier.linkifyScriptLocation(this._target, String(frame.scriptId), frame.scriptName, frame.line - 1, frame.column - 1); |
- frameDiv.appendChild(urlElement); |
- } |
- } |
- }, |
+ } |
+ |
+ /** |
+ * @param {!WebInspector.HeapSnapshotProxy} snapshot |
+ * @param {number} snapshotNodeIndex |
+ */ |
+ setAllocatedObject(snapshot, snapshotNodeIndex) { |
+ this.clear(); |
+ snapshot.allocationStack(snapshotNodeIndex, this._didReceiveAllocationStack.bind(this)); |
+ } |
+ |
+ clear() { |
+ this.element.removeChildren(); |
+ this._linkifier.reset(); |
+ } |
+ |
+ /** |
+ * @param {?Array.<!WebInspector.HeapSnapshotCommon.AllocationStackFrame>} frames |
+ */ |
+ _didReceiveAllocationStack(frames) { |
+ if (!frames) { |
+ var stackDiv = this.element.createChild('div', 'no-heap-allocation-stack'); |
+ stackDiv.createTextChild(WebInspector.UIString( |
+ 'Stack was not recorded for this object because it had been allocated before this profile recording started.')); |
+ return; |
+ } |
- __proto__: WebInspector.Widget.prototype |
+ var stackDiv = this.element.createChild('div', 'heap-allocation-stack'); |
+ for (var i = 0; i < frames.length; i++) { |
+ var frame = frames[i]; |
+ var frameDiv = stackDiv.createChild('div', 'stack-frame'); |
+ var name = frameDiv.createChild('div'); |
+ name.textContent = WebInspector.beautifyFunctionName(frame.functionName); |
+ if (frame.scriptId) { |
+ var urlElement = this._linkifier.linkifyScriptLocation( |
+ this._target, String(frame.scriptId), frame.scriptName, frame.line - 1, frame.column - 1); |
+ frameDiv.appendChild(urlElement); |
+ } |
+ } |
+ } |
}; |