Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/devtools/client/memory/components/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 14 kB image not shown  

Quelle  Heap.js   Sprache: JAVA

 
/* 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 {
  Component,
  createFactory,
} = require("resource://devtools/client/shared/vendor/react.js");
const dom = require("resource://devtools/client/shared/vendor/react-dom-factories.js");
const PropTypes = require("resource://devtools/client/shared/vendor/react-prop-types.js");
const {
  assert,
  safeErrorString,
} = require("resource://devtools/shared/DevToolsUtils.js");
const Census = createFactory(
  require("resource://devtools/client/memory/components/Census.js")
);
const CensusHeader = createFactory(
  require("resource://devtools/client/memory/components/CensusHeader.js")
);
const DominatorTree = createFactory(
  require("resource://devtools/client/memory/components/DominatorTree.js")
);
const DominatorTreeHeader = createFactory(
  require("resource://devtools/client/memory/components/DominatorTreeHeader.js")
);
const TreeMap = createFactory(
  require("resource://devtools/client/memory/components/TreeMap.js")
);
const HSplitBox = createFactory(
  require("resource://devtools/client/shared/components/HSplitBox.js")
);
const Individuals = createFactory(
  require("resource://devtools/client/memory/components/Individuals.js")
);
const IndividualsHeader = createFactory(
  require("resource://devtools/client/memory/components/IndividualsHeader.js")
);
const ShortestPaths = createFactory(
  require("resource://devtools/client/memory/components/ShortestPaths.js")
);
const {
  getStatusTextFull,
  L10N,
} = require("resource://devtools/client/memory/utils.js");
const {
  snapshotState: states,
  diffingState,
  viewState,
  censusState,
  treeMapState,
  dominatorTreeState,
  individualsState,
} = require("resource://devtools/client/memory/constants.js");
const models = require("resource://devtools/client/memory/models.js");
const { snapshot: snapshotModel, diffingModel } = models;

/**
 * Get the app state's current state atom.
 *
 * @see the relevant state string constants in `../constants.js`.
 *
 * @param {models.view} view
 * @param {snapshotModel} snapshot
 * @param {diffingModel} diffing
 * @param {individualsModel} individuals
 *
 * @return {snapshotState|diffingState|dominatorTreeState}
 */

function getState(view, snapshot, diffing, individuals) {
  switch (view.state) {
    case viewState.CENSUS:
      return snapshot.census ? snapshot.census.state : snapshot.state;

    case viewState.DIFFING:
      return diffing.state;

    case viewState.TREE_MAP:
      return snapshot.treeMap ? snapshot.treeMap.state : snapshot.state;

    case viewState.DOMINATOR_TREE:
      return snapshot.dominatorTree
        ? snapshot.dominatorTree.state
        : snapshot.state;

    case viewState.INDIVIDUALS:
      return individuals.state;
  }

  assert(false, `Unexpected view state: ${view.state}`);
  return null;
}

/**
 * Return true if we should display a status message when we are in the given
 * state. Return false otherwise.
 *
 * @param {snapshotState|diffingState|dominatorTreeState} state
 * @param {models.view} view
 * @param {snapshotModel} snapshot
 *
 * @returns {Boolean}
 */

function shouldDisplayStatus(state, view, snapshot) {
  switch (state) {
    case states.IMPORTING:
    case states.SAVING:
    case states.SAVED:
    case states.READING:
    case censusState.SAVING:
    case treeMapState.SAVING:
    case diffingState.SELECTING:
    case diffingState.TAKING_DIFF:
    case dominatorTreeState.COMPUTING:
    case dominatorTreeState.COMPUTED:
    case dominatorTreeState.FETCHING:
    case individualsState.COMPUTING_DOMINATOR_TREE:
    case individualsState.FETCHING:
      return true;
  }
  return view.state === viewState.DOMINATOR_TREE && !snapshot.dominatorTree;
}

/**
 * Get the status text to display for the given state.
 *
 * @param {snapshotState|diffingState|dominatorTreeState} state
 * @param {diffingModel} diffing
 *
 * @returns {String}
 */

function getStateStatusText(state, diffing) {
  if (state === diffingState.SELECTING) {
    return L10N.getStr(
      diffing.firstSnapshotId === null
        ? "diffing.prompt.selectBaseline"
        : "diffing.prompt.selectComparison"
    );
  }

  return getStatusTextFull(state);
}

/**
 * Given that we should display a status message, return true if we should also
 * display a throbber along with the status message. Return false otherwise.
 *
 * @param {diffingModel} diffing
 *
 * @returns {Boolean}
 */

function shouldDisplayThrobber(diffing) {
  return !diffing || diffing.state !== diffingState.SELECTING;
}

/**
 * Get the current state's error, or return null if there is none.
 *
 * @param {snapshotModel} snapshot
 * @param {diffingModel} diffing
 * @param {individualsModel} individuals
 *
 * @returns {Error|null}
 */

function getError(snapshot, diffing, individuals) {
  if (diffing) {
    if (diffing.state === diffingState.ERROR) {
      return diffing.error;
    }
    if (diffing.census === censusState.ERROR) {
      return diffing.census.error;
    }
  }

  if (snapshot) {
    if (snapshot.state === states.ERROR) {
      return snapshot.error;
    }

    if (snapshot.census === censusState.ERROR) {
      return snapshot.census.error;
    }

    if (snapshot.treeMap === treeMapState.ERROR) {
      return snapshot.treeMap.error;
    }

    if (
      snapshot.dominatorTree &&
      snapshot.dominatorTree.state === dominatorTreeState.ERROR
    ) {
      return snapshot.dominatorTree.error;
    }
  }

  if (individuals && individuals.state === individualsState.ERROR) {
    return individuals.error;
  }

  return null;
}

/**
 * Main view for the memory tool.
 *
 * The Heap component contains several panels for different states; an initial
 * state of only a button to take a snapshot, loading states, the census view
 * tree, the dominator tree, etc.
 */

class Heap extends Component {
  static get propTypes() {
    return {
      onSnapshotClick: PropTypes.func.isRequired,
      onLoadMoreSiblings: PropTypes.func.isRequired,
      onCensusExpand: PropTypes.func.isRequired,
      onCensusCollapse: PropTypes.func.isRequired,
      onDominatorTreeExpand: PropTypes.func.isRequired,
      onDominatorTreeCollapse: PropTypes.func.isRequired,
      onCensusFocus: PropTypes.func.isRequired,
      onDominatorTreeFocus: PropTypes.func.isRequired,
      onShortestPathsResize: PropTypes.func.isRequired,
      snapshot: snapshotModel,
      onViewSourceInDebugger: PropTypes.func.isRequired,
      onPopView: PropTypes.func.isRequired,
      individuals: models.individuals,
      onViewIndividuals: PropTypes.func.isRequired,
      onFocusIndividual: PropTypes.func.isRequired,
      diffing: diffingModel,
      view: models.view.isRequired,
      sizes: PropTypes.object.isRequired,
    };
  }

  constructor(props) {
    super(props);
    this._renderHeapView = this._renderHeapView.bind(this);
    this._renderInitial = this._renderInitial.bind(this);
    this._renderStatus = this._renderStatus.bind(this);
    this._renderError = this._renderError.bind(this);
    this._renderCensus = this._renderCensus.bind(this);
    this._renderTreeMap = this._renderTreeMap.bind(this);
    this._renderIndividuals = this._renderIndividuals.bind(this);
    this._renderDominatorTree = this._renderDominatorTree.bind(this);
  }

  /**
   * Render the heap view's container panel with the given contents inside of
   * it.
   *
   * @param {snapshotState|diffingState|dominatorTreeState} state
   * @param {...Any} contents
   */

  _renderHeapView(state, ...contents) {
    return dom.div(
      {
        id: "heap-view",
        "data-state": state,
      },
      dom.div(
        {
          className: "heap-view-panel",
          "data-state": state,
        },
        ...contents
      )
    );
  }

  _renderInitial(onSnapshotClick) {
    return this._renderHeapView(
      "initial",
      dom.button(
        {
          className: "devtools-button take-snapshot",
          onClick: onSnapshotClick,
          "data-standalone"true,
        },
        L10N.getStr("take-snapshot")
      )
    );
  }

  _renderStatus(state, statusText, diffing) {
    let throbber = "";
    if (shouldDisplayThrobber(diffing)) {
      throbber = "devtools-throbber";
    }

    return this._renderHeapView(
      state,
      dom.span(
        {
          className: `snapshot-status ${throbber}`,
        },
        statusText
      )
    );
  }

  _renderError(state, statusText, error) {
    return this._renderHeapView(
      state,
      dom.span({ className: "snapshot-status error" }, statusText),
      dom.pre({}, safeErrorString(error))
    );
  }

  _renderCensus(
    state,
    census,
    diffing,
    onViewSourceInDebugger,
    onViewIndividuals
  ) {
    assert(
      census.report,
      "Should not render census that does not have a report"
    );

    if (!census.report.children) {
      const censusFilterMsg = census.filter
        ? L10N.getStr("heapview.none-match")
        : L10N.getStr("heapview.empty");
      const msg = diffing
        ? L10N.getStr("heapview.no-difference")
        : censusFilterMsg;
      return this._renderHeapView(state, dom.div({ className: "empty" }, msg));
    }

    const contents = [];

    if (
      census.display.breakdown.by === "allocationStack" &&
      census.report.children &&
      census.report.children.length === 1 &&
      census.report.children[0].name === "noStack"
    ) {
      contents.push(
        dom.div(
          { className: "error no-allocation-stacks" },
          L10N.getStr("heapview.noAllocationStacks")
        )
      );
    }

    contents.push(CensusHeader({ diffing }));
    contents.push(
      Census({
        onViewSourceInDebugger,
        onViewIndividuals,
        diffing,
        census,
        onExpand: node => this.props.onCensusExpand(census, node),
        onCollapse: node => this.props.onCensusCollapse(census, node),
        onFocus: node => this.props.onCensusFocus(census, node),
      })
    );

    return this._renderHeapView(state, ...contents);
  }

  _renderTreeMap(state, treeMap) {
    return this._renderHeapView(state, TreeMap({ treeMap }));
  }

  _renderIndividuals(
    state,
    individuals,
    dominatorTree,
    onViewSourceInDebugger
  ) {
    assert(
      individuals.state === individualsState.FETCHED,
      "Should have fetched individuals"
    );
    assert(dominatorTree?.root, "Should have a dominator tree and its root");

    const tree = dom.div(
      {
        className: "vbox",
        style: {
          overflowY: "auto",
        },
      },
      IndividualsHeader(),
      Individuals({
        individuals,
        dominatorTree,
        onViewSourceInDebugger,
        onFocus: this.props.onFocusIndividual,
      })
    );

    const shortestPaths = ShortestPaths({
      graph: individuals.focused ? individuals.focused.shortestPaths : null,
    });

    return this._renderHeapView(
      state,
      dom.div(
        { className: "hbox devtools-toolbar" },
        dom.label(
          { id: "pop-view-button-label" },
          dom.button(
            {
              id: "pop-view-button",
              className: "devtools-button",
              onClick: this.props.onPopView,
            },
            L10N.getStr("toolbar.pop-view")
          ),
          L10N.getStr("toolbar.pop-view.label")
        ),
        dom.span(
          { className: "toolbar-text" },
          L10N.getStr("toolbar.viewing-individuals")
        )
      ),
      HSplitBox({
        start: tree,
        end: shortestPaths,
        startWidth: this.props.sizes.shortestPathsSize,
        onResize: this.props.onShortestPathsResize,
      })
    );
  }

  _renderDominatorTree(
    state,
    onViewSourceInDebugger,
    dominatorTree,
    onLoadMoreSiblings
  ) {
    const tree = dom.div(
      {
        className: "vbox",
        style: {
          overflowY: "auto",
        },
      },
      DominatorTreeHeader(),
      DominatorTree({
        onViewSourceInDebugger,
        dominatorTree,
        onLoadMoreSiblings,
        onExpand: this.props.onDominatorTreeExpand,
        onCollapse: this.props.onDominatorTreeCollapse,
        onFocus: this.props.onDominatorTreeFocus,
      })
    );

    const shortestPaths = ShortestPaths({
      graph: dominatorTree.focused ? dominatorTree.focused.shortestPaths : null,
    });

    return this._renderHeapView(
      state,
      HSplitBox({
        start: tree,
        end: shortestPaths,
        startWidth: this.props.sizes.shortestPathsSize,
        onResize: this.props.onShortestPathsResize,
      })
    );
  }

  render() {
    const {
      snapshot,
      diffing,
      onSnapshotClick,
      onLoadMoreSiblings,
      onViewSourceInDebugger,
      onViewIndividuals,
      individuals,
      view,
    } = this.props;

    if (!diffing && !snapshot && !individuals) {
      return this._renderInitial(onSnapshotClick);
    }

    const state = getState(view, snapshot, diffing, individuals);
    const statusText = getStateStatusText(state, diffing);

    if (shouldDisplayStatus(state, view, snapshot)) {
      return this._renderStatus(state, statusText, diffing);
    }

    const error = getError(snapshot, diffing, individuals);
    if (error) {
      return this._renderError(state, statusText, error);
    }

    if (view.state === viewState.CENSUS || view.state === viewState.DIFFING) {
      const census =
        view.state === viewState.CENSUS ? snapshot.census : diffing.census;
      if (!census) {
        return this._renderStatus(state, statusText, diffing);
      }
      return this._renderCensus(
        state,
        census,
        diffing,
        onViewSourceInDebugger,
        onViewIndividuals
      );
    }

    if (view.state === viewState.TREE_MAP) {
      return this._renderTreeMap(state, snapshot.treeMap);
    }

    if (view.state === viewState.INDIVIDUALS) {
      assert(
        individuals.state === individualsState.FETCHED,
        "Should have fetched the individuals -- " +
          "other states are rendered as statuses"
      );
      return this._renderIndividuals(
        state,
        individuals,
        individuals.dominatorTree,
        onViewSourceInDebugger
      );
    }

    assert(
      view.state === viewState.DOMINATOR_TREE,
      "If we aren't in progress, looking at a census, or diffing, then we " +
        "must be looking at a dominator tree"
    );
    assert(!diffing, "Should not have diffing");
    assert(snapshot.dominatorTree, "Should have a dominator tree");

    return this._renderDominatorTree(
      state,
      onViewSourceInDebugger,
      snapshot.dominatorTree,
      onLoadMoreSiblings
    );
  }
}

module.exports = Heap;

100%


¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.