118 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			118 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/*
 | 
						|
	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
						|
	Author Mark Knichel @mknichel
 | 
						|
*/
 | 
						|
 | 
						|
"use strict";
 | 
						|
 | 
						|
let dualStringBufferCaching = true;
 | 
						|
 | 
						|
/**
 | 
						|
 * @returns {boolean} Whether the optimization to cache copies of both the
 | 
						|
 * string and buffer version of source content is enabled. This is enabled by
 | 
						|
 * default to improve performance but can consume more memory since values are
 | 
						|
 * stored twice.
 | 
						|
 */
 | 
						|
function isDualStringBufferCachingEnabled() {
 | 
						|
	return dualStringBufferCaching;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Enables an optimization to save both string and buffer in memory to avoid
 | 
						|
 * repeat conversions between the two formats when they are requested. This
 | 
						|
 * is enabled by default. This option can improve performance but can consume
 | 
						|
 * additional memory since values are stored twice.
 | 
						|
 * @returns {void}
 | 
						|
 */
 | 
						|
function enableDualStringBufferCaching() {
 | 
						|
	dualStringBufferCaching = true;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Disables the optimization to save both string and buffer in memory. This
 | 
						|
 * may increase performance but should reduce memory usage in the Webpack
 | 
						|
 * compiler.
 | 
						|
 * @returns {void}
 | 
						|
 */
 | 
						|
function disableDualStringBufferCaching() {
 | 
						|
	dualStringBufferCaching = false;
 | 
						|
}
 | 
						|
 | 
						|
const interningStringMap = new Map();
 | 
						|
 | 
						|
let enableStringInterningRefCount = 0;
 | 
						|
 | 
						|
/**
 | 
						|
 * @returns {boolean} value
 | 
						|
 */
 | 
						|
function isStringInterningEnabled() {
 | 
						|
	return enableStringInterningRefCount > 0;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Starts a memory optimization to avoid repeat copies of the same string in
 | 
						|
 * memory by caching a single reference to the string. This can reduce memory
 | 
						|
 * usage if the same string is repeated many times in the compiler, such as
 | 
						|
 * when Webpack layers are used with the same files.
 | 
						|
 *
 | 
						|
 * {@link exitStringInterningRange} should be called when string interning is
 | 
						|
 * no longer necessary to free up the memory used by the interned strings. If
 | 
						|
 * {@link enterStringInterningRange} has been called multiple times, then
 | 
						|
 * this method may not immediately free all the memory until
 | 
						|
 * {@link exitStringInterningRange} has been called to end all string
 | 
						|
 * interning ranges.
 | 
						|
 * @returns {void}
 | 
						|
 */
 | 
						|
function enterStringInterningRange() {
 | 
						|
	enableStringInterningRefCount++;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Stops the current string interning range. Once all string interning ranges
 | 
						|
 * have been exited, this method will free all the memory used by the interned
 | 
						|
 * strings. This method should be called once for each time that
 | 
						|
 * {@link enterStringInterningRange} was called.
 | 
						|
 * @returns {void}
 | 
						|
 */
 | 
						|
function exitStringInterningRange() {
 | 
						|
	if (--enableStringInterningRefCount <= 0) {
 | 
						|
		interningStringMap.clear();
 | 
						|
		enableStringInterningRefCount = 0;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Saves the string in a map to ensure that only one copy of the string exists
 | 
						|
 * in memory at a given time. This is controlled by {@link enableStringInterning}
 | 
						|
 * and {@link disableStringInterning}. Callers are expect to manage the memory
 | 
						|
 * of the interned strings by calling {@link disableStringInterning} after the
 | 
						|
 * compiler no longer needs to save the interned memory.
 | 
						|
 * @param {string} str A string to be interned.
 | 
						|
 * @returns {string} The original string or a reference to an existing string of the same value if it has already been interned.
 | 
						|
 */
 | 
						|
function internString(str) {
 | 
						|
	if (
 | 
						|
		!isStringInterningEnabled() ||
 | 
						|
		!str ||
 | 
						|
		str.length < 128 ||
 | 
						|
		typeof str !== "string"
 | 
						|
	) {
 | 
						|
		return str;
 | 
						|
	}
 | 
						|
	let internedString = interningStringMap.get(str);
 | 
						|
	if (internedString === undefined) {
 | 
						|
		internedString = str;
 | 
						|
		interningStringMap.set(str, internedString);
 | 
						|
	}
 | 
						|
	return internedString;
 | 
						|
}
 | 
						|
 | 
						|
module.exports = {
 | 
						|
	disableDualStringBufferCaching,
 | 
						|
	enableDualStringBufferCaching,
 | 
						|
	internString,
 | 
						|
	isDualStringBufferCachingEnabled,
 | 
						|
	enterStringInterningRange,
 | 
						|
	exitStringInterningRange,
 | 
						|
};
 |