Bug 1391472: Part 2 - Cache normalized icon data for non-string values. r?mixedpuppy draft
authorKris Maglione <maglione.k@gmail.com>
Thu, 17 Aug 2017 17:00:45 -0700
changeset 648568 509ad0dd471faa6ff29eebb04d4983b76ebb1d06
parent 648567 ba7746cde8506010524a79ed5b145ad42352287f
child 726860 f86721b4371239100e9bdedd66daa15cb38be499
push id74797
push usermaglione.k@gmail.com
push dateFri, 18 Aug 2017 00:01:32 +0000
reviewersmixedpuppy
bugs1391472
milestone57.0a1
Bug 1391472: Part 2 - Cache normalized icon data for non-string values. r?mixedpuppy It turns out that stringifying a paths object is much cheaper than normalizing it, and has the added benefit of allowing us to use cached CSS text for the result. MozReview-Commit-ID: 5gIqcDmPiKr
toolkit/components/extensions/ExtensionParent.jsm
--- a/toolkit/components/extensions/ExtensionParent.jsm
+++ b/toolkit/components/extensions/ExtensionParent.jsm
@@ -40,16 +40,17 @@ Cu.import("resource://gre/modules/Extens
 var {
   BaseContext,
   CanOfAPIs,
   SchemaAPIManager,
   SpreadArgs,
 } = ExtensionCommon;
 
 var {
+  DefaultMap,
   DefaultWeakMap,
   ExtensionError,
   MessageManagerProxy,
   defineLazyGetter,
   promiseDocumentLoaded,
   promiseEvent,
   promiseFileContents,
   promiseObserved,
@@ -1219,38 +1220,41 @@ function extensionNameFromURI(uri) {
   }
   return GlobalManager.getExtension(id).name;
 }
 
 // Manages icon details for toolbar buttons in the |pageAction| and
 // |browserAction| APIs.
 let IconDetails = {
   // WeakMap<Extension -> Map<url-string -> object>>
-  iconCache: new DefaultWeakMap(() => new Map()),
+  iconCache: new DefaultWeakMap(() => new DefaultMap(() => new Map())),
 
   // Normalizes the various acceptable input formats into an object
   // with icon size as key and icon URL as value.
   //
   // If a context is specified (function is called from an extension):
   // Throws an error if an invalid icon size was provided or the
   // extension is not allowed to load the specified resources.
   //
   // If no context is specified, instead of throwing an error, this
   // function simply logs a warning message.
   normalize(details, extension, context = null) {
-    if (!details.imageData && typeof details.path === "string") {
-      let icons = this.iconCache.get(extension);
+    if (!details.imageData && details.path) {
+      let key = details.path;
+      if (typeof key !== "string") {
+        key = uneval(key);
+      }
 
-      let baseURI = context ? context.uri : extension.baseURI;
-      let url = baseURI.resolve(details.path);
+      let icons = this.iconCache.get(extension)
+                      .get(context && context.uri.spec);
 
-      let icon = icons.get(url);
+      let icon = icons.get(key);
       if (!icon) {
         icon = this._normalize(details, extension, context);
-        icons.set(url, icon);
+        icons.set(key, icon);
       }
       return icon;
     }
 
     return this._normalize(details, extension, context);
   },
 
   _normalize(details, extension, context = null) {