From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- devtools/client/memory/actions/diffing.js | 201 ++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 devtools/client/memory/actions/diffing.js (limited to 'devtools/client/memory/actions/diffing.js') diff --git a/devtools/client/memory/actions/diffing.js b/devtools/client/memory/actions/diffing.js new file mode 100644 index 000000000..70af307bb --- /dev/null +++ b/devtools/client/memory/actions/diffing.js @@ -0,0 +1,201 @@ +/* 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 { assert, reportException } = require("devtools/shared/DevToolsUtils"); +const { actions, diffingState, viewState } = require("../constants"); +const telemetry = require("../telemetry"); +const { + getSnapshot, + censusIsUpToDate, + snapshotIsDiffable, + findSelectedSnapshot, +} = require("../utils"); +// This is a circular dependency, so do not destructure the needed properties. +const snapshotActions = require("./snapshot"); + +/** + * Toggle diffing mode on or off. + */ +const toggleDiffing = exports.toggleDiffing = function () { + return function (dispatch, getState) { + dispatch({ + type: actions.CHANGE_VIEW, + newViewState: getState().diffing ? viewState.CENSUS : viewState.DIFFING, + oldDiffing: getState().diffing, + oldSelected: findSelectedSnapshot(getState()), + }); + }; +}; + +/** + * Select the given snapshot for diffing. + * + * @param {snapshotModel} snapshot + */ +const selectSnapshotForDiffing = exports.selectSnapshotForDiffing = function (snapshot) { + assert(snapshotIsDiffable(snapshot), + "To select a snapshot for diffing, it must be diffable"); + return { type: actions.SELECT_SNAPSHOT_FOR_DIFFING, snapshot }; +}; + +/** + * Compute the difference between the first and second snapshots. + * + * @param {HeapAnalysesClient} heapWorker + * @param {snapshotModel} first + * @param {snapshotModel} second + */ +const takeCensusDiff = exports.takeCensusDiff = function (heapWorker, first, second) { + return function* (dispatch, getState) { + assert(snapshotIsDiffable(first), + `First snapshot must be in a diffable state, found ${first.state}`); + assert(snapshotIsDiffable(second), + `Second snapshot must be in a diffable state, found ${second.state}`); + + let report, parentMap; + let display = getState().censusDisplay; + let filter = getState().filter; + + if (censusIsUpToDate(filter, display, getState().diffing.census)) { + return; + } + + do { + if (!getState().diffing + || getState().diffing.firstSnapshotId !== first.id + || getState().diffing.secondSnapshotId !== second.id) { + // If we stopped diffing or stopped and then started diffing a different + // pair of snapshots, then just give up with diffing this pair. In the + // latter case, a newly spawned task will handle the diffing for the new + // pair. + return; + } + + display = getState().censusDisplay; + filter = getState().filter; + + dispatch({ + type: actions.TAKE_CENSUS_DIFF_START, + first, + second, + filter, + display, + }); + + let opts = display.inverted + ? { asInvertedTreeNode: true } + : { asTreeNode: true }; + opts.filter = filter || null; + + try { + ({ delta: report, parentMap } = yield heapWorker.takeCensusDiff( + first.path, + second.path, + { breakdown: display.breakdown }, + opts)); + } catch (error) { + reportException("actions/diffing/takeCensusDiff", error); + dispatch({ type: actions.DIFFING_ERROR, error }); + return; + } + } + while (filter !== getState().filter + || display !== getState().censusDisplay); + + dispatch({ + type: actions.TAKE_CENSUS_DIFF_END, + first, + second, + report, + parentMap, + filter, + display, + }); + + telemetry.countDiff({ filter, display }); + }; +}; + +/** + * Ensure that the current diffing data is up to date with the currently + * selected display, filter, etc. If the state is not up-to-date, then a + * recompute is triggered. + * + * @param {HeapAnalysesClient} heapWorker + */ +const refreshDiffing = exports.refreshDiffing = function (heapWorker) { + return function* (dispatch, getState) { + if (getState().diffing.secondSnapshotId === null) { + return; + } + + assert(getState().diffing.firstSnapshotId, + "Should have first snapshot id"); + + if (getState().diffing.state === diffingState.TAKING_DIFF) { + // There is an existing task that will ensure that the diffing data is + // up-to-date. + return; + } + + const { firstSnapshotId, secondSnapshotId } = getState().diffing; + + const first = getSnapshot(getState(), firstSnapshotId); + const second = getSnapshot(getState(), secondSnapshotId); + dispatch(takeCensusDiff(heapWorker, first, second)); + }; +}; + +/** + * Select the given snapshot for diffing and refresh the diffing data if + * necessary (for example, if two snapshots are now selected for diffing). + * + * @param {HeapAnalysesClient} heapWorker + * @param {snapshotModel} snapshot + */ +const selectSnapshotForDiffingAndRefresh = exports.selectSnapshotForDiffingAndRefresh = function (heapWorker, snapshot) { + return function* (dispatch, getState) { + assert(getState().diffing, + "If we are selecting for diffing, we must be in diffing mode"); + dispatch(selectSnapshotForDiffing(snapshot)); + yield dispatch(refreshDiffing(heapWorker)); + }; +}; + +/** + * Expand the given node in the diffing's census's delta-report. + * + * @param {CensusTreeNode} node + */ +const expandDiffingCensusNode = exports.expandDiffingCensusNode = function (node) { + return { + type: actions.EXPAND_DIFFING_CENSUS_NODE, + node, + }; +}; + +/** + * Collapse the given node in the diffing's census's delta-report. + * + * @param {CensusTreeNode} node + */ +const collapseDiffingCensusNode = exports.collapseDiffingCensusNode = function (node) { + return { + type: actions.COLLAPSE_DIFFING_CENSUS_NODE, + node, + }; +}; + +/** + * Focus the given node in the snapshot's census's report. + * + * @param {DominatorTreeNode} node + */ +const focusDiffingCensusNode = exports.focusDiffingCensusNode = function (node) { + return { + type: actions.FOCUS_DIFFING_CENSUS_NODE, + node, + }; +}; -- cgit v1.2.3