Bug 893857 (part 2) - Add a memory reporter for the DNS service. r=sworkman.

--HG--
extra : rebase_source : 7d88cf2ef5ad4b58b377f0cec66349b5e26bfc8e
This commit is contained in:
Nicholas Nethercote 2013-11-24 15:24:12 -08:00
parent 4d49232050
commit bf145657e1
6 changed files with 173 additions and 7 deletions

View File

@ -275,5 +275,15 @@ AddrInfo::AddAddress(NetAddrElement *address)
mAddresses.insertBack(address);
}
size_t
AddrInfo::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) const
{
size_t n = mallocSizeOf(this);
n += mallocSizeOf(mHostName);
n += mallocSizeOf(mCanonicalName);
n += mAddresses.sizeOfExcludingThis(mallocSizeOf);
return n;
}
} // namespace dns
} // namespace mozilla

View File

@ -1,3 +1,5 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -9,6 +11,7 @@
#include "prio.h"
#include "prnetdb.h"
#include "mozilla/LinkedList.h"
#include "mozilla/MemoryReporting.h"
#if !defined(XP_WIN) && !defined(XP_OS2)
#include <arpa/inet.h>
@ -136,6 +139,8 @@ public:
void AddAddress(NetAddrElement *address);
size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
char *mHostName;
char *mCanonicalName;
LinkedList<NetAddrElement> mAddresses;

View File

@ -7,6 +7,7 @@
#include "nsIDNSRecord.h"
#include "nsIDNSListener.h"
#include "nsICancelable.h"
#include "nsIMemoryReporter.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "nsIServiceManager.h"
@ -268,6 +269,8 @@ public:
// particular hostname and nsIDNSListener
bool EqualsAsyncListener(nsIDNSListener *aListener);
size_t SizeOfIncludingThis(mozilla::MallocSizeOf) const;
nsRefPtr<nsHostResolver> mResolver;
nsCString mHost; // hostname we're resolving
nsCOMPtr<nsIDNSListener> mListener;
@ -307,6 +310,19 @@ nsDNSAsyncRequest::EqualsAsyncListener(nsIDNSListener *aListener)
return (aListener == mListener);
}
size_t
nsDNSAsyncRequest::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) const
{
size_t n = mallocSizeOf(this);
// The following fields aren't measured.
// - mHost, because it's a non-owning pointer
// - mResolver, because it's a non-owning pointer
// - mListener, because it's a non-owning pointer
return n;
}
NS_IMPL_ISUPPORTS1(nsDNSAsyncRequest, nsICancelable)
NS_IMETHODIMP
@ -330,6 +346,7 @@ public:
void OnLookupComplete(nsHostResolver *, nsHostRecord *, nsresult);
bool EqualsAsyncListener(nsIDNSListener *aListener);
size_t SizeOfIncludingThis(mozilla::MallocSizeOf) const;
bool mDone;
nsresult mStatus;
@ -360,8 +377,41 @@ nsDNSSyncRequest::EqualsAsyncListener(nsIDNSListener *aListener)
return false;
}
size_t
nsDNSSyncRequest::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) const
{
size_t n = mallocSizeOf(this);
// The following fields aren't measured.
// - mHostRecord, because it's a non-owning pointer
// Measurement of the following members may be added later if DMD finds it
// is worthwhile:
// - mMonitor
return n;
}
//-----------------------------------------------------------------------------
class NetworkDNSServiceReporter MOZ_FINAL : public MemoryUniReporter
{
public:
NetworkDNSServiceReporter(nsDNSService* aService)
: MemoryUniReporter("explicit/network/dns-service",
KIND_HEAP, UNITS_BYTES,
"Memory used for the DNS service.")
, mService(aService)
{}
private:
int64_t Amount() MOZ_OVERRIDE
{
return mService->SizeOfIncludingThis(MallocSizeOf);
}
nsDNSService *mService;
};
nsDNSService::nsDNSService()
: mLock("nsDNSServer.mLock")
, mFirstTime(true)
@ -373,8 +423,7 @@ nsDNSService::~nsDNSService()
{
}
NS_IMPL_ISUPPORTS3(nsDNSService, nsIDNSService, nsPIDNSService,
nsIObserver)
NS_IMPL_ISUPPORTS3(nsDNSService, nsIDNSService, nsPIDNSService, nsIObserver)
NS_IMETHODIMP
nsDNSService::Init()
@ -390,7 +439,7 @@ nsDNSService::Init()
bool disableIPv6 = false;
bool disablePrefetch = false;
int proxyType = nsIProtocolProxyService::PROXYCONFIG_DIRECT;
nsAdoptingCString ipv4OnlyDomains;
nsAdoptingCString localDomains;
@ -472,19 +521,25 @@ nsDNSService::Init()
domains.AssignASCII(nsDependentCString(localDomains).get());
nsCharSeparatedTokenizer tokenizer(domains, ',',
nsCharSeparatedTokenizerTemplate<>::SEPARATOR_OPTIONAL);
while (tokenizer.hasMoreTokens()) {
const nsSubstring& domain = tokenizer.nextToken();
mLocalDomains.PutEntry(nsDependentCString(NS_ConvertUTF16toUTF8(domain).get()));
}
}
}
mReporter = new NetworkDNSServiceReporter(this);
NS_RegisterMemoryReporter(mReporter);
return rv;
}
NS_IMETHODIMP
nsDNSService::Shutdown()
{
NS_UnregisterMemoryReporter(mReporter);
nsRefPtr<nsHostResolver> res;
{
MutexAutoLock lock(mLock);
@ -873,3 +928,26 @@ nsDNSService::GetDNSCacheEntries(nsTArray<mozilla::net::DNSCacheEntries> *args)
mResolver->GetDNSCacheEntries(args);
return NS_OK;
}
static size_t
SizeOfLocalDomainsEntryExcludingThis(nsCStringHashKey* entry,
MallocSizeOf mallocSizeOf, void*)
{
return entry->GetKey().SizeOfExcludingThisMustBeUnshared(mallocSizeOf);
}
size_t
nsDNSService::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) const
{
// Measurement of the following members may be added later if DMD finds it
// is worthwhile:
// - mIDN
// - mLock
size_t n = mallocSizeOf(this);
n += mResolver->SizeOfIncludingThis(mallocSizeOf);
n += mIPv4OnlyDomains.SizeOfExcludingThisMustBeUnshared(mallocSizeOf);
n += mLocalDomains.SizeOfExcludingThis(SizeOfLocalDomainsEntryExcludingThis,
mallocSizeOf);
return n;
}

View File

@ -16,6 +16,8 @@
#include "mozilla/Mutex.h"
#include "mozilla/Attributes.h"
class nsIMemoryReporter;
class nsDNSService MOZ_FINAL : public nsPIDNSService
, public nsIObserver
{
@ -28,6 +30,8 @@ public:
nsDNSService();
~nsDNSService();
size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
private:
uint16_t GetAFForLookup(const nsACString &host, uint32_t flags);
@ -46,6 +50,8 @@ private:
bool mFirstTime;
bool mOffline;
nsTHashtable<nsCStringHashKey> mLocalDomains;
nsCOMPtr<nsIMemoryReporter> mReporter;
};
#endif //nsDNSService2_h__

View File

@ -265,6 +265,42 @@ nsHostRecord::HasUsableResult(uint16_t queryFlags) const
return addr_info || addr || negative;
}
static size_t
SizeOfResolveHostCallbackListExcludingHead(const PRCList *head,
MallocSizeOf mallocSizeOf)
{
size_t n = 0;
PRCList *curr = head->next;
while (curr != head) {
nsResolveHostCallback *callback =
static_cast<nsResolveHostCallback*>(curr);
n += callback->SizeOfIncludingThis(mallocSizeOf);
curr = curr->next;
}
return n;
}
size_t
nsHostRecord::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) const
{
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 += SizeOfResolveHostCallbackListExcludingHead(&callbacks, mallocSizeOf);
n += addr_info ? addr_info->SizeOfIncludingThis(mallocSizeOf) : 0;
n += mallocSizeOf(addr);
n += mBlacklistedItems.SizeOfExcludingThis(mallocSizeOf);
for (size_t i = 0; i < mBlacklistedItems.Length(); i++) {
n += mBlacklistedItems[i].SizeOfIncludingThisMustBeUnshared(mallocSizeOf);
}
return n;
}
//----------------------------------------------------------------------------
struct nsHostDBEnt : PLDHashEntryHdr
@ -1070,6 +1106,31 @@ nsHostResolver::CancelAsyncRequest(const char *host,
}
}
static size_t
SizeOfHostDBEntExcludingThis(PLDHashEntryHdr* hdr, MallocSizeOf mallocSizeOf,
void*)
{
nsHostDBEnt* ent = static_cast<nsHostDBEnt*>(hdr);
return ent->rec->SizeOfIncludingThis(mallocSizeOf);
}
size_t
nsHostResolver::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) const
{
MutexAutoLock lock(mLock);
size_t n = mallocSizeOf(this);
n += PL_DHashTableSizeOfExcludingThis(&mDB, SizeOfHostDBEntExcludingThis,
mallocSizeOf);
// The following fields aren't measured.
// - mHighQ, mMediumQ, mLowQ, mEvictionQ, because they just point to
// nsHostRecords that also pointed to by entries |mDB|, and measured when
// |mDB| is measured.
return n;
}
void
nsHostResolver::ThreadFunc(void *arg)
{

View File

@ -86,6 +86,8 @@ public:
void ResetBlacklist();
void ReportUnusable(mozilla::net::NetAddr *addr);
size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
private:
friend class nsHostResolver;
@ -93,8 +95,8 @@ private:
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. */
* 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 */
bool mDoomed; /* explicitly expired */
@ -149,6 +151,8 @@ public:
* nsIDNSListener object associated with the original request
*/
virtual bool EqualsAsyncListener(nsIDNSListener *aListener) = 0;
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf) const = 0;
};
/**
@ -232,6 +236,8 @@ public:
RES_OFFLINE = 1 << 6
};
size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
private:
nsHostResolver(uint32_t maxCacheEntries = 50, uint32_t maxCacheLifetime = 1,
uint32_t lifetimeGracePeriod = 0);
@ -268,7 +274,7 @@ private:
uint32_t mMaxCacheEntries;
mozilla::TimeDuration mMaxCacheLifetime;
uint32_t mGracePeriod;
Mutex mLock;
mutable Mutex mLock; // mutable so SizeOfIncludingThis can be const
CondVar mIdleThreadCV;
uint32_t mNumIdleThreads;
uint32_t mThreadCount;