diff options
Diffstat (limited to 'WebKit/chromium/src/js/HeapProfilerPanel.js')
-rw-r--r-- | WebKit/chromium/src/js/HeapProfilerPanel.js | 966 |
1 files changed, 0 insertions, 966 deletions
diff --git a/WebKit/chromium/src/js/HeapProfilerPanel.js b/WebKit/chromium/src/js/HeapProfilerPanel.js deleted file mode 100644 index abbf580..0000000 --- a/WebKit/chromium/src/js/HeapProfilerPanel.js +++ /dev/null @@ -1,966 +0,0 @@ -/* - * Copyright (C) 2010 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @fileoverview Heap profiler panel implementation. - */ - -WebInspector.ProfilesPanel.prototype.addSnapshot = function(snapshot) { - snapshot.title = WebInspector.UIString("Snapshot %d", snapshot.number); - snapshot.typeId = WebInspector.HeapSnapshotProfileType.TypeId; - - var snapshots = WebInspector.HeapSnapshotProfileType.snapshots; - snapshots.push(snapshot); - - snapshot.listIndex = snapshots.length - 1; - - if (WebInspector.CPUProfile) - this.addProfileHeader(WebInspector.HeapSnapshotProfileType.TypeId, snapshot); - else - this.addProfileHeader(snapshot); - - this.dispatchEventToListeners("snapshot added"); -} - - -WebInspector.HeapSnapshotView = function(parent, profile) -{ - WebInspector.View.call(this); - - this.element.addStyleClass("heap-snapshot-view"); - - this.parent = parent; - this.parent.addEventListener("snapshot added", this._updateBaseOptions, this); - - this.showCountAsPercent = false; - this.showSizeAsPercent = false; - this.showCountDeltaAsPercent = false; - this.showSizeDeltaAsPercent = false; - - this.categories = { - code: new WebInspector.ResourceCategory("code", WebInspector.UIString("Code"), "rgb(255,121,0)"), - data: new WebInspector.ResourceCategory("data", WebInspector.UIString("Objects"), "rgb(47,102,236)") - }; - - var summaryContainer = document.createElement("div"); - summaryContainer.id = "heap-snapshot-summary-container"; - - this.countsSummaryBar = new WebInspector.SummaryBar(this.categories); - this.countsSummaryBar.element.className = "heap-snapshot-summary"; - this.countsSummaryBar.calculator = new WebInspector.HeapSummaryCountCalculator(); - var countsLabel = document.createElement("div"); - countsLabel.className = "heap-snapshot-summary-label"; - countsLabel.textContent = WebInspector.UIString("Count"); - this.countsSummaryBar.element.appendChild(countsLabel); - summaryContainer.appendChild(this.countsSummaryBar.element); - - this.sizesSummaryBar = new WebInspector.SummaryBar(this.categories); - this.sizesSummaryBar.element.className = "heap-snapshot-summary"; - this.sizesSummaryBar.calculator = new WebInspector.HeapSummarySizeCalculator(); - var sizesLabel = document.createElement("label"); - sizesLabel.className = "heap-snapshot-summary-label"; - sizesLabel.textContent = WebInspector.UIString("Size"); - this.sizesSummaryBar.element.appendChild(sizesLabel); - summaryContainer.appendChild(this.sizesSummaryBar.element); - - this.element.appendChild(summaryContainer); - - var columns = { "cons": { title: WebInspector.UIString("Constructor"), disclosure: true, sortable: true }, - "count": { title: WebInspector.UIString("Count"), width: "54px", sortable: true }, - "size": { title: WebInspector.UIString("Size"), width: "72px", sort: "descending", sortable: true }, - "countDelta": { title: WebInspector.UIString("\xb1 Count"), width: "72px", sortable: true }, - "sizeDelta": { title: WebInspector.UIString("\xb1 Size"), width: "72px", sortable: true } }; - - this.dataGrid = new WebInspector.DataGrid(columns); - this.dataGrid.addEventListener("sorting changed", this._sortData, this); - this.dataGrid.element.addEventListener("mousedown", this._mouseDownInDataGrid.bind(this), true); - this.element.appendChild(this.dataGrid.element); - - this.profile = profile; - - this.baseSelectElement = document.createElement("select"); - this.baseSelectElement.className = "status-bar-item"; - this.baseSelectElement.addEventListener("change", this._changeBase.bind(this), false); - this._updateBaseOptions(); - if (this.profile.listIndex > 0) - this.baseSelectElement.selectedIndex = this.profile.listIndex - 1; - else - this.baseSelectElement.selectedIndex = this.profile.listIndex; - this._resetDataGridList(); - - this.percentButton = new WebInspector.StatusBarButton("", "percent-time-status-bar-item status-bar-item"); - this.percentButton.addEventListener("click", this._percentClicked.bind(this), false); - - this.refresh(); - - this._updatePercentButton(); -}; - -WebInspector.HeapSnapshotView.prototype = { - - get statusBarItems() - { - return [this.baseSelectElement, this.percentButton.element]; - }, - - get profile() - { - return this._profile; - }, - - set profile(profile) - { - this._profile = profile; - }, - - show: function(parentElement) - { - WebInspector.View.prototype.show.call(this, parentElement); - this.dataGrid.updateWidths(); - }, - - hide: function() - { - WebInspector.View.prototype.hide.call(this); - this._currentSearchResultIndex = -1; - }, - - resize: function() - { - if (this.dataGrid) - this.dataGrid.updateWidths(); - }, - - refresh: function() - { - this.dataGrid.removeChildren(); - - var children = this.snapshotDataGridList.children; - var count = children.length; - for (var index = 0; index < count; ++index) - this.dataGrid.appendChild(children[index]); - - this._updateSummaryGraph(); - }, - - refreshShowAsPercents: function() - { - this._updatePercentButton(); - this.refreshVisibleData(); - }, - - _deleteSearchMatchedFlags: function(node) - { - delete node._searchMatchedConsColumn; - delete node._searchMatchedCountColumn; - delete node._searchMatchedSizeColumn; - delete node._searchMatchedCountDeltaColumn; - delete node._searchMatchedSizeDeltaColumn; - }, - - searchCanceled: function() - { - if (this._searchResults) { - for (var i = 0; i < this._searchResults.length; ++i) { - var profileNode = this._searchResults[i].profileNode; - this._deleteSearchMatchedFlags(profileNode); - profileNode.refresh(); - } - } - - delete this._searchFinishedCallback; - this._currentSearchResultIndex = -1; - this._searchResults = []; - }, - - performSearch: function(query, finishedCallback) - { - // Call searchCanceled since it will reset everything we need before doing a new search. - this.searchCanceled(); - - query = query.trimWhitespace(); - - if (!query.length) - return; - - this._searchFinishedCallback = finishedCallback; - - var helper = WebInspector.HeapSnapshotView.SearchHelper; - - var operationAndNumber = helper.parseOperationAndNumber(query); - var operation = operationAndNumber[0]; - var queryNumber = operationAndNumber[1]; - - var percentUnits = helper.percents.test(query); - var megaBytesUnits = helper.megaBytes.test(query); - var kiloBytesUnits = helper.kiloBytes.test(query); - var bytesUnits = helper.bytes.test(query); - - var queryNumberBytes = (megaBytesUnits ? (queryNumber * 1024 * 1024) : (kiloBytesUnits ? (queryNumber * 1024) : queryNumber)); - - function matchesQuery(heapSnapshotDataGridNode) - { - WebInspector.HeapSnapshotView.prototype._deleteSearchMatchedFlags(heapSnapshotDataGridNode); - - if (percentUnits) { - heapSnapshotDataGridNode._searchMatchedCountColumn = operation(heapSnapshotDataGridNode.countPercent, queryNumber); - heapSnapshotDataGridNode._searchMatchedSizeColumn = operation(heapSnapshotDataGridNode.sizePercent, queryNumber); - heapSnapshotDataGridNode._searchMatchedCountDeltaColumn = operation(heapSnapshotDataGridNode.countDeltaPercent, queryNumber); - heapSnapshotDataGridNode._searchMatchedSizeDeltaColumn = operation(heapSnapshotDataGridNode.sizeDeltaPercent, queryNumber); - } else if (megaBytesUnits || kiloBytesUnits || bytesUnits) { - heapSnapshotDataGridNode._searchMatchedSizeColumn = operation(heapSnapshotDataGridNode.size, queryNumberBytes); - heapSnapshotDataGridNode._searchMatchedSizeDeltaColumn = operation(heapSnapshotDataGridNode.sizeDelta, queryNumberBytes); - } else { - heapSnapshotDataGridNode._searchMatchedCountColumn = operation(heapSnapshotDataGridNode.count, queryNumber); - heapSnapshotDataGridNode._searchMatchedCountDeltaColumn = operation(heapSnapshotDataGridNode.countDelta, queryNumber); - } - - if (heapSnapshotDataGridNode.constructorName.hasSubstring(query, true)) - heapSnapshotDataGridNode._searchMatchedConsColumn = true; - - if (heapSnapshotDataGridNode._searchMatchedConsColumn || - heapSnapshotDataGridNode._searchMatchedCountColumn || - heapSnapshotDataGridNode._searchMatchedSizeColumn || - heapSnapshotDataGridNode._searchMatchedCountDeltaColumn || - heapSnapshotDataGridNode._searchMatchedSizeDeltaColumn) { - heapSnapshotDataGridNode.refresh(); - return true; - } - - return false; - } - - var current = this.snapshotDataGridList.children[0]; - var depth = 0; - var info = {}; - - // The second and subsequent levels of heap snapshot nodes represent retainers, - // so recursive expansion will be infinite, since a graph is being traversed. - // So default to a recursion cap of 2 levels. - var maxDepth = 2; - - while (current) { - if (matchesQuery(current)) - this._searchResults.push({ profileNode: current }); - current = current.traverseNextNode(false, null, (depth >= maxDepth), info); - depth += info.depthChange; - } - - finishedCallback(this, this._searchResults.length); - }, - - jumpToFirstSearchResult: WebInspector.CPUProfileView.prototype.jumpToFirstSearchResult, - jumpToLastSearchResult: WebInspector.CPUProfileView.prototype.jumpToLastSearchResult, - jumpToNextSearchResult: WebInspector.CPUProfileView.prototype.jumpToNextSearchResult, - jumpToPreviousSearchResult: WebInspector.CPUProfileView.prototype.jumpToPreviousSearchResult, - showingFirstSearchResult: WebInspector.CPUProfileView.prototype.showingFirstSearchResult, - showingLastSearchResult: WebInspector.CPUProfileView.prototype.showingLastSearchResult, - _jumpToSearchResult: WebInspector.CPUProfileView.prototype._jumpToSearchResult, - - refreshVisibleData: function() - { - var child = this.dataGrid.children[0]; - while (child) { - child.refresh(); - child = child.traverseNextNode(false, null, true); - } - this._updateSummaryGraph(); - }, - - _changeBase: function() { - if (this.baseSnapshot === WebInspector.HeapSnapshotProfileType.snapshots[this.baseSelectElement.selectedIndex]) - return; - - this._resetDataGridList(); - this.refresh(); - - if (!this.currentQuery || !this._searchFinishedCallback || !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._searchFinishedCallback(this, -this._searchResults.length); - this.performSearch(this.currentQuery, this._searchFinishedCallback); - }, - - _createSnapshotDataGridList: function() - { - if (this._snapshotDataGridList) - delete this._snapshotDataGridList; - - this._snapshotDataGridList = new WebInspector.HeapSnapshotDataGridList(this, this.baseSnapshot.entries, this.profile.entries); - return this._snapshotDataGridList; - }, - - _mouseDownInDataGrid: function(event) - { - if (event.detail < 2) - return; - - var cell = event.target.enclosingNodeOrSelfWithNodeName("td"); - if (!cell || (!cell.hasStyleClass("count-column") && !cell.hasStyleClass("size-column") && !cell.hasStyleClass("countDelta-column") && !cell.hasStyleClass("sizeDelta-column"))) - return; - - if (cell.hasStyleClass("count-column")) - this.showCountAsPercent = !this.showCountAsPercent; - else if (cell.hasStyleClass("size-column")) - this.showSizeAsPercent = !this.showSizeAsPercent; - else if (cell.hasStyleClass("countDelta-column")) - this.showCountDeltaAsPercent = !this.showCountDeltaAsPercent; - else if (cell.hasStyleClass("sizeDelta-column")) - this.showSizeDeltaAsPercent = !this.showSizeDeltaAsPercent; - - this.refreshShowAsPercents(); - - event.preventDefault(); - event.stopPropagation(); - }, - - get _isShowingAsPercent() - { - return this.showCountAsPercent && this.showSizeAsPercent && this.showCountDeltaAsPercent && this.showSizeDeltaAsPercent; - }, - - _percentClicked: function(event) - { - var currentState = this._isShowingAsPercent; - this.showCountAsPercent = !currentState; - this.showSizeAsPercent = !currentState; - this.showCountDeltaAsPercent = !currentState; - this.showSizeDeltaAsPercent = !currentState; - this.refreshShowAsPercents(); - }, - - _resetDataGridList: function() - { - this.baseSnapshot = WebInspector.HeapSnapshotProfileType.snapshots[this.baseSelectElement.selectedIndex]; - var lastComparator = WebInspector.HeapSnapshotDataGridList.propertyComparator("size", false); - if (this.snapshotDataGridList) - lastComparator = this.snapshotDataGridList.lastComparator; - this.snapshotDataGridList = this._createSnapshotDataGridList(); - this.snapshotDataGridList.sort(lastComparator, true); - }, - - _sortData: function() - { - var sortAscending = this.dataGrid.sortOrder === "ascending"; - var sortColumnIdentifier = this.dataGrid.sortColumnIdentifier; - var sortProperty = { - "cons": ["constructorName", null], - "count": ["count", null], - "size": ["size", "count"], - "countDelta": this.showCountDeltaAsPercent ? ["countDeltaPercent", null] : ["countDelta", null], - "sizeDelta": this.showSizeDeltaAsPercent ? ["sizeDeltaPercent", "countDeltaPercent"] : ["sizeDelta", "sizeDeltaPercent"] - }[sortColumnIdentifier]; - - this.snapshotDataGridList.sort(WebInspector.HeapSnapshotDataGridList.propertyComparator(sortProperty[0], sortProperty[1], sortAscending)); - - this.refresh(); - }, - - _updateBaseOptions: function() - { - var list = WebInspector.HeapSnapshotProfileType.snapshots; - // We're assuming that snapshots can only be added. - if (this.baseSelectElement.length === list.length) - return; - - for (var i = this.baseSelectElement.length, n = list.length; i < n; ++i) { - var baseOption = document.createElement("option"); - baseOption.label = WebInspector.UIString("Compared to %s", list[i].title); - this.baseSelectElement.appendChild(baseOption); - } - }, - - _updatePercentButton: function() - { - if (this._isShowingAsPercent) { - this.percentButton.title = WebInspector.UIString("Show absolute counts and sizes."); - this.percentButton.toggled = true; - } else { - this.percentButton.title = WebInspector.UIString("Show counts and sizes as percentages."); - this.percentButton.toggled = false; - } - }, - - _updateSummaryGraph: function() - { - this.countsSummaryBar.calculator.showAsPercent = this._isShowingAsPercent; - this.countsSummaryBar.update(this.profile.lowlevels); - - this.sizesSummaryBar.calculator.showAsPercent = this._isShowingAsPercent; - this.sizesSummaryBar.update(this.profile.lowlevels); - } -}; - -WebInspector.HeapSnapshotView.prototype.__proto__ = WebInspector.View.prototype; - -WebInspector.HeapSnapshotView.SearchHelper = { - // In comparators, we assume that a value from a node is passed as the first parameter. - operations: { LESS: function (a, b) { return a !== null && a < b; }, - LESS_OR_EQUAL: function (a, b) { return a !== null && a <= b; }, - EQUAL: function (a, b) { return a !== null && a === b; }, - GREATER_OR_EQUAL: function (a, b) { return a !== null && a >= b; }, - GREATER: function (a, b) { return a !== null && a > b; } }, - - operationParsers: { LESS: /^<(\d+)/, - LESS_OR_EQUAL: /^<=(\d+)/, - GREATER_OR_EQUAL: /^>=(\d+)/, - GREATER: /^>(\d+)/ }, - - parseOperationAndNumber: function(query) - { - var operations = WebInspector.HeapSnapshotView.SearchHelper.operations; - var parsers = WebInspector.HeapSnapshotView.SearchHelper.operationParsers; - for (var operation in parsers) { - var match = query.match(parsers[operation]); - if (match !== null) - return [operations[operation], parseFloat(match[1])]; - } - return [operations.EQUAL, parseFloat(query)]; - }, - - percents: /%$/, - - megaBytes: /MB$/i, - - kiloBytes: /KB$/i, - - bytes: /B$/i -} - -WebInspector.HeapSummaryCalculator = function(lowLevelField) -{ - this.total = 1; - this.lowLevelField = lowLevelField; -} - -WebInspector.HeapSummaryCalculator.prototype = { - computeSummaryValues: function(lowLevels) - { - var highLevels = {data: 0, code: 0}; - this.total = 0; - for (var item in lowLevels) { - var highItem = this._highFromLow(item); - if (highItem) { - var value = lowLevels[item][this.lowLevelField]; - highLevels[highItem] += value; - this.total += value; - } - } - var result = {categoryValues: highLevels}; - if (!this.showAsPercent) - result.total = this.total; - return result; - }, - - formatValue: function(value) - { - if (this.showAsPercent) - return WebInspector.UIString("%.2f%%", value / this.total * 100.0); - else - return this._valueToString(value); - }, - - get showAsPercent() - { - return this._showAsPercent; - }, - - set showAsPercent(x) - { - this._showAsPercent = x; - } -} - -WebInspector.HeapSummaryCountCalculator = function() -{ - WebInspector.HeapSummaryCalculator.call(this, "count"); -} - -WebInspector.HeapSummaryCountCalculator.prototype = { - _highFromLow: function(type) { - if (type === "CODE_TYPE" || type === "SHARED_FUNCTION_INFO_TYPE" || type === "SCRIPT_TYPE") return "code"; - if (type === "STRING_TYPE" || type === "HEAP_NUMBER_TYPE" || type.match(/^JS_/)) return "data"; - return null; - }, - - _valueToString: function(value) { - return value.toString(); - } -} - -WebInspector.HeapSummaryCountCalculator.prototype.__proto__ = WebInspector.HeapSummaryCalculator.prototype; - -WebInspector.HeapSummarySizeCalculator = function() -{ - WebInspector.HeapSummaryCalculator.call(this, "size"); -} - -WebInspector.HeapSummarySizeCalculator.prototype = { - _highFromLow: function(type) { - if (type === "CODE_TYPE" || type === "SHARED_FUNCTION_INFO_TYPE" || type === "SCRIPT_TYPE") return "code"; - if (type === "STRING_TYPE" || type === "HEAP_NUMBER_TYPE" || type.match(/^JS_/) || type.match(/_ARRAY_TYPE$/)) return "data"; - return null; - }, - - _valueToString: Number.bytesToString -} - -WebInspector.HeapSummarySizeCalculator.prototype.__proto__ = WebInspector.HeapSummaryCalculator.prototype; - -WebInspector.HeapSnapshotSidebarTreeElement = function(snapshot) -{ - this.profile = snapshot; - - WebInspector.SidebarTreeElement.call(this, "heap-snapshot-sidebar-tree-item", "", "", snapshot, false); - - this.refreshTitles(); -}; - -WebInspector.HeapSnapshotSidebarTreeElement.prototype = { - get mainTitle() - { - if (this._mainTitle) - return this._mainTitle; - return this.profile.title; - }, - - set mainTitle(x) - { - this._mainTitle = x; - this.refreshTitles(); - } -}; - -WebInspector.HeapSnapshotSidebarTreeElement.prototype.__proto__ = WebInspector.ProfileSidebarTreeElement.prototype; - -WebInspector.HeapSnapshotDataGridNodeWithRetainers = function(owningTree) -{ - this.tree = owningTree; - - WebInspector.DataGridNode.call(this, null, this._hasRetainers); - - this.addEventListener("populate", this._populate, this); -}; - -WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype = { - isEmptySet: function(set) - { - for (var x in set) - return false; - return true; - }, - - get _hasRetainers() - { - return !this.isEmptySet(this.retainers); - }, - - get _parent() - { - // For top-level nodes, return owning tree as a parent, not data grid. - return this.parent !== this.dataGrid ? this.parent : this.tree; - }, - - _populate: function(event) - { - var self = this; - this.produceDiff(this.baseRetainers, this.retainers, function(baseItem, snapshotItem) { - self.appendChild(new WebInspector.HeapSnapshotDataGridRetainerNode(self.snapshotView, baseItem, snapshotItem, self.tree)); - }); - - if (this._parent) { - var currentComparator = this._parent.lastComparator; - if (currentComparator) - this.sort(currentComparator, true); - } - - this.removeEventListener("populate", this._populate, this); - }, - - produceDiff: function(baseEntries, currentEntries, callback) - { - for (var item in currentEntries) - callback(baseEntries[item], currentEntries[item]); - - for (item in baseEntries) { - if (!(item in currentEntries)) - callback(baseEntries[item], null); - } - }, - - sort: function(comparator, force) { - if (!force && this.lastComparator === comparator) - return; - - this.children.sort(comparator); - var childCount = this.children.length; - for (var childIndex = 0; childIndex < childCount; ++childIndex) - this.children[childIndex]._recalculateSiblings(childIndex); - for (var i = 0; i < this.children.length; ++i) { - var child = this.children[i]; - if (!force && (!child.expanded || child.lastComparator === comparator)) - continue; - child.sort(comparator, force); - } - this.lastComparator = comparator; - }, - - signForDelta: function(delta) { - if (delta === 0) - return ""; - if (delta > 0) - return "+"; - else - // Math minus sign, same width as plus. - return "\u2212"; - }, - - showDeltaAsPercent: function(value) { - if (value === Number.POSITIVE_INFINITY) - return WebInspector.UIString("new"); - else if (value === Number.NEGATIVE_INFINITY) - return WebInspector.UIString("deleted"); - if (value > 1000.0) - return WebInspector.UIString("%s >1000%%", this.signForDelta(value)); - return WebInspector.UIString("%s%.2f%%", this.signForDelta(value), Math.abs(value)); - }, - - getTotalCount: function() { - if (!this._count) { - this._count = 0; - for (var i = 0, n = this.children.length; i < n; ++i) - this._count += this.children[i].count; - } - return this._count; - }, - - getTotalSize: function() { - if (!this._size) { - this._size = 0; - for (var i = 0, n = this.children.length; i < n; ++i) - this._size += this.children[i].size; - } - return this._size; - }, - - get countPercent() - { - return this.count / this._parent.getTotalCount() * 100.0; - }, - - get sizePercent() - { - return this.size / this._parent.getTotalSize() * 100.0; - }, - - get countDeltaPercent() - { - if (this.baseCount > 0) { - if (this.count > 0) - return this.countDelta / this.baseCount * 100.0; - else - return Number.NEGATIVE_INFINITY; - } else - return Number.POSITIVE_INFINITY; - }, - - get sizeDeltaPercent() - { - if (this.baseSize > 0) { - if (this.size > 0) - return this.sizeDelta / this.baseSize * 100.0; - else - return Number.NEGATIVE_INFINITY; - } else - return Number.POSITIVE_INFINITY; - }, - - get data() - { - var data = {}; - - data["cons"] = this.constructorName; - - if (this.snapshotView.showCountAsPercent) - data["count"] = WebInspector.UIString("%.2f%%", this.countPercent); - else - data["count"] = this.count; - - if (this.size !== null) { - if (this.snapshotView.showSizeAsPercent) - data["size"] = WebInspector.UIString("%.2f%%", this.sizePercent); - else - data["size"] = Number.bytesToString(this.size); - } else - data["size"] = ""; - - if (this.snapshotView.showCountDeltaAsPercent) - data["countDelta"] = this.showDeltaAsPercent(this.countDeltaPercent); - else - data["countDelta"] = WebInspector.UIString("%s%d", this.signForDelta(this.countDelta), Math.abs(this.countDelta)); - - if (this.sizeDelta !== null) { - if (this.snapshotView.showSizeDeltaAsPercent) - data["sizeDelta"] = this.showDeltaAsPercent(this.sizeDeltaPercent); - else - data["sizeDelta"] = WebInspector.UIString("%s%s", this.signForDelta(this.sizeDelta), Number.bytesToString(Math.abs(this.sizeDelta))); - } else - data["sizeDelta"] = ""; - - return data; - }, - - createCell: function(columnIdentifier) - { - var cell = WebInspector.DataGridNode.prototype.createCell.call(this, columnIdentifier); - - if ((columnIdentifier === "cons" && this._searchMatchedConsColumn) || - (columnIdentifier === "count" && this._searchMatchedCountColumn) || - (columnIdentifier === "size" && this._searchMatchedSizeColumn) || - (columnIdentifier === "countDelta" && this._searchMatchedCountDeltaColumn) || - (columnIdentifier === "sizeDelta" && this._searchMatchedSizeDeltaColumn)) - cell.addStyleClass("highlight"); - - return cell; - } -}; - -WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.__proto__ = WebInspector.DataGridNode.prototype; - -WebInspector.HeapSnapshotDataGridNode = function(snapshotView, baseEntry, snapshotEntry, owningTree) -{ - this.snapshotView = snapshotView; - - if (!snapshotEntry) - snapshotEntry = { cons: baseEntry.cons, count: 0, size: 0, retainers: {} }; - this.constructorName = snapshotEntry.cons; - this.count = snapshotEntry.count; - this.size = snapshotEntry.size; - this.retainers = snapshotEntry.retainers; - - if (!baseEntry) - baseEntry = { count: 0, size: 0, retainers: {} }; - this.baseCount = baseEntry.count; - this.countDelta = this.count - this.baseCount; - this.baseSize = baseEntry.size; - this.sizeDelta = this.size - this.baseSize; - this.baseRetainers = baseEntry.retainers; - - WebInspector.HeapSnapshotDataGridNodeWithRetainers.call(this, owningTree); -}; - -WebInspector.HeapSnapshotDataGridNode.prototype.__proto__ = WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype; - -WebInspector.HeapSnapshotDataGridList = function(snapshotView, baseEntries, snapshotEntries) -{ - this.tree = this; - this.snapshotView = snapshotView; - this.children = []; - this.lastComparator = null; - this.populateChildren(baseEntries, snapshotEntries); -}; - -WebInspector.HeapSnapshotDataGridList.prototype = { - appendChild: function(child) - { - this.insertChild(child, this.children.length); - }, - - insertChild: function(child, index) - { - this.children.splice(index, 0, child); - }, - - removeChildren: function() - { - this.children = []; - }, - - populateChildren: function(baseEntries, snapshotEntries) - { - var self = this; - this.produceDiff(baseEntries, snapshotEntries, function(baseItem, snapshotItem) { - self.appendChild(new WebInspector.HeapSnapshotDataGridNode(self.snapshotView, baseItem, snapshotItem, self)); - }); - }, - - produceDiff: WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.produceDiff, - sort: WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.sort, - getTotalCount: WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.getTotalCount, - getTotalSize: WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.getTotalSize -}; - -WebInspector.HeapSnapshotDataGridList.propertyComparators = [{}, {}]; - -WebInspector.HeapSnapshotDataGridList.propertyComparator = function(property, property2, isAscending) -{ - var propertyHash = property + "#" + property2; - var comparator = this.propertyComparators[(isAscending ? 1 : 0)][propertyHash]; - if (!comparator) { - comparator = function(lhs, rhs) { - var l = lhs[property], r = rhs[property]; - if ((l === null || r === null) && property2 !== null) - l = lhs[property2], r = rhs[property2]; - var result = l < r ? -1 : (l > r ? 1 : 0); - return isAscending ? result : -result; - }; - this.propertyComparators[(isAscending ? 1 : 0)][propertyHash] = comparator; - } - return comparator; -}; - -WebInspector.HeapSnapshotDataGridRetainerNode = function(snapshotView, baseEntry, snapshotEntry, owningTree) -{ - this.snapshotView = snapshotView; - - if (!snapshotEntry) - snapshotEntry = { cons: baseEntry.cons, count: 0, clusters: {} }; - this.constructorName = snapshotEntry.cons; - this.count = snapshotEntry.count; - this.retainers = this._calculateRetainers(this.snapshotView.profile, snapshotEntry.clusters); - - if (!baseEntry) - baseEntry = { count: 0, clusters: {} }; - this.baseCount = baseEntry.count; - this.countDelta = this.count - this.baseCount; - this.baseRetainers = this._calculateRetainers(this.snapshotView.baseSnapshot, baseEntry.clusters); - - this.size = null; - this.sizeDelta = null; - - WebInspector.HeapSnapshotDataGridNodeWithRetainers.call(this, owningTree); -} - -WebInspector.HeapSnapshotDataGridRetainerNode.prototype = { - get sizePercent() - { - return null; - }, - - get sizeDeltaPercent() - { - return null; - }, - - _calculateRetainers: function(snapshot, clusters) { - var retainers = {}; - if (this.isEmptySet(clusters)) { - if (this.constructorName in snapshot.entries) - return snapshot.entries[this.constructorName].retainers; - } else { - // In case when an entry is retained by clusters, we need to gather up the list - // of retainers by merging retainers of every cluster. - // E.g. having such a tree: - // A - // Object:1 10 - // X 3 - // Y 4 - // Object:2 5 - // X 6 - // - // will result in a following retainers list: X 9, Y 4. - for (var clusterName in clusters) { - if (clusterName in snapshot.clusters) { - var clusterRetainers = snapshot.clusters[clusterName].retainers; - for (var clusterRetainer in clusterRetainers) { - var clusterRetainerEntry = clusterRetainers[clusterRetainer]; - if (!(clusterRetainer in retainers)) - retainers[clusterRetainer] = { cons: clusterRetainerEntry.cons, count: 0, clusters: {} }; - retainers[clusterRetainer].count += clusterRetainerEntry.count; - for (var clusterRetainerCluster in clusterRetainerEntry.clusters) - retainers[clusterRetainer].clusters[clusterRetainerCluster] = true; - } - } - } - } - return retainers; - } -}; - -WebInspector.HeapSnapshotDataGridRetainerNode.prototype.__proto__ = WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype; - - -WebInspector.HeapSnapshotProfileType = function() -{ - WebInspector.ProfileType.call(this, WebInspector.HeapSnapshotProfileType.TypeId, WebInspector.UIString("HEAP SNAPSHOTS")); -} - -WebInspector.HeapSnapshotProfileType.TypeId = "HEAP"; - -WebInspector.HeapSnapshotProfileType.snapshots = []; - -WebInspector.HeapSnapshotProfileType.prototype = { - get buttonTooltip() - { - return WebInspector.UIString("Take heap snapshot."); - }, - - get buttonStyle() - { - return "heap-snapshot-status-bar-item status-bar-item"; - }, - - buttonClicked: function() - { - InspectorBackend.takeHeapSnapshot(); - }, - - get welcomeMessage() - { - return WebInspector.UIString("Get a heap snapshot by pressing<br>the %s button on the status bar."); - }, - - createSidebarTreeElementForProfile: function(profile) - { - var element = new WebInspector.HeapSnapshotSidebarTreeElement(profile); - element.small = false; - return element; - }, - - createView: function(profile) - { - return new WebInspector.HeapSnapshotView(WebInspector.panels.profiles, profile); - } -} - -WebInspector.HeapSnapshotProfileType.prototype.__proto__ = WebInspector.ProfileType.prototype; - - -(function() { - var originalCreatePanels = WebInspector._createPanels; - WebInspector._createPanels = function() { - originalCreatePanels.apply(this, arguments); - if (WebInspector.panels.profiles) - WebInspector.panels.profiles.registerProfileType(new WebInspector.HeapSnapshotProfileType()); - } -})(); |