Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / devtools / front_end / profiler / HeapSnapshotGridNodes.js
blob6a57e103dba4cc7cf00cee76e7420da63af7dc71
1 /*
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
6 * met:
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
13 * distribution.
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 /**
32 * @constructor
33 * @extends {WebInspector.DataGridNode}
34 * @param {!WebInspector.HeapSnapshotSortableDataGrid} tree
35 * @param {boolean} hasChildren
37 WebInspector.HeapSnapshotGridNode = function(tree, hasChildren)
39 WebInspector.DataGridNode.call(this, null, hasChildren);
40 this._dataGrid = tree;
41 this._instanceCount = 0;
43 this._savedChildren = null;
44 /**
45 * List of position ranges for all visible nodes: [startPos1, endPos1),...,[startPosN, endPosN)
46 * Position is an item position in the provider.
48 this._retrievedChildrenRanges = [];
50 /**
51 * @type {?WebInspector.HeapSnapshotGridNode.ChildrenProvider}
53 this._providerObject = null;
56 WebInspector.HeapSnapshotGridNode.Events = {
57 PopulateComplete: "PopulateComplete"
60 /**
61 * @param {!Array.<string>} fieldNames
62 * @return {!WebInspector.HeapSnapshotCommon.ComparatorConfig}
64 WebInspector.HeapSnapshotGridNode.createComparator = function(fieldNames)
66 return /** @type {!WebInspector.HeapSnapshotCommon.ComparatorConfig} */ ({fieldName1: fieldNames[0], ascending1: fieldNames[1], fieldName2: fieldNames[2], ascending2: fieldNames[3]});
70 /**
71 * @interface
73 WebInspector.HeapSnapshotGridNode.ChildrenProvider = function() { }
75 WebInspector.HeapSnapshotGridNode.ChildrenProvider.prototype = {
76 dispose: function() { },
78 /**
79 * @param {number} snapshotObjectId
80 * @return {!Promise<number>}
82 nodePosition: function(snapshotObjectId) { },
84 /**
85 * @param {function(boolean)} callback
87 isEmpty: function(callback) { },
89 /**
90 * @param {number} startPosition
91 * @param {number} endPosition
92 * @param {function(!WebInspector.HeapSnapshotCommon.ItemsRange)} callback
94 serializeItemsRange: function(startPosition, endPosition, callback) { },
96 /**
97 * @param {!WebInspector.HeapSnapshotCommon.ComparatorConfig} comparator
98 * @return {!Promise<?>}
100 sortAndRewind: function(comparator) { }
104 WebInspector.HeapSnapshotGridNode.prototype = {
106 * @return {!WebInspector.HeapSnapshotSortableDataGrid}
108 heapSnapshotDataGrid: function()
110 return this._dataGrid;
114 * @return {!WebInspector.HeapSnapshotGridNode.ChildrenProvider}
116 createProvider: function()
118 throw new Error("Not implemented.");
122 * @return {?{snapshot:!WebInspector.HeapSnapshotProxy, snapshotNodeIndex:number}}
124 retainersDataSource: function()
126 return null;
130 * @return {!WebInspector.HeapSnapshotGridNode.ChildrenProvider}
132 _provider: function()
134 if (!this._providerObject)
135 this._providerObject = this.createProvider();
136 return this._providerObject;
140 * @override
141 * @param {string} columnIdentifier
142 * @return {!Element}
144 createCell: function(columnIdentifier)
146 var cell = WebInspector.DataGridNode.prototype.createCell.call(this, columnIdentifier);
147 if (this._searchMatched)
148 cell.classList.add("highlight");
149 return cell;
153 * @override
155 collapse: function()
157 WebInspector.DataGridNode.prototype.collapse.call(this);
158 this._dataGrid.updateVisibleNodes(true);
162 * @override
164 expand: function()
166 WebInspector.DataGridNode.prototype.expand.call(this);
167 this._dataGrid.updateVisibleNodes(true);
170 dispose: function()
172 if (this._providerObject)
173 this._providerObject.dispose();
174 for (var node = this.children[0]; node; node = node.traverseNextNode(true, this, true))
175 if (node.dispose)
176 node.dispose();
179 _reachableFromWindow: false,
181 queryObjectContent: function(callback)
186 * @override
188 wasDetached: function()
190 this._dataGrid.nodeWasDetached(this);
194 * @param {number} num
195 * @return {string}
197 _toPercentString: function(num)
199 return num.toFixed(0) + "\u2009%"; // \u2009 is a thin space.
203 * @param {number} distance
204 * @return {string}
206 _toUIDistance: function(distance)
208 var baseSystemDistance = WebInspector.HeapSnapshotCommon.baseSystemDistance;
209 return distance >= 0 && distance < baseSystemDistance ? WebInspector.UIString("%d", distance) : WebInspector.UIString("\u2212");
213 * @return {!Array.<!WebInspector.DataGridNode>}
215 allChildren: function()
217 return this._dataGrid.allChildren(this);
221 * @param {number} index
223 removeChildByIndex: function(index)
225 this._dataGrid.removeChildByIndex(this, index);
229 * @param {number} nodePosition
230 * @return {?WebInspector.DataGridNode}
232 childForPosition: function(nodePosition)
234 var indexOfFirstChildInRange = 0;
235 for (var i = 0; i < this._retrievedChildrenRanges.length; i++) {
236 var range = this._retrievedChildrenRanges[i];
237 if (range.from <= nodePosition && nodePosition < range.to) {
238 var childIndex = indexOfFirstChildInRange + nodePosition - range.from;
239 return this.allChildren()[childIndex];
241 indexOfFirstChildInRange += range.to - range.from + 1;
243 return null;
247 * @param {string} columnIdentifier
248 * @return {!Element}
250 _createValueCell: function(columnIdentifier)
252 var cell = createElement("td");
253 cell.className = "numeric-column";
254 if (this.dataGrid.snapshot.totalSize !== 0) {
255 var div = createElement("div");
256 var valueSpan = createElement("span");
257 valueSpan.textContent = this.data[columnIdentifier];
258 div.appendChild(valueSpan);
259 var percentColumn = columnIdentifier + "-percent";
260 if (percentColumn in this.data) {
261 var percentSpan = createElement("span");
262 percentSpan.className = "percent-column";
263 percentSpan.textContent = this.data[percentColumn];
264 div.appendChild(percentSpan);
265 div.classList.add("profile-multiple-values");
267 cell.appendChild(div);
269 return cell;
272 populate: function(event)
274 if (this._populated)
275 return;
276 this._populated = true;
277 this._provider().sortAndRewind(this.comparator()).then(this._populateChildren.bind(this));
281 * @return {!Promise<?>}
283 expandWithoutPopulate: function()
285 // Make sure default populate won't take action.
286 this._populated = true;
287 this.expand();
288 return this._provider().sortAndRewind(this.comparator());
292 * @param {?number=} fromPosition
293 * @param {?number=} toPosition
294 * @param {function()=} afterPopulate
296 _populateChildren: function(fromPosition, toPosition, afterPopulate)
298 fromPosition = fromPosition || 0;
299 toPosition = toPosition || fromPosition + this._dataGrid.defaultPopulateCount();
300 var firstNotSerializedPosition = fromPosition;
303 * @this {WebInspector.HeapSnapshotGridNode}
305 function serializeNextChunk()
307 if (firstNotSerializedPosition >= toPosition)
308 return;
309 var end = Math.min(firstNotSerializedPosition + this._dataGrid.defaultPopulateCount(), toPosition);
310 this._provider().serializeItemsRange(firstNotSerializedPosition, end, childrenRetrieved.bind(this));
311 firstNotSerializedPosition = end;
315 * @this {WebInspector.HeapSnapshotGridNode}
317 function insertRetrievedChild(item, insertionIndex)
319 if (this._savedChildren) {
320 var hash = this._childHashForEntity(item);
321 if (hash in this._savedChildren) {
322 this._dataGrid.insertChild(this, this._savedChildren[hash], insertionIndex);
323 return;
326 this._dataGrid.insertChild(this, this._createChildNode(item), insertionIndex);
330 * @this {WebInspector.HeapSnapshotGridNode}
332 function insertShowMoreButton(from, to, insertionIndex)
334 var button = new WebInspector.ShowMoreDataGridNode(this._populateChildren.bind(this), from, to, this._dataGrid.defaultPopulateCount());
335 this._dataGrid.insertChild(this, button, insertionIndex);
339 * @param {!WebInspector.HeapSnapshotCommon.ItemsRange} itemsRange
340 * @this {WebInspector.HeapSnapshotGridNode}
342 function childrenRetrieved(itemsRange)
344 var itemIndex = 0;
345 var itemPosition = itemsRange.startPosition;
346 var items = itemsRange.items;
347 var insertionIndex = 0;
349 if (!this._retrievedChildrenRanges.length) {
350 if (itemsRange.startPosition > 0) {
351 this._retrievedChildrenRanges.push({from: 0, to: 0});
352 insertShowMoreButton.call(this, 0, itemsRange.startPosition, insertionIndex++);
354 this._retrievedChildrenRanges.push({from: itemsRange.startPosition, to: itemsRange.endPosition});
355 for (var i = 0, l = items.length; i < l; ++i)
356 insertRetrievedChild.call(this, items[i], insertionIndex++);
357 if (itemsRange.endPosition < itemsRange.totalLength)
358 insertShowMoreButton.call(this, itemsRange.endPosition, itemsRange.totalLength, insertionIndex++);
359 } else {
360 var rangeIndex = 0;
361 var found = false;
362 var range;
363 while (rangeIndex < this._retrievedChildrenRanges.length) {
364 range = this._retrievedChildrenRanges[rangeIndex];
365 if (range.to >= itemPosition) {
366 found = true;
367 break;
369 insertionIndex += range.to - range.from;
370 // Skip the button if there is one.
371 if (range.to < itemsRange.totalLength)
372 insertionIndex += 1;
373 ++rangeIndex;
376 if (!found || itemsRange.startPosition < range.from) {
377 // Update previous button.
378 this.allChildren()[insertionIndex - 1].setEndPosition(itemsRange.startPosition);
379 insertShowMoreButton.call(this, itemsRange.startPosition, found ? range.from : itemsRange.totalLength, insertionIndex);
380 range = {from: itemsRange.startPosition, to: itemsRange.startPosition};
381 if (!found)
382 rangeIndex = this._retrievedChildrenRanges.length;
383 this._retrievedChildrenRanges.splice(rangeIndex, 0, range);
384 } else {
385 insertionIndex += itemPosition - range.from;
387 // At this point insertionIndex is always an index before button or between nodes.
388 // Also it is always true here that range.from <= itemPosition <= range.to
390 // Stretch the range right bound to include all new items.
391 while (range.to < itemsRange.endPosition) {
392 // Skip already added nodes.
393 var skipCount = range.to - itemPosition;
394 insertionIndex += skipCount;
395 itemIndex += skipCount;
396 itemPosition = range.to;
398 // We're at the position before button: ...<?node>x<button>
399 var nextRange = this._retrievedChildrenRanges[rangeIndex + 1];
400 var newEndOfRange = nextRange ? nextRange.from : itemsRange.totalLength;
401 if (newEndOfRange > itemsRange.endPosition)
402 newEndOfRange = itemsRange.endPosition;
403 while (itemPosition < newEndOfRange) {
404 insertRetrievedChild.call(this, items[itemIndex++], insertionIndex++);
405 ++itemPosition;
408 // Merge with the next range.
409 if (nextRange && newEndOfRange === nextRange.from) {
410 range.to = nextRange.to;
411 // Remove "show next" button if there is one.
412 this.removeChildByIndex(insertionIndex);
413 this._retrievedChildrenRanges.splice(rangeIndex + 1, 1);
414 } else {
415 range.to = newEndOfRange;
416 // Remove or update next button.
417 if (newEndOfRange === itemsRange.totalLength)
418 this.removeChildByIndex(insertionIndex);
419 else
420 this.allChildren()[insertionIndex].setStartPosition(itemsRange.endPosition);
425 // TODO: fix this.
426 this._instanceCount += items.length;
427 if (firstNotSerializedPosition < toPosition) {
428 serializeNextChunk.call(this);
429 return;
432 if (this.expanded)
433 this._dataGrid.updateVisibleNodes(true);
434 if (afterPopulate)
435 afterPopulate();
436 this.dispatchEventToListeners(WebInspector.HeapSnapshotGridNode.Events.PopulateComplete);
438 serializeNextChunk.call(this);
441 _saveChildren: function()
443 this._savedChildren = null;
444 var children = this.allChildren();
445 for (var i = 0, l = children.length; i < l; ++i) {
446 var child = children[i];
447 if (!child.expanded)
448 continue;
449 if (!this._savedChildren)
450 this._savedChildren = {};
451 this._savedChildren[this._childHashForNode(child)] = child;
455 sort: function()
457 this._dataGrid.recursiveSortingEnter();
460 * @this {WebInspector.HeapSnapshotGridNode}
462 function afterSort()
464 this._saveChildren();
465 this._dataGrid.removeAllChildren(this);
466 this._retrievedChildrenRanges = [];
469 * @this {WebInspector.HeapSnapshotGridNode}
471 function afterPopulate()
473 var children = this.allChildren();
474 for (var i = 0, l = children.length; i < l; ++i) {
475 var child = children[i];
476 if (child.expanded)
477 child.sort();
479 this._dataGrid.recursiveSortingLeave();
481 var instanceCount = this._instanceCount;
482 this._instanceCount = 0;
483 this._populateChildren(0, instanceCount, afterPopulate.bind(this));
486 this._provider().sortAndRewind(this.comparator()).then(afterSort.bind(this));
489 __proto__: WebInspector.DataGridNode.prototype
494 * @constructor
495 * @extends {WebInspector.HeapSnapshotGridNode}
496 * @param {!WebInspector.HeapSnapshotSortableDataGrid} dataGrid
497 * @param {!WebInspector.HeapSnapshotCommon.Node} node
499 WebInspector.HeapSnapshotGenericObjectNode = function(dataGrid, node)
501 WebInspector.HeapSnapshotGridNode.call(this, dataGrid, false);
502 // node is null for DataGrid root nodes.
503 if (!node)
504 return;
505 this._name = node.name;
506 this._type = node.type;
507 this._distance = node.distance;
508 this._shallowSize = node.selfSize;
509 this._retainedSize = node.retainedSize;
510 this.snapshotNodeId = node.id;
511 this.snapshotNodeIndex = node.nodeIndex;
512 if (this._type === "string")
513 this._reachableFromWindow = true;
514 else if (this._type === "object" && this._name.startsWith("Window")) {
515 this._name = this.shortenWindowURL(this._name, false);
516 this._reachableFromWindow = true;
517 } else if (node.canBeQueried)
518 this._reachableFromWindow = true;
519 if (node.detachedDOMTreeNode)
520 this.detachedDOMTreeNode = true;
522 var snapshot = dataGrid.snapshot;
523 var shallowSizePercent = this._shallowSize / snapshot.totalSize * 100.0;
524 var retainedSizePercent = this._retainedSize / snapshot.totalSize * 100.0;
525 this.data = {
526 "distance": this._toUIDistance(this._distance),
527 "shallowSize": Number.withThousandsSeparator(this._shallowSize),
528 "retainedSize": Number.withThousandsSeparator(this._retainedSize),
529 "shallowSize-percent": this._toPercentString(shallowSizePercent),
530 "retainedSize-percent": this._toPercentString(retainedSizePercent)
534 WebInspector.HeapSnapshotGenericObjectNode.prototype = {
536 * @override
537 * @return {?{snapshot:!WebInspector.HeapSnapshotProxy, snapshotNodeIndex:number}}
539 retainersDataSource: function()
541 return {snapshot: this._dataGrid.snapshot, snapshotNodeIndex: this.snapshotNodeIndex};
545 * @override
546 * @param {string} columnIdentifier
547 * @return {!Element}
549 createCell: function(columnIdentifier)
551 var cell = columnIdentifier !== "object" ? this._createValueCell(columnIdentifier) : this._createObjectCell();
552 if (this._searchMatched)
553 cell.classList.add("highlight");
554 return cell;
558 * @return {!Element}
560 _createObjectCell: function()
562 var value = this._name;
563 var valueStyle = "object";
564 switch (this._type) {
565 case "concatenated string":
566 case "string":
567 value = "\"" + value + "\"";
568 valueStyle = "string";
569 break;
570 case "regexp":
571 value = "/" + value + "/";
572 valueStyle = "string";
573 break;
574 case "closure":
575 value = value + "()";
576 valueStyle = "function";
577 break;
578 case "number":
579 valueStyle = "number";
580 break;
581 case "hidden":
582 valueStyle = "null";
583 break;
584 case "array":
585 value = (value || "") + "[]";
586 break;
588 if (this._reachableFromWindow)
589 valueStyle += " highlight";
590 if (value === "Object")
591 value = "";
592 if (this.detachedDOMTreeNode)
593 valueStyle += " detached-dom-tree-node";
594 return this._createObjectCellWithValue(valueStyle, value);
597 _createObjectCellWithValue: function(valueStyle, value)
599 var cell = createElement("td");
600 cell.className = "object-column";
601 var div = createElement("div");
602 div.className = "source-code event-properties";
603 div.style.overflow = "visible";
605 this._prefixObjectCell(div);
607 var valueSpan = createElement("span");
608 valueSpan.className = "value object-value-" + valueStyle;
609 valueSpan.textContent = value;
610 div.appendChild(valueSpan);
612 var idSpan = createElement("span");
613 idSpan.className = "object-value-id";
614 idSpan.textContent = " @" + this.snapshotNodeId;
615 div.appendChild(idSpan);
617 cell.appendChild(div);
618 cell.classList.add("disclosure");
619 if (this.depth)
620 cell.style.setProperty("padding-left", (this.depth * this.dataGrid.indentWidth) + "px");
621 cell.heapSnapshotNode = this;
622 return cell;
625 _prefixObjectCell: function(div)
630 * @param {!WebInspector.Target} target
631 * @param {function(!WebInspector.RemoteObject)} callback
632 * @param {string} objectGroupName
634 queryObjectContent: function(target, callback, objectGroupName)
637 * @param {?Protocol.Error} error
638 * @param {!RuntimeAgent.RemoteObject} object
640 function formatResult(error, object)
642 if (!error && object.type)
643 callback(target.runtimeModel.createRemoteObject(object));
644 else
645 callback(target.runtimeModel.createRemoteObjectFromPrimitiveValue(WebInspector.UIString("Preview is not available")));
648 if (this._type === "string")
649 callback(target.runtimeModel.createRemoteObjectFromPrimitiveValue(this._name));
650 else
651 target.heapProfilerAgent().getObjectByHeapObjectId(String(this.snapshotNodeId), objectGroupName, formatResult);
654 updateHasChildren: function()
657 * @this {WebInspector.HeapSnapshotGenericObjectNode}
659 function isEmptyCallback(isEmpty)
661 this.hasChildren = !isEmpty;
663 this._provider().isEmpty(isEmptyCallback.bind(this));
667 * @param {string} fullName
668 * @param {boolean} hasObjectId
669 * @return {string}
671 shortenWindowURL: function(fullName, hasObjectId)
673 var startPos = fullName.indexOf("/");
674 var endPos = hasObjectId ? fullName.indexOf("@") : fullName.length;
675 if (startPos !== -1 && endPos !== -1) {
676 var fullURL = fullName.substring(startPos + 1, endPos).trimLeft();
677 var url = fullURL.trimURL();
678 if (url.length > 40)
679 url = url.trimMiddle(40);
680 return fullName.substr(0, startPos + 2) + url + fullName.substr(endPos);
681 } else
682 return fullName;
685 __proto__: WebInspector.HeapSnapshotGridNode.prototype
689 * @constructor
690 * @extends {WebInspector.HeapSnapshotGenericObjectNode}
691 * @param {!WebInspector.HeapSnapshotSortableDataGrid} dataGrid
692 * @param {!WebInspector.HeapSnapshotProxy} snapshot
693 * @param {!WebInspector.HeapSnapshotCommon.Edge} edge
694 * @param {?WebInspector.HeapSnapshotObjectNode} parentObjectNode
696 WebInspector.HeapSnapshotObjectNode = function(dataGrid, snapshot, edge, parentObjectNode)
698 WebInspector.HeapSnapshotGenericObjectNode.call(this, dataGrid, edge.node);
699 this._referenceName = edge.name;
700 this._referenceType = edge.type;
701 this._edgeIndex = edge.edgeIndex;
702 this._snapshot = snapshot;
704 this._parentObjectNode = parentObjectNode;
705 this._cycledWithAncestorGridNode = this._findAncestorWithSameSnapshotNodeId();
706 if (!this._cycledWithAncestorGridNode)
707 this.updateHasChildren();
709 var data = this.data;
710 data["count"] = "";
711 data["addedCount"] = "";
712 data["removedCount"] = "";
713 data["countDelta"] = "";
714 data["addedSize"] = "";
715 data["removedSize"] = "";
716 data["sizeDelta"] = "";
719 WebInspector.HeapSnapshotObjectNode.prototype = {
721 * @override
722 * @return {?{snapshot:!WebInspector.HeapSnapshotProxy, snapshotNodeIndex:number}}
724 retainersDataSource: function()
726 return {snapshot: this._snapshot, snapshotNodeIndex: this.snapshotNodeIndex};
730 * @override
731 * @return {!WebInspector.HeapSnapshotProviderProxy}
733 createProvider: function()
735 return this._snapshot.createEdgesProvider(this.snapshotNodeIndex);
738 _findAncestorWithSameSnapshotNodeId: function()
740 var ancestor = this._parentObjectNode;
741 while (ancestor) {
742 if (ancestor.snapshotNodeId === this.snapshotNodeId)
743 return ancestor;
744 ancestor = ancestor._parentObjectNode;
746 return null;
750 * @param {!WebInspector.HeapSnapshotCommon.Edge} item
751 * @return {!WebInspector.HeapSnapshotObjectNode}
753 _createChildNode: function(item)
755 return new WebInspector.HeapSnapshotObjectNode(this._dataGrid, this._snapshot, item, this);
759 * @param {!WebInspector.HeapSnapshotCommon.Edge} edge
760 * @return {number}
762 _childHashForEntity: function(edge)
764 return edge.edgeIndex;
768 * @param {!WebInspector.HeapSnapshotObjectNode} childNode
769 * @return {number}
771 _childHashForNode: function(childNode)
773 return childNode._edgeIndex;
777 * @return {!WebInspector.HeapSnapshotCommon.ComparatorConfig}
779 comparator: function()
781 var sortAscending = this._dataGrid.isSortOrderAscending();
782 var sortColumnIdentifier = this._dataGrid.sortColumnIdentifier();
783 var sortFields = {
784 object: ["!edgeName", sortAscending, "retainedSize", false],
785 count: ["!edgeName", true, "retainedSize", false],
786 shallowSize: ["selfSize", sortAscending, "!edgeName", true],
787 retainedSize: ["retainedSize", sortAscending, "!edgeName", true],
788 distance: ["distance", sortAscending, "_name", true]
789 }[sortColumnIdentifier] || ["!edgeName", true, "retainedSize", false];
790 return WebInspector.HeapSnapshotGridNode.createComparator(sortFields);
793 _prefixObjectCell: function(div)
795 var name = this._referenceName || "(empty)";
796 var nameClass = "name";
797 switch (this._referenceType) {
798 case "context":
799 nameClass = "object-value-number";
800 break;
801 case "internal":
802 case "hidden":
803 case "weak":
804 nameClass = "object-value-null";
805 break;
806 case "element":
807 name = "[" + name + "]";
808 break;
811 if (this._cycledWithAncestorGridNode)
812 div.className += " cycled-ancessor-node";
814 var nameSpan = createElement("span");
815 nameSpan.className = nameClass;
816 nameSpan.textContent = name;
817 div.appendChild(nameSpan);
819 var separatorSpan = createElement("span");
820 separatorSpan.className = "grayed";
821 separatorSpan.textContent = this._edgeNodeSeparator();
822 div.appendChild(separatorSpan);
826 * @return {string}
828 _edgeNodeSeparator: function()
830 return " :: ";
833 __proto__: WebInspector.HeapSnapshotGenericObjectNode.prototype
837 * @constructor
838 * @extends {WebInspector.HeapSnapshotObjectNode}
839 * @param {!WebInspector.HeapSnapshotSortableDataGrid} dataGrid
840 * @param {!WebInspector.HeapSnapshotProxy} snapshot
841 * @param {!WebInspector.HeapSnapshotCommon.Edge} edge
842 * @param {?WebInspector.HeapSnapshotRetainingObjectNode} parentRetainingObjectNode
844 WebInspector.HeapSnapshotRetainingObjectNode = function(dataGrid, snapshot, edge, parentRetainingObjectNode)
846 WebInspector.HeapSnapshotObjectNode.call(this, dataGrid, snapshot, edge, parentRetainingObjectNode);
849 WebInspector.HeapSnapshotRetainingObjectNode.prototype = {
851 * @override
852 * @return {!WebInspector.HeapSnapshotProviderProxy}
854 createProvider: function()
856 return this._snapshot.createRetainingEdgesProvider(this.snapshotNodeIndex);
860 * @override
861 * @param {!WebInspector.HeapSnapshotCommon.Edge} item
862 * @return {!WebInspector.HeapSnapshotRetainingObjectNode}
864 _createChildNode: function(item)
866 return new WebInspector.HeapSnapshotRetainingObjectNode(this._dataGrid, this._snapshot, item, this);
870 * @override
871 * @return {string}
873 _edgeNodeSeparator: function()
875 return " in ";
878 expand: function()
880 this._expandRetainersChain(20);
884 * @param {number} maxExpandLevels
886 _expandRetainersChain: function(maxExpandLevels)
889 * @this {!WebInspector.HeapSnapshotRetainingObjectNode}
891 function populateComplete()
893 this.removeEventListener(WebInspector.HeapSnapshotGridNode.Events.PopulateComplete, populateComplete, this);
894 this._expandRetainersChain(maxExpandLevels);
897 if (!this._populated) {
898 this.addEventListener(WebInspector.HeapSnapshotGridNode.Events.PopulateComplete, populateComplete, this);
899 this.populate();
900 return;
902 WebInspector.HeapSnapshotGenericObjectNode.prototype.expand.call(this);
903 if (--maxExpandLevels > 0 && this.children.length > 0) {
904 var retainer = this.children[0];
905 if (retainer._distance > 1) {
906 retainer._expandRetainersChain(maxExpandLevels);
907 return;
910 this._dataGrid.dispatchEventToListeners(WebInspector.HeapSnapshotRetainmentDataGrid.Events.ExpandRetainersComplete);
913 __proto__: WebInspector.HeapSnapshotObjectNode.prototype
917 * @constructor
918 * @extends {WebInspector.HeapSnapshotGenericObjectNode}
919 * @param {!WebInspector.HeapSnapshotSortableDataGrid} dataGrid
920 * @param {!WebInspector.HeapSnapshotProxy} snapshot
921 * @param {!WebInspector.HeapSnapshotCommon.Node} node
922 * @param {boolean} isDeletedNode
924 WebInspector.HeapSnapshotInstanceNode = function(dataGrid, snapshot, node, isDeletedNode)
926 WebInspector.HeapSnapshotGenericObjectNode.call(this, dataGrid, node);
927 this._baseSnapshotOrSnapshot = snapshot;
928 this._isDeletedNode = isDeletedNode;
929 this.updateHasChildren();
931 var data = this.data;
932 data["count"] = "";
933 data["countDelta"] = "";
934 data["sizeDelta"] = "";
935 if (this._isDeletedNode) {
936 data["addedCount"] = "";
937 data["addedSize"] = "";
938 data["removedCount"] = "\u2022";
939 data["removedSize"] = Number.withThousandsSeparator(this._shallowSize);
940 } else {
941 data["addedCount"] = "\u2022";
942 data["addedSize"] = Number.withThousandsSeparator(this._shallowSize);
943 data["removedCount"] = "";
944 data["removedSize"] = "";
948 WebInspector.HeapSnapshotInstanceNode.prototype = {
950 * @override
951 * @return {?{snapshot:!WebInspector.HeapSnapshotProxy, snapshotNodeIndex:number}}
953 retainersDataSource: function()
955 return {snapshot: this._baseSnapshotOrSnapshot, snapshotNodeIndex: this.snapshotNodeIndex};
959 * @override
960 * @return {!WebInspector.HeapSnapshotProviderProxy}
962 createProvider: function()
964 return this._baseSnapshotOrSnapshot.createEdgesProvider(this.snapshotNodeIndex);
968 * @param {!WebInspector.HeapSnapshotCommon.Edge} item
969 * @return {!WebInspector.HeapSnapshotObjectNode}
971 _createChildNode: function(item)
973 return new WebInspector.HeapSnapshotObjectNode(this._dataGrid, this._baseSnapshotOrSnapshot, item, null);
977 * @param {!WebInspector.HeapSnapshotCommon.Edge} edge
978 * @return {number}
980 _childHashForEntity: function(edge)
982 return edge.edgeIndex;
986 * @param {!WebInspector.HeapSnapshotObjectNode} childNode
987 * @return {number}
989 _childHashForNode: function(childNode)
991 return childNode._edgeIndex;
995 * @return {!WebInspector.HeapSnapshotCommon.ComparatorConfig}
997 comparator: function()
999 var sortAscending = this._dataGrid.isSortOrderAscending();
1000 var sortColumnIdentifier = this._dataGrid.sortColumnIdentifier();
1001 var sortFields = {
1002 object: ["!edgeName", sortAscending, "retainedSize", false],
1003 distance: ["distance", sortAscending, "retainedSize", false],
1004 count: ["!edgeName", true, "retainedSize", false],
1005 addedSize: ["selfSize", sortAscending, "!edgeName", true],
1006 removedSize: ["selfSize", sortAscending, "!edgeName", true],
1007 shallowSize: ["selfSize", sortAscending, "!edgeName", true],
1008 retainedSize: ["retainedSize", sortAscending, "!edgeName", true]
1009 }[sortColumnIdentifier] || ["!edgeName", true, "retainedSize", false];
1010 return WebInspector.HeapSnapshotGridNode.createComparator(sortFields);
1013 __proto__: WebInspector.HeapSnapshotGenericObjectNode.prototype
1017 * @constructor
1018 * @param {!WebInspector.HeapSnapshotConstructorsDataGrid} dataGrid
1019 * @param {string} className
1020 * @param {!WebInspector.HeapSnapshotCommon.Aggregate} aggregate
1021 * @param {!WebInspector.HeapSnapshotCommon.NodeFilter} nodeFilter
1022 * @extends {WebInspector.HeapSnapshotGridNode}
1024 WebInspector.HeapSnapshotConstructorNode = function(dataGrid, className, aggregate, nodeFilter)
1026 WebInspector.HeapSnapshotGridNode.call(this, dataGrid, aggregate.count > 0);
1027 this._name = className;
1028 this._nodeFilter = nodeFilter;
1029 this._distance = aggregate.distance;
1030 this._count = aggregate.count;
1031 this._shallowSize = aggregate.self;
1032 this._retainedSize = aggregate.maxRet;
1034 var snapshot = dataGrid.snapshot;
1035 var countPercent = this._count / snapshot.nodeCount * 100.0;
1036 var retainedSizePercent = this._retainedSize / snapshot.totalSize * 100.0;
1037 var shallowSizePercent = this._shallowSize / snapshot.totalSize * 100.0;
1039 this.data = {
1040 "object": className,
1041 "count": Number.withThousandsSeparator(this._count),
1042 "distance": this._toUIDistance(this._distance),
1043 "shallowSize": Number.withThousandsSeparator(this._shallowSize),
1044 "retainedSize": Number.withThousandsSeparator(this._retainedSize),
1045 "count-percent": this._toPercentString(countPercent),
1046 "shallowSize-percent": this._toPercentString(shallowSizePercent),
1047 "retainedSize-percent": this._toPercentString(retainedSizePercent)
1051 WebInspector.HeapSnapshotConstructorNode.prototype = {
1053 * @override
1054 * @return {!WebInspector.HeapSnapshotProviderProxy}
1056 createProvider: function()
1058 return this._dataGrid.snapshot.createNodesProviderForClass(this._name, this._nodeFilter)
1062 * @param {number} snapshotObjectId
1063 * @return {!Promise<!Array<!WebInspector.HeapSnapshotGridNode>>}
1065 populateNodeBySnapshotObjectId: function(snapshotObjectId)
1068 * @this {WebInspector.HeapSnapshotConstructorNode}
1070 function didExpand()
1072 return this._provider().nodePosition(snapshotObjectId).then(didGetNodePosition.bind(this));
1076 * @this {WebInspector.HeapSnapshotConstructorNode}
1077 * @param {number} nodePosition
1078 * @return {!Promise<!Array<!WebInspector.HeapSnapshotGridNode>>}
1080 function didGetNodePosition(nodePosition)
1082 if (nodePosition === -1) {
1083 this.collapse();
1084 return Promise.resolve([]);
1085 } else {
1087 * @param {function(!Array<!WebInspector.HeapSnapshotGridNode>)} fulfill
1088 * @this {WebInspector.HeapSnapshotConstructorNode}
1090 function action(fulfill)
1092 this._populateChildren(nodePosition, null, didPopulateChildren.bind(this, nodePosition, fulfill));
1094 return new Promise(action.bind(this));
1099 * @this {WebInspector.HeapSnapshotConstructorNode}
1100 * @param {number} nodePosition
1101 * @param {function(!Array<!WebInspector.HeapSnapshotGridNode>)} callback
1103 function didPopulateChildren(nodePosition, callback)
1105 var node = /** @type {?WebInspector.HeapSnapshotGridNode} */ (this.childForPosition(nodePosition));
1106 callback(node ? [this, node] : []);
1109 this._dataGrid.resetNameFilter();
1110 return this.expandWithoutPopulate().then(didExpand.bind(this));
1114 * @param {string} filterValue
1115 * @return {boolean}
1117 filteredOut: function(filterValue)
1119 return this._name.toLowerCase().indexOf(filterValue) === -1;
1123 * @override
1124 * @param {string} columnIdentifier
1125 * @return {!Element}
1127 createCell: function(columnIdentifier)
1129 var cell = columnIdentifier !== "object" ? this._createValueCell(columnIdentifier) : WebInspector.HeapSnapshotGridNode.prototype.createCell.call(this, columnIdentifier);
1130 if (this._searchMatched)
1131 cell.classList.add("highlight");
1132 return cell;
1136 * @param {!WebInspector.HeapSnapshotCommon.Node} item
1137 * @return {!WebInspector.HeapSnapshotInstanceNode}
1139 _createChildNode: function(item)
1141 return new WebInspector.HeapSnapshotInstanceNode(this._dataGrid, this._dataGrid.snapshot, item, false);
1145 * @return {!WebInspector.HeapSnapshotCommon.ComparatorConfig}
1147 comparator: function()
1149 var sortAscending = this._dataGrid.isSortOrderAscending();
1150 var sortColumnIdentifier = this._dataGrid.sortColumnIdentifier();
1151 var sortFields = {
1152 object: ["name", sortAscending, "id", true],
1153 distance: ["distance", sortAscending, "retainedSize", false],
1154 count: ["name", true, "id", true],
1155 shallowSize: ["selfSize", sortAscending, "id", true],
1156 retainedSize: ["retainedSize", sortAscending, "id", true]
1157 }[sortColumnIdentifier];
1158 return WebInspector.HeapSnapshotGridNode.createComparator(sortFields);
1162 * @param {!WebInspector.HeapSnapshotCommon.Node} node
1163 * @return {number}
1165 _childHashForEntity: function(node)
1167 return node.id;
1171 * @param {!WebInspector.HeapSnapshotInstanceNode} childNode
1172 * @return {number}
1174 _childHashForNode: function(childNode)
1176 return childNode.snapshotNodeId;
1179 __proto__: WebInspector.HeapSnapshotGridNode.prototype
1184 * @constructor
1185 * @implements {WebInspector.HeapSnapshotGridNode.ChildrenProvider}
1186 * @param {!WebInspector.HeapSnapshotProviderProxy} addedNodesProvider
1187 * @param {!WebInspector.HeapSnapshotProviderProxy} deletedNodesProvider
1188 * @param {number} addedCount
1189 * @param {number} removedCount
1191 WebInspector.HeapSnapshotDiffNodesProvider = function(addedNodesProvider, deletedNodesProvider, addedCount, removedCount)
1193 this._addedNodesProvider = addedNodesProvider;
1194 this._deletedNodesProvider = deletedNodesProvider;
1195 this._addedCount = addedCount;
1196 this._removedCount = removedCount;
1199 WebInspector.HeapSnapshotDiffNodesProvider.prototype = {
1201 * @override
1203 dispose: function()
1205 this._addedNodesProvider.dispose();
1206 this._deletedNodesProvider.dispose();
1210 * @override
1211 * @param {number} snapshotObjectId
1212 * @return {!Promise<number>}
1214 nodePosition: function(snapshotObjectId)
1216 throw new Error("Unreachable");
1220 * @override
1221 * @param {function(boolean)} callback
1223 isEmpty: function(callback)
1225 callback(false);
1229 * @override
1230 * @param {number} beginPosition
1231 * @param {number} endPosition
1232 * @param {function(!WebInspector.HeapSnapshotCommon.ItemsRange)} callback
1234 serializeItemsRange: function(beginPosition, endPosition, callback)
1237 * @param {!WebInspector.HeapSnapshotCommon.ItemsRange} items
1238 * @this {WebInspector.HeapSnapshotDiffNodesProvider}
1240 function didReceiveAllItems(items)
1242 items.totalLength = this._addedCount + this._removedCount;
1243 callback(items);
1247 * @param {!WebInspector.HeapSnapshotCommon.ItemsRange} addedItems
1248 * @param {!WebInspector.HeapSnapshotCommon.ItemsRange} itemsRange
1249 * @this {WebInspector.HeapSnapshotDiffNodesProvider}
1251 function didReceiveDeletedItems(addedItems, itemsRange)
1253 var items = itemsRange.items;
1254 if (!addedItems.items.length)
1255 addedItems.startPosition = this._addedCount + itemsRange.startPosition;
1256 for (var i = 0; i < items.length; i++) {
1257 items[i].isAddedNotRemoved = false;
1258 addedItems.items.push(items[i]);
1260 addedItems.endPosition = this._addedCount + itemsRange.endPosition;
1261 didReceiveAllItems.call(this, addedItems);
1265 * @param {!WebInspector.HeapSnapshotCommon.ItemsRange} itemsRange
1266 * @this {WebInspector.HeapSnapshotDiffNodesProvider}
1268 function didReceiveAddedItems(itemsRange)
1270 var items = itemsRange.items;
1271 for (var i = 0; i < items.length; i++)
1272 items[i].isAddedNotRemoved = true;
1273 if (itemsRange.endPosition < endPosition)
1274 return this._deletedNodesProvider.serializeItemsRange(0, endPosition - itemsRange.endPosition, didReceiveDeletedItems.bind(this, itemsRange));
1276 itemsRange.totalLength = this._addedCount + this._removedCount;
1277 didReceiveAllItems.call(this, itemsRange);
1280 if (beginPosition < this._addedCount) {
1281 this._addedNodesProvider.serializeItemsRange(beginPosition, endPosition, didReceiveAddedItems.bind(this));
1282 } else {
1283 var emptyRange = new WebInspector.HeapSnapshotCommon.ItemsRange(0, 0, 0, []);
1284 this._deletedNodesProvider.serializeItemsRange(beginPosition - this._addedCount, endPosition - this._addedCount, didReceiveDeletedItems.bind(this, emptyRange));
1289 * @override
1290 * @param {!WebInspector.HeapSnapshotCommon.ComparatorConfig} comparator
1291 * @return {!Promise<?>}
1293 sortAndRewind: function(comparator)
1296 * @this {WebInspector.HeapSnapshotDiffNodesProvider}
1297 * @return {!Promise<?>}
1299 function afterSort()
1301 return this._deletedNodesProvider.sortAndRewind(comparator);
1303 return this._addedNodesProvider.sortAndRewind(comparator).then(afterSort.bind(this));
1308 * @constructor
1309 * @param {!WebInspector.HeapSnapshotDiffDataGrid} dataGrid
1310 * @param {string} className
1311 * @param {!WebInspector.HeapSnapshotCommon.DiffForClass} diffForClass
1312 * @extends {WebInspector.HeapSnapshotGridNode}
1314 WebInspector.HeapSnapshotDiffNode = function(dataGrid, className, diffForClass)
1316 WebInspector.HeapSnapshotGridNode.call(this, dataGrid, true);
1317 this._name = className;
1318 this._addedCount = diffForClass.addedCount;
1319 this._removedCount = diffForClass.removedCount;
1320 this._countDelta = diffForClass.countDelta;
1321 this._addedSize = diffForClass.addedSize;
1322 this._removedSize = diffForClass.removedSize;
1323 this._sizeDelta = diffForClass.sizeDelta;
1324 this._deletedIndexes = diffForClass.deletedIndexes;
1325 this.data = {
1326 "object": className,
1327 "addedCount": Number.withThousandsSeparator(this._addedCount),
1328 "removedCount": Number.withThousandsSeparator(this._removedCount),
1329 "countDelta": this._signForDelta(this._countDelta) + Number.withThousandsSeparator(Math.abs(this._countDelta)),
1330 "addedSize": Number.withThousandsSeparator(this._addedSize),
1331 "removedSize": Number.withThousandsSeparator(this._removedSize),
1332 "sizeDelta": this._signForDelta(this._sizeDelta) + Number.withThousandsSeparator(Math.abs(this._sizeDelta))
1336 WebInspector.HeapSnapshotDiffNode.prototype = {
1338 * @override
1339 * @return {!WebInspector.HeapSnapshotDiffNodesProvider}
1341 createProvider: function()
1343 var tree = this._dataGrid;
1344 return new WebInspector.HeapSnapshotDiffNodesProvider(
1345 tree.snapshot.createAddedNodesProvider(tree.baseSnapshot.uid, this._name),
1346 tree.baseSnapshot.createDeletedNodesProvider(this._deletedIndexes),
1347 this._addedCount,
1348 this._removedCount);
1352 * @override
1353 * @param {string} columnIdentifier
1354 * @return {!Element}
1356 createCell: function(columnIdentifier)
1358 var cell = WebInspector.HeapSnapshotGridNode.prototype.createCell.call(this, columnIdentifier);
1359 if (columnIdentifier !== "object")
1360 cell.classList.add("numeric-column");
1361 return cell;
1365 * @param {!WebInspector.HeapSnapshotCommon.Node} item
1366 * @return {!WebInspector.HeapSnapshotInstanceNode}
1368 _createChildNode: function(item)
1370 if (item.isAddedNotRemoved)
1371 return new WebInspector.HeapSnapshotInstanceNode(this._dataGrid, this._dataGrid.snapshot, item, false);
1372 else
1373 return new WebInspector.HeapSnapshotInstanceNode(this._dataGrid, this._dataGrid.baseSnapshot, item, true);
1377 * @param {!WebInspector.HeapSnapshotCommon.Node} node
1378 * @return {number}
1380 _childHashForEntity: function(node)
1382 return node.id;
1386 * @param {!WebInspector.HeapSnapshotInstanceNode} childNode
1387 * @return {number}
1389 _childHashForNode: function(childNode)
1391 return childNode.snapshotNodeId;
1395 * @return {!WebInspector.HeapSnapshotCommon.ComparatorConfig}
1397 comparator: function()
1399 var sortAscending = this._dataGrid.isSortOrderAscending();
1400 var sortColumnIdentifier = this._dataGrid.sortColumnIdentifier();
1401 var sortFields = {
1402 object: ["name", sortAscending, "id", true],
1403 addedCount: ["name", true, "id", true],
1404 removedCount: ["name", true, "id", true],
1405 countDelta: ["name", true, "id", true],
1406 addedSize: ["selfSize", sortAscending, "id", true],
1407 removedSize: ["selfSize", sortAscending, "id", true],
1408 sizeDelta: ["selfSize", sortAscending, "id", true]
1409 }[sortColumnIdentifier];
1410 return WebInspector.HeapSnapshotGridNode.createComparator(sortFields);
1414 * @param {string} filterValue
1415 * @return {boolean}
1417 filteredOut: function(filterValue)
1419 return this._name.toLowerCase().indexOf(filterValue) === -1;
1422 _signForDelta: function(delta)
1424 if (delta === 0)
1425 return "";
1426 if (delta > 0)
1427 return "+";
1428 else
1429 return "\u2212"; // Math minus sign, same width as plus.
1432 __proto__: WebInspector.HeapSnapshotGridNode.prototype
1437 * @constructor
1438 * @extends {WebInspector.HeapSnapshotGridNode}
1439 * @param {!WebInspector.AllocationDataGrid} dataGrid
1440 * @param {!WebInspector.HeapSnapshotCommon.SerializedAllocationNode} data
1442 WebInspector.AllocationGridNode = function(dataGrid, data)
1444 WebInspector.HeapSnapshotGridNode.call(this, dataGrid, data.hasChildren);
1445 this._populated = false;
1446 this._allocationNode = data;
1447 this.data = {
1448 "liveCount": Number.withThousandsSeparator(data.liveCount),
1449 "count": Number.withThousandsSeparator(data.count),
1450 "liveSize": Number.withThousandsSeparator(data.liveSize),
1451 "size": Number.withThousandsSeparator(data.size),
1452 "name": data.name
1456 WebInspector.AllocationGridNode.prototype = {
1457 populate: function()
1459 if (this._populated)
1460 return;
1461 this._populated = true;
1462 this._dataGrid.snapshot.allocationNodeCallers(this._allocationNode.id, didReceiveCallers.bind(this));
1465 * @param {!WebInspector.HeapSnapshotCommon.AllocationNodeCallers} callers
1466 * @this {WebInspector.AllocationGridNode}
1468 function didReceiveCallers(callers)
1470 var callersChain = callers.nodesWithSingleCaller;
1471 var parentNode = this;
1472 var dataGrid = /** @type {!WebInspector.AllocationDataGrid} */ (this._dataGrid);
1473 for (var i = 0; i < callersChain.length; i++) {
1474 var child = new WebInspector.AllocationGridNode(dataGrid, callersChain[i]);
1475 dataGrid.appendNode(parentNode, child);
1476 parentNode = child;
1477 parentNode._populated = true;
1478 if (this.expanded)
1479 parentNode.expand();
1482 var callersBranch = callers.branchingCallers;
1483 callersBranch.sort(this._dataGrid._createComparator());
1484 for (var i = 0; i < callersBranch.length; i++)
1485 dataGrid.appendNode(parentNode, new WebInspector.AllocationGridNode(dataGrid, callersBranch[i]));
1486 dataGrid.updateVisibleNodes(true);
1491 * @override
1493 expand: function()
1495 WebInspector.HeapSnapshotGridNode.prototype.expand.call(this);
1496 if (this.children.length === 1)
1497 this.children[0].expand();
1501 * @override
1502 * @param {string} columnIdentifier
1503 * @return {!Element}
1505 createCell: function(columnIdentifier)
1507 if (columnIdentifier !== "name")
1508 return this._createValueCell(columnIdentifier);
1510 var cell = WebInspector.HeapSnapshotGridNode.prototype.createCell.call(this, columnIdentifier);
1511 var allocationNode = this._allocationNode;
1512 var target = this._dataGrid.target();
1513 if (allocationNode.scriptId) {
1514 var linkifier = this._dataGrid._linkifier;
1515 var urlElement = linkifier.linkifyScriptLocation(target, String(allocationNode.scriptId), allocationNode.scriptName, allocationNode.line - 1, allocationNode.column - 1, "profile-node-file");
1516 urlElement.style.maxWidth = "75%";
1517 cell.insertBefore(urlElement, cell.firstChild);
1519 return cell;
1523 * @return {number}
1525 allocationNodeId: function()
1527 return this._allocationNode.id;
1530 __proto__: WebInspector.HeapSnapshotGridNode.prototype