Bug 1320196 - Avoid string concatenation when computing the hash for ImageCacheKey. r=tnikkel, a=jcristau
authorAndrew Osmond <aosmond@mozilla.com>
Fri, 25 Nov 2016 07:28:27 -0500
changeset 352706 35d579c4ff1e15f81d3ef70a3137afc218a99353
parent 352705 f3a55c57f637061f5258eb14ae29300a659da13a
child 352707 94dac74c74a6e462fbbf9a1e1cad9fda3024122e
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstnikkel, jcristau
bugs1320196
milestone52.0a2
Bug 1320196 - Avoid string concatenation when computing the hash for ImageCacheKey. r=tnikkel, a=jcristau
image/ImageCacheKey.cpp
image/ImageURL.h
--- a/image/ImageCacheKey.cpp
+++ b/image/ImageCacheKey.cpp
@@ -136,31 +136,18 @@ ImageCacheKey::ComputeHash(ImageURL* aUR
 {
   // Since we frequently call Hash() several times in a row on the same
   // ImageCacheKey, as an optimization we compute our hash once and store it.
 
   nsPrintfCString ptr("%p", aControlledDocument);
   nsAutoCString suffix;
   aAttrs.CreateSuffix(suffix);
 
-  if (aBlobSerial) {
-    // For blob URIs, we hash the serial number of the underlying blob, so that
-    // different blob URIs which point to the same blob share a cache entry. We
-    // also include the ref portion of the URI to support -moz-samplesize, which
-    // requires us to create different Image objects even if the source data is
-    // the same.
-    nsAutoCString ref;
-    aURI->GetRef(ref);
-    return HashGeneric(*aBlobSerial, HashString(ref + suffix + ptr));
-  }
-
-  // For non-blob URIs, we hash the URI spec.
-  nsAutoCString spec;
-  aURI->GetSpec(spec);
-  return HashString(spec + suffix + ptr);
+  return AddToHash(0, aURI->ComputeHash(aBlobSerial),
+                   HashString(suffix), HashString(ptr));
 }
 
 /* static */ void*
 ImageCacheKey::GetControlledDocumentToken(nsIDocument* aDocument)
 {
   // For non-controlled documents, we just return null.  For controlled
   // documents, we cast the pointer into a void* to avoid dereferencing
   // it (since we only use it for comparisons), and return it.
--- a/image/ImageURL.h
+++ b/image/ImageURL.h
@@ -4,20 +4,24 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_image_ImageURL_h
 #define mozilla_image_ImageURL_h
 
 #include "nsIURI.h"
 #include "MainThreadUtils.h"
 #include "nsNetUtil.h"
+#include "mozilla/HashFunctions.h"
+#include "nsHashKeys.h"
 
 namespace mozilla {
 namespace image {
 
+class ImageCacheKey;
+
 /** ImageURL
  *
  * nsStandardURL is not threadsafe, so this class is created to hold only the
  * necessary URL data required for image loading and decoding.
  *
  * Note: Although several APIs have the same or similar prototypes as those
  * found in nsIURI/nsStandardURL, the class does not implement nsIURI. This is
  * intentional; functionality is limited, and is only useful for imagelib code.
@@ -108,16 +112,32 @@ public:
   }
 
   bool HasSameRef(const ImageURL& aOther) const
   {
     return mRef == aOther.mRef;
   }
 
 private:
+  friend class ImageCacheKey;
+
+  uint32_t ComputeHash(const Maybe<uint64_t>& aBlobSerial) const
+  {
+    if (aBlobSerial) {
+      // For blob URIs, we hash the serial number of the underlying blob, so that
+      // different blob URIs which point to the same blob share a cache entry. We
+      // also include the ref portion of the URI to support media fragments which
+      // requires us to create different Image objects even if the source data is
+      // the same.
+      return HashGeneric(*aBlobSerial, HashString(mRef));
+    }
+    // For non-blob URIs, we hash the URI spec.
+    return HashString(mSpec);
+  }
+
   // Since this is a basic storage class, no duplication of spec parsing is
   // included in the functionality. Instead, the class depends upon the
   // parsing implementation in the nsIURI class used in object construction.
   // This means each field is stored separately, but since only a few are
   // required, this small memory tradeoff for threadsafe usage should be ok.
   nsAutoCString mSpec;
   nsAutoCString mScheme;
   nsAutoCString mRef;