Bug 1320196 - Avoid string concatenation when computing the hash for ImageCacheKey. r=tnikkel
authorAndrew Osmond <aosmond@mozilla.com>
Fri, 25 Nov 2016 07:28:27 -0500
changeset 324314 b8cdb59ac18b8f2d3733d3b90e3433693bb233c4
parent 324313 11c4b40810daba7ecf6153b83cfa7a102be75575
child 324315 a7966a6adb3d61a2c2b495391f08f49ae035a645
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewerstnikkel
bugs1320196
milestone53.0a1
Bug 1320196 - Avoid string concatenation when computing the hash for ImageCacheKey. r=tnikkel
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 media fragments 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;