Bug 984008, part 2 - Convert nsWebBrowserPersist::mOutputMap to nsClassHashtable. r=ehsan
authorAndrew McCreight <continuation@gmail.com>
Mon, 17 Mar 2014 10:21:26 -0700
changeset 173947 18944b83451149777abb22d9e103139edef81794
parent 173946 a1d7d5b1bd92fc61af45fdec648a29cd2bf9bc4b
child 173948 eb0d9222174b457bfd0d354d010a6dcc87414740
push id26438
push userphilringnalda@gmail.com
push dateTue, 18 Mar 2014 05:39:07 +0000
treeherdermozilla-central@89275f0ae29f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs984008
milestone30.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 984008, part 2 - Convert nsWebBrowserPersist::mOutputMap to nsClassHashtable. r=ehsan
embedding/components/webbrowserpersist/src/nsWebBrowserPersist.cpp
embedding/components/webbrowserpersist/src/nsWebBrowserPersist.h
--- a/embedding/components/webbrowserpersist/src/nsWebBrowserPersist.cpp
+++ b/embedding/components/webbrowserpersist/src/nsWebBrowserPersist.cpp
@@ -622,35 +622,35 @@ NS_IMETHODIMP nsWebBrowserPersist::OnSta
     }
 
     mJustStartedLoading = false;
 
     nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
     NS_ENSURE_TRUE(channel, NS_ERROR_FAILURE);
 
     nsCOMPtr<nsISupports> keyPtr = do_QueryInterface(request);
-    nsISupportsKey key(keyPtr);
-    OutputData *data = (OutputData *) mOutputMap.Get(&key);
+    OutputData *data = mOutputMap.Get(keyPtr);
 
     // NOTE: This code uses the channel as a hash key so it will not
     //       recognize redirected channels because the key is not the same.
     //       When that happens we remove and add the data entry to use the
     //       new channel as the hash key.
     if (!data)
     {
+        nsISupportsKey key(keyPtr);
         UploadData *upData = (UploadData *) mUploadList.Get(&key);
         if (!upData)
         {
             // Redirect? Try and fixup the output table
             nsresult rv = FixRedirectedChannelEntry(channel);
             NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
 
             // Should be able to find the data after fixup unless redirects
             // are disabled.
-            data = (OutputData *) mOutputMap.Get(&key);
+            data = mOutputMap.Get(keyPtr);
             if (!data)
             {
                 return NS_ERROR_FAILURE;
             }
         }
     }
 
     if (data && data->mFile)
@@ -674,46 +674,44 @@ NS_IMETHODIMP nsWebBrowserPersist::OnSta
         }
 
         // compare uris and bail before we add to output map if they are equal
         bool isEqual = false;
         if (NS_SUCCEEDED(data->mFile->Equals(data->mOriginalLocation, &isEqual))
             && isEqual)
         {
             // remove from output map
-            delete data;
-            mOutputMap.Remove(&key);
+            mOutputMap.Remove(keyPtr);
 
             // cancel; we don't need to know any more
             // stop request will get called
             request->Cancel(NS_BINDING_ABORTED);
         }
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP nsWebBrowserPersist::OnStopRequest(
     nsIRequest* request, nsISupports *ctxt, nsresult status)
 {
     nsCOMPtr<nsISupports> keyPtr = do_QueryInterface(request);
-    nsISupportsKey key(keyPtr);
-    OutputData *data = (OutputData *) mOutputMap.Get(&key);
+    OutputData *data = mOutputMap.Get(keyPtr);
     if (data)
     {
         if (NS_SUCCEEDED(mPersistResult) && NS_FAILED(status))
             SendErrorStatusChange(true, status, request, data->mFile);
 
-        // This will close automatically close the output stream
-        delete data;
-        mOutputMap.Remove(&key);
+        // This will automatically close the output stream
+        mOutputMap.Remove(keyPtr);
     }
     else
     {
         // if we didn't find the data in mOutputMap, try mUploadList
+        nsISupportsKey key(keyPtr);
         UploadData *upData = (UploadData *) mUploadList.Get(&key);
         if (upData)
         {
             delete upData;
             mUploadList.Remove(&key);
         }
     }
 
@@ -779,18 +777,17 @@ nsWebBrowserPersist::OnDataAvailable(
     {
         nsresult rv = NS_OK;
         uint32_t bytesRemaining = aLength;
 
         nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
         NS_ENSURE_TRUE(channel, NS_ERROR_FAILURE);
 
         nsCOMPtr<nsISupports> keyPtr = do_QueryInterface(request);
-        nsISupportsKey key(keyPtr);
-        OutputData *data = (OutputData *) mOutputMap.Get(&key);
+        OutputData *data = mOutputMap.Get(keyPtr);
         if (!data) {
             // might be uploadData; consume necko's buffer and bail...
             uint32_t n;
             return aIStream->ReadSegments(NS_DiscardSegment, nullptr, aLength, &n);
         }
 
         bool readError = true;
 
@@ -916,25 +913,25 @@ NS_IMETHODIMP nsWebBrowserPersist::OnPro
 {
     if (!mProgressListener)
     {
         return NS_OK;
     }
 
     // Store the progress of this request
     nsCOMPtr<nsISupports> keyPtr = do_QueryInterface(request);
-    nsISupportsKey key(keyPtr);
-    OutputData *data = (OutputData *) mOutputMap.Get(&key);
+    OutputData *data = mOutputMap.Get(keyPtr);
     if (data)
     {
         data->mSelfProgress = int64_t(aProgress);
         data->mSelfProgressMax = int64_t(aProgressMax);
     }
     else
     {
+        nsISupportsKey key(keyPtr);
         UploadData *upData = (UploadData *) mUploadList.Get(&key);
         if (upData)
         {
             upData->mSelfProgress = int64_t(aProgress);
             upData->mSelfProgressMax = int64_t(aProgressMax);
         }
     }
 
@@ -1353,18 +1350,17 @@ nsresult nsWebBrowserPersist::SaveChanne
             EndDownload(NS_ERROR_FAILURE);
             return NS_ERROR_FAILURE;
         }
         return NS_SUCCESS_DONT_FIXUP;
     }
 
     // Add the output transport to the output map with the channel as the key
     nsCOMPtr<nsISupports> keyPtr = do_QueryInterface(aChannel);
-    nsISupportsKey key(keyPtr);
-    mOutputMap.Put(&key, new OutputData(aFile, mURI, aCalcFileExt));
+    mOutputMap.Put(keyPtr, new OutputData(aFile, mURI, aCalcFileExt));
 
     return NS_OK;
 }
 
 nsresult
 nsWebBrowserPersist::GetExtensionForContentType(const char16_t *aContentType, char16_t **aExt)
 {
     NS_ENSURE_ARG_POINTER(aContentType);
@@ -1769,18 +1765,18 @@ nsresult nsWebBrowserPersist::SaveDocume
 
     return rv;
 }
 
 void nsWebBrowserPersist::Cleanup()
 {
     mURIMap.Enumerate(EnumCleanupURIMap, this);
     mURIMap.Reset();
-    mOutputMap.Enumerate(EnumCleanupOutputMap, this);
-    mOutputMap.Reset();
+    mOutputMap.EnumerateRead(EnumCleanupOutputMap, this);
+    mOutputMap.Clear();
     mUploadList.Enumerate(EnumCleanupUploadList, this);
     mUploadList.Reset();
     uint32_t i;
     for (i = 0; i < mDocList.Length(); i++)
     {
         DocData *docData = mDocList.ElementAt(i);
         delete docData;
     }
@@ -2336,90 +2332,85 @@ public:
         return NS_OK;
     }
 };
 
 struct MOZ_STACK_CLASS FixRedirectData
 {
     nsCOMPtr<nsIChannel> mNewChannel;
     nsCOMPtr<nsIURI> mOriginalURI;
-    nsISupportsKey *mMatchingKey;
+    nsCOMPtr<nsISupports> mMatchingKey;
 };
 
 nsresult
 nsWebBrowserPersist::FixRedirectedChannelEntry(nsIChannel *aNewChannel)
 {
     NS_ENSURE_ARG_POINTER(aNewChannel);
     nsCOMPtr<nsIURI> originalURI;
 
     // Enumerate through existing open channels looking for one with
     // a URI matching the one specified.
 
     FixRedirectData data;
-    data.mMatchingKey = nullptr;
     data.mNewChannel = aNewChannel;
     data.mNewChannel->GetOriginalURI(getter_AddRefs(data.mOriginalURI));
-    mOutputMap.Enumerate(EnumFixRedirect, (void *) &data);
+    mOutputMap.EnumerateRead(EnumFixRedirect, &data);
 
     // If a match is found, remove the data entry with the old channel key
     // and re-add it with the new channel key.
 
     if (data.mMatchingKey)
     {
-        OutputData *outputData = (OutputData *) mOutputMap.Get(data.mMatchingKey);
+        nsAutoPtr<OutputData> outputData;
+        mOutputMap.RemoveAndForget(data.mMatchingKey, outputData);
         NS_ENSURE_TRUE(outputData, NS_ERROR_FAILURE);
-        mOutputMap.Remove(data.mMatchingKey);
 
         // Store data again with new channel unless told to ignore redirects
         if (!(mPersistFlags & PERSIST_FLAGS_IGNORE_REDIRECTED_DATA))
         {
             nsCOMPtr<nsISupports> keyPtr = do_QueryInterface(aNewChannel);
-            nsISupportsKey key(keyPtr);
-            mOutputMap.Put(&key, outputData);
+            mOutputMap.Put(keyPtr, outputData.forget());
         }
     }
 
     return NS_OK;
 }
 
-bool
-nsWebBrowserPersist::EnumFixRedirect(nsHashKey *aKey, void *aData, void* closure)
+PLDHashOperator
+nsWebBrowserPersist::EnumFixRedirect(nsISupports *aKey, OutputData *aData, void* aClosure)
 {
-    FixRedirectData *data = (FixRedirectData *) closure;
-
-    nsCOMPtr<nsISupports> keyPtr;
-    ((nsMyISupportsKey *) aKey)->GetISupports(getter_AddRefs(keyPtr));
-
-    nsCOMPtr<nsIChannel> thisChannel = do_QueryInterface(keyPtr);
+    FixRedirectData *data = static_cast<FixRedirectData *>(aClosure);
+
+    nsCOMPtr<nsIChannel> thisChannel = do_QueryInterface(aKey);
     nsCOMPtr<nsIURI> thisURI;
 
     thisChannel->GetOriginalURI(getter_AddRefs(thisURI));
 
     // Compare this channel's URI to the one passed in.
     bool matchingURI = false;
     thisURI->Equals(data->mOriginalURI, &matchingURI);
     if (matchingURI)
     {
-        data->mMatchingKey = (nsISupportsKey *) aKey;
-        return false; // Stop enumerating
+        data->mMatchingKey = aKey;
+        return PL_DHASH_STOP;
     }
 
-    return true;
+    return PL_DHASH_NEXT;
 }
 
 void
 nsWebBrowserPersist::CalcTotalProgress()
 {
     mTotalCurrentProgress = 0;
     mTotalMaxProgress = 0;
 
     if (mOutputMap.Count() > 0)
     {
         // Total up the progress of each output stream
-        mOutputMap.Enumerate(EnumCalcProgress, this);
+        mOutputMap.EnumerateRead(EnumCalcProgress, this);
     }
 
     if (mUploadList.Count() > 0)
     {
         // Total up the progress of each upload
         mUploadList.Enumerate(EnumCalcUploadProgress, this);
     }
 
@@ -2427,30 +2418,29 @@ nsWebBrowserPersist::CalcTotalProgress()
     if (mTotalCurrentProgress == 0 && mTotalMaxProgress == 0)
     {
         // No output streams so we must be complete
         mTotalCurrentProgress = 10000;
         mTotalMaxProgress = 10000;
     }
 }
 
-bool
-nsWebBrowserPersist::EnumCalcProgress(nsHashKey *aKey, void *aData, void* closure)
+PLDHashOperator
+nsWebBrowserPersist::EnumCalcProgress(nsISupports *aKey, OutputData *aData, void* aClosure)
 {
-    nsWebBrowserPersist *pthis = (nsWebBrowserPersist *) closure;
-    OutputData *data = (OutputData *) aData;
+    nsWebBrowserPersist *pthis = static_cast<nsWebBrowserPersist *>(aClosure);
 
     // only count toward total progress if destination file is local
-    nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(data->mFile);
+    nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(aData->mFile);
     if (fileURL)
     {
-        pthis->mTotalCurrentProgress += data->mSelfProgress;
-        pthis->mTotalMaxProgress += data->mSelfProgressMax;
+        pthis->mTotalCurrentProgress += aData->mSelfProgress;
+        pthis->mTotalMaxProgress += aData->mSelfProgressMax;
     }
-    return true;
+    return PL_DHASH_NEXT;
 }
 
 bool
 nsWebBrowserPersist::EnumCalcUploadProgress(nsHashKey *aKey, void *aData, void* closure)
 {
     if (aData && closure)
     {
         nsWebBrowserPersist *pthis = (nsWebBrowserPersist *) closure;
@@ -2520,29 +2510,25 @@ nsWebBrowserPersist::EnumPersistURIs(nsH
     }
 
     if (pthis->mSerializingOutput)
         return false;
 
     return true;
 }
 
-bool
-nsWebBrowserPersist::EnumCleanupOutputMap(nsHashKey *aKey, void *aData, void* closure)
+PLDHashOperator
+nsWebBrowserPersist::EnumCleanupOutputMap(nsISupports *aKey, OutputData *aData, void* aClosure)
 {
-    nsCOMPtr<nsISupports> keyPtr;
-    ((nsMyISupportsKey *) aKey)->GetISupports(getter_AddRefs(keyPtr));
-    nsCOMPtr<nsIChannel> channel = do_QueryInterface(keyPtr);
+    nsCOMPtr<nsIChannel> channel = do_QueryInterface(aKey);
     if (channel)
     {
         channel->Cancel(NS_BINDING_ABORTED);
     }
-    OutputData *data = (OutputData *) aData;
-    delete data;
-    return true;
+    return PL_DHASH_NEXT;
 }
 
 
 bool
 nsWebBrowserPersist::EnumCleanupURIMap(nsHashKey *aKey, void *aData, void* closure)
 {
     URIData *data = (URIData *) aData;
     delete data; // Delete data associated with key
--- a/embedding/components/webbrowserpersist/src/nsWebBrowserPersist.h
+++ b/embedding/components/webbrowserpersist/src/nsWebBrowserPersist.h
@@ -18,27 +18,30 @@
 #include "nsIChannel.h"
 #include "nsIStyleSheet.h"
 #include "nsIDocumentEncoder.h"
 #include "nsITransport.h"
 #include "nsIProgressEventSink.h"
 #include "nsIFile.h"
 #include "nsIWebProgressListener2.h"
 
+#include "nsClassHashtable.h"
 #include "nsHashtable.h"
+#include "nsHashKeys.h"
 #include "nsTArray.h"
 
 #include "nsCWebBrowserPersist.h"
 
 class nsEncoderNodeFixup;
 class nsIStorageStream;
 
-struct URIData;
 struct CleanupData;
 struct DocData;
+struct OutputData;
+struct URIData;
 
 class nsWebBrowserPersist : public nsIInterfaceRequestor,
                             public nsIWebBrowserPersist,
                             public nsIStreamListener,
                             public nsIProgressEventSink,
                             public nsSupportsWeakReference
 {
     friend class nsEncoderNodeFixup;
@@ -153,26 +156,26 @@ private:
 
     void SetApplyConversionIfNeeded(nsIChannel *aChannel);
 
     // Hash table enumerators
     static bool EnumPersistURIs(
         nsHashKey *aKey, void *aData, void* closure);
     static bool EnumCleanupURIMap(
         nsHashKey *aKey, void *aData, void* closure);
-    static bool EnumCleanupOutputMap(
-        nsHashKey *aKey, void *aData, void* closure);
+    static PLDHashOperator EnumCleanupOutputMap(
+        nsISupports *aKey, OutputData *aData, void* aClosure);
     static bool EnumCleanupUploadList(
         nsHashKey *aKey, void *aData, void* closure);
-    static bool EnumCalcProgress(
-        nsHashKey *aKey, void *aData, void* closure);
+    static PLDHashOperator EnumCalcProgress(
+        nsISupports *aKey, OutputData *aData, void* aClosure);
     static bool EnumCalcUploadProgress(
         nsHashKey *aKey, void *aData, void* closure);
-    static bool EnumFixRedirect(
-        nsHashKey *aKey, void *aData, void* closure);
+    static PLDHashOperator EnumFixRedirect(
+        nsISupports *aKey, OutputData *aData, void* aClosure);
     static bool EnumCountURIsToPersist(
         nsHashKey *aKey, void *aData, void* closure);
 
     nsCOMPtr<nsIURI>          mCurrentDataPath;
     bool                      mCurrentDataPathIsRelative;
     nsCString                 mCurrentRelativePathToData;
     nsCOMPtr<nsIURI>          mCurrentBaseURI;
     nsCString                 mCurrentCharset;
@@ -184,17 +187,17 @@ private:
     nsCOMPtr<nsIWebProgressListener> mProgressListener;
     /**
      * Progress listener for 64-bit values; this is the same object as
      * mProgressListener, but is a member to avoid having to qi it for each
      * progress notification.
      */
     nsCOMPtr<nsIWebProgressListener2> mProgressListener2;
     nsCOMPtr<nsIProgressEventSink> mEventSink;
-    nsHashtable               mOutputMap;
+    nsClassHashtable<nsISupportsHashKey, OutputData> mOutputMap;
     nsHashtable               mUploadList;
     nsHashtable               mURIMap;
     nsTArray<DocData*>        mDocList;
     nsTArray<CleanupData*>    mCleanupList;
     nsTArray<nsCString>       mFilenameList;
     bool                      mFirstAndOnlyUse;
     bool                      mCancel;
     bool                      mJustStartedLoading;