Index: third_party/WebKit/Source/devtools/front_end/profiler/BottomUpProfileDataGrid.js |
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/BottomUpProfileDataGrid.js b/third_party/WebKit/Source/devtools/front_end/profiler/BottomUpProfileDataGrid.js |
index 103678a29c3a852419184a4c3417e4ce0efcb899..80a11c3c851608a13cc0c1f524137d3a0a26facc 100644 |
--- a/third_party/WebKit/Source/devtools/front_end/profiler/BottomUpProfileDataGrid.js |
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/BottomUpProfileDataGrid.js |
@@ -22,7 +22,6 @@ |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
- |
// Bottom Up Profiling shows the entire callstack backwards: |
// The root node is a representation of each individual function called, and each child of that node represents |
// a reverse-callstack showing how many of those calls came from it. So, unlike top-down, the statistics in |
@@ -30,159 +29,152 @@ |
// because a root node can represent itself AND an ancestor. |
/** |
- * @constructor |
- * @extends {WebInspector.ProfileDataGridNode} |
- * @param {!WebInspector.ProfileNode} profileNode |
- * @param {!WebInspector.TopDownProfileDataGridTree} owningTree |
+ * @unrestricted |
*/ |
-WebInspector.BottomUpProfileDataGridNode = function(profileNode, owningTree) |
-{ |
- WebInspector.ProfileDataGridNode.call(this, profileNode, owningTree, !!profileNode.parent && !!profileNode.parent.parent); |
+WebInspector.BottomUpProfileDataGridNode = class extends WebInspector.ProfileDataGridNode { |
+ /** |
+ * @param {!WebInspector.ProfileNode} profileNode |
+ * @param {!WebInspector.TopDownProfileDataGridTree} owningTree |
+ */ |
+ constructor(profileNode, owningTree) { |
+ super(profileNode, owningTree, !!profileNode.parent && !!profileNode.parent.parent); |
this._remainingNodeInfos = []; |
-}; |
+ } |
-WebInspector.BottomUpProfileDataGridNode.prototype = { |
- /** |
- * @param {!WebInspector.ProfileDataGridNode} profileDataGridNode |
- */ |
- _takePropertiesFromProfileDataGridNode: function(profileDataGridNode) |
- { |
- this.save(); |
- this.self = profileDataGridNode.self; |
- this.total = profileDataGridNode.total; |
- }, |
- |
- /** |
- * When focusing, we keep just the members of the callstack. |
- * @param {!WebInspector.ProfileDataGridNode} child |
- */ |
- _keepOnlyChild: function(child) |
- { |
- this.save(); |
- |
- this.removeChildren(); |
- this.appendChild(child); |
- }, |
- |
- /** |
- * @param {string} aCallUID |
- */ |
- _exclude: function(aCallUID) |
- { |
- if (this._remainingNodeInfos) |
- this.populate(); |
- |
- this.save(); |
- |
- var children = this.children; |
- var index = this.children.length; |
- |
- while (index--) |
- children[index]._exclude(aCallUID); |
- |
- var child = this.childrenByCallUID.get(aCallUID); |
- |
- if (child) |
- this.merge(child, true); |
- }, |
- |
- /** |
- * @override |
- */ |
- restore: function() |
- { |
- WebInspector.ProfileDataGridNode.prototype.restore.call(this); |
- |
- if (!this.children.length) |
- this.hasChildren = this._willHaveChildren(this.profileNode); |
- }, |
- |
- /** |
- * @override |
- * @param {!WebInspector.ProfileDataGridNode} child |
- * @param {boolean} shouldAbsorb |
- */ |
- merge: function(child, shouldAbsorb) |
- { |
- this.self -= child.self; |
- WebInspector.ProfileDataGridNode.prototype.merge.call(this, child, shouldAbsorb); |
- }, |
- |
- /** |
- * @override |
- */ |
- populateChildren: function() |
- { |
- WebInspector.BottomUpProfileDataGridNode._sharedPopulate(this); |
- }, |
- |
- _willHaveChildren: function(profileNode) |
- { |
- // In bottom up mode, our parents are our children since we display an inverted tree. |
- // However, we don't want to show the very top parent since it is redundant. |
- return !!(profileNode.parent && profileNode.parent.parent); |
- }, |
- |
- __proto__: WebInspector.ProfileDataGridNode.prototype |
-}; |
- |
-/** |
- * @param {!WebInspector.BottomUpProfileDataGridNode|!WebInspector.BottomUpProfileDataGridTree} container |
- */ |
-WebInspector.BottomUpProfileDataGridNode._sharedPopulate = function(container) |
-{ |
+ /** |
+ * @param {!WebInspector.BottomUpProfileDataGridNode|!WebInspector.BottomUpProfileDataGridTree} container |
+ */ |
+ static _sharedPopulate(container) { |
var remainingNodeInfos = container._remainingNodeInfos; |
var count = remainingNodeInfos.length; |
for (var index = 0; index < count; ++index) { |
- var nodeInfo = remainingNodeInfos[index]; |
- var ancestor = nodeInfo.ancestor; |
- var focusNode = nodeInfo.focusNode; |
- var child = container.findChild(ancestor); |
- |
- // If we already have this child, then merge the data together. |
- if (child) { |
- var totalAccountedFor = nodeInfo.totalAccountedFor; |
- |
- child.self += focusNode.self; |
- |
- if (!totalAccountedFor) |
- child.total += focusNode.total; |
- } else { |
- // If not, add it as a true ancestor. |
- // In heavy mode, we take our visual identity from ancestor node... |
- child = new WebInspector.BottomUpProfileDataGridNode(ancestor, /** @type {!WebInspector.TopDownProfileDataGridTree} */ (container.tree)); |
- |
- if (ancestor !== focusNode) { |
- // But the actual statistics from the "root" node (bottom of the callstack). |
- child.self = focusNode.self; |
- child.total = focusNode.total; |
- } |
- |
- container.appendChild(child); |
+ var nodeInfo = remainingNodeInfos[index]; |
+ var ancestor = nodeInfo.ancestor; |
+ var focusNode = nodeInfo.focusNode; |
+ var child = container.findChild(ancestor); |
+ |
+ // If we already have this child, then merge the data together. |
+ if (child) { |
+ var totalAccountedFor = nodeInfo.totalAccountedFor; |
+ |
+ child.self += focusNode.self; |
+ |
+ if (!totalAccountedFor) |
+ child.total += focusNode.total; |
+ } else { |
+ // If not, add it as a true ancestor. |
+ // In heavy mode, we take our visual identity from ancestor node... |
+ child = new WebInspector.BottomUpProfileDataGridNode( |
+ ancestor, /** @type {!WebInspector.TopDownProfileDataGridTree} */ (container.tree)); |
+ |
+ if (ancestor !== focusNode) { |
+ // But the actual statistics from the "root" node (bottom of the callstack). |
+ child.self = focusNode.self; |
+ child.total = focusNode.total; |
} |
- var parent = ancestor.parent; |
- if (parent && parent.parent) { |
- nodeInfo.ancestor = parent; |
- child._remainingNodeInfos.push(nodeInfo); |
- } |
+ container.appendChild(child); |
+ } |
+ |
+ var parent = ancestor.parent; |
+ if (parent && parent.parent) { |
+ nodeInfo.ancestor = parent; |
+ child._remainingNodeInfos.push(nodeInfo); |
+ } |
} |
delete container._remainingNodeInfos; |
+ } |
+ |
+ /** |
+ * @param {!WebInspector.ProfileDataGridNode} profileDataGridNode |
+ */ |
+ _takePropertiesFromProfileDataGridNode(profileDataGridNode) { |
+ this.save(); |
+ this.self = profileDataGridNode.self; |
+ this.total = profileDataGridNode.total; |
+ } |
+ |
+ /** |
+ * When focusing, we keep just the members of the callstack. |
+ * @param {!WebInspector.ProfileDataGridNode} child |
+ */ |
+ _keepOnlyChild(child) { |
+ this.save(); |
+ |
+ this.removeChildren(); |
+ this.appendChild(child); |
+ } |
+ |
+ /** |
+ * @param {string} aCallUID |
+ */ |
+ _exclude(aCallUID) { |
+ if (this._remainingNodeInfos) |
+ this.populate(); |
+ |
+ this.save(); |
+ |
+ var children = this.children; |
+ var index = this.children.length; |
+ |
+ while (index--) |
+ children[index]._exclude(aCallUID); |
+ |
+ var child = this.childrenByCallUID.get(aCallUID); |
+ |
+ if (child) |
+ this.merge(child, true); |
+ } |
+ |
+ /** |
+ * @override |
+ */ |
+ restore() { |
+ super.restore(); |
+ |
+ if (!this.children.length) |
+ this.hasChildren = this._willHaveChildren(this.profileNode); |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {!WebInspector.ProfileDataGridNode} child |
+ * @param {boolean} shouldAbsorb |
+ */ |
+ merge(child, shouldAbsorb) { |
+ this.self -= child.self; |
+ super.merge(child, shouldAbsorb); |
+ } |
+ |
+ /** |
+ * @override |
+ */ |
+ populateChildren() { |
+ WebInspector.BottomUpProfileDataGridNode._sharedPopulate(this); |
+ } |
+ |
+ _willHaveChildren(profileNode) { |
+ // In bottom up mode, our parents are our children since we display an inverted tree. |
+ // However, we don't want to show the very top parent since it is redundant. |
+ return !!(profileNode.parent && profileNode.parent.parent); |
+ } |
}; |
+ |
/** |
- * @constructor |
- * @extends {WebInspector.ProfileDataGridTree} |
- * @param {!WebInspector.ProfileDataGridNode.Formatter} formatter |
- * @param {!WebInspector.SearchableView} searchableView |
- * @param {!WebInspector.ProfileNode} rootProfileNode |
- * @param {number} total |
+ * @unrestricted |
*/ |
-WebInspector.BottomUpProfileDataGridTree = function(formatter, searchableView, rootProfileNode, total) |
-{ |
- WebInspector.ProfileDataGridTree.call(this, formatter, searchableView, total); |
+WebInspector.BottomUpProfileDataGridTree = class extends WebInspector.ProfileDataGridTree { |
+ /** |
+ * @param {!WebInspector.ProfileDataGridNode.Formatter} formatter |
+ * @param {!WebInspector.SearchableView} searchableView |
+ * @param {!WebInspector.ProfileNode} rootProfileNode |
+ * @param {number} total |
+ */ |
+ constructor(formatter, searchableView, rootProfileNode, total) { |
+ super(formatter, searchableView, total); |
// Iterate each node in pre-order. |
var profileNodeUIDs = 0; |
@@ -193,142 +185,136 @@ WebInspector.BottomUpProfileDataGridTree = function(formatter, searchableView, r |
this._remainingNodeInfos = []; |
for (var profileNodeGroupIndex = 0; profileNodeGroupIndex < profileNodeGroups.length; ++profileNodeGroupIndex) { |
- var parentProfileNodes = profileNodeGroups[profileNodeGroupIndex]; |
- var profileNodes = profileNodeGroups[++profileNodeGroupIndex]; |
- var count = profileNodes.length; |
- |
- for (var index = 0; index < count; ++index) { |
- var profileNode = profileNodes[index]; |
- |
- if (!profileNode.UID) |
- profileNode.UID = ++profileNodeUIDs; |
- |
- if (profileNode.parent) { |
- // The total time of this ancestor is accounted for if we're in any form of recursive cycle. |
- var visitedNodes = visitedProfileNodesForCallUID.get(profileNode.callUID); |
- var totalAccountedFor = false; |
- |
- if (!visitedNodes) { |
- visitedNodes = new Set(); |
- visitedProfileNodesForCallUID.set(profileNode.callUID, visitedNodes); |
- } else { |
- // The total time for this node has already been accounted for iff one of it's parents has already been visited. |
- // We can do this check in this style because we are traversing the tree in pre-order. |
- var parentCount = parentProfileNodes.length; |
- for (var parentIndex = 0; parentIndex < parentCount; ++parentIndex) { |
- if (visitedNodes.has(parentProfileNodes[parentIndex].UID)) { |
- totalAccountedFor = true; |
- break; |
- } |
- } |
- } |
- |
- visitedNodes.add(profileNode.UID); |
- |
- this._remainingNodeInfos.push({ ancestor: profileNode, focusNode: profileNode, totalAccountedFor: totalAccountedFor }); |
+ var parentProfileNodes = profileNodeGroups[profileNodeGroupIndex]; |
+ var profileNodes = profileNodeGroups[++profileNodeGroupIndex]; |
+ var count = profileNodes.length; |
+ |
+ for (var index = 0; index < count; ++index) { |
+ var profileNode = profileNodes[index]; |
+ |
+ if (!profileNode.UID) |
+ profileNode.UID = ++profileNodeUIDs; |
+ |
+ if (profileNode.parent) { |
+ // The total time of this ancestor is accounted for if we're in any form of recursive cycle. |
+ var visitedNodes = visitedProfileNodesForCallUID.get(profileNode.callUID); |
+ var totalAccountedFor = false; |
+ |
+ if (!visitedNodes) { |
+ visitedNodes = new Set(); |
+ visitedProfileNodesForCallUID.set(profileNode.callUID, visitedNodes); |
+ } else { |
+ // The total time for this node has already been accounted for iff one of it's parents has already been visited. |
+ // We can do this check in this style because we are traversing the tree in pre-order. |
+ var parentCount = parentProfileNodes.length; |
+ for (var parentIndex = 0; parentIndex < parentCount; ++parentIndex) { |
+ if (visitedNodes.has(parentProfileNodes[parentIndex].UID)) { |
+ totalAccountedFor = true; |
+ break; |
+ } |
} |
+ } |
- var children = profileNode.children; |
- if (children.length) { |
- profileNodeGroups.push(parentProfileNodes.concat([profileNode])); |
- profileNodeGroups.push(children); |
- } |
+ visitedNodes.add(profileNode.UID); |
+ |
+ this._remainingNodeInfos.push( |
+ {ancestor: profileNode, focusNode: profileNode, totalAccountedFor: totalAccountedFor}); |
+ } |
+ |
+ var children = profileNode.children; |
+ if (children.length) { |
+ profileNodeGroups.push(parentProfileNodes.concat([profileNode])); |
+ profileNodeGroups.push(children); |
} |
+ } |
} |
// Populate the top level nodes. |
WebInspector.ProfileDataGridNode.populate(this); |
return this; |
-}; |
+ } |
-WebInspector.BottomUpProfileDataGridTree.prototype = { |
- /** |
- * When focusing, we keep the entire callstack up to this ancestor. |
- * @param {!WebInspector.ProfileDataGridNode} profileDataGridNode |
- */ |
- focus: function(profileDataGridNode) |
- { |
- if (!profileDataGridNode) |
- return; |
+ /** |
+ * When focusing, we keep the entire callstack up to this ancestor. |
+ * @param {!WebInspector.ProfileDataGridNode} profileDataGridNode |
+ */ |
+ focus(profileDataGridNode) { |
+ if (!profileDataGridNode) |
+ return; |
- this.save(); |
+ this.save(); |
- var currentNode = profileDataGridNode; |
- var focusNode = profileDataGridNode; |
+ var currentNode = profileDataGridNode; |
+ var focusNode = profileDataGridNode; |
- while (currentNode.parent && (currentNode instanceof WebInspector.ProfileDataGridNode)) { |
- currentNode._takePropertiesFromProfileDataGridNode(profileDataGridNode); |
+ while (currentNode.parent && (currentNode instanceof WebInspector.ProfileDataGridNode)) { |
+ currentNode._takePropertiesFromProfileDataGridNode(profileDataGridNode); |
- focusNode = currentNode; |
- currentNode = currentNode.parent; |
+ focusNode = currentNode; |
+ currentNode = currentNode.parent; |
- if (currentNode instanceof WebInspector.ProfileDataGridNode) |
- currentNode._keepOnlyChild(focusNode); |
- } |
+ if (currentNode instanceof WebInspector.ProfileDataGridNode) |
+ currentNode._keepOnlyChild(focusNode); |
+ } |
- this.children = [focusNode]; |
- this.total = profileDataGridNode.total; |
- }, |
- |
- /** |
- * @param {!WebInspector.ProfileDataGridNode} profileDataGridNode |
- */ |
- exclude: function(profileDataGridNode) |
- { |
- if (!profileDataGridNode) |
- return; |
- |
- this.save(); |
- |
- var excludedCallUID = profileDataGridNode.callUID; |
- var excludedTopLevelChild = this.childrenByCallUID.get(excludedCallUID); |
- |
- // If we have a top level node that is excluded, get rid of it completely (not keeping children), |
- // since bottom up data relies entirely on the root node. |
- if (excludedTopLevelChild) |
- this.children.remove(excludedTopLevelChild); |
- |
- var children = this.children; |
- var count = children.length; |
- |
- for (var index = 0; index < count; ++index) |
- children[index]._exclude(excludedCallUID); |
- |
- if (this.lastComparator) |
- this.sort(this.lastComparator, true); |
- }, |
- |
- /** |
- * @override |
- * @param {!WebInspector.SearchableView.SearchConfig} searchConfig |
- * @param {boolean} shouldJump |
- * @param {boolean=} jumpBackwards |
- */ |
- performSearch: function(searchConfig, shouldJump, jumpBackwards) |
- { |
- this.searchCanceled(); |
- var matchesQuery = this._matchFunction(searchConfig); |
- if (!matchesQuery) |
- return; |
- |
- this._searchResults = []; |
- for (var current = this.children[0]; current; current = current.traverseNextNode(true, null, true)) { |
- if (matchesQuery(current)) |
- this._searchResults.push({ profileNode: current }); |
- } |
- this._searchResultIndex = jumpBackwards ? 0 : this._searchResults.length - 1; |
- this._searchableView.updateSearchMatchesCount(this._searchResults.length); |
- this._searchableView.updateCurrentMatchIndex(this._searchResultIndex); |
- }, |
- |
- /** |
- * @override |
- */ |
- populateChildren: function() |
- { |
- WebInspector.BottomUpProfileDataGridNode._sharedPopulate(this); |
- }, |
- |
- __proto__: WebInspector.ProfileDataGridTree.prototype |
+ this.children = [focusNode]; |
+ this.total = profileDataGridNode.total; |
+ } |
+ |
+ /** |
+ * @param {!WebInspector.ProfileDataGridNode} profileDataGridNode |
+ */ |
+ exclude(profileDataGridNode) { |
+ if (!profileDataGridNode) |
+ return; |
+ |
+ this.save(); |
+ |
+ var excludedCallUID = profileDataGridNode.callUID; |
+ var excludedTopLevelChild = this.childrenByCallUID.get(excludedCallUID); |
+ |
+ // If we have a top level node that is excluded, get rid of it completely (not keeping children), |
+ // since bottom up data relies entirely on the root node. |
+ if (excludedTopLevelChild) |
+ this.children.remove(excludedTopLevelChild); |
+ |
+ var children = this.children; |
+ var count = children.length; |
+ |
+ for (var index = 0; index < count; ++index) |
+ children[index]._exclude(excludedCallUID); |
+ |
+ if (this.lastComparator) |
+ this.sort(this.lastComparator, true); |
+ } |
+ |
+ /** |
+ * @override |
+ * @param {!WebInspector.SearchableView.SearchConfig} searchConfig |
+ * @param {boolean} shouldJump |
+ * @param {boolean=} jumpBackwards |
+ */ |
+ performSearch(searchConfig, shouldJump, jumpBackwards) { |
+ this.searchCanceled(); |
+ var matchesQuery = this._matchFunction(searchConfig); |
+ if (!matchesQuery) |
+ return; |
+ |
+ this._searchResults = []; |
+ for (var current = this.children[0]; current; current = current.traverseNextNode(true, null, true)) { |
+ if (matchesQuery(current)) |
+ this._searchResults.push({profileNode: current}); |
+ } |
+ this._searchResultIndex = jumpBackwards ? 0 : this._searchResults.length - 1; |
+ this._searchableView.updateSearchMatchesCount(this._searchResults.length); |
+ this._searchableView.updateCurrentMatchIndex(this._searchResultIndex); |
+ } |
+ |
+ /** |
+ * @override |
+ */ |
+ populateChildren() { |
+ WebInspector.BottomUpProfileDataGridNode._sharedPopulate(this); |
+ } |
}; |