diff --git a/netwerk/cookie/nsCookie.cpp b/netwerk/cookie/nsCookie.cpp index e5cc845a496..34ef96c3a1e 100644 --- a/netwerk/cookie/nsCookie.cpp +++ b/netwerk/cookie/nsCookie.cpp @@ -111,6 +111,14 @@ nsCookie::Create(const nsACString &aName, aIsSession, aIsSecure, aIsHttpOnly); } +size_t +nsCookie::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const +{ + // There is no need to measure the sizes of the individual string + // members, since the strings are stored in-line with the nsCookie. + return aMallocSizeOf(this); +} + /****************************************************************************** * nsCookie: * xpcom impl diff --git a/netwerk/cookie/nsCookie.h b/netwerk/cookie/nsCookie.h index 2effda3338e..d9eeccea813 100644 --- a/netwerk/cookie/nsCookie.h +++ b/netwerk/cookie/nsCookie.h @@ -10,6 +10,8 @@ #include "nsICookie2.h" #include "nsString.h" +#include "mozilla/MemoryReporting.h" + /** * The nsCookie class is the main cookie storage medium for use within cookie * code. It implements nsICookie2, which extends nsICookie, a frozen interface @@ -76,6 +78,8 @@ class nsCookie : public nsICookie2 virtual ~nsCookie() {} + size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + // fast (inline, non-xpcom) getters inline const nsDependentCString Name() const { return nsDependentCString(mName, mValue - 1); } inline const nsDependentCString Value() const { return nsDependentCString(mValue, mHost - 1); } @@ -104,6 +108,8 @@ class nsCookie : public nsICookie2 // so we save on the overhead of using nsCStrings. However, we // store a terminating null for each string, so we can hand them // out as nsAFlatCStrings. + // + // Please update SizeOfIncludingThis if this strategy changes. const char *mName; const char *mValue; const char *mHost; diff --git a/netwerk/cookie/nsCookieService.cpp b/netwerk/cookie/nsCookieService.cpp index a6e139f359d..d8543674048 100644 --- a/netwerk/cookie/nsCookieService.cpp +++ b/netwerk/cookie/nsCookieService.cpp @@ -598,6 +598,70 @@ NS_IMPL_ISUPPORTS1(AppClearDataObserver, nsIObserver) } // anonymous namespace +size_t +nsCookieKey::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const +{ + return mBaseDomain.SizeOfExcludingThisIfUnshared(aMallocSizeOf); +} + +size_t +nsCookieEntry::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const +{ + size_t amount = nsCookieKey::SizeOfExcludingThis(aMallocSizeOf); + + amount += mCookies.SizeOfExcludingThis(aMallocSizeOf); + for (uint32_t i = 0; i < mCookies.Length(); ++i) { + amount += mCookies[i]->SizeOfIncludingThis(aMallocSizeOf); + } + + return amount; +} + +static size_t +HostTableEntrySizeOfExcludingThis(nsCookieEntry *aEntry, + MallocSizeOf aMallocSizeOf, + void *arg) +{ + return aEntry->SizeOfExcludingThis(aMallocSizeOf); +} + +size_t +CookieDomainTuple::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const +{ + size_t amount = 0; + + amount += key.SizeOfExcludingThis(aMallocSizeOf); + amount += cookie->SizeOfIncludingThis(aMallocSizeOf); + + return amount; +} + +static size_t +ReadSetEntrySizeOfExcludingThis(nsCookieKey *aEntry, + MallocSizeOf aMallocSizeOf, + void *) +{ + return aEntry->SizeOfExcludingThis(aMallocSizeOf); +} + +size_t +DBState::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const +{ + size_t amount = 0; + + amount += aMallocSizeOf(this); + amount += hostTable.SizeOfExcludingThis(HostTableEntrySizeOfExcludingThis, + aMallocSizeOf); + amount += hostArray.SizeOfExcludingThis(aMallocSizeOf); + for (uint32_t i = 0; i < hostArray.Length(); ++i) { + amount += hostArray[i].SizeOfExcludingThis(aMallocSizeOf); + } + amount += readSet.SizeOfExcludingThis(ReadSetEntrySizeOfExcludingThis, + aMallocSizeOf); + + return amount; +} + /****************************************************************************** * nsCookieService impl: * singleton instance ctor/dtor methods @@ -653,15 +717,17 @@ nsCookieService::AppClearDataObserverInit() * public methods ******************************************************************************/ -NS_IMPL_ISUPPORTS5(nsCookieService, - nsICookieService, - nsICookieManager, - nsICookieManager2, - nsIObserver, - nsISupportsWeakReference) +NS_IMPL_ISUPPORTS_INHERITED5(nsCookieService, MemoryUniReporter, + nsICookieService, + nsICookieManager, + nsICookieManager2, + nsIObserver, + nsISupportsWeakReference) nsCookieService::nsCookieService() - : mDBState(nullptr) + : MemoryUniReporter("explicit/cookie-service", KIND_HEAP, UNITS_BYTES, + "Memory used by the cookie service.") + , mDBState(nullptr) , mCookieBehavior(BEHAVIOR_ACCEPT) , mThirdPartySession(false) , mMaxNumberOfCookies(kMaxNumberOfCookies) @@ -700,6 +766,8 @@ nsCookieService::Init() // Init our default, and possibly private DBStates. InitDBStates(); + RegisterWeakMemoryReporter(this); + mObserverService = mozilla::services::GetObserverService(); NS_ENSURE_STATE(mObserverService); mObserverService->AddObserver(this, "profile-before-change", true); @@ -1480,6 +1548,8 @@ nsCookieService::~nsCookieService() { CloseDBStates(); + UnregisterWeakMemoryReporter(this); + gCookieService = nullptr; } @@ -4269,3 +4339,23 @@ nsCookieService::UpdateCookieInList(nsCookie *aCookie, } } +size_t +nsCookieService::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const +{ + size_t n = aMallocSizeOf(this); + + if (mDefaultDBState) { + n += mDefaultDBState->SizeOfIncludingThis(aMallocSizeOf); + } + if (mPrivateDBState) { + n += mPrivateDBState->SizeOfIncludingThis(aMallocSizeOf); + } + + return n; +} + +int64_t +nsCookieService::Amount() +{ + return SizeOfIncludingThis(MallocSizeOf); +} diff --git a/netwerk/cookie/nsCookieService.h b/netwerk/cookie/nsCookieService.h index a158bf535d9..1be213525bd 100644 --- a/netwerk/cookie/nsCookieService.h +++ b/netwerk/cookie/nsCookieService.h @@ -16,6 +16,7 @@ #include "nsString.h" #include "nsAutoPtr.h" #include "nsHashKeys.h" +#include "nsIMemoryReporter.h" #include "nsTHashtable.h" #include "mozIStorageStatement.h" #include "mozIStorageAsyncStatement.h" @@ -25,6 +26,8 @@ #include "mozIStorageCompletionCallback.h" #include "mozIStorageStatementCallback.h" +#include "mozilla/MemoryReporting.h" + class nsICookiePermission; class nsIEffectiveTLDService; class nsIIDNService; @@ -101,6 +104,8 @@ public: return mozilla::HashString(temp); } + size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + enum { ALLOW_MEMMOVE = true }; nsCString mBaseDomain; @@ -133,6 +138,8 @@ class nsCookieEntry : public nsCookieKey inline ArrayType& GetCookies() { return mCookies; } + size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + private: ArrayType mCookies; }; @@ -142,6 +149,8 @@ struct CookieDomainTuple { nsCookieKey key; nsRefPtr cookie; + + size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; }; // encapsulates in-memory and on-disk DB states, so we can @@ -154,6 +163,8 @@ struct DBState NS_INLINE_DECL_REFCOUNTING(DBState) + size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + // State of the database connection. enum CorruptFlag { OK, // normal @@ -220,14 +231,19 @@ enum OpenDBResult * class declaration ******************************************************************************/ -class nsCookieService : public nsICookieService +class nsCookieService : public mozilla::MemoryUniReporter + , public nsICookieService , public nsICookieManager2 , public nsIObserver , public nsSupportsWeakReference { + private: + int64_t Amount() MOZ_OVERRIDE; + size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + public: // nsISupports - NS_DECL_ISUPPORTS + NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIOBSERVER NS_DECL_NSICOOKIESERVICE NS_DECL_NSICOOKIEMANAGER