UNPKG

prepack

Version:

Execute a JS bundle, serialize global state and side effects to a snapshot that can be quickly restored.

107 lines (78 loc) 2.71 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ResidualHeapRefCounter = void 0; var _invariant = _interopRequireDefault(require("../invariant.js")); var _index = require("../values/index.js"); var _HeapInspector = require("../utils/HeapInspector.js"); var _ResidualHeapVisitor = require("./ResidualHeapVisitor.js"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ /* strict-local */ /** * Record residual heap object's incoming and outgoing reference counts. */ class ResidualHeapRefCounter extends _ResidualHeapVisitor.ResidualHeapVisitor { constructor(realm, logger, modules, additionalFunctionValuesAndEffects) { super(realm, logger, modules, additionalFunctionValuesAndEffects); this._valueToEdgeRecord = new Map(); this._path = []; } // Contains the path of nodes from root to current visiting node. getResult() { return this._valueToEdgeRecord; } _shouldIgnore(val) { return val instanceof _index.EmptyValue || val.isIntrinsic() || _HeapInspector.HeapInspector.isLeaf(val); } preProcessValue(val) { if (this._shouldIgnore(val)) { return false; } if (this._path.length > 0) { this._updateParentOutgoingEdgeCount(); } this._path.push(val); return this._updateValueIncomingEdgeCount(val); } _updateParentOutgoingEdgeCount() { const parent = this._path[this._path.length - 1]; const edgeRecord = this._valueToEdgeRecord.get(parent); (0, _invariant.default)(edgeRecord); ++edgeRecord.outGoing; } _updateValueIncomingEdgeCount(val) { let edgeRecord = this._valueToEdgeRecord.get(val); if (edgeRecord === undefined) { this._valueToEdgeRecord.set(val, { inComing: 1, outGoing: 0 }); return true; } else { ++edgeRecord.inComing; return false; // visited node, skip its children. } } // Override. postProcessValue(val) { if (this._shouldIgnore(val)) { return; } (0, _invariant.default)(this._path.length > 0); this._path.pop(); } // Override. visitRoots() { super.visitRoots(); (0, _invariant.default)(this._path.length === 0, "Path should be balanced empty after traversal."); } } exports.ResidualHeapRefCounter = ResidualHeapRefCounter; //# sourceMappingURL=ResidualHeapRefCounter.js.map