Bug 1260590 - Add the `CensusUtils.getCensusIndividuals` utility; r=jimb a=kwierso
authorNick Fitzgerald <fitzgen@gmail.com>
Thu, 31 Mar 2016 16:19:22 -0700
changeset 291300 a5e17a9cb4a02db80b1ba543a1158966c470078a
parent 291299 1ac6445b00251dd50863942dd6901eff76ebfaa6
child 291301 49adb658e099d5b38c24c5c4cf34e603c0e12afc
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimb, kwierso
bugs1260590
milestone48.0a1
Bug 1260590 - Add the `CensusUtils.getCensusIndividuals` utility; r=jimb a=kwierso This commit adds the `getCensusIndividuals` utility for getting the individual node IDs that match the census leaves specified by the given indices in a pre-order depth-first traversal of a census report generated with the given breakdown. MozReview-Commit-ID: A4IRcP82iCC
devtools/shared/heapsnapshot/CensusUtils.js
devtools/shared/heapsnapshot/tests/unit/test_getCensusIndividuals_01.js
devtools/shared/heapsnapshot/tests/unit/xpcshell.ini
--- a/devtools/shared/heapsnapshot/CensusUtils.js
+++ b/devtools/shared/heapsnapshot/CensusUtils.js
@@ -1,11 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+"use strict";
+
+const { flatten } = require("resource://devtools/shared/ThreadSafeDevToolsUtils.js");
 
 /*** Visitor ****************************************************************/
 
 /**
  * A Visitor visits each node and edge of a census report tree as the census
  * report is being traversed by `walk`.
  */
 function Visitor() { };
@@ -60,16 +63,20 @@ Visitor.prototype.count = function (brea
 /*** getReportEdges *********************************************************/
 
 const EDGES = Object.create(null);
 
 EDGES.count = function (breakdown, report) {
   return [];
 };
 
+EDGES.bucket = function (breakdown, report) {
+  return [];
+};
+
 EDGES.internalType = function (breakdown, report) {
   return Object.keys(report).map(key => ({
     edge: key,
     referent: report[key],
     breakdown: breakdown.then
   }));
 };
 
@@ -456,8 +463,27 @@ GetLeavesVisitor.prototype.leaves = func
  *
  * @returns {Array<Object>}
  */
 exports.getReportLeaves = function(indices, breakdown, report) {
   const visitor = new GetLeavesVisitor(indices);
   walk(breakdown, report, visitor);
   return visitor.leaves();
 };
+
+/**
+ * Get a list of the individual node IDs that belong to the census report leaves
+ * of the given indices.
+ *
+ * @param {Set<Number>} indices
+ * @param {Object} breakdown
+ * @param {HeapSnapshot} snapshot
+ *
+ * @returns {Array<NodeId>}
+ */
+exports.getCensusIndividuals = function(indices, countBreakdown, snapshot) {
+  const bucketBreakdown = exports.countToBucketBreakdown(countBreakdown);
+  const bucketReport = snapshot.takeCensus({ breakdown: bucketBreakdown });
+  const buckets = exports.getReportLeaves(indices,
+                                          bucketBreakdown,
+                                          bucketReport);
+  return flatten(buckets);
+};
new file mode 100644
--- /dev/null
+++ b/devtools/shared/heapsnapshot/tests/unit/test_getCensusIndividuals_01.js
@@ -0,0 +1,60 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+"use strict";
+
+// Test basic functionality of `CensusUtils.getCensusIndividuals`.
+
+function run_test() {
+  const stack1 = saveStack(1);
+  const stack2 = saveStack(1);
+  const stack3 = saveStack(1);
+
+  const COUNT = { by: "count", count: true, bytes: true };
+  const INTERNAL_TYPE = { by: "internalType", then: COUNT };
+
+  const BREAKDOWN = {
+    by: "allocationStack",
+    then: INTERNAL_TYPE,
+    noStack: INTERNAL_TYPE,
+  };
+
+  const MOCK_SNAPSHOT = {
+    takeCensus: ({ breakdown }) => {
+      assertStructurallyEquivalent(
+        breakdown,
+        CensusUtils.countToBucketBreakdown(BREAKDOWN));
+
+      //                                DFS Index
+      return new Map([               // 0
+        [stack1, {                   // 1
+          JSObject: [101, 102, 103], // 2
+          JSString: [111, 112, 113], // 3
+        }],
+        [stack2, {                   // 4
+          JSObject: [201, 202, 203], // 5
+          JSString: [211, 212, 213], // 6
+        }],
+        [stack3, {                   // 7
+          JSObject: [301, 302, 303], // 8
+          JSString: [311, 312, 313], // 9
+        }],
+        ["noStack", {                // 10
+          JSObject: [401, 402, 403], // 11
+          JSString: [411, 412, 413], // 12
+        }],
+      ]);
+    }
+  };
+
+  const INDICES = new Set([3, 5, 9]);
+
+  const EXPECTED = new Set([111, 112, 113,
+                            201, 202, 203,
+                            311, 312, 313]);
+
+  const actual = new Set(CensusUtils.getCensusIndividuals(INDICES,
+                                                          BREAKDOWN,
+                                                          MOCK_SNAPSHOT));
+
+  assertStructurallyEquivalent(EXPECTED, actual);
+}
--- a/devtools/shared/heapsnapshot/tests/unit/xpcshell.ini
+++ b/devtools/shared/heapsnapshot/tests/unit/xpcshell.ini
@@ -45,16 +45,17 @@ support-files =
 [test_DominatorTreeNode_insert_01.js]
 [test_DominatorTreeNode_insert_02.js]
 [test_DominatorTreeNode_insert_03.js]
 [test_DominatorTreeNode_LabelAndShallowSize_01.js]
 [test_DominatorTreeNode_LabelAndShallowSize_02.js]
 [test_DominatorTreeNode_LabelAndShallowSize_03.js]
 [test_DominatorTreeNode_LabelAndShallowSize_04.js]
 [test_DominatorTreeNode_partialTraversal_01.js]
+[test_getCensusIndividuals_01.js]
 [test_getReportLeaves_01.js]
 [test_HeapAnalyses_computeDominatorTree_01.js]
 [test_HeapAnalyses_computeDominatorTree_02.js]
 [test_HeapAnalyses_deleteHeapSnapshot_01.js]
 [test_HeapAnalyses_deleteHeapSnapshot_02.js]
 [test_HeapAnalyses_deleteHeapSnapshot_03.js]
 [test_HeapAnalyses_getCreationTime_01.js]
 [test_HeapAnalyses_getDominatorTree_01.js]