diff options
Diffstat (limited to 'node_modules/webpack/lib/optimize/RemoveParentModulesPlugin.js')
| -rw-r--r-- | node_modules/webpack/lib/optimize/RemoveParentModulesPlugin.js | 204 |
1 files changed, 0 insertions, 204 deletions
diff --git a/node_modules/webpack/lib/optimize/RemoveParentModulesPlugin.js b/node_modules/webpack/lib/optimize/RemoveParentModulesPlugin.js deleted file mode 100644 index 8c244ec5..00000000 --- a/node_modules/webpack/lib/optimize/RemoveParentModulesPlugin.js +++ /dev/null @@ -1,204 +0,0 @@ -/* - MIT License http://www.opensource.org/licenses/mit-license.php - Author Tobias Koppers @sokra -*/ - -"use strict"; - -const { STAGE_BASIC } = require("../OptimizationStages"); - -/** @typedef {import("../Chunk")} Chunk */ -/** @typedef {import("../ChunkGroup")} ChunkGroup */ -/** @typedef {import("../Compiler")} Compiler */ -/** @typedef {import("../Module")} Module */ - -/** - * Intersects multiple masks represented as bigints - * @param {bigint[]} masks The module masks to intersect - * @returns {bigint} The intersection of all masks - */ -function intersectMasks(masks) { - let result = masks[0]; - for (let i = masks.length - 1; i >= 1; i--) { - result &= masks[i]; - } - return result; -} - -const ZERO_BIGINT = BigInt(0); -const ONE_BIGINT = BigInt(1); -const THIRTY_TWO_BIGINT = BigInt(32); - -/** - * Parses the module mask and returns the modules represented by it - * @param {bigint} mask the module mask - * @param {Module[]} ordinalModules the modules in the order they were added to the mask (LSB is index 0) - * @returns {Generator<Module>} the modules represented by the mask - */ -function* getModulesFromMask(mask, ordinalModules) { - let offset = 31; - while (mask !== ZERO_BIGINT) { - // Consider the last 32 bits, since that's what Math.clz32 can handle - let last32 = Number(BigInt.asUintN(32, mask)); - while (last32 > 0) { - const last = Math.clz32(last32); - // The number of trailing zeros is the number trimmed off the input mask + 31 - the number of leading zeros - // The 32 is baked into the initial value of offset - const moduleIndex = offset - last; - // The number of trailing zeros is the index into the array generated by getOrCreateModuleMask - const module = ordinalModules[moduleIndex]; - yield module; - // Remove the matched module from the mask - // Since we can only count leading zeros, not trailing, we can't just downshift the mask - last32 &= ~(1 << (31 - last)); - } - - // Remove the processed chunk from the mask - mask >>= THIRTY_TWO_BIGINT; - offset += 32; - } -} - -class RemoveParentModulesPlugin { - /** - * @param {Compiler} compiler the compiler - * @returns {void} - */ - apply(compiler) { - compiler.hooks.compilation.tap("RemoveParentModulesPlugin", compilation => { - /** - * @param {Iterable<Chunk>} chunks the chunks - * @param {ChunkGroup[]} chunkGroups the chunk groups - */ - const handler = (chunks, chunkGroups) => { - const chunkGraph = compilation.chunkGraph; - const queue = new Set(); - const availableModulesMap = new WeakMap(); - - let nextModuleMask = ONE_BIGINT; - const maskByModule = new WeakMap(); - /** @type {Module[]} */ - const ordinalModules = []; - - /** - * Gets or creates a unique mask for a module - * @param {Module} mod the module to get the mask for - * @returns {bigint} the module mask to uniquely identify the module - */ - const getOrCreateModuleMask = mod => { - let id = maskByModule.get(mod); - if (id === undefined) { - id = nextModuleMask; - ordinalModules.push(mod); - maskByModule.set(mod, id); - nextModuleMask <<= ONE_BIGINT; - } - return id; - }; - - // Initialize masks by chunk and by chunk group for quicker comparisons - const chunkMasks = new WeakMap(); - for (const chunk of chunks) { - let mask = ZERO_BIGINT; - for (const m of chunkGraph.getChunkModulesIterable(chunk)) { - const id = getOrCreateModuleMask(m); - mask |= id; - } - chunkMasks.set(chunk, mask); - } - - const chunkGroupMasks = new WeakMap(); - for (const chunkGroup of chunkGroups) { - let mask = ZERO_BIGINT; - for (const chunk of chunkGroup.chunks) { - const chunkMask = chunkMasks.get(chunk); - if (chunkMask !== undefined) { - mask |= chunkMask; - } - } - chunkGroupMasks.set(chunkGroup, mask); - } - - for (const chunkGroup of compilation.entrypoints.values()) { - // initialize available modules for chunks without parents - availableModulesMap.set(chunkGroup, ZERO_BIGINT); - for (const child of chunkGroup.childrenIterable) { - queue.add(child); - } - } - for (const chunkGroup of compilation.asyncEntrypoints) { - // initialize available modules for chunks without parents - availableModulesMap.set(chunkGroup, ZERO_BIGINT); - for (const child of chunkGroup.childrenIterable) { - queue.add(child); - } - } - - for (const chunkGroup of queue) { - let availableModulesMask = availableModulesMap.get(chunkGroup); - let changed = false; - for (const parent of chunkGroup.parentsIterable) { - const availableModulesInParent = availableModulesMap.get(parent); - if (availableModulesInParent !== undefined) { - const parentMask = - availableModulesInParent | chunkGroupMasks.get(parent); - // If we know the available modules in parent: process these - if (availableModulesMask === undefined) { - // if we have not own info yet: create new entry - availableModulesMask = parentMask; - changed = true; - } else { - const newMask = availableModulesMask & parentMask; - if (newMask !== availableModulesMask) { - changed = true; - availableModulesMask = newMask; - } - } - } - } - - if (changed) { - availableModulesMap.set(chunkGroup, availableModulesMask); - // if something changed: enqueue our children - for (const child of chunkGroup.childrenIterable) { - // Push the child to the end of the queue - queue.delete(child); - queue.add(child); - } - } - } - - // now we have available modules for every chunk - for (const chunk of chunks) { - const chunkMask = chunkMasks.get(chunk); - if (chunkMask === undefined) continue; // No info about this chunk - - const availableModulesSets = Array.from( - chunk.groupsIterable, - chunkGroup => availableModulesMap.get(chunkGroup) - ); - if (availableModulesSets.includes(undefined)) continue; // No info about this chunk group - - const availableModulesMask = intersectMasks(availableModulesSets); - const toRemoveMask = chunkMask & availableModulesMask; - if (toRemoveMask !== ZERO_BIGINT) { - for (const module of getModulesFromMask( - toRemoveMask, - ordinalModules - )) { - chunkGraph.disconnectChunkAndModule(chunk, module); - } - } - } - }; - compilation.hooks.optimizeChunks.tap( - { - name: "RemoveParentModulesPlugin", - stage: STAGE_BASIC - }, - handler - ); - }); - } -} -module.exports = RemoveParentModulesPlugin; |
