Bug 1170258 - Add cache of node style module resolutions.
MozReview-Commit-ID: 2fb8aWYzs5L
--- a/addon-sdk/source/lib/toolkit/loader.js
+++ b/addon-sdk/source/lib/toolkit/loader.js
@@ -463,17 +463,35 @@ const nodeResolve = iced(function nodeRe
return stripBase(rootURI, resolvedPath);
}
// We would not find lookup for things like `sdk/tabs`, as that's part of
// the alias mapping. If during `generateMap`, the runtime lookup resolves
// with `resolveURI` -- if during runtime, then `resolve` will throw.
return void 0;
});
-Loader.nodeResolve = nodeResolve;
+
+// String (`${rootURI}:${requirer}:${id}`) -> resolvedPath
+Loader.nodeResolverCache = new Map();
+
+const nodeResolveWithCache = iced(function cacheNodeResolutions(id, requirer, { rootURI }) {
+ // Compute the cache key based on current arguments.
+ let cacheKey = `${rootURI || ""}:${requirer}:${id}`;
+
+ // Try to get the result from the cache.
+ if (Loader.nodeResolverCache.has(cacheKey)) {
+ return Loader.nodeResolverCache.get(cacheKey);
+ }
+
+ // Resolve and cache if it is not in the cache yet.
+ let result = nodeResolve(id, requirer, { rootURI });
+ Loader.nodeResolverCache.set(cacheKey, result);
+ return result;
+});
+Loader.nodeResolve = nodeResolveWithCache;
// Attempts to load `path` and then `path.js`
// Returns `path` with valid file, or `undefined` otherwise
function loadAsFile (path) {
let found;
// As per node's loader spec,
// we first should try and load 'path' (with no extension)
@@ -779,16 +797,19 @@ const Module = iced(function Module(id,
uri: { value: uri }
});
});
Loader.Module = Module;
// Takes `loader`, and unload `reason` string and notifies all observers that
// they should cleanup after them-self.
const unload = iced(function unload(loader, reason) {
+ // Clear the nodeResolverCache when the loader is unloaded.
+ Loader.nodeResolverCache.clear();
+
// subject is a unique object created per loader instance.
// This allows any code to cleanup on loader unload regardless of how
// it was loaded. To handle unload for specific loader subject may be
// asserted against loader.destructor or require('@loader/unload')
// Note: We don not destroy loader's module cache or sandboxes map as
// some modules may do cleanup in subsequent turns of event loop. Destroying
// cache may cause module identity problems in such cases.
let subject = { wrappedJSObject: loader.destructor };