This commit introduces `{ by: "bucket" }` breakdown type. Similar to `by:
"count"`, this breakdown type is a leaf and doesn't further categorize or filter
nodes that it counts. Instead, it accumulates them in a bucket and reports them
as a array of node IDs.
MozReview-Commit-ID: EeyWlrj9ujf
This commit adds the `computeShortestPaths` method to the `HeapSnapshot` webidl
interface. It implements this new method on the
`mozilla::devtools::HeapSnapshot` class.
When filtering, we were merging total counts and total bytes as we added
matching paths from the unfiltered tree into the new, filtered tree. This was
incorrect, and caused us to double, triple, ... count the totals.
This makes attempts to use the HeapAnalysesClient after the worker has already
been destroyed into an earlier, less quiet error so we can catch more of them
and catch them sooner.
The condition checked when reporting whether there were `moreChildrenAvailable`
when constructing the initial DominatorTreeNode tree from a DominatorTree was
backwards. This commit fixes the condition and adds a test that fails without
the condition fix.
This adds a new test for dominator trees computed from heap snapshots, to make
sure that a node's retained size matches the following:
retainedSize(node) = shallowSize(node) + sum(retainedSize(c) for c in children(node))
This test did not find the bug described in bug 1241221, but seems like a
valuable test to have anyways.
These two tests have been intermittently failing on WinXP because the
`Date.now()` timers only have a granularity of +/- 15 milliseconds on that
platform. This commit ensures that we have a range of at least 30 milliseconds
before and after taking the snapshot to ensure that the snapshot's timestamp
will fit within the range.
This commit adds the `DominatorTreeNode.insert` method to insert new
DominatorTreeNode children that have just been loaded from the
HeapAnalysesWorker into an existing partially complete DominatorTreeNode
tree. This is done in a persistent and immutable fashion so that we can use
=== to differentiate different generations of `DominatorTreeNode` trees but
still share the vast majority of the underlying structure.
As infrastructure for the insertion, HeapAnalysesWorker's
`getImmediatelyDominated` response also returns the path from the root to the
node whose immediately dominated children are being fetched. This makes it much
easier to know where to insert the newly loaded children.
This commit implements the HeapSnapshot.describeNode method which allows chrome
JS code to request a description of a given node as specified by our existing
"breakdown" language. This description can be used to generate a human-readable
label for the node.
This commit defines `DominatorTreeNode`, a JS class representing a node in a
heap snapshot's dominator tree. Three heap analysis client/worker
request/responses request and create these `DominatorTreeNode`s. Unlike
censuses, dominator trees are too big to practically mirror in memory as JS
object structures. Instead, we have one request to get a partial/shallow
representation of the tree starting from the root, and another to get subsequent
children and siblings in the tree. This allows for incremental, lazy, and
bounded mirroring of the dominator tree as `DominatorTreeNode`s.
This commit adds the `getImmediateDominator` method to `DominatorTree` which
returns the id of the immediate dominator of the node associated with the given
id. This enables walking the dominator tree from leaves up parents all the way
to the root of the tree.
This adds the `getImmediatelyDominated` method to `DominatorTree` which takes a
node id and returns the set of each node ids for every node that is immediately
dominated by the node with the given id. The results are sorted by greatest to
least retained size. In conjunction with the `root` attribute, this can be used
to traverse the whole dominator tree.
This commit adds the DominatorTree.webidl interface, which is only exposed to
chrome JS. The interface is implemented by mozilla::devtools::DominatorTree,
which is a thin wrapper around JS::ubi::DominatorTree. This does not expose any
methods on the DominatorTree interface, those will come as follow up changesets.