Bug 910517 - Remove nsIMemoryReporter, and rename nsIMemoryMultiReporter as nsIMemoryReporter. r=mmcr8.

This commit is contained in:
Nicholas Nethercote
2013-08-27 16:24:51 -07:00
parent d7f047fa3f
commit d7fc3db766
67 changed files with 855 additions and 1295 deletions

View File

@@ -148,6 +148,9 @@ function reportMemoryUsage() {
var mgr = Cc["@mozilla.org/memory-reporter-manager;1"] var mgr = Cc["@mozilla.org/memory-reporter-manager;1"]
.getService(Ci.nsIMemoryReporterManager); .getService(Ci.nsIMemoryReporterManager);
// XXX: this code is *so* bogus -- nsIMemoryReporter changed its |memoryUsed|
// field to |amount| *years* ago, and even bigger changes have happened
// since -- that it must just never be run.
var reporters = mgr.enumerateReporters(); var reporters = mgr.enumerateReporters();
if (reporters.hasMoreElements()) if (reporters.hasMoreElements())
print("\n"); print("\n");
@@ -376,14 +379,7 @@ function getPotentialLeaks() {
let enm = mgr.enumerateReporters(); let enm = mgr.enumerateReporters();
while (enm.hasMoreElements()) { while (enm.hasMoreElements()) {
let reporter = enm.getNext().QueryInterface(Ci.nsIMemoryReporter); let mr = enm.getNext().QueryInterface(Ci.nsIMemoryReporter);
logReporter(reporter.process, reporter.path, reporter.kind, reporter.units,
reporter.amount, reporter.description);
}
let enm = mgr.enumerateMultiReporters();
while (enm.hasMoreElements()) {
let mr = enm.getNext().QueryInterface(Ci.nsIMemoryMultiReporter);
mr.collectReports(logReporter, null); mr.collectReports(logReporter, null);
} }

View File

@@ -255,11 +255,11 @@ static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
static PLDHashTable sEventListenerManagersHash; static PLDHashTable sEventListenerManagersHash;
class DOMEventListenerManagersHashReporter MOZ_FINAL : public MemoryReporterBase class DOMEventListenerManagersHashReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
DOMEventListenerManagersHashReporter() DOMEventListenerManagersHashReporter()
: MemoryReporterBase( : MemoryUniReporter(
"explicit/dom/event-listener-managers-hash", "explicit/dom/event-listener-managers-hash",
KIND_HEAP, KIND_HEAP,
UNITS_BYTES, UNITS_BYTES,

View File

@@ -641,7 +641,7 @@ nsDOMMemoryFile::DataOwner::sMemoryReporterRegistered;
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(DOMMemoryFileDataOwnerMallocSizeOf) NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(DOMMemoryFileDataOwnerMallocSizeOf)
class nsDOMMemoryFileDataOwnerMemoryReporter MOZ_FINAL class nsDOMMemoryFileDataOwnerMemoryReporter MOZ_FINAL
: public nsIMemoryMultiReporter : public nsIMemoryReporter
{ {
NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_THREADSAFE_ISUPPORTS
@@ -651,7 +651,7 @@ class nsDOMMemoryFileDataOwnerMemoryReporter MOZ_FINAL
return NS_OK; return NS_OK;
} }
NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback *aCallback, NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCallback,
nsISupports *aClosure) nsISupports *aClosure)
{ {
typedef nsDOMMemoryFile::DataOwner DataOwner; typedef nsDOMMemoryFile::DataOwner DataOwner;
@@ -725,7 +725,7 @@ class nsDOMMemoryFileDataOwnerMemoryReporter MOZ_FINAL
}; };
NS_IMPL_ISUPPORTS1(nsDOMMemoryFileDataOwnerMemoryReporter, NS_IMPL_ISUPPORTS1(nsDOMMemoryFileDataOwnerMemoryReporter,
nsIMemoryMultiReporter) nsIMemoryReporter)
/* static */ void /* static */ void
nsDOMMemoryFile::DataOwner::EnsureMemoryReporterRegistered() nsDOMMemoryFile::DataOwner::EnsureMemoryReporterRegistered()
@@ -737,7 +737,7 @@ nsDOMMemoryFile::DataOwner::EnsureMemoryReporterRegistered()
nsRefPtr<nsDOMMemoryFileDataOwnerMemoryReporter> reporter = new nsRefPtr<nsDOMMemoryFileDataOwnerMemoryReporter> reporter = new
nsDOMMemoryFileDataOwnerMemoryReporter(); nsDOMMemoryFileDataOwnerMemoryReporter();
NS_RegisterMemoryMultiReporter(reporter); NS_RegisterMemoryReporter(reporter);
sMemoryReporterRegistered = true; sMemoryReporterRegistered = true;
} }

View File

@@ -143,11 +143,11 @@ static int64_t gCanvasAzureMemoryUsed = 0;
// This is KIND_OTHER because it's not always clear where in memory the pixels // This is KIND_OTHER because it's not always clear where in memory the pixels
// of a canvas are stored. Furthermore, this memory will be tracked by the // of a canvas are stored. Furthermore, this memory will be tracked by the
// underlying surface implementations. See bug 655638 for details. // underlying surface implementations. See bug 655638 for details.
class Canvas2dPixelsReporter MOZ_FINAL : public MemoryReporterBase class Canvas2dPixelsReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
Canvas2dPixelsReporter() Canvas2dPixelsReporter()
: MemoryReporterBase("canvas-2d-pixels", KIND_OTHER, UNITS_BYTES, : MemoryUniReporter("canvas-2d-pixels", KIND_OTHER, UNITS_BYTES,
"Memory used by 2D canvases. Each canvas requires (width * height * 4) bytes.") "Memory used by 2D canvases. Each canvas requires (width * height * 4) bytes.")
{} {}
private: private:

View File

@@ -10,7 +10,7 @@
#include "WebGLContextUtils.h" #include "WebGLContextUtils.h"
#include "WebGLBuffer.h" #include "WebGLBuffer.h"
#include "WebGLVertexAttribData.h" #include "WebGLVertexAttribData.h"
#include "WebGLMemoryMultiReporterWrapper.h" #include "WebGLMemoryReporterWrapper.h"
#include "WebGLFramebuffer.h" #include "WebGLFramebuffer.h"
#include "WebGLVertexArray.h" #include "WebGLVertexArray.h"
#include "WebGLQuery.h" #include "WebGLQuery.h"
@@ -179,7 +179,7 @@ WebGLContext::WebGLContext()
mPixelStorePackAlignment = 4; mPixelStorePackAlignment = 4;
mPixelStoreUnpackAlignment = 4; mPixelStoreUnpackAlignment = 4;
WebGLMemoryMultiReporterWrapper::AddWebGLContext(this); WebGLMemoryReporterWrapper::AddWebGLContext(this);
mAllowRestore = true; mAllowRestore = true;
mContextLossTimerRunning = false; mContextLossTimerRunning = false;
@@ -213,7 +213,7 @@ WebGLContext::WebGLContext()
WebGLContext::~WebGLContext() WebGLContext::~WebGLContext()
{ {
DestroyResourcesAndContext(); DestroyResourcesAndContext();
WebGLMemoryMultiReporterWrapper::RemoveWebGLContext(this); WebGLMemoryReporterWrapper::RemoveWebGLContext(this);
TerminateContextLossTimer(); TerminateContextLossTimer();
mContextRestorer = nullptr; mContextRestorer = nullptr;
} }
@@ -653,8 +653,8 @@ void WebGLContext::LoseOldestWebGLContextIfLimitExceeded()
// when choosing which one to lose first. // when choosing which one to lose first.
UpdateLastUseIndex(); UpdateLastUseIndex();
WebGLMemoryMultiReporterWrapper::ContextsArrayType &contexts WebGLMemoryReporterWrapper::ContextsArrayType &contexts
= WebGLMemoryMultiReporterWrapper::Contexts(); = WebGLMemoryReporterWrapper::Contexts();
// quick exit path, should cover a majority of cases // quick exit path, should cover a majority of cases
if (contexts.Length() <= kMaxWebGLContextsPerPrincipal) { if (contexts.Length() <= kMaxWebGLContextsPerPrincipal) {

View File

@@ -118,7 +118,7 @@ class WebGLContext :
{ {
friend class WebGLContextUserData; friend class WebGLContextUserData;
friend class WebGLMemoryPressureObserver; friend class WebGLMemoryPressureObserver;
friend class WebGLMemoryMultiReporterWrapper; friend class WebGLMemoryReporterWrapper;
friend class WebGLExtensionLoseContext; friend class WebGLExtensionLoseContext;
friend class WebGLExtensionCompressedTextureS3TC; friend class WebGLExtensionCompressedTextureS3TC;
friend class WebGLExtensionCompressedTextureATC; friend class WebGLExtensionCompressedTextureATC;

View File

@@ -4,32 +4,32 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebGLContext.h" #include "WebGLContext.h"
#include "WebGLMemoryMultiReporterWrapper.h" #include "WebGLMemoryReporterWrapper.h"
#include "nsIMemoryReporter.h" #include "nsIMemoryReporter.h"
using namespace mozilla; using namespace mozilla;
NS_IMPL_ISUPPORTS1(WebGLMemoryPressureObserver, nsIObserver) NS_IMPL_ISUPPORTS1(WebGLMemoryPressureObserver, nsIObserver)
class WebGLMemoryMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter class WebGLMemoryReporter MOZ_FINAL : public nsIMemoryReporter
{ {
public: public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_DECL_NSIMEMORYMULTIREPORTER NS_DECL_NSIMEMORYREPORTER
}; };
NS_IMPL_ISUPPORTS1(WebGLMemoryMultiReporter, nsIMemoryMultiReporter) NS_IMPL_ISUPPORTS1(WebGLMemoryReporter, nsIMemoryReporter)
NS_IMETHODIMP NS_IMETHODIMP
WebGLMemoryMultiReporter::GetName(nsACString &aName) WebGLMemoryReporter::GetName(nsACString &aName)
{ {
aName.AssignLiteral("webgl"); aName.AssignLiteral("webgl");
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
WebGLMemoryMultiReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb, WebGLMemoryReporter::CollectReports(nsIMemoryReporterCallback* aCb,
nsISupports* aClosure) nsISupports* aClosure)
{ {
#define REPORT(_path, _kind, _units, _amount, _desc) \ #define REPORT(_path, _kind, _units, _amount, _desc) \
do { \ do { \
@@ -42,21 +42,21 @@ WebGLMemoryMultiReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
REPORT("webgl-texture-memory", REPORT("webgl-texture-memory",
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES, nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES,
WebGLMemoryMultiReporterWrapper::GetTextureMemoryUsed(), WebGLMemoryReporterWrapper::GetTextureMemoryUsed(),
"Memory used by WebGL textures.The OpenGL" "Memory used by WebGL textures.The OpenGL"
" implementation is free to store these textures in either video" " implementation is free to store these textures in either video"
" memory or main memory. This measurement is only a lower bound," " memory or main memory. This measurement is only a lower bound,"
" actual memory usage may be higher for example if the storage" " actual memory usage may be higher for example if the storage"
" is strided."); " is strided.");
REPORT("webgl-texture-count", REPORT("webgl-texture-count",
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT, nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
WebGLMemoryMultiReporterWrapper::GetTextureCount(), WebGLMemoryReporterWrapper::GetTextureCount(),
"Number of WebGL textures."); "Number of WebGL textures.");
REPORT("webgl-buffer-memory", REPORT("webgl-buffer-memory",
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES, nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES,
WebGLMemoryMultiReporterWrapper::GetBufferMemoryUsed(), WebGLMemoryReporterWrapper::GetBufferMemoryUsed(),
"Memory used by WebGL buffers. The OpenGL" "Memory used by WebGL buffers. The OpenGL"
" implementation is free to store these buffers in either video" " implementation is free to store these buffers in either video"
" memory or main memory. This measurement is only a lower bound," " memory or main memory. This measurement is only a lower bound,"
@@ -65,7 +65,7 @@ WebGLMemoryMultiReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
REPORT("explicit/webgl/buffer-cache-memory", REPORT("explicit/webgl/buffer-cache-memory",
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
WebGLMemoryMultiReporterWrapper::GetBufferCacheMemoryUsed(), WebGLMemoryReporterWrapper::GetBufferCacheMemoryUsed(),
"Memory used by WebGL buffer caches. The WebGL" "Memory used by WebGL buffer caches. The WebGL"
" implementation caches the contents of element array buffers" " implementation caches the contents of element array buffers"
" only.This adds up with the webgl-buffer-memory value, but" " only.This adds up with the webgl-buffer-memory value, but"
@@ -74,69 +74,69 @@ WebGLMemoryMultiReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
REPORT("webgl-buffer-count", REPORT("webgl-buffer-count",
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT, nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
WebGLMemoryMultiReporterWrapper::GetBufferCount(), WebGLMemoryReporterWrapper::GetBufferCount(),
"Number of WebGL buffers."); "Number of WebGL buffers.");
REPORT("webgl-renderbuffer-memory", REPORT("webgl-renderbuffer-memory",
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES, nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES,
WebGLMemoryMultiReporterWrapper::GetRenderbufferMemoryUsed(), WebGLMemoryReporterWrapper::GetRenderbufferMemoryUsed(),
"Memory used by WebGL renderbuffers. The OpenGL" "Memory used by WebGL renderbuffers. The OpenGL"
" implementation is free to store these renderbuffers in either" " implementation is free to store these renderbuffers in either"
" video memory or main memory. This measurement is only a lower" " video memory or main memory. This measurement is only a lower"
" bound, actual memory usage may be higher for example if the" " bound, actual memory usage may be higher for example if the"
" storage is strided."); " storage is strided.");
REPORT("webgl-renderbuffer-count", REPORT("webgl-renderbuffer-count",
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT, nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
WebGLMemoryMultiReporterWrapper::GetRenderbufferCount(), WebGLMemoryReporterWrapper::GetRenderbufferCount(),
"Number of WebGL renderbuffers."); "Number of WebGL renderbuffers.");
REPORT("explicit/webgl/shader", REPORT("explicit/webgl/shader",
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
WebGLMemoryMultiReporterWrapper::GetShaderSize(), WebGLMemoryReporterWrapper::GetShaderSize(),
"Combined size of WebGL shader ASCII sources and translation" "Combined size of WebGL shader ASCII sources and translation"
" logs cached on the heap."); " logs cached on the heap.");
REPORT("webgl-shader-count", REPORT("webgl-shader-count",
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT, nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
WebGLMemoryMultiReporterWrapper::GetShaderCount(), WebGLMemoryReporterWrapper::GetShaderCount(),
"Number of WebGL shaders."); "Number of WebGL shaders.");
REPORT("webgl-context-count", REPORT("webgl-context-count",
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT, nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
WebGLMemoryMultiReporterWrapper::GetContextCount(), WebGLMemoryReporterWrapper::GetContextCount(),
"Number of WebGL contexts."); "Number of WebGL contexts.");
#undef REPORT #undef REPORT
return NS_OK; return NS_OK;
} }
WebGLMemoryMultiReporterWrapper* WebGLMemoryMultiReporterWrapper::sUniqueInstance = nullptr; WebGLMemoryReporterWrapper* WebGLMemoryReporterWrapper::sUniqueInstance = nullptr;
WebGLMemoryMultiReporterWrapper* WebGLMemoryMultiReporterWrapper::UniqueInstance() WebGLMemoryReporterWrapper* WebGLMemoryReporterWrapper::UniqueInstance()
{ {
if (!sUniqueInstance) { if (!sUniqueInstance) {
sUniqueInstance = new WebGLMemoryMultiReporterWrapper; sUniqueInstance = new WebGLMemoryReporterWrapper;
} }
return sUniqueInstance; return sUniqueInstance;
} }
WebGLMemoryMultiReporterWrapper::WebGLMemoryMultiReporterWrapper() WebGLMemoryReporterWrapper::WebGLMemoryReporterWrapper()
{
mReporter = new WebGLMemoryMultiReporter;
NS_RegisterMemoryMultiReporter(mReporter);
}
WebGLMemoryMultiReporterWrapper::~WebGLMemoryMultiReporterWrapper()
{ {
NS_UnregisterMemoryMultiReporter(mReporter); mReporter = new WebGLMemoryReporter;
NS_RegisterMemoryReporter(mReporter);
}
WebGLMemoryReporterWrapper::~WebGLMemoryReporterWrapper()
{
NS_UnregisterMemoryReporter(mReporter);
} }
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLBufferMallocSizeOf) NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLBufferMallocSizeOf)
int64_t int64_t
WebGLMemoryMultiReporterWrapper::GetBufferCacheMemoryUsed() { WebGLMemoryReporterWrapper::GetBufferCacheMemoryUsed() {
const ContextsArrayType & contexts = Contexts(); const ContextsArrayType & contexts = Contexts();
int64_t result = 0; int64_t result = 0;
for(size_t i = 0; i < contexts.Length(); ++i) { for(size_t i = 0; i < contexts.Length(); ++i) {
@@ -153,8 +153,8 @@ WebGLMemoryMultiReporterWrapper::GetBufferCacheMemoryUsed() {
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLShaderMallocSizeOf) NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLShaderMallocSizeOf)
int64_t int64_t
WebGLMemoryMultiReporterWrapper::GetShaderSize() { WebGLMemoryReporterWrapper::GetShaderSize() {
const ContextsArrayType & contexts = Contexts(); const ContextsArrayType & contexts = Contexts();
int64_t result = 0; int64_t result = 0;
for(size_t i = 0; i < contexts.Length(); ++i) { for(size_t i = 0; i < contexts.Length(); ++i) {

View File

@@ -3,8 +3,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef WEBGLMEMORYMULTIREPORTWRAPER_H_ #ifndef WEBGLMEMORYREPORTWRAPER_H_
#define WEBGLMEMORYMULTIREPORTWRAPER_H_ #define WEBGLMEMORYREPORTWRAPER_H_
#include "WebGLContext.h" #include "WebGLContext.h"
#include "WebGLBuffer.h" #include "WebGLBuffer.h"
@@ -17,21 +17,21 @@
namespace mozilla { namespace mozilla {
class WebGLMemoryMultiReporterWrapper class WebGLMemoryReporterWrapper
{ {
WebGLMemoryMultiReporterWrapper(); WebGLMemoryReporterWrapper();
~WebGLMemoryMultiReporterWrapper(); ~WebGLMemoryReporterWrapper();
static WebGLMemoryMultiReporterWrapper* sUniqueInstance; static WebGLMemoryReporterWrapper* sUniqueInstance;
// here we store plain pointers, not RefPtrs: we don't want the // here we store plain pointers, not RefPtrs: we don't want the
// WebGLMemoryMultiReporterWrapper unique instance to keep alive all // WebGLMemoryReporterWrapper unique instance to keep alive all
// WebGLContexts ever created. // WebGLContexts ever created.
typedef nsTArray<const WebGLContext*> ContextsArrayType; typedef nsTArray<const WebGLContext*> ContextsArrayType;
ContextsArrayType mContexts; ContextsArrayType mContexts;
nsCOMPtr<nsIMemoryMultiReporter> mReporter; nsCOMPtr<nsIMemoryReporter> mReporter;
static WebGLMemoryMultiReporterWrapper* UniqueInstance(); static WebGLMemoryReporterWrapper* UniqueInstance();
static ContextsArrayType & Contexts() { return UniqueInstance()->mContexts; } static ContextsArrayType & Contexts() { return UniqueInstance()->mContexts; }

View File

@@ -74,7 +74,7 @@ class MediaMemoryTracker
DecodersArray mDecoders; DecodersArray mDecoders;
nsCOMPtr<nsIMemoryMultiReporter> mReporter; nsCOMPtr<nsIMemoryReporter> mReporter;
public: public:
static void AddMediaDecoder(MediaDecoder* aDecoder) static void AddMediaDecoder(MediaDecoder* aDecoder)
@@ -1725,7 +1725,7 @@ MediaDecoder::IsWMFEnabled()
} }
#endif #endif
class MediaReporter MOZ_FINAL : public nsIMemoryMultiReporter class MediaReporter MOZ_FINAL : public nsIMemoryReporter
{ {
public: public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
@@ -1736,7 +1736,7 @@ public:
return NS_OK; return NS_OK;
} }
NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback* aCb, NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCb,
nsISupports* aClosure) nsISupports* aClosure)
{ {
int64_t video, audio; int64_t video, audio;
@@ -1762,7 +1762,7 @@ public:
} }
}; };
NS_IMPL_ISUPPORTS1(MediaReporter, nsIMemoryMultiReporter) NS_IMPL_ISUPPORTS1(MediaReporter, nsIMemoryReporter)
MediaDecoderOwner* MediaDecoderOwner*
MediaDecoder::GetOwner() MediaDecoder::GetOwner()
@@ -1774,12 +1774,12 @@ MediaDecoder::GetOwner()
MediaMemoryTracker::MediaMemoryTracker() MediaMemoryTracker::MediaMemoryTracker()
: mReporter(new MediaReporter()) : mReporter(new MediaReporter())
{ {
NS_RegisterMemoryMultiReporter(mReporter); NS_RegisterMemoryReporter(mReporter);
} }
MediaMemoryTracker::~MediaMemoryTracker() MediaMemoryTracker::~MediaMemoryTracker()
{ {
NS_UnregisterMemoryMultiReporter(mReporter); NS_UnregisterMemoryReporter(mReporter);
} }
} // namespace mozilla } // namespace mozilla

View File

@@ -116,11 +116,11 @@ GlobalNameHashInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
return true; return true;
} }
class ScriptNameSpaceManagerReporter MOZ_FINAL : public MemoryReporterBase class ScriptNameSpaceManagerReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
ScriptNameSpaceManagerReporter(nsScriptNameSpaceManager* aManager) ScriptNameSpaceManagerReporter(nsScriptNameSpaceManager* aManager)
: MemoryReporterBase( : MemoryUniReporter(
"explicit/script-namespace-manager", "explicit/script-namespace-manager",
KIND_HEAP, KIND_HEAP,
nsIMemoryReporter::UNITS_BYTES, nsIMemoryReporter::UNITS_BYTES,

View File

@@ -25,7 +25,7 @@ nsWindowMemoryReporter::nsWindowMemoryReporter()
mDetachedWindows.Init(); mDetachedWindows.Init();
} }
NS_IMPL_ISUPPORTS3(nsWindowMemoryReporter, nsIMemoryMultiReporter, nsIObserver, NS_IMPL_ISUPPORTS3(nsWindowMemoryReporter, nsIMemoryReporter, nsIObserver,
nsSupportsWeakReference) nsSupportsWeakReference)
/* static */ /* static */
@@ -34,7 +34,7 @@ nsWindowMemoryReporter::Init()
{ {
// The memory reporter manager will own this object. // The memory reporter manager will own this object.
nsRefPtr<nsWindowMemoryReporter> windowReporter = new nsWindowMemoryReporter(); nsRefPtr<nsWindowMemoryReporter> windowReporter = new nsWindowMemoryReporter();
NS_RegisterMemoryMultiReporter(windowReporter); NS_RegisterMemoryReporter(windowReporter);
nsCOMPtr<nsIObserverService> os = services::GetObserverService(); nsCOMPtr<nsIObserverService> os = services::GetObserverService();
if (os) { if (os) {
@@ -46,13 +46,13 @@ nsWindowMemoryReporter::Init()
/* weakRef = */ true); /* weakRef = */ true);
} }
nsRefPtr<GhostURLsReporter> ghostMultiReporter = nsRefPtr<GhostURLsReporter> ghostURLsReporter =
new GhostURLsReporter(windowReporter); new GhostURLsReporter(windowReporter);
NS_RegisterMemoryMultiReporter(ghostMultiReporter); NS_RegisterMemoryReporter(ghostURLsReporter);
nsRefPtr<NumGhostsReporter> ghostReporter = nsRefPtr<NumGhostsReporter> numGhostsReporter =
new NumGhostsReporter(windowReporter); new NumGhostsReporter(windowReporter);
NS_RegisterMemoryReporter(ghostReporter); NS_RegisterMemoryReporter(numGhostsReporter);
} }
static already_AddRefed<nsIURI> static already_AddRefed<nsIURI>
@@ -122,7 +122,7 @@ CollectWindowReports(nsGlobalWindow *aWindow,
nsTHashtable<nsUint64HashKey> *aGhostWindowIDs, nsTHashtable<nsUint64HashKey> *aGhostWindowIDs,
WindowPaths *aWindowPaths, WindowPaths *aWindowPaths,
WindowPaths *aTopWindowPaths, WindowPaths *aTopWindowPaths,
nsIMemoryMultiReporterCallback *aCb, nsIMemoryReporterCallback *aCb,
nsISupports *aClosure) nsISupports *aClosure)
{ {
nsAutoCString windowPath("explicit/"); nsAutoCString windowPath("explicit/");
@@ -320,7 +320,7 @@ nsWindowMemoryReporter::GetName(nsACString &aName)
} }
NS_IMETHODIMP NS_IMETHODIMP
nsWindowMemoryReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb, nsWindowMemoryReporter::CollectReports(nsIMemoryReporterCallback* aCb,
nsISupports* aClosure) nsISupports* aClosure)
{ {
nsGlobalWindow::WindowByIdTable* windowsById = nsGlobalWindow::WindowByIdTable* windowsById =
@@ -356,9 +356,9 @@ nsWindowMemoryReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
} }
// Report JS memory usage. We do this from here because the JS memory // Report JS memory usage. We do this from here because the JS memory
// multi-reporter needs to be passed |windowPaths|. // reporter needs to be passed |windowPaths|.
nsresult rv = xpc::JSMemoryMultiReporter::CollectReports(&windowPaths, &topWindowPaths, nsresult rv = xpc::JSReporter::CollectReports(&windowPaths, &topWindowPaths,
aCb, aClosure); aCb, aClosure);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
#define REPORT(_path, _amount, _desc) \ #define REPORT(_path, _amount, _desc) \
@@ -668,7 +668,7 @@ nsWindowMemoryReporter::CheckForGhostWindows(
} }
NS_IMPL_ISUPPORTS1(nsWindowMemoryReporter::GhostURLsReporter, NS_IMPL_ISUPPORTS1(nsWindowMemoryReporter::GhostURLsReporter,
nsIMemoryMultiReporter) nsIMemoryReporter)
nsWindowMemoryReporter:: nsWindowMemoryReporter::
GhostURLsReporter::GhostURLsReporter( GhostURLsReporter::GhostURLsReporter(
@@ -687,7 +687,7 @@ GhostURLsReporter::GetName(nsACString& aName)
struct ReportGhostWindowsEnumeratorData struct ReportGhostWindowsEnumeratorData
{ {
nsIMemoryMultiReporterCallback* callback; nsIMemoryReporterCallback* callback;
nsISupports* closure; nsISupports* closure;
nsresult rv; nsresult rv;
}; };
@@ -734,7 +734,7 @@ ReportGhostWindowsEnumerator(nsUint64HashKey* aIDHashKey, void* aClosure)
NS_IMETHODIMP NS_IMETHODIMP
nsWindowMemoryReporter:: nsWindowMemoryReporter::
GhostURLsReporter::CollectReports( GhostURLsReporter::CollectReports(
nsIMemoryMultiReporterCallback* aCb, nsIMemoryReporterCallback* aCb,
nsISupports* aClosure) nsISupports* aClosure)
{ {
// Get the IDs of all the ghost windows in existance. // Get the IDs of all the ghost windows in existance.
@@ -752,25 +752,6 @@ GhostURLsReporter::CollectReports(
return reportGhostWindowsEnumData.rv; return reportGhostWindowsEnumData.rv;
} }
NS_IMETHODIMP
nsWindowMemoryReporter::
NumGhostsReporter::GetDescription(nsACString& aDesc)
{
nsPrintfCString str(
"The number of ghost windows present (the number of nodes underneath \
explicit/window-objects/top(none)/ghost, modulo race conditions). A ghost \
window is not shown in any tab, does not share a domain with any non-detached \
windows, and has met these criteria for at least %ds \
(memory.ghost_window_timeout_seconds) or has survived a round of about:memory's \
minimize memory usage button.\n\n\
Ghost windows can happen legitimately, but they are often indicative of leaks \
in the browser or add-ons.",
mWindowReporter->GetGhostTimeout());
aDesc.Assign(str);
return NS_OK;
}
int64_t int64_t
nsWindowMemoryReporter::NumGhostsReporter::Amount() nsWindowMemoryReporter::NumGhostsReporter::Amount()
{ {

View File

@@ -108,13 +108,13 @@ public:
* the tab. * the tab.
* *
*/ */
class nsWindowMemoryReporter MOZ_FINAL : public nsIMemoryMultiReporter, class nsWindowMemoryReporter MOZ_FINAL : public nsIMemoryReporter,
public nsIObserver, public nsIObserver,
public nsSupportsWeakReference public nsSupportsWeakReference
{ {
public: public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_DECL_NSIMEMORYMULTIREPORTER NS_DECL_NSIMEMORYREPORTER
NS_DECL_NSIOBSERVER NS_DECL_NSIOBSERVER
static void Init(); static void Init();
@@ -126,33 +126,38 @@ private:
* this list, running this report is faster than running * this list, running this report is faster than running
* nsWindowMemoryReporter. * nsWindowMemoryReporter.
*/ */
class GhostURLsReporter MOZ_FINAL : public nsIMemoryMultiReporter class GhostURLsReporter MOZ_FINAL : public nsIMemoryReporter
{ {
public: public:
GhostURLsReporter(nsWindowMemoryReporter* aWindowReporter); GhostURLsReporter(nsWindowMemoryReporter* aWindowReporter);
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_DECL_NSIMEMORYMULTIREPORTER NS_DECL_NSIMEMORYREPORTER
private: private:
nsRefPtr<nsWindowMemoryReporter> mWindowReporter; nsRefPtr<nsWindowMemoryReporter> mWindowReporter;
}; };
/** /**
* nsGhostWindowReporter generates the "ghost-windows" single-report, which * nsGhostWindowReporter generates the "ghost-windows" report, which counts
* counts the number of ghost windows present. * the number of ghost windows present.
*/ */
class NumGhostsReporter MOZ_FINAL : public mozilla::MemoryReporterBase class NumGhostsReporter MOZ_FINAL : public mozilla::MemoryUniReporter
{ {
public: public:
NumGhostsReporter(nsWindowMemoryReporter* aWindowReporter) NumGhostsReporter(nsWindowMemoryReporter* aWindowReporter)
// Description is "???" because we define GetDescription below. : MemoryUniReporter("ghost-windows", KIND_OTHER, UNITS_COUNT,
: MemoryReporterBase("ghost-windows", KIND_OTHER, UNITS_COUNT, "???") "The number of ghost windows present (the number of nodes underneath "
"explicit/window-objects/top(none)/ghost, modulo race conditions). A ghost "
"window is not shown in any tab, does not share a domain with any non-detached "
"windows, and has met these criteria for at least "
"memory.ghost_window_timeout_seconds, or has survived a round of "
"about:memory's minimize memory usage button.\n\n"
"Ghost windows can happen legitimately, but they are often indicative of "
"leaks in the browser or add-ons.")
, mWindowReporter(aWindowReporter) , mWindowReporter(aWindowReporter)
{} {}
NS_IMETHOD GetDescription(nsACString& aDesc);
private: private:
int64_t Amount() MOZ_OVERRIDE; int64_t Amount() MOZ_OVERRIDE;

View File

@@ -398,7 +398,7 @@ ContentChild::AllocPMemoryReportRequestChild()
} }
// This is just a wrapper for InfallibleTArray<MemoryReport> that implements // This is just a wrapper for InfallibleTArray<MemoryReport> that implements
// nsISupports, so it can be passed to nsIMemoryMultiReporter::CollectReports. // nsISupports, so it can be passed to nsIMemoryReporter::CollectReports.
class MemoryReportsWrapper MOZ_FINAL : public nsISupports { class MemoryReportsWrapper MOZ_FINAL : public nsISupports {
public: public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
@@ -407,7 +407,7 @@ public:
}; };
NS_IMPL_ISUPPORTS0(MemoryReportsWrapper) NS_IMPL_ISUPPORTS0(MemoryReportsWrapper)
class MemoryReportCallback MOZ_FINAL : public nsIMemoryMultiReporterCallback class MemoryReportCallback MOZ_FINAL : public nsIMemoryReporterCallback
{ {
public: public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
@@ -435,53 +435,28 @@ private:
}; };
NS_IMPL_ISUPPORTS1( NS_IMPL_ISUPPORTS1(
MemoryReportCallback MemoryReportCallback
, nsIMemoryMultiReporterCallback , nsIMemoryReporterCallback
) )
bool bool
ContentChild::RecvPMemoryReportRequestConstructor(PMemoryReportRequestChild* child) ContentChild::RecvPMemoryReportRequestConstructor(PMemoryReportRequestChild* child)
{ {
nsCOMPtr<nsIMemoryReporterManager> mgr = do_GetService("@mozilla.org/memory-reporter-manager;1"); nsCOMPtr<nsIMemoryReporterManager> mgr = do_GetService("@mozilla.org/memory-reporter-manager;1");
InfallibleTArray<MemoryReport> reports; InfallibleTArray<MemoryReport> reports;
nsPrintfCString process("Content (%d)", getpid()); nsPrintfCString process("Content (%d)", getpid());
// First do the vanilla memory reporters. // Run each reporter. The callback will turn each measurement into a
// MemoryReport.
nsCOMPtr<nsISimpleEnumerator> e; nsCOMPtr<nsISimpleEnumerator> e;
mgr->EnumerateReporters(getter_AddRefs(e)); mgr->EnumerateReporters(getter_AddRefs(e));
bool more;
while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) {
nsCOMPtr<nsIMemoryReporter> r;
e->GetNext(getter_AddRefs(r));
nsCString path;
int32_t kind;
int32_t units;
int64_t amount;
nsCString desc;
if (NS_SUCCEEDED(r->GetPath(path)) &&
NS_SUCCEEDED(r->GetKind(&kind)) &&
NS_SUCCEEDED(r->GetUnits(&units)) &&
NS_SUCCEEDED(r->GetAmount(&amount)) &&
NS_SUCCEEDED(r->GetDescription(desc)))
{
MemoryReport memreport(process, path, kind, units, amount, desc);
reports.AppendElement(memreport);
}
}
// Then do the memory multi-reporters, by calling CollectReports on each
// one, whereupon the callback will turn each measurement into a
// MemoryReport.
mgr->EnumerateMultiReporters(getter_AddRefs(e));
nsRefPtr<MemoryReportsWrapper> wrappedReports = nsRefPtr<MemoryReportsWrapper> wrappedReports =
new MemoryReportsWrapper(&reports); new MemoryReportsWrapper(&reports);
nsRefPtr<MemoryReportCallback> cb = new MemoryReportCallback(process); nsRefPtr<MemoryReportCallback> cb = new MemoryReportCallback(process);
bool more;
while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) { while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) {
nsCOMPtr<nsIMemoryMultiReporter> r; nsCOMPtr<nsIMemoryReporter> r;
e->GetNext(getter_AddRefs(r)); e->GetNext(getter_AddRefs(r));
r->CollectReports(cb, wrappedReports); r->CollectReports(cb, wrappedReports);
} }

View File

@@ -159,34 +159,54 @@ namespace dom {
#define NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC "ipc:network:set-offline" #define NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC "ipc:network:set-offline"
// This represents a single measurement taken by a memory reporter in a child // This represents all the memory reports provided by a child process.
// process and passed to this one. Its process is non-empty, and its amount is class ChildReporter MOZ_FINAL : public nsIMemoryReporter
// fixed.
class ChildMemoryReporter MOZ_FINAL : public MemoryReporterBase
{ {
public: public:
ChildMemoryReporter(const char* aProcess, const char* aPath, int32_t aKind, ChildReporter(const InfallibleTArray<MemoryReport>& childReports)
int32_t aUnits, int64_t aAmount,
const char* aDescription)
: MemoryReporterBase(aPath, aKind, aUnits, aDescription)
, mProcess(aProcess)
, mAmount(aAmount)
{ {
for (uint32_t i = 0; i < childReports.Length(); i++) {
MemoryReport r(childReports[i].process(),
childReports[i].path(),
childReports[i].kind(),
childReports[i].units(),
childReports[i].amount(),
childReports[i].desc());
// Child reports have a non-empty process.
MOZ_ASSERT(!r.process().IsEmpty());
mChildReports.AppendElement(r);
}
} }
NS_IMETHOD GetProcess(nsACString& aProcess) NS_DECL_ISUPPORTS
NS_IMETHOD GetName(nsACString& name)
{ {
aProcess.Assign(mProcess); name.AssignLiteral("content-child");
return NS_OK; return NS_OK;
} }
private: NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCb,
int64_t Amount() { return mAmount; } nsISupports* aClosure)
{
for (uint32_t i = 0; i < mChildReports.Length(); i++) {
nsresult rv;
MemoryReport r = mChildReports[i];
rv = aCb->Callback(r.process(), r.path(), r.kind(), r.units(),
r.amount(), r.desc(), aClosure);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
nsCString mProcess; private:
int64_t mAmount; InfallibleTArray<MemoryReport> mChildReports;
}; };
NS_IMPL_ISUPPORTS1(ChildReporter, nsIMemoryReporter)
class MemoryReportRequestParent : public PMemoryReportRequestParent class MemoryReportRequestParent : public PMemoryReportRequestParent
{ {
public: public:
@@ -207,9 +227,9 @@ MemoryReportRequestParent::MemoryReportRequestParent()
} }
bool bool
MemoryReportRequestParent::Recv__delete__(const InfallibleTArray<MemoryReport>& report) MemoryReportRequestParent::Recv__delete__(const InfallibleTArray<MemoryReport>& childReports)
{ {
Owner()->SetChildMemoryReporters(report); Owner()->SetChildMemoryReports(childReports);
return true; return true;
} }
@@ -221,15 +241,15 @@ MemoryReportRequestParent::~MemoryReportRequestParent()
/** /**
* A memory reporter for ContentParent objects themselves. * A memory reporter for ContentParent objects themselves.
*/ */
class ContentParentMemoryReporter MOZ_FINAL : public nsIMemoryMultiReporter class ContentParentMemoryReporter MOZ_FINAL : public nsIMemoryReporter
{ {
public: public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_DECL_NSIMEMORYMULTIREPORTER NS_DECL_NSIMEMORYREPORTER
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(MallocSizeOf) NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(MallocSizeOf)
}; };
NS_IMPL_ISUPPORTS1(ContentParentMemoryReporter, nsIMemoryMultiReporter) NS_IMPL_ISUPPORTS1(ContentParentMemoryReporter, nsIMemoryReporter)
NS_IMETHODIMP NS_IMETHODIMP
ContentParentMemoryReporter::GetName(nsACString& aName) ContentParentMemoryReporter::GetName(nsACString& aName)
@@ -239,7 +259,7 @@ ContentParentMemoryReporter::GetName(nsACString& aName)
} }
NS_IMETHODIMP NS_IMETHODIMP
ContentParentMemoryReporter::CollectReports(nsIMemoryMultiReporterCallback* cb, ContentParentMemoryReporter::CollectReports(nsIMemoryReporterCallback* cb,
nsISupports* aClosure) nsISupports* aClosure)
{ {
nsAutoTArray<ContentParent*, 16> cps; nsAutoTArray<ContentParent*, 16> cps;
@@ -356,7 +376,7 @@ ContentParent::StartUp()
} }
nsRefPtr<ContentParentMemoryReporter> mr = new ContentParentMemoryReporter(); nsRefPtr<ContentParentMemoryReporter> mr = new ContentParentMemoryReporter();
NS_RegisterMemoryMultiReporter(mr); NS_RegisterMemoryReporter(mr);
sCanLaunchSubprocesses = true; sCanLaunchSubprocesses = true;
@@ -876,7 +896,7 @@ ContentParent::ShutDownProcess(bool aCloseWithError)
// shut down the cycle collector. But by then it's too late to release any // shut down the cycle collector. But by then it's too late to release any
// CC'ed objects, so we need to null them out here, while we still can. See // CC'ed objects, so we need to null them out here, while we still can. See
// bug 899761. // bug 899761.
mMemoryReporters.Clear(); mChildReporter = nullptr;
if (mMessageManager) { if (mMessageManager) {
mMessageManager->Disconnect(); mMessageManager->Disconnect();
mMessageManager = nullptr; mMessageManager = nullptr;
@@ -1027,8 +1047,8 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
ppm->Disconnect(); ppm->Disconnect();
} }
// clear the child memory reporters // unregister the child memory reporter
ClearChildMemoryReporters(); UnregisterChildMemoryReporter();
// remove the global remote preferences observers // remove the global remote preferences observers
Preferences::RemoveObserver(this, ""); Preferences::RemoveObserver(this, "");
@@ -2141,28 +2161,16 @@ ContentParent::DeallocPMemoryReportRequestParent(PMemoryReportRequestParent* act
} }
void void
ContentParent::SetChildMemoryReporters(const InfallibleTArray<MemoryReport>& report) ContentParent::SetChildMemoryReports(const InfallibleTArray<MemoryReport>& childReports)
{ {
nsCOMPtr<nsIMemoryReporterManager> mgr = nsCOMPtr<nsIMemoryReporterManager> mgr =
do_GetService("@mozilla.org/memory-reporter-manager;1"); do_GetService("@mozilla.org/memory-reporter-manager;1");
for (int32_t i = 0; i < mMemoryReporters.Count(); i++)
mgr->UnregisterReporter(mMemoryReporters[i]);
for (uint32_t i = 0; i < report.Length(); i++) { if (mChildReporter)
nsCString process = report[i].process(); mgr->UnregisterReporter(mChildReporter);
nsCString path = report[i].path();
int32_t kind = report[i].kind();
int32_t units = report[i].units();
int64_t amount = report[i].amount();
nsCString desc = report[i].desc();
nsRefPtr<ChildMemoryReporter> r = mChildReporter = new ChildReporter(childReports);
new ChildMemoryReporter(process.get(), path.get(), kind, units, mgr->RegisterReporter(mChildReporter);
amount, desc.get());
mMemoryReporters.AppendObject(r);
mgr->RegisterReporter(r);
}
nsCOMPtr<nsIObserverService> obs = nsCOMPtr<nsIObserverService> obs =
do_GetService("@mozilla.org/observer-service;1"); do_GetService("@mozilla.org/observer-service;1");
@@ -2171,12 +2179,11 @@ ContentParent::SetChildMemoryReporters(const InfallibleTArray<MemoryReport>& rep
} }
void void
ContentParent::ClearChildMemoryReporters() ContentParent::UnregisterChildMemoryReporter()
{ {
nsCOMPtr<nsIMemoryReporterManager> mgr = nsCOMPtr<nsIMemoryReporterManager> mgr =
do_GetService("@mozilla.org/memory-reporter-manager;1"); do_GetService("@mozilla.org/memory-reporter-manager;1");
for (int32_t i = 0; i < mMemoryReporters.Count(); i++) mgr->UnregisterReporter(mChildReporter);
mgr->UnregisterReporter(mMemoryReporters[i]);
} }
PTestShellParent* PTestShellParent*

View File

@@ -143,8 +143,9 @@ public:
bool IsAlive(); bool IsAlive();
bool IsForApp(); bool IsForApp();
void SetChildMemoryReporters(const InfallibleTArray<MemoryReport>& report); void SetChildMemoryReports(const InfallibleTArray<MemoryReport>&
void ClearChildMemoryReporters(); childReports);
void UnregisterChildMemoryReporter();
GeckoChildProcessHost* Process() { GeckoChildProcessHost* Process() {
return mSubprocess; return mSubprocess;
@@ -446,11 +447,13 @@ private:
uint64_t mChildID; uint64_t mChildID;
int32_t mGeolocationWatchID; int32_t mGeolocationWatchID;
// This is a cache of all of the memory reporters // This is a reporter holding the reports from the child's last
// registered in the child process. To update this, one // "child-memory-reporter-update" notification. To update this, one can
// can broadcast the topic "child-memory-reporter-request" using // broadcast the topic "child-memory-reporter-request" using the
// the nsIObserverService. // nsIObserverService.
nsCOMArray<nsIMemoryReporter> mMemoryReporters; //
// Note that this assumes there is at most one child process at a time!
nsCOMPtr<nsIMemoryReporter> mChildReporter;
nsString mAppManifestURL; nsString mAppManifestURL;

View File

@@ -1766,7 +1766,7 @@ struct WorkerPrivate::TimeoutInfo
bool mCanceled; bool mCanceled;
}; };
class WorkerPrivate::MemoryReporter MOZ_FINAL : public nsIMemoryMultiReporter class WorkerPrivate::MemoryReporter MOZ_FINAL : public nsIMemoryReporter
{ {
friend class WorkerPrivate; friend class WorkerPrivate;
@@ -1807,7 +1807,7 @@ public:
} }
NS_IMETHOD NS_IMETHOD
CollectReports(nsIMemoryMultiReporterCallback* aCallback, CollectReports(nsIMemoryReporterCallback* aCallback,
nsISupports* aClosure) nsISupports* aClosure)
{ {
AssertIsOnMainThread(); AssertIsOnMainThread();
@@ -1883,7 +1883,7 @@ private:
} }
}; };
NS_IMPL_ISUPPORTS1(WorkerPrivate::MemoryReporter, nsIMemoryMultiReporter) NS_IMPL_ISUPPORTS1(WorkerPrivate::MemoryReporter, nsIMemoryReporter)
template <class Derived> template <class Derived>
WorkerPrivateParent<Derived>::WorkerPrivateParent( WorkerPrivateParent<Derived>::WorkerPrivateParent(
@@ -3093,7 +3093,7 @@ WorkerPrivate::EnableMemoryReporter()
// successfully registered the reporter. // successfully registered the reporter.
mMemoryReporter = new MemoryReporter(this); mMemoryReporter = new MemoryReporter(this);
if (NS_FAILED(NS_RegisterMemoryMultiReporter(mMemoryReporter))) { if (NS_FAILED(NS_RegisterMemoryReporter(mMemoryReporter))) {
NS_WARNING("Failed to register memory reporter!"); NS_WARNING("Failed to register memory reporter!");
// No need to lock here since a failed registration means our memory // No need to lock here since a failed registration means our memory
// reporter can't start running. Just clean up. // reporter can't start running. Just clean up.
@@ -3148,7 +3148,7 @@ WorkerPrivate::DisableMemoryReporter()
} }
// Finally unregister the memory reporter. // Finally unregister the memory reporter.
if (NS_FAILED(NS_UnregisterMemoryMultiReporter(memoryReporter))) { if (NS_FAILED(NS_UnregisterMemoryReporter(memoryReporter))) {
NS_WARNING("Failed to unregister memory reporter!"); NS_WARNING("Failed to unregister memory reporter!");
} }
} }

View File

@@ -34,7 +34,6 @@
class JSAutoStructuredCloneBuffer; class JSAutoStructuredCloneBuffer;
class nsIChannel; class nsIChannel;
class nsIDocument; class nsIDocument;
class nsIMemoryMultiReporter;
class nsIPrincipal; class nsIPrincipal;
class nsIScriptContext; class nsIScriptContext;
class nsIURI; class nsIURI;

View File

@@ -97,11 +97,11 @@ NS_IMPL_CYCLE_COLLECTION_3(mozHunspell,
mEncoder, mEncoder,
mDecoder) mDecoder)
class SpellCheckReporter MOZ_FINAL : public mozilla::MemoryReporterBase class SpellCheckReporter MOZ_FINAL : public mozilla::MemoryUniReporter
{ {
public: public:
SpellCheckReporter() SpellCheckReporter()
: MemoryReporterBase("explicit/spell-check", KIND_HEAP, UNITS_BYTES, : MemoryUniReporter("explicit/spell-check", KIND_HEAP, UNITS_BYTES,
"Memory used by the Hunspell spell checking engine's internal data structures.") "Memory used by the Hunspell spell checking engine's internal data structures.")
{ {
#ifdef DEBUG #ifdef DEBUG

View File

@@ -3394,12 +3394,12 @@ public:
#endif #endif
}; };
class GfxTexturesReporter MOZ_FINAL : public MemoryReporterBase class GfxTexturesReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
GfxTexturesReporter() GfxTexturesReporter()
: MemoryReporterBase("gfx-textures", KIND_OTHER, UNITS_BYTES, : MemoryUniReporter("gfx-textures", KIND_OTHER, UNITS_BYTES,
"Memory used for storing GL textures.") "Memory used for storing GL textures.")
{ {
#ifdef DEBUG #ifdef DEBUG
// There must be only one instance of this class, due to |sAmount| // There must be only one instance of this class, due to |sAmount|

View File

@@ -184,13 +184,13 @@ ContentTypeFromPixelFormat(android::PixelFormat aFormat)
return gfxASurface::ContentFromFormat(ImageFormatForPixelFormat(aFormat)); return gfxASurface::ContentFromFormat(ImageFormatForPixelFormat(aFormat));
} }
class GrallocReporter MOZ_FINAL : public MemoryReporterBase class GrallocReporter MOZ_FINAL : public MemoryUniReporter
{ {
friend class GrallocBufferActor; friend class GrallocBufferActor;
public: public:
GrallocReporter() GrallocReporter()
: MemoryReporterBase("gralloc", KIND_OTHER, UNITS_BYTES, : MemoryUniReporter("gralloc", KIND_OTHER, UNITS_BYTES,
"Special RAM that can be shared between processes and directly accessed by " "Special RAM that can be shared between processes and directly accessed by "
"both the CPU and GPU. Gralloc memory is usually a relatively precious " "both the CPU and GPU. Gralloc memory is usually a relatively precious "
"resource, with much less available than generic RAM. When it's exhausted, " "resource, with much less available than generic RAM. When it's exhausted, "

View File

@@ -598,7 +598,7 @@ PR_STATIC_ASSERT(uint32_t(CAIRO_SURFACE_TYPE_SKIA) ==
static int64_t gSurfaceMemoryUsed[gfxASurface::SurfaceTypeMax] = { 0 }; static int64_t gSurfaceMemoryUsed[gfxASurface::SurfaceTypeMax] = { 0 };
class SurfaceMemoryReporter MOZ_FINAL : class SurfaceMemoryReporter MOZ_FINAL :
public nsIMemoryMultiReporter public nsIMemoryReporter
{ {
public: public:
SurfaceMemoryReporter() SurfaceMemoryReporter()
@@ -612,7 +612,7 @@ public:
return NS_OK; return NS_OK;
} }
NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback *aCb, NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCb,
nsISupports *aClosure) nsISupports *aClosure)
{ {
size_t len = NS_ARRAY_LENGTH(sSurfaceMemoryReporterAttrs); size_t len = NS_ARRAY_LENGTH(sSurfaceMemoryReporterAttrs);
@@ -639,7 +639,7 @@ public:
} }
}; };
NS_IMPL_ISUPPORTS1(SurfaceMemoryReporter, nsIMemoryMultiReporter) NS_IMPL_ISUPPORTS1(SurfaceMemoryReporter, nsIMemoryReporter)
void void
gfxASurface::RecordMemoryUsedForSurfaceType(gfxASurface::gfxSurfaceType aType, gfxASurface::RecordMemoryUsedForSurfaceType(gfxASurface::gfxSurfaceType aType,
@@ -652,7 +652,7 @@ gfxASurface::RecordMemoryUsedForSurfaceType(gfxASurface::gfxSurfaceType aType,
static bool registered = false; static bool registered = false;
if (!registered) { if (!registered) {
NS_RegisterMemoryMultiReporter(new SurfaceMemoryReporter()); NS_RegisterMemoryReporter(new SurfaceMemoryReporter());
registered = true; registered = true;
} }

View File

@@ -30,12 +30,12 @@ using namespace mozilla::gfx;
static FT_Library gPlatformFTLibrary = nullptr; static FT_Library gPlatformFTLibrary = nullptr;
class FreetypeReporter MOZ_FINAL : public MemoryReporterBase class FreetypeReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
FreetypeReporter() FreetypeReporter()
: MemoryReporterBase("explicit/freetype", KIND_HEAP, UNITS_BYTES, : MemoryUniReporter("explicit/freetype", KIND_HEAP, UNITS_BYTES,
"Memory used by Freetype.") "Memory used by Freetype.")
{ {
#ifdef DEBUG #ifdef DEBUG
// There must be only one instance of this class, due to |sAmount| // There must be only one instance of this class, due to |sAmount|

View File

@@ -1252,7 +1252,7 @@ gfxFontFamily::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf,
* shaped-word caches to free up memory. * shaped-word caches to free up memory.
*/ */
NS_IMPL_ISUPPORTS1(gfxFontCache::MemoryReporter, nsIMemoryMultiReporter) NS_IMPL_ISUPPORTS1(gfxFontCache::MemoryReporter, nsIMemoryReporter)
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(FontCacheMallocSizeOf) NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(FontCacheMallocSizeOf)
@@ -1265,7 +1265,7 @@ gfxFontCache::MemoryReporter::GetName(nsACString &aName)
NS_IMETHODIMP NS_IMETHODIMP
gfxFontCache::MemoryReporter::CollectReports gfxFontCache::MemoryReporter::CollectReports
(nsIMemoryMultiReporterCallback* aCb, (nsIMemoryReporterCallback* aCb,
nsISupports* aClosure) nsISupports* aClosure)
{ {
FontCacheSizes sizes; FontCacheSizes sizes;
@@ -1324,7 +1324,7 @@ gfxFontCache::Init()
if (!gGlobalCache) { if (!gGlobalCache) {
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
NS_RegisterMemoryMultiReporter(new MemoryReporter); NS_RegisterMemoryReporter(new MemoryReporter);
return NS_OK; return NS_OK;
} }

View File

@@ -977,11 +977,11 @@ public:
protected: protected:
class MemoryReporter MOZ_FINAL class MemoryReporter MOZ_FINAL
: public nsIMemoryMultiReporter : public nsIMemoryReporter
{ {
public: public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_DECL_NSIMEMORYMULTIREPORTER NS_DECL_NSIMEMORYREPORTER
}; };
void DestroyFont(gfxFont *aFont); void DestroyFont(gfxFont *aFont);

View File

@@ -70,7 +70,7 @@ gfxFontListPrefObserver::Observe(nsISupports *aSubject,
return NS_OK; return NS_OK;
} }
NS_IMPL_ISUPPORTS1(gfxPlatformFontList::MemoryReporter, nsIMemoryMultiReporter) NS_IMPL_ISUPPORTS1(gfxPlatformFontList::MemoryReporter, nsIMemoryReporter)
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(FontListMallocSizeOf) NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(FontListMallocSizeOf)
@@ -83,7 +83,7 @@ gfxPlatformFontList::MemoryReporter::GetName(nsACString &aName)
NS_IMETHODIMP NS_IMETHODIMP
gfxPlatformFontList::MemoryReporter::CollectReports gfxPlatformFontList::MemoryReporter::CollectReports
(nsIMemoryMultiReporterCallback* aCb, (nsIMemoryReporterCallback* aCb,
nsISupports* aClosure) nsISupports* aClosure)
{ {
FontListSizes sizes; FontListSizes sizes;
@@ -148,7 +148,7 @@ gfxPlatformFontList::gfxPlatformFontList(bool aNeedFullnamePostscriptNames)
mSharedCmaps.Init(16); mSharedCmaps.Init(16);
NS_RegisterMemoryMultiReporter(new MemoryReporter); NS_RegisterMemoryReporter(new MemoryReporter);
} }
gfxPlatformFontList::~gfxPlatformFontList() gfxPlatformFontList::~gfxPlatformFontList()

View File

@@ -179,11 +179,11 @@ public:
protected: protected:
class MemoryReporter MOZ_FINAL class MemoryReporter MOZ_FINAL
: public nsIMemoryMultiReporter : public nsIMemoryReporter
{ {
public: public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_DECL_NSIMEMORYMULTIREPORTER NS_DECL_NSIMEMORYREPORTER
}; };
gfxPlatformFontList(bool aNeedFullnamePostscriptNames = true); gfxPlatformFontList(bool aNeedFullnamePostscriptNames = true);

View File

@@ -73,11 +73,11 @@ static const int kSupportedFeatureLevels[] =
{ D3D10_FEATURE_LEVEL_10_1, D3D10_FEATURE_LEVEL_10_0, { D3D10_FEATURE_LEVEL_10_1, D3D10_FEATURE_LEVEL_10_0,
D3D10_FEATURE_LEVEL_9_3 }; D3D10_FEATURE_LEVEL_9_3 };
class GfxD2DSurfaceCacheReporter MOZ_FINAL : public MemoryReporterBase class GfxD2DSurfaceCacheReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
GfxD2DSurfaceCacheReporter() GfxD2DSurfaceCacheReporter()
: MemoryReporterBase("gfx-d2d-surface-cache", KIND_OTHER, UNITS_BYTES, : MemoryUniReporter("gfx-d2d-surface-cache", KIND_OTHER, UNITS_BYTES,
"Memory used by the Direct2D internal surface cache.") "Memory used by the Direct2D internal surface cache.")
{} {}
private: private:
@@ -110,11 +110,11 @@ bool OncePreferenceDirect2DForceEnabled()
} // anonymous namespace } // anonymous namespace
class GfxD2DSurfaceVramReporter MOZ_FINAL : public MemoryReporterBase class GfxD2DSurfaceVramReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
GfxD2DSurfaceVramReporter() GfxD2DSurfaceVramReporter()
: MemoryReporterBase("gfx-d2d-surface-vram", KIND_OTHER, UNITS_BYTES, : MemoryUniReporter("gfx-d2d-surface-vram", KIND_OTHER, UNITS_BYTES,
"Video memory used by D2D surfaces.") "Video memory used by D2D surfaces.")
{} {}
private: private:
@@ -127,11 +127,11 @@ private:
#endif #endif
class GfxD2DVramDrawTargetReporter MOZ_FINAL : public MemoryReporterBase class GfxD2DVramDrawTargetReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
GfxD2DVramDrawTargetReporter() GfxD2DVramDrawTargetReporter()
: MemoryReporterBase("gfx-d2d-vram-draw-target", KIND_OTHER, UNITS_BYTES, : MemoryUniReporter("gfx-d2d-vram-draw-target", KIND_OTHER, UNITS_BYTES,
"Video memory used by D2D DrawTargets.") "Video memory used by D2D DrawTargets.")
{} {}
private: private:
@@ -141,11 +141,11 @@ private:
} }
}; };
class GfxD2DVramSourceSurfaceReporter MOZ_FINAL : public MemoryReporterBase class GfxD2DVramSourceSurfaceReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
GfxD2DVramSourceSurfaceReporter() GfxD2DVramSourceSurfaceReporter()
: MemoryReporterBase("gfx-d2d-vram-source-surface", : MemoryUniReporter("gfx-d2d-vram-source-surface",
KIND_OTHER, UNITS_BYTES, KIND_OTHER, UNITS_BYTES,
"Video memory used by D2D SourceSurfaces.") "Video memory used by D2D SourceSurfaces.")
{} {}
@@ -206,7 +206,7 @@ typedef HRESULT (WINAPI*D3D11CreateDeviceFunc)(
ID3D11DeviceContext *ppImmediateContext ID3D11DeviceContext *ppImmediateContext
); );
class GPUAdapterMultiReporter : public nsIMemoryMultiReporter { class GPUAdapterReporter : public nsIMemoryReporter {
// Callers must Release the DXGIAdapter after use or risk mem-leak // Callers must Release the DXGIAdapter after use or risk mem-leak
static bool GetDXGIAdapter(IDXGIAdapter **DXGIAdapter) static bool GetDXGIAdapter(IDXGIAdapter **DXGIAdapter)
@@ -228,7 +228,7 @@ class GPUAdapterMultiReporter : public nsIMemoryMultiReporter {
public: public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
// nsIMemoryMultiReporter abstract method implementation // nsIMemoryReporter abstract method implementation
NS_IMETHOD NS_IMETHOD
GetName(nsACString &aName) GetName(nsACString &aName)
{ {
@@ -236,9 +236,9 @@ public:
return NS_OK; return NS_OK;
} }
// nsIMemoryMultiReporter abstract method implementation // nsIMemoryReporter abstract method implementation
NS_IMETHOD NS_IMETHOD
CollectReports(nsIMemoryMultiReporterCallback* aCb, CollectReports(nsIMemoryReporterCallback* aCb,
nsISupports* aClosure) nsISupports* aClosure)
{ {
int32_t winVers, buildNum; int32_t winVers, buildNum;
@@ -347,7 +347,7 @@ public:
return NS_OK; return NS_OK;
} }
}; };
NS_IMPL_ISUPPORTS1(GPUAdapterMultiReporter, nsIMemoryMultiReporter) NS_IMPL_ISUPPORTS1(GPUAdapterReporter, nsIMemoryReporter)
static __inline void static __inline void
BuildKeyNameFromFontName(nsAString &aName) BuildKeyNameFromFontName(nsAString &aName)
@@ -385,16 +385,16 @@ gfxWindowsPlatform::gfxWindowsPlatform()
UpdateRenderMode(); UpdateRenderMode();
mGPUAdapterMultiReporter = new GPUAdapterMultiReporter(); mGPUAdapterReporter = new GPUAdapterReporter();
NS_RegisterMemoryMultiReporter(mGPUAdapterMultiReporter); NS_RegisterMemoryReporter(mGPUAdapterReporter);
} }
gfxWindowsPlatform::~gfxWindowsPlatform() gfxWindowsPlatform::~gfxWindowsPlatform()
{ {
NS_UnregisterMemoryMultiReporter(mGPUAdapterMultiReporter); NS_UnregisterMemoryReporter(mGPUAdapterReporter);
mDeviceManager = nullptr; mDeviceManager = nullptr;
::ReleaseDC(nullptr, mScreenDC); ::ReleaseDC(nullptr, mScreenDC);
// not calling FT_Done_FreeType because cairo may still hold references to // not calling FT_Done_FreeType because cairo may still hold references to
// these FT_Faces. See bug 458169. // these FT_Faces. See bug 458169.

View File

@@ -52,7 +52,7 @@ class IDirect3DDevice9;
class ID3D11Device; class ID3D11Device;
class IDXGIAdapter1; class IDXGIAdapter1;
class nsIMemoryMultiReporter; class nsIMemoryReporter;
// Utility to get a Windows HDC from a thebes context, // Utility to get a Windows HDC from a thebes context,
// used by both GDI and Uniscribe font shapers // used by both GDI and Uniscribe font shapers
@@ -315,7 +315,7 @@ private:
// TODO: unify this with mPrefFonts (NB: holds families, not fonts) in gfxPlatformFontList // TODO: unify this with mPrefFonts (NB: holds families, not fonts) in gfxPlatformFontList
nsDataHashtable<nsCStringHashKey, nsTArray<nsRefPtr<gfxFontEntry> > > mPrefFonts; nsDataHashtable<nsCStringHashKey, nsTArray<nsRefPtr<gfxFontEntry> > > mPrefFonts;
nsIMemoryMultiReporter* mGPUAdapterMultiReporter; nsIMemoryReporter* mGPUAdapterReporter;
}; };
#endif /* GFX_WINDOWS_PLATFORM_H */ #endif /* GFX_WINDOWS_PLATFORM_H */

View File

@@ -61,7 +61,7 @@ using namespace mozilla::image;
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(ImagesMallocSizeOf) NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(ImagesMallocSizeOf)
class imgMemoryReporter MOZ_FINAL : class imgMemoryReporter MOZ_FINAL :
public nsIMemoryMultiReporter public nsIMemoryReporter
{ {
public: public:
imgMemoryReporter() imgMemoryReporter()
@@ -76,7 +76,7 @@ public:
return NS_OK; return NS_OK;
} }
NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback *callback, NS_IMETHOD CollectReports(nsIMemoryReporterCallback *callback,
nsISupports *closure) nsISupports *closure)
{ {
AllSizes chrome; AllSizes chrome;
@@ -233,15 +233,15 @@ private:
} }
}; };
NS_IMPL_ISUPPORTS1(imgMemoryReporter, nsIMemoryMultiReporter) NS_IMPL_ISUPPORTS1(imgMemoryReporter, nsIMemoryReporter)
// This is used by telemetry. // This is used by telemetry.
class ImagesContentUsedUncompressedReporter MOZ_FINAL class ImagesContentUsedUncompressedReporter MOZ_FINAL
: public MemoryReporterBase : public MemoryUniReporter
{ {
public: public:
ImagesContentUsedUncompressedReporter() ImagesContentUsedUncompressedReporter()
: MemoryReporterBase("images-content-used-uncompressed", : MemoryUniReporter("images-content-used-uncompressed",
KIND_OTHER, UNITS_BYTES, KIND_OTHER, UNITS_BYTES,
"This is the sum of the 'explicit/images/content/used/uncompressed-heap' " "This is the sum of the 'explicit/images/content/used/uncompressed-heap' "
"and 'explicit/images/content/used/uncompressed-nonheap' numbers. However, " "and 'explicit/images/content/used/uncompressed-nonheap' numbers. However, "
@@ -850,7 +850,7 @@ void imgLoader::GlobalInit()
sCacheMaxSize = 5 * 1024 * 1024; sCacheMaxSize = 5 * 1024 * 1024;
sMemReporter = new imgMemoryReporter(); sMemReporter = new imgMemoryReporter();
NS_RegisterMemoryMultiReporter(sMemReporter); NS_RegisterMemoryReporter(sMemReporter);
NS_RegisterMemoryReporter(new ImagesContentUsedUncompressedReporter()); NS_RegisterMemoryReporter(new ImagesContentUsedUncompressedReporter());
} }

View File

@@ -25,14 +25,18 @@ window.onload = function() {
var mgr = SpecialPowers.Cc["@mozilla.org/memory-reporter-manager;1"] var mgr = SpecialPowers.Cc["@mozilla.org/memory-reporter-manager;1"]
.getService(SpecialPowers.Ci.nsIMemoryReporterManager); .getService(SpecialPowers.Ci.nsIMemoryReporterManager);
var e = mgr.enumerateReporters(); var amount = 0;
var memoryCounter = 0; var handleReport = function(aProcess, aPath, aKind, aUnits, aAmount, aDesc) {
while (e.hasMoreElements()) { amount += aAmount;
var mr =
e.getNext().QueryInterface(SpecialPowers.Ci.nsIMemoryReporter);
memoryCounter += mr.amount;
} }
ok(memoryCounter > 0, "we should be using a nonzero amount of memory");
var e = mgr.enumerateReporters();
while (e.hasMoreElements()) {
var mr = e.getNext().QueryInterface(SpecialPowers.Ci.nsIMemoryReporter);
mr.collectReports(handleReport, null);
}
ok(amount > 0, "we should be using a nonzero amount of memory");
ok(true, "yay, didn't crash!"); ok(true, "yay, didn't crash!");
SimpleTest.finish(); SimpleTest.finish();

View File

@@ -17,11 +17,11 @@ namespace ipc {
static Atomic<size_t> gShmemAllocated; static Atomic<size_t> gShmemAllocated;
static Atomic<size_t> gShmemMapped; static Atomic<size_t> gShmemMapped;
class ShmemAllocatedReporter MOZ_FINAL : public MemoryReporterBase class ShmemAllocatedReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
ShmemAllocatedReporter() ShmemAllocatedReporter()
: MemoryReporterBase("shmem-allocated", KIND_OTHER, UNITS_BYTES, : MemoryUniReporter("shmem-allocated", KIND_OTHER, UNITS_BYTES,
"Memory shared with other processes that is accessible (but not necessarily " "Memory shared with other processes that is accessible (but not necessarily "
"mapped).") "mapped).")
{} {}
@@ -29,11 +29,11 @@ private:
int64_t Amount() MOZ_OVERRIDE { return gShmemAllocated; } int64_t Amount() MOZ_OVERRIDE { return gShmemAllocated; }
}; };
class ShmemMappedReporter MOZ_FINAL : public MemoryReporterBase class ShmemMappedReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
ShmemMappedReporter() ShmemMappedReporter()
: MemoryReporterBase("shmem-mapped", KIND_OTHER, UNITS_BYTES, : MemoryUniReporter("shmem-mapped", KIND_OTHER, UNITS_BYTES,
"Memory shared with other processes that is mapped into the address space.") "Memory shared with other processes that is mapped into the address space.")
{} {}
private: private:

View File

@@ -9,22 +9,22 @@
#define XPCJSMemoryReporter_h #define XPCJSMemoryReporter_h
class nsISupports; class nsISupports;
class nsIMemoryMultiReporterCallback; class nsIMemoryReporterCallback;
namespace xpc { namespace xpc {
// The key is the window ID. // The key is the window ID.
typedef nsDataHashtable<nsUint64HashKey, nsCString> WindowPaths; typedef nsDataHashtable<nsUint64HashKey, nsCString> WindowPaths;
// This is very nearly an instance of nsIMemoryMultiReporter, but it's not, // This is very nearly an instance of nsIMemoryReporter, but it's not,
// because it's invoked by nsWindowMemoryReporter in order to get |windowPaths| // because it's invoked by nsWindowMemoryReporter in order to get |windowPaths|
// in CollectReports. // in CollectReports.
class JSMemoryMultiReporter class JSReporter
{ {
public: public:
static nsresult CollectReports(WindowPaths *windowPaths, static nsresult CollectReports(WindowPaths *windowPaths,
WindowPaths *topWindowPaths, WindowPaths *topWindowPaths,
nsIMemoryMultiReporterCallback *cb, nsIMemoryReporterCallback *cb,
nsISupports *closure); nsISupports *closure);
}; };

View File

@@ -1560,13 +1560,13 @@ GetCompartmentName(JSCompartment *c, nsCString &name, bool replaceSlashes)
} }
} }
// Telemetry relies on this being a single reporter (rather than part of the // Telemetry relies on this being a uni-reporter (rather than part of the "js"
// "js" multi-reporter). // reporter).
class JSGCHeapReporter MOZ_FINAL : public MemoryReporterBase class JSGCHeapReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
JSGCHeapReporter() JSGCHeapReporter()
: MemoryReporterBase("js-gc-heap", KIND_OTHER, UNITS_BYTES, : MemoryUniReporter("js-gc-heap", KIND_OTHER, UNITS_BYTES,
"Memory used by the garbage-collected JavaScript heap.") "Memory used by the garbage-collected JavaScript heap.")
{} {}
private: private:
@@ -1578,19 +1578,17 @@ private:
} }
}; };
// Nb: js-compartments/system + js-compartments/user could be // Nb: js-compartments/system + js-compartments/user could be different to the
// different to the number of compartments reported by // number of compartments reported by JSReporter if a garbage collection
// JSMemoryMultiReporter if a garbage collection occurred // occurred between them being consulted. We could move these reporters into
// between them being consulted. We could move these reporters into // JSReporter to avoid that problem, but then we couldn't easily report them
// XPConnectJSCompartmentCount to avoid that problem, but then we couldn't // via telemetry, so we live with the small risk of inconsistencies.
// easily report them via telemetry, so we live with the small risk of
// inconsistencies.
class JSCompartmentsSystemReporter MOZ_FINAL : public MemoryReporterBase class JSCompartmentsSystemReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
JSCompartmentsSystemReporter() JSCompartmentsSystemReporter()
: MemoryReporterBase("js-compartments/system", KIND_OTHER, UNITS_COUNT, : MemoryUniReporter("js-compartments/system", KIND_OTHER, UNITS_COUNT,
"The number of JavaScript compartments for system code. The sum of this and " "The number of JavaScript compartments for system code. The sum of this and "
"'js-compartments/user' might not match the number of compartments listed " "'js-compartments/user' might not match the number of compartments listed "
"in the 'explicit' tree if a garbage collection occurs at an inopportune " "in the 'explicit' tree if a garbage collection occurs at an inopportune "
@@ -1604,11 +1602,11 @@ private:
} }
}; };
class JSCompartmentsUserReporter MOZ_FINAL : public MemoryReporterBase class JSCompartmentsUserReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
JSCompartmentsUserReporter() JSCompartmentsUserReporter()
: MemoryReporterBase("js-compartments/user", KIND_OTHER, UNITS_COUNT, : MemoryUniReporter("js-compartments/user", KIND_OTHER, UNITS_COUNT,
"The number of JavaScript compartments for user code. The sum of this and " "The number of JavaScript compartments for user code. The sum of this and "
"'js-compartments/system' might not match the number of compartments listed " "'js-compartments/system' might not match the number of compartments listed "
"under 'js' if a garbage collection occurs at an inopportune time, but such " "under 'js' if a garbage collection occurs at an inopportune time, but such "
@@ -1623,11 +1621,11 @@ private:
}; };
// This is also a single reporter so it can be used by telemetry. // This is also a single reporter so it can be used by telemetry.
class JSMainRuntimeTemporaryPeakReporter MOZ_FINAL : public MemoryReporterBase class JSMainRuntimeTemporaryPeakReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
JSMainRuntimeTemporaryPeakReporter() JSMainRuntimeTemporaryPeakReporter()
: MemoryReporterBase("js-main-runtime-temporary-peak", : MemoryUniReporter("js-main-runtime-temporary-peak",
KIND_OTHER, UNITS_BYTES, KIND_OTHER, UNITS_BYTES,
"The peak size of the transient storage in the main JSRuntime (the current " "The peak size of the transient storage in the main JSRuntime (the current "
"size of which is reported as 'explicit/js-non-window/runtime/temporary').") "size of which is reported as 'explicit/js-non-window/runtime/temporary').")
@@ -1758,7 +1756,7 @@ namespace xpc {
static nsresult static nsresult
ReportZoneStats(const JS::ZoneStats &zStats, ReportZoneStats(const JS::ZoneStats &zStats,
const xpc::ZoneStatsExtras &extras, const xpc::ZoneStatsExtras &extras,
nsIMemoryMultiReporterCallback *cb, nsIMemoryReporterCallback *cb,
nsISupports *closure, size_t *gcTotalOut = NULL) nsISupports *closure, size_t *gcTotalOut = NULL)
{ {
const nsAutoCString& pathPrefix = extras.pathPrefix; const nsAutoCString& pathPrefix = extras.pathPrefix;
@@ -1942,7 +1940,7 @@ static nsresult
ReportCompartmentStats(const JS::CompartmentStats &cStats, ReportCompartmentStats(const JS::CompartmentStats &cStats,
const xpc::CompartmentStatsExtras &extras, const xpc::CompartmentStatsExtras &extras,
amIAddonManager *addonManager, amIAddonManager *addonManager,
nsIMemoryMultiReporterCallback *cb, nsIMemoryReporterCallback *cb,
nsISupports *closure, size_t *gcTotalOut = NULL) nsISupports *closure, size_t *gcTotalOut = NULL)
{ {
static const nsDependentCString addonPrefix("explicit/add-ons/"); static const nsDependentCString addonPrefix("explicit/add-ons/");
@@ -2084,8 +2082,8 @@ ReportCompartmentStats(const JS::CompartmentStats &cStats,
"Memory allocated on the malloc heap for data belonging to ctypes objects."); "Memory allocated on the malloc heap for data belonging to ctypes objects.");
// Note that we use cDOMPathPrefix here. This is because we measure orphan // Note that we use cDOMPathPrefix here. This is because we measure orphan
// DOM nodes in the JS multi-reporter, but we want to report them in a // DOM nodes in the JS reporter, but we want to report them in a "dom"
// "dom" sub-tree rather than a "js" sub-tree. // sub-tree rather than a "js" sub-tree.
ZCREPORT_BYTES(cDOMPathPrefix + NS_LITERAL_CSTRING("orphan-nodes"), ZCREPORT_BYTES(cDOMPathPrefix + NS_LITERAL_CSTRING("orphan-nodes"),
cStats.objectsExtra.private_, cStats.objectsExtra.private_,
"Memory used by orphan DOM nodes that are only reachable " "Memory used by orphan DOM nodes that are only reachable "
@@ -2207,7 +2205,7 @@ static nsresult
ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats, ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats,
const nsACString &rtPath, const nsACString &rtPath,
amIAddonManager* addonManager, amIAddonManager* addonManager,
nsIMemoryMultiReporterCallback *cb, nsIMemoryReporterCallback *cb,
nsISupports *closure, size_t *rtTotalOut) nsISupports *closure, size_t *rtTotalOut)
{ {
nsresult rv; nsresult rv;
@@ -2349,7 +2347,7 @@ ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats,
nsresult nsresult
ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats, ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats,
const nsACString &rtPath, const nsACString &rtPath,
nsIMemoryMultiReporterCallback *cb, nsIMemoryReporterCallback *cb,
nsISupports *closure, size_t *rtTotalOut) nsISupports *closure, size_t *rtTotalOut)
{ {
nsCOMPtr<amIAddonManager> am = nsCOMPtr<amIAddonManager> am =
@@ -2361,7 +2359,7 @@ ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats,
} // namespace xpc } // namespace xpc
class JSCompartmentsMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter class JSCompartmentsReporter MOZ_FINAL : public nsIMemoryReporter
{ {
public: public:
NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_THREADSAFE_ISUPPORTS
@@ -2385,7 +2383,7 @@ class JSCompartmentsMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter
paths->append(path); paths->append(path);
} }
NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback *cb, NS_IMETHOD CollectReports(nsIMemoryReporterCallback *cb,
nsISupports *closure) nsISupports *closure)
{ {
// First we collect the compartment paths. Then we report them. Doing // First we collect the compartment paths. Then we report them. Doing
@@ -2407,9 +2405,7 @@ class JSCompartmentsMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter
} }
}; };
NS_IMPL_ISUPPORTS1(JSCompartmentsMultiReporter NS_IMPL_ISUPPORTS1(JSCompartmentsReporter, nsIMemoryReporter)
, nsIMemoryMultiReporter
)
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(OrphanMallocSizeOf) NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(OrphanMallocSizeOf)
@@ -2567,9 +2563,9 @@ class XPCJSRuntimeStats : public JS::RuntimeStats
// "<something>compartment(<cname>)/". // "<something>compartment(<cname>)/".
// //
// extras->domPathPrefix is used for DOM orphan nodes, which are // extras->domPathPrefix is used for DOM orphan nodes, which are
// counted by the JS multi-reporter but reported as part of the // counted by the JS reporter but reported as part of the DOM
// DOM measurements. At this point it has the form "<something>/dom/" // measurements. At this point it has the form "<something>/dom/" if
// if this compartment belongs to an nsGlobalWindow, and // this compartment belongs to an nsGlobalWindow, and
// "explicit/dom/<something>?!/" otherwise (in which case it shouldn't // "explicit/dom/<something>?!/" otherwise (in which case it shouldn't
// be used, because non-nsGlobalWindow compartments shouldn't have // be used, because non-nsGlobalWindow compartments shouldn't have
// orphan DOM nodes). // orphan DOM nodes).
@@ -2579,10 +2575,10 @@ class XPCJSRuntimeStats : public JS::RuntimeStats
}; };
nsresult nsresult
JSMemoryMultiReporter::CollectReports(WindowPaths *windowPaths, JSReporter::CollectReports(WindowPaths *windowPaths,
WindowPaths *topWindowPaths, WindowPaths *topWindowPaths,
nsIMemoryMultiReporterCallback *cb, nsIMemoryReporterCallback *cb,
nsISupports *closure) nsISupports *closure)
{ {
XPCJSRuntime *xpcrt = nsXPConnect::GetRuntimeInstance(); XPCJSRuntime *xpcrt = nsXPConnect::GetRuntimeInstance();
@@ -3053,7 +3049,7 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
NS_RegisterMemoryReporter(new JSCompartmentsSystemReporter()); NS_RegisterMemoryReporter(new JSCompartmentsSystemReporter());
NS_RegisterMemoryReporter(new JSCompartmentsUserReporter()); NS_RegisterMemoryReporter(new JSCompartmentsUserReporter());
NS_RegisterMemoryReporter(new JSMainRuntimeTemporaryPeakReporter()); NS_RegisterMemoryReporter(new JSMainRuntimeTemporaryPeakReporter());
NS_RegisterMemoryMultiReporter(new JSCompartmentsMultiReporter); NS_RegisterMemoryReporter(new JSCompartmentsReporter);
// Install a JavaScript 'debugger' keyword handler in debug builds only // Install a JavaScript 'debugger' keyword handler in debug builds only
#ifdef DEBUG #ifdef DEBUG

View File

@@ -180,7 +180,7 @@ xpc_UnmarkSkippableJSHolders();
NS_EXPORT_(void) NS_EXPORT_(void)
xpc_ActivateDebugMode(); xpc_ActivateDebugMode();
class nsIMemoryMultiReporterCallback; class nsIMemoryReporterCallback;
// readable string conversions, static methods and members only // readable string conversions, static methods and members only
class XPCStringConvert class XPCStringConvert
@@ -376,7 +376,7 @@ private:
nsresult nsresult
ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats, ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats,
const nsACString &rtPath, const nsACString &rtPath,
nsIMemoryMultiReporterCallback *cb, nsIMemoryReporterCallback *cb,
nsISupports *closure, size_t *rtTotal = NULL); nsISupports *closure, size_t *rtTotal = NULL);
/** /**

View File

@@ -26,11 +26,11 @@
using namespace mozilla; using namespace mozilla;
class LayoutStyleSheetServiceReporter MOZ_FINAL class LayoutStyleSheetServiceReporter MOZ_FINAL
: public mozilla::MemoryReporterBase : public mozilla::MemoryUniReporter
{ {
public: public:
LayoutStyleSheetServiceReporter() LayoutStyleSheetServiceReporter()
: MemoryReporterBase("explicit/layout/style-sheet-service", : MemoryUniReporter("explicit/layout/style-sheet-service",
KIND_HEAP, UNITS_BYTES, KIND_HEAP, UNITS_BYTES,
"Memory used for style sheets held by the style sheet service.") "Memory used for style sheets held by the style sheet service.")
{} {}

View File

@@ -18,11 +18,11 @@
#include "nsCSSStyleSheet.h" #include "nsCSSStyleSheet.h"
class LayoutStyleSheetCacheReporter MOZ_FINAL class LayoutStyleSheetCacheReporter MOZ_FINAL
: public mozilla::MemoryReporterBase : public mozilla::MemoryUniReporter
{ {
public: public:
LayoutStyleSheetCacheReporter() LayoutStyleSheetCacheReporter()
: MemoryReporterBase("explicit/layout/style-sheet-cache", : MemoryUniReporter("explicit/layout/style-sheet-cache",
KIND_HEAP, UNITS_BYTES, KIND_HEAP, UNITS_BYTES,
"Memory used for some built-in style sheets.") "Memory used for some built-in style sheets.")
{} {}

View File

@@ -203,11 +203,11 @@ Preferences::SizeOfIncludingThisAndOtherStuff(mozilla::MallocSizeOf aMallocSizeO
return n; return n;
} }
class PreferencesReporter MOZ_FINAL : public MemoryReporterBase class PreferencesReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
PreferencesReporter() PreferencesReporter()
: MemoryReporterBase("explicit/preferences", KIND_HEAP, UNITS_BYTES, : MemoryUniReporter("explicit/preferences", KIND_HEAP, UNITS_BYTES,
"Memory used by the preferences system.") "Memory used by the preferences system.")
{} {}
private: private:

View File

@@ -370,11 +370,11 @@ nsDiskCache::Truncate(PRFileDesc * fd, uint32_t newEOF)
* nsDiskCacheDevice * nsDiskCacheDevice
*****************************************************************************/ *****************************************************************************/
class NetworkDiskCacheReporter MOZ_FINAL : public MemoryReporterBase class NetworkDiskCacheReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
NetworkDiskCacheReporter(nsDiskCacheDevice* aDevice) NetworkDiskCacheReporter(nsDiskCacheDevice* aDevice)
: MemoryReporterBase( : MemoryUniReporter(
"explicit/network/disk-cache", "explicit/network/disk-cache",
KIND_HEAP, KIND_HEAP,
UNITS_BYTES, UNITS_BYTES,

View File

@@ -29,11 +29,11 @@
const char *gMemoryDeviceID = "memory"; const char *gMemoryDeviceID = "memory";
class NetworkMemoryCacheReporter MOZ_FINAL : class NetworkMemoryCacheReporter MOZ_FINAL :
public mozilla::MemoryReporterBase public mozilla::MemoryUniReporter
{ {
public: public:
NetworkMemoryCacheReporter(nsMemoryCacheDevice* aDevice) NetworkMemoryCacheReporter(nsMemoryCacheDevice* aDevice)
: MemoryReporterBase( : MemoryUniReporter(
"explicit/network/memory-cache", "explicit/network/memory-cache",
KIND_HEAP, KIND_HEAP,
UNITS_BYTES, UNITS_BYTES,

View File

@@ -61,11 +61,11 @@ nsDomainEntry::FuncForStaticAsserts(void)
static nsEffectiveTLDService *gService = nullptr; static nsEffectiveTLDService *gService = nullptr;
class EffectiveTLDServiceReporter MOZ_FINAL : public MemoryReporterBase class EffectiveTLDServiceReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
EffectiveTLDServiceReporter() EffectiveTLDServiceReporter()
: MemoryReporterBase("explicit/xpcom/effective-TLD-service", : MemoryUniReporter("explicit/xpcom/effective-TLD-service",
KIND_HEAP, UNITS_BYTES, KIND_HEAP, UNITS_BYTES,
"Memory used by the effective TLD service.") "Memory used by the effective TLD service.")
{} {}

View File

@@ -53,11 +53,11 @@
namespace mozilla { namespace mozilla {
namespace scache { namespace scache {
class StartupCacheMappingReporter MOZ_FINAL : public MemoryReporterBase class StartupCacheMappingReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
StartupCacheMappingReporter() StartupCacheMappingReporter()
: MemoryReporterBase("explicit/startup-cache/mapping", : MemoryUniReporter("explicit/startup-cache/mapping",
KIND_NONHEAP, UNITS_BYTES, KIND_NONHEAP, UNITS_BYTES,
"Memory used to hold the mapping of the startup cache from file. This memory " "Memory used to hold the mapping of the startup cache from file. This memory "
"is likely to be swapped out shortly after start-up.") "is likely to be swapped out shortly after start-up.")
@@ -71,11 +71,11 @@ private:
} }
}; };
class StartupCacheDataReporter MOZ_FINAL : public MemoryReporterBase class StartupCacheDataReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
StartupCacheDataReporter() StartupCacheDataReporter()
: MemoryReporterBase("explicit/startup-cache/data", KIND_HEAP, UNITS_BYTES, : MemoryUniReporter("explicit/startup-cache/data", KIND_HEAP, UNITS_BYTES,
"Memory used by the startup cache for things other than the file mapping.") "Memory used by the startup cache for things other than the file mapping.")
{} {}
private: private:

View File

@@ -57,18 +57,18 @@ namespace storage {
// the multi-reporter provides reports that add up to the total. But it's // the multi-reporter provides reports that add up to the total. But it's
// useful to have the total in the "Other Measurements" list in about:memory, // useful to have the total in the "Other Measurements" list in about:memory,
// and more importantly, we also gather the total via telemetry. // and more importantly, we also gather the total via telemetry.
class StorageSQLiteReporter MOZ_FINAL : public MemoryReporterBase class StorageSQLiteUniReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
StorageSQLiteReporter() StorageSQLiteUniReporter()
: MemoryReporterBase("storage-sqlite", KIND_OTHER, UNITS_BYTES, : MemoryUniReporter("storage-sqlite", KIND_OTHER, UNITS_BYTES,
"Memory used by SQLite.") "Memory used by SQLite.")
{} {}
private: private:
int64_t Amount() MOZ_OVERRIDE { return ::sqlite3_memory_used(); } int64_t Amount() MOZ_OVERRIDE { return ::sqlite3_memory_used(); }
}; };
class StorageSQLiteMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter class StorageSQLiteMultiReporter MOZ_FINAL : public nsIMemoryReporter
{ {
private: private:
Service *mService; // a weakref because Service contains a strongref to this Service *mService; // a weakref because Service contains a strongref to this
@@ -97,7 +97,7 @@ public:
NS_IMETHOD GetName(nsACString &aName) NS_IMETHOD GetName(nsACString &aName)
{ {
aName.AssignLiteral("storage-sqlite"); aName.AssignLiteral("storage-sqlite-multi");
return NS_OK; return NS_OK;
} }
@@ -107,7 +107,7 @@ public:
// main thread! But at the time of writing this function is only called when // main thread! But at the time of writing this function is only called when
// about:memory is loaded (not, for example, when telemetry pings occur) and // about:memory is loaded (not, for example, when telemetry pings occur) and
// any delays in that case aren't so bad. // any delays in that case aren't so bad.
NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback *aCb, NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCb,
nsISupports *aClosure) nsISupports *aClosure)
{ {
nsresult rv; nsresult rv;
@@ -164,8 +164,7 @@ public:
private: private:
/** /**
* Passes a single SQLite memory statistic to a memory multi-reporter * Passes a single SQLite memory statistic to a memory reporter callback.
* callback.
* *
* @param aCallback * @param aCallback
* The callback. * The callback.
@@ -185,7 +184,7 @@ private:
* @param aTotal * @param aTotal
* The accumulator for the measurement. * The accumulator for the measurement.
*/ */
nsresult reportConn(nsIMemoryMultiReporterCallback *aCb, nsresult reportConn(nsIMemoryReporterCallback *aCb,
nsISupports *aClosure, nsISupports *aClosure,
sqlite3 *aConn, sqlite3 *aConn,
const nsACString &aPathHead, const nsACString &aPathHead,
@@ -216,7 +215,7 @@ private:
NS_IMPL_ISUPPORTS1( NS_IMPL_ISUPPORTS1(
StorageSQLiteMultiReporter, StorageSQLiteMultiReporter,
nsIMemoryMultiReporter nsIMemoryReporter
) )
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -308,8 +307,8 @@ Service::Service()
Service::~Service() Service::~Service()
{ {
(void)::NS_UnregisterMemoryReporter(mStorageSQLiteReporter); (void)::NS_UnregisterMemoryReporter(mStorageSQLiteUniReporter);
(void)::NS_UnregisterMemoryMultiReporter(mStorageSQLiteMultiReporter); (void)::NS_UnregisterMemoryReporter(mStorageSQLiteMultiReporter);
int rc = sqlite3_vfs_unregister(mSqliteVFS); int rc = sqlite3_vfs_unregister(mSqliteVFS);
if (rc != SQLITE_OK) if (rc != SQLITE_OK)
@@ -541,10 +540,10 @@ Service::initialize()
// Create and register our SQLite memory reporters. Registration can only // Create and register our SQLite memory reporters. Registration can only
// happen on the main thread (otherwise you'll get cryptic crashes). // happen on the main thread (otherwise you'll get cryptic crashes).
mStorageSQLiteReporter = new StorageSQLiteReporter(); mStorageSQLiteUniReporter = new StorageSQLiteUniReporter();
mStorageSQLiteMultiReporter = new StorageSQLiteMultiReporter(this); mStorageSQLiteMultiReporter = new StorageSQLiteMultiReporter(this);
(void)::NS_RegisterMemoryReporter(mStorageSQLiteReporter); (void)::NS_RegisterMemoryReporter(mStorageSQLiteUniReporter);
(void)::NS_RegisterMemoryMultiReporter(mStorageSQLiteMultiReporter); (void)::NS_RegisterMemoryReporter(mStorageSQLiteMultiReporter);
return NS_OK; return NS_OK;
} }

View File

@@ -17,7 +17,6 @@
#include "mozIStorageService.h" #include "mozIStorageService.h"
class nsIMemoryReporter; class nsIMemoryReporter;
class nsIMemoryMultiReporter;
class nsIXPConnect; class nsIXPConnect;
struct sqlite3_vfs; struct sqlite3_vfs;
@@ -173,8 +172,8 @@ private:
nsCOMPtr<nsIFile> mProfileStorageFile; nsCOMPtr<nsIFile> mProfileStorageFile;
nsCOMPtr<nsIMemoryReporter> mStorageSQLiteReporter; nsCOMPtr<nsIMemoryReporter> mStorageSQLiteUniReporter;
nsCOMPtr<nsIMemoryMultiReporter> mStorageSQLiteMultiReporter; nsCOMPtr<nsIMemoryReporter> mStorageSQLiteMultiReporter;
static Service *gService; static Service *gService;

View File

@@ -166,49 +166,32 @@ function onUnload()
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
/** /**
* Iterates over each reporter and multi-reporter. * Iterates over each reporter.
* *
* @param aIgnoreSingle * @param aIgnoreReporter
* Function that indicates if we should skip a single reporter, based * Function that indicates if we should skip an entire reporter, based
* on its path. * on its name.
* @param aIgnoreMulti * @param aIgnoreReport
* Function that indicates if we should skip a multi-reporter, based on * Function that indicates if we should skip a single report from a
* its name. * reporter, based on its path.
* @param aHandleReport * @param aHandleReport
* The function that's called for each report. * The function that's called for each non-skipped report.
*/ */
function processMemoryReporters(aIgnoreSingle, aIgnoreMulti, aHandleReport) function processMemoryReporters(aIgnoreReporter, aIgnoreReport, aHandleReport)
{ {
// Process each memory reporter with aHandleReport. let handleReport = function(aProcess, aUnsafePath, aKind, aUnits,
// aAmount, aDescription) {
// - Note that copying rOrig.amount (which calls a C++ function under the if (!aIgnoreReport(aUnsafePath)) {
// IDL covers) to r._amount for every reporter now means that the aHandleReport(aProcess, aUnsafePath, aKind, aUnits, aAmount,
// results as consistent as possible -- measurements are made all at aDescription, /* presence = */ undefined);
// once before most of the memory required to generate this page is
// allocated.
//
// - After this point we never use the original memory report again.
let e = gMgr.enumerateReporters();
while (e.hasMoreElements()) {
let rOrig = e.getNext().QueryInterface(Ci.nsIMemoryReporter);
let unsafePath = rOrig.path;
if (!aIgnoreSingle(unsafePath)) {
aHandleReport(rOrig.process, unsafePath, rOrig.kind, rOrig.units,
rOrig.amount, rOrig.description);
} }
} }
let e = gMgr.enumerateMultiReporters(); let e = gMgr.enumerateReporters();
while (e.hasMoreElements()) { while (e.hasMoreElements()) {
let mr = e.getNext().QueryInterface(Ci.nsIMemoryMultiReporter); let mr = e.getNext().QueryInterface(Ci.nsIMemoryReporter);
if (!aIgnoreMulti(mr.name)) { if (!aIgnoreReporter(mr.name)) {
// |collectReports| never passes in a |presence| argument. // |collectReports| never passes in a |presence| argument.
let handleReport = function(aProcess, aUnsafePath, aKind, aUnits,
aAmount, aDescription) {
aHandleReport(aProcess, aUnsafePath, aKind, aUnits, aAmount,
aDescription, /* presence = */ undefined);
}
mr.collectReports(handleReport, null); mr.collectReports(handleReport, null);
} }
} }
@@ -219,19 +202,19 @@ function processMemoryReporters(aIgnoreSingle, aIgnoreMulti, aHandleReport)
* *
* @param aReports * @param aReports
* Array of reports, read from a file or the clipboard. * Array of reports, read from a file or the clipboard.
* @param aIgnoreSingle * @param aIgnoreReport
* Function that indicates if we should skip a single reporter, based * Function that indicates if we should skip a single report, based
* on its path. * on its path.
* @param aHandleReport * @param aHandleReport
* The function that's called for each report. * The function that's called for each report.
*/ */
function processMemoryReportsFromFile(aReports, aIgnoreSingle, aHandleReport) function processMemoryReportsFromFile(aReports, aIgnoreReport, aHandleReport)
{ {
// Process each memory reporter with aHandleReport. // Process each memory reporter with aHandleReport.
for (let i = 0; i < aReports.length; i++) { for (let i = 0; i < aReports.length; i++) {
let r = aReports[i]; let r = aReports[i];
if (!aIgnoreSingle(r.path)) { if (!aIgnoreReport(r.path)) {
aHandleReport(r.process, r.path, r.kind, r.units, r.amount, aHandleReport(r.process, r.path, r.kind, r.units, r.amount,
r.description, r._presence); r.description, r._presence);
} }
@@ -591,10 +574,7 @@ function updateAboutMemoryFromReporters()
try { try {
// Process the reports from the memory reporters. // Process the reports from the memory reporters.
let process = function(aIgnoreSingle, aIgnoreMulti, aHandleReport) { appendAboutMemoryMain(processMemoryReporters, gMgr.hasMozMallocUsableSize,
processMemoryReporters(aIgnoreSingle, aIgnoreMulti, aHandleReport);
}
appendAboutMemoryMain(process, gMgr.hasMozMallocUsableSize,
/* forceShowSmaps = */ false); /* forceShowSmaps = */ false);
} catch (ex) { } catch (ex) {
@@ -621,8 +601,8 @@ function updateAboutMemoryFromJSONObject(aObj)
"missing 'hasMozMallocUsableSize' property"); "missing 'hasMozMallocUsableSize' property");
assertInput(aObj.reports && aObj.reports instanceof Array, assertInput(aObj.reports && aObj.reports instanceof Array,
"missing or non-array 'reports' property"); "missing or non-array 'reports' property");
let process = function(aIgnoreSingle, aIgnoreMulti, aHandleReport) { let process = function(aIgnoreReporter, aIgnoreReport, aHandleReport) {
processMemoryReportsFromFile(aObj.reports, aIgnoreSingle, aHandleReport); processMemoryReportsFromFile(aObj.reports, aIgnoreReport, aHandleReport);
} }
appendAboutMemoryMain(process, aObj.hasMozMallocUsableSize, appendAboutMemoryMain(process, aObj.hasMozMallocUsableSize,
/* forceShowSmaps = */ true); /* forceShowSmaps = */ true);
@@ -973,7 +953,7 @@ function PColl()
* Processes reports (whether from reporters or from a file) and append the * Processes reports (whether from reporters or from a file) and append the
* main part of the page. * main part of the page.
* *
* @param aProcess * @param aProcessReports
* Function that extracts the memory reports from the reporters or from * Function that extracts the memory reports from the reporters or from
* file. * file.
* @param aHasMozMallocUsableSize * @param aHasMozMallocUsableSize
@@ -982,10 +962,10 @@ function PColl()
* True if we should show the smaps memory reporters even if we're not * True if we should show the smaps memory reporters even if we're not
* in verbose mode. * in verbose mode.
*/ */
function appendAboutMemoryMain(aProcess, aHasMozMallocUsableSize, function appendAboutMemoryMain(aProcessReports, aHasMozMallocUsableSize,
aForceShowSmaps) aForceShowSmaps)
{ {
let pcollsByProcess = getPCollsByProcess(aProcess, aForceShowSmaps); let pcollsByProcess = getPCollsByProcess(aProcessReports, aForceShowSmaps);
// Sort the processes. // Sort the processes.
let processes = Object.keys(pcollsByProcess); let processes = Object.keys(pcollsByProcess);
@@ -1043,7 +1023,7 @@ function appendAboutMemoryMain(aProcess, aHasMozMallocUsableSize,
* This function reads all the memory reports, and puts that data in structures * This function reads all the memory reports, and puts that data in structures
* that will be used to generate the page. * that will be used to generate the page.
* *
* @param aProcessMemoryReports * @param aProcessReports
* Function that extracts the memory reports from the reporters or from * Function that extracts the memory reports from the reporters or from
* file. * file.
* @param aForceShowSmaps * @param aForceShowSmaps
@@ -1051,7 +1031,7 @@ function appendAboutMemoryMain(aProcess, aHasMozMallocUsableSize,
* in verbose mode. * in verbose mode.
* @return The table of PColls by process. * @return The table of PColls by process.
*/ */
function getPCollsByProcess(aProcessMemoryReports, aForceShowSmaps) function getPCollsByProcess(aProcessReports, aForceShowSmaps)
{ {
let pcollsByProcess = {}; let pcollsByProcess = {};
@@ -1060,23 +1040,28 @@ function getPCollsByProcess(aProcessMemoryReports, aForceShowSmaps)
// be in parentheses, so a ')' might appear after the '.'.) // be in parentheses, so a ')' might appear after the '.'.)
const gSentenceRegExp = /^[A-Z].*\.\)?$/m; const gSentenceRegExp = /^[A-Z].*\.\)?$/m;
// Ignore the "smaps" multi-reporter in non-verbose mode unless we're reading // Ignore the "smaps" reporter in non-verbose mode unless we're reading from
// from a file or the clipboard, and ignore the "compartments" and // a file or the clipboard, and ignore the "compartments" and "ghost-windows"
// "ghost-windows" multi-reporters all the time. (Note that reports from // reporters all the time. (Note that reports from these reporters can reach
// these multi-reporters can reach here as single reports if they were in the // here via a "content-child" reporter if they were in a child process.)
// child process.)
// //
// Also ignore the resident-fast reporter; we use the vanilla resident // Also ignore the "resident-fast" reporter; we use the vanilla "resident"
// reporter because it's more important that we get accurate results than // reporter because it's more important that we get accurate results than
// that we avoid the (small) possibility of a long pause when loading // that we avoid the (small) possibility of a long pause when loading
// about:memory. // about:memory. Furthermore, the "resident" reporter can purge pages on
// // MacOS, which affects the results of the "resident-fast" reporter, and we
// We don't show both resident and resident-fast because running the resident // don't want the measurements shown in about:memory to be affected by the
// reporter can purge pages on MacOS, which affects the results of the // (arbitrary) order of memory reporter execution.
// resident-fast reporter. We don't want about:memory's results to be
// affected by the order of memory reporter execution.
function ignoreSingle(aUnsafePath) function ignoreReporter(aName)
{
return (aName === "smaps" && !gVerbose.checked && !aForceShowSmaps) ||
aName === "compartments" ||
aName === "ghost-windows" ||
aName === "resident-fast";
}
function ignoreReport(aUnsafePath)
{ {
return (isSmapsPath(aUnsafePath) && !gVerbose.checked && !aForceShowSmaps) || return (isSmapsPath(aUnsafePath) && !gVerbose.checked && !aForceShowSmaps) ||
aUnsafePath.startsWith("compartments/") || aUnsafePath.startsWith("compartments/") ||
@@ -1084,13 +1069,6 @@ function getPCollsByProcess(aProcessMemoryReports, aForceShowSmaps)
aUnsafePath == "resident-fast"; aUnsafePath == "resident-fast";
} }
function ignoreMulti(aMRName)
{
return (aMRName === "smaps" && !gVerbose.checked && !aForceShowSmaps) ||
aMRName === "compartments" ||
aMRName === "ghost-windows";
}
function handleReport(aProcess, aUnsafePath, aKind, aUnits, aAmount, function handleReport(aProcess, aUnsafePath, aKind, aUnits, aAmount,
aDescription, aPresence) aDescription, aPresence)
{ {
@@ -1171,7 +1149,7 @@ function getPCollsByProcess(aProcessMemoryReports, aForceShowSmaps)
} }
} }
aProcessMemoryReports(ignoreSingle, ignoreMulti, handleReport); aProcessReports(ignoreReporter, ignoreReport, handleReport);
return pcollsByProcess; return pcollsByProcess;
} }
@@ -2107,18 +2085,18 @@ Compartment.prototype = {
function getCompartmentsByProcess() function getCompartmentsByProcess()
{ {
// Ignore anything that didn't come from the "compartments" multi-reporter. // Ignore anything that didn't come from the "compartments" reporter. (Note
// (Note that some such reports can reach here as single reports if they were // reports from this reporter can reach here via a "content-child" reporter
// in the child process.) // if they were in a child process.)
function ignoreSingle(aUnsafePath) function ignoreReporter(aName)
{ {
return !aUnsafePath.startsWith("compartments/"); return !(aName == "compartments" || aName == "content-child");
} }
function ignoreMulti(aMRName) function ignoreReport(aUnsafePath)
{ {
return aMRName !== "compartments"; return !aUnsafePath.startsWith("compartments/");
} }
let compartmentsByProcess = {}; let compartmentsByProcess = {};
@@ -2169,7 +2147,7 @@ function getCompartmentsByProcess()
} }
} }
processMemoryReporters(ignoreSingle, ignoreMulti, handleReport); processMemoryReporters(ignoreReporter, ignoreReport, handleReport);
return compartmentsByProcess; return compartmentsByProcess;
} }
@@ -2191,14 +2169,14 @@ GhostWindow.prototype = {
function getGhostWindowsByProcess() function getGhostWindowsByProcess()
{ {
function ignoreSingle(aUnsafePath) function ignoreReporter(aName)
{ {
return !aUnsafePath.startsWith('ghost-windows/') return !(aName == "ghost-windows" || aName == "content-child");
} }
function ignoreMulti(aName) function ignoreReport(aUnsafePath)
{ {
return aName !== "ghost-windows"; return !aUnsafePath.startsWith('ghost-windows/')
} }
let ghostWindowsByProcess = {}; let ghostWindowsByProcess = {};
@@ -2230,7 +2208,7 @@ function getGhostWindowsByProcess()
} }
} }
processMemoryReporters(ignoreSingle, ignoreMulti, handleReport); processMemoryReporters(ignoreReporter, ignoreReport, handleReport);
return ghostWindowsByProcess; return ghostWindowsByProcess;
} }

View File

@@ -24,8 +24,7 @@
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"]. let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
getService(Ci.nsIMemoryReporterManager); getService(Ci.nsIMemoryReporterManager);
// Remove all the real reporters and multi-reporters; save them to // Remove all the real reporters; save them to restore at the end.
// restore at the end.
mgr.blockRegistration(); mgr.blockRegistration();
var e = mgr.enumerateReporters(); var e = mgr.enumerateReporters();
var realReporters = []; var realReporters = [];
@@ -34,13 +33,6 @@
mgr.unregisterReporter(r); mgr.unregisterReporter(r);
realReporters.push(r); realReporters.push(r);
} }
e = mgr.enumerateMultiReporters();
var realMultiReporters = [];
while (e.hasMoreElements()) {
var r = e.getNext().QueryInterface(Ci.nsIMemoryMultiReporter);
mgr.unregisterMultiReporter(r);
realMultiReporters.push(r);
}
// Setup various fake-but-deterministic reporters. // Setup various fake-but-deterministic reporters.
const KB = 1024; const KB = 1024;
@@ -52,41 +44,39 @@
const BYTES = Ci.nsIMemoryReporter.UNITS_BYTES; const BYTES = Ci.nsIMemoryReporter.UNITS_BYTES;
const COUNT = Ci.nsIMemoryReporter.UNITS_COUNT; const COUNT = Ci.nsIMemoryReporter.UNITS_COUNT;
function f(aProcess, aPath, aKind, aUnits, aAmount) {
return {
process: aProcess,
path: aPath,
kind: aKind,
units: aUnits,
description: "",
amount: aAmount
};
}
var fakeReporters = [ var fakeReporters = [
// These should be ignored. { name: "fake1",
f("", "explicit/a", HEAP, BYTES, 222 * MB), collectReports: function(aCbObj, aClosure) {
f("", "explicit/b/a", HEAP, BYTES, 85 * MB), function f(aP1, aP2, aK, aU, aA) {
f("", "explicit/b/b", NONHEAP, BYTES, 85 * MB), aCbObj.callback(aP1, aP2, aK, aU, aA, "Desc.", aClosure);
f("", "other1", OTHER, BYTES, 111 * MB), }
f("", "other2", OTHER, COUNT, 888), // These should be ignored.
f("", "explicit/a", HEAP, BYTES, 222 * MB);
f("2nd", "explicit/c", HEAP, BYTES, 333 * MB), f("", "explicit/b/a", HEAP, BYTES, 85 * MB);
f("2nd", "compartments/user/child-user-compartment", OTHER, COUNT, 1), f("", "explicit/b/b", NONHEAP, BYTES, 85 * MB);
f("2nd", "compartments/system/child-system-compartment", OTHER, COUNT, 1) f("", "other1", OTHER, BYTES, 111 * MB);
]; f("", "other2", OTHER, COUNT, 888);
}
var fakeMultiReporters = [ },
// These shouldn't show up. { name: "fake2",
{ name: "fake",
collectReports: function(aCbObj, aClosure) { collectReports: function(aCbObj, aClosure) {
function f(aP, aK, aU, aA) { function f(aP, aK, aU, aA) {
aCbObj.callback("", aP, aK, aU, aA, "Desc.", aClosure); aCbObj.callback("", aP, aK, aU, aA, "Desc.", aClosure);
} }
// These shouldn't show up.
f("explicit/a/d", HEAP, BYTES, 13 * MB); f("explicit/a/d", HEAP, BYTES, 13 * MB);
f("explicit/b/c", NONHEAP, BYTES, 10 * MB); f("explicit/b/c", NONHEAP, BYTES, 10 * MB);
}, }
explicitNonHeap: 10*MB },
{ name: "content-child",
collectReports: function(aCbObj, aClosure) {
function f(aP1, aP2, aK, aU, aA, aD) {
aCbObj.callback(aP1, aP2, aK, aU, aA, aD, aClosure);
}
f("2nd", "explicit/c", HEAP, BYTES, 333 * MB, "Desc.");
f("2nd", "compartments/user/child-user-compartment", OTHER, COUNT, 1, "");
f("2nd", "compartments/system/child-system-compartment", OTHER, COUNT, 1, "");
}
}, },
{ name: "compartments", { name: "compartments",
collectReports: function(aCbObj, aClosure) { collectReports: function(aCbObj, aClosure) {
@@ -104,8 +94,7 @@
f("compartments/system/[System Principal]"); f("compartments/system/[System Principal]");
f("compartments/system/[System Principal]"); f("compartments/system/[System Principal]");
f("compartments/system/atoms"); f("compartments/system/atoms");
}, }
explicitNonHeap: 0
}, },
{ name: "ghost-windows", { name: "ghost-windows",
collectReports: function(aCbObj, aClosure) { collectReports: function(aCbObj, aClosure) {
@@ -114,8 +103,7 @@
} }
f("ghost-windows/https:\\\\very-long-url.com\\very-long\\oh-so-long\\really-quite-long.html?a=2&b=3&c=4&d=5&e=abcdefghijklmnopqrstuvwxyz&f=123456789123456789123456789"); f("ghost-windows/https:\\\\very-long-url.com\\very-long\\oh-so-long\\really-quite-long.html?a=2&b=3&c=4&d=5&e=abcdefghijklmnopqrstuvwxyz&f=123456789123456789123456789");
f("ghost-windows/http:\\\\foobar.com\\foo?bar#baz"); f("ghost-windows/http:\\\\foobar.com\\foo?bar#baz");
}, }
explicitNonHeap: 0
}, },
// These shouldn't show up. // These shouldn't show up.
{ name: "smaps", { name: "smaps",
@@ -126,17 +114,13 @@
} }
f("smaps/vsize/a", 24); f("smaps/vsize/a", 24);
f("smaps/swap/a", 1); f("smaps/swap/a", 1);
}, }
explicitNonHeap: 0
} }
]; ];
for (var i = 0; i < fakeReporters.length; i++) { for (var i = 0; i < fakeReporters.length; i++) {
mgr.registerReporterEvenIfBlocked(fakeReporters[i]); mgr.registerReporterEvenIfBlocked(fakeReporters[i]);
} }
for (var i = 0; i < fakeMultiReporters.length; i++) {
mgr.registerMultiReporterEvenIfBlocked(fakeMultiReporters[i]);
}
]]> ]]>
</script> </script>
@@ -180,21 +164,14 @@ Ghost Windows\n\
function finish() function finish()
{ {
// Unregister fake reporters and multi-reporters, re-register the real // Unregister fake reporters and re-register the real reporters, just in
// reporters and multi-reporters, just in case subsequent tests rely on // case subsequent tests rely on them.
// them.
for (var i = 0; i < fakeReporters.length; i++) { for (var i = 0; i < fakeReporters.length; i++) {
mgr.unregisterReporter(fakeReporters[i]); mgr.unregisterReporter(fakeReporters[i]);
} }
for (var i = 0; i < fakeMultiReporters.length; i++) {
mgr.unregisterMultiReporter(fakeMultiReporters[i]);
}
for (var i = 0; i < realReporters.length; i++) { for (var i = 0; i < realReporters.length; i++) {
mgr.registerReporterEvenIfBlocked(realReporters[i]); mgr.registerReporterEvenIfBlocked(realReporters[i]);
} }
for (var i = 0; i < realMultiReporters.length; i++) {
mgr.registerMultiReporterEvenIfBlocked(realMultiReporters[i]);
}
mgr.unblockRegistration(); mgr.unblockRegistration();
SimpleTest.finish(); SimpleTest.finish();

View File

@@ -27,8 +27,7 @@
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"]. let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
getService(Ci.nsIMemoryReporterManager); getService(Ci.nsIMemoryReporterManager);
// Remove all the real reporters and multi-reporters; save them to // Remove all the real reporters; save them to restore at the end.
// restore at the end.
mgr.blockRegistration(); mgr.blockRegistration();
let e = mgr.enumerateReporters(); let e = mgr.enumerateReporters();
let realReporters = []; let realReporters = [];
@@ -37,13 +36,6 @@
mgr.unregisterReporter(r); mgr.unregisterReporter(r);
realReporters.push(r); realReporters.push(r);
} }
e = mgr.enumerateMultiReporters();
let realMultiReporters = [];
while (e.hasMoreElements()) {
let r = e.getNext().QueryInterface(Ci.nsIMemoryMultiReporter);
mgr.unregisterMultiReporter(r);
realMultiReporters.push(r);
}
// Setup various fake-but-deterministic reporters. // Setup various fake-but-deterministic reporters.
const KB = 1024; const KB = 1024;
@@ -57,71 +49,60 @@
const COUNT_CUMULATIVE = Ci.nsIMemoryReporter.UNITS_COUNT_CUMULATIVE; const COUNT_CUMULATIVE = Ci.nsIMemoryReporter.UNITS_COUNT_CUMULATIVE;
const PERCENTAGE = Ci.nsIMemoryReporter.UNITS_PERCENTAGE; const PERCENTAGE = Ci.nsIMemoryReporter.UNITS_PERCENTAGE;
function f2(aProcess, aPath, aKind, aUnits, aAmount) {
return {
process: aProcess,
path: aPath,
kind: aKind,
units: aUnits,
description: "Desc.",
amount: aAmount
};
}
function f(aProcess, aPath, aKind, aAmount) {
return f2(aProcess, aPath, aKind, BYTES, aAmount);
}
let fakeReporters = [ let fakeReporters = [
f("", "heap-allocated", OTHER, 500 * MB), { name: "fake0",
f("", "heap-unallocated", OTHER, 100 * MB), collectReports: function(aCbObj, aClosure) {
f("", "explicit/a", HEAP, 222 * MB), function f(aP, aK, aU, aA) {
f("", "explicit/b/a", HEAP, 85 * MB), aCbObj.callback("", aP, aK, aU, aA, "Desc.", aClosure);
f("", "explicit/b/b", HEAP, 75 * MB), }
f("", "explicit/b/c/a", HEAP, 70 * MB), f("heap-allocated", OTHER, BYTES, 500 * MB);
f("", "explicit/b/c/b", HEAP, 2 * MB), // omitted f("heap-unallocated", OTHER, BYTES, 100 * MB);
f("", "explicit/g/a", HEAP, 6 * MB), f("explicit/a", HEAP, BYTES, 222 * MB);
f("", "explicit/g/b", HEAP, 5 * MB), f("explicit/b/a", HEAP, BYTES, 85 * MB);
f("", "explicit/g/other", HEAP, 4 * MB), f("explicit/b/b", HEAP, BYTES, 75 * MB);
// A degenerate tree with the same name as a non-degenerate tree should f("explicit/b/c/a", HEAP, BYTES, 70 * MB);
// work ok. f("explicit/b/c/b", HEAP, BYTES, 2 * MB); // omitted
f("", "explicit", OTHER, 888 * MB), f("explicit/g/a", HEAP, BYTES, 6 * MB);
f("", "other1/a/b", OTHER, 111 * MB), f("explicit/g/b", HEAP, BYTES, 5 * MB);
f("", "other1/c/d", OTHER, 22 * MB), f("explicit/g/other", HEAP, BYTES, 4 * MB);
f("", "other1/c/e", OTHER, 33 * MB), // A degenerate tree with the same name as a non-degenerate tree should
f2("", "other4", OTHER, COUNT_CUMULATIVE, 777), // work ok.
f2("", "other4", OTHER, COUNT_CUMULATIVE, 111), f("explicit", OTHER, BYTES, 888 * MB);
f2("", "other3/a/b/c/d/e", OTHER, PERCENTAGE, 2000), f("other1/a/b", OTHER, BYTES, 111 * MB);
f2("", "other3/a/b/c/d/f", OTHER, PERCENTAGE, 10), f("other1/c/d", OTHER, BYTES, 22 * MB);
f2("", "other3/a/b/c/d/g", OTHER, PERCENTAGE, 5), f("other1/c/e", OTHER, BYTES, 33 * MB);
f2("", "other3/a/b/c/d/g", OTHER, PERCENTAGE, 5), f("other4", OTHER, COUNT_CUMULATIVE, 777);
// Check that a rounded-up-to-100.00% value is shown as "100.0%" (i.e. one f("other4", OTHER, COUNT_CUMULATIVE, 111);
// decimal point). f("other3/a/b/c/d/e", OTHER, PERCENTAGE, 2000);
f2("", "other6/big", OTHER, COUNT, 99999), f("other3/a/b/c/d/f", OTHER, PERCENTAGE, 10);
f2("", "other6/small", OTHER, COUNT, 1), f("other3/a/b/c/d/g", OTHER, PERCENTAGE, 5);
// Check that a 0 / 0 is handled correctly. f("other3/a/b/c/d/g", OTHER, PERCENTAGE, 5);
f("", "other7/zero", OTHER, 0), // Check that a rounded-up-to-100.00% value is shown as "100.0%" (i.e. one
// These compartments ones shouldn't be displayed. // decimal point).
f2("", "compartments/user/foo", OTHER, COUNT, 1), f("other6/big", OTHER, COUNT, 99999);
f2("", "compartments/system/foo", OTHER, COUNT, 1) f("other6/small", OTHER, COUNT, 1);
]; // Check that a 0 / 0 is handled correctly.
let fakeMultiReporters = [ f("other7/zero", OTHER, BYTES, 0);
// These compartments ones shouldn't be displayed.
f("compartments/user/foo", OTHER, COUNT, 1);
f("compartments/system/foo", OTHER, COUNT, 1);
}
},
{ name: "fake1", { name: "fake1",
collectReports: function(aCbObj, aClosure) { collectReports: function(aCbObj, aClosure) {
function f(aP, aK, aU, aA) { function f(aP, aK, aU, aA) {
aCbObj.callback("", aP, aK, aU, aA, "Desc.", aClosure); aCbObj.callback("", aP, aK, aU, aA, "Desc.", aClosure);
} }
f("explicit/c/d", NONHEAP, BYTES, 13 * MB), f("explicit/c/d", NONHEAP, BYTES, 13 * MB);
f("explicit/c/d", NONHEAP, BYTES, 10 * MB), // dup f("explicit/c/d", NONHEAP, BYTES, 10 * MB); // dup
f("explicit/c/other", NONHEAP, BYTES, 77 * MB), f("explicit/c/other", NONHEAP, BYTES, 77 * MB);
f("explicit/cc", NONHEAP, BYTES, 13 * MB); f("explicit/cc", NONHEAP, BYTES, 13 * MB);
f("explicit/cc", NONHEAP, BYTES, 10 * MB); // dup f("explicit/cc", NONHEAP, BYTES, 10 * MB); // dup
f("explicit/d", NONHEAP, BYTES, 499 * KB); // omitted f("explicit/d", NONHEAP, BYTES, 499 * KB); // omitted
f("explicit/e", NONHEAP, BYTES, 100 * KB); // omitted f("explicit/e", NONHEAP, BYTES, 100 * KB); // omitted
f("explicit/f/g/h/i", HEAP, BYTES, 10 * MB); f("explicit/f/g/h/i", HEAP, BYTES, 10 * MB);
f("explicit/f/g/h/j", HEAP, BYTES, 10 * MB); f("explicit/f/g/h/j", HEAP, BYTES, 10 * MB);
}, }
explicitNonHeap: (100 + 13 + 10)*MB + (499 + 100)*KB
}, },
{ name: "fake2", { name: "fake2",
collectReports: function(aCbObj, aClosure) { collectReports: function(aCbObj, aClosure) {
@@ -132,8 +113,7 @@
f("other2", OTHER, BYTES, 222 * MB); f("other2", OTHER, BYTES, 222 * MB);
f("perc2", OTHER, PERCENTAGE, 10000); f("perc2", OTHER, PERCENTAGE, 10000);
f("perc1", OTHER, PERCENTAGE, 4567); f("perc1", OTHER, PERCENTAGE, 4567);
}, }
explicitNonHeap: 0
}, },
{ name: "smaps", { name: "smaps",
collectReports: function(aCbObj, aClosure) { collectReports: function(aCbObj, aClosure) {
@@ -148,8 +128,7 @@
f("swap/b/c", 10); f("swap/b/c", 10);
f("rss/a", 42); f("rss/a", 42);
f("pss/a", 43); f("pss/a", 43);
}, }
explicitNonHeap: 0
}, },
{ name: "compartments", { name: "compartments",
collectReports: function(aCbObj, aClosure) { collectReports: function(aCbObj, aClosure) {
@@ -158,16 +137,12 @@
} }
f("compartments/user/bar"); f("compartments/user/bar");
f("compartments/system/bar"); f("compartments/system/bar");
}, }
explicitNonHeap: 0
} }
]; ];
for (let i = 0; i < fakeReporters.length; i++) { for (let i = 0; i < fakeReporters.length; i++) {
mgr.registerReporterEvenIfBlocked(fakeReporters[i]); mgr.registerReporterEvenIfBlocked(fakeReporters[i]);
} }
for (let i = 0; i < fakeMultiReporters.length; i++) {
mgr.registerMultiReporterEvenIfBlocked(fakeMultiReporters[i]);
}
// mgr.explicit sums "heap-allocated" and all the appropriate NONHEAP ones: // mgr.explicit sums "heap-allocated" and all the appropriate NONHEAP ones:
// - "explicit/c", "explicit/cc" x 2, "explicit/d", "explicit/e" // - "explicit/c", "explicit/cc" x 2, "explicit/d", "explicit/e"
@@ -189,59 +164,74 @@
// the largest). Processes without a |resident| memory reporter are saved // the largest). Processes without a |resident| memory reporter are saved
// for the end. // for the end.
let fakeReporters2 = [ let fakeReporters2 = [
f("2nd", "heap-allocated", OTHER, 1000 * MB), { name: "resident-fast",
f("2nd", "heap-unallocated",OTHER, 100 * MB), collectReports: function(aCbObj, aClosure) {
f("2nd", "explicit/a/b/c", HEAP, 497 * MB), // Shouldn't reach here; aboutMemory.js should skip the reporter.
f("2nd", "explicit/a/b/c", HEAP, 1 * MB), // dup: merge // (Nb: this must come after |mgr.explicit| is accessed, otherwise it
f("2nd", "explicit/a/b/c", HEAP, 1 * MB), // dup: merge // *will* be run by nsMemoryReporterManager::GetExplicit()).
f("2nd", "explicit/flip\\the\\backslashes", ok(false, "'resident-fast' reporter was run");
HEAP, 200 * MB), }
f("2nd", "explicit/compartment(compartment-url)", },
HEAP, 200 * MB), { name: "fake3",
f("2nd", "other0", OTHER, 666 * MB), collectReports: function(aCbObj, aClosure) {
f("2nd", "other1", OTHER, 111 * MB), function f(aP1, aP2, aK, aU, aA) {
// Even though the "smaps" reporter is a multi-reporter, if its in a aCbObj.callback(aP1, aP2, aK, aU, aA, "Desc.", aClosure);
// child process it'll be passed to the main process as single reports. }
// The fact that we skip the "smaps" multi-reporter in the main f("2nd", "heap-allocated", OTHER, BYTES,1000* MB);
// process won't cause these to be skipped; the fall-back skipping will f("2nd", "heap-unallocated",OTHER, BYTES,100 * MB);
// be hit instead. f("2nd", "explicit/a/b/c", HEAP, BYTES,497 * MB);
f("2nd", "size/e", NONHEAP, 24*4*KB), f("2nd", "explicit/a/b/c", HEAP, BYTES, 1 * MB); // dup: merge
f("2nd", "size/f", NONHEAP, 24*4*KB), f("2nd", "explicit/a/b/c", HEAP, BYTES, 1 * MB); // dup: merge
f("2nd", "explicit/flip\\the\\backslashes",
HEAP, BYTES,200 * MB);
f("2nd", "explicit/compartment(compartment-url)",
HEAP, BYTES,200 * MB);
f("2nd", "other0", OTHER, BYTES,666 * MB);
f("2nd", "other1", OTHER, BYTES,111 * MB);
// If the "smaps" reporter is in a child process it'll be passed to
// the main process under a different name. The fact that we skip
// the "smaps" reporter in the main process won't cause these
// to be skipped; the report-level skipping will be hit instead.
f("2nd", "size/e", NONHEAP, BYTES,24*4*KB);
f("2nd", "size/f", NONHEAP, BYTES,24*4*KB);
f("2nd", "resident-fast", NONHEAP, BYTES,24*4*KB); // ignored!
// Check that we can handle "heap-allocated" not being present. // Check that we can handle "heap-allocated" not being present.
f("3rd", "explicit/a/b", HEAP, 333 * MB), f("3rd", "explicit/a/b", HEAP, BYTES,333 * MB);
f("3rd", "explicit/a/c", HEAP, 444 * MB), f("3rd", "explicit/a/c", HEAP, BYTES,444 * MB);
f("3rd", "other1", OTHER, 1 * MB), f("3rd", "other1", OTHER, BYTES, 1 * MB);
f("3rd", "resident", OTHER, 100 * MB), f("3rd", "resident", OTHER, BYTES,100 * MB);
// Invalid values (negative, too-big) should be identified. // Invalid values (negative, too-big) should be identified.
f("4th", "heap-allocated", OTHER, 100 * MB), f("4th", "heap-allocated", OTHER, BYTES,100 * MB);
f("4th", "resident", OTHER, 200 * MB), f("4th", "resident", OTHER, BYTES,200 * MB);
f("4th", "explicit/js/compartment(http:\\\\too-big.com\\)/stuff", f("4th", "explicit/js/compartment(http:\\\\too-big.com\\)/stuff",
HEAP, 150 * MB), HEAP, BYTES,150 * MB);
f("4th", "explicit/ok", HEAP, 5 * MB), f("4th", "explicit/ok", HEAP, BYTES, 5 * MB);
f("4th", "explicit/neg1", NONHEAP, -2 * MB), f("4th", "explicit/neg1", NONHEAP, BYTES, -2 * MB);
// -111 becomes "-0.00MB" in non-verbose mode, and getting the negative // -111 becomes "-0.00MB" in non-verbose mode, and getting the negative
// sign in there correctly is non-trivial. // sign in there correctly is non-trivial.
f("4th", "other1", OTHER, -111), f("4th", "other1", OTHER, BYTES,-111);
f("4th", "other2", OTHER, -222 * MB), f("4th", "other2", OTHER, BYTES,-222 * MB);
f2("4th", "other3", OTHER, COUNT, -333), f("4th", "other3", OTHER, COUNT, -333);
f2("4th", "other4", OTHER, COUNT_CUMULATIVE, -444), f("4th", "other4", OTHER, COUNT_CUMULATIVE, -444);
f2("4th", "other5", OTHER, PERCENTAGE, -555), f("4th", "other5", OTHER, PERCENTAGE, -555);
f2("4th", "other6", OTHER, PERCENTAGE, 66666), f("4th", "other6", OTHER, PERCENTAGE, 66666);
// If a negative value is within a collapsed sub-tree in non-verbose mode, // If a negative value is within a collapsed sub-tree in non-verbose mode,
// we should get the warning at the top and the relevant sub-trees should // we should get the warning at the top and the relevant sub-trees should
// be expanded, even in non-verbose mode. // be expanded, even in non-verbose mode.
f("5th", "heap-allocated", OTHER, 100 * MB), f("5th", "heap-allocated", OTHER, BYTES,100 * MB);
f("5th", "explicit/big", HEAP, 99 * MB), f("5th", "explicit/big", HEAP, BYTES, 99 * MB);
f("5th", "explicit/a/pos", HEAP, 40 * KB), f("5th", "explicit/a/pos", HEAP, BYTES, 40 * KB);
f("5th", "explicit/a/neg1", NONHEAP, -20 * KB), f("5th", "explicit/a/neg1", NONHEAP, BYTES,-20 * KB);
f("5th", "explicit/a/neg2", NONHEAP, -10 * KB), f("5th", "explicit/a/neg2", NONHEAP, BYTES,-10 * KB);
f("5th", "explicit/b/c/d/e", NONHEAP, 20 * KB), f("5th", "explicit/b/c/d/e", NONHEAP, BYTES, 20 * KB);
f("5th", "explicit/b/c/d/f", NONHEAP, -60 * KB), f("5th", "explicit/b/c/d/f", NONHEAP, BYTES,-60 * KB);
f("5th", "explicit/b/c/g/h", NONHEAP, 10 * KB), f("5th", "explicit/b/c/g/h", NONHEAP, BYTES, 10 * KB);
f("5th", "explicit/b/c/i/j", NONHEAP, 5 * KB) f("5th", "explicit/b/c/i/j", NONHEAP, BYTES, 5 * KB);
}
}
]; ];
for (let i = 0; i < fakeReporters2.length; i++) { for (let i = 0; i < fakeReporters2.length; i++) {
mgr.registerReporterEvenIfBlocked(fakeReporters2[i]); mgr.registerReporterEvenIfBlocked(fakeReporters2[i]);
@@ -586,21 +576,14 @@ Other Measurements\n\
function finish() function finish()
{ {
// Unregister fake reporters and multi-reporters, re-register the real // Unregister fake reporters and re-register the real reporters, just in
// reporters and multi-reporters, just in case subsequent tests rely on // case subsequent tests rely on them.
// them.
for (let i = 0; i < fakeReporters.length; i++) { for (let i = 0; i < fakeReporters.length; i++) {
mgr.unregisterReporter(fakeReporters[i]); mgr.unregisterReporter(fakeReporters[i]);
} }
for (let i = 0; i < fakeMultiReporters.length; i++) {
mgr.unregisterMultiReporter(fakeMultiReporters[i]);
}
for (let i = 0; i < realReporters.length; i++) { for (let i = 0; i < realReporters.length; i++) {
mgr.registerReporterEvenIfBlocked(realReporters[i]); mgr.registerReporterEvenIfBlocked(realReporters[i]);
} }
for (let i = 0; i < realMultiReporters.length; i++) {
mgr.registerMultiReporterEvenIfBlocked(realMultiReporters[i]);
}
mgr.unblockRegistration(); mgr.unblockRegistration();
SimpleTest.finish(); SimpleTest.finish();

View File

@@ -22,8 +22,7 @@
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"]. let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
getService(Ci.nsIMemoryReporterManager); getService(Ci.nsIMemoryReporterManager);
// Remove all the real reporters and multi-reporters; save them to // Remove all the real reporters; save them to restore at the end.
// restore at the end.
mgr.blockRegistration(); mgr.blockRegistration();
let e = mgr.enumerateReporters(); let e = mgr.enumerateReporters();
let realReporters = []; let realReporters = [];
@@ -32,13 +31,6 @@
mgr.unregisterReporter(r); mgr.unregisterReporter(r);
realReporters.push(r); realReporters.push(r);
} }
e = mgr.enumerateMultiReporters();
let realMultiReporters = [];
while (e.hasMoreElements()) {
let r = e.getNext().QueryInterface(Ci.nsIMemoryMultiReporter);
mgr.unregisterMultiReporter(r);
realMultiReporters.push(r);
}
// Setup various fake-but-deterministic reporters. // Setup various fake-but-deterministic reporters.
const KB = 1024; const KB = 1024;
@@ -47,35 +39,31 @@
const OTHER = Ci.nsIMemoryReporter.KIND_OTHER; const OTHER = Ci.nsIMemoryReporter.KIND_OTHER;
const BYTES = Ci.nsIMemoryReporter.UNITS_BYTES; const BYTES = Ci.nsIMemoryReporter.UNITS_BYTES;
function f(aPath, aKind, aAmount) { let hiPath = "explicit/h/i";
return { let hi2Path = "explicit/h/i2";
process: "", let jkPath = "explicit/j/k";
path: aPath, let jk2Path = "explicit/j/k2";
kind: aKind,
units: BYTES,
description: "Desc.",
amount: aAmount
};
}
let hiReport = f("explicit/h/i", HEAP, 10 * MB);
let hi2Report = f("explicit/h/i2", HEAP, 9 * MB);
let jkReport = f("explicit/j/k", HEAP, 0.5 * MB);
let jk2Report = f("explicit/j/k2", HEAP, 0.3 * MB);
let fakeReporters = [ let fakeReporters = [
f("heap-allocated", OTHER, 250 * MB), { name: "fake1",
f("explicit/a/b", HEAP, 50 * MB), collectReports: function(aCbObj, aClosure) {
f("explicit/a/c/d", HEAP, 25 * MB), function f(aP, aK, aA) {
f("explicit/a/c/e", HEAP, 15 * MB), aCbObj.callback("", aP, aK, BYTES, aA, "Desc.", aClosure);
f("explicit/a/f", HEAP, 30 * MB), }
f("explicit/g", HEAP, 100 * MB), f("heap-allocated", OTHER, 250 * MB);
hiReport, f("explicit/a/b", HEAP, 50 * MB);
hi2Report, f("explicit/a/c/d", HEAP, 25 * MB);
jkReport, f("explicit/a/c/e", HEAP, 15 * MB);
jk2Report, f("explicit/a/f", HEAP, 30 * MB);
f("explicit/a/l/m", HEAP, 0.1 * MB), f("explicit/g", HEAP, 100 * MB);
f("explicit/a/l/n", HEAP, 0.1 * MB), f(hiPath, HEAP, 10 * MB);
f(hi2Path, HEAP, 9 * MB);
f(jkPath, HEAP, 0.5 * MB);
f(jk2Path, HEAP, 0.3 * MB);
f("explicit/a/l/m", HEAP, 0.1 * MB);
f("explicit/a/l/n", HEAP, 0.1 * MB);
}
}
]; ];
for (let i = 0; i < fakeReporters.length; i++) { for (let i = 0; i < fakeReporters.length; i++) {
@@ -91,18 +79,14 @@
<![CDATA[ <![CDATA[
function finish() function finish()
{ {
// Unregister fake reporters and multi-reporters, re-register the real // Unregister fake reporters and re-register the real reporters, just in
// reporters and multi-reporters, just in case subsequent tests rely on // case subsequent tests rely on them.
// them.
for (let i = 0; i < fakeReporters.length; i++) { for (let i = 0; i < fakeReporters.length; i++) {
mgr.unregisterReporter(fakeReporters[i]); mgr.unregisterReporter(fakeReporters[i]);
} }
for (let i = 0; i < realReporters.length; i++) { for (let i = 0; i < realReporters.length; i++) {
mgr.registerReporterEvenIfBlocked(realReporters[i]); mgr.registerReporterEvenIfBlocked(realReporters[i]);
} }
for (let i = 0; i < realMultiReporters.length; i++) {
mgr.registerMultiReporterEvenIfBlocked(realMultiReporters[i]);
}
mgr.unblockRegistration(); mgr.unblockRegistration();
SimpleTest.finish(); SimpleTest.finish();
@@ -119,13 +103,13 @@
// click on a child of the span identified via |id|. // click on a child of the span identified via |id|.
if (node.nodeName === "button") { if (node.nodeName === "button") {
if (aSwap) { if (aSwap) {
// We swap the paths of hiReport/hi2Report and jkReport/jk2Report // We swap hipath/hi2Path and jkPath/jk2Path just before updating, to
// just before updating, to test what happens when significant nodes // test what happens when significant nodes become insignificant and
// become insignificant and vice versa. // vice versa.
hiReport.path = "explicit/j/k"; hiPath = "explicit/j/k";
hi2Report.path = "explicit/j/k2"; hi2Path = "explicit/j/k2";
jkReport.path = "explicit/h/i"; jkPath = "explicit/h/i";
jk2Report.path = "explicit/h/i2"; jk2Path = "explicit/h/i2";
} }
node.click(); node.click();
} else { } else {

View File

@@ -22,8 +22,7 @@
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"]. let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
getService(Ci.nsIMemoryReporterManager); getService(Ci.nsIMemoryReporterManager);
// Remove all the real reporters and multi-reporters; save them to // Remove all the real reporters; save them to restore at the end.
// restore at the end.
mgr.blockRegistration(); mgr.blockRegistration();
let e = mgr.enumerateReporters(); let e = mgr.enumerateReporters();
let realReporters = []; let realReporters = [];
@@ -32,13 +31,6 @@
mgr.unregisterReporter(r); mgr.unregisterReporter(r);
realReporters.push(r); realReporters.push(r);
} }
e = mgr.enumerateMultiReporters();
let realMultiReporters = [];
while (e.hasMoreElements()) {
let r = e.getNext().QueryInterface(Ci.nsIMemoryMultiReporter);
mgr.unregisterMultiReporter(r);
realMultiReporters.push(r);
}
// Setup a minimal number of fake reporters. // Setup a minimal number of fake reporters.
const KB = 1024; const KB = 1024;
@@ -47,22 +39,18 @@
const OTHER = Ci.nsIMemoryReporter.KIND_OTHER; const OTHER = Ci.nsIMemoryReporter.KIND_OTHER;
const BYTES = Ci.nsIMemoryReporter.UNITS_BYTES; const BYTES = Ci.nsIMemoryReporter.UNITS_BYTES;
function f(aPath, aKind, aAmount, aDesc) {
return {
process: "",
path: aPath,
kind: aKind,
units: BYTES,
amount: aAmount,
description: aDesc
};
}
let fakeReporters = [ let fakeReporters = [
f("heap-allocated", OTHER, 250 * MB, "Heap allocated."), { name: "fake1",
f("explicit/a/b", HEAP, 50 * MB, "A b."), collectReports: function(aCbObj, aClosure) {
f("other/a", OTHER, 0.2 * MB, "Other a."), function f(aP, aK, aA, aD) {
f("other/b", OTHER, 0.1 * MB, "Other b."), aCbObj.callback("", aP, aK, BYTES, aA, aD, aClosure);
}
f("heap-allocated", OTHER, 250 * MB, "Heap allocated.");
f("explicit/a/b", HEAP, 50 * MB, "A b.");
f("other/a", OTHER, 0.2 * MB, "Other a.");
f("other/b", OTHER, 0.1 * MB, "Other b.");
}
}
]; ];
for (let i = 0; i < fakeReporters.length; i++) { for (let i = 0; i < fakeReporters.length; i++) {
@@ -78,18 +66,14 @@
<![CDATA[ <![CDATA[
function finish() function finish()
{ {
// Unregister fake reporters and multi-reporters, re-register the real // Unregister fake reporters and re-register the real reporters, just in
// reporters and multi-reporters, just in case subsequent tests rely on // case subsequent tests rely on them.
// them.
for (let i = 0; i < fakeReporters.length; i++) { for (let i = 0; i < fakeReporters.length; i++) {
mgr.unregisterReporter(fakeReporters[i]); mgr.unregisterReporter(fakeReporters[i]);
} }
for (let i = 0; i < realReporters.length; i++) { for (let i = 0; i < realReporters.length; i++) {
mgr.registerReporterEvenIfBlocked(realReporters[i]); mgr.registerReporterEvenIfBlocked(realReporters[i]);
} }
for (let i = 0; i < realMultiReporters.length; i++) {
mgr.registerMultiReporterEvenIfBlocked(realMultiReporters[i]);
}
mgr.unblockRegistration(); mgr.unblockRegistration();
SimpleTest.finish(); SimpleTest.finish();

View File

@@ -138,11 +138,6 @@
let e = mgr.enumerateReporters(); let e = mgr.enumerateReporters();
while (e.hasMoreElements()) { while (e.hasMoreElements()) {
let r = e.getNext().QueryInterface(Ci.nsIMemoryReporter); let r = e.getNext().QueryInterface(Ci.nsIMemoryReporter);
handleReport(r.process, r.path, r.kind, r.units, r.amount, r.description);
}
e = mgr.enumerateMultiReporters();
while (e.hasMoreElements()) {
let r = e.getNext().QueryInterface(Ci.nsIMemoryMultiReporter);
r.collectReports(handleReport, null); r.collectReports(handleReport, null);
// Access |name| to make sure it doesn't crash or assert. // Access |name| to make sure it doesn't crash or assert.

View File

@@ -36,13 +36,13 @@
let db = storage.openDatabase(file); let db = storage.openDatabase(file);
db.close(); db.close();
// Invoke all the multi-reporters. The SQLite multi-reporter is among // Invoke all the reporters. The SQLite multi-reporter is among
// them. It shouldn't crash. // them. It shouldn't crash.
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"]. let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
getService(Ci.nsIMemoryReporterManager); getService(Ci.nsIMemoryReporterManager);
e = mgr.enumerateMultiReporters(); e = mgr.enumerateReporters();
while (e.hasMoreElements()) { while (e.hasMoreElements()) {
let r = e.getNext().QueryInterface(Ci.nsIMemoryMultiReporter); let r = e.getNext().QueryInterface(Ci.nsIMemoryReporter);
r.collectReports(function(){}, null); r.collectReports(function(){}, null);
} }

View File

@@ -1909,11 +1909,11 @@ StoreAndNotifyEmbedVisit(VisitData& aPlace,
(void)NS_DispatchToMainThread(event); (void)NS_DispatchToMainThread(event);
} }
class HistoryLinksHashtableReporter MOZ_FINAL : public MemoryReporterBase class HistoryLinksHashtableReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
HistoryLinksHashtableReporter() HistoryLinksHashtableReporter()
: MemoryReporterBase("explicit/history-links-hashtable", : MemoryUniReporter("explicit/history-links-hashtable",
KIND_HEAP, UNITS_BYTES, KIND_HEAP, UNITS_BYTES,
"Memory used by the hashtable that records changes to the visited state of " "Memory used by the hashtable that records changes to the visited state of "
"links.") "links.")

View File

@@ -370,11 +370,11 @@ TelemetryImpl::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
return n; return n;
} }
class TelemetryReporter MOZ_FINAL : public MemoryReporterBase class TelemetryReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
TelemetryReporter() TelemetryReporter()
: MemoryReporterBase("explicit/telemetry", KIND_HEAP, UNITS_BYTES, : MemoryUniReporter("explicit/telemetry", KIND_HEAP, UNITS_BYTES,
"Memory used by the telemetry system.") "Memory used by the telemetry system.")
{} {}
private: private:

View File

@@ -8,6 +8,7 @@ const Ci = Components.interfaces;
const Cr = Components.results; const Cr = Components.results;
const Cu = Components.utils; const Cu = Components.utils;
Cu.import("resource://gre/modules/debug.js");
Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm");
#ifndef MOZ_WIDGET_GONK #ifndef MOZ_WIDGET_GONK
@@ -458,15 +459,32 @@ TelemetryPing.prototype = {
let e = mgr.enumerateReporters(); let e = mgr.enumerateReporters();
while (e.hasMoreElements()) { while (e.hasMoreElements()) {
let mr = e.getNext().QueryInterface(Ci.nsIMemoryReporter); let mr = e.getNext().QueryInterface(Ci.nsIMemoryReporter);
let id = MEM_HISTOGRAMS[mr.path]; let id = MEM_HISTOGRAMS[mr.name];
if (!id) { if (!id) {
continue; continue;
} }
// Reading mr.amount might throw an exception. If so, just ignore that // collectReports might throw an exception. If so, just ignore that
// memory reporter; we're not getting useful data out of it. // memory reporter; we're not getting useful data out of it.
try { try {
this.handleMemoryReport(id, mr.path, mr.units, mr.amount); // Bind handleMemoryReport() so it can be called inside the closure
// used as the callback.
let boundHandleMemoryReport = this.handleMemoryReport.bind(this);
// Reporters used for telemetry should be uni-reporters! we assert if
// they make more than one report.
let hasReported = false;
function h(process, path, kind, units, amount, desc) {
if (!hasReported) {
boundHandleMemoryReport(id, path, units, amount);
hasReported = true;
} else {
NS_ASSERT(false,
"reporter " + mr.name + " has made more than one report");
}
}
mr.collectReports(h, null);
} }
catch (e) { catch (e) {
} }
@@ -474,11 +492,7 @@ TelemetryPing.prototype = {
histogram.add(new Date() - startTime); histogram.add(new Date() - startTime);
}, },
handleMemoryReport: function handleMemoryReport(id, path, units, amount) { handleMemoryReport: function(id, path, units, amount) {
if (amount == -1) {
return;
}
let val; let val;
if (units == Ci.nsIMemoryReporter.UNITS_BYTES) { if (units == Ci.nsIMemoryReporter.UNITS_BYTES) {
val = Math.floor(amount / 1024); val = Math.floor(amount / 1024);

View File

@@ -36,12 +36,12 @@ static const PRLogModuleInfo *gUrlClassifierPrefixSetLog = nullptr;
#define LOG_ENABLED() (false) #define LOG_ENABLED() (false)
#endif #endif
class PrefixSetReporter MOZ_FINAL : public MemoryReporterBase class PrefixSetReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
PrefixSetReporter(nsUrlClassifierPrefixSet* aPrefixSet, PrefixSetReporter(nsUrlClassifierPrefixSet* aPrefixSet,
const nsACString& aName) const nsACString& aName)
: MemoryReporterBase( : MemoryUniReporter(
nsPrintfCString( nsPrintfCString(
"explicit/storage/prefix-set/%s", "explicit/storage/prefix-set/%s",
(!aName.IsEmpty() ? PromiseFlatCString(aName).get() : "?!") (!aName.IsEmpty() ? PromiseFlatCString(aName).get() : "?!")

View File

@@ -325,37 +325,19 @@ CreateDIBSectionHook(HDC aDC,
return result; return result;
} }
class LowMemoryEventsVirtualReporter MOZ_FINAL : public MemoryReporterBase class LowMemoryEventsVirtualReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
// The description is "???" because we implement GetDescription().
LowMemoryEventsVirtualReporter() LowMemoryEventsVirtualReporter()
: MemoryReporterBase("low-memory-events/virtual", : MemoryUniReporter("low-memory-events/virtual",
KIND_OTHER, UNITS_COUNT_CUMULATIVE, "???") KIND_OTHER, UNITS_COUNT_CUMULATIVE,
"Number of low-virtual-memory events fired since startup. We fire such an "
"event if we notice there is less than memory.low_virtual_mem_threshold_mb of "
"virtual address space available (if zero, this behavior is disabled). The "
"process will probably crash if it runs out of virtual address space, so "
"this event is dire.")
{} {}
NS_IMETHOD GetDescription(nsACString &aDescription)
{
aDescription.AssignLiteral(
"Number of low-virtual-memory events fired since startup. ");
if (sLowVirtualMemoryThreshold == 0) {
aDescription.AppendLiteral(
"Tracking low-virtual-memory events is disabled, but you can enable it "
"by giving the memory.low_virtual_mem_threshold_mb pref a non-zero "
"value.");
}
else {
aDescription.Append(nsPrintfCString(
"We fire such an event if we notice there is less than %d MB of virtual "
"address space available (controlled by the "
"'memory.low_virtual_mem_threshold_mb' pref). We'll likely crash if "
"we run out of virtual address space, so this event is somewhat dire.",
sLowVirtualMemoryThreshold));
}
return NS_OK;
}
private: private:
int64_t Amount() MOZ_OVERRIDE int64_t Amount() MOZ_OVERRIDE
{ {
@@ -367,73 +349,36 @@ private:
} }
}; };
class LowCommitSpaceEventsReporter MOZ_FINAL : public MemoryReporterBase class LowCommitSpaceEventsReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
// The description is "???" because we implement GetDescription().
LowCommitSpaceEventsReporter() LowCommitSpaceEventsReporter()
: MemoryReporterBase("low-commit-space-events", : MemoryUniReporter("low-commit-space-events",
KIND_OTHER, UNITS_COUNT_CUMULATIVE, "???") KIND_OTHER, UNITS_COUNT_CUMULATIVE,
"Number of low-commit-space events fired since startup. We fire such an "
"event if we notice there is less than memory.low_commit_space_threshold_mb of "
"commit space available (if zero, this behavior is disabled). Windows will "
"likely kill the process if it runs out of commit space, so this event is "
"dire.")
{} {}
NS_IMETHOD GetDescription(nsACString &aDescription)
{
aDescription.AssignLiteral(
"Number of low-commit-space events fired since startup. ");
if (sLowCommitSpaceThreshold == 0) {
aDescription.Append(
"Tracking low-commit-space events is disabled, but you can enable it "
"by giving the memory.low_commit_space_threshold_mb pref a non-zero "
"value.");
}
else {
aDescription.Append(nsPrintfCString(
"We fire such an event if we notice there is less than %d MB of "
"available commit space (controlled by the "
"'memory.low_commit_space_threshold_mb' pref). Windows will likely "
"kill us if we run out of commit space, so this event is somewhat dire.",
sLowCommitSpaceThreshold));
}
return NS_OK;
}
private: private:
int64_t Amount() MOZ_OVERRIDE { return sNumLowCommitSpaceEvents; } int64_t Amount() MOZ_OVERRIDE { return sNumLowCommitSpaceEvents; }
}; };
class LowMemoryEventsPhysicalReporter MOZ_FINAL : public MemoryReporterBase class LowMemoryEventsPhysicalReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
// The description is "???" because we implement GetDescription().
LowMemoryEventsPhysicalReporter() LowMemoryEventsPhysicalReporter()
: MemoryReporterBase("low-memory-events/physical", : MemoryUniReporter("low-memory-events/physical",
KIND_OTHER, UNITS_COUNT_CUMULATIVE, "???") KIND_OTHER, UNITS_COUNT_CUMULATIVE,
"Number of low-physical-memory events fired since startup. We fire such an "
"event if we notice there is less than memory.low_physical_memory_threshold_mb "
"of physical memory available (if zero, this behavior is disabled). The "
"machine will start to page if it runs out of physical memory. This may "
"cause it to run slowly, but it shouldn't cause it to crash.")
{} {}
NS_IMETHOD GetDescription(nsACString &aDescription)
{
aDescription.AssignLiteral(
"Number of low-physical-memory events fired since startup. ");
if (sLowPhysicalMemoryThreshold == 0) {
aDescription.Append(
"Tracking low-physical-memory events is disabled, but you can enable it "
"by giving the memory.low_physical_memory_threshold_mb pref a non-zero "
"value.");
}
else {
aDescription.Append(nsPrintfCString(
"We fire such an event if we notice there is less than %d MB of "
"available physical memory (controlled by the "
"'memory.low_physical_memory_threshold_mb' pref). The machine will start "
"to page if it runs out of physical memory; this may cause it to run "
"slowly, but it shouldn't cause us to crash.",
sLowPhysicalMemoryThreshold));
}
return NS_OK;
}
private: private:
int64_t Amount() MOZ_OVERRIDE { return sNumLowPhysicalMemEvents; } int64_t Amount() MOZ_OVERRIDE { return sNumLowPhysicalMemEvents; }
}; };

View File

@@ -111,7 +111,7 @@ struct CategoriesSeen {
} // anonymous namespace } // anonymous namespace
class MapsReporter MOZ_FINAL : public nsIMemoryMultiReporter class MapsReporter MOZ_FINAL : public nsIMemoryReporter
{ {
public: public:
MapsReporter(); MapsReporter();
@@ -125,7 +125,7 @@ public:
} }
NS_IMETHOD NS_IMETHOD
CollectReports(nsIMemoryMultiReporterCallback *aCb, CollectReports(nsIMemoryReporterCallback *aCb,
nsISupports *aClosure); nsISupports *aClosure);
private: private:
@@ -135,7 +135,7 @@ private:
nsresult nsresult
ParseMapping(FILE *aFile, ParseMapping(FILE *aFile,
nsIMemoryMultiReporterCallback *aCb, nsIMemoryReporterCallback *aCb,
nsISupports *aClosure, nsISupports *aClosure,
CategoriesSeen *aCategoriesSeen); CategoriesSeen *aCategoriesSeen);
@@ -149,7 +149,7 @@ private:
ParseMapBody(FILE *aFile, ParseMapBody(FILE *aFile,
const nsACString &aName, const nsACString &aName,
const nsACString &aDescription, const nsACString &aDescription,
nsIMemoryMultiReporterCallback *aCb, nsIMemoryReporterCallback *aCb,
nsISupports *aClosure, nsISupports *aClosure,
CategoriesSeen *aCategoriesSeen); CategoriesSeen *aCategoriesSeen);
@@ -158,7 +158,7 @@ private:
nsTHashtable<nsCStringHashKey> mMozillaLibraries; nsTHashtable<nsCStringHashKey> mMozillaLibraries;
}; };
NS_IMPL_ISUPPORTS1(MapsReporter, nsIMemoryMultiReporter) NS_IMPL_ISUPPORTS1(MapsReporter, nsIMemoryReporter)
MapsReporter::MapsReporter() MapsReporter::MapsReporter()
: mSearchedForLibxul(false) : mSearchedForLibxul(false)
@@ -173,7 +173,7 @@ MapsReporter::MapsReporter()
} }
NS_IMETHODIMP NS_IMETHODIMP
MapsReporter::CollectReports(nsIMemoryMultiReporterCallback *aCb, MapsReporter::CollectReports(nsIMemoryReporterCallback *aCb,
nsISupports *aClosure) nsISupports *aClosure)
{ {
CategoriesSeen categoriesSeen; CategoriesSeen categoriesSeen;
@@ -258,7 +258,7 @@ MapsReporter::FindLibxul()
nsresult nsresult
MapsReporter::ParseMapping( MapsReporter::ParseMapping(
FILE *aFile, FILE *aFile,
nsIMemoryMultiReporterCallback *aCb, nsIMemoryReporterCallback *aCb,
nsISupports *aClosure, nsISupports *aClosure,
CategoriesSeen *aCategoriesSeen) CategoriesSeen *aCategoriesSeen)
{ {
@@ -461,7 +461,7 @@ MapsReporter::ParseMapBody(
FILE *aFile, FILE *aFile,
const nsACString &aName, const nsACString &aName,
const nsACString &aDescription, const nsACString &aDescription,
nsIMemoryMultiReporterCallback *aCb, nsIMemoryReporterCallback *aCb,
nsISupports *aClosure, nsISupports *aClosure,
CategoriesSeen *aCategoriesSeen) CategoriesSeen *aCategoriesSeen)
{ {
@@ -520,11 +520,11 @@ MapsReporter::ParseMapBody(
return NS_OK; return NS_OK;
} }
class ResidentUniqueReporter MOZ_FINAL : public MemoryReporterBase class ResidentUniqueReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
ResidentUniqueReporter() ResidentUniqueReporter()
: MemoryReporterBase("resident-unique", KIND_OTHER, UNITS_BYTES, : MemoryUniReporter("resident-unique", KIND_OTHER, UNITS_BYTES,
"Memory mapped by the process that is present in physical memory and not " "Memory mapped by the process that is present in physical memory and not "
"shared with any other processes. This is also known as the process's unique " "shared with any other processes. This is also known as the process's unique "
"set size (USS). This is the amount of RAM we'd expect to be freed if we " "set size (USS). This is the amount of RAM we'd expect to be freed if we "
@@ -540,9 +540,9 @@ private:
// little to do with whether the pages are actually shared. smaps on the // little to do with whether the pages are actually shared. smaps on the
// other hand appears to give us the correct information. // other hand appears to give us the correct information.
// //
// We could calculate this data during the smaps multi-reporter, but the // We could calculate this data within the smaps reporter, but the overhead
// overhead of the smaps reporter is considerable (we don't even run the // of the smaps reporter is considerable (we don't even run the smaps
// smaps reporter in normal about:memory operation). Hopefully this // reporter in normal about:memory operation). Hopefully this
// implementation is fast enough not to matter. // implementation is fast enough not to matter.
*aAmount = 0; *aAmount = 0;
@@ -568,8 +568,8 @@ private:
void Init() void Init()
{ {
nsCOMPtr<nsIMemoryMultiReporter> reporter = new MapsReporter(); nsCOMPtr<nsIMemoryReporter> reporter = new MapsReporter();
NS_RegisterMemoryMultiReporter(reporter); NS_RegisterMemoryReporter(reporter);
NS_RegisterMemoryReporter(new ResidentUniqueReporter()); NS_RegisterMemoryReporter(new ResidentUniqueReporter());
} }

View File

@@ -917,7 +917,7 @@ private:
CC_BeforeUnlinkCallback mBeforeUnlinkCB; CC_BeforeUnlinkCallback mBeforeUnlinkCB;
CC_ForgetSkippableCallback mForgetSkippableCB; CC_ForgetSkippableCallback mForgetSkippableCB;
nsCOMPtr<nsIMemoryMultiReporter> mReporter; nsCOMPtr<nsIMemoryReporter> mReporter;
nsPurpleBuffer mPurpleBuf; nsPurpleBuffer mPurpleBuf;
@@ -2398,10 +2398,10 @@ nsCycleCollector::CollectWhite(nsICycleCollectorListener *aListener)
// Memory reporter // Memory reporter
//////////////////////// ////////////////////////
class CycleCollectorMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter class CycleCollectorReporter MOZ_FINAL : public nsIMemoryReporter
{ {
public: public:
CycleCollectorMultiReporter(nsCycleCollector* aCollector) CycleCollectorReporter(nsCycleCollector* aCollector)
: mCollector(aCollector) : mCollector(aCollector)
{} {}
@@ -2413,7 +2413,7 @@ class CycleCollectorMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter
return NS_OK; return NS_OK;
} }
NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback* aCb, NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCb,
nsISupports* aClosure) nsISupports* aClosure)
{ {
size_t objectSize, graphNodesSize, graphEdgesSize, whiteNodesSize, size_t objectSize, graphNodesSize, graphEdgesSize, whiteNodesSize,
@@ -2465,7 +2465,7 @@ class CycleCollectorMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter
nsCycleCollector* mCollector; nsCycleCollector* mCollector;
}; };
NS_IMPL_ISUPPORTS1(CycleCollectorMultiReporter, nsIMemoryMultiReporter) NS_IMPL_ISUPPORTS1(CycleCollectorReporter, nsIMemoryReporter)
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@@ -2492,7 +2492,7 @@ nsCycleCollector::nsCycleCollector() :
nsCycleCollector::~nsCycleCollector() nsCycleCollector::~nsCycleCollector()
{ {
NS_UnregisterMemoryMultiReporter(mReporter); NS_UnregisterMemoryReporter(mReporter);
} }
void void
@@ -2508,7 +2508,7 @@ nsCycleCollector::RegisterJSRuntime(CycleCollectedJSRuntime *aJSRuntime)
// instead. // instead.
static bool registered = false; static bool registered = false;
if (!registered) { if (!registered) {
NS_RegisterMemoryMultiReporter(new CycleCollectorMultiReporter(this)); NS_RegisterMemoryReporter(new CycleCollectorReporter(this));
registered = true; registered = true;
} }
} }

View File

@@ -17,55 +17,22 @@ interface nsICancelableRunnable;
* reporter. * reporter.
*/ */
/* [scriptable, function, uuid(3a61be3b-b93b-461a-a4f8-388214f558b1)]
* An nsIMemoryReporter reports a single memory measurement as an object. interface nsIMemoryReporterCallback : nsISupports
* Use this when it makes sense to gather this measurement without gathering
* related measurements at the same time.
*
* Note that the |amount| field may be implemented as a function, and so
* accessing it can trigger significant computation; the other fields can
* be accessed without triggering this computation. (Compare and contrast
* this with nsIMemoryMultiReporter.)
*
* aboutMemory.js is the most important consumer of memory reports. It
* places the following constraints on reports.
*
* - There must be an "explicit" tree. It represents non-overlapping
* regions of memory that have been explicitly allocated with an
* OS-level allocation (e.g. mmap/VirtualAlloc/vm_allocate) or a
* heap-level allocation (e.g. malloc/calloc/operator new). Reporters
* in this tree must have kind HEAP or NONHEAP, units BYTES, and a
* description that is a sentence (i.e. starts with a capital letter and
* ends with a period, or similar).
*
* - The "size", "rss", "pss" and "swap" trees are optional. They
* represent regions of virtual memory that the process has mapped.
* Reporters in this category must have kind NONHEAP, units BYTES, and a
* non-empty description.
*
* - The "compartments" and "ghost-windows" trees are optional. They are
* used by about:compartments. Reporters in these trees must have kind
* OTHER, units COUNT, an amount of 1, and a description that's an empty
* string.
*
* - All other reports are unconstrained except that they must have a
* description that is a sentence.
*/
[scriptable, uuid(b2c39f65-1799-4b92-a806-ab3cf6af3cfa)]
interface nsIMemoryReporter : nsISupports
{ {
/* /*
* The name of the process containing this reporter. Each reporter initially * The arguments to the callback are as follows.
* has "" in this field, indicating that it applies to the current process. *
* (This is true even for reporters in a child process.) When a reporter *
* from a child process is copied into the main process, the copy has its * |process| The name of the process containing this reporter. Each
* 'process' field set appropriately. * reporter initially has "" in this field, indicating that it applies to the
*/ * current process. (This is true even for reporters in a child process.)
readonly attribute ACString process; * When a reporter from a child process is copied into the main process, the
* copy has its 'process' field set appropriately.
/* *
* The path that this memory usage should be reported under. Paths are *
* '/'-delimited, eg. "a/b/c". * |path| The path that this memory usage should be reported under. Paths
* are '/'-delimited, eg. "a/b/c".
* *
* Each reporter can be viewed as representing a leaf node in a tree. * Each reporter can be viewed as representing a leaf node in a tree.
* Internal nodes of the tree don't have reporters. So, for example, the * Internal nodes of the tree don't have reporters. So, for example, the
@@ -98,11 +65,9 @@ interface nsIMemoryReporter : nsISupports
* *
* The paths of all reporters form a set of trees. Trees can be * The paths of all reporters form a set of trees. Trees can be
* "degenerate", i.e. contain a single entry with no '/'. * "degenerate", i.e. contain a single entry with no '/'.
*/ *
readonly attribute AUTF8String path; *
* |kind| There are three kinds of memory reporters.
/*
* There are three kinds of memory reporters.
* *
* - HEAP: reporters measuring memory allocated by the heap allocator, * - HEAP: reporters measuring memory allocated by the heap allocator,
* e.g. by calling malloc, calloc, realloc, memalign, operator new, or * e.g. by calling malloc, calloc, realloc, memalign, operator new, or
@@ -120,19 +85,9 @@ interface nsIMemoryReporter : nsISupports
* *
* The kind only matters for reporters in the "explicit" tree; * The kind only matters for reporters in the "explicit" tree;
* aboutMemory.js uses it to calculate "heap-unclassified". * aboutMemory.js uses it to calculate "heap-unclassified".
*/ *
const int32_t KIND_NONHEAP = 0; *
const int32_t KIND_HEAP = 1; * |units| The units on the reporter's amount. One of the following.
const int32_t KIND_OTHER = 2;
/*
* The reporter kind. See KIND_* above.
*/
readonly attribute int32_t kind;
/*
* The amount reported by a memory reporter must have one of the following
* units, but you may of course add new units as necessary:
* *
* - BYTES: The amount contains a number of bytes. * - BYTES: The amount contains a number of bytes.
* *
@@ -156,67 +111,84 @@ interface nsIMemoryReporter : nsISupports
* be 1234. * be 1234.
* *
* Values greater than 100% are allowed. * Values greater than 100% are allowed.
*
*
* |amount| The numeric value reported by this memory reporter. Accesses
* can fail if something goes wrong when getting the amount.
*
*
* |description| A human-readable description of this memory usage report.
*/ */
const int32_t UNITS_BYTES = 0;
const int32_t UNITS_COUNT = 1;
const int32_t UNITS_COUNT_CUMULATIVE = 2;
const int32_t UNITS_PERCENTAGE = 3;
/*
* The units on the reporter's amount. See UNITS_* above.
*/
readonly attribute int32_t units;
/*
* The numeric value reported by this memory reporter. Accesses can fail if
* something goes wrong when getting the amount.
*/
readonly attribute int64_t amount;
/*
* A human-readable description of this memory usage report.
*/
readonly attribute AUTF8String description;
};
[scriptable, function, uuid(5b15f3fa-ba15-443c-8337-7770f5f0ce5d)]
interface nsIMemoryMultiReporterCallback : nsISupports
{
void callback(in ACString process, in AUTF8String path, in int32_t kind, void callback(in ACString process, in AUTF8String path, in int32_t kind,
in int32_t units, in int64_t amount, in int32_t units, in int64_t amount,
in AUTF8String description, in nsISupports closure); in AUTF8String description, in nsISupports closure);
}; };
/* /*
* An nsIMemoryMultiReporter reports multiple memory measurements via a * An nsIMemoryReporter reports one or more memory measurements via a
* callback function which is called once for each measurement. Use this * callback function which is called once for each measurement.
* when you want to gather multiple measurements in a single operation (eg.
* a single traversal of a large data structure).
* *
* The arguments to the callback deliberately match the fields in * An nsIMemoryReporter that reports a single measurement is sometimes called a
* nsIMemoryReporter, but note that seeing any of these arguments requires * "uni-reporter". One that reports multiple measurements is sometimes called
* calling collectReports which will trigger all relevant computation. * a "multi-reporter".
* (Compare and contrast this with nsIMemoryReporter, which allows all *
* fields except |amount| to be accessed without triggering computation.) * aboutMemory.js is the most important consumer of memory reports. It
* places the following constraints on reports.
*
* - There must be an "explicit" tree. It represents non-overlapping
* regions of memory that have been explicitly allocated with an
* OS-level allocation (e.g. mmap/VirtualAlloc/vm_allocate) or a
* heap-level allocation (e.g. malloc/calloc/operator new). Reporters
* in this tree must have kind HEAP or NONHEAP, units BYTES, and a
* description that is a sentence (i.e. starts with a capital letter and
* ends with a period, or similar).
*
* - The "size", "rss", "pss" and "swap" trees are optional. They
* represent regions of virtual memory that the process has mapped.
* Reporters in this category must have kind NONHEAP, units BYTES, and a
* non-empty description.
*
* - The "compartments" and "ghost-windows" trees are optional. They are
* used by about:compartments. Reporters in these trees must have kind
* OTHER, units COUNT, an amount of 1, and a description that's an empty
* string.
*
* - All other reports are unconstrained except that they must have a
* description that is a sentence.
*/ */
[scriptable, uuid(24d61ead-237b-4969-a6bd-73fd8fed1d99)] [scriptable, uuid(53248304-124b-43cd-99dc-6e5797b91618)]
interface nsIMemoryMultiReporter : nsISupports interface nsIMemoryReporter : nsISupports
{ {
/* /*
* The name of the multi-reporter. Useful when only one multi-reporter * The name of the reporter. Useful when only one reporter needs to be run.
* needs to be run. Must be unique; if multi-reporters share names it's * Must be unique; if reporters share names it's likely the wrong one will
* likely the wrong one will be called in certain circumstances. * be called in certain circumstances.
*/ */
readonly attribute ACString name; readonly attribute ACString name;
/* /*
* Run the multi-reporter. * Run the reporter.
*/ */
void collectReports(in nsIMemoryMultiReporterCallback callback, void collectReports(in nsIMemoryReporterCallback callback,
in nsISupports closure); in nsISupports closure);
/*
* Kinds. See the |kind| comment in nsIMemoryReporterCallback.
*/
const int32_t KIND_NONHEAP = 0;
const int32_t KIND_HEAP = 1;
const int32_t KIND_OTHER = 2;
/*
* Units. See the |units| comment in nsIMemoryReporterCallback.
*/
const int32_t UNITS_BYTES = 0;
const int32_t UNITS_COUNT = 1;
const int32_t UNITS_COUNT_CUMULATIVE = 2;
const int32_t UNITS_PERCENTAGE = 3;
}; };
[scriptable, builtinclass, uuid(70b0e608-8dbf-4dc7-b88f-f1c745c1b48c)] [scriptable, builtinclass, uuid(4db7040a-16f9-4249-879b-fe72729c7ef5)]
interface nsIMemoryReporterManager : nsISupports interface nsIMemoryReporterManager : nsISupports
{ {
/* /*
@@ -224,12 +196,6 @@ interface nsIMemoryReporterManager : nsISupports
*/ */
nsISimpleEnumerator enumerateReporters (); nsISimpleEnumerator enumerateReporters ();
/*
* Return an enumerator of nsIMemoryMultiReporters that are currently
* registered.
*/
nsISimpleEnumerator enumerateMultiReporters ();
/* /*
* Register the given nsIMemoryReporter. After a reporter is registered, * Register the given nsIMemoryReporter. After a reporter is registered,
* it will be available via enumerateReporters(). The Manager service * it will be available via enumerateReporters(). The Manager service
@@ -237,31 +203,17 @@ interface nsIMemoryReporterManager : nsISupports
*/ */
void registerReporter (in nsIMemoryReporter reporter); void registerReporter (in nsIMemoryReporter reporter);
/*
* Register the given nsIMemoryMultiReporter. After a multi-reporter is
* registered, it will be available via enumerateMultiReporters(). The
* Manager service will hold a strong reference to the given
* multi-reporter.
*/
void registerMultiReporter (in nsIMemoryMultiReporter reporter);
/* /*
* Unregister the given memory reporter. * Unregister the given memory reporter.
*/ */
void unregisterReporter (in nsIMemoryReporter reporter); void unregisterReporter (in nsIMemoryReporter reporter);
/*
* Unregister the given memory multi-reporter.
*/
void unregisterMultiReporter (in nsIMemoryMultiReporter reporter);
/** /**
* These functions should only be used for testing purposes. * These functions should only be used for testing purposes.
*/ */
void blockRegistration(); void blockRegistration();
void unblockRegistration(); void unblockRegistration();
void registerReporterEvenIfBlocked(in nsIMemoryReporter aReporter); void registerReporterEvenIfBlocked(in nsIMemoryReporter aReporter);
void registerMultiReporterEvenIfBlocked(in nsIMemoryMultiReporter aReporter);
/* /*
* Initialize. * Initialize.
@@ -280,8 +232,8 @@ interface nsIMemoryReporterManager : nsISupports
* (eg. via mmap, VirtualAlloc) and at the heap level (eg. via malloc, * (eg. via mmap, VirtualAlloc) and at the heap level (eg. via malloc,
* calloc, operator new). (Nb: it covers all heap allocations, but will * calloc, operator new). (Nb: it covers all heap allocations, but will
* miss any OS-level ones not covered by memory reporters.) This reporter * miss any OS-level ones not covered by memory reporters.) This reporter
* is special-cased because it's interesting, and is moderately difficult * is special-cased because it's interesting, and is difficult to compute
* to compute in JS. Accesses can fail. * from JavaScript code. Accesses can fail.
*/ */
readonly attribute int64_t explicit; readonly attribute int64_t explicit;
@@ -307,10 +259,7 @@ interface nsIMemoryReporterManager : nsISupports
// instead of nsCOMPtr<nsIMemoryReporter>. // instead of nsCOMPtr<nsIMemoryReporter>.
XPCOM_API(nsresult) NS_RegisterMemoryReporter(nsIMemoryReporter* aReporter); XPCOM_API(nsresult) NS_RegisterMemoryReporter(nsIMemoryReporter* aReporter);
XPCOM_API(nsresult) NS_RegisterMemoryMultiReporter(nsIMemoryMultiReporter* aReporter);
XPCOM_API(nsresult) NS_UnregisterMemoryReporter(nsIMemoryReporter* aReporter); XPCOM_API(nsresult) NS_UnregisterMemoryReporter(nsIMemoryReporter* aReporter);
XPCOM_API(nsresult) NS_UnregisterMemoryMultiReporter(nsIMemoryMultiReporter* aReporter);
#if defined(MOZ_DMD) #if defined(MOZ_DMD)
namespace mozilla { namespace mozilla {
@@ -375,10 +324,11 @@ void RunReporters();
namespace mozilla { namespace mozilla {
// The following base class reduces the amount of boilerplate code required for // The following base class reduces the amount of boilerplate code required for
// memory reporters. You just need to provide the following. // memory uni-reporters. You just need to provide the following.
// - The constant values: path, kind, units, and description. They are passed // - The constant values: nameAndPath (which serves as both the reporters name,
// to the MemoryReporterBase constructor. // and the path in its single report), kind, units, and description. They
// - A (private) Amount() or (public) GetAmount() method. It can use the // are passed to the MemoryUniReporter constructor.
// - A (private) Amount() or (public) GetAmount() method. It can use the
// MallocSizeOf method if necessary. (There is also // MallocSizeOf method if necessary. (There is also
// MallocSizeOfOn{Alloc,Free}, which can be useful.) Use Amount() if the // MallocSizeOfOn{Alloc,Free}, which can be useful.) Use Amount() if the
// reporter is infallible, and GetAmount() otherwise. (If you fail to // reporter is infallible, and GetAmount() otherwise. (If you fail to
@@ -390,58 +340,45 @@ namespace mozilla {
// - "explicit/dom/xyzzy" --> DOMXyzzyReporter // - "explicit/dom/xyzzy" --> DOMXyzzyReporter
// - "js-compartments/system" --> JSCompartmentsSystemReporter // - "js-compartments/system" --> JSCompartmentsSystemReporter
// //
class MemoryReporterBase : public nsIMemoryReporter class MemoryUniReporter : public nsIMemoryReporter
{ {
public: public:
MemoryReporterBase(const char* aPath, int32_t aKind, int32_t aUnits, MemoryUniReporter(const char* aNameAndPath, int32_t aKind, int32_t aUnits,
const char* aDescription) const char* aDescription)
: mPath(aPath) : mNameAndPath(aNameAndPath)
, mKind(aKind) , mKind(aKind)
, mUnits(aUnits) , mUnits(aUnits)
, mDescription(aDescription) , mDescription(aDescription)
{} {}
virtual ~MemoryReporterBase() {} virtual ~MemoryUniReporter() {}
NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_THREADSAFE_ISUPPORTS
NS_IMETHOD GetProcess(nsACString& aProcess) NS_IMETHOD GetName(nsACString& aName)
{ {
aProcess.Truncate(); aName.Assign(mNameAndPath);
return NS_OK; return NS_OK;
} }
NS_IMETHOD GetPath(nsACString& aPath) NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCallback,
nsISupports* aClosure)
{ {
aPath.Assign(mPath); int64_t amount;
return NS_OK; nsresult rv = GetAmount(&amount);
} NS_ENSURE_SUCCESS(rv, rv);
NS_IMETHOD GetKind(int32_t* aKind) return aCallback->Callback(EmptyCString(), mNameAndPath, mKind, mUnits,
{ amount, mDescription, aClosure);
*aKind = mKind;
return NS_OK;
}
NS_IMETHOD GetUnits(int32_t* aUnits)
{
*aUnits = mUnits;
return NS_OK;
} }
protected:
NS_IMETHOD GetAmount(int64_t* aAmount) NS_IMETHOD GetAmount(int64_t* aAmount)
{ {
*aAmount = Amount(); *aAmount = Amount();
return NS_OK; return NS_OK;
} }
NS_IMETHOD GetDescription(nsACString& aDescription)
{
aDescription.Assign(mDescription);
return NS_OK;
}
protected:
virtual int64_t Amount() virtual int64_t Amount()
{ {
// We only reach here if neither GetAmount() nor Amount() was overridden. // We only reach here if neither GetAmount() nor Amount() was overridden.
@@ -453,7 +390,7 @@ protected:
NS_MEMORY_REPORTER_MALLOC_SIZEOF_ON_ALLOC_FUN(MallocSizeOfOnAlloc) NS_MEMORY_REPORTER_MALLOC_SIZEOF_ON_ALLOC_FUN(MallocSizeOfOnAlloc)
NS_MEMORY_REPORTER_MALLOC_SIZEOF_ON_FREE_FUN(MallocSizeOfOnFree) NS_MEMORY_REPORTER_MALLOC_SIZEOF_ON_FREE_FUN(MallocSizeOfOnFree)
const nsCString mPath; const nsCString mNameAndPath;
const int32_t mKind; const int32_t mKind;
const int32_t mUnits; const int32_t mUnits;
const nsCString mDescription; const nsCString mDescription;

View File

@@ -672,32 +672,35 @@ DumpReport(nsIGZFileWriter *aWriter, bool aIsFirst,
return NS_OK; return NS_OK;
} }
class DumpMultiReporterCallback MOZ_FINAL : public nsIMemoryMultiReporterCallback class DumpReporterCallback MOZ_FINAL : public nsIMemoryReporterCallback
{ {
public: public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_IMETHOD Callback(const nsACString &aProcess, const nsACString &aPath, DumpReporterCallback(bool* aIsFirstPtr) : mIsFirstPtr(aIsFirstPtr) {}
int32_t aKind, int32_t aUnits, int64_t aAmount,
const nsACString &aDescription,
nsISupports *aData)
{
nsCOMPtr<nsIGZFileWriter> writer = do_QueryInterface(aData);
NS_ENSURE_TRUE(writer, NS_ERROR_FAILURE);
// The |isFirst = false| assumes that at least one single reporter is NS_IMETHOD Callback(const nsACString &aProcess, const nsACString &aPath,
// present and so will have been processed in int32_t aKind, int32_t aUnits, int64_t aAmount,
// DumpProcessMemoryReportsToGZFileWriter() below. const nsACString &aDescription,
return DumpReport(writer, /* isFirst = */ false, aProcess, aPath, nsISupports *aData)
aKind, aUnits, aAmount, aDescription); {
return NS_OK; nsCOMPtr<nsIGZFileWriter> writer = do_QueryInterface(aData);
} NS_ENSURE_TRUE(writer, NS_ERROR_FAILURE);
// The |isFirst = false| assumes that at least one single reporter is
// present and so will have been processed in
// DumpProcessMemoryReportsToGZFileWriter() below.
bool isFirst = *mIsFirstPtr;
*mIsFirstPtr = false;
return DumpReport(writer, isFirst, aProcess, aPath, aKind, aUnits, aAmount,
aDescription);
}
private:
bool* mIsFirstPtr;
}; };
NS_IMPL_ISUPPORTS1( NS_IMPL_ISUPPORTS1(DumpReporterCallback, nsIMemoryReporterCallback)
DumpMultiReporterCallback
, nsIMemoryMultiReporterCallback
)
} // namespace mozilla } // namespace mozilla
@@ -795,8 +798,6 @@ DMDWrite(void* aState, const char* aFmt, va_list ap)
static nsresult static nsresult
DumpProcessMemoryReportsToGZFileWriter(nsIGZFileWriter *aWriter) DumpProcessMemoryReportsToGZFileWriter(nsIGZFileWriter *aWriter)
{ {
nsresult rv;
// Increment this number if the format changes. // Increment this number if the format changes.
// //
// This is the first write to the file, and it causes |aWriter| to allocate // This is the first write to the file, and it causes |aWriter| to allocate
@@ -814,53 +815,15 @@ DumpProcessMemoryReportsToGZFileWriter(nsIGZFileWriter *aWriter)
DUMP(aWriter, ",\n"); DUMP(aWriter, ",\n");
DUMP(aWriter, " \"reports\": "); DUMP(aWriter, " \"reports\": ");
// Process single reporters. // Process reporters.
bool isFirst = true; bool isFirst = true;
bool more; bool more;
nsCOMPtr<nsISimpleEnumerator> e; nsCOMPtr<nsISimpleEnumerator> e;
mgr->EnumerateReporters(getter_AddRefs(e)); mgr->EnumerateReporters(getter_AddRefs(e));
nsRefPtr<DumpReporterCallback> cb = new DumpReporterCallback(&isFirst);
while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) { while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) {
nsCOMPtr<nsIMemoryReporter> r; nsCOMPtr<nsIMemoryReporter> r;
e->GetNext(getter_AddRefs(r)); e->GetNext(getter_AddRefs(r));
nsCString process;
rv = r->GetProcess(process);
NS_ENSURE_SUCCESS(rv, rv);
nsCString path;
rv = r->GetPath(path);
NS_ENSURE_SUCCESS(rv, rv);
int32_t kind;
rv = r->GetKind(&kind);
NS_ENSURE_SUCCESS(rv, rv);
int32_t units;
rv = r->GetUnits(&units);
NS_ENSURE_SUCCESS(rv, rv);
int64_t amount;
rv = r->GetAmount(&amount);
NS_ENSURE_SUCCESS(rv, rv);
nsCString description;
rv = r->GetDescription(description);
NS_ENSURE_SUCCESS(rv, rv);
rv = DumpReport(aWriter, isFirst, process, path, kind, units, amount,
description);
NS_ENSURE_SUCCESS(rv, rv);
isFirst = false;
}
// Process multi-reporters.
nsCOMPtr<nsISimpleEnumerator> e2;
mgr->EnumerateMultiReporters(getter_AddRefs(e2));
nsRefPtr<DumpMultiReporterCallback> cb = new DumpMultiReporterCallback();
while (NS_SUCCEEDED(e2->HasMoreElements(&more)) && more) {
nsCOMPtr<nsIMemoryMultiReporter> r;
e2->GetNext(getter_AddRefs(r));
r->CollectReports(cb, aWriter); r->CollectReports(cb, aWriter);
} }

View File

@@ -327,11 +327,11 @@ static nsresult GetResidentFast(int64_t* aN)
} }
#define HAVE_PRIVATE_REPORTER #define HAVE_PRIVATE_REPORTER
class PrivateReporter MOZ_FINAL : public MemoryReporterBase class PrivateReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
PrivateReporter() PrivateReporter()
: MemoryReporterBase("private", KIND_OTHER, UNITS_BYTES, : MemoryUniReporter("private", KIND_OTHER, UNITS_BYTES,
"Memory that cannot be shared with other processes, including memory that is " "Memory that cannot be shared with other processes, including memory that is "
"committed and marked MEM_PRIVATE, data that is not mapped, and executable " "committed and marked MEM_PRIVATE, data that is not mapped, and executable "
"pages that have been written to.") "pages that have been written to.")
@@ -356,11 +356,11 @@ public:
#endif // XP_<PLATFORM> #endif // XP_<PLATFORM>
#ifdef HAVE_VSIZE_AND_RESIDENT_REPORTERS #ifdef HAVE_VSIZE_AND_RESIDENT_REPORTERS
class VsizeReporter MOZ_FINAL : public MemoryReporterBase class VsizeReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
VsizeReporter() VsizeReporter()
: MemoryReporterBase("vsize", KIND_OTHER, UNITS_BYTES, : MemoryUniReporter("vsize", KIND_OTHER, UNITS_BYTES,
"Memory mapped by the process, including code and data segments, the heap, " "Memory mapped by the process, including code and data segments, the heap, "
"thread stacks, memory explicitly mapped by the process via mmap and similar " "thread stacks, memory explicitly mapped by the process via mmap and similar "
"operations, and memory shared with other processes. This is the vsize figure " "operations, and memory shared with other processes. This is the vsize figure "
@@ -373,11 +373,11 @@ public:
NS_IMETHOD GetAmount(int64_t* aAmount) { return GetVsize(aAmount); } NS_IMETHOD GetAmount(int64_t* aAmount) { return GetVsize(aAmount); }
}; };
class ResidentReporter MOZ_FINAL : public MemoryReporterBase class ResidentReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
ResidentReporter() ResidentReporter()
: MemoryReporterBase("resident", KIND_OTHER, UNITS_BYTES, : MemoryUniReporter("resident", KIND_OTHER, UNITS_BYTES,
"Memory mapped by the process that is present in physical memory, also known " "Memory mapped by the process that is present in physical memory, also known "
"as the resident set size (RSS). This is the best single figure to use when " "as the resident set size (RSS). This is the best single figure to use when "
"considering the memory resources used by the process, but it depends both on " "considering the memory resources used by the process, but it depends both on "
@@ -389,11 +389,11 @@ public:
NS_IMETHOD GetAmount(int64_t* aAmount) { return GetResident(aAmount); } NS_IMETHOD GetAmount(int64_t* aAmount) { return GetResident(aAmount); }
}; };
class ResidentFastReporter MOZ_FINAL : public MemoryReporterBase class ResidentFastReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
ResidentFastReporter() ResidentFastReporter()
: MemoryReporterBase("resident-fast", KIND_OTHER, UNITS_BYTES, : MemoryUniReporter("resident-fast", KIND_OTHER, UNITS_BYTES,
"This is the same measurement as 'resident', but it tries to be as fast as " "This is the same measurement as 'resident', but it tries to be as fast as "
"possible at the expense of accuracy. On most platforms this is identical to " "possible at the expense of accuracy. On most platforms this is identical to "
"the 'resident' measurement, but on Mac it may over-count. You should use " "the 'resident' measurement, but on Mac it may over-count. You should use "
@@ -412,11 +412,11 @@ public:
#define HAVE_PAGE_FAULT_REPORTERS 1 #define HAVE_PAGE_FAULT_REPORTERS 1
class PageFaultsSoftReporter MOZ_FINAL : public MemoryReporterBase class PageFaultsSoftReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
PageFaultsSoftReporter() PageFaultsSoftReporter()
: MemoryReporterBase("page-faults-soft", KIND_OTHER, : MemoryUniReporter("page-faults-soft", KIND_OTHER,
UNITS_COUNT_CUMULATIVE, UNITS_COUNT_CUMULATIVE,
"The number of soft page faults (also known as 'minor page faults') that " "The number of soft page faults (also known as 'minor page faults') that "
"have occurred since the process started. A soft page fault occurs when the " "have occurred since the process started. A soft page fault occurs when the "
@@ -441,11 +441,11 @@ public:
} }
}; };
class PageFaultsHardReporter MOZ_FINAL : public MemoryReporterBase class PageFaultsHardReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
PageFaultsHardReporter() PageFaultsHardReporter()
: MemoryReporterBase("page-faults-hard", KIND_OTHER, : MemoryUniReporter("page-faults-hard", KIND_OTHER,
UNITS_COUNT_CUMULATIVE, UNITS_COUNT_CUMULATIVE,
"The number of hard page faults (also known as 'major page faults') that have " "The number of hard page faults (also known as 'major page faults') that have "
"occurred since the process started. A hard page fault occurs when a process " "occurred since the process started. A hard page fault occurs when a process "
@@ -479,11 +479,11 @@ public:
#ifdef HAVE_JEMALLOC_STATS #ifdef HAVE_JEMALLOC_STATS
class HeapAllocatedReporter MOZ_FINAL : public MemoryReporterBase class HeapAllocatedReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
HeapAllocatedReporter() HeapAllocatedReporter()
: MemoryReporterBase("heap-allocated", KIND_OTHER, UNITS_BYTES, : MemoryUniReporter("heap-allocated", KIND_OTHER, UNITS_BYTES,
"Memory mapped by the heap allocator that is currently allocated to the " "Memory mapped by the heap allocator that is currently allocated to the "
"application. This may exceed the amount of memory requested by the " "application. This may exceed the amount of memory requested by the "
"application because the allocator regularly rounds up request sizes. (The " "application because the allocator regularly rounds up request sizes. (The "
@@ -498,14 +498,14 @@ private:
} }
}; };
class HeapOverheadWasteReporter MOZ_FINAL : public MemoryReporterBase class HeapOverheadWasteReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
// We mark this and the other heap-overhead reporters as KIND_NONHEAP // We mark this and the other heap-overhead reporters as KIND_NONHEAP
// because KIND_HEAP memory means "counted in heap-allocated", which this // because KIND_HEAP memory means "counted in heap-allocated", which this
// is not. // is not.
HeapOverheadWasteReporter() HeapOverheadWasteReporter()
: MemoryReporterBase("explicit/heap-overhead/waste", : MemoryUniReporter("explicit/heap-overhead/waste",
KIND_NONHEAP, UNITS_BYTES, KIND_NONHEAP, UNITS_BYTES,
"Committed bytes which do not correspond to an active allocation and which the " "Committed bytes which do not correspond to an active allocation and which the "
"allocator is not intentionally keeping alive (i.e., not 'heap-bookkeeping' or " "allocator is not intentionally keeping alive (i.e., not 'heap-bookkeeping' or "
@@ -522,11 +522,11 @@ private:
} }
}; };
class HeapOverheadBookkeepingReporter MOZ_FINAL : public MemoryReporterBase class HeapOverheadBookkeepingReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
HeapOverheadBookkeepingReporter() HeapOverheadBookkeepingReporter()
: MemoryReporterBase("explicit/heap-overhead/bookkeeping", : MemoryUniReporter("explicit/heap-overhead/bookkeeping",
KIND_NONHEAP, UNITS_BYTES, KIND_NONHEAP, UNITS_BYTES,
"Committed bytes which the heap allocator uses for internal data structures.") "Committed bytes which the heap allocator uses for internal data structures.")
{} {}
@@ -539,11 +539,11 @@ private:
} }
}; };
class HeapOverheadPageCacheReporter MOZ_FINAL : public MemoryReporterBase class HeapOverheadPageCacheReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
HeapOverheadPageCacheReporter() HeapOverheadPageCacheReporter()
: MemoryReporterBase("explicit/heap-overhead/page-cache", : MemoryUniReporter("explicit/heap-overhead/page-cache",
KIND_NONHEAP, UNITS_BYTES, KIND_NONHEAP, UNITS_BYTES,
"Memory which the allocator could return to the operating system, but hasn't. " "Memory which the allocator could return to the operating system, but hasn't. "
"The allocator keeps this memory around as an optimization, so it doesn't " "The allocator keeps this memory around as an optimization, so it doesn't "
@@ -559,11 +559,11 @@ private:
} }
}; };
class HeapCommittedReporter MOZ_FINAL : public MemoryReporterBase class HeapCommittedReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
HeapCommittedReporter() HeapCommittedReporter()
: MemoryReporterBase("heap-committed", KIND_OTHER, UNITS_BYTES, : MemoryUniReporter("heap-committed", KIND_OTHER, UNITS_BYTES,
"Memory mapped by the heap allocator that is committed, i.e. in physical " "Memory mapped by the heap allocator that is committed, i.e. in physical "
"memory or paged to disk. This value corresponds to 'heap-allocated' + " "memory or paged to disk. This value corresponds to 'heap-allocated' + "
"'heap-waste' + 'heap-bookkeeping' + 'heap-page-cache', but because " "'heap-waste' + 'heap-bookkeeping' + 'heap-page-cache', but because "
@@ -580,11 +580,11 @@ private:
} }
}; };
class HeapOverheadRatioReporter MOZ_FINAL : public MemoryReporterBase class HeapOverheadRatioReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
HeapOverheadRatioReporter() HeapOverheadRatioReporter()
: MemoryReporterBase("heap-overhead-ratio", KIND_OTHER, : MemoryUniReporter("heap-overhead-ratio", KIND_OTHER,
UNITS_PERCENTAGE, UNITS_PERCENTAGE,
"Ratio of committed, unused bytes to allocated bytes; i.e., " "Ratio of committed, unused bytes to allocated bytes; i.e., "
"'heap-overhead' / 'heap-allocated'. This measures the overhead of " "'heap-overhead' / 'heap-allocated'. This measures the overhead of "
@@ -607,11 +607,11 @@ private:
// However, the obvious time to register it is when the table is initialized, // However, the obvious time to register it is when the table is initialized,
// and that happens before XPCOM components are initialized, which means the // and that happens before XPCOM components are initialized, which means the
// NS_RegisterMemoryReporter call fails. So instead we do it here. // NS_RegisterMemoryReporter call fails. So instead we do it here.
class AtomTablesReporter MOZ_FINAL : public MemoryReporterBase class AtomTablesReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
AtomTablesReporter() AtomTablesReporter()
: MemoryReporterBase("explicit/atom-tables", KIND_HEAP, UNITS_BYTES, : MemoryUniReporter("explicit/atom-tables", KIND_HEAP, UNITS_BYTES,
"Memory used by the dynamic and static atoms tables.") "Memory used by the dynamic and static atoms tables.")
{} {}
private: private:
@@ -623,10 +623,10 @@ private:
namespace mozilla { namespace mozilla {
namespace dmd { namespace dmd {
class DMDMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter class DMDReporter MOZ_FINAL : public nsIMemoryReporter
{ {
public: public:
DMDMultiReporter() DMDReporter()
{} {}
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
@@ -637,7 +637,7 @@ public:
return NS_OK; return NS_OK;
} }
NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback* aCallback, NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCallback,
nsISupports* aClosure) nsISupports* aClosure)
{ {
dmd::Sizes sizes; dmd::Sizes sizes;
@@ -677,7 +677,7 @@ public:
} }
}; };
NS_IMPL_ISUPPORTS1(DMDMultiReporter, nsIMemoryMultiReporter) NS_IMPL_ISUPPORTS1(DMDReporter, nsIMemoryReporter)
} // namespace dmd } // namespace dmd
} // namespace mozilla } // namespace mozilla
@@ -725,7 +725,7 @@ nsMemoryReporterManager::Init()
RegisterReporter(new AtomTablesReporter); RegisterReporter(new AtomTablesReporter);
#ifdef MOZ_DMD #ifdef MOZ_DMD
RegisterMultiReporter(new mozilla::dmd::DMDMultiReporter); RegisterReporter(new mozilla::dmd::DMDReporter);
#endif #endif
#if defined(XP_LINUX) #if defined(XP_LINUX)
@@ -803,7 +803,6 @@ nsMemoryReporterManager::nsMemoryReporterManager()
mIsRegistrationBlocked(false) mIsRegistrationBlocked(false)
{ {
mReporters.Init(); mReporters.Init();
mMultiReporters.Init();
} }
nsMemoryReporterManager::~nsMemoryReporterManager() nsMemoryReporterManager::~nsMemoryReporterManager()
@@ -827,23 +826,6 @@ nsMemoryReporterManager::EnumerateReporters(nsISimpleEnumerator** aResult)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsMemoryReporterManager::EnumerateMultiReporters(nsISimpleEnumerator** aResult)
{
// Memory multi-reporters are not necessarily threadsafe, so
// EnumerateMultiReporters() must be called from the main thread.
if (!NS_IsMainThread()) {
MOZ_CRASH();
}
mozilla::MutexAutoLock autoLock(mMutex);
nsRefPtr<HashtableEnumerator> enumerator =
new HashtableEnumerator(mMultiReporters);
enumerator.forget(aResult);
return NS_OK;
}
static void static void
DebugAssertRefcountIsNonZero(nsISupports* aObj) DebugAssertRefcountIsNonZero(nsISupports* aObj)
{ {
@@ -899,41 +881,6 @@ nsMemoryReporterManager::RegisterReporterEvenIfBlocked(
return RegisterReporterHelper(aReporter, /* force = */ true); return RegisterReporterHelper(aReporter, /* force = */ true);
} }
nsresult
nsMemoryReporterManager::RegisterMultiReporterHelper(
nsIMemoryMultiReporter* aReporter, bool aForce)
{
// This method is thread-safe.
mozilla::MutexAutoLock autoLock(mMutex);
if ((mIsRegistrationBlocked && !aForce) ||
mMultiReporters.Contains(aReporter)) {
return NS_ERROR_FAILURE;
}
{
nsCOMPtr<nsIMemoryMultiReporter> kungFuDeathGrip = aReporter;
mMultiReporters.PutEntry(aReporter);
}
DebugAssertRefcountIsNonZero(aReporter);
return NS_OK;
}
NS_IMETHODIMP
nsMemoryReporterManager::RegisterMultiReporter(nsIMemoryMultiReporter* aReporter)
{
return RegisterMultiReporterHelper(aReporter, /* force = */ false);
}
NS_IMETHODIMP
nsMemoryReporterManager::RegisterMultiReporterEvenIfBlocked(
nsIMemoryMultiReporter* aReporter)
{
return RegisterMultiReporterHelper(aReporter, /* force = */ true);
}
NS_IMETHODIMP NS_IMETHODIMP
nsMemoryReporterManager::UnregisterReporter(nsIMemoryReporter* aReporter) nsMemoryReporterManager::UnregisterReporter(nsIMemoryReporter* aReporter)
{ {
@@ -948,20 +895,6 @@ nsMemoryReporterManager::UnregisterReporter(nsIMemoryReporter* aReporter)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsMemoryReporterManager::UnregisterMultiReporter(nsIMemoryMultiReporter* aReporter)
{
// This method is thread-safe.
mozilla::MutexAutoLock autoLock(mMutex);
if (!mMultiReporters.Contains(aReporter)) {
return NS_ERROR_FAILURE;
}
mMultiReporters.RemoveEntry(aReporter);
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
nsMemoryReporterManager::BlockRegistration() nsMemoryReporterManager::BlockRegistration()
{ {
@@ -998,7 +931,7 @@ nsMemoryReporterManager::GetResident(int64_t* aResident)
} }
// This is just a wrapper for int64_t that implements nsISupports, so it can be // This is just a wrapper for int64_t that implements nsISupports, so it can be
// passed to nsIMemoryMultiReporter::CollectReports. // passed to nsIMemoryReporter::CollectReports.
class Int64Wrapper MOZ_FINAL : public nsISupports { class Int64Wrapper MOZ_FINAL : public nsISupports {
public: public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
@@ -1007,7 +940,7 @@ public:
}; };
NS_IMPL_ISUPPORTS0(Int64Wrapper) NS_IMPL_ISUPPORTS0(Int64Wrapper)
class ExplicitNonHeapCountingCallback MOZ_FINAL : public nsIMemoryMultiReporterCallback class ExplicitCallback MOZ_FINAL : public nsIMemoryReporterCallback
{ {
public: public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
@@ -1015,23 +948,20 @@ public:
NS_IMETHOD Callback(const nsACString& aProcess, const nsACString& aPath, NS_IMETHOD Callback(const nsACString& aProcess, const nsACString& aPath,
int32_t aKind, int32_t aUnits, int64_t aAmount, int32_t aKind, int32_t aUnits, int64_t aAmount,
const nsACString& aDescription, const nsACString& aDescription,
nsISupports* aWrappedExplicitNonHeap) nsISupports* aWrappedExplicit)
{ {
if (aKind == nsIMemoryReporter::KIND_NONHEAP && if (aPath.Equals("heap-allocated") ||
PromiseFlatCString(aPath).Find("explicit") == 0 && (aKind == nsIMemoryReporter::KIND_NONHEAP &&
aAmount != int64_t(-1)) PromiseFlatCString(aPath).Find("explicit") == 0))
{ {
Int64Wrapper* wrappedPRInt64 = Int64Wrapper* wrappedInt64 =
static_cast<Int64Wrapper*>(aWrappedExplicitNonHeap); static_cast<Int64Wrapper*>(aWrappedExplicit);
wrappedPRInt64->mValue += aAmount; wrappedInt64->mValue += aAmount;
} }
return NS_OK; return NS_OK;
} }
}; };
NS_IMPL_ISUPPORTS1( NS_IMPL_ISUPPORTS1(ExplicitCallback, nsIMemoryReporterCallback)
ExplicitNonHeapCountingCallback
, nsIMemoryMultiReporterCallback
)
NS_IMETHODIMP NS_IMETHODIMP
nsMemoryReporterManager::GetExplicit(int64_t* aExplicit) nsMemoryReporterManager::GetExplicit(int64_t* aExplicit)
@@ -1044,63 +974,25 @@ nsMemoryReporterManager::GetExplicit(int64_t* aExplicit)
nsresult rv; nsresult rv;
bool more; bool more;
// Get "heap-allocated" and all the KIND_NONHEAP measurements from normal // For each reporter we call CollectReports and filter out the
// (i.e. non-multi) "explicit" reporters. // non-explicit, non-NONHEAP measurements (except for "heap-allocated").
int64_t heapAllocated = int64_t(-1); // That's lots of wasted work, and we used to have a GetExplicitNonHeap()
int64_t explicitNonHeapNormalSize = 0; // method which did this more efficiently, but it ended up being more
// trouble than it was worth.
nsRefPtr<ExplicitCallback> cb = new ExplicitCallback();
nsRefPtr<Int64Wrapper> wrappedExplicitSize = new Int64Wrapper();
nsCOMPtr<nsISimpleEnumerator> e; nsCOMPtr<nsISimpleEnumerator> e;
EnumerateReporters(getter_AddRefs(e)); EnumerateReporters(getter_AddRefs(e));
while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) { while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) {
nsCOMPtr<nsIMemoryReporter> r; nsCOMPtr<nsIMemoryReporter> r;
e->GetNext(getter_AddRefs(r)); e->GetNext(getter_AddRefs(r));
r->CollectReports(cb, wrappedExplicitSize);
int32_t kind;
rv = r->GetKind(&kind);
NS_ENSURE_SUCCESS(rv, rv);
nsCString path;
rv = r->GetPath(path);
NS_ENSURE_SUCCESS(rv, rv);
// We're only interested in NONHEAP explicit reporters and
// the 'heap-allocated' reporter.
if (kind == nsIMemoryReporter::KIND_NONHEAP &&
path.Find("explicit") == 0)
{
// Just skip any NONHEAP reporters that fail, because
// "heap-allocated" is the most important one.
int64_t amount;
rv = r->GetAmount(&amount);
if (NS_SUCCEEDED(rv)) {
explicitNonHeapNormalSize += amount;
}
} else if (path.Equals("heap-allocated")) {
// If we don't have "heap-allocated", give up, because the result
// would be horribly inaccurate.
rv = r->GetAmount(&heapAllocated);
NS_ENSURE_SUCCESS(rv, rv);
}
} }
// For each multi-reporter we call CollectReports and filter out the *aExplicit = wrappedExplicitSize->mValue;
// non-explicit, non-NONHEAP measurements. That's lots of wasted work,
// and we used to have a GetExplicitNonHeap() method which did this more
// efficiently, but it ended up being more trouble than it was worth.
nsRefPtr<ExplicitNonHeapCountingCallback> cb =
new ExplicitNonHeapCountingCallback();
nsRefPtr<Int64Wrapper> wrappedExplicitNonHeapMultiSize =
new Int64Wrapper();
nsCOMPtr<nsISimpleEnumerator> e2;
EnumerateMultiReporters(getter_AddRefs(e2));
while (NS_SUCCEEDED(e2->HasMoreElements(&more)) && more) {
nsCOMPtr<nsIMemoryMultiReporter> r;
e2->GetNext(getter_AddRefs(r));
r->CollectReports(cb, wrappedExplicitNonHeapMultiSize);
}
int64_t explicitNonHeapMultiSize = wrappedExplicitNonHeapMultiSize->mValue;
*aExplicit = heapAllocated + explicitNonHeapNormalSize + explicitNonHeapMultiSize;
return NS_OK; return NS_OK;
#endif // HAVE_JEMALLOC_STATS #endif // HAVE_JEMALLOC_STATS
} }
@@ -1205,7 +1097,7 @@ nsMemoryReporterManager::MinimizeMemoryUsage(nsIRunnable* aCallback,
// Most memory reporters don't need thread safety, but some do. Make them all // Most memory reporters don't need thread safety, but some do. Make them all
// thread-safe just to be safe. Memory reporters are created and destroyed // thread-safe just to be safe. Memory reporters are created and destroyed
// infrequently enough that the performance cost should be negligible. // infrequently enough that the performance cost should be negligible.
NS_IMPL_ISUPPORTS1(MemoryReporterBase, nsIMemoryReporter) NS_IMPL_ISUPPORTS1(MemoryUniReporter, nsIMemoryReporter)
nsresult nsresult
NS_RegisterMemoryReporter(nsIMemoryReporter* aReporter) NS_RegisterMemoryReporter(nsIMemoryReporter* aReporter)
@@ -1217,16 +1109,6 @@ NS_RegisterMemoryReporter(nsIMemoryReporter* aReporter)
return mgr->RegisterReporter(aReporter); return mgr->RegisterReporter(aReporter);
} }
nsresult
NS_RegisterMemoryMultiReporter(nsIMemoryMultiReporter* aReporter)
{
nsCOMPtr<nsIMemoryReporterManager> mgr = do_GetService("@mozilla.org/memory-reporter-manager;1");
if (!mgr) {
return NS_ERROR_FAILURE;
}
return mgr->RegisterMultiReporter(aReporter);
}
nsresult nsresult
NS_UnregisterMemoryReporter(nsIMemoryReporter* aReporter) NS_UnregisterMemoryReporter(nsIMemoryReporter* aReporter)
{ {
@@ -1237,22 +1119,12 @@ NS_UnregisterMemoryReporter(nsIMemoryReporter* aReporter)
return mgr->UnregisterReporter(aReporter); return mgr->UnregisterReporter(aReporter);
} }
nsresult
NS_UnregisterMemoryMultiReporter(nsIMemoryMultiReporter* aReporter)
{
nsCOMPtr<nsIMemoryReporterManager> mgr = do_GetService("@mozilla.org/memory-reporter-manager;1");
if (!mgr) {
return NS_ERROR_FAILURE;
}
return mgr->UnregisterMultiReporter(aReporter);
}
#if defined(MOZ_DMD) #if defined(MOZ_DMD)
namespace mozilla { namespace mozilla {
namespace dmd { namespace dmd {
class NullMultiReporterCallback : public nsIMemoryMultiReporterCallback class NullReporterCallback : public nsIMemoryReporterCallback
{ {
public: public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
@@ -1267,8 +1139,8 @@ public:
} }
}; };
NS_IMPL_ISUPPORTS1( NS_IMPL_ISUPPORTS1(
NullMultiReporterCallback NullReporterCallback
, nsIMemoryMultiReporterCallback , nsIMemoryReporterCallback
) )
void void
@@ -1277,48 +1149,15 @@ RunReporters()
nsCOMPtr<nsIMemoryReporterManager> mgr = nsCOMPtr<nsIMemoryReporterManager> mgr =
do_GetService("@mozilla.org/memory-reporter-manager;1"); do_GetService("@mozilla.org/memory-reporter-manager;1");
// Do vanilla reporters. nsRefPtr<NullReporterCallback> cb = new NullReporterCallback();
bool more;
nsCOMPtr<nsISimpleEnumerator> e; nsCOMPtr<nsISimpleEnumerator> e;
mgr->EnumerateReporters(getter_AddRefs(e)); mgr->EnumerateReporters(getter_AddRefs(e));
bool more;
while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) { while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) {
nsCOMPtr<nsIMemoryReporter> r; nsCOMPtr<nsIMemoryReporter> r;
e->GetNext(getter_AddRefs(r)); e->GetNext(getter_AddRefs(r));
r->CollectReports(cb, nullptr);
int32_t kind;
nsresult rv = r->GetKind(&kind);
if (NS_FAILED(rv)) {
continue;
}
nsCString path;
rv = r->GetPath(path);
if (NS_FAILED(rv)) {
continue;
}
// We're only interested in HEAP explicit reporters. (In particular,
// some heap blocks are deliberately measured once inside an "explicit"
// reporter and once outside, which isn't a problem. This condition
// prevents them being reported as double-counted. See bug 811018
// comment 2.)
if (kind == nsIMemoryReporter::KIND_HEAP &&
path.Find("explicit") == 0)
{
// Just getting the amount is enough for the reporter to report to
// DMD.
int64_t amount;
(void)r->GetAmount(&amount);
}
}
// Do multi-reporters.
nsCOMPtr<nsISimpleEnumerator> e2;
mgr->EnumerateMultiReporters(getter_AddRefs(e2));
nsRefPtr<NullMultiReporterCallback> cb = new NullMultiReporterCallback();
while (NS_SUCCEEDED(e2->HasMoreElements(&more)) && more) {
nsCOMPtr<nsIMemoryMultiReporter> r;
e2->GetNext(getter_AddRefs(r));
r->CollectReports(cb, nullptr);
} }
} }

View File

@@ -24,11 +24,8 @@ public:
private: private:
nsresult RegisterReporterHelper(nsIMemoryReporter *reporter, bool aForce); nsresult RegisterReporterHelper(nsIMemoryReporter *reporter, bool aForce);
nsresult RegisterMultiReporterHelper(nsIMemoryMultiReporter *reporter,
bool aForce);
nsTHashtable<nsISupportsHashKey> mReporters; nsTHashtable<nsISupportsHashKey> mReporters;
nsTHashtable<nsISupportsHashKey> mMultiReporters;
Mutex mMutex; Mutex mMutex;
bool mIsRegistrationBlocked; bool mIsRegistrationBlocked;
}; };

View File

@@ -334,11 +334,11 @@ NS_InitXPCOM(nsIServiceManager* *result,
return NS_InitXPCOM2(result, binDirectory, nullptr); return NS_InitXPCOM2(result, binDirectory, nullptr);
} }
class ICUReporter MOZ_FINAL : public MemoryReporterBase class ICUReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
ICUReporter() ICUReporter()
: MemoryReporterBase("explicit/icu", KIND_HEAP, UNITS_BYTES, : MemoryUniReporter("explicit/icu", KIND_HEAP, UNITS_BYTES,
"Memory used by ICU, a Unicode and globalization support library.") "Memory used by ICU, a Unicode and globalization support library.")
{ {
#ifdef DEBUG #ifdef DEBUG

View File

@@ -402,11 +402,11 @@ CategoryEnumerator::enumfunc_createenumerator(const char* aStr, CategoryNode* aN
NS_IMPL_QUERY_INTERFACE1(nsCategoryManager, nsICategoryManager) NS_IMPL_QUERY_INTERFACE1(nsCategoryManager, nsICategoryManager)
class XPCOMCategoryManagerReporter MOZ_FINAL : public MemoryReporterBase class XPCOMCategoryManagerReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
XPCOMCategoryManagerReporter() XPCOMCategoryManagerReporter()
: MemoryReporterBase("explicit/xpcom/category-manager", : MemoryUniReporter("explicit/xpcom/category-manager",
KIND_HEAP, UNITS_BYTES, KIND_HEAP, UNITS_BYTES,
"Memory used for the XPCOM category manager.") "Memory used for the XPCOM category manager.")
{} {}

View File

@@ -280,11 +280,11 @@ CloneAndAppend(nsIFile* aBase, const nsACString& append)
// nsComponentManagerImpl // nsComponentManagerImpl
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
class XPCOMComponentManagerReporter MOZ_FINAL : public MemoryReporterBase class XPCOMComponentManagerReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
XPCOMComponentManagerReporter() XPCOMComponentManagerReporter()
: MemoryReporterBase("explicit/xpcom/component-manager", : MemoryUniReporter("explicit/xpcom/component-manager",
KIND_HEAP, UNITS_BYTES, KIND_HEAP, UNITS_BYTES,
"Memory used for the XPCOM component manager.") "Memory used for the XPCOM component manager.")
{} {}

View File

@@ -48,18 +48,18 @@ GetObserverServiceLog()
namespace mozilla { namespace mozilla {
class ObserverServiceReporter MOZ_FINAL : public nsIMemoryMultiReporter class ObserverServiceReporter MOZ_FINAL : public nsIMemoryReporter
{ {
public: public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_DECL_NSIMEMORYMULTIREPORTER NS_DECL_NSIMEMORYREPORTER
protected: protected:
static const size_t kSuspectReferentCount = 1000; static const size_t kSuspectReferentCount = 1000;
static PLDHashOperator CountReferents(nsObserverList* aObserverList, static PLDHashOperator CountReferents(nsObserverList* aObserverList,
void* aClosure); void* aClosure);
}; };
NS_IMPL_ISUPPORTS1(ObserverServiceReporter, nsIMemoryMultiReporter) NS_IMPL_ISUPPORTS1(ObserverServiceReporter, nsIMemoryReporter)
NS_IMETHODIMP NS_IMETHODIMP
ObserverServiceReporter::GetName(nsACString& aName) ObserverServiceReporter::GetName(nsACString& aName)
@@ -128,7 +128,7 @@ ObserverServiceReporter::CountReferents(nsObserverList* aObserverList,
} }
NS_IMETHODIMP NS_IMETHODIMP
ObserverServiceReporter::CollectReports(nsIMemoryMultiReporterCallback* cb, ObserverServiceReporter::CollectReports(nsIMemoryReporterCallback* cb,
nsISupports* aClosure) nsISupports* aClosure)
{ {
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService(); nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
@@ -220,14 +220,14 @@ void
nsObserverService::RegisterReporter() nsObserverService::RegisterReporter()
{ {
mReporter = new ObserverServiceReporter(); mReporter = new ObserverServiceReporter();
NS_RegisterMemoryMultiReporter(mReporter); NS_RegisterMemoryReporter(mReporter);
} }
void void
nsObserverService::Shutdown() nsObserverService::Shutdown()
{ {
if (mReporter) { if (mReporter) {
NS_UnregisterMemoryMultiReporter(mReporter); NS_UnregisterMemoryReporter(mReporter);
} }
mShuttingDown = true; mShuttingDown = true;

View File

@@ -15,7 +15,7 @@
#define NS_OBSERVERSERVICE_CID \ #define NS_OBSERVERSERVICE_CID \
{ 0xd07f5195, 0xe3d1, 0x11d2, { 0x8a, 0xcd, 0x0, 0x10, 0x5a, 0x1b, 0x88, 0x60 } } { 0xd07f5195, 0xe3d1, 0x11d2, { 0x8a, 0xcd, 0x0, 0x10, 0x5a, 0x1b, 0x88, 0x60 } }
class nsIMemoryMultiReporter; class nsIMemoryReporter;
namespace mozilla { namespace mozilla {
class ObserverServiceReporter; class ObserverServiceReporter;
@@ -47,7 +47,7 @@ private:
bool mShuttingDown; bool mShuttingDown;
nsTHashtable<nsObserverList> mObserverTopicTable; nsTHashtable<nsObserverList> mObserverTopicTable;
nsCOMPtr<nsIMemoryMultiReporter> mReporter; nsCOMPtr<nsIMemoryReporter> mReporter;
}; };
NS_DEFINE_STATIC_IID_ACCESSOR(nsObserverService, NS_OBSERVERSERVICE_CID) NS_DEFINE_STATIC_IID_ACCESSOR(nsObserverService, NS_OBSERVERSERVICE_CID)

View File

@@ -40,11 +40,11 @@ XPTInterfaceInfoManager::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf)
return n; return n;
} }
class XPTIWorkingSetReporter MOZ_FINAL : public MemoryReporterBase class XPTIWorkingSetReporter MOZ_FINAL : public MemoryUniReporter
{ {
public: public:
XPTIWorkingSetReporter() XPTIWorkingSetReporter()
: MemoryReporterBase("explicit/xpti-working-set", KIND_HEAP, UNITS_BYTES, : MemoryUniReporter("explicit/xpti-working-set", KIND_HEAP, UNITS_BYTES,
"Memory used by the XPCOM typelib system.") "Memory used by the XPCOM typelib system.")
{} {}
private: private: