зеркало из https://github.com/mozilla/gecko-dev.git
Bug 910517 (3rd attempt) - Remove nsIMemoryReporter, and rename nsIMemoryMultiReporter as nsIMemoryReporter. r=mmcr8.
--HG-- rename : content/canvas/src/WebGLMemoryMultiReporterWrapper.h => content/canvas/src/WebGLMemoryReporterWrapper.h extra : rebase_source : 2b2a1b2667d6562fcf803ec48b4a8c10fdd519a3
This commit is contained in:
Родитель
6b5008db95
Коммит
7983bb2a7f
|
@ -148,6 +148,9 @@ function reportMemoryUsage() {
|
|||
var mgr = Cc["@mozilla.org/memory-reporter-manager;1"]
|
||||
.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();
|
||||
if (reporters.hasMoreElements())
|
||||
print("\n");
|
||||
|
@ -376,14 +379,7 @@ function getPotentialLeaks() {
|
|||
|
||||
let enm = mgr.enumerateReporters();
|
||||
while (enm.hasMoreElements()) {
|
||||
let reporter = 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);
|
||||
let mr = enm.getNext().QueryInterface(Ci.nsIMemoryReporter);
|
||||
mr.collectReports(logReporter, null);
|
||||
}
|
||||
|
||||
|
|
|
@ -257,11 +257,11 @@ static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
|
|||
|
||||
static PLDHashTable sEventListenerManagersHash;
|
||||
|
||||
class DOMEventListenerManagersHashReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class DOMEventListenerManagersHashReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
DOMEventListenerManagersHashReporter()
|
||||
: MemoryReporterBase(
|
||||
: MemoryUniReporter(
|
||||
"explicit/dom/event-listener-managers-hash",
|
||||
KIND_HEAP,
|
||||
UNITS_BYTES,
|
||||
|
|
|
@ -641,7 +641,7 @@ nsDOMMemoryFile::DataOwner::sMemoryReporterRegistered;
|
|||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(DOMMemoryFileDataOwnerMallocSizeOf)
|
||||
|
||||
class nsDOMMemoryFileDataOwnerMemoryReporter MOZ_FINAL
|
||||
: public nsIMemoryMultiReporter
|
||||
: public nsIMemoryReporter
|
||||
{
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
|
@ -651,7 +651,7 @@ class nsDOMMemoryFileDataOwnerMemoryReporter MOZ_FINAL
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback *aCallback,
|
||||
NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCallback,
|
||||
nsISupports *aClosure)
|
||||
{
|
||||
typedef nsDOMMemoryFile::DataOwner DataOwner;
|
||||
|
@ -725,7 +725,7 @@ class nsDOMMemoryFileDataOwnerMemoryReporter MOZ_FINAL
|
|||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsDOMMemoryFileDataOwnerMemoryReporter,
|
||||
nsIMemoryMultiReporter)
|
||||
nsIMemoryReporter)
|
||||
|
||||
/* static */ void
|
||||
nsDOMMemoryFile::DataOwner::EnsureMemoryReporterRegistered()
|
||||
|
@ -737,7 +737,7 @@ nsDOMMemoryFile::DataOwner::EnsureMemoryReporterRegistered()
|
|||
|
||||
nsRefPtr<nsDOMMemoryFileDataOwnerMemoryReporter> reporter = new
|
||||
nsDOMMemoryFileDataOwnerMemoryReporter();
|
||||
NS_RegisterMemoryMultiReporter(reporter);
|
||||
NS_RegisterMemoryReporter(reporter);
|
||||
|
||||
sMemoryReporterRegistered = true;
|
||||
}
|
||||
|
|
|
@ -133,11 +133,11 @@ static int64_t gCanvasAzureMemoryUsed = 0;
|
|||
// 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
|
||||
// underlying surface implementations. See bug 655638 for details.
|
||||
class Canvas2dPixelsReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class Canvas2dPixelsReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
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.")
|
||||
{}
|
||||
private:
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include "WebGLContextUtils.h"
|
||||
#include "WebGLBuffer.h"
|
||||
#include "WebGLVertexAttribData.h"
|
||||
#include "WebGLMemoryMultiReporterWrapper.h"
|
||||
#include "WebGLMemoryReporterWrapper.h"
|
||||
#include "WebGLFramebuffer.h"
|
||||
#include "WebGLVertexArray.h"
|
||||
#include "WebGLQuery.h"
|
||||
|
@ -179,7 +179,7 @@ WebGLContext::WebGLContext()
|
|||
mPixelStorePackAlignment = 4;
|
||||
mPixelStoreUnpackAlignment = 4;
|
||||
|
||||
WebGLMemoryMultiReporterWrapper::AddWebGLContext(this);
|
||||
WebGLMemoryReporterWrapper::AddWebGLContext(this);
|
||||
|
||||
mAllowRestore = true;
|
||||
mContextLossTimerRunning = false;
|
||||
|
@ -213,7 +213,7 @@ WebGLContext::WebGLContext()
|
|||
WebGLContext::~WebGLContext()
|
||||
{
|
||||
DestroyResourcesAndContext();
|
||||
WebGLMemoryMultiReporterWrapper::RemoveWebGLContext(this);
|
||||
WebGLMemoryReporterWrapper::RemoveWebGLContext(this);
|
||||
TerminateContextLossTimer();
|
||||
mContextRestorer = nullptr;
|
||||
}
|
||||
|
@ -653,8 +653,8 @@ void WebGLContext::LoseOldestWebGLContextIfLimitExceeded()
|
|||
// when choosing which one to lose first.
|
||||
UpdateLastUseIndex();
|
||||
|
||||
WebGLMemoryMultiReporterWrapper::ContextsArrayType &contexts
|
||||
= WebGLMemoryMultiReporterWrapper::Contexts();
|
||||
WebGLMemoryReporterWrapper::ContextsArrayType &contexts
|
||||
= WebGLMemoryReporterWrapper::Contexts();
|
||||
|
||||
// quick exit path, should cover a majority of cases
|
||||
if (contexts.Length() <= kMaxWebGLContextsPerPrincipal) {
|
||||
|
|
|
@ -118,7 +118,7 @@ class WebGLContext :
|
|||
{
|
||||
friend class WebGLContextUserData;
|
||||
friend class WebGLMemoryPressureObserver;
|
||||
friend class WebGLMemoryMultiReporterWrapper;
|
||||
friend class WebGLMemoryReporterWrapper;
|
||||
friend class WebGLExtensionLoseContext;
|
||||
friend class WebGLExtensionCompressedTextureS3TC;
|
||||
friend class WebGLExtensionCompressedTextureATC;
|
||||
|
|
|
@ -4,32 +4,32 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WebGLContext.h"
|
||||
#include "WebGLMemoryMultiReporterWrapper.h"
|
||||
#include "WebGLMemoryReporterWrapper.h"
|
||||
#include "nsIMemoryReporter.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
NS_IMPL_ISUPPORTS1(WebGLMemoryPressureObserver, nsIObserver)
|
||||
|
||||
class WebGLMemoryMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
||||
class WebGLMemoryReporter MOZ_FINAL : public nsIMemoryReporter
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMEMORYMULTIREPORTER
|
||||
NS_DECL_NSIMEMORYREPORTER
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(WebGLMemoryMultiReporter, nsIMemoryMultiReporter)
|
||||
NS_IMPL_ISUPPORTS1(WebGLMemoryReporter, nsIMemoryReporter)
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebGLMemoryMultiReporter::GetName(nsACString &aName)
|
||||
WebGLMemoryReporter::GetName(nsACString &aName)
|
||||
{
|
||||
aName.AssignLiteral("webgl");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebGLMemoryMultiReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
|
||||
nsISupports* aClosure)
|
||||
WebGLMemoryReporter::CollectReports(nsIMemoryReporterCallback* aCb,
|
||||
nsISupports* aClosure)
|
||||
{
|
||||
#define REPORT(_path, _kind, _units, _amount, _desc) \
|
||||
do { \
|
||||
|
@ -42,21 +42,21 @@ WebGLMemoryMultiReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
|
|||
|
||||
REPORT("webgl-texture-memory",
|
||||
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES,
|
||||
WebGLMemoryMultiReporterWrapper::GetTextureMemoryUsed(),
|
||||
WebGLMemoryReporterWrapper::GetTextureMemoryUsed(),
|
||||
"Memory used by WebGL textures.The OpenGL"
|
||||
" implementation is free to store these textures in either video"
|
||||
" 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.");
|
||||
|
||||
|
||||
REPORT("webgl-texture-count",
|
||||
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
|
||||
WebGLMemoryMultiReporterWrapper::GetTextureCount(),
|
||||
WebGLMemoryReporterWrapper::GetTextureCount(),
|
||||
"Number of WebGL textures.");
|
||||
|
||||
REPORT("webgl-buffer-memory",
|
||||
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES,
|
||||
WebGLMemoryMultiReporterWrapper::GetBufferMemoryUsed(),
|
||||
WebGLMemoryReporterWrapper::GetBufferMemoryUsed(),
|
||||
"Memory used by WebGL buffers. The OpenGL"
|
||||
" implementation is free to store these buffers in either video"
|
||||
" 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",
|
||||
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
|
||||
WebGLMemoryMultiReporterWrapper::GetBufferCacheMemoryUsed(),
|
||||
WebGLMemoryReporterWrapper::GetBufferCacheMemoryUsed(),
|
||||
"Memory used by WebGL buffer caches. The WebGL"
|
||||
" implementation caches the contents of element array buffers"
|
||||
" only.This adds up with the webgl-buffer-memory value, but"
|
||||
|
@ -74,69 +74,69 @@ WebGLMemoryMultiReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
|
|||
|
||||
REPORT("webgl-buffer-count",
|
||||
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
|
||||
WebGLMemoryMultiReporterWrapper::GetBufferCount(),
|
||||
"Number of WebGL buffers.");
|
||||
|
||||
WebGLMemoryReporterWrapper::GetBufferCount(),
|
||||
"Number of WebGL buffers.");
|
||||
|
||||
REPORT("webgl-renderbuffer-memory",
|
||||
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES,
|
||||
WebGLMemoryMultiReporterWrapper::GetRenderbufferMemoryUsed(),
|
||||
WebGLMemoryReporterWrapper::GetRenderbufferMemoryUsed(),
|
||||
"Memory used by WebGL renderbuffers. The OpenGL"
|
||||
" implementation is free to store these renderbuffers in either"
|
||||
" video memory or main memory. This measurement is only a lower"
|
||||
" bound, actual memory usage may be higher for example if the"
|
||||
" storage is strided.");
|
||||
|
||||
|
||||
REPORT("webgl-renderbuffer-count",
|
||||
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
|
||||
WebGLMemoryMultiReporterWrapper::GetRenderbufferCount(),
|
||||
WebGLMemoryReporterWrapper::GetRenderbufferCount(),
|
||||
"Number of WebGL renderbuffers.");
|
||||
|
||||
|
||||
REPORT("explicit/webgl/shader",
|
||||
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
|
||||
WebGLMemoryMultiReporterWrapper::GetShaderSize(),
|
||||
WebGLMemoryReporterWrapper::GetShaderSize(),
|
||||
"Combined size of WebGL shader ASCII sources and translation"
|
||||
" logs cached on the heap.");
|
||||
" logs cached on the heap.");
|
||||
|
||||
REPORT("webgl-shader-count",
|
||||
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
|
||||
WebGLMemoryMultiReporterWrapper::GetShaderCount(),
|
||||
"Number of WebGL shaders.");
|
||||
WebGLMemoryReporterWrapper::GetShaderCount(),
|
||||
"Number of WebGL shaders.");
|
||||
|
||||
REPORT("webgl-context-count",
|
||||
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
|
||||
WebGLMemoryMultiReporterWrapper::GetContextCount(),
|
||||
"Number of WebGL contexts.");
|
||||
WebGLMemoryReporterWrapper::GetContextCount(),
|
||||
"Number of WebGL contexts.");
|
||||
|
||||
#undef REPORT
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
WebGLMemoryMultiReporterWrapper* WebGLMemoryMultiReporterWrapper::sUniqueInstance = nullptr;
|
||||
WebGLMemoryReporterWrapper* WebGLMemoryReporterWrapper::sUniqueInstance = nullptr;
|
||||
|
||||
WebGLMemoryMultiReporterWrapper* WebGLMemoryMultiReporterWrapper::UniqueInstance()
|
||||
WebGLMemoryReporterWrapper* WebGLMemoryReporterWrapper::UniqueInstance()
|
||||
{
|
||||
if (!sUniqueInstance) {
|
||||
sUniqueInstance = new WebGLMemoryMultiReporterWrapper;
|
||||
sUniqueInstance = new WebGLMemoryReporterWrapper;
|
||||
}
|
||||
return sUniqueInstance;
|
||||
return sUniqueInstance;
|
||||
}
|
||||
|
||||
WebGLMemoryMultiReporterWrapper::WebGLMemoryMultiReporterWrapper()
|
||||
{
|
||||
mReporter = new WebGLMemoryMultiReporter;
|
||||
NS_RegisterMemoryMultiReporter(mReporter);
|
||||
}
|
||||
|
||||
WebGLMemoryMultiReporterWrapper::~WebGLMemoryMultiReporterWrapper()
|
||||
WebGLMemoryReporterWrapper::WebGLMemoryReporterWrapper()
|
||||
{
|
||||
NS_UnregisterMemoryMultiReporter(mReporter);
|
||||
mReporter = new WebGLMemoryReporter;
|
||||
NS_RegisterMemoryReporter(mReporter);
|
||||
}
|
||||
|
||||
WebGLMemoryReporterWrapper::~WebGLMemoryReporterWrapper()
|
||||
{
|
||||
NS_UnregisterMemoryReporter(mReporter);
|
||||
}
|
||||
|
||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLBufferMallocSizeOf)
|
||||
|
||||
int64_t
|
||||
WebGLMemoryMultiReporterWrapper::GetBufferCacheMemoryUsed() {
|
||||
int64_t
|
||||
WebGLMemoryReporterWrapper::GetBufferCacheMemoryUsed() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
int64_t result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
|
@ -153,8 +153,8 @@ WebGLMemoryMultiReporterWrapper::GetBufferCacheMemoryUsed() {
|
|||
|
||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLShaderMallocSizeOf)
|
||||
|
||||
int64_t
|
||||
WebGLMemoryMultiReporterWrapper::GetShaderSize() {
|
||||
int64_t
|
||||
WebGLMemoryReporterWrapper::GetShaderSize() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
int64_t result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
* 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/. */
|
||||
|
||||
#ifndef WEBGLMEMORYMULTIREPORTWRAPER_H_
|
||||
#define WEBGLMEMORYMULTIREPORTWRAPER_H_
|
||||
#ifndef WEBGLMEMORYREPORTERWRAPPER_H_
|
||||
#define WEBGLMEMORYREPORTERWRAPPER_H_
|
||||
|
||||
#include "WebGLContext.h"
|
||||
#include "WebGLBuffer.h"
|
||||
|
@ -17,21 +17,21 @@
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
class WebGLMemoryMultiReporterWrapper
|
||||
class WebGLMemoryReporterWrapper
|
||||
{
|
||||
WebGLMemoryMultiReporterWrapper();
|
||||
~WebGLMemoryMultiReporterWrapper();
|
||||
static WebGLMemoryMultiReporterWrapper* sUniqueInstance;
|
||||
WebGLMemoryReporterWrapper();
|
||||
~WebGLMemoryReporterWrapper();
|
||||
static WebGLMemoryReporterWrapper* sUniqueInstance;
|
||||
|
||||
// here we store plain pointers, not RefPtrs: we don't want the
|
||||
// WebGLMemoryMultiReporterWrapper unique instance to keep alive all
|
||||
// here we store plain pointers, not RefPtrs: we don't want the
|
||||
// WebGLMemoryReporterWrapper unique instance to keep alive all
|
||||
// WebGLContexts ever created.
|
||||
typedef nsTArray<const WebGLContext*> ContextsArrayType;
|
||||
ContextsArrayType mContexts;
|
||||
|
||||
nsCOMPtr<nsIMemoryMultiReporter> mReporter;
|
||||
nsCOMPtr<nsIMemoryReporter> mReporter;
|
||||
|
||||
static WebGLMemoryMultiReporterWrapper* UniqueInstance();
|
||||
static WebGLMemoryReporterWrapper* UniqueInstance();
|
||||
|
||||
static ContextsArrayType & Contexts() { return UniqueInstance()->mContexts; }
|
||||
|
|
@ -73,7 +73,7 @@ class MediaMemoryTracker
|
|||
|
||||
DecodersArray mDecoders;
|
||||
|
||||
nsCOMPtr<nsIMemoryMultiReporter> mReporter;
|
||||
nsCOMPtr<nsIMemoryReporter> mReporter;
|
||||
|
||||
public:
|
||||
static void AddMediaDecoder(MediaDecoder* aDecoder)
|
||||
|
@ -1728,7 +1728,7 @@ MediaDecoder::IsWMFEnabled()
|
|||
}
|
||||
#endif
|
||||
|
||||
class MediaReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
||||
class MediaReporter MOZ_FINAL : public nsIMemoryReporter
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -1739,7 +1739,7 @@ public:
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback* aCb,
|
||||
NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCb,
|
||||
nsISupports* aClosure)
|
||||
{
|
||||
int64_t video, audio;
|
||||
|
@ -1765,7 +1765,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(MediaReporter, nsIMemoryMultiReporter)
|
||||
NS_IMPL_ISUPPORTS1(MediaReporter, nsIMemoryReporter)
|
||||
|
||||
MediaDecoderOwner*
|
||||
MediaDecoder::GetOwner()
|
||||
|
@ -1777,12 +1777,12 @@ MediaDecoder::GetOwner()
|
|||
MediaMemoryTracker::MediaMemoryTracker()
|
||||
: mReporter(new MediaReporter())
|
||||
{
|
||||
NS_RegisterMemoryMultiReporter(mReporter);
|
||||
NS_RegisterMemoryReporter(mReporter);
|
||||
}
|
||||
|
||||
MediaMemoryTracker::~MediaMemoryTracker()
|
||||
{
|
||||
NS_UnregisterMemoryMultiReporter(mReporter);
|
||||
NS_UnregisterMemoryReporter(mReporter);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -116,11 +116,11 @@ GlobalNameHashInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
|
|||
return true;
|
||||
}
|
||||
|
||||
class ScriptNameSpaceManagerReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class ScriptNameSpaceManagerReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
ScriptNameSpaceManagerReporter(nsScriptNameSpaceManager* aManager)
|
||||
: MemoryReporterBase(
|
||||
: MemoryUniReporter(
|
||||
"explicit/script-namespace-manager",
|
||||
KIND_HEAP,
|
||||
nsIMemoryReporter::UNITS_BYTES,
|
||||
|
|
|
@ -24,7 +24,7 @@ nsWindowMemoryReporter::nsWindowMemoryReporter()
|
|||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS3(nsWindowMemoryReporter, nsIMemoryMultiReporter, nsIObserver,
|
||||
NS_IMPL_ISUPPORTS3(nsWindowMemoryReporter, nsIMemoryReporter, nsIObserver,
|
||||
nsSupportsWeakReference)
|
||||
|
||||
/* static */
|
||||
|
@ -33,7 +33,7 @@ nsWindowMemoryReporter::Init()
|
|||
{
|
||||
// The memory reporter manager will own this object.
|
||||
nsRefPtr<nsWindowMemoryReporter> windowReporter = new nsWindowMemoryReporter();
|
||||
NS_RegisterMemoryMultiReporter(windowReporter);
|
||||
NS_RegisterMemoryReporter(windowReporter);
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
||||
if (os) {
|
||||
|
@ -45,13 +45,13 @@ nsWindowMemoryReporter::Init()
|
|||
/* weakRef = */ true);
|
||||
}
|
||||
|
||||
nsRefPtr<GhostURLsReporter> ghostMultiReporter =
|
||||
nsRefPtr<GhostURLsReporter> ghostURLsReporter =
|
||||
new GhostURLsReporter(windowReporter);
|
||||
NS_RegisterMemoryMultiReporter(ghostMultiReporter);
|
||||
NS_RegisterMemoryReporter(ghostURLsReporter);
|
||||
|
||||
nsRefPtr<NumGhostsReporter> ghostReporter =
|
||||
nsRefPtr<NumGhostsReporter> numGhostsReporter =
|
||||
new NumGhostsReporter(windowReporter);
|
||||
NS_RegisterMemoryReporter(ghostReporter);
|
||||
NS_RegisterMemoryReporter(numGhostsReporter);
|
||||
}
|
||||
|
||||
static already_AddRefed<nsIURI>
|
||||
|
@ -121,7 +121,7 @@ CollectWindowReports(nsGlobalWindow *aWindow,
|
|||
nsTHashtable<nsUint64HashKey> *aGhostWindowIDs,
|
||||
WindowPaths *aWindowPaths,
|
||||
WindowPaths *aTopWindowPaths,
|
||||
nsIMemoryMultiReporterCallback *aCb,
|
||||
nsIMemoryReporterCallback *aCb,
|
||||
nsISupports *aClosure)
|
||||
{
|
||||
nsAutoCString windowPath("explicit/");
|
||||
|
@ -319,7 +319,7 @@ nsWindowMemoryReporter::GetName(nsACString &aName)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowMemoryReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
|
||||
nsWindowMemoryReporter::CollectReports(nsIMemoryReporterCallback* aCb,
|
||||
nsISupports* aClosure)
|
||||
{
|
||||
nsGlobalWindow::WindowByIdTable* windowsById =
|
||||
|
@ -352,9 +352,9 @@ nsWindowMemoryReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
|
|||
}
|
||||
|
||||
// Report JS memory usage. We do this from here because the JS memory
|
||||
// multi-reporter needs to be passed |windowPaths|.
|
||||
nsresult rv = xpc::JSMemoryMultiReporter::CollectReports(&windowPaths, &topWindowPaths,
|
||||
aCb, aClosure);
|
||||
// reporter needs to be passed |windowPaths|.
|
||||
nsresult rv = xpc::JSReporter::CollectReports(&windowPaths, &topWindowPaths,
|
||||
aCb, aClosure);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
#define REPORT(_path, _amount, _desc) \
|
||||
|
@ -663,7 +663,7 @@ nsWindowMemoryReporter::CheckForGhostWindows(
|
|||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsWindowMemoryReporter::GhostURLsReporter,
|
||||
nsIMemoryMultiReporter)
|
||||
nsIMemoryReporter)
|
||||
|
||||
nsWindowMemoryReporter::
|
||||
GhostURLsReporter::GhostURLsReporter(
|
||||
|
@ -676,13 +676,13 @@ NS_IMETHODIMP
|
|||
nsWindowMemoryReporter::
|
||||
GhostURLsReporter::GetName(nsACString& aName)
|
||||
{
|
||||
aName.AssignLiteral("ghost-windows");
|
||||
aName.AssignLiteral("ghost-windows-multi");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
struct ReportGhostWindowsEnumeratorData
|
||||
{
|
||||
nsIMemoryMultiReporterCallback* callback;
|
||||
nsIMemoryReporterCallback* callback;
|
||||
nsISupports* closure;
|
||||
nsresult rv;
|
||||
};
|
||||
|
@ -729,7 +729,7 @@ ReportGhostWindowsEnumerator(nsUint64HashKey* aIDHashKey, void* aClosure)
|
|||
NS_IMETHODIMP
|
||||
nsWindowMemoryReporter::
|
||||
GhostURLsReporter::CollectReports(
|
||||
nsIMemoryMultiReporterCallback* aCb,
|
||||
nsIMemoryReporterCallback* aCb,
|
||||
nsISupports* aClosure)
|
||||
{
|
||||
// Get the IDs of all the ghost windows in existance.
|
||||
|
@ -746,25 +746,6 @@ GhostURLsReporter::CollectReports(
|
|||
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
|
||||
nsWindowMemoryReporter::NumGhostsReporter::Amount()
|
||||
{
|
||||
|
|
|
@ -108,51 +108,55 @@ public:
|
|||
* the tab.
|
||||
*
|
||||
*/
|
||||
class nsWindowMemoryReporter MOZ_FINAL : public nsIMemoryMultiReporter,
|
||||
class nsWindowMemoryReporter MOZ_FINAL : public nsIMemoryReporter,
|
||||
public nsIObserver,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMEMORYMULTIREPORTER
|
||||
NS_DECL_NSIMEMORYREPORTER
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
static void Init();
|
||||
|
||||
private:
|
||||
/**
|
||||
* GhostURLsReporter generates the "ghost-windows" multi-report, which
|
||||
* includes a list of all ghost windows' URLs. If you're only interested in
|
||||
* this list, running this report is faster than running
|
||||
* nsWindowMemoryReporter.
|
||||
* GhostURLsReporter generates the list of all ghost windows' URLs. If
|
||||
* you're only interested in this list, running this report is faster than
|
||||
* running nsWindowMemoryReporter.
|
||||
*/
|
||||
class GhostURLsReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
||||
class GhostURLsReporter MOZ_FINAL : public nsIMemoryReporter
|
||||
{
|
||||
public:
|
||||
GhostURLsReporter(nsWindowMemoryReporter* aWindowReporter);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMEMORYMULTIREPORTER
|
||||
NS_DECL_NSIMEMORYREPORTER
|
||||
|
||||
private:
|
||||
nsRefPtr<nsWindowMemoryReporter> mWindowReporter;
|
||||
};
|
||||
|
||||
/**
|
||||
* nsGhostWindowReporter generates the "ghost-windows" single-report, which
|
||||
* counts the number of ghost windows present.
|
||||
* nsGhostWindowReporter generates the "ghost-windows" report, which counts
|
||||
* the number of ghost windows present.
|
||||
*/
|
||||
class NumGhostsReporter MOZ_FINAL : public mozilla::MemoryReporterBase
|
||||
class NumGhostsReporter MOZ_FINAL : public mozilla::MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
NumGhostsReporter(nsWindowMemoryReporter* aWindowReporter)
|
||||
// Description is "???" because we define GetDescription below.
|
||||
: MemoryReporterBase("ghost-windows", KIND_OTHER, UNITS_COUNT, "???")
|
||||
: MemoryUniReporter("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)
|
||||
{}
|
||||
|
||||
NS_IMETHOD GetDescription(nsACString& aDesc);
|
||||
|
||||
private:
|
||||
int64_t Amount() MOZ_OVERRIDE;
|
||||
|
||||
|
|
|
@ -400,7 +400,7 @@ ContentChild::AllocPMemoryReportRequestChild()
|
|||
}
|
||||
|
||||
// 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 {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -409,7 +409,7 @@ public:
|
|||
};
|
||||
NS_IMPL_ISUPPORTS0(MemoryReportsWrapper)
|
||||
|
||||
class MemoryReportCallback MOZ_FINAL : public nsIMemoryMultiReporterCallback
|
||||
class MemoryReportCallback MOZ_FINAL : public nsIMemoryReporterCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -437,53 +437,28 @@ private:
|
|||
};
|
||||
NS_IMPL_ISUPPORTS1(
|
||||
MemoryReportCallback
|
||||
, nsIMemoryMultiReporterCallback
|
||||
, nsIMemoryReporterCallback
|
||||
)
|
||||
|
||||
bool
|
||||
ContentChild::RecvPMemoryReportRequestConstructor(PMemoryReportRequestChild* child)
|
||||
{
|
||||
|
||||
nsCOMPtr<nsIMemoryReporterManager> mgr = do_GetService("@mozilla.org/memory-reporter-manager;1");
|
||||
|
||||
InfallibleTArray<MemoryReport> reports;
|
||||
|
||||
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;
|
||||
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 =
|
||||
new MemoryReportsWrapper(&reports);
|
||||
nsRefPtr<MemoryReportCallback> cb = new MemoryReportCallback(process);
|
||||
bool more;
|
||||
while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) {
|
||||
nsCOMPtr<nsIMemoryMultiReporter> r;
|
||||
nsCOMPtr<nsIMemoryReporter> r;
|
||||
e->GetNext(getter_AddRefs(r));
|
||||
r->CollectReports(cb, wrappedReports);
|
||||
}
|
||||
|
|
|
@ -161,34 +161,54 @@ namespace dom {
|
|||
|
||||
#define NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC "ipc:network:set-offline"
|
||||
|
||||
// This represents a single measurement taken by a memory reporter in a child
|
||||
// process and passed to this one. Its process is non-empty, and its amount is
|
||||
// fixed.
|
||||
class ChildMemoryReporter MOZ_FINAL : public MemoryReporterBase
|
||||
// This represents all the memory reports provided by a child process.
|
||||
class ChildReporter MOZ_FINAL : public nsIMemoryReporter
|
||||
{
|
||||
public:
|
||||
ChildMemoryReporter(const char* aProcess, const char* aPath, int32_t aKind,
|
||||
int32_t aUnits, int64_t aAmount,
|
||||
const char* aDescription)
|
||||
: MemoryReporterBase(aPath, aKind, aUnits, aDescription)
|
||||
, mProcess(aProcess)
|
||||
, mAmount(aAmount)
|
||||
ChildReporter(const InfallibleTArray<MemoryReport>& childReports)
|
||||
{
|
||||
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);
|
||||
return NS_OK;
|
||||
name.AssignLiteral("content-child");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
int64_t Amount() { return mAmount; }
|
||||
NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCb,
|
||||
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;
|
||||
int64_t mAmount;
|
||||
private:
|
||||
InfallibleTArray<MemoryReport> mChildReports;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(ChildReporter, nsIMemoryReporter)
|
||||
|
||||
class MemoryReportRequestParent : public PMemoryReportRequestParent
|
||||
{
|
||||
public:
|
||||
|
@ -209,9 +229,9 @@ MemoryReportRequestParent::MemoryReportRequestParent()
|
|||
}
|
||||
|
||||
bool
|
||||
MemoryReportRequestParent::Recv__delete__(const InfallibleTArray<MemoryReport>& report)
|
||||
MemoryReportRequestParent::Recv__delete__(const InfallibleTArray<MemoryReport>& childReports)
|
||||
{
|
||||
Owner()->SetChildMemoryReporters(report);
|
||||
Owner()->SetChildMemoryReports(childReports);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -223,15 +243,15 @@ MemoryReportRequestParent::~MemoryReportRequestParent()
|
|||
/**
|
||||
* A memory reporter for ContentParent objects themselves.
|
||||
*/
|
||||
class ContentParentMemoryReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
||||
class ContentParentMemoryReporter MOZ_FINAL : public nsIMemoryReporter
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMEMORYMULTIREPORTER
|
||||
NS_DECL_NSIMEMORYREPORTER
|
||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(MallocSizeOf)
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(ContentParentMemoryReporter, nsIMemoryMultiReporter)
|
||||
NS_IMPL_ISUPPORTS1(ContentParentMemoryReporter, nsIMemoryReporter)
|
||||
|
||||
NS_IMETHODIMP
|
||||
ContentParentMemoryReporter::GetName(nsACString& aName)
|
||||
|
@ -241,7 +261,7 @@ ContentParentMemoryReporter::GetName(nsACString& aName)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ContentParentMemoryReporter::CollectReports(nsIMemoryMultiReporterCallback* cb,
|
||||
ContentParentMemoryReporter::CollectReports(nsIMemoryReporterCallback* cb,
|
||||
nsISupports* aClosure)
|
||||
{
|
||||
nsAutoTArray<ContentParent*, 16> cps;
|
||||
|
@ -358,7 +378,7 @@ ContentParent::StartUp()
|
|||
}
|
||||
|
||||
nsRefPtr<ContentParentMemoryReporter> mr = new ContentParentMemoryReporter();
|
||||
NS_RegisterMemoryMultiReporter(mr);
|
||||
NS_RegisterMemoryReporter(mr);
|
||||
|
||||
sCanLaunchSubprocesses = true;
|
||||
|
||||
|
@ -877,7 +897,7 @@ ContentParent::ShutDownProcess(bool aCloseWithError)
|
|||
// 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
|
||||
// bug 899761.
|
||||
mMemoryReporters.Clear();
|
||||
mChildReporter = nullptr;
|
||||
if (mMessageManager) {
|
||||
mMessageManager->Disconnect();
|
||||
mMessageManager = nullptr;
|
||||
|
@ -1028,8 +1048,8 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
|
|||
ppm->Disconnect();
|
||||
}
|
||||
|
||||
// clear the child memory reporters
|
||||
ClearChildMemoryReporters();
|
||||
// unregister the child memory reporter
|
||||
UnregisterChildMemoryReporter();
|
||||
|
||||
// remove the global remote preferences observers
|
||||
Preferences::RemoveObserver(this, "");
|
||||
|
@ -2141,28 +2161,16 @@ ContentParent::DeallocPMemoryReportRequestParent(PMemoryReportRequestParent* act
|
|||
}
|
||||
|
||||
void
|
||||
ContentParent::SetChildMemoryReporters(const InfallibleTArray<MemoryReport>& report)
|
||||
ContentParent::SetChildMemoryReports(const InfallibleTArray<MemoryReport>& childReports)
|
||||
{
|
||||
nsCOMPtr<nsIMemoryReporterManager> mgr =
|
||||
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++) {
|
||||
nsCString process = report[i].process();
|
||||
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();
|
||||
if (mChildReporter)
|
||||
mgr->UnregisterReporter(mChildReporter);
|
||||
|
||||
nsRefPtr<ChildMemoryReporter> r =
|
||||
new ChildMemoryReporter(process.get(), path.get(), kind, units,
|
||||
amount, desc.get());
|
||||
|
||||
mMemoryReporters.AppendObject(r);
|
||||
mgr->RegisterReporter(r);
|
||||
}
|
||||
mChildReporter = new ChildReporter(childReports);
|
||||
mgr->RegisterReporter(mChildReporter);
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs =
|
||||
do_GetService("@mozilla.org/observer-service;1");
|
||||
|
@ -2171,12 +2179,11 @@ ContentParent::SetChildMemoryReporters(const InfallibleTArray<MemoryReport>& rep
|
|||
}
|
||||
|
||||
void
|
||||
ContentParent::ClearChildMemoryReporters()
|
||||
ContentParent::UnregisterChildMemoryReporter()
|
||||
{
|
||||
nsCOMPtr<nsIMemoryReporterManager> mgr =
|
||||
do_GetService("@mozilla.org/memory-reporter-manager;1");
|
||||
for (int32_t i = 0; i < mMemoryReporters.Count(); i++)
|
||||
mgr->UnregisterReporter(mMemoryReporters[i]);
|
||||
mgr->UnregisterReporter(mChildReporter);
|
||||
}
|
||||
|
||||
PTestShellParent*
|
||||
|
|
|
@ -143,8 +143,9 @@ public:
|
|||
bool IsAlive();
|
||||
bool IsForApp();
|
||||
|
||||
void SetChildMemoryReporters(const InfallibleTArray<MemoryReport>& report);
|
||||
void ClearChildMemoryReporters();
|
||||
void SetChildMemoryReports(const InfallibleTArray<MemoryReport>&
|
||||
childReports);
|
||||
void UnregisterChildMemoryReporter();
|
||||
|
||||
GeckoChildProcessHost* Process() {
|
||||
return mSubprocess;
|
||||
|
@ -449,11 +450,13 @@ private:
|
|||
uint64_t mChildID;
|
||||
int32_t mGeolocationWatchID;
|
||||
|
||||
// This is a cache of all of the memory reporters
|
||||
// registered in the child process. To update this, one
|
||||
// can broadcast the topic "child-memory-reporter-request" using
|
||||
// the nsIObserverService.
|
||||
nsCOMArray<nsIMemoryReporter> mMemoryReporters;
|
||||
// This is a reporter holding the reports from the child's last
|
||||
// "child-memory-reporter-update" notification. To update this, one can
|
||||
// broadcast the topic "child-memory-reporter-request" using the
|
||||
// nsIObserverService.
|
||||
//
|
||||
// Note that this assumes there is at most one child process at a time!
|
||||
nsCOMPtr<nsIMemoryReporter> mChildReporter;
|
||||
|
||||
nsString mAppManifestURL;
|
||||
|
||||
|
|
|
@ -1767,7 +1767,7 @@ struct WorkerPrivate::TimeoutInfo
|
|||
bool mCanceled;
|
||||
};
|
||||
|
||||
class WorkerPrivate::MemoryReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
||||
class WorkerPrivate::MemoryReporter MOZ_FINAL : public nsIMemoryReporter
|
||||
{
|
||||
friend class WorkerPrivate;
|
||||
|
||||
|
@ -1808,7 +1808,7 @@ public:
|
|||
}
|
||||
|
||||
NS_IMETHOD
|
||||
CollectReports(nsIMemoryMultiReporterCallback* aCallback,
|
||||
CollectReports(nsIMemoryReporterCallback* aCallback,
|
||||
nsISupports* aClosure)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
@ -1884,7 +1884,7 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(WorkerPrivate::MemoryReporter, nsIMemoryMultiReporter)
|
||||
NS_IMPL_ISUPPORTS1(WorkerPrivate::MemoryReporter, nsIMemoryReporter)
|
||||
|
||||
template <class Derived>
|
||||
WorkerPrivateParent<Derived>::WorkerPrivateParent(
|
||||
|
@ -3094,7 +3094,7 @@ WorkerPrivate::EnableMemoryReporter()
|
|||
// successfully registered the reporter.
|
||||
mMemoryReporter = new MemoryReporter(this);
|
||||
|
||||
if (NS_FAILED(NS_RegisterMemoryMultiReporter(mMemoryReporter))) {
|
||||
if (NS_FAILED(NS_RegisterMemoryReporter(mMemoryReporter))) {
|
||||
NS_WARNING("Failed to register memory reporter!");
|
||||
// No need to lock here since a failed registration means our memory
|
||||
// reporter can't start running. Just clean up.
|
||||
|
@ -3149,7 +3149,7 @@ WorkerPrivate::DisableMemoryReporter()
|
|||
}
|
||||
|
||||
// Finally unregister the memory reporter.
|
||||
if (NS_FAILED(NS_UnregisterMemoryMultiReporter(memoryReporter))) {
|
||||
if (NS_FAILED(NS_UnregisterMemoryReporter(memoryReporter))) {
|
||||
NS_WARNING("Failed to unregister memory reporter!");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
class JSAutoStructuredCloneBuffer;
|
||||
class nsIChannel;
|
||||
class nsIDocument;
|
||||
class nsIMemoryMultiReporter;
|
||||
class nsIPrincipal;
|
||||
class nsIScriptContext;
|
||||
class nsIURI;
|
||||
|
|
|
@ -97,11 +97,11 @@ NS_IMPL_CYCLE_COLLECTION_3(mozHunspell,
|
|||
mEncoder,
|
||||
mDecoder)
|
||||
|
||||
class SpellCheckReporter MOZ_FINAL : public mozilla::MemoryReporterBase
|
||||
class SpellCheckReporter MOZ_FINAL : public mozilla::MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
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.")
|
||||
{
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -13,12 +13,12 @@
|
|||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
||||
class GfxTexturesReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class GfxTexturesReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
GfxTexturesReporter()
|
||||
: MemoryReporterBase("gfx-textures", KIND_OTHER, UNITS_BYTES,
|
||||
"Memory used for storing GL textures.")
|
||||
: MemoryUniReporter("gfx-textures", KIND_OTHER, UNITS_BYTES,
|
||||
"Memory used for storing GL textures.")
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// There must be only one instance of this class, due to |sAmount|
|
||||
|
|
|
@ -184,13 +184,13 @@ ContentTypeFromPixelFormat(android::PixelFormat aFormat)
|
|||
return gfxASurface::ContentFromFormat(ImageFormatForPixelFormat(aFormat));
|
||||
}
|
||||
|
||||
class GrallocReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class GrallocReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
friend class GrallocBufferActor;
|
||||
|
||||
public:
|
||||
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 "
|
||||
"both the CPU and GPU. Gralloc memory is usually a relatively precious "
|
||||
"resource, with much less available than generic RAM. When it's exhausted, "
|
||||
|
|
|
@ -598,7 +598,7 @@ PR_STATIC_ASSERT(uint32_t(CAIRO_SURFACE_TYPE_SKIA) ==
|
|||
static int64_t gSurfaceMemoryUsed[gfxASurface::SurfaceTypeMax] = { 0 };
|
||||
|
||||
class SurfaceMemoryReporter MOZ_FINAL :
|
||||
public nsIMemoryMultiReporter
|
||||
public nsIMemoryReporter
|
||||
{
|
||||
public:
|
||||
SurfaceMemoryReporter()
|
||||
|
@ -612,7 +612,7 @@ public:
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback *aCb,
|
||||
NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCb,
|
||||
nsISupports *aClosure)
|
||||
{
|
||||
size_t len = NS_ARRAY_LENGTH(sSurfaceMemoryReporterAttrs);
|
||||
|
@ -639,7 +639,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(SurfaceMemoryReporter, nsIMemoryMultiReporter)
|
||||
NS_IMPL_ISUPPORTS1(SurfaceMemoryReporter, nsIMemoryReporter)
|
||||
|
||||
void
|
||||
gfxASurface::RecordMemoryUsedForSurfaceType(gfxASurface::gfxSurfaceType aType,
|
||||
|
@ -652,7 +652,7 @@ gfxASurface::RecordMemoryUsedForSurfaceType(gfxASurface::gfxSurfaceType aType,
|
|||
|
||||
static bool registered = false;
|
||||
if (!registered) {
|
||||
NS_RegisterMemoryMultiReporter(new SurfaceMemoryReporter());
|
||||
NS_RegisterMemoryReporter(new SurfaceMemoryReporter());
|
||||
registered = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,12 +30,12 @@ using namespace mozilla::gfx;
|
|||
|
||||
static FT_Library gPlatformFTLibrary = nullptr;
|
||||
|
||||
class FreetypeReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class FreetypeReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
FreetypeReporter()
|
||||
: MemoryReporterBase("explicit/freetype", KIND_HEAP, UNITS_BYTES,
|
||||
"Memory used by Freetype.")
|
||||
: MemoryUniReporter("explicit/freetype", KIND_HEAP, UNITS_BYTES,
|
||||
"Memory used by Freetype.")
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// There must be only one instance of this class, due to |sAmount|
|
||||
|
|
|
@ -1253,7 +1253,7 @@ gfxFontFamily::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf,
|
|||
* 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)
|
||||
|
||||
|
@ -1266,7 +1266,7 @@ gfxFontCache::MemoryReporter::GetName(nsACString &aName)
|
|||
|
||||
NS_IMETHODIMP
|
||||
gfxFontCache::MemoryReporter::CollectReports
|
||||
(nsIMemoryMultiReporterCallback* aCb,
|
||||
(nsIMemoryReporterCallback* aCb,
|
||||
nsISupports* aClosure)
|
||||
{
|
||||
FontCacheSizes sizes;
|
||||
|
@ -1325,7 +1325,7 @@ gfxFontCache::Init()
|
|||
if (!gGlobalCache) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
NS_RegisterMemoryMultiReporter(new MemoryReporter);
|
||||
NS_RegisterMemoryReporter(new MemoryReporter);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -977,11 +977,11 @@ public:
|
|||
|
||||
protected:
|
||||
class MemoryReporter MOZ_FINAL
|
||||
: public nsIMemoryMultiReporter
|
||||
: public nsIMemoryReporter
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMEMORYMULTIREPORTER
|
||||
NS_DECL_NSIMEMORYREPORTER
|
||||
};
|
||||
|
||||
void DestroyFont(gfxFont *aFont);
|
||||
|
|
|
@ -70,7 +70,7 @@ gfxFontListPrefObserver::Observe(nsISupports *aSubject,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(gfxPlatformFontList::MemoryReporter, nsIMemoryMultiReporter)
|
||||
NS_IMPL_ISUPPORTS1(gfxPlatformFontList::MemoryReporter, nsIMemoryReporter)
|
||||
|
||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(FontListMallocSizeOf)
|
||||
|
||||
|
@ -83,7 +83,7 @@ gfxPlatformFontList::MemoryReporter::GetName(nsACString &aName)
|
|||
|
||||
NS_IMETHODIMP
|
||||
gfxPlatformFontList::MemoryReporter::CollectReports
|
||||
(nsIMemoryMultiReporterCallback* aCb,
|
||||
(nsIMemoryReporterCallback* aCb,
|
||||
nsISupports* aClosure)
|
||||
{
|
||||
FontListSizes sizes;
|
||||
|
@ -141,7 +141,7 @@ gfxPlatformFontList::gfxPlatformFontList(bool aNeedFullnamePostscriptNames)
|
|||
NS_ADDREF(gFontListPrefObserver);
|
||||
Preferences::AddStrongObservers(gFontListPrefObserver, kObservedPrefs);
|
||||
|
||||
NS_RegisterMemoryMultiReporter(new MemoryReporter);
|
||||
NS_RegisterMemoryReporter(new MemoryReporter);
|
||||
}
|
||||
|
||||
gfxPlatformFontList::~gfxPlatformFontList()
|
||||
|
|
|
@ -179,11 +179,11 @@ public:
|
|||
|
||||
protected:
|
||||
class MemoryReporter MOZ_FINAL
|
||||
: public nsIMemoryMultiReporter
|
||||
: public nsIMemoryReporter
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMEMORYMULTIREPORTER
|
||||
NS_DECL_NSIMEMORYREPORTER
|
||||
};
|
||||
|
||||
gfxPlatformFontList(bool aNeedFullnamePostscriptNames = true);
|
||||
|
|
|
@ -73,11 +73,11 @@ static const int kSupportedFeatureLevels[] =
|
|||
{ D3D10_FEATURE_LEVEL_10_1, D3D10_FEATURE_LEVEL_10_0,
|
||||
D3D10_FEATURE_LEVEL_9_3 };
|
||||
|
||||
class GfxD2DSurfaceCacheReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class GfxD2DSurfaceCacheReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
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.")
|
||||
{}
|
||||
private:
|
||||
|
@ -110,11 +110,11 @@ bool OncePreferenceDirect2DForceEnabled()
|
|||
|
||||
} // anonymous namespace
|
||||
|
||||
class GfxD2DSurfaceVramReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class GfxD2DSurfaceVramReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
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.")
|
||||
{}
|
||||
private:
|
||||
|
@ -127,11 +127,11 @@ private:
|
|||
|
||||
#endif
|
||||
|
||||
class GfxD2DVramDrawTargetReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class GfxD2DVramDrawTargetReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
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.")
|
||||
{}
|
||||
private:
|
||||
|
@ -141,11 +141,11 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
class GfxD2DVramSourceSurfaceReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class GfxD2DVramSourceSurfaceReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
GfxD2DVramSourceSurfaceReporter()
|
||||
: MemoryReporterBase("gfx-d2d-vram-source-surface",
|
||||
: MemoryUniReporter("gfx-d2d-vram-source-surface",
|
||||
KIND_OTHER, UNITS_BYTES,
|
||||
"Video memory used by D2D SourceSurfaces.")
|
||||
{}
|
||||
|
@ -206,7 +206,7 @@ typedef HRESULT (WINAPI*D3D11CreateDeviceFunc)(
|
|||
ID3D11DeviceContext *ppImmediateContext
|
||||
);
|
||||
|
||||
class GPUAdapterMultiReporter : public nsIMemoryMultiReporter {
|
||||
class GPUAdapterReporter : public nsIMemoryReporter {
|
||||
|
||||
// Callers must Release the DXGIAdapter after use or risk mem-leak
|
||||
static bool GetDXGIAdapter(IDXGIAdapter **DXGIAdapter)
|
||||
|
@ -228,7 +228,7 @@ class GPUAdapterMultiReporter : public nsIMemoryMultiReporter {
|
|||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIMemoryMultiReporter abstract method implementation
|
||||
// nsIMemoryReporter abstract method implementation
|
||||
NS_IMETHOD
|
||||
GetName(nsACString &aName)
|
||||
{
|
||||
|
@ -236,9 +236,9 @@ public:
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIMemoryMultiReporter abstract method implementation
|
||||
// nsIMemoryReporter abstract method implementation
|
||||
NS_IMETHOD
|
||||
CollectReports(nsIMemoryMultiReporterCallback* aCb,
|
||||
CollectReports(nsIMemoryReporterCallback* aCb,
|
||||
nsISupports* aClosure)
|
||||
{
|
||||
int32_t winVers, buildNum;
|
||||
|
@ -347,7 +347,7 @@ public:
|
|||
return NS_OK;
|
||||
}
|
||||
};
|
||||
NS_IMPL_ISUPPORTS1(GPUAdapterMultiReporter, nsIMemoryMultiReporter)
|
||||
NS_IMPL_ISUPPORTS1(GPUAdapterReporter, nsIMemoryReporter)
|
||||
|
||||
static __inline void
|
||||
BuildKeyNameFromFontName(nsAString &aName)
|
||||
|
@ -384,16 +384,16 @@ gfxWindowsPlatform::gfxWindowsPlatform()
|
|||
|
||||
UpdateRenderMode();
|
||||
|
||||
mGPUAdapterMultiReporter = new GPUAdapterMultiReporter();
|
||||
NS_RegisterMemoryMultiReporter(mGPUAdapterMultiReporter);
|
||||
mGPUAdapterReporter = new GPUAdapterReporter();
|
||||
NS_RegisterMemoryReporter(mGPUAdapterReporter);
|
||||
}
|
||||
|
||||
gfxWindowsPlatform::~gfxWindowsPlatform()
|
||||
{
|
||||
NS_UnregisterMemoryMultiReporter(mGPUAdapterMultiReporter);
|
||||
|
||||
mDeviceManager = nullptr;
|
||||
|
||||
NS_UnregisterMemoryReporter(mGPUAdapterReporter);
|
||||
|
||||
mDeviceManager = nullptr;
|
||||
|
||||
::ReleaseDC(nullptr, mScreenDC);
|
||||
// not calling FT_Done_FreeType because cairo may still hold references to
|
||||
// these FT_Faces. See bug 458169.
|
||||
|
|
|
@ -52,7 +52,7 @@ class IDirect3DDevice9;
|
|||
class ID3D11Device;
|
||||
class IDXGIAdapter1;
|
||||
|
||||
class nsIMemoryMultiReporter;
|
||||
class nsIMemoryReporter;
|
||||
|
||||
// Utility to get a Windows HDC from a thebes context,
|
||||
// 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
|
||||
nsDataHashtable<nsCStringHashKey, nsTArray<nsRefPtr<gfxFontEntry> > > mPrefFonts;
|
||||
|
||||
nsIMemoryMultiReporter* mGPUAdapterMultiReporter;
|
||||
nsIMemoryReporter* mGPUAdapterReporter;
|
||||
};
|
||||
|
||||
#endif /* GFX_WINDOWS_PLATFORM_H */
|
||||
|
|
|
@ -49,7 +49,7 @@ using namespace mozilla::image;
|
|||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(ImagesMallocSizeOf)
|
||||
|
||||
class imgMemoryReporter MOZ_FINAL :
|
||||
public nsIMemoryMultiReporter
|
||||
public nsIMemoryReporter
|
||||
{
|
||||
public:
|
||||
imgMemoryReporter()
|
||||
|
@ -64,7 +64,7 @@ public:
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback *callback,
|
||||
NS_IMETHOD CollectReports(nsIMemoryReporterCallback *callback,
|
||||
nsISupports *closure)
|
||||
{
|
||||
AllSizes chrome;
|
||||
|
@ -221,15 +221,15 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(imgMemoryReporter, nsIMemoryMultiReporter)
|
||||
NS_IMPL_ISUPPORTS1(imgMemoryReporter, nsIMemoryReporter)
|
||||
|
||||
// This is used by telemetry.
|
||||
class ImagesContentUsedUncompressedReporter MOZ_FINAL
|
||||
: public MemoryReporterBase
|
||||
: public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
ImagesContentUsedUncompressedReporter()
|
||||
: MemoryReporterBase("images-content-used-uncompressed",
|
||||
: MemoryUniReporter("images-content-used-uncompressed",
|
||||
KIND_OTHER, UNITS_BYTES,
|
||||
"This is the sum of the 'explicit/images/content/used/uncompressed-heap' "
|
||||
"and 'explicit/images/content/used/uncompressed-nonheap' numbers. However, "
|
||||
|
@ -838,7 +838,7 @@ void imgLoader::GlobalInit()
|
|||
sCacheMaxSize = 5 * 1024 * 1024;
|
||||
|
||||
sMemReporter = new imgMemoryReporter();
|
||||
NS_RegisterMemoryMultiReporter(sMemReporter);
|
||||
NS_RegisterMemoryReporter(sMemReporter);
|
||||
NS_RegisterMemoryReporter(new ImagesContentUsedUncompressedReporter());
|
||||
}
|
||||
|
||||
|
|
|
@ -25,14 +25,18 @@ window.onload = function() {
|
|||
var mgr = SpecialPowers.Cc["@mozilla.org/memory-reporter-manager;1"]
|
||||
.getService(SpecialPowers.Ci.nsIMemoryReporterManager);
|
||||
|
||||
var e = mgr.enumerateReporters();
|
||||
var memoryCounter = 0;
|
||||
while (e.hasMoreElements()) {
|
||||
var mr =
|
||||
e.getNext().QueryInterface(SpecialPowers.Ci.nsIMemoryReporter);
|
||||
memoryCounter += mr.amount;
|
||||
var amount = 0;
|
||||
var handleReport = function(aProcess, aPath, aKind, aUnits, aAmount, aDesc) {
|
||||
amount += aAmount;
|
||||
}
|
||||
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!");
|
||||
|
||||
SimpleTest.finish();
|
||||
|
|
|
@ -17,11 +17,11 @@ namespace ipc {
|
|||
static Atomic<size_t> gShmemAllocated;
|
||||
static Atomic<size_t> gShmemMapped;
|
||||
|
||||
class ShmemAllocatedReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class ShmemAllocatedReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
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 "
|
||||
"mapped).")
|
||||
{}
|
||||
|
@ -29,11 +29,11 @@ private:
|
|||
int64_t Amount() MOZ_OVERRIDE { return gShmemAllocated; }
|
||||
};
|
||||
|
||||
class ShmemMappedReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class ShmemMappedReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
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.")
|
||||
{}
|
||||
private:
|
||||
|
|
|
@ -9,22 +9,22 @@
|
|||
#define XPCJSMemoryReporter_h
|
||||
|
||||
class nsISupports;
|
||||
class nsIMemoryMultiReporterCallback;
|
||||
class nsIMemoryReporterCallback;
|
||||
|
||||
namespace xpc {
|
||||
|
||||
// The key is the window ID.
|
||||
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|
|
||||
// in CollectReports.
|
||||
class JSMemoryMultiReporter
|
||||
class JSReporter
|
||||
{
|
||||
public:
|
||||
static nsresult CollectReports(WindowPaths *windowPaths,
|
||||
WindowPaths *topWindowPaths,
|
||||
nsIMemoryMultiReporterCallback *cb,
|
||||
nsIMemoryReporterCallback *cb,
|
||||
nsISupports *closure);
|
||||
};
|
||||
|
||||
|
|
|
@ -1561,13 +1561,13 @@ GetCompartmentName(JSCompartment *c, nsCString &name, bool replaceSlashes)
|
|||
}
|
||||
}
|
||||
|
||||
// Telemetry relies on this being a single reporter (rather than part of the
|
||||
// "js" multi-reporter).
|
||||
class JSGCHeapReporter MOZ_FINAL : public MemoryReporterBase
|
||||
// Telemetry relies on this being a uni-reporter (rather than part of the "js"
|
||||
// reporter).
|
||||
class JSGCHeapReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
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.")
|
||||
{}
|
||||
private:
|
||||
|
@ -1579,19 +1579,17 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
// Nb: js-compartments/system + js-compartments/user could be
|
||||
// different to the number of compartments reported by
|
||||
// JSMemoryMultiReporter if a garbage collection occurred
|
||||
// between them being consulted. We could move these reporters into
|
||||
// XPConnectJSCompartmentCount to avoid that problem, but then we couldn't
|
||||
// easily report them via telemetry, so we live with the small risk of
|
||||
// inconsistencies.
|
||||
// Nb: js-compartments/system + js-compartments/user could be different to the
|
||||
// number of compartments reported by JSReporter if a garbage collection
|
||||
// occurred between them being consulted. We could move these reporters into
|
||||
// JSReporter to avoid that problem, but then we couldn't 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:
|
||||
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 "
|
||||
"'js-compartments/user' might not match the number of compartments listed "
|
||||
"in the 'explicit' tree if a garbage collection occurs at an inopportune "
|
||||
|
@ -1605,11 +1603,11 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
class JSCompartmentsUserReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class JSCompartmentsUserReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
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 "
|
||||
"'js-compartments/system' might not match the number of compartments listed "
|
||||
"under 'js' if a garbage collection occurs at an inopportune time, but such "
|
||||
|
@ -1624,11 +1622,11 @@ private:
|
|||
};
|
||||
|
||||
// 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:
|
||||
JSMainRuntimeTemporaryPeakReporter()
|
||||
: MemoryReporterBase("js-main-runtime-temporary-peak",
|
||||
: MemoryUniReporter("js-main-runtime-temporary-peak",
|
||||
KIND_OTHER, UNITS_BYTES,
|
||||
"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').")
|
||||
|
@ -1759,7 +1757,7 @@ namespace xpc {
|
|||
static nsresult
|
||||
ReportZoneStats(const JS::ZoneStats &zStats,
|
||||
const xpc::ZoneStatsExtras &extras,
|
||||
nsIMemoryMultiReporterCallback *cb,
|
||||
nsIMemoryReporterCallback *cb,
|
||||
nsISupports *closure, size_t *gcTotalOut = NULL)
|
||||
{
|
||||
const nsAutoCString& pathPrefix = extras.pathPrefix;
|
||||
|
@ -1943,7 +1941,7 @@ static nsresult
|
|||
ReportCompartmentStats(const JS::CompartmentStats &cStats,
|
||||
const xpc::CompartmentStatsExtras &extras,
|
||||
amIAddonManager *addonManager,
|
||||
nsIMemoryMultiReporterCallback *cb,
|
||||
nsIMemoryReporterCallback *cb,
|
||||
nsISupports *closure, size_t *gcTotalOut = NULL)
|
||||
{
|
||||
static const nsDependentCString addonPrefix("explicit/add-ons/");
|
||||
|
@ -2085,8 +2083,8 @@ ReportCompartmentStats(const JS::CompartmentStats &cStats,
|
|||
"Memory allocated on the malloc heap for data belonging to ctypes objects.");
|
||||
|
||||
// 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" sub-tree rather than a "js" sub-tree.
|
||||
// DOM nodes in the JS reporter, but we want to report them in a "dom"
|
||||
// sub-tree rather than a "js" sub-tree.
|
||||
ZCREPORT_BYTES(cDOMPathPrefix + NS_LITERAL_CSTRING("orphan-nodes"),
|
||||
cStats.objectsExtra.private_,
|
||||
"Memory used by orphan DOM nodes that are only reachable "
|
||||
|
@ -2208,7 +2206,7 @@ static nsresult
|
|||
ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats,
|
||||
const nsACString &rtPath,
|
||||
amIAddonManager* addonManager,
|
||||
nsIMemoryMultiReporterCallback *cb,
|
||||
nsIMemoryReporterCallback *cb,
|
||||
nsISupports *closure, size_t *rtTotalOut)
|
||||
{
|
||||
nsresult rv;
|
||||
|
@ -2350,7 +2348,7 @@ ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats,
|
|||
nsresult
|
||||
ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats,
|
||||
const nsACString &rtPath,
|
||||
nsIMemoryMultiReporterCallback *cb,
|
||||
nsIMemoryReporterCallback *cb,
|
||||
nsISupports *closure, size_t *rtTotalOut)
|
||||
{
|
||||
nsCOMPtr<amIAddonManager> am =
|
||||
|
@ -2362,7 +2360,7 @@ ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats,
|
|||
|
||||
} // namespace xpc
|
||||
|
||||
class JSCompartmentsMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
||||
class JSCompartmentsReporter MOZ_FINAL : public nsIMemoryReporter
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
@ -2386,7 +2384,7 @@ class JSCompartmentsMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
|||
paths->append(path);
|
||||
}
|
||||
|
||||
NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback *cb,
|
||||
NS_IMETHOD CollectReports(nsIMemoryReporterCallback *cb,
|
||||
nsISupports *closure)
|
||||
{
|
||||
// First we collect the compartment paths. Then we report them. Doing
|
||||
|
@ -2408,9 +2406,7 @@ class JSCompartmentsMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
|||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(JSCompartmentsMultiReporter
|
||||
, nsIMemoryMultiReporter
|
||||
)
|
||||
NS_IMPL_ISUPPORTS1(JSCompartmentsReporter, nsIMemoryReporter)
|
||||
|
||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(OrphanMallocSizeOf)
|
||||
|
||||
|
@ -2567,9 +2563,9 @@ class XPCJSRuntimeStats : public JS::RuntimeStats
|
|||
// "<something>compartment(<cname>)/".
|
||||
//
|
||||
// extras->domPathPrefix is used for DOM orphan nodes, which are
|
||||
// counted by the JS multi-reporter but reported as part of the
|
||||
// DOM measurements. At this point it has the form "<something>/dom/"
|
||||
// if this compartment belongs to an nsGlobalWindow, and
|
||||
// counted by the JS reporter but reported as part of the DOM
|
||||
// measurements. At this point it has the form "<something>/dom/" if
|
||||
// this compartment belongs to an nsGlobalWindow, and
|
||||
// "explicit/dom/<something>?!/" otherwise (in which case it shouldn't
|
||||
// be used, because non-nsGlobalWindow compartments shouldn't have
|
||||
// orphan DOM nodes).
|
||||
|
@ -2579,10 +2575,10 @@ class XPCJSRuntimeStats : public JS::RuntimeStats
|
|||
};
|
||||
|
||||
nsresult
|
||||
JSMemoryMultiReporter::CollectReports(WindowPaths *windowPaths,
|
||||
WindowPaths *topWindowPaths,
|
||||
nsIMemoryMultiReporterCallback *cb,
|
||||
nsISupports *closure)
|
||||
JSReporter::CollectReports(WindowPaths *windowPaths,
|
||||
WindowPaths *topWindowPaths,
|
||||
nsIMemoryReporterCallback *cb,
|
||||
nsISupports *closure)
|
||||
{
|
||||
XPCJSRuntime *xpcrt = nsXPConnect::GetRuntimeInstance();
|
||||
|
||||
|
@ -3052,7 +3048,7 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
|
|||
NS_RegisterMemoryReporter(new JSCompartmentsSystemReporter());
|
||||
NS_RegisterMemoryReporter(new JSCompartmentsUserReporter());
|
||||
NS_RegisterMemoryReporter(new JSMainRuntimeTemporaryPeakReporter());
|
||||
NS_RegisterMemoryMultiReporter(new JSCompartmentsMultiReporter);
|
||||
NS_RegisterMemoryReporter(new JSCompartmentsReporter);
|
||||
|
||||
// Install a JavaScript 'debugger' keyword handler in debug builds only
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -163,7 +163,7 @@ xpc_UnmarkSkippableJSHolders();
|
|||
NS_EXPORT_(void)
|
||||
xpc_ActivateDebugMode();
|
||||
|
||||
class nsIMemoryMultiReporterCallback;
|
||||
class nsIMemoryReporterCallback;
|
||||
|
||||
// readable string conversions, static methods and members only
|
||||
class XPCStringConvert
|
||||
|
@ -359,7 +359,7 @@ private:
|
|||
nsresult
|
||||
ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats,
|
||||
const nsACString &rtPath,
|
||||
nsIMemoryMultiReporterCallback *cb,
|
||||
nsIMemoryReporterCallback *cb,
|
||||
nsISupports *closure, size_t *rtTotal = NULL);
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,11 +26,11 @@
|
|||
using namespace mozilla;
|
||||
|
||||
class LayoutStyleSheetServiceReporter MOZ_FINAL
|
||||
: public mozilla::MemoryReporterBase
|
||||
: public mozilla::MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
LayoutStyleSheetServiceReporter()
|
||||
: MemoryReporterBase("explicit/layout/style-sheet-service",
|
||||
: MemoryUniReporter("explicit/layout/style-sheet-service",
|
||||
KIND_HEAP, UNITS_BYTES,
|
||||
"Memory used for style sheets held by the style sheet service.")
|
||||
{}
|
||||
|
|
|
@ -18,11 +18,11 @@
|
|||
#include "nsCSSStyleSheet.h"
|
||||
|
||||
class LayoutStyleSheetCacheReporter MOZ_FINAL
|
||||
: public mozilla::MemoryReporterBase
|
||||
: public mozilla::MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
LayoutStyleSheetCacheReporter()
|
||||
: MemoryReporterBase("explicit/layout/style-sheet-cache",
|
||||
: MemoryUniReporter("explicit/layout/style-sheet-cache",
|
||||
KIND_HEAP, UNITS_BYTES,
|
||||
"Memory used for some built-in style sheets.")
|
||||
{}
|
||||
|
|
|
@ -203,11 +203,11 @@ Preferences::SizeOfIncludingThisAndOtherStuff(mozilla::MallocSizeOf aMallocSizeO
|
|||
return n;
|
||||
}
|
||||
|
||||
class PreferencesReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class PreferencesReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
PreferencesReporter()
|
||||
: MemoryReporterBase("explicit/preferences", KIND_HEAP, UNITS_BYTES,
|
||||
: MemoryUniReporter("explicit/preferences", KIND_HEAP, UNITS_BYTES,
|
||||
"Memory used by the preferences system.")
|
||||
{}
|
||||
private:
|
||||
|
|
|
@ -370,11 +370,11 @@ nsDiskCache::Truncate(PRFileDesc * fd, uint32_t newEOF)
|
|||
* nsDiskCacheDevice
|
||||
*****************************************************************************/
|
||||
|
||||
class NetworkDiskCacheReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class NetworkDiskCacheReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
NetworkDiskCacheReporter(nsDiskCacheDevice* aDevice)
|
||||
: MemoryReporterBase(
|
||||
: MemoryUniReporter(
|
||||
"explicit/network/disk-cache",
|
||||
KIND_HEAP,
|
||||
UNITS_BYTES,
|
||||
|
|
|
@ -29,11 +29,11 @@
|
|||
const char *gMemoryDeviceID = "memory";
|
||||
|
||||
class NetworkMemoryCacheReporter MOZ_FINAL :
|
||||
public mozilla::MemoryReporterBase
|
||||
public mozilla::MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
NetworkMemoryCacheReporter(nsMemoryCacheDevice* aDevice)
|
||||
: MemoryReporterBase(
|
||||
: MemoryUniReporter(
|
||||
"explicit/network/memory-cache",
|
||||
KIND_HEAP,
|
||||
UNITS_BYTES,
|
||||
|
|
|
@ -61,11 +61,11 @@ nsDomainEntry::FuncForStaticAsserts(void)
|
|||
|
||||
static nsEffectiveTLDService *gService = nullptr;
|
||||
|
||||
class EffectiveTLDServiceReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class EffectiveTLDServiceReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
EffectiveTLDServiceReporter()
|
||||
: MemoryReporterBase("explicit/xpcom/effective-TLD-service",
|
||||
: MemoryUniReporter("explicit/xpcom/effective-TLD-service",
|
||||
KIND_HEAP, UNITS_BYTES,
|
||||
"Memory used by the effective TLD service.")
|
||||
{}
|
||||
|
|
|
@ -53,11 +53,11 @@
|
|||
namespace mozilla {
|
||||
namespace scache {
|
||||
|
||||
class StartupCacheMappingReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class StartupCacheMappingReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
StartupCacheMappingReporter()
|
||||
: MemoryReporterBase("explicit/startup-cache/mapping",
|
||||
: MemoryUniReporter("explicit/startup-cache/mapping",
|
||||
KIND_NONHEAP, UNITS_BYTES,
|
||||
"Memory used to hold the mapping of the startup cache from file. This memory "
|
||||
"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:
|
||||
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.")
|
||||
{}
|
||||
private:
|
||||
|
|
|
@ -57,18 +57,18 @@ namespace storage {
|
|||
// 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,
|
||||
// and more importantly, we also gather the total via telemetry.
|
||||
class StorageSQLiteReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class StorageSQLiteUniReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
StorageSQLiteReporter()
|
||||
: MemoryReporterBase("storage-sqlite", KIND_OTHER, UNITS_BYTES,
|
||||
StorageSQLiteUniReporter()
|
||||
: MemoryUniReporter("storage-sqlite", KIND_OTHER, UNITS_BYTES,
|
||||
"Memory used by SQLite.")
|
||||
{}
|
||||
private:
|
||||
int64_t Amount() MOZ_OVERRIDE { return ::sqlite3_memory_used(); }
|
||||
};
|
||||
|
||||
class StorageSQLiteMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
||||
class StorageSQLiteMultiReporter MOZ_FINAL : public nsIMemoryReporter
|
||||
{
|
||||
private:
|
||||
Service *mService; // a weakref because Service contains a strongref to this
|
||||
|
@ -97,7 +97,7 @@ public:
|
|||
|
||||
NS_IMETHOD GetName(nsACString &aName)
|
||||
{
|
||||
aName.AssignLiteral("storage-sqlite");
|
||||
aName.AssignLiteral("storage-sqlite-multi");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -107,7 +107,7 @@ public:
|
|||
// 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
|
||||
// any delays in that case aren't so bad.
|
||||
NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback *aCb,
|
||||
NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCb,
|
||||
nsISupports *aClosure)
|
||||
{
|
||||
nsresult rv;
|
||||
|
@ -164,8 +164,7 @@ public:
|
|||
|
||||
private:
|
||||
/**
|
||||
* Passes a single SQLite memory statistic to a memory multi-reporter
|
||||
* callback.
|
||||
* Passes a single SQLite memory statistic to a memory reporter callback.
|
||||
*
|
||||
* @param aCallback
|
||||
* The callback.
|
||||
|
@ -185,7 +184,7 @@ private:
|
|||
* @param aTotal
|
||||
* The accumulator for the measurement.
|
||||
*/
|
||||
nsresult reportConn(nsIMemoryMultiReporterCallback *aCb,
|
||||
nsresult reportConn(nsIMemoryReporterCallback *aCb,
|
||||
nsISupports *aClosure,
|
||||
sqlite3 *aConn,
|
||||
const nsACString &aPathHead,
|
||||
|
@ -216,7 +215,7 @@ private:
|
|||
|
||||
NS_IMPL_ISUPPORTS1(
|
||||
StorageSQLiteMultiReporter,
|
||||
nsIMemoryMultiReporter
|
||||
nsIMemoryReporter
|
||||
)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -308,8 +307,8 @@ Service::Service()
|
|||
|
||||
Service::~Service()
|
||||
{
|
||||
(void)::NS_UnregisterMemoryReporter(mStorageSQLiteReporter);
|
||||
(void)::NS_UnregisterMemoryMultiReporter(mStorageSQLiteMultiReporter);
|
||||
(void)::NS_UnregisterMemoryReporter(mStorageSQLiteUniReporter);
|
||||
(void)::NS_UnregisterMemoryReporter(mStorageSQLiteMultiReporter);
|
||||
|
||||
int rc = sqlite3_vfs_unregister(mSqliteVFS);
|
||||
if (rc != SQLITE_OK)
|
||||
|
@ -541,10 +540,10 @@ Service::initialize()
|
|||
|
||||
// Create and register our SQLite memory reporters. Registration can only
|
||||
// happen on the main thread (otherwise you'll get cryptic crashes).
|
||||
mStorageSQLiteReporter = new StorageSQLiteReporter();
|
||||
mStorageSQLiteUniReporter = new StorageSQLiteUniReporter();
|
||||
mStorageSQLiteMultiReporter = new StorageSQLiteMultiReporter(this);
|
||||
(void)::NS_RegisterMemoryReporter(mStorageSQLiteReporter);
|
||||
(void)::NS_RegisterMemoryMultiReporter(mStorageSQLiteMultiReporter);
|
||||
(void)::NS_RegisterMemoryReporter(mStorageSQLiteUniReporter);
|
||||
(void)::NS_RegisterMemoryReporter(mStorageSQLiteMultiReporter);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include "mozIStorageService.h"
|
||||
|
||||
class nsIMemoryReporter;
|
||||
class nsIMemoryMultiReporter;
|
||||
class nsIXPConnect;
|
||||
struct sqlite3_vfs;
|
||||
|
||||
|
@ -173,8 +172,8 @@ private:
|
|||
|
||||
nsCOMPtr<nsIFile> mProfileStorageFile;
|
||||
|
||||
nsCOMPtr<nsIMemoryReporter> mStorageSQLiteReporter;
|
||||
nsCOMPtr<nsIMemoryMultiReporter> mStorageSQLiteMultiReporter;
|
||||
nsCOMPtr<nsIMemoryReporter> mStorageSQLiteUniReporter;
|
||||
nsCOMPtr<nsIMemoryReporter> mStorageSQLiteMultiReporter;
|
||||
|
||||
static Service *gService;
|
||||
|
||||
|
|
|
@ -166,49 +166,32 @@ function onUnload()
|
|||
//---------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Iterates over each reporter and multi-reporter.
|
||||
* Iterates over each reporter.
|
||||
*
|
||||
* @param aIgnoreSingle
|
||||
* Function that indicates if we should skip a single reporter, based
|
||||
* on its path.
|
||||
* @param aIgnoreMulti
|
||||
* Function that indicates if we should skip a multi-reporter, based on
|
||||
* its name.
|
||||
* @param aIgnoreReporter
|
||||
* Function that indicates if we should skip an entire reporter, based
|
||||
* on its name.
|
||||
* @param aIgnoreReport
|
||||
* Function that indicates if we should skip a single report from a
|
||||
* reporter, based on its path.
|
||||
* @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.
|
||||
//
|
||||
// - Note that copying rOrig.amount (which calls a C++ function under the
|
||||
// IDL covers) to r._amount for every reporter now means that the
|
||||
// results as consistent as possible -- measurements are made all at
|
||||
// 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 handleReport = function(aProcess, aUnsafePath, aKind, aUnits,
|
||||
aAmount, aDescription) {
|
||||
if (!aIgnoreReport(aUnsafePath)) {
|
||||
aHandleReport(aProcess, aUnsafePath, aKind, aUnits, aAmount,
|
||||
aDescription, /* presence = */ undefined);
|
||||
}
|
||||
}
|
||||
|
||||
let e = gMgr.enumerateMultiReporters();
|
||||
let e = gMgr.enumerateReporters();
|
||||
while (e.hasMoreElements()) {
|
||||
let mr = e.getNext().QueryInterface(Ci.nsIMemoryMultiReporter);
|
||||
if (!aIgnoreMulti(mr.name)) {
|
||||
let mr = e.getNext().QueryInterface(Ci.nsIMemoryReporter);
|
||||
if (!aIgnoreReporter(mr.name)) {
|
||||
// |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);
|
||||
}
|
||||
}
|
||||
|
@ -219,19 +202,19 @@ function processMemoryReporters(aIgnoreSingle, aIgnoreMulti, aHandleReport)
|
|||
*
|
||||
* @param aReports
|
||||
* Array of reports, read from a file or the clipboard.
|
||||
* @param aIgnoreSingle
|
||||
* Function that indicates if we should skip a single reporter, based
|
||||
* @param aIgnoreReport
|
||||
* Function that indicates if we should skip a single report, based
|
||||
* on its path.
|
||||
* @param aHandleReport
|
||||
* The function that's called for each report.
|
||||
*/
|
||||
function processMemoryReportsFromFile(aReports, aIgnoreSingle, aHandleReport)
|
||||
function processMemoryReportsFromFile(aReports, aIgnoreReport, aHandleReport)
|
||||
{
|
||||
// Process each memory reporter with aHandleReport.
|
||||
|
||||
for (let i = 0; i < aReports.length; i++) {
|
||||
let r = aReports[i];
|
||||
if (!aIgnoreSingle(r.path)) {
|
||||
if (!aIgnoreReport(r.path)) {
|
||||
aHandleReport(r.process, r.path, r.kind, r.units, r.amount,
|
||||
r.description, r._presence);
|
||||
}
|
||||
|
@ -591,10 +574,7 @@ function updateAboutMemoryFromReporters()
|
|||
|
||||
try {
|
||||
// Process the reports from the memory reporters.
|
||||
let process = function(aIgnoreSingle, aIgnoreMulti, aHandleReport) {
|
||||
processMemoryReporters(aIgnoreSingle, aIgnoreMulti, aHandleReport);
|
||||
}
|
||||
appendAboutMemoryMain(process, gMgr.hasMozMallocUsableSize,
|
||||
appendAboutMemoryMain(processMemoryReporters, gMgr.hasMozMallocUsableSize,
|
||||
/* forceShowSmaps = */ false);
|
||||
|
||||
} catch (ex) {
|
||||
|
@ -621,8 +601,8 @@ function updateAboutMemoryFromJSONObject(aObj)
|
|||
"missing 'hasMozMallocUsableSize' property");
|
||||
assertInput(aObj.reports && aObj.reports instanceof Array,
|
||||
"missing or non-array 'reports' property");
|
||||
let process = function(aIgnoreSingle, aIgnoreMulti, aHandleReport) {
|
||||
processMemoryReportsFromFile(aObj.reports, aIgnoreSingle, aHandleReport);
|
||||
let process = function(aIgnoreReporter, aIgnoreReport, aHandleReport) {
|
||||
processMemoryReportsFromFile(aObj.reports, aIgnoreReport, aHandleReport);
|
||||
}
|
||||
appendAboutMemoryMain(process, aObj.hasMozMallocUsableSize,
|
||||
/* forceShowSmaps = */ true);
|
||||
|
@ -973,7 +953,7 @@ function PColl()
|
|||
* Processes reports (whether from reporters or from a file) and append the
|
||||
* main part of the page.
|
||||
*
|
||||
* @param aProcess
|
||||
* @param aProcessReports
|
||||
* Function that extracts the memory reports from the reporters or from
|
||||
* file.
|
||||
* @param aHasMozMallocUsableSize
|
||||
|
@ -982,10 +962,10 @@ function PColl()
|
|||
* True if we should show the smaps memory reporters even if we're not
|
||||
* in verbose mode.
|
||||
*/
|
||||
function appendAboutMemoryMain(aProcess, aHasMozMallocUsableSize,
|
||||
function appendAboutMemoryMain(aProcessReports, aHasMozMallocUsableSize,
|
||||
aForceShowSmaps)
|
||||
{
|
||||
let pcollsByProcess = getPCollsByProcess(aProcess, aForceShowSmaps);
|
||||
let pcollsByProcess = getPCollsByProcess(aProcessReports, aForceShowSmaps);
|
||||
|
||||
// Sort the processes.
|
||||
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
|
||||
* that will be used to generate the page.
|
||||
*
|
||||
* @param aProcessMemoryReports
|
||||
* @param aProcessReports
|
||||
* Function that extracts the memory reports from the reporters or from
|
||||
* file.
|
||||
* @param aForceShowSmaps
|
||||
|
@ -1051,7 +1031,7 @@ function appendAboutMemoryMain(aProcess, aHasMozMallocUsableSize,
|
|||
* in verbose mode.
|
||||
* @return The table of PColls by process.
|
||||
*/
|
||||
function getPCollsByProcess(aProcessMemoryReports, aForceShowSmaps)
|
||||
function getPCollsByProcess(aProcessReports, aForceShowSmaps)
|
||||
{
|
||||
let pcollsByProcess = {};
|
||||
|
||||
|
@ -1060,23 +1040,28 @@ function getPCollsByProcess(aProcessMemoryReports, aForceShowSmaps)
|
|||
// be in parentheses, so a ')' might appear after the '.'.)
|
||||
const gSentenceRegExp = /^[A-Z].*\.\)?$/m;
|
||||
|
||||
// Ignore the "smaps" multi-reporter in non-verbose mode unless we're reading
|
||||
// from a file or the clipboard, and ignore the "compartments" and
|
||||
// "ghost-windows" multi-reporters all the time. (Note that reports from
|
||||
// these multi-reporters can reach here as single reports if they were in the
|
||||
// child process.)
|
||||
// Ignore the "smaps" reporter in non-verbose mode unless we're reading from
|
||||
// a file or the clipboard, and ignore the "compartments" and "ghost-windows"
|
||||
// reporters all the time. (Note that reports from these reporters can reach
|
||||
// here via a "content-child" reporter if they were in a 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
|
||||
// that we avoid the (small) possibility of a long pause when loading
|
||||
// about:memory.
|
||||
//
|
||||
// We don't show both resident and resident-fast because running the resident
|
||||
// reporter can purge pages on MacOS, which affects the results of the
|
||||
// resident-fast reporter. We don't want about:memory's results to be
|
||||
// affected by the order of memory reporter execution.
|
||||
// about:memory. Furthermore, the "resident" reporter can purge pages on
|
||||
// MacOS, which affects the results of the "resident-fast" reporter, and we
|
||||
// don't want the measurements shown in about:memory to be affected by the
|
||||
// (arbitrary) 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) ||
|
||||
aUnsafePath.startsWith("compartments/") ||
|
||||
|
@ -1084,13 +1069,6 @@ function getPCollsByProcess(aProcessMemoryReports, aForceShowSmaps)
|
|||
aUnsafePath == "resident-fast";
|
||||
}
|
||||
|
||||
function ignoreMulti(aMRName)
|
||||
{
|
||||
return (aMRName === "smaps" && !gVerbose.checked && !aForceShowSmaps) ||
|
||||
aMRName === "compartments" ||
|
||||
aMRName === "ghost-windows";
|
||||
}
|
||||
|
||||
function handleReport(aProcess, aUnsafePath, aKind, aUnits, aAmount,
|
||||
aDescription, aPresence)
|
||||
{
|
||||
|
@ -1171,7 +1149,7 @@ function getPCollsByProcess(aProcessMemoryReports, aForceShowSmaps)
|
|||
}
|
||||
}
|
||||
|
||||
aProcessMemoryReports(ignoreSingle, ignoreMulti, handleReport);
|
||||
aProcessReports(ignoreReporter, ignoreReport, handleReport);
|
||||
|
||||
return pcollsByProcess;
|
||||
}
|
||||
|
@ -2107,18 +2085,18 @@ Compartment.prototype = {
|
|||
|
||||
function getCompartmentsByProcess()
|
||||
{
|
||||
// Ignore anything that didn't come from the "compartments" multi-reporter.
|
||||
// (Note that some such reports can reach here as single reports if they were
|
||||
// in the child process.)
|
||||
// Ignore anything that didn't come from the "compartments" reporter. (Note
|
||||
// reports from this reporter can reach here via a "content-child" reporter
|
||||
// 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 = {};
|
||||
|
@ -2169,7 +2147,7 @@ function getCompartmentsByProcess()
|
|||
}
|
||||
}
|
||||
|
||||
processMemoryReporters(ignoreSingle, ignoreMulti, handleReport);
|
||||
processMemoryReporters(ignoreReporter, ignoreReport, handleReport);
|
||||
|
||||
return compartmentsByProcess;
|
||||
}
|
||||
|
@ -2191,14 +2169,14 @@ GhostWindow.prototype = {
|
|||
|
||||
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 = {};
|
||||
|
@ -2230,7 +2208,7 @@ function getGhostWindowsByProcess()
|
|||
}
|
||||
}
|
||||
|
||||
processMemoryReporters(ignoreSingle, ignoreMulti, handleReport);
|
||||
processMemoryReporters(ignoreReporter, ignoreReport, handleReport);
|
||||
|
||||
return ghostWindowsByProcess;
|
||||
}
|
||||
|
|
|
@ -24,8 +24,7 @@
|
|||
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
|
||||
getService(Ci.nsIMemoryReporterManager);
|
||||
|
||||
// Remove all the real reporters and multi-reporters; save them to
|
||||
// restore at the end.
|
||||
// Remove all the real reporters; save them to restore at the end.
|
||||
mgr.blockRegistration();
|
||||
var e = mgr.enumerateReporters();
|
||||
var realReporters = [];
|
||||
|
@ -34,13 +33,6 @@
|
|||
mgr.unregisterReporter(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.
|
||||
const KB = 1024;
|
||||
|
@ -52,41 +44,39 @@
|
|||
const BYTES = Ci.nsIMemoryReporter.UNITS_BYTES;
|
||||
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 = [
|
||||
// These should be ignored.
|
||||
f("", "explicit/a", HEAP, BYTES, 222 * MB),
|
||||
f("", "explicit/b/a", HEAP, BYTES, 85 * MB),
|
||||
f("", "explicit/b/b", NONHEAP, BYTES, 85 * MB),
|
||||
f("", "other1", OTHER, BYTES, 111 * MB),
|
||||
f("", "other2", OTHER, COUNT, 888),
|
||||
|
||||
f("2nd", "explicit/c", HEAP, BYTES, 333 * MB),
|
||||
f("2nd", "compartments/user/child-user-compartment", OTHER, COUNT, 1),
|
||||
f("2nd", "compartments/system/child-system-compartment", OTHER, COUNT, 1)
|
||||
];
|
||||
|
||||
var fakeMultiReporters = [
|
||||
// These shouldn't show up.
|
||||
{ name: "fake",
|
||||
{ name: "fake1",
|
||||
collectReports: function(aCbObj, aClosure) {
|
||||
function f(aP1, aP2, aK, aU, aA) {
|
||||
aCbObj.callback(aP1, aP2, aK, aU, aA, "Desc.", aClosure);
|
||||
}
|
||||
// These should be ignored.
|
||||
f("", "explicit/a", HEAP, BYTES, 222 * MB);
|
||||
f("", "explicit/b/a", HEAP, BYTES, 85 * MB);
|
||||
f("", "explicit/b/b", NONHEAP, BYTES, 85 * MB);
|
||||
f("", "other1", OTHER, BYTES, 111 * MB);
|
||||
f("", "other2", OTHER, COUNT, 888);
|
||||
}
|
||||
},
|
||||
{ name: "fake2",
|
||||
collectReports: function(aCbObj, aClosure) {
|
||||
function f(aP, aK, aU, aA) {
|
||||
aCbObj.callback("", aP, aK, aU, aA, "Desc.", aClosure);
|
||||
}
|
||||
// These shouldn't show up.
|
||||
f("explicit/a/d", HEAP, BYTES, 13 * 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",
|
||||
collectReports: function(aCbObj, aClosure) {
|
||||
|
@ -104,8 +94,7 @@
|
|||
f("compartments/system/[System Principal]");
|
||||
f("compartments/system/[System Principal]");
|
||||
f("compartments/system/atoms");
|
||||
},
|
||||
explicitNonHeap: 0
|
||||
}
|
||||
},
|
||||
{ name: "ghost-windows",
|
||||
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/http:\\\\foobar.com\\foo?bar#baz");
|
||||
},
|
||||
explicitNonHeap: 0
|
||||
}
|
||||
},
|
||||
// These shouldn't show up.
|
||||
{ name: "smaps",
|
||||
|
@ -126,17 +114,13 @@
|
|||
}
|
||||
f("smaps/vsize/a", 24);
|
||||
f("smaps/swap/a", 1);
|
||||
},
|
||||
explicitNonHeap: 0
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
for (var i = 0; i < fakeReporters.length; i++) {
|
||||
mgr.registerReporterEvenIfBlocked(fakeReporters[i]);
|
||||
}
|
||||
for (var i = 0; i < fakeMultiReporters.length; i++) {
|
||||
mgr.registerMultiReporterEvenIfBlocked(fakeMultiReporters[i]);
|
||||
}
|
||||
]]>
|
||||
</script>
|
||||
|
||||
|
@ -180,21 +164,14 @@ Ghost Windows\n\
|
|||
|
||||
function finish()
|
||||
{
|
||||
// Unregister fake reporters and multi-reporters, re-register the real
|
||||
// reporters and multi-reporters, just in case subsequent tests rely on
|
||||
// them.
|
||||
// Unregister fake reporters and re-register the real reporters, just in
|
||||
// case subsequent tests rely on them.
|
||||
for (var i = 0; i < fakeReporters.length; 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++) {
|
||||
mgr.registerReporterEvenIfBlocked(realReporters[i]);
|
||||
}
|
||||
for (var i = 0; i < realMultiReporters.length; i++) {
|
||||
mgr.registerMultiReporterEvenIfBlocked(realMultiReporters[i]);
|
||||
}
|
||||
mgr.unblockRegistration();
|
||||
|
||||
SimpleTest.finish();
|
||||
|
|
|
@ -27,8 +27,7 @@
|
|||
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
|
||||
getService(Ci.nsIMemoryReporterManager);
|
||||
|
||||
// Remove all the real reporters and multi-reporters; save them to
|
||||
// restore at the end.
|
||||
// Remove all the real reporters; save them to restore at the end.
|
||||
mgr.blockRegistration();
|
||||
let e = mgr.enumerateReporters();
|
||||
let realReporters = [];
|
||||
|
@ -37,13 +36,6 @@
|
|||
mgr.unregisterReporter(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.
|
||||
const KB = 1024;
|
||||
|
@ -57,71 +49,60 @@
|
|||
const COUNT_CUMULATIVE = Ci.nsIMemoryReporter.UNITS_COUNT_CUMULATIVE;
|
||||
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 = [
|
||||
f("", "heap-allocated", OTHER, 500 * MB),
|
||||
f("", "heap-unallocated", OTHER, 100 * MB),
|
||||
f("", "explicit/a", HEAP, 222 * MB),
|
||||
f("", "explicit/b/a", HEAP, 85 * MB),
|
||||
f("", "explicit/b/b", HEAP, 75 * MB),
|
||||
f("", "explicit/b/c/a", HEAP, 70 * MB),
|
||||
f("", "explicit/b/c/b", HEAP, 2 * MB), // omitted
|
||||
f("", "explicit/g/a", HEAP, 6 * MB),
|
||||
f("", "explicit/g/b", HEAP, 5 * MB),
|
||||
f("", "explicit/g/other", HEAP, 4 * MB),
|
||||
// A degenerate tree with the same name as a non-degenerate tree should
|
||||
// work ok.
|
||||
f("", "explicit", OTHER, 888 * MB),
|
||||
f("", "other1/a/b", OTHER, 111 * MB),
|
||||
f("", "other1/c/d", OTHER, 22 * MB),
|
||||
f("", "other1/c/e", OTHER, 33 * MB),
|
||||
f2("", "other4", OTHER, COUNT_CUMULATIVE, 777),
|
||||
f2("", "other4", OTHER, COUNT_CUMULATIVE, 111),
|
||||
f2("", "other3/a/b/c/d/e", OTHER, PERCENTAGE, 2000),
|
||||
f2("", "other3/a/b/c/d/f", OTHER, PERCENTAGE, 10),
|
||||
f2("", "other3/a/b/c/d/g", OTHER, PERCENTAGE, 5),
|
||||
f2("", "other3/a/b/c/d/g", OTHER, PERCENTAGE, 5),
|
||||
// Check that a rounded-up-to-100.00% value is shown as "100.0%" (i.e. one
|
||||
// decimal point).
|
||||
f2("", "other6/big", OTHER, COUNT, 99999),
|
||||
f2("", "other6/small", OTHER, COUNT, 1),
|
||||
// Check that a 0 / 0 is handled correctly.
|
||||
f("", "other7/zero", OTHER, 0),
|
||||
// These compartments ones shouldn't be displayed.
|
||||
f2("", "compartments/user/foo", OTHER, COUNT, 1),
|
||||
f2("", "compartments/system/foo", OTHER, COUNT, 1)
|
||||
];
|
||||
let fakeMultiReporters = [
|
||||
{ name: "fake0",
|
||||
collectReports: function(aCbObj, aClosure) {
|
||||
function f(aP, aK, aU, aA) {
|
||||
aCbObj.callback("", aP, aK, aU, aA, "Desc.", aClosure);
|
||||
}
|
||||
f("heap-allocated", OTHER, BYTES, 500 * MB);
|
||||
f("heap-unallocated", OTHER, BYTES, 100 * MB);
|
||||
f("explicit/a", HEAP, BYTES, 222 * MB);
|
||||
f("explicit/b/a", HEAP, BYTES, 85 * MB);
|
||||
f("explicit/b/b", HEAP, BYTES, 75 * MB);
|
||||
f("explicit/b/c/a", HEAP, BYTES, 70 * MB);
|
||||
f("explicit/b/c/b", HEAP, BYTES, 2 * MB); // omitted
|
||||
f("explicit/g/a", HEAP, BYTES, 6 * MB);
|
||||
f("explicit/g/b", HEAP, BYTES, 5 * MB);
|
||||
f("explicit/g/other", HEAP, BYTES, 4 * MB);
|
||||
// A degenerate tree with the same name as a non-degenerate tree should
|
||||
// work ok.
|
||||
f("explicit", OTHER, BYTES, 888 * MB);
|
||||
f("other1/a/b", OTHER, BYTES, 111 * MB);
|
||||
f("other1/c/d", OTHER, BYTES, 22 * MB);
|
||||
f("other1/c/e", OTHER, BYTES, 33 * MB);
|
||||
f("other4", OTHER, COUNT_CUMULATIVE, 777);
|
||||
f("other4", OTHER, COUNT_CUMULATIVE, 111);
|
||||
f("other3/a/b/c/d/e", OTHER, PERCENTAGE, 2000);
|
||||
f("other3/a/b/c/d/f", OTHER, PERCENTAGE, 10);
|
||||
f("other3/a/b/c/d/g", OTHER, PERCENTAGE, 5);
|
||||
f("other3/a/b/c/d/g", OTHER, PERCENTAGE, 5);
|
||||
// Check that a rounded-up-to-100.00% value is shown as "100.0%" (i.e. one
|
||||
// decimal point).
|
||||
f("other6/big", OTHER, COUNT, 99999);
|
||||
f("other6/small", OTHER, COUNT, 1);
|
||||
// Check that a 0 / 0 is handled correctly.
|
||||
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",
|
||||
collectReports: function(aCbObj, aClosure) {
|
||||
function f(aP, aK, aU, aA) {
|
||||
aCbObj.callback("", aP, aK, aU, aA, "Desc.", aClosure);
|
||||
}
|
||||
f("explicit/c/d", NONHEAP, BYTES, 13 * MB),
|
||||
f("explicit/c/d", NONHEAP, BYTES, 10 * MB), // dup
|
||||
f("explicit/c/other", NONHEAP, BYTES, 77 * MB),
|
||||
f("explicit/c/d", NONHEAP, BYTES, 13 * MB);
|
||||
f("explicit/c/d", NONHEAP, BYTES, 10 * MB); // dup
|
||||
f("explicit/c/other", NONHEAP, BYTES, 77 * MB);
|
||||
f("explicit/cc", NONHEAP, BYTES, 13 * MB);
|
||||
f("explicit/cc", NONHEAP, BYTES, 10 * MB); // dup
|
||||
f("explicit/d", NONHEAP, BYTES, 499 * 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/j", HEAP, BYTES, 10 * MB);
|
||||
},
|
||||
explicitNonHeap: (100 + 13 + 10)*MB + (499 + 100)*KB
|
||||
}
|
||||
},
|
||||
{ name: "fake2",
|
||||
collectReports: function(aCbObj, aClosure) {
|
||||
|
@ -132,8 +113,7 @@
|
|||
f("other2", OTHER, BYTES, 222 * MB);
|
||||
f("perc2", OTHER, PERCENTAGE, 10000);
|
||||
f("perc1", OTHER, PERCENTAGE, 4567);
|
||||
},
|
||||
explicitNonHeap: 0
|
||||
}
|
||||
},
|
||||
{ name: "smaps",
|
||||
collectReports: function(aCbObj, aClosure) {
|
||||
|
@ -148,8 +128,7 @@
|
|||
f("swap/b/c", 10);
|
||||
f("rss/a", 42);
|
||||
f("pss/a", 43);
|
||||
},
|
||||
explicitNonHeap: 0
|
||||
}
|
||||
},
|
||||
{ name: "compartments",
|
||||
collectReports: function(aCbObj, aClosure) {
|
||||
|
@ -158,16 +137,12 @@
|
|||
}
|
||||
f("compartments/user/bar");
|
||||
f("compartments/system/bar");
|
||||
},
|
||||
explicitNonHeap: 0
|
||||
}
|
||||
}
|
||||
];
|
||||
for (let i = 0; i < fakeReporters.length; 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:
|
||||
// - "explicit/c", "explicit/cc" x 2, "explicit/d", "explicit/e"
|
||||
|
@ -189,59 +164,74 @@
|
|||
// the largest). Processes without a |resident| memory reporter are saved
|
||||
// for the end.
|
||||
let fakeReporters2 = [
|
||||
f("2nd", "heap-allocated", OTHER, 1000 * MB),
|
||||
f("2nd", "heap-unallocated",OTHER, 100 * MB),
|
||||
f("2nd", "explicit/a/b/c", HEAP, 497 * MB),
|
||||
f("2nd", "explicit/a/b/c", HEAP, 1 * MB), // dup: merge
|
||||
f("2nd", "explicit/a/b/c", HEAP, 1 * MB), // dup: merge
|
||||
f("2nd", "explicit/flip\\the\\backslashes",
|
||||
HEAP, 200 * MB),
|
||||
f("2nd", "explicit/compartment(compartment-url)",
|
||||
HEAP, 200 * MB),
|
||||
f("2nd", "other0", OTHER, 666 * MB),
|
||||
f("2nd", "other1", OTHER, 111 * MB),
|
||||
// Even though the "smaps" reporter is a multi-reporter, if its in a
|
||||
// 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
|
||||
// process won't cause these to be skipped; the fall-back skipping will
|
||||
// be hit instead.
|
||||
f("2nd", "size/e", NONHEAP, 24*4*KB),
|
||||
f("2nd", "size/f", NONHEAP, 24*4*KB),
|
||||
{ name: "resident-fast",
|
||||
collectReports: function(aCbObj, aClosure) {
|
||||
// Shouldn't reach here; aboutMemory.js should skip the reporter.
|
||||
// (Nb: this must come after |mgr.explicit| is accessed, otherwise it
|
||||
// *will* be run by nsMemoryReporterManager::GetExplicit()).
|
||||
ok(false, "'resident-fast' reporter was run");
|
||||
}
|
||||
},
|
||||
{ name: "fake3",
|
||||
collectReports: function(aCbObj, aClosure) {
|
||||
function f(aP1, aP2, aK, aU, aA) {
|
||||
aCbObj.callback(aP1, aP2, aK, aU, aA, "Desc.", aClosure);
|
||||
}
|
||||
f("2nd", "heap-allocated", OTHER, BYTES,1000* MB);
|
||||
f("2nd", "heap-unallocated",OTHER, BYTES,100 * MB);
|
||||
f("2nd", "explicit/a/b/c", HEAP, BYTES,497 * MB);
|
||||
f("2nd", "explicit/a/b/c", HEAP, BYTES, 1 * MB); // dup: merge
|
||||
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.
|
||||
f("3rd", "explicit/a/b", HEAP, 333 * MB),
|
||||
f("3rd", "explicit/a/c", HEAP, 444 * MB),
|
||||
f("3rd", "other1", OTHER, 1 * MB),
|
||||
f("3rd", "resident", OTHER, 100 * MB),
|
||||
// Check that we can handle "heap-allocated" not being present.
|
||||
f("3rd", "explicit/a/b", HEAP, BYTES,333 * MB);
|
||||
f("3rd", "explicit/a/c", HEAP, BYTES,444 * MB);
|
||||
f("3rd", "other1", OTHER, BYTES, 1 * MB);
|
||||
f("3rd", "resident", OTHER, BYTES,100 * MB);
|
||||
|
||||
// Invalid values (negative, too-big) should be identified.
|
||||
f("4th", "heap-allocated", OTHER, 100 * MB),
|
||||
f("4th", "resident", OTHER, 200 * MB),
|
||||
f("4th", "explicit/js/compartment(http:\\\\too-big.com\\)/stuff",
|
||||
HEAP, 150 * MB),
|
||||
f("4th", "explicit/ok", HEAP, 5 * MB),
|
||||
f("4th", "explicit/neg1", NONHEAP, -2 * MB),
|
||||
// -111 becomes "-0.00MB" in non-verbose mode, and getting the negative
|
||||
// sign in there correctly is non-trivial.
|
||||
f("4th", "other1", OTHER, -111),
|
||||
f("4th", "other2", OTHER, -222 * MB),
|
||||
f2("4th", "other3", OTHER, COUNT, -333),
|
||||
f2("4th", "other4", OTHER, COUNT_CUMULATIVE, -444),
|
||||
f2("4th", "other5", OTHER, PERCENTAGE, -555),
|
||||
f2("4th", "other6", OTHER, PERCENTAGE, 66666),
|
||||
// Invalid values (negative, too-big) should be identified.
|
||||
f("4th", "heap-allocated", OTHER, BYTES,100 * MB);
|
||||
f("4th", "resident", OTHER, BYTES,200 * MB);
|
||||
f("4th", "explicit/js/compartment(http:\\\\too-big.com\\)/stuff",
|
||||
HEAP, BYTES,150 * MB);
|
||||
f("4th", "explicit/ok", HEAP, BYTES, 5 * MB);
|
||||
f("4th", "explicit/neg1", NONHEAP, BYTES, -2 * MB);
|
||||
// -111 becomes "-0.00MB" in non-verbose mode, and getting the negative
|
||||
// sign in there correctly is non-trivial.
|
||||
f("4th", "other1", OTHER, BYTES,-111);
|
||||
f("4th", "other2", OTHER, BYTES,-222 * MB);
|
||||
f("4th", "other3", OTHER, COUNT, -333);
|
||||
f("4th", "other4", OTHER, COUNT_CUMULATIVE, -444);
|
||||
f("4th", "other5", OTHER, PERCENTAGE, -555);
|
||||
f("4th", "other6", OTHER, PERCENTAGE, 66666);
|
||||
|
||||
// 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
|
||||
// be expanded, even in non-verbose mode.
|
||||
f("5th", "heap-allocated", OTHER, 100 * MB),
|
||||
f("5th", "explicit/big", HEAP, 99 * MB),
|
||||
f("5th", "explicit/a/pos", HEAP, 40 * KB),
|
||||
f("5th", "explicit/a/neg1", NONHEAP, -20 * KB),
|
||||
f("5th", "explicit/a/neg2", NONHEAP, -10 * KB),
|
||||
f("5th", "explicit/b/c/d/e", NONHEAP, 20 * KB),
|
||||
f("5th", "explicit/b/c/d/f", NONHEAP, -60 * KB),
|
||||
f("5th", "explicit/b/c/g/h", NONHEAP, 10 * KB),
|
||||
f("5th", "explicit/b/c/i/j", NONHEAP, 5 * KB)
|
||||
// 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
|
||||
// be expanded, even in non-verbose mode.
|
||||
f("5th", "heap-allocated", OTHER, BYTES,100 * MB);
|
||||
f("5th", "explicit/big", HEAP, BYTES, 99 * MB);
|
||||
f("5th", "explicit/a/pos", HEAP, BYTES, 40 * KB);
|
||||
f("5th", "explicit/a/neg1", NONHEAP, BYTES,-20 * KB);
|
||||
f("5th", "explicit/a/neg2", NONHEAP, BYTES,-10 * KB);
|
||||
f("5th", "explicit/b/c/d/e", NONHEAP, BYTES, 20 * KB);
|
||||
f("5th", "explicit/b/c/d/f", NONHEAP, BYTES,-60 * KB);
|
||||
f("5th", "explicit/b/c/g/h", NONHEAP, BYTES, 10 * KB);
|
||||
f("5th", "explicit/b/c/i/j", NONHEAP, BYTES, 5 * KB);
|
||||
}
|
||||
}
|
||||
];
|
||||
for (let i = 0; i < fakeReporters2.length; i++) {
|
||||
mgr.registerReporterEvenIfBlocked(fakeReporters2[i]);
|
||||
|
@ -586,21 +576,14 @@ Other Measurements\n\
|
|||
|
||||
function finish()
|
||||
{
|
||||
// Unregister fake reporters and multi-reporters, re-register the real
|
||||
// reporters and multi-reporters, just in case subsequent tests rely on
|
||||
// them.
|
||||
// Unregister fake reporters and re-register the real reporters, just in
|
||||
// case subsequent tests rely on them.
|
||||
for (let i = 0; i < fakeReporters.length; 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++) {
|
||||
mgr.registerReporterEvenIfBlocked(realReporters[i]);
|
||||
}
|
||||
for (let i = 0; i < realMultiReporters.length; i++) {
|
||||
mgr.registerMultiReporterEvenIfBlocked(realMultiReporters[i]);
|
||||
}
|
||||
mgr.unblockRegistration();
|
||||
|
||||
SimpleTest.finish();
|
||||
|
|
|
@ -22,8 +22,7 @@
|
|||
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
|
||||
getService(Ci.nsIMemoryReporterManager);
|
||||
|
||||
// Remove all the real reporters and multi-reporters; save them to
|
||||
// restore at the end.
|
||||
// Remove all the real reporters; save them to restore at the end.
|
||||
mgr.blockRegistration();
|
||||
let e = mgr.enumerateReporters();
|
||||
let realReporters = [];
|
||||
|
@ -32,13 +31,6 @@
|
|||
mgr.unregisterReporter(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.
|
||||
const KB = 1024;
|
||||
|
@ -47,35 +39,31 @@
|
|||
const OTHER = Ci.nsIMemoryReporter.KIND_OTHER;
|
||||
const BYTES = Ci.nsIMemoryReporter.UNITS_BYTES;
|
||||
|
||||
function f(aPath, aKind, aAmount) {
|
||||
return {
|
||||
process: "",
|
||||
path: aPath,
|
||||
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 hiPath = "explicit/h/i";
|
||||
let hi2Path = "explicit/h/i2";
|
||||
let jkPath = "explicit/j/k";
|
||||
let jk2Path = "explicit/j/k2";
|
||||
|
||||
let fakeReporters = [
|
||||
f("heap-allocated", OTHER, 250 * MB),
|
||||
f("explicit/a/b", HEAP, 50 * MB),
|
||||
f("explicit/a/c/d", HEAP, 25 * MB),
|
||||
f("explicit/a/c/e", HEAP, 15 * MB),
|
||||
f("explicit/a/f", HEAP, 30 * MB),
|
||||
f("explicit/g", HEAP, 100 * MB),
|
||||
hiReport,
|
||||
hi2Report,
|
||||
jkReport,
|
||||
jk2Report,
|
||||
f("explicit/a/l/m", HEAP, 0.1 * MB),
|
||||
f("explicit/a/l/n", HEAP, 0.1 * MB),
|
||||
{ name: "fake1",
|
||||
collectReports: function(aCbObj, aClosure) {
|
||||
function f(aP, aK, aA) {
|
||||
aCbObj.callback("", aP, aK, BYTES, aA, "Desc.", aClosure);
|
||||
}
|
||||
f("heap-allocated", OTHER, 250 * MB);
|
||||
f("explicit/a/b", HEAP, 50 * MB);
|
||||
f("explicit/a/c/d", HEAP, 25 * MB);
|
||||
f("explicit/a/c/e", HEAP, 15 * MB);
|
||||
f("explicit/a/f", HEAP, 30 * MB);
|
||||
f("explicit/g", HEAP, 100 * 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++) {
|
||||
|
@ -91,18 +79,14 @@
|
|||
<![CDATA[
|
||||
function finish()
|
||||
{
|
||||
// Unregister fake reporters and multi-reporters, re-register the real
|
||||
// reporters and multi-reporters, just in case subsequent tests rely on
|
||||
// them.
|
||||
// Unregister fake reporters and re-register the real reporters, just in
|
||||
// case subsequent tests rely on them.
|
||||
for (let i = 0; i < fakeReporters.length; i++) {
|
||||
mgr.unregisterReporter(fakeReporters[i]);
|
||||
}
|
||||
for (let i = 0; i < realReporters.length; i++) {
|
||||
mgr.registerReporterEvenIfBlocked(realReporters[i]);
|
||||
}
|
||||
for (let i = 0; i < realMultiReporters.length; i++) {
|
||||
mgr.registerMultiReporterEvenIfBlocked(realMultiReporters[i]);
|
||||
}
|
||||
mgr.unblockRegistration();
|
||||
|
||||
SimpleTest.finish();
|
||||
|
@ -119,13 +103,13 @@
|
|||
// click on a child of the span identified via |id|.
|
||||
if (node.nodeName === "button") {
|
||||
if (aSwap) {
|
||||
// We swap the paths of hiReport/hi2Report and jkReport/jk2Report
|
||||
// just before updating, to test what happens when significant nodes
|
||||
// become insignificant and vice versa.
|
||||
hiReport.path = "explicit/j/k";
|
||||
hi2Report.path = "explicit/j/k2";
|
||||
jkReport.path = "explicit/h/i";
|
||||
jk2Report.path = "explicit/h/i2";
|
||||
// We swap hipath/hi2Path and jkPath/jk2Path just before updating, to
|
||||
// test what happens when significant nodes become insignificant and
|
||||
// vice versa.
|
||||
hiPath = "explicit/j/k";
|
||||
hi2Path = "explicit/j/k2";
|
||||
jkPath = "explicit/h/i";
|
||||
jk2Path = "explicit/h/i2";
|
||||
}
|
||||
node.click();
|
||||
} else {
|
||||
|
|
|
@ -22,8 +22,7 @@
|
|||
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
|
||||
getService(Ci.nsIMemoryReporterManager);
|
||||
|
||||
// Remove all the real reporters and multi-reporters; save them to
|
||||
// restore at the end.
|
||||
// Remove all the real reporters; save them to restore at the end.
|
||||
mgr.blockRegistration();
|
||||
let e = mgr.enumerateReporters();
|
||||
let realReporters = [];
|
||||
|
@ -32,13 +31,6 @@
|
|||
mgr.unregisterReporter(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.
|
||||
const KB = 1024;
|
||||
|
@ -47,22 +39,18 @@
|
|||
const OTHER = Ci.nsIMemoryReporter.KIND_OTHER;
|
||||
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 = [
|
||||
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."),
|
||||
{ name: "fake1",
|
||||
collectReports: function(aCbObj, aClosure) {
|
||||
function f(aP, aK, aA, aD) {
|
||||
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++) {
|
||||
|
@ -78,18 +66,14 @@
|
|||
<![CDATA[
|
||||
function finish()
|
||||
{
|
||||
// Unregister fake reporters and multi-reporters, re-register the real
|
||||
// reporters and multi-reporters, just in case subsequent tests rely on
|
||||
// them.
|
||||
// Unregister fake reporters and re-register the real reporters, just in
|
||||
// case subsequent tests rely on them.
|
||||
for (let i = 0; i < fakeReporters.length; i++) {
|
||||
mgr.unregisterReporter(fakeReporters[i]);
|
||||
}
|
||||
for (let i = 0; i < realReporters.length; i++) {
|
||||
mgr.registerReporterEvenIfBlocked(realReporters[i]);
|
||||
}
|
||||
for (let i = 0; i < realMultiReporters.length; i++) {
|
||||
mgr.registerMultiReporterEvenIfBlocked(realMultiReporters[i]);
|
||||
}
|
||||
mgr.unblockRegistration();
|
||||
|
||||
SimpleTest.finish();
|
||||
|
|
|
@ -138,11 +138,6 @@
|
|||
let e = mgr.enumerateReporters();
|
||||
while (e.hasMoreElements()) {
|
||||
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);
|
||||
|
||||
// Access |name| to make sure it doesn't crash or assert.
|
||||
|
|
|
@ -36,13 +36,13 @@
|
|||
let db = storage.openDatabase(file);
|
||||
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.
|
||||
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
|
||||
getService(Ci.nsIMemoryReporterManager);
|
||||
e = mgr.enumerateMultiReporters();
|
||||
e = mgr.enumerateReporters();
|
||||
while (e.hasMoreElements()) {
|
||||
let r = e.getNext().QueryInterface(Ci.nsIMemoryMultiReporter);
|
||||
let r = e.getNext().QueryInterface(Ci.nsIMemoryReporter);
|
||||
r.collectReports(function(){}, null);
|
||||
}
|
||||
|
||||
|
|
|
@ -1908,11 +1908,11 @@ StoreAndNotifyEmbedVisit(VisitData& aPlace,
|
|||
(void)NS_DispatchToMainThread(event);
|
||||
}
|
||||
|
||||
class HistoryLinksHashtableReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class HistoryLinksHashtableReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
HistoryLinksHashtableReporter()
|
||||
: MemoryReporterBase("explicit/history-links-hashtable",
|
||||
: MemoryUniReporter("explicit/history-links-hashtable",
|
||||
KIND_HEAP, UNITS_BYTES,
|
||||
"Memory used by the hashtable that records changes to the visited state of "
|
||||
"links.")
|
||||
|
|
|
@ -363,11 +363,11 @@ TelemetryImpl::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
|
|||
return n;
|
||||
}
|
||||
|
||||
class TelemetryReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class TelemetryReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
TelemetryReporter()
|
||||
: MemoryReporterBase("explicit/telemetry", KIND_HEAP, UNITS_BYTES,
|
||||
: MemoryUniReporter("explicit/telemetry", KIND_HEAP, UNITS_BYTES,
|
||||
"Memory used by the telemetry system.")
|
||||
{}
|
||||
private:
|
||||
|
|
|
@ -8,6 +8,7 @@ const Ci = Components.interfaces;
|
|||
const Cr = Components.results;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/debug.js");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
#ifndef MOZ_WIDGET_GONK
|
||||
|
@ -458,15 +459,32 @@ TelemetryPing.prototype = {
|
|||
let e = mgr.enumerateReporters();
|
||||
while (e.hasMoreElements()) {
|
||||
let mr = e.getNext().QueryInterface(Ci.nsIMemoryReporter);
|
||||
let id = MEM_HISTOGRAMS[mr.path];
|
||||
let id = MEM_HISTOGRAMS[mr.name];
|
||||
if (!id) {
|
||||
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.
|
||||
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) {
|
||||
}
|
||||
|
@ -474,11 +492,7 @@ TelemetryPing.prototype = {
|
|||
histogram.add(new Date() - startTime);
|
||||
},
|
||||
|
||||
handleMemoryReport: function handleMemoryReport(id, path, units, amount) {
|
||||
if (amount == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
handleMemoryReport: function(id, path, units, amount) {
|
||||
let val;
|
||||
if (units == Ci.nsIMemoryReporter.UNITS_BYTES) {
|
||||
val = Math.floor(amount / 1024);
|
||||
|
|
|
@ -36,12 +36,12 @@ static const PRLogModuleInfo *gUrlClassifierPrefixSetLog = nullptr;
|
|||
#define LOG_ENABLED() (false)
|
||||
#endif
|
||||
|
||||
class PrefixSetReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class PrefixSetReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
PrefixSetReporter(nsUrlClassifierPrefixSet* aPrefixSet,
|
||||
const nsACString& aName)
|
||||
: MemoryReporterBase(
|
||||
: MemoryUniReporter(
|
||||
nsPrintfCString(
|
||||
"explicit/storage/prefix-set/%s",
|
||||
(!aName.IsEmpty() ? PromiseFlatCString(aName).get() : "?!")
|
||||
|
|
|
@ -325,37 +325,19 @@ CreateDIBSectionHook(HDC aDC,
|
|||
return result;
|
||||
}
|
||||
|
||||
class LowMemoryEventsVirtualReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class LowMemoryEventsVirtualReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
// The description is "???" because we implement GetDescription().
|
||||
LowMemoryEventsVirtualReporter()
|
||||
: MemoryReporterBase("low-memory-events/virtual",
|
||||
KIND_OTHER, UNITS_COUNT_CUMULATIVE, "???")
|
||||
: MemoryUniReporter("low-memory-events/virtual",
|
||||
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:
|
||||
int64_t Amount() MOZ_OVERRIDE
|
||||
{
|
||||
|
@ -367,73 +349,36 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
class LowCommitSpaceEventsReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class LowCommitSpaceEventsReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
// The description is "???" because we implement GetDescription().
|
||||
LowCommitSpaceEventsReporter()
|
||||
: MemoryReporterBase("low-commit-space-events",
|
||||
KIND_OTHER, UNITS_COUNT_CUMULATIVE, "???")
|
||||
: MemoryUniReporter("low-commit-space-events",
|
||||
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:
|
||||
int64_t Amount() MOZ_OVERRIDE { return sNumLowCommitSpaceEvents; }
|
||||
};
|
||||
|
||||
class LowMemoryEventsPhysicalReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class LowMemoryEventsPhysicalReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
// The description is "???" because we implement GetDescription().
|
||||
LowMemoryEventsPhysicalReporter()
|
||||
: MemoryReporterBase("low-memory-events/physical",
|
||||
KIND_OTHER, UNITS_COUNT_CUMULATIVE, "???")
|
||||
: MemoryUniReporter("low-memory-events/physical",
|
||||
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:
|
||||
int64_t Amount() MOZ_OVERRIDE { return sNumLowPhysicalMemEvents; }
|
||||
};
|
||||
|
|
|
@ -111,7 +111,7 @@ struct CategoriesSeen {
|
|||
|
||||
} // anonymous namespace
|
||||
|
||||
class MapsReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
||||
class MapsReporter MOZ_FINAL : public nsIMemoryReporter
|
||||
{
|
||||
public:
|
||||
MapsReporter();
|
||||
|
@ -125,7 +125,7 @@ public:
|
|||
}
|
||||
|
||||
NS_IMETHOD
|
||||
CollectReports(nsIMemoryMultiReporterCallback *aCb,
|
||||
CollectReports(nsIMemoryReporterCallback *aCb,
|
||||
nsISupports *aClosure);
|
||||
|
||||
private:
|
||||
|
@ -135,7 +135,7 @@ private:
|
|||
|
||||
nsresult
|
||||
ParseMapping(FILE *aFile,
|
||||
nsIMemoryMultiReporterCallback *aCb,
|
||||
nsIMemoryReporterCallback *aCb,
|
||||
nsISupports *aClosure,
|
||||
CategoriesSeen *aCategoriesSeen);
|
||||
|
||||
|
@ -149,7 +149,7 @@ private:
|
|||
ParseMapBody(FILE *aFile,
|
||||
const nsACString &aName,
|
||||
const nsACString &aDescription,
|
||||
nsIMemoryMultiReporterCallback *aCb,
|
||||
nsIMemoryReporterCallback *aCb,
|
||||
nsISupports *aClosure,
|
||||
CategoriesSeen *aCategoriesSeen);
|
||||
|
||||
|
@ -158,7 +158,7 @@ private:
|
|||
nsTHashtable<nsCStringHashKey> mMozillaLibraries;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(MapsReporter, nsIMemoryMultiReporter)
|
||||
NS_IMPL_ISUPPORTS1(MapsReporter, nsIMemoryReporter)
|
||||
|
||||
MapsReporter::MapsReporter()
|
||||
: mSearchedForLibxul(false)
|
||||
|
@ -173,7 +173,7 @@ MapsReporter::MapsReporter()
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MapsReporter::CollectReports(nsIMemoryMultiReporterCallback *aCb,
|
||||
MapsReporter::CollectReports(nsIMemoryReporterCallback *aCb,
|
||||
nsISupports *aClosure)
|
||||
{
|
||||
CategoriesSeen categoriesSeen;
|
||||
|
@ -258,7 +258,7 @@ MapsReporter::FindLibxul()
|
|||
nsresult
|
||||
MapsReporter::ParseMapping(
|
||||
FILE *aFile,
|
||||
nsIMemoryMultiReporterCallback *aCb,
|
||||
nsIMemoryReporterCallback *aCb,
|
||||
nsISupports *aClosure,
|
||||
CategoriesSeen *aCategoriesSeen)
|
||||
{
|
||||
|
@ -461,7 +461,7 @@ MapsReporter::ParseMapBody(
|
|||
FILE *aFile,
|
||||
const nsACString &aName,
|
||||
const nsACString &aDescription,
|
||||
nsIMemoryMultiReporterCallback *aCb,
|
||||
nsIMemoryReporterCallback *aCb,
|
||||
nsISupports *aClosure,
|
||||
CategoriesSeen *aCategoriesSeen)
|
||||
{
|
||||
|
@ -520,11 +520,11 @@ MapsReporter::ParseMapBody(
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
class ResidentUniqueReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class ResidentUniqueReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
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 "
|
||||
"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 "
|
||||
|
@ -540,9 +540,9 @@ private:
|
|||
// little to do with whether the pages are actually shared. smaps on the
|
||||
// other hand appears to give us the correct information.
|
||||
//
|
||||
// We could calculate this data during the smaps multi-reporter, but the
|
||||
// overhead of the smaps reporter is considerable (we don't even run the
|
||||
// smaps reporter in normal about:memory operation). Hopefully this
|
||||
// We could calculate this data within the smaps reporter, but the overhead
|
||||
// of the smaps reporter is considerable (we don't even run the smaps
|
||||
// reporter in normal about:memory operation). Hopefully this
|
||||
// implementation is fast enough not to matter.
|
||||
|
||||
*aAmount = 0;
|
||||
|
@ -568,8 +568,8 @@ private:
|
|||
|
||||
void Init()
|
||||
{
|
||||
nsCOMPtr<nsIMemoryMultiReporter> reporter = new MapsReporter();
|
||||
NS_RegisterMemoryMultiReporter(reporter);
|
||||
nsCOMPtr<nsIMemoryReporter> reporter = new MapsReporter();
|
||||
NS_RegisterMemoryReporter(reporter);
|
||||
|
||||
NS_RegisterMemoryReporter(new ResidentUniqueReporter());
|
||||
}
|
||||
|
|
|
@ -934,7 +934,7 @@ class nsCycleCollector
|
|||
CC_BeforeUnlinkCallback mBeforeUnlinkCB;
|
||||
CC_ForgetSkippableCallback mForgetSkippableCB;
|
||||
|
||||
nsCOMPtr<nsIMemoryMultiReporter> mReporter;
|
||||
nsCOMPtr<nsIMemoryReporter> mReporter;
|
||||
|
||||
nsPurpleBuffer mPurpleBuf;
|
||||
|
||||
|
@ -2407,10 +2407,10 @@ nsCycleCollector::CollectWhite()
|
|||
// Memory reporter
|
||||
////////////////////////
|
||||
|
||||
class CycleCollectorMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
||||
class CycleCollectorReporter MOZ_FINAL : public nsIMemoryReporter
|
||||
{
|
||||
public:
|
||||
CycleCollectorMultiReporter(nsCycleCollector* aCollector)
|
||||
CycleCollectorReporter(nsCycleCollector* aCollector)
|
||||
: mCollector(aCollector)
|
||||
{}
|
||||
|
||||
|
@ -2422,7 +2422,7 @@ class CycleCollectorMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback* aCb,
|
||||
NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCb,
|
||||
nsISupports* aClosure)
|
||||
{
|
||||
size_t objectSize, graphNodesSize, graphEdgesSize, weakMapsSize,
|
||||
|
@ -2481,7 +2481,7 @@ class CycleCollectorMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
|||
nsCycleCollector* mCollector;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(CycleCollectorMultiReporter, nsIMemoryMultiReporter)
|
||||
NS_IMPL_ISUPPORTS1(CycleCollectorReporter, nsIMemoryReporter)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
@ -2508,7 +2508,7 @@ nsCycleCollector::nsCycleCollector() :
|
|||
|
||||
nsCycleCollector::~nsCycleCollector()
|
||||
{
|
||||
NS_UnregisterMemoryMultiReporter(mReporter);
|
||||
NS_UnregisterMemoryReporter(mReporter);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2524,7 +2524,7 @@ nsCycleCollector::RegisterJSRuntime(CycleCollectedJSRuntime *aJSRuntime)
|
|||
// instead.
|
||||
static bool registered = false;
|
||||
if (!registered) {
|
||||
NS_RegisterMemoryMultiReporter(new CycleCollectorMultiReporter(this));
|
||||
NS_RegisterMemoryReporter(new CycleCollectorReporter(this));
|
||||
registered = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,55 +17,22 @@ interface nsICancelableRunnable;
|
|||
* reporter.
|
||||
*/
|
||||
|
||||
/*
|
||||
* An nsIMemoryReporter reports a single memory measurement as an object.
|
||||
* 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
|
||||
[scriptable, function, uuid(3a61be3b-b93b-461a-a4f8-388214f558b1)]
|
||||
interface nsIMemoryReporterCallback : nsISupports
|
||||
{
|
||||
/*
|
||||
* The name of the process containing this reporter. Each reporter initially
|
||||
* 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' field set appropriately.
|
||||
*/
|
||||
readonly attribute ACString process;
|
||||
|
||||
/*
|
||||
* The path that this memory usage should be reported under. Paths are
|
||||
* '/'-delimited, eg. "a/b/c".
|
||||
* The arguments to the callback are as follows.
|
||||
*
|
||||
*
|
||||
* |process| The name of the process containing this reporter. Each
|
||||
* reporter initially 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' field set appropriately.
|
||||
*
|
||||
*
|
||||
* |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.
|
||||
* 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
|
||||
* "degenerate", i.e. contain a single entry with no '/'.
|
||||
*/
|
||||
readonly attribute AUTF8String path;
|
||||
|
||||
/*
|
||||
* There are three kinds of memory reporters.
|
||||
*
|
||||
*
|
||||
* |kind| There are three kinds of memory reporters.
|
||||
*
|
||||
* - HEAP: reporters measuring memory allocated by the heap allocator,
|
||||
* 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;
|
||||
* aboutMemory.js uses it to calculate "heap-unclassified".
|
||||
*/
|
||||
const int32_t KIND_NONHEAP = 0;
|
||||
const int32_t KIND_HEAP = 1;
|
||||
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:
|
||||
*
|
||||
*
|
||||
* |units| The units on the reporter's amount. One of the following.
|
||||
*
|
||||
* - BYTES: The amount contains a number of bytes.
|
||||
*
|
||||
|
@ -156,67 +111,84 @@ interface nsIMemoryReporter : nsISupports
|
|||
* be 1234.
|
||||
*
|
||||
* 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,
|
||||
in int32_t units, in int64_t amount,
|
||||
in AUTF8String description, in nsISupports closure);
|
||||
};
|
||||
|
||||
/*
|
||||
* An nsIMemoryMultiReporter reports multiple memory measurements via a
|
||||
* callback function which is called once for each measurement. Use this
|
||||
* when you want to gather multiple measurements in a single operation (eg.
|
||||
* a single traversal of a large data structure).
|
||||
* An nsIMemoryReporter reports one or more memory measurements via a
|
||||
* callback function which is called once for each measurement.
|
||||
*
|
||||
* The arguments to the callback deliberately match the fields in
|
||||
* nsIMemoryReporter, but note that seeing any of these arguments requires
|
||||
* calling collectReports which will trigger all relevant computation.
|
||||
* (Compare and contrast this with nsIMemoryReporter, which allows all
|
||||
* fields except |amount| to be accessed without triggering computation.)
|
||||
* An nsIMemoryReporter that reports a single measurement is sometimes called a
|
||||
* "uni-reporter". One that reports multiple measurements is sometimes called
|
||||
* a "multi-reporter".
|
||||
*
|
||||
* 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)]
|
||||
interface nsIMemoryMultiReporter : nsISupports
|
||||
[scriptable, uuid(53248304-124b-43cd-99dc-6e5797b91618)]
|
||||
interface nsIMemoryReporter : nsISupports
|
||||
{
|
||||
/*
|
||||
* The name of the multi-reporter. Useful when only one multi-reporter
|
||||
* needs to be run. Must be unique; if multi-reporters share names it's
|
||||
* likely the wrong one will be called in certain circumstances.
|
||||
* The name of the reporter. Useful when only one reporter needs to be run.
|
||||
* Must be unique; if reporters share names it's likely the wrong one will
|
||||
* be called in certain circumstances.
|
||||
*/
|
||||
readonly attribute ACString name;
|
||||
|
||||
/*
|
||||
* Run the multi-reporter.
|
||||
* Run the reporter.
|
||||
*/
|
||||
void collectReports(in nsIMemoryMultiReporterCallback callback,
|
||||
void collectReports(in nsIMemoryReporterCallback callback,
|
||||
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
|
||||
{
|
||||
/*
|
||||
|
@ -224,12 +196,6 @@ interface nsIMemoryReporterManager : nsISupports
|
|||
*/
|
||||
nsISimpleEnumerator enumerateReporters ();
|
||||
|
||||
/*
|
||||
* Return an enumerator of nsIMemoryMultiReporters that are currently
|
||||
* registered.
|
||||
*/
|
||||
nsISimpleEnumerator enumerateMultiReporters ();
|
||||
|
||||
/*
|
||||
* Register the given nsIMemoryReporter. After a reporter is registered,
|
||||
* it will be available via enumerateReporters(). The Manager service
|
||||
|
@ -237,31 +203,17 @@ interface nsIMemoryReporterManager : nsISupports
|
|||
*/
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
void blockRegistration();
|
||||
void unblockRegistration();
|
||||
void registerReporterEvenIfBlocked(in nsIMemoryReporter aReporter);
|
||||
void registerMultiReporterEvenIfBlocked(in nsIMemoryMultiReporter aReporter);
|
||||
|
||||
/*
|
||||
* Initialize.
|
||||
|
@ -280,8 +232,8 @@ interface nsIMemoryReporterManager : nsISupports
|
|||
* (eg. via mmap, VirtualAlloc) and at the heap level (eg. via malloc,
|
||||
* calloc, operator new). (Nb: it covers all heap allocations, but will
|
||||
* miss any OS-level ones not covered by memory reporters.) This reporter
|
||||
* is special-cased because it's interesting, and is moderately difficult
|
||||
* to compute in JS. Accesses can fail.
|
||||
* is special-cased because it's interesting, and is difficult to compute
|
||||
* from JavaScript code. Accesses can fail.
|
||||
*/
|
||||
readonly attribute int64_t explicit;
|
||||
|
||||
|
@ -307,10 +259,7 @@ interface nsIMemoryReporterManager : nsISupports
|
|||
// instead of nsCOMPtr<nsIMemoryReporter>.
|
||||
|
||||
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_UnregisterMemoryMultiReporter(nsIMemoryMultiReporter* aReporter);
|
||||
|
||||
#if defined(MOZ_DMD)
|
||||
namespace mozilla {
|
||||
|
@ -375,10 +324,11 @@ void RunReporters();
|
|||
namespace mozilla {
|
||||
|
||||
// The following base class reduces the amount of boilerplate code required for
|
||||
// memory reporters. You just need to provide the following.
|
||||
// - The constant values: path, kind, units, and description. They are passed
|
||||
// to the MemoryReporterBase constructor.
|
||||
// - A (private) Amount() or (public) GetAmount() method. It can use the
|
||||
// memory uni-reporters. You just need to provide the following.
|
||||
// - The constant values: nameAndPath (which serves as both the reporters name,
|
||||
// and the path in its single report), kind, units, and description. They
|
||||
// are passed to the MemoryUniReporter constructor.
|
||||
// - A (private) Amount() or (public) GetAmount() method. It can use the
|
||||
// MallocSizeOf method if necessary. (There is also
|
||||
// MallocSizeOfOn{Alloc,Free}, which can be useful.) Use Amount() if the
|
||||
// reporter is infallible, and GetAmount() otherwise. (If you fail to
|
||||
|
@ -390,58 +340,45 @@ namespace mozilla {
|
|||
// - "explicit/dom/xyzzy" --> DOMXyzzyReporter
|
||||
// - "js-compartments/system" --> JSCompartmentsSystemReporter
|
||||
//
|
||||
class MemoryReporterBase : public nsIMemoryReporter
|
||||
class MemoryUniReporter : public nsIMemoryReporter
|
||||
{
|
||||
public:
|
||||
MemoryReporterBase(const char* aPath, int32_t aKind, int32_t aUnits,
|
||||
const char* aDescription)
|
||||
: mPath(aPath)
|
||||
MemoryUniReporter(const char* aNameAndPath, int32_t aKind, int32_t aUnits,
|
||||
const char* aDescription)
|
||||
: mNameAndPath(aNameAndPath)
|
||||
, mKind(aKind)
|
||||
, mUnits(aUnits)
|
||||
, mDescription(aDescription)
|
||||
{}
|
||||
|
||||
virtual ~MemoryReporterBase() {}
|
||||
virtual ~MemoryUniReporter() {}
|
||||
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
NS_IMETHOD GetProcess(nsACString& aProcess)
|
||||
NS_IMETHOD GetName(nsACString& aName)
|
||||
{
|
||||
aProcess.Truncate();
|
||||
aName.Assign(mNameAndPath);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD GetPath(nsACString& aPath)
|
||||
NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCallback,
|
||||
nsISupports* aClosure)
|
||||
{
|
||||
aPath.Assign(mPath);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD GetKind(int32_t* aKind)
|
||||
{
|
||||
*aKind = mKind;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD GetUnits(int32_t* aUnits)
|
||||
{
|
||||
*aUnits = mUnits;
|
||||
return NS_OK;
|
||||
int64_t amount;
|
||||
nsresult rv = GetAmount(&amount);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return aCallback->Callback(EmptyCString(), mNameAndPath, mKind, mUnits,
|
||||
amount, mDescription, aClosure);
|
||||
}
|
||||
|
||||
protected:
|
||||
NS_IMETHOD GetAmount(int64_t* aAmount)
|
||||
{
|
||||
*aAmount = Amount();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD GetDescription(nsACString& aDescription)
|
||||
{
|
||||
aDescription.Assign(mDescription);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual int64_t Amount()
|
||||
{
|
||||
// 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_FREE_FUN(MallocSizeOfOnFree)
|
||||
|
||||
const nsCString mPath;
|
||||
const nsCString mNameAndPath;
|
||||
const int32_t mKind;
|
||||
const int32_t mUnits;
|
||||
const nsCString mDescription;
|
||||
|
|
|
@ -672,32 +672,35 @@ DumpReport(nsIGZFileWriter *aWriter, bool aIsFirst,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
class DumpMultiReporterCallback MOZ_FINAL : public nsIMemoryMultiReporterCallback
|
||||
class DumpReporterCallback MOZ_FINAL : public nsIMemoryReporterCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Callback(const nsACString &aProcess, const nsACString &aPath,
|
||||
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);
|
||||
DumpReporterCallback(bool* aIsFirstPtr) : mIsFirstPtr(aIsFirstPtr) {}
|
||||
|
||||
// The |isFirst = false| assumes that at least one single reporter is
|
||||
// present and so will have been processed in
|
||||
// DumpProcessMemoryReportsToGZFileWriter() below.
|
||||
return DumpReport(writer, /* isFirst = */ false, aProcess, aPath,
|
||||
aKind, aUnits, aAmount, aDescription);
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD Callback(const nsACString &aProcess, const nsACString &aPath,
|
||||
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
|
||||
// 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(
|
||||
DumpMultiReporterCallback
|
||||
, nsIMemoryMultiReporterCallback
|
||||
)
|
||||
NS_IMPL_ISUPPORTS1(DumpReporterCallback, nsIMemoryReporterCallback)
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -795,8 +798,6 @@ DMDWrite(void* aState, const char* aFmt, va_list ap)
|
|||
static nsresult
|
||||
DumpProcessMemoryReportsToGZFileWriter(nsIGZFileWriter *aWriter)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// Increment this number if the format changes.
|
||||
//
|
||||
// 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, " \"reports\": ");
|
||||
|
||||
// Process single reporters.
|
||||
// Process reporters.
|
||||
bool isFirst = true;
|
||||
bool more;
|
||||
nsCOMPtr<nsISimpleEnumerator> e;
|
||||
mgr->EnumerateReporters(getter_AddRefs(e));
|
||||
nsRefPtr<DumpReporterCallback> cb = new DumpReporterCallback(&isFirst);
|
||||
while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) {
|
||||
nsCOMPtr<nsIMemoryReporter> 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -327,11 +327,11 @@ static nsresult GetResidentFast(int64_t* aN)
|
|||
}
|
||||
|
||||
#define HAVE_PRIVATE_REPORTER
|
||||
class PrivateReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class PrivateReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
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 "
|
||||
"committed and marked MEM_PRIVATE, data that is not mapped, and executable "
|
||||
"pages that have been written to.")
|
||||
|
@ -356,11 +356,11 @@ public:
|
|||
#endif // XP_<PLATFORM>
|
||||
|
||||
#ifdef HAVE_VSIZE_AND_RESIDENT_REPORTERS
|
||||
class VsizeReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class VsizeReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
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, "
|
||||
"thread stacks, memory explicitly mapped by the process via mmap and similar "
|
||||
"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); }
|
||||
};
|
||||
|
||||
class ResidentReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class ResidentReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
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 "
|
||||
"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 "
|
||||
|
@ -389,11 +389,11 @@ public:
|
|||
NS_IMETHOD GetAmount(int64_t* aAmount) { return GetResident(aAmount); }
|
||||
};
|
||||
|
||||
class ResidentFastReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class ResidentFastReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
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 "
|
||||
"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 "
|
||||
|
@ -412,11 +412,11 @@ public:
|
|||
|
||||
#define HAVE_PAGE_FAULT_REPORTERS 1
|
||||
|
||||
class PageFaultsSoftReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class PageFaultsSoftReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
PageFaultsSoftReporter()
|
||||
: MemoryReporterBase("page-faults-soft", KIND_OTHER,
|
||||
: MemoryUniReporter("page-faults-soft", KIND_OTHER,
|
||||
UNITS_COUNT_CUMULATIVE,
|
||||
"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 "
|
||||
|
@ -441,11 +441,11 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class PageFaultsHardReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class PageFaultsHardReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
PageFaultsHardReporter()
|
||||
: MemoryReporterBase("page-faults-hard", KIND_OTHER,
|
||||
: MemoryUniReporter("page-faults-hard", KIND_OTHER,
|
||||
UNITS_COUNT_CUMULATIVE,
|
||||
"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 "
|
||||
|
@ -479,11 +479,11 @@ public:
|
|||
|
||||
#ifdef HAVE_JEMALLOC_STATS
|
||||
|
||||
class HeapAllocatedReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class HeapAllocatedReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
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 "
|
||||
"application. This may exceed the amount of memory requested by 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:
|
||||
// We mark this and the other heap-overhead reporters as KIND_NONHEAP
|
||||
// because KIND_HEAP memory means "counted in heap-allocated", which this
|
||||
// is not.
|
||||
HeapOverheadWasteReporter()
|
||||
: MemoryReporterBase("explicit/heap-overhead/waste",
|
||||
: MemoryUniReporter("explicit/heap-overhead/waste",
|
||||
KIND_NONHEAP, UNITS_BYTES,
|
||||
"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 "
|
||||
|
@ -522,11 +522,11 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
class HeapOverheadBookkeepingReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class HeapOverheadBookkeepingReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
HeapOverheadBookkeepingReporter()
|
||||
: MemoryReporterBase("explicit/heap-overhead/bookkeeping",
|
||||
: MemoryUniReporter("explicit/heap-overhead/bookkeeping",
|
||||
KIND_NONHEAP, UNITS_BYTES,
|
||||
"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:
|
||||
HeapOverheadPageCacheReporter()
|
||||
: MemoryReporterBase("explicit/heap-overhead/page-cache",
|
||||
: MemoryUniReporter("explicit/heap-overhead/page-cache",
|
||||
KIND_NONHEAP, UNITS_BYTES,
|
||||
"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 "
|
||||
|
@ -559,11 +559,11 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
class HeapCommittedReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class HeapCommittedReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
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 or paged to disk. This value corresponds to 'heap-allocated' + "
|
||||
"'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:
|
||||
HeapOverheadRatioReporter()
|
||||
: MemoryReporterBase("heap-overhead-ratio", KIND_OTHER,
|
||||
: MemoryUniReporter("heap-overhead-ratio", KIND_OTHER,
|
||||
UNITS_PERCENTAGE,
|
||||
"Ratio of committed, unused bytes to allocated bytes; i.e., "
|
||||
"'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,
|
||||
// and that happens before XPCOM components are initialized, which means the
|
||||
// NS_RegisterMemoryReporter call fails. So instead we do it here.
|
||||
class AtomTablesReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class AtomTablesReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
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.")
|
||||
{}
|
||||
private:
|
||||
|
@ -623,10 +623,10 @@ private:
|
|||
namespace mozilla {
|
||||
namespace dmd {
|
||||
|
||||
class DMDMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
||||
class DMDReporter MOZ_FINAL : public nsIMemoryReporter
|
||||
{
|
||||
public:
|
||||
DMDMultiReporter()
|
||||
DMDReporter()
|
||||
{}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -637,7 +637,7 @@ public:
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback* aCallback,
|
||||
NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCallback,
|
||||
nsISupports* aClosure)
|
||||
{
|
||||
dmd::Sizes sizes;
|
||||
|
@ -677,7 +677,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(DMDMultiReporter, nsIMemoryMultiReporter)
|
||||
NS_IMPL_ISUPPORTS1(DMDReporter, nsIMemoryReporter)
|
||||
|
||||
} // namespace dmd
|
||||
} // namespace mozilla
|
||||
|
@ -725,7 +725,7 @@ nsMemoryReporterManager::Init()
|
|||
RegisterReporter(new AtomTablesReporter);
|
||||
|
||||
#ifdef MOZ_DMD
|
||||
RegisterMultiReporter(new mozilla::dmd::DMDMultiReporter);
|
||||
RegisterReporter(new mozilla::dmd::DMDReporter);
|
||||
#endif
|
||||
|
||||
#if defined(XP_LINUX)
|
||||
|
@ -825,23 +825,6 @@ nsMemoryReporterManager::EnumerateReporters(nsISimpleEnumerator** aResult)
|
|||
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
|
||||
DebugAssertRefcountIsNonZero(nsISupports* aObj)
|
||||
{
|
||||
|
@ -897,41 +880,6 @@ nsMemoryReporterManager::RegisterReporterEvenIfBlocked(
|
|||
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
|
||||
nsMemoryReporterManager::UnregisterReporter(nsIMemoryReporter* aReporter)
|
||||
{
|
||||
|
@ -946,20 +894,6 @@ nsMemoryReporterManager::UnregisterReporter(nsIMemoryReporter* aReporter)
|
|||
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
|
||||
nsMemoryReporterManager::BlockRegistration()
|
||||
{
|
||||
|
@ -996,7 +930,7 @@ nsMemoryReporterManager::GetResident(int64_t* aResident)
|
|||
}
|
||||
|
||||
// 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 {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -1005,7 +939,7 @@ public:
|
|||
};
|
||||
NS_IMPL_ISUPPORTS0(Int64Wrapper)
|
||||
|
||||
class ExplicitNonHeapCountingCallback MOZ_FINAL : public nsIMemoryMultiReporterCallback
|
||||
class ExplicitCallback MOZ_FINAL : public nsIMemoryReporterCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -1013,23 +947,20 @@ public:
|
|||
NS_IMETHOD Callback(const nsACString& aProcess, const nsACString& aPath,
|
||||
int32_t aKind, int32_t aUnits, int64_t aAmount,
|
||||
const nsACString& aDescription,
|
||||
nsISupports* aWrappedExplicitNonHeap)
|
||||
nsISupports* aWrappedExplicit)
|
||||
{
|
||||
if (aKind == nsIMemoryReporter::KIND_NONHEAP &&
|
||||
PromiseFlatCString(aPath).Find("explicit") == 0 &&
|
||||
aAmount != int64_t(-1))
|
||||
if (aPath.Equals("heap-allocated") ||
|
||||
(aKind == nsIMemoryReporter::KIND_NONHEAP &&
|
||||
PromiseFlatCString(aPath).Find("explicit") == 0))
|
||||
{
|
||||
Int64Wrapper* wrappedPRInt64 =
|
||||
static_cast<Int64Wrapper*>(aWrappedExplicitNonHeap);
|
||||
wrappedPRInt64->mValue += aAmount;
|
||||
Int64Wrapper* wrappedInt64 =
|
||||
static_cast<Int64Wrapper*>(aWrappedExplicit);
|
||||
wrappedInt64->mValue += aAmount;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
NS_IMPL_ISUPPORTS1(
|
||||
ExplicitNonHeapCountingCallback
|
||||
, nsIMemoryMultiReporterCallback
|
||||
)
|
||||
NS_IMPL_ISUPPORTS1(ExplicitCallback, nsIMemoryReporterCallback)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMemoryReporterManager::GetExplicit(int64_t* aExplicit)
|
||||
|
@ -1042,63 +973,25 @@ nsMemoryReporterManager::GetExplicit(int64_t* aExplicit)
|
|||
nsresult rv;
|
||||
bool more;
|
||||
|
||||
// Get "heap-allocated" and all the KIND_NONHEAP measurements from normal
|
||||
// (i.e. non-multi) "explicit" reporters.
|
||||
int64_t heapAllocated = int64_t(-1);
|
||||
int64_t explicitNonHeapNormalSize = 0;
|
||||
// For each reporter we call CollectReports and filter out the
|
||||
// non-explicit, non-NONHEAP measurements (except for "heap-allocated").
|
||||
// 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<ExplicitCallback> cb = new ExplicitCallback();
|
||||
nsRefPtr<Int64Wrapper> wrappedExplicitSize = new Int64Wrapper();
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> e;
|
||||
EnumerateReporters(getter_AddRefs(e));
|
||||
while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) {
|
||||
nsCOMPtr<nsIMemoryReporter> r;
|
||||
e->GetNext(getter_AddRefs(r));
|
||||
|
||||
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);
|
||||
}
|
||||
r->CollectReports(cb, wrappedExplicitSize);
|
||||
}
|
||||
|
||||
// For each multi-reporter we call CollectReports and filter out the
|
||||
// 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.
|
||||
*aExplicit = wrappedExplicitSize->mValue;
|
||||
|
||||
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;
|
||||
#endif // HAVE_JEMALLOC_STATS
|
||||
}
|
||||
|
@ -1203,7 +1096,7 @@ nsMemoryReporterManager::MinimizeMemoryUsage(nsIRunnable* aCallback,
|
|||
// 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
|
||||
// infrequently enough that the performance cost should be negligible.
|
||||
NS_IMPL_ISUPPORTS1(MemoryReporterBase, nsIMemoryReporter)
|
||||
NS_IMPL_ISUPPORTS1(MemoryUniReporter, nsIMemoryReporter)
|
||||
|
||||
nsresult
|
||||
NS_RegisterMemoryReporter(nsIMemoryReporter* aReporter)
|
||||
|
@ -1215,16 +1108,6 @@ NS_RegisterMemoryReporter(nsIMemoryReporter* 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
|
||||
NS_UnregisterMemoryReporter(nsIMemoryReporter* aReporter)
|
||||
{
|
||||
|
@ -1235,22 +1118,12 @@ NS_UnregisterMemoryReporter(nsIMemoryReporter* 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)
|
||||
|
||||
namespace mozilla {
|
||||
namespace dmd {
|
||||
|
||||
class NullMultiReporterCallback : public nsIMemoryMultiReporterCallback
|
||||
class NullReporterCallback : public nsIMemoryReporterCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -1265,8 +1138,8 @@ public:
|
|||
}
|
||||
};
|
||||
NS_IMPL_ISUPPORTS1(
|
||||
NullMultiReporterCallback
|
||||
, nsIMemoryMultiReporterCallback
|
||||
NullReporterCallback
|
||||
, nsIMemoryReporterCallback
|
||||
)
|
||||
|
||||
void
|
||||
|
@ -1275,48 +1148,15 @@ RunReporters()
|
|||
nsCOMPtr<nsIMemoryReporterManager> mgr =
|
||||
do_GetService("@mozilla.org/memory-reporter-manager;1");
|
||||
|
||||
// Do vanilla reporters.
|
||||
nsRefPtr<NullReporterCallback> cb = new NullReporterCallback();
|
||||
|
||||
bool more;
|
||||
nsCOMPtr<nsISimpleEnumerator> e;
|
||||
mgr->EnumerateReporters(getter_AddRefs(e));
|
||||
bool more;
|
||||
while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) {
|
||||
nsCOMPtr<nsIMemoryReporter> r;
|
||||
e->GetNext(getter_AddRefs(r));
|
||||
|
||||
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);
|
||||
r->CollectReports(cb, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,11 +24,8 @@ public:
|
|||
|
||||
private:
|
||||
nsresult RegisterReporterHelper(nsIMemoryReporter *reporter, bool aForce);
|
||||
nsresult RegisterMultiReporterHelper(nsIMemoryMultiReporter *reporter,
|
||||
bool aForce);
|
||||
|
||||
nsTHashtable<nsISupportsHashKey> mReporters;
|
||||
nsTHashtable<nsISupportsHashKey> mMultiReporters;
|
||||
Mutex mMutex;
|
||||
bool mIsRegistrationBlocked;
|
||||
};
|
||||
|
|
|
@ -332,11 +332,11 @@ NS_InitXPCOM(nsIServiceManager* *result,
|
|||
return NS_InitXPCOM2(result, binDirectory, nullptr);
|
||||
}
|
||||
|
||||
class ICUReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class ICUReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
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.")
|
||||
{
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -401,11 +401,11 @@ CategoryEnumerator::enumfunc_createenumerator(const char* aStr, CategoryNode* aN
|
|||
|
||||
NS_IMPL_QUERY_INTERFACE1(nsCategoryManager, nsICategoryManager)
|
||||
|
||||
class XPCOMCategoryManagerReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class XPCOMCategoryManagerReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
XPCOMCategoryManagerReporter()
|
||||
: MemoryReporterBase("explicit/xpcom/category-manager",
|
||||
: MemoryUniReporter("explicit/xpcom/category-manager",
|
||||
KIND_HEAP, UNITS_BYTES,
|
||||
"Memory used for the XPCOM category manager.")
|
||||
{}
|
||||
|
|
|
@ -280,11 +280,11 @@ CloneAndAppend(nsIFile* aBase, const nsACString& append)
|
|||
// nsComponentManagerImpl
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class XPCOMComponentManagerReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class XPCOMComponentManagerReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
XPCOMComponentManagerReporter()
|
||||
: MemoryReporterBase("explicit/xpcom/component-manager",
|
||||
: MemoryUniReporter("explicit/xpcom/component-manager",
|
||||
KIND_HEAP, UNITS_BYTES,
|
||||
"Memory used for the XPCOM component manager.")
|
||||
{}
|
||||
|
|
|
@ -48,18 +48,18 @@ GetObserverServiceLog()
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
class ObserverServiceReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
||||
class ObserverServiceReporter MOZ_FINAL : public nsIMemoryReporter
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMEMORYMULTIREPORTER
|
||||
NS_DECL_NSIMEMORYREPORTER
|
||||
protected:
|
||||
static const size_t kSuspectReferentCount = 1000;
|
||||
static PLDHashOperator CountReferents(nsObserverList* aObserverList,
|
||||
void* aClosure);
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(ObserverServiceReporter, nsIMemoryMultiReporter)
|
||||
NS_IMPL_ISUPPORTS1(ObserverServiceReporter, nsIMemoryReporter)
|
||||
|
||||
NS_IMETHODIMP
|
||||
ObserverServiceReporter::GetName(nsACString& aName)
|
||||
|
@ -128,7 +128,7 @@ ObserverServiceReporter::CountReferents(nsObserverList* aObserverList,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ObserverServiceReporter::CollectReports(nsIMemoryMultiReporterCallback* cb,
|
||||
ObserverServiceReporter::CollectReports(nsIMemoryReporterCallback* cb,
|
||||
nsISupports* aClosure)
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
|
@ -219,14 +219,14 @@ void
|
|||
nsObserverService::RegisterReporter()
|
||||
{
|
||||
mReporter = new ObserverServiceReporter();
|
||||
NS_RegisterMemoryMultiReporter(mReporter);
|
||||
NS_RegisterMemoryReporter(mReporter);
|
||||
}
|
||||
|
||||
void
|
||||
nsObserverService::Shutdown()
|
||||
{
|
||||
if (mReporter) {
|
||||
NS_UnregisterMemoryMultiReporter(mReporter);
|
||||
NS_UnregisterMemoryReporter(mReporter);
|
||||
}
|
||||
|
||||
mShuttingDown = true;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#define NS_OBSERVERSERVICE_CID \
|
||||
{ 0xd07f5195, 0xe3d1, 0x11d2, { 0x8a, 0xcd, 0x0, 0x10, 0x5a, 0x1b, 0x88, 0x60 } }
|
||||
|
||||
class nsIMemoryMultiReporter;
|
||||
class nsIMemoryReporter;
|
||||
|
||||
namespace mozilla {
|
||||
class ObserverServiceReporter;
|
||||
|
@ -47,7 +47,7 @@ private:
|
|||
|
||||
bool mShuttingDown;
|
||||
nsTHashtable<nsObserverList> mObserverTopicTable;
|
||||
nsCOMPtr<nsIMemoryMultiReporter> mReporter;
|
||||
nsCOMPtr<nsIMemoryReporter> mReporter;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsObserverService, NS_OBSERVERSERVICE_CID)
|
||||
|
|
|
@ -40,11 +40,11 @@ XPTInterfaceInfoManager::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf)
|
|||
return n;
|
||||
}
|
||||
|
||||
class XPTIWorkingSetReporter MOZ_FINAL : public MemoryReporterBase
|
||||
class XPTIWorkingSetReporter MOZ_FINAL : public MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
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.")
|
||||
{}
|
||||
private:
|
||||
|
|
Загрузка…
Ссылка в новой задаче