Bug 1170258 - Add cache of node style module resolutions. draft
authorLuca Greco <lgreco@mozilla.com>
Thu, 02 Jun 2016 11:38:50 +0200
changeset 374994 b70252cf8381ab5464f08ff83cf83f922c8b9950
parent 369674 e594053a76d599d8aa4d0864d3278a48edf466d5
child 522738 ce90e4c0c4a0193312608faaa50243c98d9fc05c
push id20140
push userluca.greco@alcacoop.it
push dateFri, 03 Jun 2016 07:13:49 +0000
bugs1170258
milestone49.0a1
Bug 1170258 - Add cache of node style module resolutions. MozReview-Commit-ID: 2fb8aWYzs5L
addon-sdk/source/lib/toolkit/loader.js
--- 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 };