From 17ce4e85453662d4820e53a2708c2b742d4b3dc0 Mon Sep 17 00:00:00 2001 From: Nate Hughes Date: Fri, 17 Jul 2015 14:38:10 -0700 Subject: [PATCH] Bug 986302 - Add memory reporting for HPACK tables. r=hurley r=njn --- netwerk/protocol/http/Http2Compression.cpp | 89 ++++++++++++++++++++++ netwerk/protocol/http/Http2Compression.h | 11 ++- xpcom/base/nsIMemoryReporter.idl | 3 + xpcom/base/nsMemoryReporterManager.cpp | 11 +++ 4 files changed, 113 insertions(+), 1 deletion(-) diff --git a/netwerk/protocol/http/Http2Compression.cpp b/netwerk/protocol/http/Http2Compression.cpp index 9bc69abd611..6edf366e983 100644 --- a/netwerk/protocol/http/Http2Compression.cpp +++ b/netwerk/protocol/http/Http2Compression.cpp @@ -16,6 +16,7 @@ #include "Http2Compression.h" #include "Http2HuffmanIncoming.h" #include "Http2HuffmanOutgoing.h" +#include "mozilla/StaticPtr.h" extern PRThread *gSocketThread; @@ -24,12 +25,70 @@ namespace net { static nsDeque *gStaticHeaders = nullptr; +class HpackStaticTableReporter final : public nsIMemoryReporter +{ +public: + NS_DECL_THREADSAFE_ISUPPORTS + + HpackStaticTableReporter() {} + + NS_IMETHODIMP + CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData, + bool aAnonymize) + { + return MOZ_COLLECT_REPORT( + "explicit/network/hpack/static-table", KIND_HEAP, UNITS_BYTES, + gStaticHeaders->SizeOfIncludingThis(MallocSizeOf), + "Memory usage of HPACK static table."); + } + +private: + MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf) + + ~HpackStaticTableReporter() {} +}; + +NS_IMPL_ISUPPORTS(HpackStaticTableReporter, nsIMemoryReporter) + +class HpackDynamicTableReporter final : public nsIMemoryReporter +{ +public: + NS_DECL_THREADSAFE_ISUPPORTS + + explicit HpackDynamicTableReporter(Http2BaseCompressor* aCompressor) + : mCompressor(aCompressor) + {} + + NS_IMETHODIMP + CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData, + bool aAnonymize) + { + return MOZ_COLLECT_REPORT( + "explicit/network/hpack/dynamic-tables", KIND_HEAP, UNITS_BYTES, + mCompressor->SizeOfExcludingThis(MallocSizeOf), + "Aggregate memory usage of HPACK dynamic tables."); + } + +private: + MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf) + + ~HpackDynamicTableReporter() {} + + Http2BaseCompressor* mCompressor; +}; + +NS_IMPL_ISUPPORTS(HpackDynamicTableReporter, nsIMemoryReporter) + +StaticRefPtr gStaticReporter; + void Http2CompressionCleanup() { // this happens after the socket thread has been destroyed delete gStaticHeaders; gStaticHeaders = nullptr; + UnregisterStrongMemoryReporter(gStaticReporter); + gStaticReporter = nullptr; } static void @@ -51,6 +110,8 @@ InitializeStaticHeaders() MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); if (!gStaticHeaders) { gStaticHeaders = new nsDeque(); + gStaticReporter = new HpackStaticTableReporter(); + RegisterStrongMemoryReporter(gStaticReporter); AddStaticElement(NS_LITERAL_CSTRING(":authority")); AddStaticElement(NS_LITERAL_CSTRING(":method"), NS_LITERAL_CSTRING("GET")); AddStaticElement(NS_LITERAL_CSTRING(":method"), NS_LITERAL_CSTRING("POST")); @@ -115,6 +176,17 @@ InitializeStaticHeaders() } } +size_t nvPair::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const +{ + return mName.SizeOfExcludingThisIfUnshared(aMallocSizeOf) + + mValue.SizeOfExcludingThisIfUnshared(aMallocSizeOf); +} + +size_t nvPair::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const +{ + return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); +} + nvFIFO::nvFIFO() : mByteCount(0) , mTable() @@ -203,6 +275,13 @@ Http2BaseCompressor::Http2BaseCompressor() : mOutput(nullptr) , mMaxBuffer(kDefaultMaxBuffer) { + mDynamicReporter = new HpackDynamicTableReporter(this); + RegisterStrongMemoryReporter(mDynamicReporter); +} + +Http2BaseCompressor::~Http2BaseCompressor() +{ + UnregisterStrongMemoryReporter(mDynamicReporter); } void @@ -211,6 +290,16 @@ Http2BaseCompressor::ClearHeaderTable() mHeaderTable.Clear(); } +size_t +Http2BaseCompressor::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const +{ + size_t size = 0; + for (uint32_t i = mHeaderTable.StaticLength(); i < mHeaderTable.Length(); ++i) { + size += mHeaderTable[i]->SizeOfIncludingThis(aMallocSizeOf); + } + return size; +} + void Http2BaseCompressor::MakeRoom(uint32_t amount, const char *direction) { diff --git a/netwerk/protocol/http/Http2Compression.h b/netwerk/protocol/http/Http2Compression.h index 60f0923040b..c78175d02f1 100644 --- a/netwerk/protocol/http/Http2Compression.h +++ b/netwerk/protocol/http/Http2Compression.h @@ -12,6 +12,7 @@ #include "mozilla/Attributes.h" #include "nsDeque.h" #include "nsString.h" +#include "nsIMemoryReporter.h" namespace mozilla { namespace net { @@ -29,6 +30,8 @@ nvPair(const nsACString &name, const nsACString &value) { } uint32_t Size() const { return mName.Length() + mValue.Length() + 32; } + size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const; + size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const; nsCString mName; nsCString mValue; @@ -54,11 +57,14 @@ private: nsDeque mTable; }; +class HpackDynamicTableReporter; + class Http2BaseCompressor { public: Http2BaseCompressor(); - virtual ~Http2BaseCompressor() { }; + virtual ~Http2BaseCompressor(); + size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; protected: const static uint32_t kDefaultMaxBuffer = 4096; @@ -71,6 +77,9 @@ protected: nvFIFO mHeaderTable; uint32_t mMaxBuffer; + +private: + nsRefPtr mDynamicReporter; }; class Http2Compressor; diff --git a/xpcom/base/nsIMemoryReporter.idl b/xpcom/base/nsIMemoryReporter.idl index 14c31c24c0f..39e3be823b1 100644 --- a/xpcom/base/nsIMemoryReporter.idl +++ b/xpcom/base/nsIMemoryReporter.idl @@ -464,6 +464,9 @@ XPCOM_API(nsresult) RegisterStrongMemoryReporter(nsIMemoryReporter* aReporter); // to this reporter. XPCOM_API(nsresult) RegisterWeakMemoryReporter(nsIMemoryReporter* aReporter); +// Unregister a strong memory reporter. +XPCOM_API(nsresult) UnregisterStrongMemoryReporter(nsIMemoryReporter* aReporter); + // Unregister a weak memory reporter. XPCOM_API(nsresult) UnregisterWeakMemoryReporter(nsIMemoryReporter* aReporter); diff --git a/xpcom/base/nsMemoryReporterManager.cpp b/xpcom/base/nsMemoryReporterManager.cpp index 0d63557103f..00491749d95 100644 --- a/xpcom/base/nsMemoryReporterManager.cpp +++ b/xpcom/base/nsMemoryReporterManager.cpp @@ -2293,6 +2293,17 @@ RegisterWeakMemoryReporter(nsIMemoryReporter* aReporter) return mgr->RegisterWeakReporter(aReporter); } +nsresult +UnregisterStrongMemoryReporter(nsIMemoryReporter* aReporter) +{ + nsCOMPtr mgr = + do_GetService("@mozilla.org/memory-reporter-manager;1"); + if (!mgr) { + return NS_ERROR_FAILURE; + } + return mgr->UnregisterStrongReporter(aReporter); +} + nsresult UnregisterWeakMemoryReporter(nsIMemoryReporter* aReporter) {