2011-04-14 Mikhail Naganov <mnaganov@chromium.org>
authormnaganov@chromium.org <mnaganov@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 14 Apr 2011 13:42:26 +0000 (13:42 +0000)
committermnaganov@chromium.org <mnaganov@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 14 Apr 2011 13:42:26 +0000 (13:42 +0000)
        Reviewed by Pavel Feldman.

        Web Inspector: [Chromium] Ready to move detailed heap snapshots storage and processing into workers.
        https://bugs.webkit.org/show_bug.cgi?id=58534

        * inspector/front-end/DetailedHeapshotGridNodes.js:
        (WebInspector.HeapSnapshotGenericObjectNode.prototype.get _countPercent):
        (WebInspector.HeapSnapshotDiffNode):
        (WebInspector.HeapSnapshotDiffNode.prototype.calculateDiff.diffCalculated):
        (WebInspector.HeapSnapshotDiffNode.prototype.calculateDiff):
        (WebInspector.HeapSnapshotDiffNode.prototype.calculateDiff.baseIdsReceived):
        (WebInspector.HeapSnapshotDiffNode.prototype.calculateDiff.idsReceived):
        (WebInspector.HeapSnapshotDiffNode.prototype._createNodesProvider.createProvider):
        (WebInspector.HeapSnapshotDiffNode.prototype._createNodesProvider):
        (WebInspector.HeapSnapshotDiffNode.prototype.get data):
        * inspector/front-end/DetailedHeapshotView.js:
        (WebInspector.HeapSnapshotDiffDataGrid.prototype.setBaseDataSource):
        (WebInspector.HeapSnapshotDiffDataGrid.prototype.populateChildren.baseAggregatesReceived.aggregatesReceived.addNodeIfNonZeroDiff):
        (WebInspector.HeapSnapshotDiffDataGrid.prototype.populateChildren.baseAggregatesReceived.aggregatesReceived):
        (WebInspector.HeapSnapshotDiffDataGrid.prototype.populateChildren):
        * inspector/front-end/HeapSnapshot.js:
        (WebInspector.HeapSnapshot):
        (WebInspector.HeapSnapshot.prototype.dispose):
        (WebInspector.HeapSnapshot.prototype.nodeFieldValuesByIndex):
        (WebInspector.HeapSnapshot.prototype._numbersComparator):
        (WebInspector.HeapSnapshot.prototype.baseSnapshotHasNode):
        (WebInspector.HeapSnapshot.prototype.updateBaseNodeIds):
        (WebInspector.HeapSnapshotsDiff):
        (WebInspector.HeapSnapshotsDiff.prototype.set baseIds):
        (WebInspector.HeapSnapshotsDiff.prototype.set baseSelfSizes):
        (WebInspector.HeapSnapshotsDiff.prototype.calculate):
        * inspector/front-end/HeapSnapshotProxy.js:
        (WebInspector.HeapSnapshotProxy):
        (WebInspector.HeapSnapshotProxy.prototype.createDiff):
        (WebInspector.HeapSnapshotProxy.prototype.createEdgesProvider):
        (WebInspector.HeapSnapshotProxy.prototype.createNodesProvider):
        (WebInspector.HeapSnapshotProxy.prototype.dispose):
        (WebInspector.HeapSnapshotProxy.prototype.nodeFieldValuesByIndex):
        (WebInspector.HeapSnapshotProxy.prototype.pushBaseIds):
        (WebInspector.HeapSnapshotsDiffProxy):
        (WebInspector.HeapSnapshotsDiffProxy.prototype.calculate):
        (WebInspector.HeapSnapshotsDiffProxy.prototype.pushBaseIds):
        (WebInspector.HeapSnapshotsDiffProxy.prototype.pushBaseSelfSizes):

2011-04-14  Mikhail Naganov  <mnaganov@chromium.org>

        Reviewed by Pavel Feldman.

        Web Inspector: [Chromium] Ready to move detailed heap snapshots storage and processing into workers.
        https://bugs.webkit.org/show_bug.cgi?id=58534

        * inspector/profiler/detailed-heapshots-test.js:
        (initialize_DetailedHeapshotTest.):
        (initialize_DetailedHeapshotTest):
        * inspector/profiler/heap-snapshot-test.js:
        (initialize_HeapSnapshotTest.InspectorTest.createHeapSnapshotMock):
        (initialize_HeapSnapshotTest):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@83850 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/inspector/profiler/detailed-heapshots-test.js
LayoutTests/inspector/profiler/heap-snapshot-test.js
Source/WebCore/ChangeLog
Source/WebCore/inspector/front-end/DetailedHeapshotGridNodes.js
Source/WebCore/inspector/front-end/DetailedHeapshotView.js
Source/WebCore/inspector/front-end/HeapSnapshot.js
Source/WebCore/inspector/front-end/HeapSnapshotProxy.js

index c5f9216..857a7b2 100644 (file)
@@ -1,3 +1,17 @@
+2011-04-14  Mikhail Naganov  <mnaganov@chromium.org>
+
+        Reviewed by Pavel Feldman.
+
+        Web Inspector: [Chromium] Ready to move detailed heap snapshots storage and processing into workers.
+        https://bugs.webkit.org/show_bug.cgi?id=58534
+
+        * inspector/profiler/detailed-heapshots-test.js:
+        (initialize_DetailedHeapshotTest.):
+        (initialize_DetailedHeapshotTest):
+        * inspector/profiler/heap-snapshot-test.js:
+        (initialize_HeapSnapshotTest.InspectorTest.createHeapSnapshotMock):
+        (initialize_HeapSnapshotTest):
+
 2011-04-14  Andrey Kosyakov  <caseq@chromium.org>
 
         Unreviewed. Added chromium baselines for SVG tests added in r83821.
index d3e4439..d1417cf 100644 (file)
@@ -373,7 +373,7 @@ InspectorTest.takeAndOpenSnapshot = function(generator, callback)
         snapshot.snapshot.typeId = profile.typeId;
         snapshot.snapshot.title = profile.title;
         snapshot.snapshot.uid = profile.uid;
-        WebInspector.panels.profiles._addHeapSnapshotChunk(uid, JSON.stringify(generator()));
+        WebInspector.panels.profiles._addHeapSnapshotChunk(uid, JSON.stringify(snapshot));
         WebInspector.panels.profiles._finishHeapSnapshot(uid);
     }
     InspectorTest.override(ProfilerAgent, "getProfile", pushGeneratedSnapshot);
index fb695c6..8ade9b5 100644 (file)
@@ -61,7 +61,8 @@ InspectorTest.createHeapSnapshotMock = function()
             1, 3, 4, 4, 10,  1, 1, 1, 11, 57,
             1, 4, 5, 5,  5, 27, 0,
             1, 5, 6, 6,  6, 40, 0],
-        strings: ["", "A", "B", "C", "D", "E", "a", "b", "ac", "bc", "bd", "ce"]
+        strings: ["", "A", "B", "C", "D", "E", "a", "b", "ac", "bc", "bd", "ce"],
+        snapshot: {}
     };
 };
 
index bee61ea..b4cdb2f 100644 (file)
@@ -1,3 +1,49 @@
+2011-04-14  Mikhail Naganov  <mnaganov@chromium.org>
+
+        Reviewed by Pavel Feldman.
+
+        Web Inspector: [Chromium] Ready to move detailed heap snapshots storage and processing into workers.
+        https://bugs.webkit.org/show_bug.cgi?id=58534
+
+        * inspector/front-end/DetailedHeapshotGridNodes.js:
+        (WebInspector.HeapSnapshotGenericObjectNode.prototype.get _countPercent):
+        (WebInspector.HeapSnapshotDiffNode):
+        (WebInspector.HeapSnapshotDiffNode.prototype.calculateDiff.diffCalculated):
+        (WebInspector.HeapSnapshotDiffNode.prototype.calculateDiff):
+        (WebInspector.HeapSnapshotDiffNode.prototype.calculateDiff.baseIdsReceived):
+        (WebInspector.HeapSnapshotDiffNode.prototype.calculateDiff.idsReceived):
+        (WebInspector.HeapSnapshotDiffNode.prototype._createNodesProvider.createProvider):
+        (WebInspector.HeapSnapshotDiffNode.prototype._createNodesProvider):
+        (WebInspector.HeapSnapshotDiffNode.prototype.get data):
+        * inspector/front-end/DetailedHeapshotView.js:
+        (WebInspector.HeapSnapshotDiffDataGrid.prototype.setBaseDataSource):
+        (WebInspector.HeapSnapshotDiffDataGrid.prototype.populateChildren.baseAggregatesReceived.aggregatesReceived.addNodeIfNonZeroDiff):
+        (WebInspector.HeapSnapshotDiffDataGrid.prototype.populateChildren.baseAggregatesReceived.aggregatesReceived):
+        (WebInspector.HeapSnapshotDiffDataGrid.prototype.populateChildren):
+        * inspector/front-end/HeapSnapshot.js:
+        (WebInspector.HeapSnapshot):
+        (WebInspector.HeapSnapshot.prototype.dispose):
+        (WebInspector.HeapSnapshot.prototype.nodeFieldValuesByIndex):
+        (WebInspector.HeapSnapshot.prototype._numbersComparator):
+        (WebInspector.HeapSnapshot.prototype.baseSnapshotHasNode):
+        (WebInspector.HeapSnapshot.prototype.updateBaseNodeIds):
+        (WebInspector.HeapSnapshotsDiff):
+        (WebInspector.HeapSnapshotsDiff.prototype.set baseIds):
+        (WebInspector.HeapSnapshotsDiff.prototype.set baseSelfSizes):
+        (WebInspector.HeapSnapshotsDiff.prototype.calculate):
+        * inspector/front-end/HeapSnapshotProxy.js:
+        (WebInspector.HeapSnapshotProxy):
+        (WebInspector.HeapSnapshotProxy.prototype.createDiff):
+        (WebInspector.HeapSnapshotProxy.prototype.createEdgesProvider):
+        (WebInspector.HeapSnapshotProxy.prototype.createNodesProvider):
+        (WebInspector.HeapSnapshotProxy.prototype.dispose):
+        (WebInspector.HeapSnapshotProxy.prototype.nodeFieldValuesByIndex):
+        (WebInspector.HeapSnapshotProxy.prototype.pushBaseIds):
+        (WebInspector.HeapSnapshotsDiffProxy):
+        (WebInspector.HeapSnapshotsDiffProxy.prototype.calculate):
+        (WebInspector.HeapSnapshotsDiffProxy.prototype.pushBaseIds):
+        (WebInspector.HeapSnapshotsDiffProxy.prototype.pushBaseSelfSizes):
+
 2011-04-14  Ilya Tikhonovsky  <loislo@chromium.org>
 
         Reviewed by Pavel Feldman.
index 47e36b9..e706e1d 100644 (file)
@@ -194,7 +194,7 @@ WebInspector.HeapSnapshotGenericObjectNode.prototype = {
 
     get _countPercent()
     {
-        return this._count / this.tree.snapshot.nodeCount * 100.0;
+        return this._count / this.dataGrid.snapshot.nodeCount * 100.0;
     },
 
     get data()
@@ -514,55 +514,42 @@ WebInspector.HeapSnapshotIteratorsTuple.prototype = {
 
 WebInspector.HeapSnapshotDiffNode = function(tree, className, baseAggregate, aggregate)
 {
-    if (!baseAggregate)
-        baseAggregate = { count: 0, self: 0, maxRet: 0, type:aggregate.type, name:aggregate.name, idxs: [] };
-    if (!aggregate)
-        aggregate = { count: 0, self: 0, maxRet: 0, type:baseAggregate.type, name:baseAggregate.name, idxs: [] };
     WebInspector.HeapSnapshotGridNode.call(this, tree, true);
     this._name = className;
-    this._calculateDiff(tree.baseSnapshot, tree.snapshot, baseAggregate.idxs, aggregate.idxs);
-    this._provider = this._createNodesProvider(tree.baseSnapshot, tree.snapshot, aggregate.type, className);
+    this._baseIndexes = baseAggregate ? baseAggregate.idxs : [];
+    this._indexes = aggregate ? aggregate.idxs : [];
+    this._provider = this._createNodesProvider(tree.baseSnapshot, tree.snapshot, aggregate ? aggregate.type : baseAggregate.type, className);
 }
 
 WebInspector.HeapSnapshotDiffNode.prototype = {
-    _calculateDiff: function(baseSnapshot, snapshot, baseIndexes, currentIndexes)
-    {
-        var i = 0, l = baseIndexes.length;
-        var j = 0, m = currentIndexes.length;
-        this._addedCount = 0;
-        this._removedCount = 0;
-        this._addedSize = 0;
-        this._removedSize = 0;
-        var nodeA = new WebInspector.HeapSnapshotNode(baseSnapshot._snapshot);
-        var nodeB = new WebInspector.HeapSnapshotNode(snapshot._snapshot);
-        nodeA.nodeIndex = baseIndexes[i];
-        nodeB.nodeIndex = currentIndexes[j];
-        while (i < l && j < m) {
-            if (nodeA.id < nodeB.id) {
-                this._removedCount++;
-                this._removedSize += nodeA.selfSize;
-                nodeA.nodeIndex = baseIndexes[++i];
-            } else if (nodeA.id > nodeB.id) {
-                this._addedCount++;
-                this._addedSize += nodeB.selfSize;
-                nodeB.nodeIndex = currentIndexes[++j];                
-            } else {
-                nodeA.nodeIndex = baseIndexes[++i];
-                nodeB.nodeIndex = currentIndexes[++j];                
-            }
+    calculateDiff: function(dataGrid, callback)
+    {
+        var diff = dataGrid.snapshot.createDiff(this._name);
+        
+        function diffCalculated(diffResult)
+        {
+            this._diff = diffResult;
+            this._baseIndexes = null;
+            this._indexes = null;
+            callback(this._diff.addedSize === 0 && this._diff.removedSize === 0);
+        }
+        function baseSelfSizesReceived(baseSelfSizes)
+        {
+            diff.pushBaseSelfSizes(baseSelfSizes);
+            diff.calculate(diffCalculated.bind(this));
         }
-        while (i < l) {
-            this._removedCount++;
-            this._removedSize += nodeA.selfSize;
-            nodeA.nodeIndex = baseIndexes[++i];
+        function baseIdsReceived(baseIds)
+        {
+            diff.pushBaseIds(dataGrid.baseSnapshot.uid, baseIds);
+            dataGrid.snapshot.pushBaseIds(dataGrid.baseSnapshot.uid, this._name, baseIds);
+            dataGrid.baseSnapshot.nodeFieldValuesByIndex("selfSize", this._baseIndexes, baseSelfSizesReceived.bind(this));
         }
-        while (j < m) {
-            this._addedCount++;
-            this._addedSize += nodeB.selfSize;
-            nodeB.nodeIndex = currentIndexes[++j];
+        function idsReceived(ids)
+        {
+            dataGrid.baseSnapshot.pushBaseIds(dataGrid.snapshot.uid, this._name, ids);
         }
-        this._countDelta = this._addedCount - this._removedCount;
-        this._sizeDelta = this._addedSize - this._removedSize;
+        dataGrid.baseSnapshot.nodeFieldValuesByIndex("id", this._baseIndexes, baseIdsReceived.bind(this));
+        dataGrid.snapshot.nodeFieldValuesByIndex("id", this._indexes, idsReceived.bind(this));
     },
 
     _createChildNode: function(item, provider)
@@ -575,6 +562,7 @@ WebInspector.HeapSnapshotDiffNode.prototype = {
 
     _createNodesProvider: function(baseSnapshot, snapshot, nodeType, nodeClassName)
     {
+        var className = this._name;
         return new WebInspector.HeapSnapshotIteratorsTuple(
             createProvider(snapshot, baseSnapshot), createProvider(baseSnapshot, snapshot));
 
@@ -585,7 +573,7 @@ WebInspector.HeapSnapshotDiffNode.prototype = {
                 function (node) {
                      return node.type === nodeType
                          && (nodeClassName === null || node.className === nodeClassName)
-                         && !this.snapshotHasNodeWithId(otherSnapshotId, node.id);
+                         && !this.baseSnapshotHasNode(otherSnapshotId, className, node.id);
                 });
             provider.snapshot = snapshot;
             return provider;
@@ -650,19 +638,16 @@ WebInspector.HeapSnapshotDiffNode.prototype = {
     {
         var data = {object: this._name};
 
-        data["addedCount"] = this._addedCount;
-        data["removedCount"] = this._removedCount;
-        data["countDelta"] = WebInspector.UIString("%s%d", this._signForDelta(this._countDelta), Math.abs(this._countDelta));
-        data["addedSize"] = Number.bytesToString(this._addedSize);
-        data["removedSize"] = Number.bytesToString(this._removedSize);
-        data["sizeDelta"] = WebInspector.UIString("%s%s", this._signForDelta(this._sizeDelta), Number.bytesToString(Math.abs(this._sizeDelta)));
+        data["addedCount"] = this._diff.addedCount;
+        data["removedCount"] = this._diff.removedCount;
+        var countDelta = this._diff.countDelta;
+        data["countDelta"] = WebInspector.UIString("%s%d", this._signForDelta(countDelta), Math.abs(countDelta));
+        data["addedSize"] = Number.bytesToString(this._diff.addedSize);
+        data["removedSize"] = Number.bytesToString(this._diff.removedSize);
+        var sizeDelta = this._diff.sizeDelta;
+        data["sizeDelta"] = WebInspector.UIString("%s%s", this._signForDelta(sizeDelta), Number.bytesToString(Math.abs(sizeDelta)));
 
         return data;
-    },
-
-    get zeroDiff()
-    {
-        return this._addedCount === 0 && this._removedCount === 0;
     }
 };
 
index fa6189d..1e46b51 100644 (file)
@@ -198,28 +198,7 @@ WebInspector.HeapSnapshotDiffDataGrid.prototype = {
         this.removeChildren();
         if (this.baseSnapshot === this.snapshot)
             return;
-
-        function baseSnapshotNodeIdsReceived(nodeIds)
-        {
-            this.snapshot.pushSnapshotNodeIds(this.baseSnapshot.uid, nodeIds);
-            this.populateChildren();
-        }
-        function pushBaseSnapshotNodeIds()
-        {
-            if (!this.snapshot.hasSnapshotNodeIds(this.baseSnapshot.uid))
-                this.baseSnapshot.nodeIds(baseSnapshotNodeIdsReceived.bind(this));
-            else
-                this.populateChildren();        
-        }
-        function snapshotNodeIdsReceived(nodeIds)
-        {
-            this.baseSnapshot.pushSnapshotNodeIds(this.snapshot.uid, nodeIds);
-            pushBaseSnapshotNodeIds.call(this);
-        }
-        if (!this.baseSnapshot.hasSnapshotNodeIds(this.snapshot.uid))
-            this.snapshot.nodeIds(snapshotNodeIdsReceived.bind(this));
-        else
-            pushBaseSnapshotNodeIds.call(this);
+        this.populateChildren();        
     },
 
     populateChildren: function()
@@ -228,19 +207,26 @@ WebInspector.HeapSnapshotDiffDataGrid.prototype = {
         {
             function aggregatesReceived(classes)
             {
+                var nodeCount = 0;
+                function addNodeIfNonZeroDiff(node, zeroDiff)
+                {
+                    if (!zeroDiff)
+                        this.appendChild(node);
+                    if (!--nodeCount)
+                        this.sortingChanged();
+                }
                 for (var clss in baseClasses) {
                     var node = new WebInspector.HeapSnapshotDiffNode(this, clss, baseClasses[clss], classes[clss]);
-                    if (!node.zeroDiff)
-                        this.appendChild(node);
+                    ++nodeCount;
+                    node.calculateDiff(this, addNodeIfNonZeroDiff.bind(this, node));
                 }
                 for (clss in classes) {
                     if (!(clss in baseClasses)) {
                         var node = new WebInspector.HeapSnapshotDiffNode(this, clss, null, classes[clss]);
-                        if (!node.zeroDiff)
-                            this.appendChild(node);
+                        ++nodeCount;
+                        node.calculateDiff(this, addNodeIfNonZeroDiff.bind(this, node));
                     }
                 }
-                this.sortingChanged();
             }
             this.snapshot.aggregates(true, aggregatesReceived.bind(this));
         }
index 2b1afee..781a13b 100644 (file)
@@ -482,7 +482,7 @@ WebInspector.HeapSnapshotNodeIterator.prototype = {
 
 WebInspector.HeapSnapshot = function(profile)
 {
-    this.uid = profile.uid;
+    this.uid = profile.snapshot.uid;
     this._nodes = profile.nodes;
     this._strings = profile.strings;
 
@@ -534,6 +534,7 @@ WebInspector.HeapSnapshot.prototype = {
             delete this._aggregates;
             this._aggregatesWithIndexes = false;
         }
+        delete this._baseNodeIds;
     },
 
     get _allNodes()
@@ -552,6 +553,17 @@ WebInspector.HeapSnapshot.prototype = {
         return this._nodeCount;
     },
 
+    nodeFieldValuesByIndex: function(fieldName, indexes)
+    {
+        var node = new WebInspector.HeapSnapshotNode(this);
+        var result = new Array(indexes.length);
+        for (var i = 0, l = indexes.length; i < l; ++i) {
+            node.nodeIndex = indexes[i];
+            result[i] = node[fieldName];
+        }
+        return result;
+    },
+
     get rootNode()
     {
         return new WebInspector.HeapSnapshotNode(this, this._rootNodeIndex);
@@ -756,6 +768,20 @@ WebInspector.HeapSnapshot.prototype = {
     _numbersComparator: function(a, b)
     {
         return a < b ? -1 : (a > b ? 1 : 0);
+    },
+
+    baseSnapshotHasNode: function(baseSnapshotId, className, nodeId)
+    {
+        return this._baseNodeIds[baseSnapshotId][className].binaryIndexOf(nodeId, this._numbersComparator) !== -1;
+    },
+
+    updateBaseNodeIds: function(baseSnapshotId, className, nodeIds)
+    {
+        if (!this._baseNodeIds)
+            this._baseNodeIds = [];
+        if (!this._baseNodeIds[baseSnapshotId])
+            this._baseNodeIds[baseSnapshotId] = {};
+        this._baseNodeIds[baseSnapshotId][className] = nodeIds;
     }
 };
 
@@ -1119,3 +1145,59 @@ WebInspector.HeapSnapshotPathFinder.prototype = {
         return sPath.join("");
     }
 };
+
+WebInspector.HeapSnapshotsDiff = function(snapshot, className)
+{
+    this._snapshot = snapshot;
+    this._className = className;
+};
+
+WebInspector.HeapSnapshotsDiff.prototype = {
+    set baseIds(baseIds)
+    {
+        this._baseIds = baseIds;
+    },
+
+    set baseSelfSizes(baseSelfSizes)
+    {
+        this._baseSelfSizes = baseSelfSizes;
+    },
+
+    calculate: function()
+    {
+        var indexes = this._snapshot.aggregates(true)[this._className].idxs;
+        var i = 0, l = this._baseIds.length;
+        var j = 0, m = indexes.length;
+        var diff = { addedCount: 0, removedCount: 0, addedSize: 0, removedSize: 0 };
+           
+        var nodeB = new WebInspector.HeapSnapshotNode(this._snapshot);
+        while (i < l && j < m) {
+            var nodeAId = this._baseIds[i];
+            if (nodeAId < nodeB.id) {
+                diff.removedCount++;
+                diff.removedSize += this._baseSelfSizes[i];
+                ++i;
+            } else if (nodeAId > nodeB.id) {
+                diff.addedCount++;
+                diff.addedSize += nodeB.selfSize;
+                nodeB.nodeIndex = indexes[++j];                
+            } else {
+                ++i;
+                nodeB.nodeIndex = indexes[++j];                
+            }
+        }
+        while (i < l) {
+            diff.removedCount++;
+            diff.removedSize += this._baseSelfSizes[i];
+            ++i;
+        }
+        while (j < m) {
+            diff.addedCount++;
+            diff.addedSize += nodeB.selfSize;
+            nodeB.nodeIndex = indexes[++j];
+        }
+        diff.countDelta = diff.addedCount - diff.removedCount;
+        diff.sizeDelta = diff.addedSize - diff.removedSize;
+        return diff;
+    }
+};
index 19a61d4..bb0a7ec 100644 (file)
@@ -31,7 +31,6 @@
 WebInspector.HeapSnapshotProxy = function()
 {   
     this._snapshot = null;
-    this._nodeIds = [];
 }
 
 WebInspector.HeapSnapshotProxy.prototype = {
@@ -63,12 +62,17 @@ WebInspector.HeapSnapshotProxy.prototype = {
         return {id: node.id, name: node.name, nodeIndex: node.nodeIndex, retainedSize: node.retainedSize, selfSize: node.selfSize, type: node.type};
     },
 
+    createDiff: function(className)
+    {
+        return new WebInspector.HeapSnapshotsDiffProxy(new WebInspector.HeapSnapshotsDiff(this._snapshot, className));
+    },
+
     createEdgesProvider: function(nodeIndex, filter)
     {
         function createProvider()
         {
             if (filter)
-                filter = filter.bind(this);
+                filter = filter.bind(this._snapshot);
             return new WebInspector.HeapSnapshotEdgesProvider(this._snapshot, nodeIndex, filter);
         }
         return new WebInspector.HeapSnapshotProviderProxy(createProvider.bind(this), this._extractEdgeData.bind(this));
@@ -79,7 +83,7 @@ WebInspector.HeapSnapshotProxy.prototype = {
         function createProvider()
         {
             if (filter)
-                filter = filter.bind(this);
+                filter = filter.bind(this._snapshot);
             return new WebInspector.HeapSnapshotNodesProvider(this._snapshot, filter);
         }
         return new WebInspector.HeapSnapshotProviderProxy(createProvider.bind(this), this._extractNodeData.bind(this));
@@ -93,12 +97,6 @@ WebInspector.HeapSnapshotProxy.prototype = {
     dispose: function()
     {
         this._snapshot.dispose();
-        delete this._nodeIds;
-    },
-
-    hasSnapshotNodeIds: function(snapshotId)
-    {
-        return snapshotId in this._nodeIds;
     },
 
     finishLoading: function(callback)
@@ -133,6 +131,15 @@ WebInspector.HeapSnapshotProxy.prototype = {
         return this._nodeCount;
     },
 
+    nodeFieldValuesByIndex: function(fieldName, indexes, callback)
+    {
+        function returnResult()
+        {
+            callback(this._snapshot.nodeFieldValuesByIndex(fieldName, indexes));
+        }
+        setTimeout(returnResult.bind(this), 0);
+    },
+
     nodeIds: function(callback)
     {
         this._invokeGetter("nodeIds", callback);
@@ -145,9 +152,9 @@ WebInspector.HeapSnapshotProxy.prototype = {
         this._json += chunk;
     },
 
-    pushSnapshotNodeIds: function(snapshotId, nodeIds)
+    pushBaseIds: function(snapshotId, className, nodeIds)
     {
-        this._nodeIds[snapshotId] = nodeIds;
+        this._snapshot.updateBaseNodeIds(snapshotId, className, nodeIds);
     },
 
     get rootNodeIndex()
@@ -155,15 +162,6 @@ WebInspector.HeapSnapshotProxy.prototype = {
         return this._rootNodeIndex;
     },
 
-    snapshotHasNodeWithId: function(snapshotId, nodeId)
-    {
-        var nodeIds = this._nodeIds[snapshotId];
-        if (nodeIds)
-            return nodeIds.binaryIndexOf(nodeId, this._snapshot._numbersComparator) >= 0;
-        else
-            return false;
-    },
-
     startLoading: function(callback)
     {
         if (this._snapshot) {
@@ -261,3 +259,29 @@ WebInspector.HeapSnapshotPathFinderProxy.prototype = {
         setTimeout(asyncInvoke.bind(this), 0);
     }
 };
+
+WebInspector.HeapSnapshotsDiffProxy = function(diff)
+{
+    this._diff = diff;
+}
+
+WebInspector.HeapSnapshotsDiffProxy.prototype = {
+    calculate: function(callback)
+    {
+        function returnResult()
+        {
+            callback(this._diff.calculate());
+        }
+        setTimeout(returnResult.bind(this), 0);
+    },
+
+    pushBaseIds: function(baseSnapshotId, baseIds)
+    {
+        this._diff.baseIds = baseIds;
+    },
+
+    pushBaseSelfSizes: function(baseSelfSizes)
+    {
+        this._diff.baseSelfSizes = baseSelfSizes;
+    }
+};