diff --git a/js/xpconnect/loader/mozJSComponentLoader.cpp b/js/xpconnect/loader/mozJSComponentLoader.cpp index df7e96e0a2b..9428d817f0c 100644 --- a/js/xpconnect/loader/mozJSComponentLoader.cpp +++ b/js/xpconnect/loader/mozJSComponentLoader.cpp @@ -570,6 +570,37 @@ mozJSComponentLoader::NoteSubScript(HandleScript aScript, HandleObject aThisObje mThisObjects.Put(aScript, aThisObject); } +/* static */ size_t +mozJSComponentLoader::DataEntrySizeOfExcludingThis(const nsACString& aKey, + ModuleEntry* const& aData, + MallocSizeOf aMallocSizeOf, void*) +{ + return aKey.SizeOfExcludingThisIfUnshared(aMallocSizeOf) + + aData->SizeOfIncludingThis(aMallocSizeOf); +} + +/* static */ size_t +mozJSComponentLoader::ClassEntrySizeOfExcludingThis(const nsACString& aKey, + const nsAutoPtr& aData, + MallocSizeOf aMallocSizeOf, void*) +{ + return aKey.SizeOfExcludingThisIfUnshared(aMallocSizeOf) + + aData->SizeOfIncludingThis(aMallocSizeOf); +} + +size_t +mozJSComponentLoader::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) +{ + size_t amount = aMallocSizeOf(this); + + amount += mModules.SizeOfExcludingThis(DataEntrySizeOfExcludingThis, aMallocSizeOf); + amount += mImports.SizeOfExcludingThis(ClassEntrySizeOfExcludingThis, aMallocSizeOf); + amount += mInProgressImports.SizeOfExcludingThis(DataEntrySizeOfExcludingThis, aMallocSizeOf); + amount += mThisObjects.SizeOfExcludingThis(nullptr, aMallocSizeOf); + + return amount; +} + // Some stack based classes for cleaning up on early return #ifdef HAVE_PR_MEMMAP class FileAutoCloser @@ -1353,6 +1384,15 @@ mozJSComponentLoader::Observe(nsISupports *subject, const char *topic, return NS_OK; } +size_t +mozJSComponentLoader::ModuleEntry::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const +{ + size_t n = aMallocSizeOf(this); + n += aMallocSizeOf(location); + + return n; +} + /* static */ already_AddRefed mozJSComponentLoader::ModuleEntry::GetFactory(const mozilla::Module& module, const mozilla::Module::CIDEntry& entry) diff --git a/js/xpconnect/loader/mozJSComponentLoader.h b/js/xpconnect/loader/mozJSComponentLoader.h index 17781640e61..86d2207143d 100644 --- a/js/xpconnect/loader/mozJSComponentLoader.h +++ b/js/xpconnect/loader/mozJSComponentLoader.h @@ -7,6 +7,7 @@ #ifndef mozJSComponentLoader_h #define mozJSComponentLoader_h +#include "mozilla/MemoryReporting.h" #include "mozilla/ModuleLoader.h" #include "nsISupports.h" #include "nsIObserver.h" @@ -55,6 +56,8 @@ class mozJSComponentLoader : public mozilla::ModuleLoader, void NoteSubScript(JS::HandleScript aScript, JS::HandleObject aThisObject); + size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf); + protected: static mozJSComponentLoader* sSelf; @@ -125,6 +128,8 @@ class mozJSComponentLoader : public mozilla::ModuleLoader, location = nullptr; } + size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + static already_AddRefed GetFactory(const mozilla::Module& module, const mozilla::Module::CIDEntry& entry); @@ -135,6 +140,12 @@ class mozJSComponentLoader : public mozilla::ModuleLoader, friend class ModuleEntry; + static size_t DataEntrySizeOfExcludingThis(const nsACString& aKey, ModuleEntry* const& aData, + mozilla::MallocSizeOf aMallocSizeOf, void* arg); + static size_t ClassEntrySizeOfExcludingThis(const nsACString& aKey, + const nsAutoPtr& aData, + mozilla::MallocSizeOf aMallocSizeOf, void* arg); + // Modules are intentionally leaked, but still cleared. static PLDHashOperator ClearModules(const nsACString& key, ModuleEntry*& entry, void* cx); nsDataHashtable mModules; diff --git a/js/xpconnect/src/XPCJSRuntime.cpp b/js/xpconnect/src/XPCJSRuntime.cpp index 6802c6671d8..44ccf44baa0 100644 --- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -14,6 +14,7 @@ #include "XPCJSMemoryReporter.h" #include "WrapperFactory.h" #include "dom_quickstubs.h" +#include "mozJSComponentLoader.h" #include "nsIMemoryReporter.h" #include "nsIObserverService.h" @@ -2634,6 +2635,9 @@ JSReporter::CollectReports(WindowPaths *windowPaths, size_t scopes = XPCWrappedNativeScope::SizeOfAllScopesIncludingThis(JSMallocSizeOf); + mozJSComponentLoader* loader = mozJSComponentLoader::Get(); + size_t jsComponentLoaderSize = loader ? loader->SizeOfIncludingThis(JSMallocSizeOf) : 0; + // This is the second step (see above). First we report stuff in the // "explicit" tree, then we report other stuff. @@ -2723,6 +2727,10 @@ JSReporter::CollectReports(WindowPaths *windowPaths, KIND_HEAP, scopes, "Memory used by XPConnect scopes."); + REPORT_BYTES(NS_LITERAL_CSTRING("explicit/xpconnect/js-component-loader"), + KIND_HEAP, jsComponentLoaderSize, + "Memory used by XPConnect's JS component loader."); + return NS_OK; }