Bug 1442756 - Switch nsHttpAuthCache::mDB to nsClassHashtable. r=mayhemer
authorEric Rahm <erahm@mozilla.com>
Fri, 02 Mar 2018 15:04:25 -0800
changeset 462163 5705bfa39d3a4390864db1a3fe941b093cb65884
parent 462162 6907f5975dbade1a14e2f916f141a3d9fa1ccab0
child 462164 8bbb6c0d3214e84541e26b690bf1ecb93d0bdcb9
push id1683
push usersfraser@mozilla.com
push dateThu, 26 Apr 2018 16:43:40 +0000
treeherdermozilla-release@5af6cb21869d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmayhemer
bugs1442756
milestone60.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 1442756 - Switch nsHttpAuthCache::mDB to nsClassHashtable. r=mayhemer
netwerk/protocol/http/nsHttpAuthCache.cpp
netwerk/protocol/http/nsHttpAuthCache.h
netwerk/protocol/http/nsHttpHandler.cpp
--- a/netwerk/protocol/http/nsHttpAuthCache.cpp
+++ b/netwerk/protocol/http/nsHttpAuthCache.cpp
@@ -49,55 +49,37 @@ StrEquivalent(const char16_t *a, const c
     return nsCRT::strcmp(a, b) == 0;
 }
 
 //-----------------------------------------------------------------------------
 // nsHttpAuthCache <public>
 //-----------------------------------------------------------------------------
 
 nsHttpAuthCache::nsHttpAuthCache()
-    : mDB(nullptr)
+    : mDB(128)
     , mObserver(new OriginClearObserver(this))
 {
     nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService();
     if (obsSvc) {
         obsSvc->AddObserver(mObserver, "clear-origin-attributes-data", false);
     }
 }
 
 nsHttpAuthCache::~nsHttpAuthCache()
 {
-    if (mDB) {
-        DebugOnly<nsresult> rv = ClearAll();
-        MOZ_ASSERT(NS_SUCCEEDED(rv));
-    }
+    DebugOnly<nsresult> rv = ClearAll();
+    MOZ_ASSERT(NS_SUCCEEDED(rv));
     nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService();
     if (obsSvc) {
         obsSvc->RemoveObserver(mObserver, "clear-origin-attributes-data");
         mObserver->mOwner = nullptr;
     }
 }
 
 nsresult
-nsHttpAuthCache::Init()
-{
-    NS_ENSURE_TRUE(!mDB, NS_ERROR_ALREADY_INITIALIZED);
-
-    LOG(("nsHttpAuthCache::Init\n"));
-
-    mDB = PL_NewHashTable(128, (PLHashFunction) PL_HashString,
-                               (PLHashComparator) PL_CompareStrings,
-                               (PLHashComparator) 0, &gHashAllocOps, this);
-    if (!mDB)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    return NS_OK;
-}
-
-nsresult
 nsHttpAuthCache::GetAuthEntryForPath(const char *scheme,
                                      const char *host,
                                      int32_t     port,
                                      const char *path,
                                      nsACString const &originSuffix,
                                      nsHttpAuthEntry **entry)
 {
     LOG(("nsHttpAuthCache::GetAuthEntryForPath [key=%s://%s:%d path=%s]\n",
@@ -145,129 +127,68 @@ nsHttpAuthCache::SetAuthEntry(const char
                               const nsHttpAuthIdentity *ident,
                               nsISupports *metadata)
 {
     nsresult rv;
 
     LOG(("nsHttpAuthCache::SetAuthEntry [key=%s://%s:%d realm=%s path=%s metadata=%p]\n",
         scheme, host, port, realm, path, metadata));
 
-    if (!mDB) {
-        rv = Init();
-        if (NS_FAILED(rv)) return rv;
-    }
-
     nsAutoCString key;
     nsHttpAuthNode *node = LookupAuthNode(scheme, host, port, originSuffix, key);
 
     if (!node) {
         // create a new entry node and set the given entry
         node = new nsHttpAuthNode();
-        if (!node)
-            return NS_ERROR_OUT_OF_MEMORY;
         rv = node->SetAuthEntry(path, realm, creds, challenge, ident, metadata);
         if (NS_FAILED(rv))
             delete node;
         else
-            PL_HashTableAdd(mDB, strdup(key.get()), node);
+            mDB.Put(key, node);
         return rv;
     }
 
     return node->SetAuthEntry(path, realm, creds, challenge, ident, metadata);
 }
 
 void
 nsHttpAuthCache::ClearAuthEntry(const char *scheme,
                                 const char *host,
                                 int32_t     port,
                                 const char *realm,
                                 nsACString const &originSuffix)
 {
-    if (!mDB)
-        return;
-
     nsAutoCString key;
     GetAuthKey(scheme, host, port, originSuffix, key);
-    PL_HashTableRemove(mDB, key.get());
+    mDB.Remove(key);
 }
 
 nsresult
 nsHttpAuthCache::ClearAll()
 {
     LOG(("nsHttpAuthCache::ClearAll\n"));
-
-    if (mDB) {
-        PL_HashTableDestroy(mDB);
-        mDB = 0;
-    }
+    mDB.Clear();
     return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // nsHttpAuthCache <private>
 //-----------------------------------------------------------------------------
 
 nsHttpAuthNode *
 nsHttpAuthCache::LookupAuthNode(const char *scheme,
                                 const char *host,
                                 int32_t     port,
                                 nsACString const &originSuffix,
                                 nsCString  &key)
 {
-    if (!mDB)
-        return nullptr;
-
     GetAuthKey(scheme, host, port, originSuffix, key);
-
-    return (nsHttpAuthNode *) PL_HashTableLookup(mDB, key.get());
-}
-
-void *
-nsHttpAuthCache::AllocTable(void *self, size_t size)
-{
-    return malloc(size);
-}
-
-void
-nsHttpAuthCache::FreeTable(void *self, void *item)
-{
-    free(item);
-}
-
-PLHashEntry *
-nsHttpAuthCache::AllocEntry(void *self, const void *key)
-{
-    return (PLHashEntry *) malloc(sizeof(PLHashEntry));
+    return mDB.Get(key);
 }
 
-void
-nsHttpAuthCache::FreeEntry(void *self, PLHashEntry *he, unsigned flag)
-{
-    if (flag == HT_FREE_VALUE) {
-        // this would only happen if PL_HashTableAdd were to replace an
-        // existing entry in the hash table, but we _always_ do a lookup
-        // before adding a new entry to avoid this case.
-        NS_NOTREACHED("should never happen");
-    }
-    else if (flag == HT_FREE_ENTRY) {
-        // three wonderful flavors of freeing memory ;-)
-        delete (nsHttpAuthNode *) he->value;
-        free((char *) he->key);
-        free(he);
-    }
-}
-
-PLHashAllocOps nsHttpAuthCache::gHashAllocOps =
-{
-    nsHttpAuthCache::AllocTable,
-    nsHttpAuthCache::FreeTable,
-    nsHttpAuthCache::AllocEntry,
-    nsHttpAuthCache::FreeEntry
-};
-
 NS_IMPL_ISUPPORTS(nsHttpAuthCache::OriginClearObserver, nsIObserver)
 
 NS_IMETHODIMP
 nsHttpAuthCache::OriginClearObserver::Observe(nsISupports *subject,
                                               const char *      topic,
                                               const char16_t * data_unicode)
 {
     NS_ENSURE_TRUE(mOwner, NS_ERROR_NOT_AVAILABLE);
@@ -277,47 +198,37 @@ nsHttpAuthCache::OriginClearObserver::Ob
         NS_ERROR("Cannot parse origin attributes pattern");
         return NS_ERROR_FAILURE;
     }
 
     mOwner->ClearOriginData(pattern);
     return NS_OK;
 }
 
-static int
-RemoveEntriesForPattern(PLHashEntry *entry, int32_t number, void *arg)
-{
-    nsDependentCString key(static_cast<const char*>(entry->key));
-
-    // Extract the origin attributes suffix from the key.
-    int32_t colon = key.Find(NS_LITERAL_CSTRING(":"));
-    MOZ_ASSERT(colon != kNotFound);
-    nsDependentCSubstring oaSuffix;
-    oaSuffix.Rebind(key.BeginReading(), colon);
-
-    // Build the OriginAttributes object of it...
-    OriginAttributes oa;
-    DebugOnly<bool> rv = oa.PopulateFromSuffix(oaSuffix);
-    MOZ_ASSERT(rv);
-
-    // ...and match it against the given pattern.
-    OriginAttributesPattern const *pattern = static_cast<OriginAttributesPattern const*>(arg);
-    if (pattern->Matches(oa)) {
-        return HT_ENUMERATE_NEXT | HT_ENUMERATE_REMOVE;
-    }
-    return HT_ENUMERATE_NEXT;
-}
-
 void
 nsHttpAuthCache::ClearOriginData(OriginAttributesPattern const &pattern)
 {
-    if (!mDB) {
-        return;
+    for (auto iter = mDB.Iter(); !iter.Done(); iter.Next()) {
+        const nsACString& key = iter.Key();
+
+        // Extract the origin attributes suffix from the key.
+        int32_t colon = key.FindChar(':');
+        MOZ_ASSERT(colon != kNotFound);
+        nsDependentCSubstring oaSuffix = StringHead(key, colon);
+
+        // Build the OriginAttributes object of it...
+        OriginAttributes oa;
+        DebugOnly<bool> rv = oa.PopulateFromSuffix(oaSuffix);
+        MOZ_ASSERT(rv);
+
+        // ...and match it against the given pattern.
+        if (pattern.Matches(oa)) {
+            iter.Remove();
+        }
     }
-    PL_HashTableEnumerateEntries(mDB, RemoveEntriesForPattern, (void*)&pattern);
 }
 
 //-----------------------------------------------------------------------------
 // nsHttpAuthIdentity
 //-----------------------------------------------------------------------------
 
 nsresult
 nsHttpAuthIdentity::Set(const char16_t *domain,
--- a/netwerk/protocol/http/nsHttpAuthCache.h
+++ b/netwerk/protocol/http/nsHttpAuthCache.h
@@ -4,19 +4,20 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsHttpAuthCache_h__
 #define nsHttpAuthCache_h__
 
 #include "nsError.h"
 #include "nsTArray.h"
 #include "nsAutoPtr.h"
+#include "nsClassHashtable.h"
 #include "nsCOMPtr.h"
+#include "nsHashKeys.h"
 #include "nsStringFwd.h"
-#include "plhash.h"
 #include "nsIObserver.h"
 
 namespace mozilla {
 
 class OriginAttributesPattern;
 
 namespace net {
 
@@ -161,31 +162,30 @@ private:
     void ClearAuthEntry(const char *realm);
 
     uint32_t EntryCount() { return mList.Length(); }
 
 private:
     nsTArray<nsAutoPtr<nsHttpAuthEntry> > mList;
 
     friend class nsHttpAuthCache;
+    friend class nsAutoPtr<nsHttpAuthNode>; // needs to call the destructor
 };
 
 //-----------------------------------------------------------------------------
 // nsHttpAuthCache
 //  (holds a hash table from host:port to nsHttpAuthNode)
 //-----------------------------------------------------------------------------
 
 class nsHttpAuthCache
 {
 public:
     nsHttpAuthCache();
    ~nsHttpAuthCache();
 
-    MOZ_MUST_USE nsresult Init();
-
     // |scheme|, |host|, and |port| are required
     // |path| can be null
     // |entry| is either null or a weak reference
     MOZ_MUST_USE nsresult GetAuthEntryForPath(const char *scheme,
                                               const char *host,
                                               int32_t     port,
                                               const char *path,
                                               nsACString const &originSuffix,
@@ -228,36 +228,29 @@ public:
 
 private:
     nsHttpAuthNode *LookupAuthNode(const char *scheme,
                                    const char *host,
                                    int32_t     port,
                                    nsACString const &originSuffix,
                                    nsCString  &key);
 
-    // hash table allocation functions
-    static void*        AllocTable(void *, size_t size);
-    static void         FreeTable(void *, void *item);
-    static PLHashEntry* AllocEntry(void *, const void *key);
-    static void         FreeEntry(void *, PLHashEntry *he, unsigned flag);
-
-    static PLHashAllocOps gHashAllocOps;
-
     class OriginClearObserver : public nsIObserver {
       virtual ~OriginClearObserver() {}
     public:
       NS_DECL_ISUPPORTS
       NS_DECL_NSIOBSERVER
       explicit OriginClearObserver(nsHttpAuthCache* aOwner) : mOwner(aOwner) {}
       nsHttpAuthCache* mOwner;
     };
 
     void ClearOriginData(OriginAttributesPattern const &pattern);
 
 private:
-    PLHashTable *mDB; // "host:port" --> nsHttpAuthNode
+    using AuthNodeTable = nsClassHashtable<nsCStringHashKey, nsHttpAuthNode>;
+    AuthNodeTable mDB; // "host:port" --> nsHttpAuthNode
     RefPtr<OriginClearObserver> mObserver;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif // nsHttpAuthCache_h__
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -496,22 +496,16 @@ nsHttpHandler::Init()
       // Empty mSpoofedUserAgent to make sure the unsuccessful spoofed UA string
       // will not be used anywhere.
       mSpoofedUserAgent.Truncate();
     }
 
     mSessionStartTime = NowInSeconds();
     mHandlerActive = true;
 
-    rv = mAuthCache.Init();
-    if (NS_FAILED(rv)) return rv;
-
-    rv = mPrivateAuthCache.Init();
-    if (NS_FAILED(rv)) return rv;
-
     rv = InitConnectionMgr();
     if (NS_FAILED(rv)) return rv;
 
     mRequestContextService =
         do_GetService("@mozilla.org/network/request-context-service;1");
 
 #if defined(ANDROID) || defined(MOZ_MULET)
     mProductSub.AssignLiteral(MOZILLA_UAVERSION);