2 * Copyright (C) 2011 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 WebInspector.HeapSnapshotGridNode = function(tree, hasChildren)
33 WebInspector.DataGridNode.call(this, null, hasChildren);
34 this._defaultPopulateCount = tree._defaultPopulateCount;
35 this._provider = null;
36 this.addEventListener("populate", this._populate, this);
39 WebInspector.HeapSnapshotGridNode.prototype = {
40 createCell: function(columnIdentifier)
42 var cell = WebInspector.DataGridNode.prototype.createCell.call(this, columnIdentifier);
43 if (this._searchMatched)
44 cell.addStyleClass("highlight");
51 this._provider.dispose();
52 for (var node = this.children[0]; node; node = node.traverseNextNode(true, this, true))
57 hasHoverMessage: false,
59 queryObjectContent: function(callback)
63 _populate: function(event)
65 this.removeEventListener("populate", this._populate, this);
66 function sorted(ignored)
68 this.populateChildren();
70 this._provider.sortAndRewind(this.comparator(), sorted.bind(this));
73 populateChildren: function(provider, howMany, atIndex, afterPopulate, suppressNotifyAboutCompletion)
75 if (!howMany && provider) {
76 howMany = provider.instanceCount;
77 provider.instanceCount = 0;
79 provider = provider || this._provider;
80 if (!("instanceCount" in provider))
81 provider.instanceCount = 0;
82 howMany = howMany || this._defaultPopulateCount;
83 atIndex = atIndex || this.children.length;
84 var haveSavedChildren = !!this._savedChildren;
85 if (haveSavedChildren) {
86 haveSavedChildren = false;
87 for (var c in this._savedChildren) {
88 haveSavedChildren = true;
94 function callSerialize()
98 part += this._defaultPopulateCount;
99 provider.serializeNextItems(this._defaultPopulateCount, childrenRetrieved.bind(this));
101 function childrenRetrieved(items)
103 var length = items.totalLength;
104 for (var i = 0, l = items.length; i < l; ++i) {
106 if (haveSavedChildren) {
107 var hash = this._childHashForEntity(item);
108 if (hash in this._savedChildren) {
109 this.insertChild(this._savedChildren[hash], atIndex++);
113 this.insertChild(this._createChildNode(item, provider, this), atIndex++);
115 provider.instanceCount += items.length;
116 if (part < howMany) {
117 setTimeout(callSerialize.bind(this), 0);
122 this.insertChild(new WebInspector.ShowMoreDataGridNode(this.populateChildren.bind(this, provider), this._defaultPopulateCount, length), atIndex++);
125 if (!suppressNotifyAboutCompletion) {
128 this.dispatchEventToListeners("populate complete");
130 setTimeout(notify.bind(this), 0);
133 setTimeout(callSerialize.bind(this), 0);
136 _saveChildren: function()
138 this._savedChildren = {};
139 for (var i = 0, childrenCount = this.children.length; i < childrenCount; ++i) {
140 var child = this.children[i];
142 this._savedChildren[this._childHashForNode(child)] = child;
148 this.dataGrid.recursiveSortingEnter();
149 function afterSort(sorted)
152 this.dataGrid.recursiveSortingLeave();
155 this._saveChildren();
156 this.removeChildren();
158 function afterPopulate()
160 for (var i = 0, l = this.children.length; i < l; ++i) {
161 var child = this.children[i];
165 this.dataGrid.recursiveSortingLeave();
167 this.populateChildren(this._provider, null, null, afterPopulate.bind(this));
169 this._provider.sortAndRewind(this.comparator(), afterSort.bind(this));
173 WebInspector.HeapSnapshotGridNode.prototype.__proto__ = WebInspector.DataGridNode.prototype;
175 WebInspector.HeapSnapshotGenericObjectNode = function(tree, node)
177 WebInspector.HeapSnapshotGridNode.call(this, tree, false);
178 this._name = node.name;
179 this._type = node.type;
180 this._shallowSize = node.selfSize;
181 this._retainedSize = node.retainedSize;
182 this.snapshotNodeId = node.id;
183 this.snapshotNodeIndex = node.nodeIndex;
184 if (this._type === "string")
185 this.hasHoverMessage = true;
186 else if (this._type === "object" && this.isDOMWindow(this._name)) {
187 this._name = this.shortenWindowURL(this._name, false);
188 this.hasHoverMessage = true;
189 } else if (node.flags & tree.snapshot.nodeFlags.canBeQueried)
190 this.hasHoverMessage = true;
191 if (node.flags & tree.snapshot.nodeFlags.detachedDOMTreeNode)
192 this.detachedDOMTreeNode = true;
195 WebInspector.HeapSnapshotGenericObjectNode.prototype = {
196 createCell: function(columnIdentifier)
198 var cell = columnIdentifier !== "object" ? WebInspector.DataGridNode.prototype.createCell.call(this, columnIdentifier) : this._createObjectCell();
199 if (this._searchMatched)
200 cell.addStyleClass("highlight");
204 _createObjectCell: function()
206 var cell = document.createElement("td");
207 cell.className = "object-column";
208 var div = document.createElement("div");
209 div.className = "source-code event-properties";
210 div.style.overflow = "visible";
211 var data = this.data["object"];
212 if (this._prefixObjectCell)
213 this._prefixObjectCell(div, data);
214 var valueSpan = document.createElement("span");
215 valueSpan.className = "value console-formatted-" + data.valueStyle;
216 valueSpan.textContent = data.value;
217 div.appendChild(valueSpan);
218 if (this._postfixObjectCell)
219 this._postfixObjectCell(div, data);
220 cell.appendChild(div);
221 cell.addStyleClass("disclosure");
223 cell.style.setProperty("padding-left", (this.depth * this.dataGrid.indentWidth) + "px");
229 return this._count / this.dataGrid.snapshot.nodeCount * 100.0;
234 var data = this._emptyData();
236 var value = this._name;
237 var valueStyle = "object";
238 switch (this._type) {
240 value = "\"" + value + "\"";
241 valueStyle = "string";
244 value = "/" + value + "/";
245 valueStyle = "string";
248 value = "function " + value + "()";
249 valueStyle = "function";
252 valueStyle = "number";
264 if (this.hasHoverMessage)
265 valueStyle += " highlight";
266 if (this.detachedDOMTreeNode)
267 valueStyle += " detached-dom-tree-node";
268 data["object"] = { valueStyle: valueStyle, value: value + ": @" + this.snapshotNodeId };
270 var view = this.dataGrid.snapshotView;
271 data["shallowSize"] = view.showShallowSizeAsPercent ? WebInspector.UIString("%.2f%%", this._shallowSizePercent) : Number.bytesToString(this._shallowSize);
272 data["retainedSize"] = view.showRetainedSizeAsPercent ? WebInspector.UIString("%.2f%%", this._retainedSizePercent) : Number.bytesToString(this._retainedSize);
274 return this._enhanceData ? this._enhanceData(data) : data;
277 queryObjectContent: function(callback)
279 if (this._type === "string")
280 callback(WebInspector.RemoteObject.fromPrimitiveValue(this._name));
282 function formatResult(error, object)
284 if (!error && object.type)
285 callback(WebInspector.RemoteObject.fromPayload(object), !!error);
287 callback(WebInspector.RemoteObject.fromPrimitiveValue(WebInspector.UIString("Not available")));
289 ProfilerAgent.getObjectByHeapObjectId(this.snapshotNodeId, formatResult);
293 get _retainedSizePercent()
295 return this._retainedSize / this.dataGrid.snapshot.totalSize * 100.0;
298 get _shallowSizePercent()
300 return this._shallowSize / this.dataGrid.snapshot.totalSize * 100.0;
303 _updateHasChildren: function()
305 function isEmptyCallback(isEmpty)
307 this.hasChildren = !isEmpty;
309 this._provider.isEmpty(isEmptyCallback.bind(this));
312 isDOMWindow: function(fullName)
314 return fullName.substr(0, 9) === "DOMWindow";
317 shortenWindowURL: function(fullName, hasObjectId)
319 var startPos = fullName.indexOf("/");
320 var endPos = hasObjectId ? fullName.indexOf("@") : fullName.length;
321 if (startPos !== -1 && endPos !== -1) {
322 var fullURL = fullName.substring(startPos + 1, endPos).trimLeft();
323 var url = fullURL.trimURL();
325 url = url.trimMiddle(40);
326 return fullName.substr(0, startPos + 2) + url + fullName.substr(endPos);
332 WebInspector.HeapSnapshotGenericObjectNode.prototype.__proto__ = WebInspector.HeapSnapshotGridNode.prototype;
334 WebInspector.HeapSnapshotObjectNode = function(tree, isFromBaseSnapshot, edge)
336 WebInspector.HeapSnapshotGenericObjectNode.call(this, tree, edge.node);
337 this._referenceName = edge.name;
338 this._referenceType = edge.type;
339 this._propertyAccessor = edge.propertyAccessor;
340 this._retainerNode = tree.showRetainingEdges;
341 this._isFromBaseSnapshot = isFromBaseSnapshot;
342 this._provider = this._createProvider(!isFromBaseSnapshot ? tree.snapshot : tree.baseSnapshot, edge.nodeIndex, tree);
343 this._updateHasChildren();
346 WebInspector.HeapSnapshotObjectNode.prototype = {
347 _createChildNode: function(item)
349 return new WebInspector.HeapSnapshotObjectNode(this.dataGrid, this._isFromBaseSnapshot, item);
352 _createProvider: function(snapshot, nodeIndex, tree)
354 var showHiddenData = WebInspector.settings.showHeapSnapshotObjectsHiddenProperties.get();
355 var filter = "function(edge) {" +
356 " return !edge.isInvisible" +
357 " && (" + showHiddenData + " || (!edge.isHidden && !edge.node.isHidden));" +
359 if (tree.showRetainingEdges)
360 return snapshot.createRetainingEdgesProvider(nodeIndex, filter);
362 return snapshot.createEdgesProvider(nodeIndex, filter);
365 _childHashForEntity: function(edge)
367 return edge.type + "#" + edge.name;
370 _childHashForNode: function(childNode)
372 return childNode._referenceType + "#" + childNode._referenceName;
375 comparator: function()
377 var sortAscending = this.dataGrid.sortOrder === "ascending";
378 var sortColumnIdentifier = this.dataGrid.sortColumnIdentifier;
380 object: ["!edgeName", sortAscending, "retainedSize", false],
381 count: ["!edgeName", true, "retainedSize", false],
382 shallowSize: ["selfSize", sortAscending, "!edgeName", true],
383 retainedSize: ["retainedSize", sortAscending, "!edgeName", true]
384 }[sortColumnIdentifier] || ["!edgeName", true, "retainedSize", false];
385 return WebInspector.HeapSnapshotFilteredOrderedIterator.prototype.createComparator(sortFields);
388 _emptyData: function()
390 return {count:"", addedCount: "", removedCount: "", countDelta:"", addedSize: "", removedSize: "", sizeDelta: ""};
393 _enhanceData: function(data)
395 var name = this._referenceName;
396 if (name === "") name = "(empty)";
397 var nameClass = "name";
398 switch (this._referenceType) {
400 nameClass = "console-formatted-number";
404 nameClass = "console-formatted-null";
407 data["object"].nameClass = nameClass;
408 data["object"].name = name;
412 _prefixObjectCell: function(div, data)
414 if (this._retainerNode) {
415 var prefixSpan = document.createElement("span");
416 prefixSpan.textContent = WebInspector.UIString("retained by ");
417 div.appendChild(prefixSpan);
421 var nameSpan = document.createElement("span");
422 nameSpan.className = data.nameClass;
423 nameSpan.textContent = data.name;
424 div.appendChild(nameSpan);
426 var separatorSpan = document.createElement("span");
427 separatorSpan.className = "separator";
428 separatorSpan.textContent = ": ";
429 div.appendChild(separatorSpan);
432 _postfixObjectCell: function(div, data)
434 if (this._retainerNode) {
435 var referenceTypeSpan = document.createElement("span");
436 referenceTypeSpan.className = "console-formatted-object";
437 referenceTypeSpan.textContent = this._propertyAccessor;
438 div.appendChild(referenceTypeSpan);
443 WebInspector.HeapSnapshotObjectNode.prototype.__proto__ = WebInspector.HeapSnapshotGenericObjectNode.prototype;
445 WebInspector.HeapSnapshotInstanceNode = function(tree, baseSnapshot, snapshot, node)
447 WebInspector.HeapSnapshotGenericObjectNode.call(this, tree, node);
448 this._isDeletedNode = !!baseSnapshot;
449 this._provider = this._createProvider(baseSnapshot || snapshot, node.nodeIndex);
450 this._updateHasChildren();
453 WebInspector.HeapSnapshotInstanceNode.prototype = {
454 _createChildNode: function(item)
456 return new WebInspector.HeapSnapshotObjectNode(this.dataGrid, this._isDeletedNode, item);
459 _createProvider: function(snapshot, nodeIndex)
461 var showHiddenData = WebInspector.DetailedHeapshotView.prototype.showHiddenData;
462 return snapshot.createEdgesProvider(
465 " return !edge.isInvisible" +
466 " && (" + showHiddenData + " || (!edge.isHidden && !edge.node.isHidden));" +
470 _childHashForEntity: function(edge)
472 return edge.type + "#" + edge.name;
475 _childHashForNode: function(childNode)
477 return childNode._referenceType + "#" + childNode._referenceName;
480 comparator: function()
482 var sortAscending = this.dataGrid.sortOrder === "ascending";
483 var sortColumnIdentifier = this.dataGrid.sortColumnIdentifier;
485 object: ["!edgeName", sortAscending, "retainedSize", false],
486 count: ["!edgeName", true, "retainedSize", false],
487 addedSize: ["selfSize", sortAscending, "!edgeName", true],
488 removedSize: ["selfSize", sortAscending, "!edgeName", true],
489 shallowSize: ["selfSize", sortAscending, "!edgeName", true],
490 retainedSize: ["retainedSize", sortAscending, "!edgeName", true]
491 }[sortColumnIdentifier] || ["!edgeName", true, "retainedSize", false];
492 return WebInspector.HeapSnapshotFilteredOrderedIterator.prototype.createComparator(sortFields);
495 _emptyData: function()
497 return {count:"", countDelta:"", sizeDelta: ""};
500 _enhanceData: function(data)
502 if (this._isDeletedNode) {
503 data["addedCount"] = "";
504 data["addedSize"] = "";
505 data["removedCount"] = "\u2022";
506 data["removedSize"] = Number.bytesToString(this._shallowSize);
508 data["addedCount"] = "\u2022";
509 data["addedSize"] = Number.bytesToString(this._shallowSize);
510 data["removedCount"] = "";
511 data["removedSize"] = "";
518 return this._isDeletedNode;
522 WebInspector.HeapSnapshotInstanceNode.prototype.__proto__ = WebInspector.HeapSnapshotGenericObjectNode.prototype;
524 WebInspector.HeapSnapshotConstructorNode = function(tree, className, aggregate, aggregatesKey)
526 WebInspector.HeapSnapshotGridNode.call(this, tree, aggregate.count > 0);
527 this._name = className;
528 this._count = aggregate.count;
529 this._shallowSize = aggregate.self;
530 this._retainedSize = aggregate.maxRet;
531 this._provider = this._createNodesProvider(tree.snapshot, className, aggregatesKey);
534 WebInspector.HeapSnapshotConstructorNode.prototype = {
535 _createChildNode: function(item)
537 return new WebInspector.HeapSnapshotInstanceNode(this.dataGrid, null, this.dataGrid.snapshot, item);
540 _createNodesProvider: function(snapshot, className, aggregatesKey)
542 return snapshot.createNodesProviderForClass(className, aggregatesKey);
545 comparator: function()
547 var sortAscending = this.dataGrid.sortOrder === "ascending";
548 var sortColumnIdentifier = this.dataGrid.sortColumnIdentifier;
550 object: ["id", sortAscending, "retainedSize", false],
551 count: ["id", true, "retainedSize", false],
552 shallowSize: ["selfSize", sortAscending, "id", true],
553 retainedSize: ["retainedSize", sortAscending, "id", true]
554 }[sortColumnIdentifier];
555 return WebInspector.HeapSnapshotFilteredOrderedIterator.prototype.createComparator(sortFields);
558 _childHashForEntity: function(node)
563 _childHashForNode: function(childNode)
565 return childNode.snapshotNodeId;
570 var data = {object: this._name, count: this._count};
571 var view = this.dataGrid.snapshotView;
572 data["count"] = view.showCountAsPercent ? WebInspector.UIString("%.2f%%", this._countPercent) : this._count;
573 data["shallowSize"] = view.showShallowSizeAsPercent ? WebInspector.UIString("%.2f%%", this._shallowSizePercent) : Number.bytesToString(this._shallowSize);
574 data["retainedSize"] = "> " + (view.showRetainedSizeAsPercent ? WebInspector.UIString("%.2f%%", this._retainedSizePercent) : Number.bytesToString(this._retainedSize));
580 return this._count / this.dataGrid.snapshot.nodeCount * 100.0;
583 get _retainedSizePercent()
585 return this._retainedSize / this.dataGrid.snapshot.totalSize * 100.0;
588 get _shallowSizePercent()
590 return this._shallowSize / this.dataGrid.snapshot.totalSize * 100.0;
594 WebInspector.HeapSnapshotConstructorNode.prototype.__proto__ = WebInspector.HeapSnapshotGridNode.prototype;
596 WebInspector.HeapSnapshotIteratorsTuple = function(it1, it2)
602 WebInspector.HeapSnapshotIteratorsTuple.prototype = {
609 sortAndRewind: function(comparator, callback)
611 function afterSort(ignored)
613 this._it2.sortAndRewind(comparator, callback);
615 this._it1.sortAndRewind(comparator, afterSort.bind(this));
619 WebInspector.HeapSnapshotDiffNode = function(tree, className, baseAggregate, aggregate)
621 WebInspector.HeapSnapshotGridNode.call(this, tree, true);
622 this._name = className;
623 this._baseIndexes = baseAggregate ? baseAggregate.idxs : [];
624 this._indexes = aggregate ? aggregate.idxs : [];
625 this._provider = this._createNodesProvider(tree.baseSnapshot, tree.snapshot, aggregate ? aggregate.type : baseAggregate.type, className);
628 WebInspector.HeapSnapshotDiffNode.prototype = {
629 calculateDiff: function(dataGrid, callback)
631 var diff = dataGrid.snapshot.createDiff(this._name);
633 function diffCalculated(diffResult)
636 this._addedCount = diffResult.addedCount;
637 this._removedCount = diffResult.removedCount;
638 this._countDelta = diffResult.countDelta;
639 this._addedSize = diffResult.addedSize;
640 this._removedSize = diffResult.removedSize;
641 this._sizeDelta = diffResult.sizeDelta;
642 this._baseIndexes = null;
643 this._indexes = null;
644 callback(this._addedSize === 0 && this._removedSize === 0);
646 function baseSelfSizesReceived(baseSelfSizes)
648 diff.pushBaseSelfSizes(baseSelfSizes);
649 diff.calculate(diffCalculated.bind(this));
651 function baseIdsReceived(baseIds)
653 diff.pushBaseIds(baseIds);
654 dataGrid.snapshot.pushBaseIds(dataGrid.baseSnapshot.uid, this._name, baseIds);
655 dataGrid.baseSnapshot.nodeFieldValuesByIndex("selfSize", this._baseIndexes, baseSelfSizesReceived.bind(this));
657 function idsReceived(ids)
659 dataGrid.baseSnapshot.pushBaseIds(dataGrid.snapshot.uid, this._name, ids);
661 dataGrid.baseSnapshot.nodeFieldValuesByIndex("id", this._baseIndexes, baseIdsReceived.bind(this));
662 dataGrid.snapshot.nodeFieldValuesByIndex("id", this._indexes, idsReceived.bind(this));
665 _createChildNode: function(item, provider)
667 if (provider === this._provider._it1)
668 return new WebInspector.HeapSnapshotInstanceNode(this.dataGrid, null, provider.snapshot, item);
670 return new WebInspector.HeapSnapshotInstanceNode(this.dataGrid, provider.snapshot, null, item);
673 _createNodesProvider: function(baseSnapshot, snapshot, nodeType, nodeClassName)
675 var className = this._name;
676 return new WebInspector.HeapSnapshotIteratorsTuple(
677 createProvider(snapshot, baseSnapshot), createProvider(baseSnapshot, snapshot));
679 function createProvider(snapshot, otherSnapshot)
681 var otherSnapshotId = otherSnapshot.uid;
682 var provider = snapshot.createNodesProvider(
683 "function (node) {" +
684 " return node.type === \"" + nodeType + "\" " +
685 (nodeClassName !== null ? "&& node.className === \"" + nodeClassName + "\"" : "") +
686 " && !this.baseSnapshotHasNode(" + otherSnapshotId + ", \"" + className + "\", node.id);" +
688 provider.snapshot = snapshot;
693 _childHashForEntity: function(node)
698 _childHashForNode: function(childNode)
700 return childNode.snapshotNodeId;
703 comparator: function()
705 var sortAscending = this.dataGrid.sortOrder === "ascending";
706 var sortColumnIdentifier = this.dataGrid.sortColumnIdentifier;
708 object: ["id", sortAscending, "selfSize", false],
709 addedCount: ["selfSize", sortAscending, "id", true],
710 removedCount: ["selfSize", sortAscending, "id", true],
711 countDelta: ["selfSize", sortAscending, "id", true],
712 addedSize: ["selfSize", sortAscending, "id", true],
713 removedSize: ["selfSize", sortAscending, "id", true],
714 sizeDelta: ["selfSize", sortAscending, "id", true]
715 }[sortColumnIdentifier];
716 return WebInspector.HeapSnapshotFilteredOrderedIterator.prototype.createComparator(sortFields);
719 populateChildren: function(provider, howMany, atIndex, afterPopulate)
721 if (!provider && !howMany) {
722 var firstProviderPopulated = function()
724 WebInspector.HeapSnapshotGridNode.prototype.populateChildren.call(this, this._provider._it2, this._defaultPopulateCount, atIndex, afterPopulate);
726 WebInspector.HeapSnapshotGridNode.prototype.populateChildren.call(this, this._provider._it1, this._defaultPopulateCount, atIndex, firstProviderPopulated.bind(this), true);
727 } else if (!howMany) {
728 var firstProviderPopulated = function()
730 WebInspector.HeapSnapshotGridNode.prototype.populateChildren.call(this, this._provider._it2, null, atIndex, afterPopulate);
732 WebInspector.HeapSnapshotGridNode.prototype.populateChildren.call(this, this._provider._it1, null, atIndex, firstProviderPopulated.bind(this), true);
734 WebInspector.HeapSnapshotGridNode.prototype.populateChildren.call(this, provider, howMany, atIndex, afterPopulate);
737 _signForDelta: function(delta)
744 return "\u2212"; // Math minus sign, same width as plus.
749 var data = {object: this._name};
751 data["addedCount"] = this._addedCount;
752 data["removedCount"] = this._removedCount;
753 data["countDelta"] = WebInspector.UIString("%s%d", this._signForDelta(this._countDelta), Math.abs(this._countDelta));
754 data["addedSize"] = Number.bytesToString(this._addedSize);
755 data["removedSize"] = Number.bytesToString(this._removedSize);
756 data["sizeDelta"] = WebInspector.UIString("%s%s", this._signForDelta(this._sizeDelta), Number.bytesToString(Math.abs(this._sizeDelta)));
762 WebInspector.HeapSnapshotDiffNode.prototype.__proto__ = WebInspector.HeapSnapshotGridNode.prototype;
764 WebInspector.HeapSnapshotDominatorObjectNode = function(tree, node)
766 WebInspector.HeapSnapshotGenericObjectNode.call(this, tree, node);
767 this._provider = this._createProvider(tree.snapshot, node.nodeIndex);
768 this._updateHasChildren();
771 WebInspector.HeapSnapshotDominatorObjectNode.prototype = {
772 _createChildNode: function(item)
774 return new WebInspector.HeapSnapshotDominatorObjectNode(this.dataGrid, item);
777 _createProvider: function(snapshot, nodeIndex)
779 var showHiddenData = WebInspector.DetailedHeapshotView.prototype.showHiddenData;
780 return snapshot.createNodesProviderForDominator(nodeIndex,
781 "function (node) {" +
782 " return " + showHiddenData + " || !node.isHidden;" +
786 _childHashForEntity: function(node)
791 _childHashForNode: function(childNode)
793 return childNode.snapshotNodeId;
796 comparator: function()
798 var sortAscending = this.dataGrid.sortOrder === "ascending";
799 var sortColumnIdentifier = this.dataGrid.sortColumnIdentifier;
801 object: ["id", sortAscending, "retainedSize", false],
802 shallowSize: ["selfSize", sortAscending, "id", true],
803 retainedSize: ["retainedSize", sortAscending, "id", true]
804 }[sortColumnIdentifier];
805 return WebInspector.HeapSnapshotFilteredOrderedIterator.prototype.createComparator(sortFields);
808 _emptyData: function()
814 WebInspector.HeapSnapshotDominatorObjectNode.prototype.__proto__ = WebInspector.HeapSnapshotGenericObjectNode.prototype;
816 function MixInSnapshotNodeFunctions(sourcePrototype, targetPrototype)
818 targetPrototype._childHashForEntity = sourcePrototype._childHashForEntity;
819 targetPrototype._childHashForNode = sourcePrototype._childHashForNode;
820 targetPrototype.comparator = sourcePrototype.comparator;
821 targetPrototype._createChildNode = sourcePrototype._createChildNode;
822 targetPrototype._createProvider = sourcePrototype._createProvider;
823 targetPrototype.dispose = sourcePrototype.dispose;
824 targetPrototype.populateChildren = sourcePrototype.populateChildren;
825 targetPrototype._saveChildren = sourcePrototype._saveChildren;
826 targetPrototype.sort = sourcePrototype.sort;