Merge mozilla-central to inbound. r=merge a=merge on a CLOSED TREE
authorCosmin Sabou <csabou@mozilla.com>
Thu, 28 Dec 2017 11:50:49 +0200
changeset 449230 bfae84ba89f222286c649af0148a20f1bb50c799
parent 449229 5fff4549d41137f153e4fd2ea1a0f0be37a13c02 (current diff)
parent 449225 d8d0222927b44d384e9caef796ee52372050659e (diff)
child 449231 816fbb9103df3449ee8edb5249d3117f9fc8ba0f
push id8527
push userCallek@gmail.com
push dateThu, 11 Jan 2018 21:05:50 +0000
treeherdermozilla-beta@95342d212a7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge, merge
milestone59.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
Merge mozilla-central to inbound. r=merge a=merge on a CLOSED TREE
--- a/netwerk/dns/nsDNSService2.cpp
+++ b/netwerk/dns/nsDNSService2.cpp
@@ -83,28 +83,26 @@ NS_IMPL_ISUPPORTS(nsDNSRecord, nsIDNSRec
 
 NS_IMETHODIMP
 nsDNSRecord::GetCanonicalName(nsACString &result)
 {
     // this method should only be called if we have a CNAME
     NS_ENSURE_TRUE(mHostRecord->flags & nsHostResolver::RES_CANON_NAME,
                    NS_ERROR_NOT_AVAILABLE);
 
-    // if the record is for an IP address literal, then the canonical
-    // host name is the IP address literal.
-    const char *cname;
-    {
-        MutexAutoLock lock(mHostRecord->addr_info_lock);
-        if (mHostRecord->addr_info)
-            cname = mHostRecord->addr_info->mCanonicalName ?
-                mHostRecord->addr_info->mCanonicalName :
-                mHostRecord->addr_info->mHostName;
-        else
-            cname = mHostRecord->host;
+    MutexAutoLock lock(mHostRecord->addr_info_lock);
+    if (mHostRecord->addr_info) {
+        const char* cname = mHostRecord->addr_info->mCanonicalName ?
+            mHostRecord->addr_info->mCanonicalName :
+            mHostRecord->addr_info->mHostName;
         result.Assign(cname);
+    } else {
+        // if the record is for an IP address literal, then the canonical
+        // host name is the IP address literal.
+        result = mHostRecord->host;
     }
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDNSRecord::GetNextAddr(uint16_t port, NetAddr *addr)
 {
     if (mDone) {
--- a/netwerk/dns/nsHostResolver.cpp
+++ b/netwerk/dns/nsHostResolver.cpp
@@ -157,57 +157,60 @@ IsLowPriority(uint16_t flags)
 }
 
 //----------------------------------------------------------------------------
 // this macro filters out any flags that are not used when constructing the
 // host key.  the significant flags are those that would affect the resulting
 // host record (i.e., the flags that are passed down to PR_GetAddrInfoByName).
 #define RES_KEY_FLAGS(_f) ((_f) & nsHostResolver::RES_CANON_NAME)
 
-nsHostRecord::nsHostRecord(const nsHostKey *key)
-    : addr_info_lock("nsHostRecord.addr_info_lock")
+bool
+nsHostKey::operator==(const nsHostKey& other) const
+{
+    return host == other.host &&
+        RES_KEY_FLAGS (flags) == RES_KEY_FLAGS(other.flags) &&
+        af == other.af &&
+        netInterface == other.netInterface &&
+        originSuffix == other.originSuffix;
+}
+
+size_t
+nsHostKey::SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const
+{
+    size_t n = 0;
+    n += host.SizeOfExcludingThisIfUnshared(mallocSizeOf);
+    n += netInterface.SizeOfExcludingThisIfUnshared(mallocSizeOf);
+    n += originSuffix.SizeOfExcludingThisIfUnshared(mallocSizeOf);
+    return n;
+}
+
+nsHostRecord::nsHostRecord(const nsHostKey& key)
+    : nsHostKey(key)
+    , addr_info_lock("nsHostRecord.addr_info_lock")
     , addr_info_gencnt(0)
     , addr_info(nullptr)
     , addr(nullptr)
     , negative(false)
     , resolving(false)
     , onQueue(false)
     , usingAnyThread(false)
     , mDoomed(false)
 #if TTL_AVAILABLE
     , mGetTtl(false)
 #endif
     , mBlacklistedCount(0)
     , mResolveAgain(false)
 {
-    host = ((char *) this) + sizeof(nsHostRecord);
-    memcpy((char *) host, key->host, strlen(key->host) + 1);
-    flags = key->flags;
-    af = key->af;
-    netInterface = host + strlen(key->host) + 1;
-    memcpy((char *) netInterface, key->netInterface,
-           strlen(key->netInterface) + 1);
-    originSuffix = netInterface + strlen(key->netInterface) + 1;
-    memcpy((char *) originSuffix, key->originSuffix,
-           strlen(key->originSuffix) + 1);
     PR_INIT_CLIST(this);
 }
 
 nsresult
 nsHostRecord::Create(const nsHostKey *key, nsHostRecord **result)
 {
-    size_t hostLen = strlen(key->host) + 1;
-    size_t netInterfaceLen = strlen(key->netInterface) + 1;
-    size_t originSuffixLen = strlen(key->originSuffix) + 1;
-    size_t size = hostLen + netInterfaceLen + originSuffixLen + sizeof(nsHostRecord);
-
-    // Use placement new to create the object with room for the hostname,
-    // network interface name and originSuffix allocated after it.
-    void *place = ::operator new(size);
-    *result = new(place) nsHostRecord(key);
+    *result = new nsHostRecord(*key);
     NS_ADDREF(*result);
 
     return NS_OK;
 }
 
 void
 nsHostRecord::SetExpiration(const mozilla::TimeStamp& now, unsigned int valid, unsigned int grace)
 {
@@ -235,66 +238,66 @@ nsHostRecord::~nsHostRecord()
     delete addr_info;
 }
 
 bool
 nsHostRecord::Blacklisted(NetAddr *aQuery)
 {
     // must call locked
     LOG(("Checking blacklist for host [%s%s%s], host record [%p].\n",
-          LOG_HOST(host, netInterface), this));
+          LOG_HOST(host.get(), netInterface.get()), this));
 
     // skip the string conversion for the common case of no blacklist
     if (!mBlacklistedItems.Length()) {
         return false;
     }
 
     char buf[kIPv6CStrBufSize];
     if (!NetAddrToString(aQuery, buf, sizeof(buf))) {
         return false;
     }
     nsDependentCString strQuery(buf);
 
     for (uint32_t i = 0; i < mBlacklistedItems.Length(); i++) {
         if (mBlacklistedItems.ElementAt(i).Equals(strQuery)) {
             LOG(("Address [%s] is blacklisted for host [%s%s%s].\n", buf,
-                 LOG_HOST(host, netInterface)));
+                 LOG_HOST(host.get(), netInterface.get())));
             return true;
         }
     }
 
     return false;
 }
 
 void
 nsHostRecord::ReportUnusable(NetAddr *aAddress)
 {
     // must call locked
     LOG(("Adding address to blacklist for host [%s%s%s], host record [%p].\n",
-         LOG_HOST(host, netInterface), this));
+         LOG_HOST(host.get(), netInterface.get()), this));
 
     ++mBlacklistedCount;
 
     if (negative)
         mDoomed = true;
 
     char buf[kIPv6CStrBufSize];
     if (NetAddrToString(aAddress, buf, sizeof(buf))) {
         LOG(("Successfully adding address [%s] to blacklist for host "
-             "[%s%s%s].\n", buf, LOG_HOST(host, netInterface)));
+             "[%s%s%s].\n", buf, LOG_HOST(host.get(), netInterface.get())));
         mBlacklistedItems.AppendElement(nsCString(buf));
     }
 }
 
 void
 nsHostRecord::ResetBlacklist()
 {
     // must call locked
     LOG(("Resetting blacklist for host [%s%s%s], host record [%p].\n",
-         LOG_HOST(host, netInterface), this));
+         LOG_HOST(host.get(), netInterface.get()), this));
     mBlacklistedItems.Clear();
 }
 
 nsHostRecord::ExpirationStatus
 nsHostRecord::CheckExpiration(const mozilla::TimeStamp& now) const {
     if (!mGraceStart.IsNull() && now >= mGraceStart
             && !mValidEnd.IsNull() && now < mValidEnd) {
         return nsHostRecord::EXP_GRACE;
@@ -344,16 +347,17 @@ nsHostRecord::SizeOfIncludingThis(Malloc
 {
     size_t n = mallocSizeOf(this);
 
     // The |host| field (inherited from nsHostKey) actually points to extra
     // memory that is allocated beyond the end of the nsHostRecord (see
     // nsHostRecord::Create()).  So it will be included in the
     // |mallocSizeOf(this)| call above.
 
+    n += nsHostKey::SizeOfExcludingThis(mallocSizeOf);
     n += SizeOfResolveHostCallbackListExcludingHead(mCallbacks, mallocSizeOf);
     n += addr_info ? addr_info->SizeOfIncludingThis(mallocSizeOf) : 0;
     n += mallocSizeOf(addr.get());
 
     n += mBlacklistedItems.ShallowSizeOfExcludingThis(mallocSizeOf);
     for (size_t i = 0; i < mBlacklistedItems.Length(); i++) {
         n += mBlacklistedItems[i].SizeOfExcludingThisIfUnshared(mallocSizeOf);
     }
@@ -399,33 +403,29 @@ struct nsHostDBEnt : PLDHashEntryHdr
 {
     nsHostRecord *rec;
 };
 
 static PLDHashNumber
 HostDB_HashKey(const void *key)
 {
     const nsHostKey *hk = static_cast<const nsHostKey *>(key);
-    return AddToHash(HashString(hk->host), RES_KEY_FLAGS(hk->flags), hk->af,
-                     HashString(hk->netInterface), HashString(hk->originSuffix));
+    return AddToHash(HashString(hk->host.get()), RES_KEY_FLAGS(hk->flags),
+                     hk->af, HashString(hk->netInterface.get()),
+                     HashString(hk->originSuffix.get()));
 }
 
 static bool
 HostDB_MatchEntry(const PLDHashEntryHdr *entry,
                   const void *key)
 {
     const nsHostDBEnt *he = static_cast<const nsHostDBEnt *>(entry);
     const nsHostKey *hk = static_cast<const nsHostKey *>(key);
 
-    return !strcmp(he->rec->host ? he->rec->host : "",
-                   hk->host ? hk->host : "") &&
-            RES_KEY_FLAGS (he->rec->flags) == RES_KEY_FLAGS(hk->flags) &&
-            he->rec->af == hk->af &&
-            !strcmp(he->rec->netInterface, hk->netInterface) &&
-            !strcmp(he->rec->originSuffix, hk->originSuffix);
+    return *he->rec == *hk;
 }
 
 static void
 HostDB_MoveEntry(PLDHashTable *table,
                  const PLDHashEntryHdr *from,
                  PLDHashEntryHdr *to)
 {
     static_cast<nsHostDBEnt *>(to)->rec =
@@ -438,32 +438,32 @@ HostDB_ClearEntry(PLDHashTable *table,
 {
     nsHostDBEnt *he = static_cast<nsHostDBEnt*>(entry);
     MOZ_ASSERT(he, "nsHostDBEnt is null!");
 
     nsHostRecord *hr = he->rec;
     MOZ_ASSERT(hr, "nsHostDBEnt has null host record!");
 
     LOG(("Clearing cache db entry for host [%s%s%s].\n",
-         LOG_HOST(hr->host, hr->netInterface)));
+         LOG_HOST(hr->host.get(), hr->netInterface.get())));
 #if defined(DEBUG)
     {
         MutexAutoLock lock(hr->addr_info_lock);
         if (!hr->addr_info) {
             LOG(("No address info for host [%s%s%s].\n",
-                 LOG_HOST(hr->host, hr->netInterface)));
+                 LOG_HOST(hr->host.get(), hr->netInterface.get())));
         } else {
             if (!hr->mValidEnd.IsNull()) {
                 TimeDuration diff = hr->mValidEnd - TimeStamp::NowLoRes();
                 LOG(("Record for host [%s%s%s] expires in %f seconds.\n",
-                     LOG_HOST(hr->host, hr->netInterface),
+                     LOG_HOST(hr->host.get(), hr->netInterface.get()),
                      diff.ToSeconds()));
             } else {
                 LOG(("Record for host [%s%s%s] not yet valid.\n",
-                     LOG_HOST(hr->host, hr->netInterface)));
+                     LOG_HOST(hr->host.get(), hr->netInterface.get())));
             }
 
             NetAddrElement *addrElement = nullptr;
             char buf[kIPv6CStrBufSize];
             do {
                 if (!addrElement) {
                     addrElement = hr->addr_info->mAddresses.getFirst();
                 } else {
@@ -622,17 +622,17 @@ nsHostResolver::FlushCache()
     // Clear the evictionQ and remove all its corresponding entries from
     // the cache first
     if (!PR_CLIST_IS_EMPTY(&mEvictionQ)) {
         PRCList *node = mEvictionQ.next;
         while (node != &mEvictionQ) {
             nsHostRecord *rec = static_cast<nsHostRecord *>(node);
             node = node->next;
             PR_REMOVE_AND_INIT_LINK(rec);
-            mDB.Remove((nsHostKey *) rec);
+            mDB.Remove(static_cast<nsHostKey *>(rec));
             NS_RELEASE(rec);
         }
     }
 
     // Refresh the cache entries that are resolving RIGHT now, remove the rest.
     for (auto iter = mDB.Iter(); !iter.Done(); iter.Next()) {
         auto entry = static_cast<nsHostDBEnt *>(iter.Get());
         // Try to remove the record, or mark it for refresh.
@@ -766,17 +766,18 @@ nsHostResolver::ResolveHost(const char  
             // in the hash table.  if so, then check to see if we can't
             // just reuse the lookup result.  otherwise, if there are
             // any pending callbacks, then add to pending callbacks queue,
             // and return.  otherwise, add ourselves as first pending
             // callback, and proceed to do the lookup.
             nsAutoCString originSuffix;
             aOriginAttributes.CreateSuffix(originSuffix);
 
-            nsHostKey key = { host, flags, af, netInterface, originSuffix.get() };
+            nsHostKey key(nsCString(host), flags, af, nsCString(netInterface),
+                          originSuffix);
             auto he = static_cast<nsHostDBEnt*>(mDB.Add(&key, fallible));
 
             // if the record is null, the hash table OOM'd.
             if (!he) {
                 LOG(("  Out of memory: no cache entry for host [%s%s%s].\n",
                      LOG_HOST(host, netInterface)));
                 rv = NS_ERROR_OUT_OF_MEMORY;
             }
@@ -843,18 +844,18 @@ nsHostResolver::ResolveHost(const char  
             }
 
             // If this is an IPV4 or IPV6 specific request, check if there is
             // an AF_UNSPEC entry we can use. Otherwise, hit the resolver...
             else if (!he->rec->resolving) {
                 if (!(flags & RES_BYPASS_CACHE) &&
                     ((af == PR_AF_INET) || (af == PR_AF_INET6))) {
                     // First, search for an entry with AF_UNSPEC
-                    const nsHostKey unspecKey = { host, flags, PR_AF_UNSPEC,
-                                                  netInterface, originSuffix.get() };
+                    const nsHostKey unspecKey(nsCString(host), flags, PR_AF_UNSPEC,
+                                              nsCString(netInterface), originSuffix);
                     auto unspecHe =
                         static_cast<nsHostDBEnt*>(mDB.Search(&unspecKey));
                     NS_ASSERTION(!unspecHe ||
                                  (unspecHe && unspecHe->rec),
                                 "Valid host entries should contain a record");
                     TimeStamp now = TimeStamp::NowLoRes();
                     if (unspecHe &&
                         unspecHe->rec->HasUsableResult(now, flags)) {
@@ -1000,17 +1001,18 @@ nsHostResolver::DetachCallback(const cha
     RefPtr<nsResolveHostCallback> callback(aCallback);
 
     {
         MutexAutoLock lock(mLock);
 
         nsAutoCString originSuffix;
         aOriginAttributes.CreateSuffix(originSuffix);
 
-        nsHostKey key = { host, flags, af, netInterface, originSuffix.get() };
+        nsHostKey key(nsCString(host), flags, af, nsCString(netInterface),
+                      originSuffix);
         auto he = static_cast<nsHostDBEnt*>(mDB.Search(&key));
         if (he) {
             // walk list looking for |callback|... we cannot assume
             // that it will be there!
 
             for (nsResolveHostCallback* c: he->rec->mCallbacks) {
                 if (c == callback) {
                     rec = he->rec;
@@ -1051,17 +1053,17 @@ nsHostResolver::ConditionallyCreateThrea
         if (!thr) {
             mThreadCount--;
             NS_RELEASE_THIS();
             return NS_ERROR_OUT_OF_MEMORY;
         }
     }
     else {
         LOG(("  Unable to find a thread for looking up host [%s%s%s].\n",
-             LOG_HOST(rec->host, rec->netInterface)));
+             LOG_HOST(rec->host.get(), rec->netInterface.get())));
     }
     return NS_OK;
 }
 
 nsresult
 nsHostResolver::IssueLookup(nsHostRecord *rec)
 {
     nsresult rv = NS_OK;
@@ -1213,17 +1215,17 @@ nsHostResolver::GetHostToLookup(nsHostRe
 void
 nsHostResolver::PrepareRecordExpiration(nsHostRecord* rec) const
 {
     MOZ_ASSERT(((bool)rec->addr_info) != rec->negative);
     if (!rec->addr_info) {
         rec->SetExpiration(TimeStamp::NowLoRes(),
                            NEGATIVE_RECORD_LIFETIME, 0);
         LOG(("Caching host [%s%s%s] negative record for %u seconds.\n",
-             LOG_HOST(rec->host, rec->netInterface),
+             LOG_HOST(rec->host.get(), rec->netInterface.get()),
              NEGATIVE_RECORD_LIFETIME));
         return;
     }
 
     unsigned int lifetime = mDefaultCacheLifetime;
     unsigned int grace = mDefaultGracePeriod;
 #if TTL_AVAILABLE
     unsigned int ttl = mDefaultCacheLifetime;
@@ -1234,17 +1236,17 @@ nsHostResolver::PrepareRecordExpiration(
         }
         lifetime = ttl;
         grace = 0;
     }
 #endif
 
     rec->SetExpiration(TimeStamp::NowLoRes(), lifetime, grace);
     LOG(("Caching host [%s%s%s] record for %u seconds (grace %d).",
-         LOG_HOST(rec->host, rec->netInterface), lifetime, grace));
+         LOG_HOST(rec->host.get(), rec->netInterface.get()), lifetime, grace));
 }
 
 static bool
 different_rrset(AddrInfo *rrset1, AddrInfo *rrset2)
 {
     if (!rrset1 || !rrset2) {
         return true;
     }
@@ -1348,32 +1350,32 @@ nsHostResolver::CompleteLookup(nsHostRec
             NS_ADDREF(rec);
             if (mEvictionQSize < mMaxCacheEntries)
                 mEvictionQSize++;
             else {
                 // remove first element on mEvictionQ
                 nsHostRecord *head =
                     static_cast<nsHostRecord *>(PR_LIST_HEAD(&mEvictionQ));
                 PR_REMOVE_AND_INIT_LINK(head);
-                mDB.Remove((nsHostKey *) head);
+                mDB.Remove(static_cast<nsHostKey *>(head));
 
                 if (!head->negative) {
                     // record the age of the entry upon eviction.
                     TimeDuration age = TimeStamp::NowLoRes() - head->mValidStart;
                     Telemetry::Accumulate(Telemetry::DNS_CLEANUP_AGE,
                                           static_cast<uint32_t>(age.ToSeconds() / 60));
                 }
 
                 // release reference to rec owned by mEvictionQ
                 NS_RELEASE(head);
             }
 #if TTL_AVAILABLE
             if (!rec->mGetTtl && !rec->resolving && sGetTtlEnabled) {
                 LOG(("Issuing second async lookup for TTL for host [%s%s%s].",
-                     LOG_HOST(rec->host, rec->netInterface)));
+                     LOG_HOST(rec->host.get(), rec->netInterface.get())));
                 rec->flags =
                   (rec->flags & ~RES_PRIORITY_MEDIUM) | RES_PRIORITY_LOW;
                 DebugOnly<nsresult> rv = IssueLookup(rec);
                 NS_WARNING_ASSERTION(
                     NS_SUCCEEDED(rv),
                     "Could not issue second async lookup for TTL.");
             }
 #endif
@@ -1396,37 +1398,38 @@ nsHostResolver::CancelAsyncRequest(const
                                    uint16_t                af,
                                    const char             *netInterface,
                                    nsIDNSListener         *aListener,
                                    nsresult                status)
 
 {
     MutexAutoLock lock(mLock);
 
-    nsAutoCString originSuffix;
+    nsCString originSuffix;
     aOriginAttributes.CreateSuffix(originSuffix);
 
     // Lookup the host record associated with host, flags & address family
-    nsHostKey key = { host, flags, af, netInterface, originSuffix.get() };
+    nsHostKey key(nsCString(host), flags, af, nsCString(netInterface),
+                  originSuffix);
     auto he = static_cast<nsHostDBEnt*>(mDB.Search(&key));
     if (he) {
         nsHostRecord* recPtr = nullptr;
 
         for (RefPtr<nsResolveHostCallback> c : he->rec->mCallbacks) {
             if (c->EqualsAsyncListener(aListener)) {
                 c->remove();
                 recPtr = he->rec;
                 c->OnResolveHostComplete(this, recPtr, status);
                 break;
             }
         }
 
         // If there are no more callbacks, remove the hash table entry
         if (recPtr && recPtr->mCallbacks.isEmpty()) {
-            mDB.Remove((nsHostKey *)recPtr);
+            mDB.Remove(static_cast<nsHostKey *>(recPtr));
             // If record is on a Queue, remove it and then deref it
             if (recPtr->next != recPtr) {
                 PR_REMOVE_LINK(recPtr);
                 NS_RELEASE(recPtr);
             }
         }
     }
 }
@@ -1467,30 +1470,33 @@ nsHostResolver::ThreadFunc(void *arg)
     nsResState rs;
 #endif
     RefPtr<nsHostResolver> resolver = dont_AddRef((nsHostResolver *)arg);
     nsHostRecord *rec  = nullptr;
     AddrInfo *ai = nullptr;
 
     while (rec || resolver->GetHostToLookup(&rec)) {
         LOG(("DNS lookup thread - Calling getaddrinfo for host [%s%s%s].\n",
-             LOG_HOST(rec->host, rec->netInterface)));
+             LOG_HOST(rec->host.get(), rec->netInterface.get())));
 
         TimeStamp startTime = TimeStamp::Now();
 #if TTL_AVAILABLE
         bool getTtl = rec->mGetTtl;
 #else
         bool getTtl = false;
 #endif
 
-        nsresult status = GetAddrInfo(rec->host, rec->af, rec->flags, rec->netInterface,
-                                      &ai, getTtl);
+        nsresult status = GetAddrInfo(rec->host.get(), rec->af,
+                                      rec->flags,
+                                      rec->netInterface.get(), &ai,
+                                      getTtl);
 #if defined(RES_RETRY_ON_FAILURE)
         if (NS_FAILED(status) && rs.Reset()) {
-            status = GetAddrInfo(rec->host, rec->af, rec->flags, rec->netInterface, &ai,
+            status = GetAddrInfo(rec->host.get(), rec->af,
+                                 rec->flags, rec->netInterface.get(), &ai,
                                  getTtl);
         }
 #endif
 
         {   // obtain lock to check shutdown and manage inter-module telemetry
             MutexAutoLock lock(resolver->mLock);
 
             if (!resolver->mShutdown) {
@@ -1513,23 +1519,23 @@ nsHostResolver::ThreadFunc(void *arg)
                 } else {
                     Telemetry::Accumulate(Telemetry::DNS_FAILED_LOOKUP_TIME, millis);
                 }
             }
         }
 
         // CompleteLookup may release "rec", long before we lose it.
         LOG(("DNS lookup thread - lookup completed for host [%s%s%s]: %s.\n",
-             LOG_HOST(rec->host, rec->netInterface),
+             LOG_HOST(rec->host.get(), rec->netInterface.get()),
              ai ? "success" : "failure: unknown host"));
 
         if (LOOKUP_RESOLVEAGAIN == resolver->CompleteLookup(rec, status, ai)) {
             // leave 'rec' assigned and loop to make a renewed host resolve
             LOG(("DNS lookup thread - Re-resolving host [%s%s%s].\n",
-                 LOG_HOST(rec->host, rec->netInterface)));
+                 LOG_HOST(rec->host.get(), rec->netInterface.get())));
         } else {
             rec = nullptr;
         }
     }
     resolver->mThreadCount--;
     resolver = nullptr;
     LOG(("DNS lookup thread - queue empty, thread finished.\n"));
 }
@@ -1556,17 +1562,17 @@ void
 nsHostResolver::GetDNSCacheEntries(nsTArray<DNSCacheEntries> *args)
 {
     for (auto iter = mDB.Iter(); !iter.Done(); iter.Next()) {
         // We don't pay attention to address literals, only resolved domains.
         // Also require a host.
         auto entry = static_cast<nsHostDBEnt*>(iter.Get());
         nsHostRecord* rec = entry->rec;
         MOZ_ASSERT(rec, "rec should never be null here!");
-        if (!rec || !rec->addr_info || !rec->host) {
+        if (!rec || !rec->addr_info) {
             continue;
         }
 
         DNSCacheEntries info;
         info.hostname = rec->host;
         info.family = rec->af;
         info.netInterface = rec->netInterface;
         info.expiration =
--- a/netwerk/dns/nsHostResolver.h
+++ b/netwerk/dns/nsHostResolver.h
@@ -32,21 +32,34 @@ class nsResolveHostCallback;
 #define MAX_RESOLVER_THREADS_FOR_HIGH_PRIORITY 5
 #define MAX_NON_PRIORITY_REQUESTS 150
 
 #define MAX_RESOLVER_THREADS (MAX_RESOLVER_THREADS_FOR_ANY_PRIORITY + \
                               MAX_RESOLVER_THREADS_FOR_HIGH_PRIORITY)
 
 struct nsHostKey
 {
-    const char *host;
-    uint16_t    flags;
-    uint16_t    af;
-    const char *netInterface;
-    const char *originSuffix;
+    const nsCString host;
+    uint16_t flags;
+    uint16_t af;
+    const nsCString netInterface;
+    const nsCString originSuffix;
+
+    nsHostKey(const nsACString& host, uint16_t flags,
+              uint16_t af, const nsACString& netInterface,
+              const nsACString& originSuffix)
+        : host(host)
+        , flags(flags)
+        , af(af)
+        , netInterface(netInterface)
+        , originSuffix(originSuffix) {
+    }
+
+    bool operator==(const nsHostKey& other) const;
+    size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
 };
 
 /**
  * nsHostRecord - ref counted object type stored in host resolver cache.
  */
 class nsHostRecord : public PRCList, public nsHostKey
 {
     typedef mozilla::Mutex Mutex;
@@ -126,16 +139,17 @@ public:
     static DnsPriority GetPriority(uint16_t aFlags);
 
     bool RemoveOrRefresh(); // Mark records currently being resolved as needed
                             // to resolve again.
 
 private:
     friend class nsHostResolver;
 
+    explicit nsHostRecord(const nsHostKey& key);
     mozilla::LinkedList<RefPtr<nsResolveHostCallback>> mCallbacks;
 
     bool    resolving; /* true if this record is being resolved, which means
                         * that it is either on the pending queue or owned by
                         * one of the worker threads. */
 
     bool    onQueue;  /* true if pending and on the queue (not yet given to getaddrinfo())*/
     bool    usingAnyThread; /* true if off queue and contributing to mActiveAnyThreadCount */
--- a/taskcluster/docker/recipes/run-task
+++ b/taskcluster/docker/recipes/run-task
@@ -542,17 +542,16 @@ def main(args):
             if e.errno != errno.EEXIST:
                 raise
 
         if running_as_root:
             os.chown(store_path, uid, gid)
 
     prepare_checkout_dir(args.vcs_checkout)
     prepare_checkout_dir(args.tools_checkout)
-    prepare_checkout_dir(args.comm_checkout)
     if args.vcs_checkout or args.tools_checkout or args.comm_checkout:
         prepare_hg_store_path()
 
     if running_as_root:
         # Drop permissions to requested user.
         # This code is modeled after what `sudo` was observed to do in a Docker
         # container. We do not bother calling setrlimit() because containers have
         # their own limits.