Bug 910517 - Remove nsIMemoryReporter, and rename nsIMemoryMultiReporter as nsIMemoryReporter. r=mmcr8.
This commit is contained in:
@@ -148,6 +148,9 @@ function reportMemoryUsage() {
|
|||||||
var mgr = Cc["@mozilla.org/memory-reporter-manager;1"]
|
var mgr = Cc["@mozilla.org/memory-reporter-manager;1"]
|
||||||
.getService(Ci.nsIMemoryReporterManager);
|
.getService(Ci.nsIMemoryReporterManager);
|
||||||
|
|
||||||
|
// XXX: this code is *so* bogus -- nsIMemoryReporter changed its |memoryUsed|
|
||||||
|
// field to |amount| *years* ago, and even bigger changes have happened
|
||||||
|
// since -- that it must just never be run.
|
||||||
var reporters = mgr.enumerateReporters();
|
var reporters = mgr.enumerateReporters();
|
||||||
if (reporters.hasMoreElements())
|
if (reporters.hasMoreElements())
|
||||||
print("\n");
|
print("\n");
|
||||||
@@ -376,14 +379,7 @@ function getPotentialLeaks() {
|
|||||||
|
|
||||||
let enm = mgr.enumerateReporters();
|
let enm = mgr.enumerateReporters();
|
||||||
while (enm.hasMoreElements()) {
|
while (enm.hasMoreElements()) {
|
||||||
let reporter = enm.getNext().QueryInterface(Ci.nsIMemoryReporter);
|
let mr = enm.getNext().QueryInterface(Ci.nsIMemoryReporter);
|
||||||
logReporter(reporter.process, reporter.path, reporter.kind, reporter.units,
|
|
||||||
reporter.amount, reporter.description);
|
|
||||||
}
|
|
||||||
|
|
||||||
let enm = mgr.enumerateMultiReporters();
|
|
||||||
while (enm.hasMoreElements()) {
|
|
||||||
let mr = enm.getNext().QueryInterface(Ci.nsIMemoryMultiReporter);
|
|
||||||
mr.collectReports(logReporter, null);
|
mr.collectReports(logReporter, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -255,11 +255,11 @@ static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
|
|||||||
|
|
||||||
static PLDHashTable sEventListenerManagersHash;
|
static PLDHashTable sEventListenerManagersHash;
|
||||||
|
|
||||||
class DOMEventListenerManagersHashReporter MOZ_FINAL : public MemoryReporterBase
|
class DOMEventListenerManagersHashReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DOMEventListenerManagersHashReporter()
|
DOMEventListenerManagersHashReporter()
|
||||||
: MemoryReporterBase(
|
: MemoryUniReporter(
|
||||||
"explicit/dom/event-listener-managers-hash",
|
"explicit/dom/event-listener-managers-hash",
|
||||||
KIND_HEAP,
|
KIND_HEAP,
|
||||||
UNITS_BYTES,
|
UNITS_BYTES,
|
||||||
|
|||||||
@@ -641,7 +641,7 @@ nsDOMMemoryFile::DataOwner::sMemoryReporterRegistered;
|
|||||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(DOMMemoryFileDataOwnerMallocSizeOf)
|
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(DOMMemoryFileDataOwnerMallocSizeOf)
|
||||||
|
|
||||||
class nsDOMMemoryFileDataOwnerMemoryReporter MOZ_FINAL
|
class nsDOMMemoryFileDataOwnerMemoryReporter MOZ_FINAL
|
||||||
: public nsIMemoryMultiReporter
|
: public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||||||
|
|
||||||
@@ -651,7 +651,7 @@ class nsDOMMemoryFileDataOwnerMemoryReporter MOZ_FINAL
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback *aCallback,
|
NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCallback,
|
||||||
nsISupports *aClosure)
|
nsISupports *aClosure)
|
||||||
{
|
{
|
||||||
typedef nsDOMMemoryFile::DataOwner DataOwner;
|
typedef nsDOMMemoryFile::DataOwner DataOwner;
|
||||||
@@ -725,7 +725,7 @@ class nsDOMMemoryFileDataOwnerMemoryReporter MOZ_FINAL
|
|||||||
};
|
};
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(nsDOMMemoryFileDataOwnerMemoryReporter,
|
NS_IMPL_ISUPPORTS1(nsDOMMemoryFileDataOwnerMemoryReporter,
|
||||||
nsIMemoryMultiReporter)
|
nsIMemoryReporter)
|
||||||
|
|
||||||
/* static */ void
|
/* static */ void
|
||||||
nsDOMMemoryFile::DataOwner::EnsureMemoryReporterRegistered()
|
nsDOMMemoryFile::DataOwner::EnsureMemoryReporterRegistered()
|
||||||
@@ -737,7 +737,7 @@ nsDOMMemoryFile::DataOwner::EnsureMemoryReporterRegistered()
|
|||||||
|
|
||||||
nsRefPtr<nsDOMMemoryFileDataOwnerMemoryReporter> reporter = new
|
nsRefPtr<nsDOMMemoryFileDataOwnerMemoryReporter> reporter = new
|
||||||
nsDOMMemoryFileDataOwnerMemoryReporter();
|
nsDOMMemoryFileDataOwnerMemoryReporter();
|
||||||
NS_RegisterMemoryMultiReporter(reporter);
|
NS_RegisterMemoryReporter(reporter);
|
||||||
|
|
||||||
sMemoryReporterRegistered = true;
|
sMemoryReporterRegistered = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,11 +143,11 @@ static int64_t gCanvasAzureMemoryUsed = 0;
|
|||||||
// This is KIND_OTHER because it's not always clear where in memory the pixels
|
// This is KIND_OTHER because it's not always clear where in memory the pixels
|
||||||
// of a canvas are stored. Furthermore, this memory will be tracked by the
|
// of a canvas are stored. Furthermore, this memory will be tracked by the
|
||||||
// underlying surface implementations. See bug 655638 for details.
|
// underlying surface implementations. See bug 655638 for details.
|
||||||
class Canvas2dPixelsReporter MOZ_FINAL : public MemoryReporterBase
|
class Canvas2dPixelsReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Canvas2dPixelsReporter()
|
Canvas2dPixelsReporter()
|
||||||
: MemoryReporterBase("canvas-2d-pixels", KIND_OTHER, UNITS_BYTES,
|
: MemoryUniReporter("canvas-2d-pixels", KIND_OTHER, UNITS_BYTES,
|
||||||
"Memory used by 2D canvases. Each canvas requires (width * height * 4) bytes.")
|
"Memory used by 2D canvases. Each canvas requires (width * height * 4) bytes.")
|
||||||
{}
|
{}
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#include "WebGLContextUtils.h"
|
#include "WebGLContextUtils.h"
|
||||||
#include "WebGLBuffer.h"
|
#include "WebGLBuffer.h"
|
||||||
#include "WebGLVertexAttribData.h"
|
#include "WebGLVertexAttribData.h"
|
||||||
#include "WebGLMemoryMultiReporterWrapper.h"
|
#include "WebGLMemoryReporterWrapper.h"
|
||||||
#include "WebGLFramebuffer.h"
|
#include "WebGLFramebuffer.h"
|
||||||
#include "WebGLVertexArray.h"
|
#include "WebGLVertexArray.h"
|
||||||
#include "WebGLQuery.h"
|
#include "WebGLQuery.h"
|
||||||
@@ -179,7 +179,7 @@ WebGLContext::WebGLContext()
|
|||||||
mPixelStorePackAlignment = 4;
|
mPixelStorePackAlignment = 4;
|
||||||
mPixelStoreUnpackAlignment = 4;
|
mPixelStoreUnpackAlignment = 4;
|
||||||
|
|
||||||
WebGLMemoryMultiReporterWrapper::AddWebGLContext(this);
|
WebGLMemoryReporterWrapper::AddWebGLContext(this);
|
||||||
|
|
||||||
mAllowRestore = true;
|
mAllowRestore = true;
|
||||||
mContextLossTimerRunning = false;
|
mContextLossTimerRunning = false;
|
||||||
@@ -213,7 +213,7 @@ WebGLContext::WebGLContext()
|
|||||||
WebGLContext::~WebGLContext()
|
WebGLContext::~WebGLContext()
|
||||||
{
|
{
|
||||||
DestroyResourcesAndContext();
|
DestroyResourcesAndContext();
|
||||||
WebGLMemoryMultiReporterWrapper::RemoveWebGLContext(this);
|
WebGLMemoryReporterWrapper::RemoveWebGLContext(this);
|
||||||
TerminateContextLossTimer();
|
TerminateContextLossTimer();
|
||||||
mContextRestorer = nullptr;
|
mContextRestorer = nullptr;
|
||||||
}
|
}
|
||||||
@@ -653,8 +653,8 @@ void WebGLContext::LoseOldestWebGLContextIfLimitExceeded()
|
|||||||
// when choosing which one to lose first.
|
// when choosing which one to lose first.
|
||||||
UpdateLastUseIndex();
|
UpdateLastUseIndex();
|
||||||
|
|
||||||
WebGLMemoryMultiReporterWrapper::ContextsArrayType &contexts
|
WebGLMemoryReporterWrapper::ContextsArrayType &contexts
|
||||||
= WebGLMemoryMultiReporterWrapper::Contexts();
|
= WebGLMemoryReporterWrapper::Contexts();
|
||||||
|
|
||||||
// quick exit path, should cover a majority of cases
|
// quick exit path, should cover a majority of cases
|
||||||
if (contexts.Length() <= kMaxWebGLContextsPerPrincipal) {
|
if (contexts.Length() <= kMaxWebGLContextsPerPrincipal) {
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ class WebGLContext :
|
|||||||
{
|
{
|
||||||
friend class WebGLContextUserData;
|
friend class WebGLContextUserData;
|
||||||
friend class WebGLMemoryPressureObserver;
|
friend class WebGLMemoryPressureObserver;
|
||||||
friend class WebGLMemoryMultiReporterWrapper;
|
friend class WebGLMemoryReporterWrapper;
|
||||||
friend class WebGLExtensionLoseContext;
|
friend class WebGLExtensionLoseContext;
|
||||||
friend class WebGLExtensionCompressedTextureS3TC;
|
friend class WebGLExtensionCompressedTextureS3TC;
|
||||||
friend class WebGLExtensionCompressedTextureATC;
|
friend class WebGLExtensionCompressedTextureATC;
|
||||||
|
|||||||
@@ -4,32 +4,32 @@
|
|||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "WebGLContext.h"
|
#include "WebGLContext.h"
|
||||||
#include "WebGLMemoryMultiReporterWrapper.h"
|
#include "WebGLMemoryReporterWrapper.h"
|
||||||
#include "nsIMemoryReporter.h"
|
#include "nsIMemoryReporter.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(WebGLMemoryPressureObserver, nsIObserver)
|
NS_IMPL_ISUPPORTS1(WebGLMemoryPressureObserver, nsIObserver)
|
||||||
|
|
||||||
class WebGLMemoryMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
class WebGLMemoryReporter MOZ_FINAL : public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
NS_DECL_NSIMEMORYMULTIREPORTER
|
NS_DECL_NSIMEMORYREPORTER
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(WebGLMemoryMultiReporter, nsIMemoryMultiReporter)
|
NS_IMPL_ISUPPORTS1(WebGLMemoryReporter, nsIMemoryReporter)
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
WebGLMemoryMultiReporter::GetName(nsACString &aName)
|
WebGLMemoryReporter::GetName(nsACString &aName)
|
||||||
{
|
{
|
||||||
aName.AssignLiteral("webgl");
|
aName.AssignLiteral("webgl");
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
WebGLMemoryMultiReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
|
WebGLMemoryReporter::CollectReports(nsIMemoryReporterCallback* aCb,
|
||||||
nsISupports* aClosure)
|
nsISupports* aClosure)
|
||||||
{
|
{
|
||||||
#define REPORT(_path, _kind, _units, _amount, _desc) \
|
#define REPORT(_path, _kind, _units, _amount, _desc) \
|
||||||
do { \
|
do { \
|
||||||
@@ -42,21 +42,21 @@ WebGLMemoryMultiReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
|
|||||||
|
|
||||||
REPORT("webgl-texture-memory",
|
REPORT("webgl-texture-memory",
|
||||||
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES,
|
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES,
|
||||||
WebGLMemoryMultiReporterWrapper::GetTextureMemoryUsed(),
|
WebGLMemoryReporterWrapper::GetTextureMemoryUsed(),
|
||||||
"Memory used by WebGL textures.The OpenGL"
|
"Memory used by WebGL textures.The OpenGL"
|
||||||
" implementation is free to store these textures in either video"
|
" implementation is free to store these textures in either video"
|
||||||
" memory or main memory. This measurement is only a lower bound,"
|
" memory or main memory. This measurement is only a lower bound,"
|
||||||
" actual memory usage may be higher for example if the storage"
|
" actual memory usage may be higher for example if the storage"
|
||||||
" is strided.");
|
" is strided.");
|
||||||
|
|
||||||
REPORT("webgl-texture-count",
|
REPORT("webgl-texture-count",
|
||||||
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
|
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
|
||||||
WebGLMemoryMultiReporterWrapper::GetTextureCount(),
|
WebGLMemoryReporterWrapper::GetTextureCount(),
|
||||||
"Number of WebGL textures.");
|
"Number of WebGL textures.");
|
||||||
|
|
||||||
REPORT("webgl-buffer-memory",
|
REPORT("webgl-buffer-memory",
|
||||||
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES,
|
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES,
|
||||||
WebGLMemoryMultiReporterWrapper::GetBufferMemoryUsed(),
|
WebGLMemoryReporterWrapper::GetBufferMemoryUsed(),
|
||||||
"Memory used by WebGL buffers. The OpenGL"
|
"Memory used by WebGL buffers. The OpenGL"
|
||||||
" implementation is free to store these buffers in either video"
|
" implementation is free to store these buffers in either video"
|
||||||
" memory or main memory. This measurement is only a lower bound,"
|
" memory or main memory. This measurement is only a lower bound,"
|
||||||
@@ -65,7 +65,7 @@ WebGLMemoryMultiReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
|
|||||||
|
|
||||||
REPORT("explicit/webgl/buffer-cache-memory",
|
REPORT("explicit/webgl/buffer-cache-memory",
|
||||||
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
|
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
|
||||||
WebGLMemoryMultiReporterWrapper::GetBufferCacheMemoryUsed(),
|
WebGLMemoryReporterWrapper::GetBufferCacheMemoryUsed(),
|
||||||
"Memory used by WebGL buffer caches. The WebGL"
|
"Memory used by WebGL buffer caches. The WebGL"
|
||||||
" implementation caches the contents of element array buffers"
|
" implementation caches the contents of element array buffers"
|
||||||
" only.This adds up with the webgl-buffer-memory value, but"
|
" only.This adds up with the webgl-buffer-memory value, but"
|
||||||
@@ -74,69 +74,69 @@ WebGLMemoryMultiReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
|
|||||||
|
|
||||||
REPORT("webgl-buffer-count",
|
REPORT("webgl-buffer-count",
|
||||||
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
|
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
|
||||||
WebGLMemoryMultiReporterWrapper::GetBufferCount(),
|
WebGLMemoryReporterWrapper::GetBufferCount(),
|
||||||
"Number of WebGL buffers.");
|
"Number of WebGL buffers.");
|
||||||
|
|
||||||
REPORT("webgl-renderbuffer-memory",
|
REPORT("webgl-renderbuffer-memory",
|
||||||
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES,
|
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES,
|
||||||
WebGLMemoryMultiReporterWrapper::GetRenderbufferMemoryUsed(),
|
WebGLMemoryReporterWrapper::GetRenderbufferMemoryUsed(),
|
||||||
"Memory used by WebGL renderbuffers. The OpenGL"
|
"Memory used by WebGL renderbuffers. The OpenGL"
|
||||||
" implementation is free to store these renderbuffers in either"
|
" implementation is free to store these renderbuffers in either"
|
||||||
" video memory or main memory. This measurement is only a lower"
|
" video memory or main memory. This measurement is only a lower"
|
||||||
" bound, actual memory usage may be higher for example if the"
|
" bound, actual memory usage may be higher for example if the"
|
||||||
" storage is strided.");
|
" storage is strided.");
|
||||||
|
|
||||||
REPORT("webgl-renderbuffer-count",
|
REPORT("webgl-renderbuffer-count",
|
||||||
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
|
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
|
||||||
WebGLMemoryMultiReporterWrapper::GetRenderbufferCount(),
|
WebGLMemoryReporterWrapper::GetRenderbufferCount(),
|
||||||
"Number of WebGL renderbuffers.");
|
"Number of WebGL renderbuffers.");
|
||||||
|
|
||||||
REPORT("explicit/webgl/shader",
|
REPORT("explicit/webgl/shader",
|
||||||
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
|
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
|
||||||
WebGLMemoryMultiReporterWrapper::GetShaderSize(),
|
WebGLMemoryReporterWrapper::GetShaderSize(),
|
||||||
"Combined size of WebGL shader ASCII sources and translation"
|
"Combined size of WebGL shader ASCII sources and translation"
|
||||||
" logs cached on the heap.");
|
" logs cached on the heap.");
|
||||||
|
|
||||||
REPORT("webgl-shader-count",
|
REPORT("webgl-shader-count",
|
||||||
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
|
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
|
||||||
WebGLMemoryMultiReporterWrapper::GetShaderCount(),
|
WebGLMemoryReporterWrapper::GetShaderCount(),
|
||||||
"Number of WebGL shaders.");
|
"Number of WebGL shaders.");
|
||||||
|
|
||||||
REPORT("webgl-context-count",
|
REPORT("webgl-context-count",
|
||||||
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
|
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
|
||||||
WebGLMemoryMultiReporterWrapper::GetContextCount(),
|
WebGLMemoryReporterWrapper::GetContextCount(),
|
||||||
"Number of WebGL contexts.");
|
"Number of WebGL contexts.");
|
||||||
|
|
||||||
#undef REPORT
|
#undef REPORT
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
WebGLMemoryMultiReporterWrapper* WebGLMemoryMultiReporterWrapper::sUniqueInstance = nullptr;
|
WebGLMemoryReporterWrapper* WebGLMemoryReporterWrapper::sUniqueInstance = nullptr;
|
||||||
|
|
||||||
WebGLMemoryMultiReporterWrapper* WebGLMemoryMultiReporterWrapper::UniqueInstance()
|
WebGLMemoryReporterWrapper* WebGLMemoryReporterWrapper::UniqueInstance()
|
||||||
{
|
{
|
||||||
if (!sUniqueInstance) {
|
if (!sUniqueInstance) {
|
||||||
sUniqueInstance = new WebGLMemoryMultiReporterWrapper;
|
sUniqueInstance = new WebGLMemoryReporterWrapper;
|
||||||
}
|
}
|
||||||
return sUniqueInstance;
|
return sUniqueInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
WebGLMemoryMultiReporterWrapper::WebGLMemoryMultiReporterWrapper()
|
WebGLMemoryReporterWrapper::WebGLMemoryReporterWrapper()
|
||||||
{
|
|
||||||
mReporter = new WebGLMemoryMultiReporter;
|
|
||||||
NS_RegisterMemoryMultiReporter(mReporter);
|
|
||||||
}
|
|
||||||
|
|
||||||
WebGLMemoryMultiReporterWrapper::~WebGLMemoryMultiReporterWrapper()
|
|
||||||
{
|
{
|
||||||
NS_UnregisterMemoryMultiReporter(mReporter);
|
mReporter = new WebGLMemoryReporter;
|
||||||
|
NS_RegisterMemoryReporter(mReporter);
|
||||||
|
}
|
||||||
|
|
||||||
|
WebGLMemoryReporterWrapper::~WebGLMemoryReporterWrapper()
|
||||||
|
{
|
||||||
|
NS_UnregisterMemoryReporter(mReporter);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLBufferMallocSizeOf)
|
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLBufferMallocSizeOf)
|
||||||
|
|
||||||
int64_t
|
int64_t
|
||||||
WebGLMemoryMultiReporterWrapper::GetBufferCacheMemoryUsed() {
|
WebGLMemoryReporterWrapper::GetBufferCacheMemoryUsed() {
|
||||||
const ContextsArrayType & contexts = Contexts();
|
const ContextsArrayType & contexts = Contexts();
|
||||||
int64_t result = 0;
|
int64_t result = 0;
|
||||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||||
@@ -153,8 +153,8 @@ WebGLMemoryMultiReporterWrapper::GetBufferCacheMemoryUsed() {
|
|||||||
|
|
||||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLShaderMallocSizeOf)
|
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLShaderMallocSizeOf)
|
||||||
|
|
||||||
int64_t
|
int64_t
|
||||||
WebGLMemoryMultiReporterWrapper::GetShaderSize() {
|
WebGLMemoryReporterWrapper::GetShaderSize() {
|
||||||
const ContextsArrayType & contexts = Contexts();
|
const ContextsArrayType & contexts = Contexts();
|
||||||
int64_t result = 0;
|
int64_t result = 0;
|
||||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#ifndef WEBGLMEMORYMULTIREPORTWRAPER_H_
|
#ifndef WEBGLMEMORYREPORTWRAPER_H_
|
||||||
#define WEBGLMEMORYMULTIREPORTWRAPER_H_
|
#define WEBGLMEMORYREPORTWRAPER_H_
|
||||||
|
|
||||||
#include "WebGLContext.h"
|
#include "WebGLContext.h"
|
||||||
#include "WebGLBuffer.h"
|
#include "WebGLBuffer.h"
|
||||||
@@ -17,21 +17,21 @@
|
|||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
class WebGLMemoryMultiReporterWrapper
|
class WebGLMemoryReporterWrapper
|
||||||
{
|
{
|
||||||
WebGLMemoryMultiReporterWrapper();
|
WebGLMemoryReporterWrapper();
|
||||||
~WebGLMemoryMultiReporterWrapper();
|
~WebGLMemoryReporterWrapper();
|
||||||
static WebGLMemoryMultiReporterWrapper* sUniqueInstance;
|
static WebGLMemoryReporterWrapper* sUniqueInstance;
|
||||||
|
|
||||||
// here we store plain pointers, not RefPtrs: we don't want the
|
// here we store plain pointers, not RefPtrs: we don't want the
|
||||||
// WebGLMemoryMultiReporterWrapper unique instance to keep alive all
|
// WebGLMemoryReporterWrapper unique instance to keep alive all
|
||||||
// WebGLContexts ever created.
|
// WebGLContexts ever created.
|
||||||
typedef nsTArray<const WebGLContext*> ContextsArrayType;
|
typedef nsTArray<const WebGLContext*> ContextsArrayType;
|
||||||
ContextsArrayType mContexts;
|
ContextsArrayType mContexts;
|
||||||
|
|
||||||
nsCOMPtr<nsIMemoryMultiReporter> mReporter;
|
nsCOMPtr<nsIMemoryReporter> mReporter;
|
||||||
|
|
||||||
static WebGLMemoryMultiReporterWrapper* UniqueInstance();
|
static WebGLMemoryReporterWrapper* UniqueInstance();
|
||||||
|
|
||||||
static ContextsArrayType & Contexts() { return UniqueInstance()->mContexts; }
|
static ContextsArrayType & Contexts() { return UniqueInstance()->mContexts; }
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ class MediaMemoryTracker
|
|||||||
|
|
||||||
DecodersArray mDecoders;
|
DecodersArray mDecoders;
|
||||||
|
|
||||||
nsCOMPtr<nsIMemoryMultiReporter> mReporter;
|
nsCOMPtr<nsIMemoryReporter> mReporter;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void AddMediaDecoder(MediaDecoder* aDecoder)
|
static void AddMediaDecoder(MediaDecoder* aDecoder)
|
||||||
@@ -1725,7 +1725,7 @@ MediaDecoder::IsWMFEnabled()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class MediaReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
class MediaReporter MOZ_FINAL : public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
@@ -1736,7 +1736,7 @@ public:
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback* aCb,
|
NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCb,
|
||||||
nsISupports* aClosure)
|
nsISupports* aClosure)
|
||||||
{
|
{
|
||||||
int64_t video, audio;
|
int64_t video, audio;
|
||||||
@@ -1762,7 +1762,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(MediaReporter, nsIMemoryMultiReporter)
|
NS_IMPL_ISUPPORTS1(MediaReporter, nsIMemoryReporter)
|
||||||
|
|
||||||
MediaDecoderOwner*
|
MediaDecoderOwner*
|
||||||
MediaDecoder::GetOwner()
|
MediaDecoder::GetOwner()
|
||||||
@@ -1774,12 +1774,12 @@ MediaDecoder::GetOwner()
|
|||||||
MediaMemoryTracker::MediaMemoryTracker()
|
MediaMemoryTracker::MediaMemoryTracker()
|
||||||
: mReporter(new MediaReporter())
|
: mReporter(new MediaReporter())
|
||||||
{
|
{
|
||||||
NS_RegisterMemoryMultiReporter(mReporter);
|
NS_RegisterMemoryReporter(mReporter);
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaMemoryTracker::~MediaMemoryTracker()
|
MediaMemoryTracker::~MediaMemoryTracker()
|
||||||
{
|
{
|
||||||
NS_UnregisterMemoryMultiReporter(mReporter);
|
NS_UnregisterMemoryReporter(mReporter);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|||||||
@@ -116,11 +116,11 @@ GlobalNameHashInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ScriptNameSpaceManagerReporter MOZ_FINAL : public MemoryReporterBase
|
class ScriptNameSpaceManagerReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ScriptNameSpaceManagerReporter(nsScriptNameSpaceManager* aManager)
|
ScriptNameSpaceManagerReporter(nsScriptNameSpaceManager* aManager)
|
||||||
: MemoryReporterBase(
|
: MemoryUniReporter(
|
||||||
"explicit/script-namespace-manager",
|
"explicit/script-namespace-manager",
|
||||||
KIND_HEAP,
|
KIND_HEAP,
|
||||||
nsIMemoryReporter::UNITS_BYTES,
|
nsIMemoryReporter::UNITS_BYTES,
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ nsWindowMemoryReporter::nsWindowMemoryReporter()
|
|||||||
mDetachedWindows.Init();
|
mDetachedWindows.Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS3(nsWindowMemoryReporter, nsIMemoryMultiReporter, nsIObserver,
|
NS_IMPL_ISUPPORTS3(nsWindowMemoryReporter, nsIMemoryReporter, nsIObserver,
|
||||||
nsSupportsWeakReference)
|
nsSupportsWeakReference)
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
@@ -34,7 +34,7 @@ nsWindowMemoryReporter::Init()
|
|||||||
{
|
{
|
||||||
// The memory reporter manager will own this object.
|
// The memory reporter manager will own this object.
|
||||||
nsRefPtr<nsWindowMemoryReporter> windowReporter = new nsWindowMemoryReporter();
|
nsRefPtr<nsWindowMemoryReporter> windowReporter = new nsWindowMemoryReporter();
|
||||||
NS_RegisterMemoryMultiReporter(windowReporter);
|
NS_RegisterMemoryReporter(windowReporter);
|
||||||
|
|
||||||
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
||||||
if (os) {
|
if (os) {
|
||||||
@@ -46,13 +46,13 @@ nsWindowMemoryReporter::Init()
|
|||||||
/* weakRef = */ true);
|
/* weakRef = */ true);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<GhostURLsReporter> ghostMultiReporter =
|
nsRefPtr<GhostURLsReporter> ghostURLsReporter =
|
||||||
new GhostURLsReporter(windowReporter);
|
new GhostURLsReporter(windowReporter);
|
||||||
NS_RegisterMemoryMultiReporter(ghostMultiReporter);
|
NS_RegisterMemoryReporter(ghostURLsReporter);
|
||||||
|
|
||||||
nsRefPtr<NumGhostsReporter> ghostReporter =
|
nsRefPtr<NumGhostsReporter> numGhostsReporter =
|
||||||
new NumGhostsReporter(windowReporter);
|
new NumGhostsReporter(windowReporter);
|
||||||
NS_RegisterMemoryReporter(ghostReporter);
|
NS_RegisterMemoryReporter(numGhostsReporter);
|
||||||
}
|
}
|
||||||
|
|
||||||
static already_AddRefed<nsIURI>
|
static already_AddRefed<nsIURI>
|
||||||
@@ -122,7 +122,7 @@ CollectWindowReports(nsGlobalWindow *aWindow,
|
|||||||
nsTHashtable<nsUint64HashKey> *aGhostWindowIDs,
|
nsTHashtable<nsUint64HashKey> *aGhostWindowIDs,
|
||||||
WindowPaths *aWindowPaths,
|
WindowPaths *aWindowPaths,
|
||||||
WindowPaths *aTopWindowPaths,
|
WindowPaths *aTopWindowPaths,
|
||||||
nsIMemoryMultiReporterCallback *aCb,
|
nsIMemoryReporterCallback *aCb,
|
||||||
nsISupports *aClosure)
|
nsISupports *aClosure)
|
||||||
{
|
{
|
||||||
nsAutoCString windowPath("explicit/");
|
nsAutoCString windowPath("explicit/");
|
||||||
@@ -320,7 +320,7 @@ nsWindowMemoryReporter::GetName(nsACString &aName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsWindowMemoryReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
|
nsWindowMemoryReporter::CollectReports(nsIMemoryReporterCallback* aCb,
|
||||||
nsISupports* aClosure)
|
nsISupports* aClosure)
|
||||||
{
|
{
|
||||||
nsGlobalWindow::WindowByIdTable* windowsById =
|
nsGlobalWindow::WindowByIdTable* windowsById =
|
||||||
@@ -356,9 +356,9 @@ nsWindowMemoryReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Report JS memory usage. We do this from here because the JS memory
|
// Report JS memory usage. We do this from here because the JS memory
|
||||||
// multi-reporter needs to be passed |windowPaths|.
|
// reporter needs to be passed |windowPaths|.
|
||||||
nsresult rv = xpc::JSMemoryMultiReporter::CollectReports(&windowPaths, &topWindowPaths,
|
nsresult rv = xpc::JSReporter::CollectReports(&windowPaths, &topWindowPaths,
|
||||||
aCb, aClosure);
|
aCb, aClosure);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
#define REPORT(_path, _amount, _desc) \
|
#define REPORT(_path, _amount, _desc) \
|
||||||
@@ -668,7 +668,7 @@ nsWindowMemoryReporter::CheckForGhostWindows(
|
|||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(nsWindowMemoryReporter::GhostURLsReporter,
|
NS_IMPL_ISUPPORTS1(nsWindowMemoryReporter::GhostURLsReporter,
|
||||||
nsIMemoryMultiReporter)
|
nsIMemoryReporter)
|
||||||
|
|
||||||
nsWindowMemoryReporter::
|
nsWindowMemoryReporter::
|
||||||
GhostURLsReporter::GhostURLsReporter(
|
GhostURLsReporter::GhostURLsReporter(
|
||||||
@@ -687,7 +687,7 @@ GhostURLsReporter::GetName(nsACString& aName)
|
|||||||
|
|
||||||
struct ReportGhostWindowsEnumeratorData
|
struct ReportGhostWindowsEnumeratorData
|
||||||
{
|
{
|
||||||
nsIMemoryMultiReporterCallback* callback;
|
nsIMemoryReporterCallback* callback;
|
||||||
nsISupports* closure;
|
nsISupports* closure;
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
};
|
};
|
||||||
@@ -734,7 +734,7 @@ ReportGhostWindowsEnumerator(nsUint64HashKey* aIDHashKey, void* aClosure)
|
|||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsWindowMemoryReporter::
|
nsWindowMemoryReporter::
|
||||||
GhostURLsReporter::CollectReports(
|
GhostURLsReporter::CollectReports(
|
||||||
nsIMemoryMultiReporterCallback* aCb,
|
nsIMemoryReporterCallback* aCb,
|
||||||
nsISupports* aClosure)
|
nsISupports* aClosure)
|
||||||
{
|
{
|
||||||
// Get the IDs of all the ghost windows in existance.
|
// Get the IDs of all the ghost windows in existance.
|
||||||
@@ -752,25 +752,6 @@ GhostURLsReporter::CollectReports(
|
|||||||
return reportGhostWindowsEnumData.rv;
|
return reportGhostWindowsEnumData.rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsWindowMemoryReporter::
|
|
||||||
NumGhostsReporter::GetDescription(nsACString& aDesc)
|
|
||||||
{
|
|
||||||
nsPrintfCString str(
|
|
||||||
"The number of ghost windows present (the number of nodes underneath \
|
|
||||||
explicit/window-objects/top(none)/ghost, modulo race conditions). A ghost \
|
|
||||||
window is not shown in any tab, does not share a domain with any non-detached \
|
|
||||||
windows, and has met these criteria for at least %ds \
|
|
||||||
(memory.ghost_window_timeout_seconds) or has survived a round of about:memory's \
|
|
||||||
minimize memory usage button.\n\n\
|
|
||||||
Ghost windows can happen legitimately, but they are often indicative of leaks \
|
|
||||||
in the browser or add-ons.",
|
|
||||||
mWindowReporter->GetGhostTimeout());
|
|
||||||
|
|
||||||
aDesc.Assign(str);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t
|
int64_t
|
||||||
nsWindowMemoryReporter::NumGhostsReporter::Amount()
|
nsWindowMemoryReporter::NumGhostsReporter::Amount()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -108,13 +108,13 @@ public:
|
|||||||
* the tab.
|
* the tab.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class nsWindowMemoryReporter MOZ_FINAL : public nsIMemoryMultiReporter,
|
class nsWindowMemoryReporter MOZ_FINAL : public nsIMemoryReporter,
|
||||||
public nsIObserver,
|
public nsIObserver,
|
||||||
public nsSupportsWeakReference
|
public nsSupportsWeakReference
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
NS_DECL_NSIMEMORYMULTIREPORTER
|
NS_DECL_NSIMEMORYREPORTER
|
||||||
NS_DECL_NSIOBSERVER
|
NS_DECL_NSIOBSERVER
|
||||||
|
|
||||||
static void Init();
|
static void Init();
|
||||||
@@ -126,33 +126,38 @@ private:
|
|||||||
* this list, running this report is faster than running
|
* this list, running this report is faster than running
|
||||||
* nsWindowMemoryReporter.
|
* nsWindowMemoryReporter.
|
||||||
*/
|
*/
|
||||||
class GhostURLsReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
class GhostURLsReporter MOZ_FINAL : public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GhostURLsReporter(nsWindowMemoryReporter* aWindowReporter);
|
GhostURLsReporter(nsWindowMemoryReporter* aWindowReporter);
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
NS_DECL_NSIMEMORYMULTIREPORTER
|
NS_DECL_NSIMEMORYREPORTER
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsRefPtr<nsWindowMemoryReporter> mWindowReporter;
|
nsRefPtr<nsWindowMemoryReporter> mWindowReporter;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nsGhostWindowReporter generates the "ghost-windows" single-report, which
|
* nsGhostWindowReporter generates the "ghost-windows" report, which counts
|
||||||
* counts the number of ghost windows present.
|
* the number of ghost windows present.
|
||||||
*/
|
*/
|
||||||
class NumGhostsReporter MOZ_FINAL : public mozilla::MemoryReporterBase
|
class NumGhostsReporter MOZ_FINAL : public mozilla::MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NumGhostsReporter(nsWindowMemoryReporter* aWindowReporter)
|
NumGhostsReporter(nsWindowMemoryReporter* aWindowReporter)
|
||||||
// Description is "???" because we define GetDescription below.
|
: MemoryUniReporter("ghost-windows", KIND_OTHER, UNITS_COUNT,
|
||||||
: MemoryReporterBase("ghost-windows", KIND_OTHER, UNITS_COUNT, "???")
|
"The number of ghost windows present (the number of nodes underneath "
|
||||||
|
"explicit/window-objects/top(none)/ghost, modulo race conditions). A ghost "
|
||||||
|
"window is not shown in any tab, does not share a domain with any non-detached "
|
||||||
|
"windows, and has met these criteria for at least "
|
||||||
|
"memory.ghost_window_timeout_seconds, or has survived a round of "
|
||||||
|
"about:memory's minimize memory usage button.\n\n"
|
||||||
|
"Ghost windows can happen legitimately, but they are often indicative of "
|
||||||
|
"leaks in the browser or add-ons.")
|
||||||
, mWindowReporter(aWindowReporter)
|
, mWindowReporter(aWindowReporter)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
NS_IMETHOD GetDescription(nsACString& aDesc);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int64_t Amount() MOZ_OVERRIDE;
|
int64_t Amount() MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
|||||||
@@ -398,7 +398,7 @@ ContentChild::AllocPMemoryReportRequestChild()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This is just a wrapper for InfallibleTArray<MemoryReport> that implements
|
// This is just a wrapper for InfallibleTArray<MemoryReport> that implements
|
||||||
// nsISupports, so it can be passed to nsIMemoryMultiReporter::CollectReports.
|
// nsISupports, so it can be passed to nsIMemoryReporter::CollectReports.
|
||||||
class MemoryReportsWrapper MOZ_FINAL : public nsISupports {
|
class MemoryReportsWrapper MOZ_FINAL : public nsISupports {
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
@@ -407,7 +407,7 @@ public:
|
|||||||
};
|
};
|
||||||
NS_IMPL_ISUPPORTS0(MemoryReportsWrapper)
|
NS_IMPL_ISUPPORTS0(MemoryReportsWrapper)
|
||||||
|
|
||||||
class MemoryReportCallback MOZ_FINAL : public nsIMemoryMultiReporterCallback
|
class MemoryReportCallback MOZ_FINAL : public nsIMemoryReporterCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
@@ -435,53 +435,28 @@ private:
|
|||||||
};
|
};
|
||||||
NS_IMPL_ISUPPORTS1(
|
NS_IMPL_ISUPPORTS1(
|
||||||
MemoryReportCallback
|
MemoryReportCallback
|
||||||
, nsIMemoryMultiReporterCallback
|
, nsIMemoryReporterCallback
|
||||||
)
|
)
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ContentChild::RecvPMemoryReportRequestConstructor(PMemoryReportRequestChild* child)
|
ContentChild::RecvPMemoryReportRequestConstructor(PMemoryReportRequestChild* child)
|
||||||
{
|
{
|
||||||
|
|
||||||
nsCOMPtr<nsIMemoryReporterManager> mgr = do_GetService("@mozilla.org/memory-reporter-manager;1");
|
nsCOMPtr<nsIMemoryReporterManager> mgr = do_GetService("@mozilla.org/memory-reporter-manager;1");
|
||||||
|
|
||||||
InfallibleTArray<MemoryReport> reports;
|
InfallibleTArray<MemoryReport> reports;
|
||||||
|
|
||||||
nsPrintfCString process("Content (%d)", getpid());
|
nsPrintfCString process("Content (%d)", getpid());
|
||||||
|
|
||||||
// First do the vanilla memory reporters.
|
// Run each reporter. The callback will turn each measurement into a
|
||||||
|
// MemoryReport.
|
||||||
nsCOMPtr<nsISimpleEnumerator> e;
|
nsCOMPtr<nsISimpleEnumerator> e;
|
||||||
mgr->EnumerateReporters(getter_AddRefs(e));
|
mgr->EnumerateReporters(getter_AddRefs(e));
|
||||||
bool more;
|
|
||||||
while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) {
|
|
||||||
nsCOMPtr<nsIMemoryReporter> r;
|
|
||||||
e->GetNext(getter_AddRefs(r));
|
|
||||||
|
|
||||||
nsCString path;
|
|
||||||
int32_t kind;
|
|
||||||
int32_t units;
|
|
||||||
int64_t amount;
|
|
||||||
nsCString desc;
|
|
||||||
|
|
||||||
if (NS_SUCCEEDED(r->GetPath(path)) &&
|
|
||||||
NS_SUCCEEDED(r->GetKind(&kind)) &&
|
|
||||||
NS_SUCCEEDED(r->GetUnits(&units)) &&
|
|
||||||
NS_SUCCEEDED(r->GetAmount(&amount)) &&
|
|
||||||
NS_SUCCEEDED(r->GetDescription(desc)))
|
|
||||||
{
|
|
||||||
MemoryReport memreport(process, path, kind, units, amount, desc);
|
|
||||||
reports.AppendElement(memreport);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Then do the memory multi-reporters, by calling CollectReports on each
|
|
||||||
// one, whereupon the callback will turn each measurement into a
|
|
||||||
// MemoryReport.
|
|
||||||
mgr->EnumerateMultiReporters(getter_AddRefs(e));
|
|
||||||
nsRefPtr<MemoryReportsWrapper> wrappedReports =
|
nsRefPtr<MemoryReportsWrapper> wrappedReports =
|
||||||
new MemoryReportsWrapper(&reports);
|
new MemoryReportsWrapper(&reports);
|
||||||
nsRefPtr<MemoryReportCallback> cb = new MemoryReportCallback(process);
|
nsRefPtr<MemoryReportCallback> cb = new MemoryReportCallback(process);
|
||||||
|
bool more;
|
||||||
while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) {
|
while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) {
|
||||||
nsCOMPtr<nsIMemoryMultiReporter> r;
|
nsCOMPtr<nsIMemoryReporter> r;
|
||||||
e->GetNext(getter_AddRefs(r));
|
e->GetNext(getter_AddRefs(r));
|
||||||
r->CollectReports(cb, wrappedReports);
|
r->CollectReports(cb, wrappedReports);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -159,34 +159,54 @@ namespace dom {
|
|||||||
|
|
||||||
#define NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC "ipc:network:set-offline"
|
#define NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC "ipc:network:set-offline"
|
||||||
|
|
||||||
// This represents a single measurement taken by a memory reporter in a child
|
// This represents all the memory reports provided by a child process.
|
||||||
// process and passed to this one. Its process is non-empty, and its amount is
|
class ChildReporter MOZ_FINAL : public nsIMemoryReporter
|
||||||
// fixed.
|
|
||||||
class ChildMemoryReporter MOZ_FINAL : public MemoryReporterBase
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ChildMemoryReporter(const char* aProcess, const char* aPath, int32_t aKind,
|
ChildReporter(const InfallibleTArray<MemoryReport>& childReports)
|
||||||
int32_t aUnits, int64_t aAmount,
|
|
||||||
const char* aDescription)
|
|
||||||
: MemoryReporterBase(aPath, aKind, aUnits, aDescription)
|
|
||||||
, mProcess(aProcess)
|
|
||||||
, mAmount(aAmount)
|
|
||||||
{
|
{
|
||||||
|
for (uint32_t i = 0; i < childReports.Length(); i++) {
|
||||||
|
MemoryReport r(childReports[i].process(),
|
||||||
|
childReports[i].path(),
|
||||||
|
childReports[i].kind(),
|
||||||
|
childReports[i].units(),
|
||||||
|
childReports[i].amount(),
|
||||||
|
childReports[i].desc());
|
||||||
|
|
||||||
|
// Child reports have a non-empty process.
|
||||||
|
MOZ_ASSERT(!r.process().IsEmpty());
|
||||||
|
|
||||||
|
mChildReports.AppendElement(r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHOD GetProcess(nsACString& aProcess)
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
|
NS_IMETHOD GetName(nsACString& name)
|
||||||
{
|
{
|
||||||
aProcess.Assign(mProcess);
|
name.AssignLiteral("content-child");
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCb,
|
||||||
int64_t Amount() { return mAmount; }
|
nsISupports* aClosure)
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < mChildReports.Length(); i++) {
|
||||||
|
nsresult rv;
|
||||||
|
MemoryReport r = mChildReports[i];
|
||||||
|
rv = aCb->Callback(r.process(), r.path(), r.kind(), r.units(),
|
||||||
|
r.amount(), r.desc(), aClosure);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
nsCString mProcess;
|
private:
|
||||||
int64_t mAmount;
|
InfallibleTArray<MemoryReport> mChildReports;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1(ChildReporter, nsIMemoryReporter)
|
||||||
|
|
||||||
class MemoryReportRequestParent : public PMemoryReportRequestParent
|
class MemoryReportRequestParent : public PMemoryReportRequestParent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -207,9 +227,9 @@ MemoryReportRequestParent::MemoryReportRequestParent()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
MemoryReportRequestParent::Recv__delete__(const InfallibleTArray<MemoryReport>& report)
|
MemoryReportRequestParent::Recv__delete__(const InfallibleTArray<MemoryReport>& childReports)
|
||||||
{
|
{
|
||||||
Owner()->SetChildMemoryReporters(report);
|
Owner()->SetChildMemoryReports(childReports);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,15 +241,15 @@ MemoryReportRequestParent::~MemoryReportRequestParent()
|
|||||||
/**
|
/**
|
||||||
* A memory reporter for ContentParent objects themselves.
|
* A memory reporter for ContentParent objects themselves.
|
||||||
*/
|
*/
|
||||||
class ContentParentMemoryReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
class ContentParentMemoryReporter MOZ_FINAL : public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
NS_DECL_NSIMEMORYMULTIREPORTER
|
NS_DECL_NSIMEMORYREPORTER
|
||||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(MallocSizeOf)
|
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(MallocSizeOf)
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(ContentParentMemoryReporter, nsIMemoryMultiReporter)
|
NS_IMPL_ISUPPORTS1(ContentParentMemoryReporter, nsIMemoryReporter)
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
ContentParentMemoryReporter::GetName(nsACString& aName)
|
ContentParentMemoryReporter::GetName(nsACString& aName)
|
||||||
@@ -239,7 +259,7 @@ ContentParentMemoryReporter::GetName(nsACString& aName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
ContentParentMemoryReporter::CollectReports(nsIMemoryMultiReporterCallback* cb,
|
ContentParentMemoryReporter::CollectReports(nsIMemoryReporterCallback* cb,
|
||||||
nsISupports* aClosure)
|
nsISupports* aClosure)
|
||||||
{
|
{
|
||||||
nsAutoTArray<ContentParent*, 16> cps;
|
nsAutoTArray<ContentParent*, 16> cps;
|
||||||
@@ -356,7 +376,7 @@ ContentParent::StartUp()
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<ContentParentMemoryReporter> mr = new ContentParentMemoryReporter();
|
nsRefPtr<ContentParentMemoryReporter> mr = new ContentParentMemoryReporter();
|
||||||
NS_RegisterMemoryMultiReporter(mr);
|
NS_RegisterMemoryReporter(mr);
|
||||||
|
|
||||||
sCanLaunchSubprocesses = true;
|
sCanLaunchSubprocesses = true;
|
||||||
|
|
||||||
@@ -876,7 +896,7 @@ ContentParent::ShutDownProcess(bool aCloseWithError)
|
|||||||
// shut down the cycle collector. But by then it's too late to release any
|
// shut down the cycle collector. But by then it's too late to release any
|
||||||
// CC'ed objects, so we need to null them out here, while we still can. See
|
// CC'ed objects, so we need to null them out here, while we still can. See
|
||||||
// bug 899761.
|
// bug 899761.
|
||||||
mMemoryReporters.Clear();
|
mChildReporter = nullptr;
|
||||||
if (mMessageManager) {
|
if (mMessageManager) {
|
||||||
mMessageManager->Disconnect();
|
mMessageManager->Disconnect();
|
||||||
mMessageManager = nullptr;
|
mMessageManager = nullptr;
|
||||||
@@ -1027,8 +1047,8 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
|
|||||||
ppm->Disconnect();
|
ppm->Disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear the child memory reporters
|
// unregister the child memory reporter
|
||||||
ClearChildMemoryReporters();
|
UnregisterChildMemoryReporter();
|
||||||
|
|
||||||
// remove the global remote preferences observers
|
// remove the global remote preferences observers
|
||||||
Preferences::RemoveObserver(this, "");
|
Preferences::RemoveObserver(this, "");
|
||||||
@@ -2141,28 +2161,16 @@ ContentParent::DeallocPMemoryReportRequestParent(PMemoryReportRequestParent* act
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ContentParent::SetChildMemoryReporters(const InfallibleTArray<MemoryReport>& report)
|
ContentParent::SetChildMemoryReports(const InfallibleTArray<MemoryReport>& childReports)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIMemoryReporterManager> mgr =
|
nsCOMPtr<nsIMemoryReporterManager> mgr =
|
||||||
do_GetService("@mozilla.org/memory-reporter-manager;1");
|
do_GetService("@mozilla.org/memory-reporter-manager;1");
|
||||||
for (int32_t i = 0; i < mMemoryReporters.Count(); i++)
|
|
||||||
mgr->UnregisterReporter(mMemoryReporters[i]);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < report.Length(); i++) {
|
if (mChildReporter)
|
||||||
nsCString process = report[i].process();
|
mgr->UnregisterReporter(mChildReporter);
|
||||||
nsCString path = report[i].path();
|
|
||||||
int32_t kind = report[i].kind();
|
|
||||||
int32_t units = report[i].units();
|
|
||||||
int64_t amount = report[i].amount();
|
|
||||||
nsCString desc = report[i].desc();
|
|
||||||
|
|
||||||
nsRefPtr<ChildMemoryReporter> r =
|
mChildReporter = new ChildReporter(childReports);
|
||||||
new ChildMemoryReporter(process.get(), path.get(), kind, units,
|
mgr->RegisterReporter(mChildReporter);
|
||||||
amount, desc.get());
|
|
||||||
|
|
||||||
mMemoryReporters.AppendObject(r);
|
|
||||||
mgr->RegisterReporter(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIObserverService> obs =
|
nsCOMPtr<nsIObserverService> obs =
|
||||||
do_GetService("@mozilla.org/observer-service;1");
|
do_GetService("@mozilla.org/observer-service;1");
|
||||||
@@ -2171,12 +2179,11 @@ ContentParent::SetChildMemoryReporters(const InfallibleTArray<MemoryReport>& rep
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ContentParent::ClearChildMemoryReporters()
|
ContentParent::UnregisterChildMemoryReporter()
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIMemoryReporterManager> mgr =
|
nsCOMPtr<nsIMemoryReporterManager> mgr =
|
||||||
do_GetService("@mozilla.org/memory-reporter-manager;1");
|
do_GetService("@mozilla.org/memory-reporter-manager;1");
|
||||||
for (int32_t i = 0; i < mMemoryReporters.Count(); i++)
|
mgr->UnregisterReporter(mChildReporter);
|
||||||
mgr->UnregisterReporter(mMemoryReporters[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PTestShellParent*
|
PTestShellParent*
|
||||||
|
|||||||
@@ -143,8 +143,9 @@ public:
|
|||||||
bool IsAlive();
|
bool IsAlive();
|
||||||
bool IsForApp();
|
bool IsForApp();
|
||||||
|
|
||||||
void SetChildMemoryReporters(const InfallibleTArray<MemoryReport>& report);
|
void SetChildMemoryReports(const InfallibleTArray<MemoryReport>&
|
||||||
void ClearChildMemoryReporters();
|
childReports);
|
||||||
|
void UnregisterChildMemoryReporter();
|
||||||
|
|
||||||
GeckoChildProcessHost* Process() {
|
GeckoChildProcessHost* Process() {
|
||||||
return mSubprocess;
|
return mSubprocess;
|
||||||
@@ -446,11 +447,13 @@ private:
|
|||||||
uint64_t mChildID;
|
uint64_t mChildID;
|
||||||
int32_t mGeolocationWatchID;
|
int32_t mGeolocationWatchID;
|
||||||
|
|
||||||
// This is a cache of all of the memory reporters
|
// This is a reporter holding the reports from the child's last
|
||||||
// registered in the child process. To update this, one
|
// "child-memory-reporter-update" notification. To update this, one can
|
||||||
// can broadcast the topic "child-memory-reporter-request" using
|
// broadcast the topic "child-memory-reporter-request" using the
|
||||||
// the nsIObserverService.
|
// nsIObserverService.
|
||||||
nsCOMArray<nsIMemoryReporter> mMemoryReporters;
|
//
|
||||||
|
// Note that this assumes there is at most one child process at a time!
|
||||||
|
nsCOMPtr<nsIMemoryReporter> mChildReporter;
|
||||||
|
|
||||||
nsString mAppManifestURL;
|
nsString mAppManifestURL;
|
||||||
|
|
||||||
|
|||||||
@@ -1766,7 +1766,7 @@ struct WorkerPrivate::TimeoutInfo
|
|||||||
bool mCanceled;
|
bool mCanceled;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WorkerPrivate::MemoryReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
class WorkerPrivate::MemoryReporter MOZ_FINAL : public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
friend class WorkerPrivate;
|
friend class WorkerPrivate;
|
||||||
|
|
||||||
@@ -1807,7 +1807,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHOD
|
NS_IMETHOD
|
||||||
CollectReports(nsIMemoryMultiReporterCallback* aCallback,
|
CollectReports(nsIMemoryReporterCallback* aCallback,
|
||||||
nsISupports* aClosure)
|
nsISupports* aClosure)
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
@@ -1883,7 +1883,7 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(WorkerPrivate::MemoryReporter, nsIMemoryMultiReporter)
|
NS_IMPL_ISUPPORTS1(WorkerPrivate::MemoryReporter, nsIMemoryReporter)
|
||||||
|
|
||||||
template <class Derived>
|
template <class Derived>
|
||||||
WorkerPrivateParent<Derived>::WorkerPrivateParent(
|
WorkerPrivateParent<Derived>::WorkerPrivateParent(
|
||||||
@@ -3093,7 +3093,7 @@ WorkerPrivate::EnableMemoryReporter()
|
|||||||
// successfully registered the reporter.
|
// successfully registered the reporter.
|
||||||
mMemoryReporter = new MemoryReporter(this);
|
mMemoryReporter = new MemoryReporter(this);
|
||||||
|
|
||||||
if (NS_FAILED(NS_RegisterMemoryMultiReporter(mMemoryReporter))) {
|
if (NS_FAILED(NS_RegisterMemoryReporter(mMemoryReporter))) {
|
||||||
NS_WARNING("Failed to register memory reporter!");
|
NS_WARNING("Failed to register memory reporter!");
|
||||||
// No need to lock here since a failed registration means our memory
|
// No need to lock here since a failed registration means our memory
|
||||||
// reporter can't start running. Just clean up.
|
// reporter can't start running. Just clean up.
|
||||||
@@ -3148,7 +3148,7 @@ WorkerPrivate::DisableMemoryReporter()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Finally unregister the memory reporter.
|
// Finally unregister the memory reporter.
|
||||||
if (NS_FAILED(NS_UnregisterMemoryMultiReporter(memoryReporter))) {
|
if (NS_FAILED(NS_UnregisterMemoryReporter(memoryReporter))) {
|
||||||
NS_WARNING("Failed to unregister memory reporter!");
|
NS_WARNING("Failed to unregister memory reporter!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,6 @@
|
|||||||
class JSAutoStructuredCloneBuffer;
|
class JSAutoStructuredCloneBuffer;
|
||||||
class nsIChannel;
|
class nsIChannel;
|
||||||
class nsIDocument;
|
class nsIDocument;
|
||||||
class nsIMemoryMultiReporter;
|
|
||||||
class nsIPrincipal;
|
class nsIPrincipal;
|
||||||
class nsIScriptContext;
|
class nsIScriptContext;
|
||||||
class nsIURI;
|
class nsIURI;
|
||||||
|
|||||||
@@ -97,11 +97,11 @@ NS_IMPL_CYCLE_COLLECTION_3(mozHunspell,
|
|||||||
mEncoder,
|
mEncoder,
|
||||||
mDecoder)
|
mDecoder)
|
||||||
|
|
||||||
class SpellCheckReporter MOZ_FINAL : public mozilla::MemoryReporterBase
|
class SpellCheckReporter MOZ_FINAL : public mozilla::MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SpellCheckReporter()
|
SpellCheckReporter()
|
||||||
: MemoryReporterBase("explicit/spell-check", KIND_HEAP, UNITS_BYTES,
|
: MemoryUniReporter("explicit/spell-check", KIND_HEAP, UNITS_BYTES,
|
||||||
"Memory used by the Hunspell spell checking engine's internal data structures.")
|
"Memory used by the Hunspell spell checking engine's internal data structures.")
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|||||||
@@ -3394,12 +3394,12 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
class GfxTexturesReporter MOZ_FINAL : public MemoryReporterBase
|
class GfxTexturesReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GfxTexturesReporter()
|
GfxTexturesReporter()
|
||||||
: MemoryReporterBase("gfx-textures", KIND_OTHER, UNITS_BYTES,
|
: MemoryUniReporter("gfx-textures", KIND_OTHER, UNITS_BYTES,
|
||||||
"Memory used for storing GL textures.")
|
"Memory used for storing GL textures.")
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
// There must be only one instance of this class, due to |sAmount|
|
// There must be only one instance of this class, due to |sAmount|
|
||||||
|
|||||||
@@ -184,13 +184,13 @@ ContentTypeFromPixelFormat(android::PixelFormat aFormat)
|
|||||||
return gfxASurface::ContentFromFormat(ImageFormatForPixelFormat(aFormat));
|
return gfxASurface::ContentFromFormat(ImageFormatForPixelFormat(aFormat));
|
||||||
}
|
}
|
||||||
|
|
||||||
class GrallocReporter MOZ_FINAL : public MemoryReporterBase
|
class GrallocReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
friend class GrallocBufferActor;
|
friend class GrallocBufferActor;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GrallocReporter()
|
GrallocReporter()
|
||||||
: MemoryReporterBase("gralloc", KIND_OTHER, UNITS_BYTES,
|
: MemoryUniReporter("gralloc", KIND_OTHER, UNITS_BYTES,
|
||||||
"Special RAM that can be shared between processes and directly accessed by "
|
"Special RAM that can be shared between processes and directly accessed by "
|
||||||
"both the CPU and GPU. Gralloc memory is usually a relatively precious "
|
"both the CPU and GPU. Gralloc memory is usually a relatively precious "
|
||||||
"resource, with much less available than generic RAM. When it's exhausted, "
|
"resource, with much less available than generic RAM. When it's exhausted, "
|
||||||
|
|||||||
@@ -598,7 +598,7 @@ PR_STATIC_ASSERT(uint32_t(CAIRO_SURFACE_TYPE_SKIA) ==
|
|||||||
static int64_t gSurfaceMemoryUsed[gfxASurface::SurfaceTypeMax] = { 0 };
|
static int64_t gSurfaceMemoryUsed[gfxASurface::SurfaceTypeMax] = { 0 };
|
||||||
|
|
||||||
class SurfaceMemoryReporter MOZ_FINAL :
|
class SurfaceMemoryReporter MOZ_FINAL :
|
||||||
public nsIMemoryMultiReporter
|
public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SurfaceMemoryReporter()
|
SurfaceMemoryReporter()
|
||||||
@@ -612,7 +612,7 @@ public:
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback *aCb,
|
NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCb,
|
||||||
nsISupports *aClosure)
|
nsISupports *aClosure)
|
||||||
{
|
{
|
||||||
size_t len = NS_ARRAY_LENGTH(sSurfaceMemoryReporterAttrs);
|
size_t len = NS_ARRAY_LENGTH(sSurfaceMemoryReporterAttrs);
|
||||||
@@ -639,7 +639,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(SurfaceMemoryReporter, nsIMemoryMultiReporter)
|
NS_IMPL_ISUPPORTS1(SurfaceMemoryReporter, nsIMemoryReporter)
|
||||||
|
|
||||||
void
|
void
|
||||||
gfxASurface::RecordMemoryUsedForSurfaceType(gfxASurface::gfxSurfaceType aType,
|
gfxASurface::RecordMemoryUsedForSurfaceType(gfxASurface::gfxSurfaceType aType,
|
||||||
@@ -652,7 +652,7 @@ gfxASurface::RecordMemoryUsedForSurfaceType(gfxASurface::gfxSurfaceType aType,
|
|||||||
|
|
||||||
static bool registered = false;
|
static bool registered = false;
|
||||||
if (!registered) {
|
if (!registered) {
|
||||||
NS_RegisterMemoryMultiReporter(new SurfaceMemoryReporter());
|
NS_RegisterMemoryReporter(new SurfaceMemoryReporter());
|
||||||
registered = true;
|
registered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,12 +30,12 @@ using namespace mozilla::gfx;
|
|||||||
|
|
||||||
static FT_Library gPlatformFTLibrary = nullptr;
|
static FT_Library gPlatformFTLibrary = nullptr;
|
||||||
|
|
||||||
class FreetypeReporter MOZ_FINAL : public MemoryReporterBase
|
class FreetypeReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FreetypeReporter()
|
FreetypeReporter()
|
||||||
: MemoryReporterBase("explicit/freetype", KIND_HEAP, UNITS_BYTES,
|
: MemoryUniReporter("explicit/freetype", KIND_HEAP, UNITS_BYTES,
|
||||||
"Memory used by Freetype.")
|
"Memory used by Freetype.")
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
// There must be only one instance of this class, due to |sAmount|
|
// There must be only one instance of this class, due to |sAmount|
|
||||||
|
|||||||
@@ -1252,7 +1252,7 @@ gfxFontFamily::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf,
|
|||||||
* shaped-word caches to free up memory.
|
* shaped-word caches to free up memory.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(gfxFontCache::MemoryReporter, nsIMemoryMultiReporter)
|
NS_IMPL_ISUPPORTS1(gfxFontCache::MemoryReporter, nsIMemoryReporter)
|
||||||
|
|
||||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(FontCacheMallocSizeOf)
|
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(FontCacheMallocSizeOf)
|
||||||
|
|
||||||
@@ -1265,7 +1265,7 @@ gfxFontCache::MemoryReporter::GetName(nsACString &aName)
|
|||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
gfxFontCache::MemoryReporter::CollectReports
|
gfxFontCache::MemoryReporter::CollectReports
|
||||||
(nsIMemoryMultiReporterCallback* aCb,
|
(nsIMemoryReporterCallback* aCb,
|
||||||
nsISupports* aClosure)
|
nsISupports* aClosure)
|
||||||
{
|
{
|
||||||
FontCacheSizes sizes;
|
FontCacheSizes sizes;
|
||||||
@@ -1324,7 +1324,7 @@ gfxFontCache::Init()
|
|||||||
if (!gGlobalCache) {
|
if (!gGlobalCache) {
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
NS_RegisterMemoryMultiReporter(new MemoryReporter);
|
NS_RegisterMemoryReporter(new MemoryReporter);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -977,11 +977,11 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
class MemoryReporter MOZ_FINAL
|
class MemoryReporter MOZ_FINAL
|
||||||
: public nsIMemoryMultiReporter
|
: public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
NS_DECL_NSIMEMORYMULTIREPORTER
|
NS_DECL_NSIMEMORYREPORTER
|
||||||
};
|
};
|
||||||
|
|
||||||
void DestroyFont(gfxFont *aFont);
|
void DestroyFont(gfxFont *aFont);
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ gfxFontListPrefObserver::Observe(nsISupports *aSubject,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(gfxPlatformFontList::MemoryReporter, nsIMemoryMultiReporter)
|
NS_IMPL_ISUPPORTS1(gfxPlatformFontList::MemoryReporter, nsIMemoryReporter)
|
||||||
|
|
||||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(FontListMallocSizeOf)
|
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(FontListMallocSizeOf)
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ gfxPlatformFontList::MemoryReporter::GetName(nsACString &aName)
|
|||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
gfxPlatformFontList::MemoryReporter::CollectReports
|
gfxPlatformFontList::MemoryReporter::CollectReports
|
||||||
(nsIMemoryMultiReporterCallback* aCb,
|
(nsIMemoryReporterCallback* aCb,
|
||||||
nsISupports* aClosure)
|
nsISupports* aClosure)
|
||||||
{
|
{
|
||||||
FontListSizes sizes;
|
FontListSizes sizes;
|
||||||
@@ -148,7 +148,7 @@ gfxPlatformFontList::gfxPlatformFontList(bool aNeedFullnamePostscriptNames)
|
|||||||
|
|
||||||
mSharedCmaps.Init(16);
|
mSharedCmaps.Init(16);
|
||||||
|
|
||||||
NS_RegisterMemoryMultiReporter(new MemoryReporter);
|
NS_RegisterMemoryReporter(new MemoryReporter);
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxPlatformFontList::~gfxPlatformFontList()
|
gfxPlatformFontList::~gfxPlatformFontList()
|
||||||
|
|||||||
@@ -179,11 +179,11 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
class MemoryReporter MOZ_FINAL
|
class MemoryReporter MOZ_FINAL
|
||||||
: public nsIMemoryMultiReporter
|
: public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
NS_DECL_NSIMEMORYMULTIREPORTER
|
NS_DECL_NSIMEMORYREPORTER
|
||||||
};
|
};
|
||||||
|
|
||||||
gfxPlatformFontList(bool aNeedFullnamePostscriptNames = true);
|
gfxPlatformFontList(bool aNeedFullnamePostscriptNames = true);
|
||||||
|
|||||||
@@ -73,11 +73,11 @@ static const int kSupportedFeatureLevels[] =
|
|||||||
{ D3D10_FEATURE_LEVEL_10_1, D3D10_FEATURE_LEVEL_10_0,
|
{ D3D10_FEATURE_LEVEL_10_1, D3D10_FEATURE_LEVEL_10_0,
|
||||||
D3D10_FEATURE_LEVEL_9_3 };
|
D3D10_FEATURE_LEVEL_9_3 };
|
||||||
|
|
||||||
class GfxD2DSurfaceCacheReporter MOZ_FINAL : public MemoryReporterBase
|
class GfxD2DSurfaceCacheReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GfxD2DSurfaceCacheReporter()
|
GfxD2DSurfaceCacheReporter()
|
||||||
: MemoryReporterBase("gfx-d2d-surface-cache", KIND_OTHER, UNITS_BYTES,
|
: MemoryUniReporter("gfx-d2d-surface-cache", KIND_OTHER, UNITS_BYTES,
|
||||||
"Memory used by the Direct2D internal surface cache.")
|
"Memory used by the Direct2D internal surface cache.")
|
||||||
{}
|
{}
|
||||||
private:
|
private:
|
||||||
@@ -110,11 +110,11 @@ bool OncePreferenceDirect2DForceEnabled()
|
|||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
class GfxD2DSurfaceVramReporter MOZ_FINAL : public MemoryReporterBase
|
class GfxD2DSurfaceVramReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GfxD2DSurfaceVramReporter()
|
GfxD2DSurfaceVramReporter()
|
||||||
: MemoryReporterBase("gfx-d2d-surface-vram", KIND_OTHER, UNITS_BYTES,
|
: MemoryUniReporter("gfx-d2d-surface-vram", KIND_OTHER, UNITS_BYTES,
|
||||||
"Video memory used by D2D surfaces.")
|
"Video memory used by D2D surfaces.")
|
||||||
{}
|
{}
|
||||||
private:
|
private:
|
||||||
@@ -127,11 +127,11 @@ private:
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class GfxD2DVramDrawTargetReporter MOZ_FINAL : public MemoryReporterBase
|
class GfxD2DVramDrawTargetReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GfxD2DVramDrawTargetReporter()
|
GfxD2DVramDrawTargetReporter()
|
||||||
: MemoryReporterBase("gfx-d2d-vram-draw-target", KIND_OTHER, UNITS_BYTES,
|
: MemoryUniReporter("gfx-d2d-vram-draw-target", KIND_OTHER, UNITS_BYTES,
|
||||||
"Video memory used by D2D DrawTargets.")
|
"Video memory used by D2D DrawTargets.")
|
||||||
{}
|
{}
|
||||||
private:
|
private:
|
||||||
@@ -141,11 +141,11 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class GfxD2DVramSourceSurfaceReporter MOZ_FINAL : public MemoryReporterBase
|
class GfxD2DVramSourceSurfaceReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GfxD2DVramSourceSurfaceReporter()
|
GfxD2DVramSourceSurfaceReporter()
|
||||||
: MemoryReporterBase("gfx-d2d-vram-source-surface",
|
: MemoryUniReporter("gfx-d2d-vram-source-surface",
|
||||||
KIND_OTHER, UNITS_BYTES,
|
KIND_OTHER, UNITS_BYTES,
|
||||||
"Video memory used by D2D SourceSurfaces.")
|
"Video memory used by D2D SourceSurfaces.")
|
||||||
{}
|
{}
|
||||||
@@ -206,7 +206,7 @@ typedef HRESULT (WINAPI*D3D11CreateDeviceFunc)(
|
|||||||
ID3D11DeviceContext *ppImmediateContext
|
ID3D11DeviceContext *ppImmediateContext
|
||||||
);
|
);
|
||||||
|
|
||||||
class GPUAdapterMultiReporter : public nsIMemoryMultiReporter {
|
class GPUAdapterReporter : public nsIMemoryReporter {
|
||||||
|
|
||||||
// Callers must Release the DXGIAdapter after use or risk mem-leak
|
// Callers must Release the DXGIAdapter after use or risk mem-leak
|
||||||
static bool GetDXGIAdapter(IDXGIAdapter **DXGIAdapter)
|
static bool GetDXGIAdapter(IDXGIAdapter **DXGIAdapter)
|
||||||
@@ -228,7 +228,7 @@ class GPUAdapterMultiReporter : public nsIMemoryMultiReporter {
|
|||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
// nsIMemoryMultiReporter abstract method implementation
|
// nsIMemoryReporter abstract method implementation
|
||||||
NS_IMETHOD
|
NS_IMETHOD
|
||||||
GetName(nsACString &aName)
|
GetName(nsACString &aName)
|
||||||
{
|
{
|
||||||
@@ -236,9 +236,9 @@ public:
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// nsIMemoryMultiReporter abstract method implementation
|
// nsIMemoryReporter abstract method implementation
|
||||||
NS_IMETHOD
|
NS_IMETHOD
|
||||||
CollectReports(nsIMemoryMultiReporterCallback* aCb,
|
CollectReports(nsIMemoryReporterCallback* aCb,
|
||||||
nsISupports* aClosure)
|
nsISupports* aClosure)
|
||||||
{
|
{
|
||||||
int32_t winVers, buildNum;
|
int32_t winVers, buildNum;
|
||||||
@@ -347,7 +347,7 @@ public:
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
NS_IMPL_ISUPPORTS1(GPUAdapterMultiReporter, nsIMemoryMultiReporter)
|
NS_IMPL_ISUPPORTS1(GPUAdapterReporter, nsIMemoryReporter)
|
||||||
|
|
||||||
static __inline void
|
static __inline void
|
||||||
BuildKeyNameFromFontName(nsAString &aName)
|
BuildKeyNameFromFontName(nsAString &aName)
|
||||||
@@ -385,16 +385,16 @@ gfxWindowsPlatform::gfxWindowsPlatform()
|
|||||||
|
|
||||||
UpdateRenderMode();
|
UpdateRenderMode();
|
||||||
|
|
||||||
mGPUAdapterMultiReporter = new GPUAdapterMultiReporter();
|
mGPUAdapterReporter = new GPUAdapterReporter();
|
||||||
NS_RegisterMemoryMultiReporter(mGPUAdapterMultiReporter);
|
NS_RegisterMemoryReporter(mGPUAdapterReporter);
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxWindowsPlatform::~gfxWindowsPlatform()
|
gfxWindowsPlatform::~gfxWindowsPlatform()
|
||||||
{
|
{
|
||||||
NS_UnregisterMemoryMultiReporter(mGPUAdapterMultiReporter);
|
NS_UnregisterMemoryReporter(mGPUAdapterReporter);
|
||||||
|
|
||||||
mDeviceManager = nullptr;
|
mDeviceManager = nullptr;
|
||||||
|
|
||||||
::ReleaseDC(nullptr, mScreenDC);
|
::ReleaseDC(nullptr, mScreenDC);
|
||||||
// not calling FT_Done_FreeType because cairo may still hold references to
|
// not calling FT_Done_FreeType because cairo may still hold references to
|
||||||
// these FT_Faces. See bug 458169.
|
// these FT_Faces. See bug 458169.
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ class IDirect3DDevice9;
|
|||||||
class ID3D11Device;
|
class ID3D11Device;
|
||||||
class IDXGIAdapter1;
|
class IDXGIAdapter1;
|
||||||
|
|
||||||
class nsIMemoryMultiReporter;
|
class nsIMemoryReporter;
|
||||||
|
|
||||||
// Utility to get a Windows HDC from a thebes context,
|
// Utility to get a Windows HDC from a thebes context,
|
||||||
// used by both GDI and Uniscribe font shapers
|
// used by both GDI and Uniscribe font shapers
|
||||||
@@ -315,7 +315,7 @@ private:
|
|||||||
// TODO: unify this with mPrefFonts (NB: holds families, not fonts) in gfxPlatformFontList
|
// TODO: unify this with mPrefFonts (NB: holds families, not fonts) in gfxPlatformFontList
|
||||||
nsDataHashtable<nsCStringHashKey, nsTArray<nsRefPtr<gfxFontEntry> > > mPrefFonts;
|
nsDataHashtable<nsCStringHashKey, nsTArray<nsRefPtr<gfxFontEntry> > > mPrefFonts;
|
||||||
|
|
||||||
nsIMemoryMultiReporter* mGPUAdapterMultiReporter;
|
nsIMemoryReporter* mGPUAdapterReporter;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* GFX_WINDOWS_PLATFORM_H */
|
#endif /* GFX_WINDOWS_PLATFORM_H */
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ using namespace mozilla::image;
|
|||||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(ImagesMallocSizeOf)
|
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(ImagesMallocSizeOf)
|
||||||
|
|
||||||
class imgMemoryReporter MOZ_FINAL :
|
class imgMemoryReporter MOZ_FINAL :
|
||||||
public nsIMemoryMultiReporter
|
public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
imgMemoryReporter()
|
imgMemoryReporter()
|
||||||
@@ -76,7 +76,7 @@ public:
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback *callback,
|
NS_IMETHOD CollectReports(nsIMemoryReporterCallback *callback,
|
||||||
nsISupports *closure)
|
nsISupports *closure)
|
||||||
{
|
{
|
||||||
AllSizes chrome;
|
AllSizes chrome;
|
||||||
@@ -233,15 +233,15 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(imgMemoryReporter, nsIMemoryMultiReporter)
|
NS_IMPL_ISUPPORTS1(imgMemoryReporter, nsIMemoryReporter)
|
||||||
|
|
||||||
// This is used by telemetry.
|
// This is used by telemetry.
|
||||||
class ImagesContentUsedUncompressedReporter MOZ_FINAL
|
class ImagesContentUsedUncompressedReporter MOZ_FINAL
|
||||||
: public MemoryReporterBase
|
: public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ImagesContentUsedUncompressedReporter()
|
ImagesContentUsedUncompressedReporter()
|
||||||
: MemoryReporterBase("images-content-used-uncompressed",
|
: MemoryUniReporter("images-content-used-uncompressed",
|
||||||
KIND_OTHER, UNITS_BYTES,
|
KIND_OTHER, UNITS_BYTES,
|
||||||
"This is the sum of the 'explicit/images/content/used/uncompressed-heap' "
|
"This is the sum of the 'explicit/images/content/used/uncompressed-heap' "
|
||||||
"and 'explicit/images/content/used/uncompressed-nonheap' numbers. However, "
|
"and 'explicit/images/content/used/uncompressed-nonheap' numbers. However, "
|
||||||
@@ -850,7 +850,7 @@ void imgLoader::GlobalInit()
|
|||||||
sCacheMaxSize = 5 * 1024 * 1024;
|
sCacheMaxSize = 5 * 1024 * 1024;
|
||||||
|
|
||||||
sMemReporter = new imgMemoryReporter();
|
sMemReporter = new imgMemoryReporter();
|
||||||
NS_RegisterMemoryMultiReporter(sMemReporter);
|
NS_RegisterMemoryReporter(sMemReporter);
|
||||||
NS_RegisterMemoryReporter(new ImagesContentUsedUncompressedReporter());
|
NS_RegisterMemoryReporter(new ImagesContentUsedUncompressedReporter());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,14 +25,18 @@ window.onload = function() {
|
|||||||
var mgr = SpecialPowers.Cc["@mozilla.org/memory-reporter-manager;1"]
|
var mgr = SpecialPowers.Cc["@mozilla.org/memory-reporter-manager;1"]
|
||||||
.getService(SpecialPowers.Ci.nsIMemoryReporterManager);
|
.getService(SpecialPowers.Ci.nsIMemoryReporterManager);
|
||||||
|
|
||||||
var e = mgr.enumerateReporters();
|
var amount = 0;
|
||||||
var memoryCounter = 0;
|
var handleReport = function(aProcess, aPath, aKind, aUnits, aAmount, aDesc) {
|
||||||
while (e.hasMoreElements()) {
|
amount += aAmount;
|
||||||
var mr =
|
|
||||||
e.getNext().QueryInterface(SpecialPowers.Ci.nsIMemoryReporter);
|
|
||||||
memoryCounter += mr.amount;
|
|
||||||
}
|
}
|
||||||
ok(memoryCounter > 0, "we should be using a nonzero amount of memory");
|
|
||||||
|
var e = mgr.enumerateReporters();
|
||||||
|
while (e.hasMoreElements()) {
|
||||||
|
var mr = e.getNext().QueryInterface(SpecialPowers.Ci.nsIMemoryReporter);
|
||||||
|
mr.collectReports(handleReport, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
ok(amount > 0, "we should be using a nonzero amount of memory");
|
||||||
ok(true, "yay, didn't crash!");
|
ok(true, "yay, didn't crash!");
|
||||||
|
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ namespace ipc {
|
|||||||
static Atomic<size_t> gShmemAllocated;
|
static Atomic<size_t> gShmemAllocated;
|
||||||
static Atomic<size_t> gShmemMapped;
|
static Atomic<size_t> gShmemMapped;
|
||||||
|
|
||||||
class ShmemAllocatedReporter MOZ_FINAL : public MemoryReporterBase
|
class ShmemAllocatedReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ShmemAllocatedReporter()
|
ShmemAllocatedReporter()
|
||||||
: MemoryReporterBase("shmem-allocated", KIND_OTHER, UNITS_BYTES,
|
: MemoryUniReporter("shmem-allocated", KIND_OTHER, UNITS_BYTES,
|
||||||
"Memory shared with other processes that is accessible (but not necessarily "
|
"Memory shared with other processes that is accessible (but not necessarily "
|
||||||
"mapped).")
|
"mapped).")
|
||||||
{}
|
{}
|
||||||
@@ -29,11 +29,11 @@ private:
|
|||||||
int64_t Amount() MOZ_OVERRIDE { return gShmemAllocated; }
|
int64_t Amount() MOZ_OVERRIDE { return gShmemAllocated; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class ShmemMappedReporter MOZ_FINAL : public MemoryReporterBase
|
class ShmemMappedReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ShmemMappedReporter()
|
ShmemMappedReporter()
|
||||||
: MemoryReporterBase("shmem-mapped", KIND_OTHER, UNITS_BYTES,
|
: MemoryUniReporter("shmem-mapped", KIND_OTHER, UNITS_BYTES,
|
||||||
"Memory shared with other processes that is mapped into the address space.")
|
"Memory shared with other processes that is mapped into the address space.")
|
||||||
{}
|
{}
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -9,22 +9,22 @@
|
|||||||
#define XPCJSMemoryReporter_h
|
#define XPCJSMemoryReporter_h
|
||||||
|
|
||||||
class nsISupports;
|
class nsISupports;
|
||||||
class nsIMemoryMultiReporterCallback;
|
class nsIMemoryReporterCallback;
|
||||||
|
|
||||||
namespace xpc {
|
namespace xpc {
|
||||||
|
|
||||||
// The key is the window ID.
|
// The key is the window ID.
|
||||||
typedef nsDataHashtable<nsUint64HashKey, nsCString> WindowPaths;
|
typedef nsDataHashtable<nsUint64HashKey, nsCString> WindowPaths;
|
||||||
|
|
||||||
// This is very nearly an instance of nsIMemoryMultiReporter, but it's not,
|
// This is very nearly an instance of nsIMemoryReporter, but it's not,
|
||||||
// because it's invoked by nsWindowMemoryReporter in order to get |windowPaths|
|
// because it's invoked by nsWindowMemoryReporter in order to get |windowPaths|
|
||||||
// in CollectReports.
|
// in CollectReports.
|
||||||
class JSMemoryMultiReporter
|
class JSReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static nsresult CollectReports(WindowPaths *windowPaths,
|
static nsresult CollectReports(WindowPaths *windowPaths,
|
||||||
WindowPaths *topWindowPaths,
|
WindowPaths *topWindowPaths,
|
||||||
nsIMemoryMultiReporterCallback *cb,
|
nsIMemoryReporterCallback *cb,
|
||||||
nsISupports *closure);
|
nsISupports *closure);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1560,13 +1560,13 @@ GetCompartmentName(JSCompartment *c, nsCString &name, bool replaceSlashes)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Telemetry relies on this being a single reporter (rather than part of the
|
// Telemetry relies on this being a uni-reporter (rather than part of the "js"
|
||||||
// "js" multi-reporter).
|
// reporter).
|
||||||
class JSGCHeapReporter MOZ_FINAL : public MemoryReporterBase
|
class JSGCHeapReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
JSGCHeapReporter()
|
JSGCHeapReporter()
|
||||||
: MemoryReporterBase("js-gc-heap", KIND_OTHER, UNITS_BYTES,
|
: MemoryUniReporter("js-gc-heap", KIND_OTHER, UNITS_BYTES,
|
||||||
"Memory used by the garbage-collected JavaScript heap.")
|
"Memory used by the garbage-collected JavaScript heap.")
|
||||||
{}
|
{}
|
||||||
private:
|
private:
|
||||||
@@ -1578,19 +1578,17 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Nb: js-compartments/system + js-compartments/user could be
|
// Nb: js-compartments/system + js-compartments/user could be different to the
|
||||||
// different to the number of compartments reported by
|
// number of compartments reported by JSReporter if a garbage collection
|
||||||
// JSMemoryMultiReporter if a garbage collection occurred
|
// occurred between them being consulted. We could move these reporters into
|
||||||
// between them being consulted. We could move these reporters into
|
// JSReporter to avoid that problem, but then we couldn't easily report them
|
||||||
// XPConnectJSCompartmentCount to avoid that problem, but then we couldn't
|
// via telemetry, so we live with the small risk of inconsistencies.
|
||||||
// easily report them via telemetry, so we live with the small risk of
|
|
||||||
// inconsistencies.
|
|
||||||
|
|
||||||
class JSCompartmentsSystemReporter MOZ_FINAL : public MemoryReporterBase
|
class JSCompartmentsSystemReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
JSCompartmentsSystemReporter()
|
JSCompartmentsSystemReporter()
|
||||||
: MemoryReporterBase("js-compartments/system", KIND_OTHER, UNITS_COUNT,
|
: MemoryUniReporter("js-compartments/system", KIND_OTHER, UNITS_COUNT,
|
||||||
"The number of JavaScript compartments for system code. The sum of this and "
|
"The number of JavaScript compartments for system code. The sum of this and "
|
||||||
"'js-compartments/user' might not match the number of compartments listed "
|
"'js-compartments/user' might not match the number of compartments listed "
|
||||||
"in the 'explicit' tree if a garbage collection occurs at an inopportune "
|
"in the 'explicit' tree if a garbage collection occurs at an inopportune "
|
||||||
@@ -1604,11 +1602,11 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class JSCompartmentsUserReporter MOZ_FINAL : public MemoryReporterBase
|
class JSCompartmentsUserReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
JSCompartmentsUserReporter()
|
JSCompartmentsUserReporter()
|
||||||
: MemoryReporterBase("js-compartments/user", KIND_OTHER, UNITS_COUNT,
|
: MemoryUniReporter("js-compartments/user", KIND_OTHER, UNITS_COUNT,
|
||||||
"The number of JavaScript compartments for user code. The sum of this and "
|
"The number of JavaScript compartments for user code. The sum of this and "
|
||||||
"'js-compartments/system' might not match the number of compartments listed "
|
"'js-compartments/system' might not match the number of compartments listed "
|
||||||
"under 'js' if a garbage collection occurs at an inopportune time, but such "
|
"under 'js' if a garbage collection occurs at an inopportune time, but such "
|
||||||
@@ -1623,11 +1621,11 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// This is also a single reporter so it can be used by telemetry.
|
// This is also a single reporter so it can be used by telemetry.
|
||||||
class JSMainRuntimeTemporaryPeakReporter MOZ_FINAL : public MemoryReporterBase
|
class JSMainRuntimeTemporaryPeakReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
JSMainRuntimeTemporaryPeakReporter()
|
JSMainRuntimeTemporaryPeakReporter()
|
||||||
: MemoryReporterBase("js-main-runtime-temporary-peak",
|
: MemoryUniReporter("js-main-runtime-temporary-peak",
|
||||||
KIND_OTHER, UNITS_BYTES,
|
KIND_OTHER, UNITS_BYTES,
|
||||||
"The peak size of the transient storage in the main JSRuntime (the current "
|
"The peak size of the transient storage in the main JSRuntime (the current "
|
||||||
"size of which is reported as 'explicit/js-non-window/runtime/temporary').")
|
"size of which is reported as 'explicit/js-non-window/runtime/temporary').")
|
||||||
@@ -1758,7 +1756,7 @@ namespace xpc {
|
|||||||
static nsresult
|
static nsresult
|
||||||
ReportZoneStats(const JS::ZoneStats &zStats,
|
ReportZoneStats(const JS::ZoneStats &zStats,
|
||||||
const xpc::ZoneStatsExtras &extras,
|
const xpc::ZoneStatsExtras &extras,
|
||||||
nsIMemoryMultiReporterCallback *cb,
|
nsIMemoryReporterCallback *cb,
|
||||||
nsISupports *closure, size_t *gcTotalOut = NULL)
|
nsISupports *closure, size_t *gcTotalOut = NULL)
|
||||||
{
|
{
|
||||||
const nsAutoCString& pathPrefix = extras.pathPrefix;
|
const nsAutoCString& pathPrefix = extras.pathPrefix;
|
||||||
@@ -1942,7 +1940,7 @@ static nsresult
|
|||||||
ReportCompartmentStats(const JS::CompartmentStats &cStats,
|
ReportCompartmentStats(const JS::CompartmentStats &cStats,
|
||||||
const xpc::CompartmentStatsExtras &extras,
|
const xpc::CompartmentStatsExtras &extras,
|
||||||
amIAddonManager *addonManager,
|
amIAddonManager *addonManager,
|
||||||
nsIMemoryMultiReporterCallback *cb,
|
nsIMemoryReporterCallback *cb,
|
||||||
nsISupports *closure, size_t *gcTotalOut = NULL)
|
nsISupports *closure, size_t *gcTotalOut = NULL)
|
||||||
{
|
{
|
||||||
static const nsDependentCString addonPrefix("explicit/add-ons/");
|
static const nsDependentCString addonPrefix("explicit/add-ons/");
|
||||||
@@ -2084,8 +2082,8 @@ ReportCompartmentStats(const JS::CompartmentStats &cStats,
|
|||||||
"Memory allocated on the malloc heap for data belonging to ctypes objects.");
|
"Memory allocated on the malloc heap for data belonging to ctypes objects.");
|
||||||
|
|
||||||
// Note that we use cDOMPathPrefix here. This is because we measure orphan
|
// Note that we use cDOMPathPrefix here. This is because we measure orphan
|
||||||
// DOM nodes in the JS multi-reporter, but we want to report them in a
|
// DOM nodes in the JS reporter, but we want to report them in a "dom"
|
||||||
// "dom" sub-tree rather than a "js" sub-tree.
|
// sub-tree rather than a "js" sub-tree.
|
||||||
ZCREPORT_BYTES(cDOMPathPrefix + NS_LITERAL_CSTRING("orphan-nodes"),
|
ZCREPORT_BYTES(cDOMPathPrefix + NS_LITERAL_CSTRING("orphan-nodes"),
|
||||||
cStats.objectsExtra.private_,
|
cStats.objectsExtra.private_,
|
||||||
"Memory used by orphan DOM nodes that are only reachable "
|
"Memory used by orphan DOM nodes that are only reachable "
|
||||||
@@ -2207,7 +2205,7 @@ static nsresult
|
|||||||
ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats,
|
ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats,
|
||||||
const nsACString &rtPath,
|
const nsACString &rtPath,
|
||||||
amIAddonManager* addonManager,
|
amIAddonManager* addonManager,
|
||||||
nsIMemoryMultiReporterCallback *cb,
|
nsIMemoryReporterCallback *cb,
|
||||||
nsISupports *closure, size_t *rtTotalOut)
|
nsISupports *closure, size_t *rtTotalOut)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
@@ -2349,7 +2347,7 @@ ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats,
|
|||||||
nsresult
|
nsresult
|
||||||
ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats,
|
ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats,
|
||||||
const nsACString &rtPath,
|
const nsACString &rtPath,
|
||||||
nsIMemoryMultiReporterCallback *cb,
|
nsIMemoryReporterCallback *cb,
|
||||||
nsISupports *closure, size_t *rtTotalOut)
|
nsISupports *closure, size_t *rtTotalOut)
|
||||||
{
|
{
|
||||||
nsCOMPtr<amIAddonManager> am =
|
nsCOMPtr<amIAddonManager> am =
|
||||||
@@ -2361,7 +2359,7 @@ ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats,
|
|||||||
|
|
||||||
} // namespace xpc
|
} // namespace xpc
|
||||||
|
|
||||||
class JSCompartmentsMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
class JSCompartmentsReporter MOZ_FINAL : public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||||||
@@ -2385,7 +2383,7 @@ class JSCompartmentsMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
|||||||
paths->append(path);
|
paths->append(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback *cb,
|
NS_IMETHOD CollectReports(nsIMemoryReporterCallback *cb,
|
||||||
nsISupports *closure)
|
nsISupports *closure)
|
||||||
{
|
{
|
||||||
// First we collect the compartment paths. Then we report them. Doing
|
// First we collect the compartment paths. Then we report them. Doing
|
||||||
@@ -2407,9 +2405,7 @@ class JSCompartmentsMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(JSCompartmentsMultiReporter
|
NS_IMPL_ISUPPORTS1(JSCompartmentsReporter, nsIMemoryReporter)
|
||||||
, nsIMemoryMultiReporter
|
|
||||||
)
|
|
||||||
|
|
||||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(OrphanMallocSizeOf)
|
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(OrphanMallocSizeOf)
|
||||||
|
|
||||||
@@ -2567,9 +2563,9 @@ class XPCJSRuntimeStats : public JS::RuntimeStats
|
|||||||
// "<something>compartment(<cname>)/".
|
// "<something>compartment(<cname>)/".
|
||||||
//
|
//
|
||||||
// extras->domPathPrefix is used for DOM orphan nodes, which are
|
// extras->domPathPrefix is used for DOM orphan nodes, which are
|
||||||
// counted by the JS multi-reporter but reported as part of the
|
// counted by the JS reporter but reported as part of the DOM
|
||||||
// DOM measurements. At this point it has the form "<something>/dom/"
|
// measurements. At this point it has the form "<something>/dom/" if
|
||||||
// if this compartment belongs to an nsGlobalWindow, and
|
// this compartment belongs to an nsGlobalWindow, and
|
||||||
// "explicit/dom/<something>?!/" otherwise (in which case it shouldn't
|
// "explicit/dom/<something>?!/" otherwise (in which case it shouldn't
|
||||||
// be used, because non-nsGlobalWindow compartments shouldn't have
|
// be used, because non-nsGlobalWindow compartments shouldn't have
|
||||||
// orphan DOM nodes).
|
// orphan DOM nodes).
|
||||||
@@ -2579,10 +2575,10 @@ class XPCJSRuntimeStats : public JS::RuntimeStats
|
|||||||
};
|
};
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
JSMemoryMultiReporter::CollectReports(WindowPaths *windowPaths,
|
JSReporter::CollectReports(WindowPaths *windowPaths,
|
||||||
WindowPaths *topWindowPaths,
|
WindowPaths *topWindowPaths,
|
||||||
nsIMemoryMultiReporterCallback *cb,
|
nsIMemoryReporterCallback *cb,
|
||||||
nsISupports *closure)
|
nsISupports *closure)
|
||||||
{
|
{
|
||||||
XPCJSRuntime *xpcrt = nsXPConnect::GetRuntimeInstance();
|
XPCJSRuntime *xpcrt = nsXPConnect::GetRuntimeInstance();
|
||||||
|
|
||||||
@@ -3053,7 +3049,7 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
|
|||||||
NS_RegisterMemoryReporter(new JSCompartmentsSystemReporter());
|
NS_RegisterMemoryReporter(new JSCompartmentsSystemReporter());
|
||||||
NS_RegisterMemoryReporter(new JSCompartmentsUserReporter());
|
NS_RegisterMemoryReporter(new JSCompartmentsUserReporter());
|
||||||
NS_RegisterMemoryReporter(new JSMainRuntimeTemporaryPeakReporter());
|
NS_RegisterMemoryReporter(new JSMainRuntimeTemporaryPeakReporter());
|
||||||
NS_RegisterMemoryMultiReporter(new JSCompartmentsMultiReporter);
|
NS_RegisterMemoryReporter(new JSCompartmentsReporter);
|
||||||
|
|
||||||
// Install a JavaScript 'debugger' keyword handler in debug builds only
|
// Install a JavaScript 'debugger' keyword handler in debug builds only
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ xpc_UnmarkSkippableJSHolders();
|
|||||||
NS_EXPORT_(void)
|
NS_EXPORT_(void)
|
||||||
xpc_ActivateDebugMode();
|
xpc_ActivateDebugMode();
|
||||||
|
|
||||||
class nsIMemoryMultiReporterCallback;
|
class nsIMemoryReporterCallback;
|
||||||
|
|
||||||
// readable string conversions, static methods and members only
|
// readable string conversions, static methods and members only
|
||||||
class XPCStringConvert
|
class XPCStringConvert
|
||||||
@@ -376,7 +376,7 @@ private:
|
|||||||
nsresult
|
nsresult
|
||||||
ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats,
|
ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats,
|
||||||
const nsACString &rtPath,
|
const nsACString &rtPath,
|
||||||
nsIMemoryMultiReporterCallback *cb,
|
nsIMemoryReporterCallback *cb,
|
||||||
nsISupports *closure, size_t *rtTotal = NULL);
|
nsISupports *closure, size_t *rtTotal = NULL);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -26,11 +26,11 @@
|
|||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
|
||||||
class LayoutStyleSheetServiceReporter MOZ_FINAL
|
class LayoutStyleSheetServiceReporter MOZ_FINAL
|
||||||
: public mozilla::MemoryReporterBase
|
: public mozilla::MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LayoutStyleSheetServiceReporter()
|
LayoutStyleSheetServiceReporter()
|
||||||
: MemoryReporterBase("explicit/layout/style-sheet-service",
|
: MemoryUniReporter("explicit/layout/style-sheet-service",
|
||||||
KIND_HEAP, UNITS_BYTES,
|
KIND_HEAP, UNITS_BYTES,
|
||||||
"Memory used for style sheets held by the style sheet service.")
|
"Memory used for style sheets held by the style sheet service.")
|
||||||
{}
|
{}
|
||||||
|
|||||||
@@ -18,11 +18,11 @@
|
|||||||
#include "nsCSSStyleSheet.h"
|
#include "nsCSSStyleSheet.h"
|
||||||
|
|
||||||
class LayoutStyleSheetCacheReporter MOZ_FINAL
|
class LayoutStyleSheetCacheReporter MOZ_FINAL
|
||||||
: public mozilla::MemoryReporterBase
|
: public mozilla::MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LayoutStyleSheetCacheReporter()
|
LayoutStyleSheetCacheReporter()
|
||||||
: MemoryReporterBase("explicit/layout/style-sheet-cache",
|
: MemoryUniReporter("explicit/layout/style-sheet-cache",
|
||||||
KIND_HEAP, UNITS_BYTES,
|
KIND_HEAP, UNITS_BYTES,
|
||||||
"Memory used for some built-in style sheets.")
|
"Memory used for some built-in style sheets.")
|
||||||
{}
|
{}
|
||||||
|
|||||||
@@ -203,11 +203,11 @@ Preferences::SizeOfIncludingThisAndOtherStuff(mozilla::MallocSizeOf aMallocSizeO
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
class PreferencesReporter MOZ_FINAL : public MemoryReporterBase
|
class PreferencesReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PreferencesReporter()
|
PreferencesReporter()
|
||||||
: MemoryReporterBase("explicit/preferences", KIND_HEAP, UNITS_BYTES,
|
: MemoryUniReporter("explicit/preferences", KIND_HEAP, UNITS_BYTES,
|
||||||
"Memory used by the preferences system.")
|
"Memory used by the preferences system.")
|
||||||
{}
|
{}
|
||||||
private:
|
private:
|
||||||
|
|||||||
4
netwerk/cache/nsDiskCacheDevice.cpp
vendored
4
netwerk/cache/nsDiskCacheDevice.cpp
vendored
@@ -370,11 +370,11 @@ nsDiskCache::Truncate(PRFileDesc * fd, uint32_t newEOF)
|
|||||||
* nsDiskCacheDevice
|
* nsDiskCacheDevice
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
class NetworkDiskCacheReporter MOZ_FINAL : public MemoryReporterBase
|
class NetworkDiskCacheReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NetworkDiskCacheReporter(nsDiskCacheDevice* aDevice)
|
NetworkDiskCacheReporter(nsDiskCacheDevice* aDevice)
|
||||||
: MemoryReporterBase(
|
: MemoryUniReporter(
|
||||||
"explicit/network/disk-cache",
|
"explicit/network/disk-cache",
|
||||||
KIND_HEAP,
|
KIND_HEAP,
|
||||||
UNITS_BYTES,
|
UNITS_BYTES,
|
||||||
|
|||||||
4
netwerk/cache/nsMemoryCacheDevice.cpp
vendored
4
netwerk/cache/nsMemoryCacheDevice.cpp
vendored
@@ -29,11 +29,11 @@
|
|||||||
const char *gMemoryDeviceID = "memory";
|
const char *gMemoryDeviceID = "memory";
|
||||||
|
|
||||||
class NetworkMemoryCacheReporter MOZ_FINAL :
|
class NetworkMemoryCacheReporter MOZ_FINAL :
|
||||||
public mozilla::MemoryReporterBase
|
public mozilla::MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NetworkMemoryCacheReporter(nsMemoryCacheDevice* aDevice)
|
NetworkMemoryCacheReporter(nsMemoryCacheDevice* aDevice)
|
||||||
: MemoryReporterBase(
|
: MemoryUniReporter(
|
||||||
"explicit/network/memory-cache",
|
"explicit/network/memory-cache",
|
||||||
KIND_HEAP,
|
KIND_HEAP,
|
||||||
UNITS_BYTES,
|
UNITS_BYTES,
|
||||||
|
|||||||
@@ -61,11 +61,11 @@ nsDomainEntry::FuncForStaticAsserts(void)
|
|||||||
|
|
||||||
static nsEffectiveTLDService *gService = nullptr;
|
static nsEffectiveTLDService *gService = nullptr;
|
||||||
|
|
||||||
class EffectiveTLDServiceReporter MOZ_FINAL : public MemoryReporterBase
|
class EffectiveTLDServiceReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EffectiveTLDServiceReporter()
|
EffectiveTLDServiceReporter()
|
||||||
: MemoryReporterBase("explicit/xpcom/effective-TLD-service",
|
: MemoryUniReporter("explicit/xpcom/effective-TLD-service",
|
||||||
KIND_HEAP, UNITS_BYTES,
|
KIND_HEAP, UNITS_BYTES,
|
||||||
"Memory used by the effective TLD service.")
|
"Memory used by the effective TLD service.")
|
||||||
{}
|
{}
|
||||||
|
|||||||
@@ -53,11 +53,11 @@
|
|||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace scache {
|
namespace scache {
|
||||||
|
|
||||||
class StartupCacheMappingReporter MOZ_FINAL : public MemoryReporterBase
|
class StartupCacheMappingReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StartupCacheMappingReporter()
|
StartupCacheMappingReporter()
|
||||||
: MemoryReporterBase("explicit/startup-cache/mapping",
|
: MemoryUniReporter("explicit/startup-cache/mapping",
|
||||||
KIND_NONHEAP, UNITS_BYTES,
|
KIND_NONHEAP, UNITS_BYTES,
|
||||||
"Memory used to hold the mapping of the startup cache from file. This memory "
|
"Memory used to hold the mapping of the startup cache from file. This memory "
|
||||||
"is likely to be swapped out shortly after start-up.")
|
"is likely to be swapped out shortly after start-up.")
|
||||||
@@ -71,11 +71,11 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class StartupCacheDataReporter MOZ_FINAL : public MemoryReporterBase
|
class StartupCacheDataReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StartupCacheDataReporter()
|
StartupCacheDataReporter()
|
||||||
: MemoryReporterBase("explicit/startup-cache/data", KIND_HEAP, UNITS_BYTES,
|
: MemoryUniReporter("explicit/startup-cache/data", KIND_HEAP, UNITS_BYTES,
|
||||||
"Memory used by the startup cache for things other than the file mapping.")
|
"Memory used by the startup cache for things other than the file mapping.")
|
||||||
{}
|
{}
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -57,18 +57,18 @@ namespace storage {
|
|||||||
// the multi-reporter provides reports that add up to the total. But it's
|
// the multi-reporter provides reports that add up to the total. But it's
|
||||||
// useful to have the total in the "Other Measurements" list in about:memory,
|
// useful to have the total in the "Other Measurements" list in about:memory,
|
||||||
// and more importantly, we also gather the total via telemetry.
|
// and more importantly, we also gather the total via telemetry.
|
||||||
class StorageSQLiteReporter MOZ_FINAL : public MemoryReporterBase
|
class StorageSQLiteUniReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StorageSQLiteReporter()
|
StorageSQLiteUniReporter()
|
||||||
: MemoryReporterBase("storage-sqlite", KIND_OTHER, UNITS_BYTES,
|
: MemoryUniReporter("storage-sqlite", KIND_OTHER, UNITS_BYTES,
|
||||||
"Memory used by SQLite.")
|
"Memory used by SQLite.")
|
||||||
{}
|
{}
|
||||||
private:
|
private:
|
||||||
int64_t Amount() MOZ_OVERRIDE { return ::sqlite3_memory_used(); }
|
int64_t Amount() MOZ_OVERRIDE { return ::sqlite3_memory_used(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class StorageSQLiteMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
class StorageSQLiteMultiReporter MOZ_FINAL : public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Service *mService; // a weakref because Service contains a strongref to this
|
Service *mService; // a weakref because Service contains a strongref to this
|
||||||
@@ -97,7 +97,7 @@ public:
|
|||||||
|
|
||||||
NS_IMETHOD GetName(nsACString &aName)
|
NS_IMETHOD GetName(nsACString &aName)
|
||||||
{
|
{
|
||||||
aName.AssignLiteral("storage-sqlite");
|
aName.AssignLiteral("storage-sqlite-multi");
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ public:
|
|||||||
// main thread! But at the time of writing this function is only called when
|
// main thread! But at the time of writing this function is only called when
|
||||||
// about:memory is loaded (not, for example, when telemetry pings occur) and
|
// about:memory is loaded (not, for example, when telemetry pings occur) and
|
||||||
// any delays in that case aren't so bad.
|
// any delays in that case aren't so bad.
|
||||||
NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback *aCb,
|
NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCb,
|
||||||
nsISupports *aClosure)
|
nsISupports *aClosure)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
@@ -164,8 +164,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* Passes a single SQLite memory statistic to a memory multi-reporter
|
* Passes a single SQLite memory statistic to a memory reporter callback.
|
||||||
* callback.
|
|
||||||
*
|
*
|
||||||
* @param aCallback
|
* @param aCallback
|
||||||
* The callback.
|
* The callback.
|
||||||
@@ -185,7 +184,7 @@ private:
|
|||||||
* @param aTotal
|
* @param aTotal
|
||||||
* The accumulator for the measurement.
|
* The accumulator for the measurement.
|
||||||
*/
|
*/
|
||||||
nsresult reportConn(nsIMemoryMultiReporterCallback *aCb,
|
nsresult reportConn(nsIMemoryReporterCallback *aCb,
|
||||||
nsISupports *aClosure,
|
nsISupports *aClosure,
|
||||||
sqlite3 *aConn,
|
sqlite3 *aConn,
|
||||||
const nsACString &aPathHead,
|
const nsACString &aPathHead,
|
||||||
@@ -216,7 +215,7 @@ private:
|
|||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(
|
NS_IMPL_ISUPPORTS1(
|
||||||
StorageSQLiteMultiReporter,
|
StorageSQLiteMultiReporter,
|
||||||
nsIMemoryMultiReporter
|
nsIMemoryReporter
|
||||||
)
|
)
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -308,8 +307,8 @@ Service::Service()
|
|||||||
|
|
||||||
Service::~Service()
|
Service::~Service()
|
||||||
{
|
{
|
||||||
(void)::NS_UnregisterMemoryReporter(mStorageSQLiteReporter);
|
(void)::NS_UnregisterMemoryReporter(mStorageSQLiteUniReporter);
|
||||||
(void)::NS_UnregisterMemoryMultiReporter(mStorageSQLiteMultiReporter);
|
(void)::NS_UnregisterMemoryReporter(mStorageSQLiteMultiReporter);
|
||||||
|
|
||||||
int rc = sqlite3_vfs_unregister(mSqliteVFS);
|
int rc = sqlite3_vfs_unregister(mSqliteVFS);
|
||||||
if (rc != SQLITE_OK)
|
if (rc != SQLITE_OK)
|
||||||
@@ -541,10 +540,10 @@ Service::initialize()
|
|||||||
|
|
||||||
// Create and register our SQLite memory reporters. Registration can only
|
// Create and register our SQLite memory reporters. Registration can only
|
||||||
// happen on the main thread (otherwise you'll get cryptic crashes).
|
// happen on the main thread (otherwise you'll get cryptic crashes).
|
||||||
mStorageSQLiteReporter = new StorageSQLiteReporter();
|
mStorageSQLiteUniReporter = new StorageSQLiteUniReporter();
|
||||||
mStorageSQLiteMultiReporter = new StorageSQLiteMultiReporter(this);
|
mStorageSQLiteMultiReporter = new StorageSQLiteMultiReporter(this);
|
||||||
(void)::NS_RegisterMemoryReporter(mStorageSQLiteReporter);
|
(void)::NS_RegisterMemoryReporter(mStorageSQLiteUniReporter);
|
||||||
(void)::NS_RegisterMemoryMultiReporter(mStorageSQLiteMultiReporter);
|
(void)::NS_RegisterMemoryReporter(mStorageSQLiteMultiReporter);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
#include "mozIStorageService.h"
|
#include "mozIStorageService.h"
|
||||||
|
|
||||||
class nsIMemoryReporter;
|
class nsIMemoryReporter;
|
||||||
class nsIMemoryMultiReporter;
|
|
||||||
class nsIXPConnect;
|
class nsIXPConnect;
|
||||||
struct sqlite3_vfs;
|
struct sqlite3_vfs;
|
||||||
|
|
||||||
@@ -173,8 +172,8 @@ private:
|
|||||||
|
|
||||||
nsCOMPtr<nsIFile> mProfileStorageFile;
|
nsCOMPtr<nsIFile> mProfileStorageFile;
|
||||||
|
|
||||||
nsCOMPtr<nsIMemoryReporter> mStorageSQLiteReporter;
|
nsCOMPtr<nsIMemoryReporter> mStorageSQLiteUniReporter;
|
||||||
nsCOMPtr<nsIMemoryMultiReporter> mStorageSQLiteMultiReporter;
|
nsCOMPtr<nsIMemoryReporter> mStorageSQLiteMultiReporter;
|
||||||
|
|
||||||
static Service *gService;
|
static Service *gService;
|
||||||
|
|
||||||
|
|||||||
@@ -166,49 +166,32 @@ function onUnload()
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iterates over each reporter and multi-reporter.
|
* Iterates over each reporter.
|
||||||
*
|
*
|
||||||
* @param aIgnoreSingle
|
* @param aIgnoreReporter
|
||||||
* Function that indicates if we should skip a single reporter, based
|
* Function that indicates if we should skip an entire reporter, based
|
||||||
* on its path.
|
* on its name.
|
||||||
* @param aIgnoreMulti
|
* @param aIgnoreReport
|
||||||
* Function that indicates if we should skip a multi-reporter, based on
|
* Function that indicates if we should skip a single report from a
|
||||||
* its name.
|
* reporter, based on its path.
|
||||||
* @param aHandleReport
|
* @param aHandleReport
|
||||||
* The function that's called for each report.
|
* The function that's called for each non-skipped report.
|
||||||
*/
|
*/
|
||||||
function processMemoryReporters(aIgnoreSingle, aIgnoreMulti, aHandleReport)
|
function processMemoryReporters(aIgnoreReporter, aIgnoreReport, aHandleReport)
|
||||||
{
|
{
|
||||||
// Process each memory reporter with aHandleReport.
|
let handleReport = function(aProcess, aUnsafePath, aKind, aUnits,
|
||||||
//
|
aAmount, aDescription) {
|
||||||
// - Note that copying rOrig.amount (which calls a C++ function under the
|
if (!aIgnoreReport(aUnsafePath)) {
|
||||||
// IDL covers) to r._amount for every reporter now means that the
|
aHandleReport(aProcess, aUnsafePath, aKind, aUnits, aAmount,
|
||||||
// results as consistent as possible -- measurements are made all at
|
aDescription, /* presence = */ undefined);
|
||||||
// once before most of the memory required to generate this page is
|
|
||||||
// allocated.
|
|
||||||
//
|
|
||||||
// - After this point we never use the original memory report again.
|
|
||||||
|
|
||||||
let e = gMgr.enumerateReporters();
|
|
||||||
while (e.hasMoreElements()) {
|
|
||||||
let rOrig = e.getNext().QueryInterface(Ci.nsIMemoryReporter);
|
|
||||||
let unsafePath = rOrig.path;
|
|
||||||
if (!aIgnoreSingle(unsafePath)) {
|
|
||||||
aHandleReport(rOrig.process, unsafePath, rOrig.kind, rOrig.units,
|
|
||||||
rOrig.amount, rOrig.description);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let e = gMgr.enumerateMultiReporters();
|
let e = gMgr.enumerateReporters();
|
||||||
while (e.hasMoreElements()) {
|
while (e.hasMoreElements()) {
|
||||||
let mr = e.getNext().QueryInterface(Ci.nsIMemoryMultiReporter);
|
let mr = e.getNext().QueryInterface(Ci.nsIMemoryReporter);
|
||||||
if (!aIgnoreMulti(mr.name)) {
|
if (!aIgnoreReporter(mr.name)) {
|
||||||
// |collectReports| never passes in a |presence| argument.
|
// |collectReports| never passes in a |presence| argument.
|
||||||
let handleReport = function(aProcess, aUnsafePath, aKind, aUnits,
|
|
||||||
aAmount, aDescription) {
|
|
||||||
aHandleReport(aProcess, aUnsafePath, aKind, aUnits, aAmount,
|
|
||||||
aDescription, /* presence = */ undefined);
|
|
||||||
}
|
|
||||||
mr.collectReports(handleReport, null);
|
mr.collectReports(handleReport, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -219,19 +202,19 @@ function processMemoryReporters(aIgnoreSingle, aIgnoreMulti, aHandleReport)
|
|||||||
*
|
*
|
||||||
* @param aReports
|
* @param aReports
|
||||||
* Array of reports, read from a file or the clipboard.
|
* Array of reports, read from a file or the clipboard.
|
||||||
* @param aIgnoreSingle
|
* @param aIgnoreReport
|
||||||
* Function that indicates if we should skip a single reporter, based
|
* Function that indicates if we should skip a single report, based
|
||||||
* on its path.
|
* on its path.
|
||||||
* @param aHandleReport
|
* @param aHandleReport
|
||||||
* The function that's called for each report.
|
* The function that's called for each report.
|
||||||
*/
|
*/
|
||||||
function processMemoryReportsFromFile(aReports, aIgnoreSingle, aHandleReport)
|
function processMemoryReportsFromFile(aReports, aIgnoreReport, aHandleReport)
|
||||||
{
|
{
|
||||||
// Process each memory reporter with aHandleReport.
|
// Process each memory reporter with aHandleReport.
|
||||||
|
|
||||||
for (let i = 0; i < aReports.length; i++) {
|
for (let i = 0; i < aReports.length; i++) {
|
||||||
let r = aReports[i];
|
let r = aReports[i];
|
||||||
if (!aIgnoreSingle(r.path)) {
|
if (!aIgnoreReport(r.path)) {
|
||||||
aHandleReport(r.process, r.path, r.kind, r.units, r.amount,
|
aHandleReport(r.process, r.path, r.kind, r.units, r.amount,
|
||||||
r.description, r._presence);
|
r.description, r._presence);
|
||||||
}
|
}
|
||||||
@@ -591,10 +574,7 @@ function updateAboutMemoryFromReporters()
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// Process the reports from the memory reporters.
|
// Process the reports from the memory reporters.
|
||||||
let process = function(aIgnoreSingle, aIgnoreMulti, aHandleReport) {
|
appendAboutMemoryMain(processMemoryReporters, gMgr.hasMozMallocUsableSize,
|
||||||
processMemoryReporters(aIgnoreSingle, aIgnoreMulti, aHandleReport);
|
|
||||||
}
|
|
||||||
appendAboutMemoryMain(process, gMgr.hasMozMallocUsableSize,
|
|
||||||
/* forceShowSmaps = */ false);
|
/* forceShowSmaps = */ false);
|
||||||
|
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
@@ -621,8 +601,8 @@ function updateAboutMemoryFromJSONObject(aObj)
|
|||||||
"missing 'hasMozMallocUsableSize' property");
|
"missing 'hasMozMallocUsableSize' property");
|
||||||
assertInput(aObj.reports && aObj.reports instanceof Array,
|
assertInput(aObj.reports && aObj.reports instanceof Array,
|
||||||
"missing or non-array 'reports' property");
|
"missing or non-array 'reports' property");
|
||||||
let process = function(aIgnoreSingle, aIgnoreMulti, aHandleReport) {
|
let process = function(aIgnoreReporter, aIgnoreReport, aHandleReport) {
|
||||||
processMemoryReportsFromFile(aObj.reports, aIgnoreSingle, aHandleReport);
|
processMemoryReportsFromFile(aObj.reports, aIgnoreReport, aHandleReport);
|
||||||
}
|
}
|
||||||
appendAboutMemoryMain(process, aObj.hasMozMallocUsableSize,
|
appendAboutMemoryMain(process, aObj.hasMozMallocUsableSize,
|
||||||
/* forceShowSmaps = */ true);
|
/* forceShowSmaps = */ true);
|
||||||
@@ -973,7 +953,7 @@ function PColl()
|
|||||||
* Processes reports (whether from reporters or from a file) and append the
|
* Processes reports (whether from reporters or from a file) and append the
|
||||||
* main part of the page.
|
* main part of the page.
|
||||||
*
|
*
|
||||||
* @param aProcess
|
* @param aProcessReports
|
||||||
* Function that extracts the memory reports from the reporters or from
|
* Function that extracts the memory reports from the reporters or from
|
||||||
* file.
|
* file.
|
||||||
* @param aHasMozMallocUsableSize
|
* @param aHasMozMallocUsableSize
|
||||||
@@ -982,10 +962,10 @@ function PColl()
|
|||||||
* True if we should show the smaps memory reporters even if we're not
|
* True if we should show the smaps memory reporters even if we're not
|
||||||
* in verbose mode.
|
* in verbose mode.
|
||||||
*/
|
*/
|
||||||
function appendAboutMemoryMain(aProcess, aHasMozMallocUsableSize,
|
function appendAboutMemoryMain(aProcessReports, aHasMozMallocUsableSize,
|
||||||
aForceShowSmaps)
|
aForceShowSmaps)
|
||||||
{
|
{
|
||||||
let pcollsByProcess = getPCollsByProcess(aProcess, aForceShowSmaps);
|
let pcollsByProcess = getPCollsByProcess(aProcessReports, aForceShowSmaps);
|
||||||
|
|
||||||
// Sort the processes.
|
// Sort the processes.
|
||||||
let processes = Object.keys(pcollsByProcess);
|
let processes = Object.keys(pcollsByProcess);
|
||||||
@@ -1043,7 +1023,7 @@ function appendAboutMemoryMain(aProcess, aHasMozMallocUsableSize,
|
|||||||
* This function reads all the memory reports, and puts that data in structures
|
* This function reads all the memory reports, and puts that data in structures
|
||||||
* that will be used to generate the page.
|
* that will be used to generate the page.
|
||||||
*
|
*
|
||||||
* @param aProcessMemoryReports
|
* @param aProcessReports
|
||||||
* Function that extracts the memory reports from the reporters or from
|
* Function that extracts the memory reports from the reporters or from
|
||||||
* file.
|
* file.
|
||||||
* @param aForceShowSmaps
|
* @param aForceShowSmaps
|
||||||
@@ -1051,7 +1031,7 @@ function appendAboutMemoryMain(aProcess, aHasMozMallocUsableSize,
|
|||||||
* in verbose mode.
|
* in verbose mode.
|
||||||
* @return The table of PColls by process.
|
* @return The table of PColls by process.
|
||||||
*/
|
*/
|
||||||
function getPCollsByProcess(aProcessMemoryReports, aForceShowSmaps)
|
function getPCollsByProcess(aProcessReports, aForceShowSmaps)
|
||||||
{
|
{
|
||||||
let pcollsByProcess = {};
|
let pcollsByProcess = {};
|
||||||
|
|
||||||
@@ -1060,23 +1040,28 @@ function getPCollsByProcess(aProcessMemoryReports, aForceShowSmaps)
|
|||||||
// be in parentheses, so a ')' might appear after the '.'.)
|
// be in parentheses, so a ')' might appear after the '.'.)
|
||||||
const gSentenceRegExp = /^[A-Z].*\.\)?$/m;
|
const gSentenceRegExp = /^[A-Z].*\.\)?$/m;
|
||||||
|
|
||||||
// Ignore the "smaps" multi-reporter in non-verbose mode unless we're reading
|
// Ignore the "smaps" reporter in non-verbose mode unless we're reading from
|
||||||
// from a file or the clipboard, and ignore the "compartments" and
|
// a file or the clipboard, and ignore the "compartments" and "ghost-windows"
|
||||||
// "ghost-windows" multi-reporters all the time. (Note that reports from
|
// reporters all the time. (Note that reports from these reporters can reach
|
||||||
// these multi-reporters can reach here as single reports if they were in the
|
// here via a "content-child" reporter if they were in a child process.)
|
||||||
// child process.)
|
|
||||||
//
|
//
|
||||||
// Also ignore the resident-fast reporter; we use the vanilla resident
|
// Also ignore the "resident-fast" reporter; we use the vanilla "resident"
|
||||||
// reporter because it's more important that we get accurate results than
|
// reporter because it's more important that we get accurate results than
|
||||||
// that we avoid the (small) possibility of a long pause when loading
|
// that we avoid the (small) possibility of a long pause when loading
|
||||||
// about:memory.
|
// about:memory. Furthermore, the "resident" reporter can purge pages on
|
||||||
//
|
// MacOS, which affects the results of the "resident-fast" reporter, and we
|
||||||
// We don't show both resident and resident-fast because running the resident
|
// don't want the measurements shown in about:memory to be affected by the
|
||||||
// reporter can purge pages on MacOS, which affects the results of the
|
// (arbitrary) order of memory reporter execution.
|
||||||
// resident-fast reporter. We don't want about:memory's results to be
|
|
||||||
// affected by the order of memory reporter execution.
|
|
||||||
|
|
||||||
function ignoreSingle(aUnsafePath)
|
function ignoreReporter(aName)
|
||||||
|
{
|
||||||
|
return (aName === "smaps" && !gVerbose.checked && !aForceShowSmaps) ||
|
||||||
|
aName === "compartments" ||
|
||||||
|
aName === "ghost-windows" ||
|
||||||
|
aName === "resident-fast";
|
||||||
|
}
|
||||||
|
|
||||||
|
function ignoreReport(aUnsafePath)
|
||||||
{
|
{
|
||||||
return (isSmapsPath(aUnsafePath) && !gVerbose.checked && !aForceShowSmaps) ||
|
return (isSmapsPath(aUnsafePath) && !gVerbose.checked && !aForceShowSmaps) ||
|
||||||
aUnsafePath.startsWith("compartments/") ||
|
aUnsafePath.startsWith("compartments/") ||
|
||||||
@@ -1084,13 +1069,6 @@ function getPCollsByProcess(aProcessMemoryReports, aForceShowSmaps)
|
|||||||
aUnsafePath == "resident-fast";
|
aUnsafePath == "resident-fast";
|
||||||
}
|
}
|
||||||
|
|
||||||
function ignoreMulti(aMRName)
|
|
||||||
{
|
|
||||||
return (aMRName === "smaps" && !gVerbose.checked && !aForceShowSmaps) ||
|
|
||||||
aMRName === "compartments" ||
|
|
||||||
aMRName === "ghost-windows";
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleReport(aProcess, aUnsafePath, aKind, aUnits, aAmount,
|
function handleReport(aProcess, aUnsafePath, aKind, aUnits, aAmount,
|
||||||
aDescription, aPresence)
|
aDescription, aPresence)
|
||||||
{
|
{
|
||||||
@@ -1171,7 +1149,7 @@ function getPCollsByProcess(aProcessMemoryReports, aForceShowSmaps)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
aProcessMemoryReports(ignoreSingle, ignoreMulti, handleReport);
|
aProcessReports(ignoreReporter, ignoreReport, handleReport);
|
||||||
|
|
||||||
return pcollsByProcess;
|
return pcollsByProcess;
|
||||||
}
|
}
|
||||||
@@ -2107,18 +2085,18 @@ Compartment.prototype = {
|
|||||||
|
|
||||||
function getCompartmentsByProcess()
|
function getCompartmentsByProcess()
|
||||||
{
|
{
|
||||||
// Ignore anything that didn't come from the "compartments" multi-reporter.
|
// Ignore anything that didn't come from the "compartments" reporter. (Note
|
||||||
// (Note that some such reports can reach here as single reports if they were
|
// reports from this reporter can reach here via a "content-child" reporter
|
||||||
// in the child process.)
|
// if they were in a child process.)
|
||||||
|
|
||||||
function ignoreSingle(aUnsafePath)
|
function ignoreReporter(aName)
|
||||||
{
|
{
|
||||||
return !aUnsafePath.startsWith("compartments/");
|
return !(aName == "compartments" || aName == "content-child");
|
||||||
}
|
}
|
||||||
|
|
||||||
function ignoreMulti(aMRName)
|
function ignoreReport(aUnsafePath)
|
||||||
{
|
{
|
||||||
return aMRName !== "compartments";
|
return !aUnsafePath.startsWith("compartments/");
|
||||||
}
|
}
|
||||||
|
|
||||||
let compartmentsByProcess = {};
|
let compartmentsByProcess = {};
|
||||||
@@ -2169,7 +2147,7 @@ function getCompartmentsByProcess()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
processMemoryReporters(ignoreSingle, ignoreMulti, handleReport);
|
processMemoryReporters(ignoreReporter, ignoreReport, handleReport);
|
||||||
|
|
||||||
return compartmentsByProcess;
|
return compartmentsByProcess;
|
||||||
}
|
}
|
||||||
@@ -2191,14 +2169,14 @@ GhostWindow.prototype = {
|
|||||||
|
|
||||||
function getGhostWindowsByProcess()
|
function getGhostWindowsByProcess()
|
||||||
{
|
{
|
||||||
function ignoreSingle(aUnsafePath)
|
function ignoreReporter(aName)
|
||||||
{
|
{
|
||||||
return !aUnsafePath.startsWith('ghost-windows/')
|
return !(aName == "ghost-windows" || aName == "content-child");
|
||||||
}
|
}
|
||||||
|
|
||||||
function ignoreMulti(aName)
|
function ignoreReport(aUnsafePath)
|
||||||
{
|
{
|
||||||
return aName !== "ghost-windows";
|
return !aUnsafePath.startsWith('ghost-windows/')
|
||||||
}
|
}
|
||||||
|
|
||||||
let ghostWindowsByProcess = {};
|
let ghostWindowsByProcess = {};
|
||||||
@@ -2230,7 +2208,7 @@ function getGhostWindowsByProcess()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
processMemoryReporters(ignoreSingle, ignoreMulti, handleReport);
|
processMemoryReporters(ignoreReporter, ignoreReport, handleReport);
|
||||||
|
|
||||||
return ghostWindowsByProcess;
|
return ghostWindowsByProcess;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,7 @@
|
|||||||
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
|
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
|
||||||
getService(Ci.nsIMemoryReporterManager);
|
getService(Ci.nsIMemoryReporterManager);
|
||||||
|
|
||||||
// Remove all the real reporters and multi-reporters; save them to
|
// Remove all the real reporters; save them to restore at the end.
|
||||||
// restore at the end.
|
|
||||||
mgr.blockRegistration();
|
mgr.blockRegistration();
|
||||||
var e = mgr.enumerateReporters();
|
var e = mgr.enumerateReporters();
|
||||||
var realReporters = [];
|
var realReporters = [];
|
||||||
@@ -34,13 +33,6 @@
|
|||||||
mgr.unregisterReporter(r);
|
mgr.unregisterReporter(r);
|
||||||
realReporters.push(r);
|
realReporters.push(r);
|
||||||
}
|
}
|
||||||
e = mgr.enumerateMultiReporters();
|
|
||||||
var realMultiReporters = [];
|
|
||||||
while (e.hasMoreElements()) {
|
|
||||||
var r = e.getNext().QueryInterface(Ci.nsIMemoryMultiReporter);
|
|
||||||
mgr.unregisterMultiReporter(r);
|
|
||||||
realMultiReporters.push(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup various fake-but-deterministic reporters.
|
// Setup various fake-but-deterministic reporters.
|
||||||
const KB = 1024;
|
const KB = 1024;
|
||||||
@@ -52,41 +44,39 @@
|
|||||||
const BYTES = Ci.nsIMemoryReporter.UNITS_BYTES;
|
const BYTES = Ci.nsIMemoryReporter.UNITS_BYTES;
|
||||||
const COUNT = Ci.nsIMemoryReporter.UNITS_COUNT;
|
const COUNT = Ci.nsIMemoryReporter.UNITS_COUNT;
|
||||||
|
|
||||||
function f(aProcess, aPath, aKind, aUnits, aAmount) {
|
|
||||||
return {
|
|
||||||
process: aProcess,
|
|
||||||
path: aPath,
|
|
||||||
kind: aKind,
|
|
||||||
units: aUnits,
|
|
||||||
description: "",
|
|
||||||
amount: aAmount
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var fakeReporters = [
|
var fakeReporters = [
|
||||||
// These should be ignored.
|
{ name: "fake1",
|
||||||
f("", "explicit/a", HEAP, BYTES, 222 * MB),
|
collectReports: function(aCbObj, aClosure) {
|
||||||
f("", "explicit/b/a", HEAP, BYTES, 85 * MB),
|
function f(aP1, aP2, aK, aU, aA) {
|
||||||
f("", "explicit/b/b", NONHEAP, BYTES, 85 * MB),
|
aCbObj.callback(aP1, aP2, aK, aU, aA, "Desc.", aClosure);
|
||||||
f("", "other1", OTHER, BYTES, 111 * MB),
|
}
|
||||||
f("", "other2", OTHER, COUNT, 888),
|
// These should be ignored.
|
||||||
|
f("", "explicit/a", HEAP, BYTES, 222 * MB);
|
||||||
f("2nd", "explicit/c", HEAP, BYTES, 333 * MB),
|
f("", "explicit/b/a", HEAP, BYTES, 85 * MB);
|
||||||
f("2nd", "compartments/user/child-user-compartment", OTHER, COUNT, 1),
|
f("", "explicit/b/b", NONHEAP, BYTES, 85 * MB);
|
||||||
f("2nd", "compartments/system/child-system-compartment", OTHER, COUNT, 1)
|
f("", "other1", OTHER, BYTES, 111 * MB);
|
||||||
];
|
f("", "other2", OTHER, COUNT, 888);
|
||||||
|
}
|
||||||
var fakeMultiReporters = [
|
},
|
||||||
// These shouldn't show up.
|
{ name: "fake2",
|
||||||
{ name: "fake",
|
|
||||||
collectReports: function(aCbObj, aClosure) {
|
collectReports: function(aCbObj, aClosure) {
|
||||||
function f(aP, aK, aU, aA) {
|
function f(aP, aK, aU, aA) {
|
||||||
aCbObj.callback("", aP, aK, aU, aA, "Desc.", aClosure);
|
aCbObj.callback("", aP, aK, aU, aA, "Desc.", aClosure);
|
||||||
}
|
}
|
||||||
|
// These shouldn't show up.
|
||||||
f("explicit/a/d", HEAP, BYTES, 13 * MB);
|
f("explicit/a/d", HEAP, BYTES, 13 * MB);
|
||||||
f("explicit/b/c", NONHEAP, BYTES, 10 * MB);
|
f("explicit/b/c", NONHEAP, BYTES, 10 * MB);
|
||||||
},
|
}
|
||||||
explicitNonHeap: 10*MB
|
},
|
||||||
|
{ name: "content-child",
|
||||||
|
collectReports: function(aCbObj, aClosure) {
|
||||||
|
function f(aP1, aP2, aK, aU, aA, aD) {
|
||||||
|
aCbObj.callback(aP1, aP2, aK, aU, aA, aD, aClosure);
|
||||||
|
}
|
||||||
|
f("2nd", "explicit/c", HEAP, BYTES, 333 * MB, "Desc.");
|
||||||
|
f("2nd", "compartments/user/child-user-compartment", OTHER, COUNT, 1, "");
|
||||||
|
f("2nd", "compartments/system/child-system-compartment", OTHER, COUNT, 1, "");
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{ name: "compartments",
|
{ name: "compartments",
|
||||||
collectReports: function(aCbObj, aClosure) {
|
collectReports: function(aCbObj, aClosure) {
|
||||||
@@ -104,8 +94,7 @@
|
|||||||
f("compartments/system/[System Principal]");
|
f("compartments/system/[System Principal]");
|
||||||
f("compartments/system/[System Principal]");
|
f("compartments/system/[System Principal]");
|
||||||
f("compartments/system/atoms");
|
f("compartments/system/atoms");
|
||||||
},
|
}
|
||||||
explicitNonHeap: 0
|
|
||||||
},
|
},
|
||||||
{ name: "ghost-windows",
|
{ name: "ghost-windows",
|
||||||
collectReports: function(aCbObj, aClosure) {
|
collectReports: function(aCbObj, aClosure) {
|
||||||
@@ -114,8 +103,7 @@
|
|||||||
}
|
}
|
||||||
f("ghost-windows/https:\\\\very-long-url.com\\very-long\\oh-so-long\\really-quite-long.html?a=2&b=3&c=4&d=5&e=abcdefghijklmnopqrstuvwxyz&f=123456789123456789123456789");
|
f("ghost-windows/https:\\\\very-long-url.com\\very-long\\oh-so-long\\really-quite-long.html?a=2&b=3&c=4&d=5&e=abcdefghijklmnopqrstuvwxyz&f=123456789123456789123456789");
|
||||||
f("ghost-windows/http:\\\\foobar.com\\foo?bar#baz");
|
f("ghost-windows/http:\\\\foobar.com\\foo?bar#baz");
|
||||||
},
|
}
|
||||||
explicitNonHeap: 0
|
|
||||||
},
|
},
|
||||||
// These shouldn't show up.
|
// These shouldn't show up.
|
||||||
{ name: "smaps",
|
{ name: "smaps",
|
||||||
@@ -126,17 +114,13 @@
|
|||||||
}
|
}
|
||||||
f("smaps/vsize/a", 24);
|
f("smaps/vsize/a", 24);
|
||||||
f("smaps/swap/a", 1);
|
f("smaps/swap/a", 1);
|
||||||
},
|
}
|
||||||
explicitNonHeap: 0
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
for (var i = 0; i < fakeReporters.length; i++) {
|
for (var i = 0; i < fakeReporters.length; i++) {
|
||||||
mgr.registerReporterEvenIfBlocked(fakeReporters[i]);
|
mgr.registerReporterEvenIfBlocked(fakeReporters[i]);
|
||||||
}
|
}
|
||||||
for (var i = 0; i < fakeMultiReporters.length; i++) {
|
|
||||||
mgr.registerMultiReporterEvenIfBlocked(fakeMultiReporters[i]);
|
|
||||||
}
|
|
||||||
]]>
|
]]>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -180,21 +164,14 @@ Ghost Windows\n\
|
|||||||
|
|
||||||
function finish()
|
function finish()
|
||||||
{
|
{
|
||||||
// Unregister fake reporters and multi-reporters, re-register the real
|
// Unregister fake reporters and re-register the real reporters, just in
|
||||||
// reporters and multi-reporters, just in case subsequent tests rely on
|
// case subsequent tests rely on them.
|
||||||
// them.
|
|
||||||
for (var i = 0; i < fakeReporters.length; i++) {
|
for (var i = 0; i < fakeReporters.length; i++) {
|
||||||
mgr.unregisterReporter(fakeReporters[i]);
|
mgr.unregisterReporter(fakeReporters[i]);
|
||||||
}
|
}
|
||||||
for (var i = 0; i < fakeMultiReporters.length; i++) {
|
|
||||||
mgr.unregisterMultiReporter(fakeMultiReporters[i]);
|
|
||||||
}
|
|
||||||
for (var i = 0; i < realReporters.length; i++) {
|
for (var i = 0; i < realReporters.length; i++) {
|
||||||
mgr.registerReporterEvenIfBlocked(realReporters[i]);
|
mgr.registerReporterEvenIfBlocked(realReporters[i]);
|
||||||
}
|
}
|
||||||
for (var i = 0; i < realMultiReporters.length; i++) {
|
|
||||||
mgr.registerMultiReporterEvenIfBlocked(realMultiReporters[i]);
|
|
||||||
}
|
|
||||||
mgr.unblockRegistration();
|
mgr.unblockRegistration();
|
||||||
|
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
|
|||||||
@@ -27,8 +27,7 @@
|
|||||||
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
|
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
|
||||||
getService(Ci.nsIMemoryReporterManager);
|
getService(Ci.nsIMemoryReporterManager);
|
||||||
|
|
||||||
// Remove all the real reporters and multi-reporters; save them to
|
// Remove all the real reporters; save them to restore at the end.
|
||||||
// restore at the end.
|
|
||||||
mgr.blockRegistration();
|
mgr.blockRegistration();
|
||||||
let e = mgr.enumerateReporters();
|
let e = mgr.enumerateReporters();
|
||||||
let realReporters = [];
|
let realReporters = [];
|
||||||
@@ -37,13 +36,6 @@
|
|||||||
mgr.unregisterReporter(r);
|
mgr.unregisterReporter(r);
|
||||||
realReporters.push(r);
|
realReporters.push(r);
|
||||||
}
|
}
|
||||||
e = mgr.enumerateMultiReporters();
|
|
||||||
let realMultiReporters = [];
|
|
||||||
while (e.hasMoreElements()) {
|
|
||||||
let r = e.getNext().QueryInterface(Ci.nsIMemoryMultiReporter);
|
|
||||||
mgr.unregisterMultiReporter(r);
|
|
||||||
realMultiReporters.push(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup various fake-but-deterministic reporters.
|
// Setup various fake-but-deterministic reporters.
|
||||||
const KB = 1024;
|
const KB = 1024;
|
||||||
@@ -57,71 +49,60 @@
|
|||||||
const COUNT_CUMULATIVE = Ci.nsIMemoryReporter.UNITS_COUNT_CUMULATIVE;
|
const COUNT_CUMULATIVE = Ci.nsIMemoryReporter.UNITS_COUNT_CUMULATIVE;
|
||||||
const PERCENTAGE = Ci.nsIMemoryReporter.UNITS_PERCENTAGE;
|
const PERCENTAGE = Ci.nsIMemoryReporter.UNITS_PERCENTAGE;
|
||||||
|
|
||||||
function f2(aProcess, aPath, aKind, aUnits, aAmount) {
|
|
||||||
return {
|
|
||||||
process: aProcess,
|
|
||||||
path: aPath,
|
|
||||||
kind: aKind,
|
|
||||||
units: aUnits,
|
|
||||||
description: "Desc.",
|
|
||||||
amount: aAmount
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function f(aProcess, aPath, aKind, aAmount) {
|
|
||||||
return f2(aProcess, aPath, aKind, BYTES, aAmount);
|
|
||||||
}
|
|
||||||
|
|
||||||
let fakeReporters = [
|
let fakeReporters = [
|
||||||
f("", "heap-allocated", OTHER, 500 * MB),
|
{ name: "fake0",
|
||||||
f("", "heap-unallocated", OTHER, 100 * MB),
|
collectReports: function(aCbObj, aClosure) {
|
||||||
f("", "explicit/a", HEAP, 222 * MB),
|
function f(aP, aK, aU, aA) {
|
||||||
f("", "explicit/b/a", HEAP, 85 * MB),
|
aCbObj.callback("", aP, aK, aU, aA, "Desc.", aClosure);
|
||||||
f("", "explicit/b/b", HEAP, 75 * MB),
|
}
|
||||||
f("", "explicit/b/c/a", HEAP, 70 * MB),
|
f("heap-allocated", OTHER, BYTES, 500 * MB);
|
||||||
f("", "explicit/b/c/b", HEAP, 2 * MB), // omitted
|
f("heap-unallocated", OTHER, BYTES, 100 * MB);
|
||||||
f("", "explicit/g/a", HEAP, 6 * MB),
|
f("explicit/a", HEAP, BYTES, 222 * MB);
|
||||||
f("", "explicit/g/b", HEAP, 5 * MB),
|
f("explicit/b/a", HEAP, BYTES, 85 * MB);
|
||||||
f("", "explicit/g/other", HEAP, 4 * MB),
|
f("explicit/b/b", HEAP, BYTES, 75 * MB);
|
||||||
// A degenerate tree with the same name as a non-degenerate tree should
|
f("explicit/b/c/a", HEAP, BYTES, 70 * MB);
|
||||||
// work ok.
|
f("explicit/b/c/b", HEAP, BYTES, 2 * MB); // omitted
|
||||||
f("", "explicit", OTHER, 888 * MB),
|
f("explicit/g/a", HEAP, BYTES, 6 * MB);
|
||||||
f("", "other1/a/b", OTHER, 111 * MB),
|
f("explicit/g/b", HEAP, BYTES, 5 * MB);
|
||||||
f("", "other1/c/d", OTHER, 22 * MB),
|
f("explicit/g/other", HEAP, BYTES, 4 * MB);
|
||||||
f("", "other1/c/e", OTHER, 33 * MB),
|
// A degenerate tree with the same name as a non-degenerate tree should
|
||||||
f2("", "other4", OTHER, COUNT_CUMULATIVE, 777),
|
// work ok.
|
||||||
f2("", "other4", OTHER, COUNT_CUMULATIVE, 111),
|
f("explicit", OTHER, BYTES, 888 * MB);
|
||||||
f2("", "other3/a/b/c/d/e", OTHER, PERCENTAGE, 2000),
|
f("other1/a/b", OTHER, BYTES, 111 * MB);
|
||||||
f2("", "other3/a/b/c/d/f", OTHER, PERCENTAGE, 10),
|
f("other1/c/d", OTHER, BYTES, 22 * MB);
|
||||||
f2("", "other3/a/b/c/d/g", OTHER, PERCENTAGE, 5),
|
f("other1/c/e", OTHER, BYTES, 33 * MB);
|
||||||
f2("", "other3/a/b/c/d/g", OTHER, PERCENTAGE, 5),
|
f("other4", OTHER, COUNT_CUMULATIVE, 777);
|
||||||
// Check that a rounded-up-to-100.00% value is shown as "100.0%" (i.e. one
|
f("other4", OTHER, COUNT_CUMULATIVE, 111);
|
||||||
// decimal point).
|
f("other3/a/b/c/d/e", OTHER, PERCENTAGE, 2000);
|
||||||
f2("", "other6/big", OTHER, COUNT, 99999),
|
f("other3/a/b/c/d/f", OTHER, PERCENTAGE, 10);
|
||||||
f2("", "other6/small", OTHER, COUNT, 1),
|
f("other3/a/b/c/d/g", OTHER, PERCENTAGE, 5);
|
||||||
// Check that a 0 / 0 is handled correctly.
|
f("other3/a/b/c/d/g", OTHER, PERCENTAGE, 5);
|
||||||
f("", "other7/zero", OTHER, 0),
|
// Check that a rounded-up-to-100.00% value is shown as "100.0%" (i.e. one
|
||||||
// These compartments ones shouldn't be displayed.
|
// decimal point).
|
||||||
f2("", "compartments/user/foo", OTHER, COUNT, 1),
|
f("other6/big", OTHER, COUNT, 99999);
|
||||||
f2("", "compartments/system/foo", OTHER, COUNT, 1)
|
f("other6/small", OTHER, COUNT, 1);
|
||||||
];
|
// Check that a 0 / 0 is handled correctly.
|
||||||
let fakeMultiReporters = [
|
f("other7/zero", OTHER, BYTES, 0);
|
||||||
|
// These compartments ones shouldn't be displayed.
|
||||||
|
f("compartments/user/foo", OTHER, COUNT, 1);
|
||||||
|
f("compartments/system/foo", OTHER, COUNT, 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
{ name: "fake1",
|
{ name: "fake1",
|
||||||
collectReports: function(aCbObj, aClosure) {
|
collectReports: function(aCbObj, aClosure) {
|
||||||
function f(aP, aK, aU, aA) {
|
function f(aP, aK, aU, aA) {
|
||||||
aCbObj.callback("", aP, aK, aU, aA, "Desc.", aClosure);
|
aCbObj.callback("", aP, aK, aU, aA, "Desc.", aClosure);
|
||||||
}
|
}
|
||||||
f("explicit/c/d", NONHEAP, BYTES, 13 * MB),
|
f("explicit/c/d", NONHEAP, BYTES, 13 * MB);
|
||||||
f("explicit/c/d", NONHEAP, BYTES, 10 * MB), // dup
|
f("explicit/c/d", NONHEAP, BYTES, 10 * MB); // dup
|
||||||
f("explicit/c/other", NONHEAP, BYTES, 77 * MB),
|
f("explicit/c/other", NONHEAP, BYTES, 77 * MB);
|
||||||
f("explicit/cc", NONHEAP, BYTES, 13 * MB);
|
f("explicit/cc", NONHEAP, BYTES, 13 * MB);
|
||||||
f("explicit/cc", NONHEAP, BYTES, 10 * MB); // dup
|
f("explicit/cc", NONHEAP, BYTES, 10 * MB); // dup
|
||||||
f("explicit/d", NONHEAP, BYTES, 499 * KB); // omitted
|
f("explicit/d", NONHEAP, BYTES, 499 * KB); // omitted
|
||||||
f("explicit/e", NONHEAP, BYTES, 100 * KB); // omitted
|
f("explicit/e", NONHEAP, BYTES, 100 * KB); // omitted
|
||||||
f("explicit/f/g/h/i", HEAP, BYTES, 10 * MB);
|
f("explicit/f/g/h/i", HEAP, BYTES, 10 * MB);
|
||||||
f("explicit/f/g/h/j", HEAP, BYTES, 10 * MB);
|
f("explicit/f/g/h/j", HEAP, BYTES, 10 * MB);
|
||||||
},
|
}
|
||||||
explicitNonHeap: (100 + 13 + 10)*MB + (499 + 100)*KB
|
|
||||||
},
|
},
|
||||||
{ name: "fake2",
|
{ name: "fake2",
|
||||||
collectReports: function(aCbObj, aClosure) {
|
collectReports: function(aCbObj, aClosure) {
|
||||||
@@ -132,8 +113,7 @@
|
|||||||
f("other2", OTHER, BYTES, 222 * MB);
|
f("other2", OTHER, BYTES, 222 * MB);
|
||||||
f("perc2", OTHER, PERCENTAGE, 10000);
|
f("perc2", OTHER, PERCENTAGE, 10000);
|
||||||
f("perc1", OTHER, PERCENTAGE, 4567);
|
f("perc1", OTHER, PERCENTAGE, 4567);
|
||||||
},
|
}
|
||||||
explicitNonHeap: 0
|
|
||||||
},
|
},
|
||||||
{ name: "smaps",
|
{ name: "smaps",
|
||||||
collectReports: function(aCbObj, aClosure) {
|
collectReports: function(aCbObj, aClosure) {
|
||||||
@@ -148,8 +128,7 @@
|
|||||||
f("swap/b/c", 10);
|
f("swap/b/c", 10);
|
||||||
f("rss/a", 42);
|
f("rss/a", 42);
|
||||||
f("pss/a", 43);
|
f("pss/a", 43);
|
||||||
},
|
}
|
||||||
explicitNonHeap: 0
|
|
||||||
},
|
},
|
||||||
{ name: "compartments",
|
{ name: "compartments",
|
||||||
collectReports: function(aCbObj, aClosure) {
|
collectReports: function(aCbObj, aClosure) {
|
||||||
@@ -158,16 +137,12 @@
|
|||||||
}
|
}
|
||||||
f("compartments/user/bar");
|
f("compartments/user/bar");
|
||||||
f("compartments/system/bar");
|
f("compartments/system/bar");
|
||||||
},
|
}
|
||||||
explicitNonHeap: 0
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
for (let i = 0; i < fakeReporters.length; i++) {
|
for (let i = 0; i < fakeReporters.length; i++) {
|
||||||
mgr.registerReporterEvenIfBlocked(fakeReporters[i]);
|
mgr.registerReporterEvenIfBlocked(fakeReporters[i]);
|
||||||
}
|
}
|
||||||
for (let i = 0; i < fakeMultiReporters.length; i++) {
|
|
||||||
mgr.registerMultiReporterEvenIfBlocked(fakeMultiReporters[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// mgr.explicit sums "heap-allocated" and all the appropriate NONHEAP ones:
|
// mgr.explicit sums "heap-allocated" and all the appropriate NONHEAP ones:
|
||||||
// - "explicit/c", "explicit/cc" x 2, "explicit/d", "explicit/e"
|
// - "explicit/c", "explicit/cc" x 2, "explicit/d", "explicit/e"
|
||||||
@@ -189,59 +164,74 @@
|
|||||||
// the largest). Processes without a |resident| memory reporter are saved
|
// the largest). Processes without a |resident| memory reporter are saved
|
||||||
// for the end.
|
// for the end.
|
||||||
let fakeReporters2 = [
|
let fakeReporters2 = [
|
||||||
f("2nd", "heap-allocated", OTHER, 1000 * MB),
|
{ name: "resident-fast",
|
||||||
f("2nd", "heap-unallocated",OTHER, 100 * MB),
|
collectReports: function(aCbObj, aClosure) {
|
||||||
f("2nd", "explicit/a/b/c", HEAP, 497 * MB),
|
// Shouldn't reach here; aboutMemory.js should skip the reporter.
|
||||||
f("2nd", "explicit/a/b/c", HEAP, 1 * MB), // dup: merge
|
// (Nb: this must come after |mgr.explicit| is accessed, otherwise it
|
||||||
f("2nd", "explicit/a/b/c", HEAP, 1 * MB), // dup: merge
|
// *will* be run by nsMemoryReporterManager::GetExplicit()).
|
||||||
f("2nd", "explicit/flip\\the\\backslashes",
|
ok(false, "'resident-fast' reporter was run");
|
||||||
HEAP, 200 * MB),
|
}
|
||||||
f("2nd", "explicit/compartment(compartment-url)",
|
},
|
||||||
HEAP, 200 * MB),
|
{ name: "fake3",
|
||||||
f("2nd", "other0", OTHER, 666 * MB),
|
collectReports: function(aCbObj, aClosure) {
|
||||||
f("2nd", "other1", OTHER, 111 * MB),
|
function f(aP1, aP2, aK, aU, aA) {
|
||||||
// Even though the "smaps" reporter is a multi-reporter, if its in a
|
aCbObj.callback(aP1, aP2, aK, aU, aA, "Desc.", aClosure);
|
||||||
// child process it'll be passed to the main process as single reports.
|
}
|
||||||
// The fact that we skip the "smaps" multi-reporter in the main
|
f("2nd", "heap-allocated", OTHER, BYTES,1000* MB);
|
||||||
// process won't cause these to be skipped; the fall-back skipping will
|
f("2nd", "heap-unallocated",OTHER, BYTES,100 * MB);
|
||||||
// be hit instead.
|
f("2nd", "explicit/a/b/c", HEAP, BYTES,497 * MB);
|
||||||
f("2nd", "size/e", NONHEAP, 24*4*KB),
|
f("2nd", "explicit/a/b/c", HEAP, BYTES, 1 * MB); // dup: merge
|
||||||
f("2nd", "size/f", NONHEAP, 24*4*KB),
|
f("2nd", "explicit/a/b/c", HEAP, BYTES, 1 * MB); // dup: merge
|
||||||
|
f("2nd", "explicit/flip\\the\\backslashes",
|
||||||
|
HEAP, BYTES,200 * MB);
|
||||||
|
f("2nd", "explicit/compartment(compartment-url)",
|
||||||
|
HEAP, BYTES,200 * MB);
|
||||||
|
f("2nd", "other0", OTHER, BYTES,666 * MB);
|
||||||
|
f("2nd", "other1", OTHER, BYTES,111 * MB);
|
||||||
|
// If the "smaps" reporter is in a child process it'll be passed to
|
||||||
|
// the main process under a different name. The fact that we skip
|
||||||
|
// the "smaps" reporter in the main process won't cause these
|
||||||
|
// to be skipped; the report-level skipping will be hit instead.
|
||||||
|
f("2nd", "size/e", NONHEAP, BYTES,24*4*KB);
|
||||||
|
f("2nd", "size/f", NONHEAP, BYTES,24*4*KB);
|
||||||
|
f("2nd", "resident-fast", NONHEAP, BYTES,24*4*KB); // ignored!
|
||||||
|
|
||||||
// Check that we can handle "heap-allocated" not being present.
|
// Check that we can handle "heap-allocated" not being present.
|
||||||
f("3rd", "explicit/a/b", HEAP, 333 * MB),
|
f("3rd", "explicit/a/b", HEAP, BYTES,333 * MB);
|
||||||
f("3rd", "explicit/a/c", HEAP, 444 * MB),
|
f("3rd", "explicit/a/c", HEAP, BYTES,444 * MB);
|
||||||
f("3rd", "other1", OTHER, 1 * MB),
|
f("3rd", "other1", OTHER, BYTES, 1 * MB);
|
||||||
f("3rd", "resident", OTHER, 100 * MB),
|
f("3rd", "resident", OTHER, BYTES,100 * MB);
|
||||||
|
|
||||||
// Invalid values (negative, too-big) should be identified.
|
// Invalid values (negative, too-big) should be identified.
|
||||||
f("4th", "heap-allocated", OTHER, 100 * MB),
|
f("4th", "heap-allocated", OTHER, BYTES,100 * MB);
|
||||||
f("4th", "resident", OTHER, 200 * MB),
|
f("4th", "resident", OTHER, BYTES,200 * MB);
|
||||||
f("4th", "explicit/js/compartment(http:\\\\too-big.com\\)/stuff",
|
f("4th", "explicit/js/compartment(http:\\\\too-big.com\\)/stuff",
|
||||||
HEAP, 150 * MB),
|
HEAP, BYTES,150 * MB);
|
||||||
f("4th", "explicit/ok", HEAP, 5 * MB),
|
f("4th", "explicit/ok", HEAP, BYTES, 5 * MB);
|
||||||
f("4th", "explicit/neg1", NONHEAP, -2 * MB),
|
f("4th", "explicit/neg1", NONHEAP, BYTES, -2 * MB);
|
||||||
// -111 becomes "-0.00MB" in non-verbose mode, and getting the negative
|
// -111 becomes "-0.00MB" in non-verbose mode, and getting the negative
|
||||||
// sign in there correctly is non-trivial.
|
// sign in there correctly is non-trivial.
|
||||||
f("4th", "other1", OTHER, -111),
|
f("4th", "other1", OTHER, BYTES,-111);
|
||||||
f("4th", "other2", OTHER, -222 * MB),
|
f("4th", "other2", OTHER, BYTES,-222 * MB);
|
||||||
f2("4th", "other3", OTHER, COUNT, -333),
|
f("4th", "other3", OTHER, COUNT, -333);
|
||||||
f2("4th", "other4", OTHER, COUNT_CUMULATIVE, -444),
|
f("4th", "other4", OTHER, COUNT_CUMULATIVE, -444);
|
||||||
f2("4th", "other5", OTHER, PERCENTAGE, -555),
|
f("4th", "other5", OTHER, PERCENTAGE, -555);
|
||||||
f2("4th", "other6", OTHER, PERCENTAGE, 66666),
|
f("4th", "other6", OTHER, PERCENTAGE, 66666);
|
||||||
|
|
||||||
// If a negative value is within a collapsed sub-tree in non-verbose mode,
|
// If a negative value is within a collapsed sub-tree in non-verbose mode,
|
||||||
// we should get the warning at the top and the relevant sub-trees should
|
// we should get the warning at the top and the relevant sub-trees should
|
||||||
// be expanded, even in non-verbose mode.
|
// be expanded, even in non-verbose mode.
|
||||||
f("5th", "heap-allocated", OTHER, 100 * MB),
|
f("5th", "heap-allocated", OTHER, BYTES,100 * MB);
|
||||||
f("5th", "explicit/big", HEAP, 99 * MB),
|
f("5th", "explicit/big", HEAP, BYTES, 99 * MB);
|
||||||
f("5th", "explicit/a/pos", HEAP, 40 * KB),
|
f("5th", "explicit/a/pos", HEAP, BYTES, 40 * KB);
|
||||||
f("5th", "explicit/a/neg1", NONHEAP, -20 * KB),
|
f("5th", "explicit/a/neg1", NONHEAP, BYTES,-20 * KB);
|
||||||
f("5th", "explicit/a/neg2", NONHEAP, -10 * KB),
|
f("5th", "explicit/a/neg2", NONHEAP, BYTES,-10 * KB);
|
||||||
f("5th", "explicit/b/c/d/e", NONHEAP, 20 * KB),
|
f("5th", "explicit/b/c/d/e", NONHEAP, BYTES, 20 * KB);
|
||||||
f("5th", "explicit/b/c/d/f", NONHEAP, -60 * KB),
|
f("5th", "explicit/b/c/d/f", NONHEAP, BYTES,-60 * KB);
|
||||||
f("5th", "explicit/b/c/g/h", NONHEAP, 10 * KB),
|
f("5th", "explicit/b/c/g/h", NONHEAP, BYTES, 10 * KB);
|
||||||
f("5th", "explicit/b/c/i/j", NONHEAP, 5 * KB)
|
f("5th", "explicit/b/c/i/j", NONHEAP, BYTES, 5 * KB);
|
||||||
|
}
|
||||||
|
}
|
||||||
];
|
];
|
||||||
for (let i = 0; i < fakeReporters2.length; i++) {
|
for (let i = 0; i < fakeReporters2.length; i++) {
|
||||||
mgr.registerReporterEvenIfBlocked(fakeReporters2[i]);
|
mgr.registerReporterEvenIfBlocked(fakeReporters2[i]);
|
||||||
@@ -586,21 +576,14 @@ Other Measurements\n\
|
|||||||
|
|
||||||
function finish()
|
function finish()
|
||||||
{
|
{
|
||||||
// Unregister fake reporters and multi-reporters, re-register the real
|
// Unregister fake reporters and re-register the real reporters, just in
|
||||||
// reporters and multi-reporters, just in case subsequent tests rely on
|
// case subsequent tests rely on them.
|
||||||
// them.
|
|
||||||
for (let i = 0; i < fakeReporters.length; i++) {
|
for (let i = 0; i < fakeReporters.length; i++) {
|
||||||
mgr.unregisterReporter(fakeReporters[i]);
|
mgr.unregisterReporter(fakeReporters[i]);
|
||||||
}
|
}
|
||||||
for (let i = 0; i < fakeMultiReporters.length; i++) {
|
|
||||||
mgr.unregisterMultiReporter(fakeMultiReporters[i]);
|
|
||||||
}
|
|
||||||
for (let i = 0; i < realReporters.length; i++) {
|
for (let i = 0; i < realReporters.length; i++) {
|
||||||
mgr.registerReporterEvenIfBlocked(realReporters[i]);
|
mgr.registerReporterEvenIfBlocked(realReporters[i]);
|
||||||
}
|
}
|
||||||
for (let i = 0; i < realMultiReporters.length; i++) {
|
|
||||||
mgr.registerMultiReporterEvenIfBlocked(realMultiReporters[i]);
|
|
||||||
}
|
|
||||||
mgr.unblockRegistration();
|
mgr.unblockRegistration();
|
||||||
|
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
|
|||||||
@@ -22,8 +22,7 @@
|
|||||||
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
|
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
|
||||||
getService(Ci.nsIMemoryReporterManager);
|
getService(Ci.nsIMemoryReporterManager);
|
||||||
|
|
||||||
// Remove all the real reporters and multi-reporters; save them to
|
// Remove all the real reporters; save them to restore at the end.
|
||||||
// restore at the end.
|
|
||||||
mgr.blockRegistration();
|
mgr.blockRegistration();
|
||||||
let e = mgr.enumerateReporters();
|
let e = mgr.enumerateReporters();
|
||||||
let realReporters = [];
|
let realReporters = [];
|
||||||
@@ -32,13 +31,6 @@
|
|||||||
mgr.unregisterReporter(r);
|
mgr.unregisterReporter(r);
|
||||||
realReporters.push(r);
|
realReporters.push(r);
|
||||||
}
|
}
|
||||||
e = mgr.enumerateMultiReporters();
|
|
||||||
let realMultiReporters = [];
|
|
||||||
while (e.hasMoreElements()) {
|
|
||||||
let r = e.getNext().QueryInterface(Ci.nsIMemoryMultiReporter);
|
|
||||||
mgr.unregisterMultiReporter(r);
|
|
||||||
realMultiReporters.push(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup various fake-but-deterministic reporters.
|
// Setup various fake-but-deterministic reporters.
|
||||||
const KB = 1024;
|
const KB = 1024;
|
||||||
@@ -47,35 +39,31 @@
|
|||||||
const OTHER = Ci.nsIMemoryReporter.KIND_OTHER;
|
const OTHER = Ci.nsIMemoryReporter.KIND_OTHER;
|
||||||
const BYTES = Ci.nsIMemoryReporter.UNITS_BYTES;
|
const BYTES = Ci.nsIMemoryReporter.UNITS_BYTES;
|
||||||
|
|
||||||
function f(aPath, aKind, aAmount) {
|
let hiPath = "explicit/h/i";
|
||||||
return {
|
let hi2Path = "explicit/h/i2";
|
||||||
process: "",
|
let jkPath = "explicit/j/k";
|
||||||
path: aPath,
|
let jk2Path = "explicit/j/k2";
|
||||||
kind: aKind,
|
|
||||||
units: BYTES,
|
|
||||||
description: "Desc.",
|
|
||||||
amount: aAmount
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
let hiReport = f("explicit/h/i", HEAP, 10 * MB);
|
|
||||||
let hi2Report = f("explicit/h/i2", HEAP, 9 * MB);
|
|
||||||
let jkReport = f("explicit/j/k", HEAP, 0.5 * MB);
|
|
||||||
let jk2Report = f("explicit/j/k2", HEAP, 0.3 * MB);
|
|
||||||
|
|
||||||
let fakeReporters = [
|
let fakeReporters = [
|
||||||
f("heap-allocated", OTHER, 250 * MB),
|
{ name: "fake1",
|
||||||
f("explicit/a/b", HEAP, 50 * MB),
|
collectReports: function(aCbObj, aClosure) {
|
||||||
f("explicit/a/c/d", HEAP, 25 * MB),
|
function f(aP, aK, aA) {
|
||||||
f("explicit/a/c/e", HEAP, 15 * MB),
|
aCbObj.callback("", aP, aK, BYTES, aA, "Desc.", aClosure);
|
||||||
f("explicit/a/f", HEAP, 30 * MB),
|
}
|
||||||
f("explicit/g", HEAP, 100 * MB),
|
f("heap-allocated", OTHER, 250 * MB);
|
||||||
hiReport,
|
f("explicit/a/b", HEAP, 50 * MB);
|
||||||
hi2Report,
|
f("explicit/a/c/d", HEAP, 25 * MB);
|
||||||
jkReport,
|
f("explicit/a/c/e", HEAP, 15 * MB);
|
||||||
jk2Report,
|
f("explicit/a/f", HEAP, 30 * MB);
|
||||||
f("explicit/a/l/m", HEAP, 0.1 * MB),
|
f("explicit/g", HEAP, 100 * MB);
|
||||||
f("explicit/a/l/n", HEAP, 0.1 * MB),
|
f(hiPath, HEAP, 10 * MB);
|
||||||
|
f(hi2Path, HEAP, 9 * MB);
|
||||||
|
f(jkPath, HEAP, 0.5 * MB);
|
||||||
|
f(jk2Path, HEAP, 0.3 * MB);
|
||||||
|
f("explicit/a/l/m", HEAP, 0.1 * MB);
|
||||||
|
f("explicit/a/l/n", HEAP, 0.1 * MB);
|
||||||
|
}
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
for (let i = 0; i < fakeReporters.length; i++) {
|
for (let i = 0; i < fakeReporters.length; i++) {
|
||||||
@@ -91,18 +79,14 @@
|
|||||||
<![CDATA[
|
<![CDATA[
|
||||||
function finish()
|
function finish()
|
||||||
{
|
{
|
||||||
// Unregister fake reporters and multi-reporters, re-register the real
|
// Unregister fake reporters and re-register the real reporters, just in
|
||||||
// reporters and multi-reporters, just in case subsequent tests rely on
|
// case subsequent tests rely on them.
|
||||||
// them.
|
|
||||||
for (let i = 0; i < fakeReporters.length; i++) {
|
for (let i = 0; i < fakeReporters.length; i++) {
|
||||||
mgr.unregisterReporter(fakeReporters[i]);
|
mgr.unregisterReporter(fakeReporters[i]);
|
||||||
}
|
}
|
||||||
for (let i = 0; i < realReporters.length; i++) {
|
for (let i = 0; i < realReporters.length; i++) {
|
||||||
mgr.registerReporterEvenIfBlocked(realReporters[i]);
|
mgr.registerReporterEvenIfBlocked(realReporters[i]);
|
||||||
}
|
}
|
||||||
for (let i = 0; i < realMultiReporters.length; i++) {
|
|
||||||
mgr.registerMultiReporterEvenIfBlocked(realMultiReporters[i]);
|
|
||||||
}
|
|
||||||
mgr.unblockRegistration();
|
mgr.unblockRegistration();
|
||||||
|
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
@@ -119,13 +103,13 @@
|
|||||||
// click on a child of the span identified via |id|.
|
// click on a child of the span identified via |id|.
|
||||||
if (node.nodeName === "button") {
|
if (node.nodeName === "button") {
|
||||||
if (aSwap) {
|
if (aSwap) {
|
||||||
// We swap the paths of hiReport/hi2Report and jkReport/jk2Report
|
// We swap hipath/hi2Path and jkPath/jk2Path just before updating, to
|
||||||
// just before updating, to test what happens when significant nodes
|
// test what happens when significant nodes become insignificant and
|
||||||
// become insignificant and vice versa.
|
// vice versa.
|
||||||
hiReport.path = "explicit/j/k";
|
hiPath = "explicit/j/k";
|
||||||
hi2Report.path = "explicit/j/k2";
|
hi2Path = "explicit/j/k2";
|
||||||
jkReport.path = "explicit/h/i";
|
jkPath = "explicit/h/i";
|
||||||
jk2Report.path = "explicit/h/i2";
|
jk2Path = "explicit/h/i2";
|
||||||
}
|
}
|
||||||
node.click();
|
node.click();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -22,8 +22,7 @@
|
|||||||
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
|
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
|
||||||
getService(Ci.nsIMemoryReporterManager);
|
getService(Ci.nsIMemoryReporterManager);
|
||||||
|
|
||||||
// Remove all the real reporters and multi-reporters; save them to
|
// Remove all the real reporters; save them to restore at the end.
|
||||||
// restore at the end.
|
|
||||||
mgr.blockRegistration();
|
mgr.blockRegistration();
|
||||||
let e = mgr.enumerateReporters();
|
let e = mgr.enumerateReporters();
|
||||||
let realReporters = [];
|
let realReporters = [];
|
||||||
@@ -32,13 +31,6 @@
|
|||||||
mgr.unregisterReporter(r);
|
mgr.unregisterReporter(r);
|
||||||
realReporters.push(r);
|
realReporters.push(r);
|
||||||
}
|
}
|
||||||
e = mgr.enumerateMultiReporters();
|
|
||||||
let realMultiReporters = [];
|
|
||||||
while (e.hasMoreElements()) {
|
|
||||||
let r = e.getNext().QueryInterface(Ci.nsIMemoryMultiReporter);
|
|
||||||
mgr.unregisterMultiReporter(r);
|
|
||||||
realMultiReporters.push(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup a minimal number of fake reporters.
|
// Setup a minimal number of fake reporters.
|
||||||
const KB = 1024;
|
const KB = 1024;
|
||||||
@@ -47,22 +39,18 @@
|
|||||||
const OTHER = Ci.nsIMemoryReporter.KIND_OTHER;
|
const OTHER = Ci.nsIMemoryReporter.KIND_OTHER;
|
||||||
const BYTES = Ci.nsIMemoryReporter.UNITS_BYTES;
|
const BYTES = Ci.nsIMemoryReporter.UNITS_BYTES;
|
||||||
|
|
||||||
function f(aPath, aKind, aAmount, aDesc) {
|
|
||||||
return {
|
|
||||||
process: "",
|
|
||||||
path: aPath,
|
|
||||||
kind: aKind,
|
|
||||||
units: BYTES,
|
|
||||||
amount: aAmount,
|
|
||||||
description: aDesc
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
let fakeReporters = [
|
let fakeReporters = [
|
||||||
f("heap-allocated", OTHER, 250 * MB, "Heap allocated."),
|
{ name: "fake1",
|
||||||
f("explicit/a/b", HEAP, 50 * MB, "A b."),
|
collectReports: function(aCbObj, aClosure) {
|
||||||
f("other/a", OTHER, 0.2 * MB, "Other a."),
|
function f(aP, aK, aA, aD) {
|
||||||
f("other/b", OTHER, 0.1 * MB, "Other b."),
|
aCbObj.callback("", aP, aK, BYTES, aA, aD, aClosure);
|
||||||
|
}
|
||||||
|
f("heap-allocated", OTHER, 250 * MB, "Heap allocated.");
|
||||||
|
f("explicit/a/b", HEAP, 50 * MB, "A b.");
|
||||||
|
f("other/a", OTHER, 0.2 * MB, "Other a.");
|
||||||
|
f("other/b", OTHER, 0.1 * MB, "Other b.");
|
||||||
|
}
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
for (let i = 0; i < fakeReporters.length; i++) {
|
for (let i = 0; i < fakeReporters.length; i++) {
|
||||||
@@ -78,18 +66,14 @@
|
|||||||
<![CDATA[
|
<![CDATA[
|
||||||
function finish()
|
function finish()
|
||||||
{
|
{
|
||||||
// Unregister fake reporters and multi-reporters, re-register the real
|
// Unregister fake reporters and re-register the real reporters, just in
|
||||||
// reporters and multi-reporters, just in case subsequent tests rely on
|
// case subsequent tests rely on them.
|
||||||
// them.
|
|
||||||
for (let i = 0; i < fakeReporters.length; i++) {
|
for (let i = 0; i < fakeReporters.length; i++) {
|
||||||
mgr.unregisterReporter(fakeReporters[i]);
|
mgr.unregisterReporter(fakeReporters[i]);
|
||||||
}
|
}
|
||||||
for (let i = 0; i < realReporters.length; i++) {
|
for (let i = 0; i < realReporters.length; i++) {
|
||||||
mgr.registerReporterEvenIfBlocked(realReporters[i]);
|
mgr.registerReporterEvenIfBlocked(realReporters[i]);
|
||||||
}
|
}
|
||||||
for (let i = 0; i < realMultiReporters.length; i++) {
|
|
||||||
mgr.registerMultiReporterEvenIfBlocked(realMultiReporters[i]);
|
|
||||||
}
|
|
||||||
mgr.unblockRegistration();
|
mgr.unblockRegistration();
|
||||||
|
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
|
|||||||
@@ -138,11 +138,6 @@
|
|||||||
let e = mgr.enumerateReporters();
|
let e = mgr.enumerateReporters();
|
||||||
while (e.hasMoreElements()) {
|
while (e.hasMoreElements()) {
|
||||||
let r = e.getNext().QueryInterface(Ci.nsIMemoryReporter);
|
let r = e.getNext().QueryInterface(Ci.nsIMemoryReporter);
|
||||||
handleReport(r.process, r.path, r.kind, r.units, r.amount, r.description);
|
|
||||||
}
|
|
||||||
e = mgr.enumerateMultiReporters();
|
|
||||||
while (e.hasMoreElements()) {
|
|
||||||
let r = e.getNext().QueryInterface(Ci.nsIMemoryMultiReporter);
|
|
||||||
r.collectReports(handleReport, null);
|
r.collectReports(handleReport, null);
|
||||||
|
|
||||||
// Access |name| to make sure it doesn't crash or assert.
|
// Access |name| to make sure it doesn't crash or assert.
|
||||||
|
|||||||
@@ -36,13 +36,13 @@
|
|||||||
let db = storage.openDatabase(file);
|
let db = storage.openDatabase(file);
|
||||||
db.close();
|
db.close();
|
||||||
|
|
||||||
// Invoke all the multi-reporters. The SQLite multi-reporter is among
|
// Invoke all the reporters. The SQLite multi-reporter is among
|
||||||
// them. It shouldn't crash.
|
// them. It shouldn't crash.
|
||||||
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
|
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
|
||||||
getService(Ci.nsIMemoryReporterManager);
|
getService(Ci.nsIMemoryReporterManager);
|
||||||
e = mgr.enumerateMultiReporters();
|
e = mgr.enumerateReporters();
|
||||||
while (e.hasMoreElements()) {
|
while (e.hasMoreElements()) {
|
||||||
let r = e.getNext().QueryInterface(Ci.nsIMemoryMultiReporter);
|
let r = e.getNext().QueryInterface(Ci.nsIMemoryReporter);
|
||||||
r.collectReports(function(){}, null);
|
r.collectReports(function(){}, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1909,11 +1909,11 @@ StoreAndNotifyEmbedVisit(VisitData& aPlace,
|
|||||||
(void)NS_DispatchToMainThread(event);
|
(void)NS_DispatchToMainThread(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
class HistoryLinksHashtableReporter MOZ_FINAL : public MemoryReporterBase
|
class HistoryLinksHashtableReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HistoryLinksHashtableReporter()
|
HistoryLinksHashtableReporter()
|
||||||
: MemoryReporterBase("explicit/history-links-hashtable",
|
: MemoryUniReporter("explicit/history-links-hashtable",
|
||||||
KIND_HEAP, UNITS_BYTES,
|
KIND_HEAP, UNITS_BYTES,
|
||||||
"Memory used by the hashtable that records changes to the visited state of "
|
"Memory used by the hashtable that records changes to the visited state of "
|
||||||
"links.")
|
"links.")
|
||||||
|
|||||||
@@ -370,11 +370,11 @@ TelemetryImpl::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
class TelemetryReporter MOZ_FINAL : public MemoryReporterBase
|
class TelemetryReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TelemetryReporter()
|
TelemetryReporter()
|
||||||
: MemoryReporterBase("explicit/telemetry", KIND_HEAP, UNITS_BYTES,
|
: MemoryUniReporter("explicit/telemetry", KIND_HEAP, UNITS_BYTES,
|
||||||
"Memory used by the telemetry system.")
|
"Memory used by the telemetry system.")
|
||||||
{}
|
{}
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ const Ci = Components.interfaces;
|
|||||||
const Cr = Components.results;
|
const Cr = Components.results;
|
||||||
const Cu = Components.utils;
|
const Cu = Components.utils;
|
||||||
|
|
||||||
|
Cu.import("resource://gre/modules/debug.js");
|
||||||
Cu.import("resource://gre/modules/Services.jsm");
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
#ifndef MOZ_WIDGET_GONK
|
#ifndef MOZ_WIDGET_GONK
|
||||||
@@ -458,15 +459,32 @@ TelemetryPing.prototype = {
|
|||||||
let e = mgr.enumerateReporters();
|
let e = mgr.enumerateReporters();
|
||||||
while (e.hasMoreElements()) {
|
while (e.hasMoreElements()) {
|
||||||
let mr = e.getNext().QueryInterface(Ci.nsIMemoryReporter);
|
let mr = e.getNext().QueryInterface(Ci.nsIMemoryReporter);
|
||||||
let id = MEM_HISTOGRAMS[mr.path];
|
let id = MEM_HISTOGRAMS[mr.name];
|
||||||
if (!id) {
|
if (!id) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reading mr.amount might throw an exception. If so, just ignore that
|
// collectReports might throw an exception. If so, just ignore that
|
||||||
// memory reporter; we're not getting useful data out of it.
|
// memory reporter; we're not getting useful data out of it.
|
||||||
try {
|
try {
|
||||||
this.handleMemoryReport(id, mr.path, mr.units, mr.amount);
|
// Bind handleMemoryReport() so it can be called inside the closure
|
||||||
|
// used as the callback.
|
||||||
|
let boundHandleMemoryReport = this.handleMemoryReport.bind(this);
|
||||||
|
|
||||||
|
// Reporters used for telemetry should be uni-reporters! we assert if
|
||||||
|
// they make more than one report.
|
||||||
|
let hasReported = false;
|
||||||
|
|
||||||
|
function h(process, path, kind, units, amount, desc) {
|
||||||
|
if (!hasReported) {
|
||||||
|
boundHandleMemoryReport(id, path, units, amount);
|
||||||
|
hasReported = true;
|
||||||
|
} else {
|
||||||
|
NS_ASSERT(false,
|
||||||
|
"reporter " + mr.name + " has made more than one report");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mr.collectReports(h, null);
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
}
|
}
|
||||||
@@ -474,11 +492,7 @@ TelemetryPing.prototype = {
|
|||||||
histogram.add(new Date() - startTime);
|
histogram.add(new Date() - startTime);
|
||||||
},
|
},
|
||||||
|
|
||||||
handleMemoryReport: function handleMemoryReport(id, path, units, amount) {
|
handleMemoryReport: function(id, path, units, amount) {
|
||||||
if (amount == -1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let val;
|
let val;
|
||||||
if (units == Ci.nsIMemoryReporter.UNITS_BYTES) {
|
if (units == Ci.nsIMemoryReporter.UNITS_BYTES) {
|
||||||
val = Math.floor(amount / 1024);
|
val = Math.floor(amount / 1024);
|
||||||
|
|||||||
@@ -36,12 +36,12 @@ static const PRLogModuleInfo *gUrlClassifierPrefixSetLog = nullptr;
|
|||||||
#define LOG_ENABLED() (false)
|
#define LOG_ENABLED() (false)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class PrefixSetReporter MOZ_FINAL : public MemoryReporterBase
|
class PrefixSetReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PrefixSetReporter(nsUrlClassifierPrefixSet* aPrefixSet,
|
PrefixSetReporter(nsUrlClassifierPrefixSet* aPrefixSet,
|
||||||
const nsACString& aName)
|
const nsACString& aName)
|
||||||
: MemoryReporterBase(
|
: MemoryUniReporter(
|
||||||
nsPrintfCString(
|
nsPrintfCString(
|
||||||
"explicit/storage/prefix-set/%s",
|
"explicit/storage/prefix-set/%s",
|
||||||
(!aName.IsEmpty() ? PromiseFlatCString(aName).get() : "?!")
|
(!aName.IsEmpty() ? PromiseFlatCString(aName).get() : "?!")
|
||||||
|
|||||||
@@ -325,37 +325,19 @@ CreateDIBSectionHook(HDC aDC,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
class LowMemoryEventsVirtualReporter MOZ_FINAL : public MemoryReporterBase
|
class LowMemoryEventsVirtualReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// The description is "???" because we implement GetDescription().
|
|
||||||
LowMemoryEventsVirtualReporter()
|
LowMemoryEventsVirtualReporter()
|
||||||
: MemoryReporterBase("low-memory-events/virtual",
|
: MemoryUniReporter("low-memory-events/virtual",
|
||||||
KIND_OTHER, UNITS_COUNT_CUMULATIVE, "???")
|
KIND_OTHER, UNITS_COUNT_CUMULATIVE,
|
||||||
|
"Number of low-virtual-memory events fired since startup. We fire such an "
|
||||||
|
"event if we notice there is less than memory.low_virtual_mem_threshold_mb of "
|
||||||
|
"virtual address space available (if zero, this behavior is disabled). The "
|
||||||
|
"process will probably crash if it runs out of virtual address space, so "
|
||||||
|
"this event is dire.")
|
||||||
{}
|
{}
|
||||||
|
|
||||||
NS_IMETHOD GetDescription(nsACString &aDescription)
|
|
||||||
{
|
|
||||||
aDescription.AssignLiteral(
|
|
||||||
"Number of low-virtual-memory events fired since startup. ");
|
|
||||||
|
|
||||||
if (sLowVirtualMemoryThreshold == 0) {
|
|
||||||
aDescription.AppendLiteral(
|
|
||||||
"Tracking low-virtual-memory events is disabled, but you can enable it "
|
|
||||||
"by giving the memory.low_virtual_mem_threshold_mb pref a non-zero "
|
|
||||||
"value.");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
aDescription.Append(nsPrintfCString(
|
|
||||||
"We fire such an event if we notice there is less than %d MB of virtual "
|
|
||||||
"address space available (controlled by the "
|
|
||||||
"'memory.low_virtual_mem_threshold_mb' pref). We'll likely crash if "
|
|
||||||
"we run out of virtual address space, so this event is somewhat dire.",
|
|
||||||
sLowVirtualMemoryThreshold));
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int64_t Amount() MOZ_OVERRIDE
|
int64_t Amount() MOZ_OVERRIDE
|
||||||
{
|
{
|
||||||
@@ -367,73 +349,36 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class LowCommitSpaceEventsReporter MOZ_FINAL : public MemoryReporterBase
|
class LowCommitSpaceEventsReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// The description is "???" because we implement GetDescription().
|
|
||||||
LowCommitSpaceEventsReporter()
|
LowCommitSpaceEventsReporter()
|
||||||
: MemoryReporterBase("low-commit-space-events",
|
: MemoryUniReporter("low-commit-space-events",
|
||||||
KIND_OTHER, UNITS_COUNT_CUMULATIVE, "???")
|
KIND_OTHER, UNITS_COUNT_CUMULATIVE,
|
||||||
|
"Number of low-commit-space events fired since startup. We fire such an "
|
||||||
|
"event if we notice there is less than memory.low_commit_space_threshold_mb of "
|
||||||
|
"commit space available (if zero, this behavior is disabled). Windows will "
|
||||||
|
"likely kill the process if it runs out of commit space, so this event is "
|
||||||
|
"dire.")
|
||||||
{}
|
{}
|
||||||
|
|
||||||
NS_IMETHOD GetDescription(nsACString &aDescription)
|
|
||||||
{
|
|
||||||
aDescription.AssignLiteral(
|
|
||||||
"Number of low-commit-space events fired since startup. ");
|
|
||||||
|
|
||||||
if (sLowCommitSpaceThreshold == 0) {
|
|
||||||
aDescription.Append(
|
|
||||||
"Tracking low-commit-space events is disabled, but you can enable it "
|
|
||||||
"by giving the memory.low_commit_space_threshold_mb pref a non-zero "
|
|
||||||
"value.");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
aDescription.Append(nsPrintfCString(
|
|
||||||
"We fire such an event if we notice there is less than %d MB of "
|
|
||||||
"available commit space (controlled by the "
|
|
||||||
"'memory.low_commit_space_threshold_mb' pref). Windows will likely "
|
|
||||||
"kill us if we run out of commit space, so this event is somewhat dire.",
|
|
||||||
sLowCommitSpaceThreshold));
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int64_t Amount() MOZ_OVERRIDE { return sNumLowCommitSpaceEvents; }
|
int64_t Amount() MOZ_OVERRIDE { return sNumLowCommitSpaceEvents; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class LowMemoryEventsPhysicalReporter MOZ_FINAL : public MemoryReporterBase
|
class LowMemoryEventsPhysicalReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// The description is "???" because we implement GetDescription().
|
|
||||||
LowMemoryEventsPhysicalReporter()
|
LowMemoryEventsPhysicalReporter()
|
||||||
: MemoryReporterBase("low-memory-events/physical",
|
: MemoryUniReporter("low-memory-events/physical",
|
||||||
KIND_OTHER, UNITS_COUNT_CUMULATIVE, "???")
|
KIND_OTHER, UNITS_COUNT_CUMULATIVE,
|
||||||
|
"Number of low-physical-memory events fired since startup. We fire such an "
|
||||||
|
"event if we notice there is less than memory.low_physical_memory_threshold_mb "
|
||||||
|
"of physical memory available (if zero, this behavior is disabled). The "
|
||||||
|
"machine will start to page if it runs out of physical memory. This may "
|
||||||
|
"cause it to run slowly, but it shouldn't cause it to crash.")
|
||||||
{}
|
{}
|
||||||
|
|
||||||
NS_IMETHOD GetDescription(nsACString &aDescription)
|
|
||||||
{
|
|
||||||
aDescription.AssignLiteral(
|
|
||||||
"Number of low-physical-memory events fired since startup. ");
|
|
||||||
|
|
||||||
if (sLowPhysicalMemoryThreshold == 0) {
|
|
||||||
aDescription.Append(
|
|
||||||
"Tracking low-physical-memory events is disabled, but you can enable it "
|
|
||||||
"by giving the memory.low_physical_memory_threshold_mb pref a non-zero "
|
|
||||||
"value.");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
aDescription.Append(nsPrintfCString(
|
|
||||||
"We fire such an event if we notice there is less than %d MB of "
|
|
||||||
"available physical memory (controlled by the "
|
|
||||||
"'memory.low_physical_memory_threshold_mb' pref). The machine will start "
|
|
||||||
"to page if it runs out of physical memory; this may cause it to run "
|
|
||||||
"slowly, but it shouldn't cause us to crash.",
|
|
||||||
sLowPhysicalMemoryThreshold));
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int64_t Amount() MOZ_OVERRIDE { return sNumLowPhysicalMemEvents; }
|
int64_t Amount() MOZ_OVERRIDE { return sNumLowPhysicalMemEvents; }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ struct CategoriesSeen {
|
|||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
class MapsReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
class MapsReporter MOZ_FINAL : public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MapsReporter();
|
MapsReporter();
|
||||||
@@ -125,7 +125,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHOD
|
NS_IMETHOD
|
||||||
CollectReports(nsIMemoryMultiReporterCallback *aCb,
|
CollectReports(nsIMemoryReporterCallback *aCb,
|
||||||
nsISupports *aClosure);
|
nsISupports *aClosure);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -135,7 +135,7 @@ private:
|
|||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
ParseMapping(FILE *aFile,
|
ParseMapping(FILE *aFile,
|
||||||
nsIMemoryMultiReporterCallback *aCb,
|
nsIMemoryReporterCallback *aCb,
|
||||||
nsISupports *aClosure,
|
nsISupports *aClosure,
|
||||||
CategoriesSeen *aCategoriesSeen);
|
CategoriesSeen *aCategoriesSeen);
|
||||||
|
|
||||||
@@ -149,7 +149,7 @@ private:
|
|||||||
ParseMapBody(FILE *aFile,
|
ParseMapBody(FILE *aFile,
|
||||||
const nsACString &aName,
|
const nsACString &aName,
|
||||||
const nsACString &aDescription,
|
const nsACString &aDescription,
|
||||||
nsIMemoryMultiReporterCallback *aCb,
|
nsIMemoryReporterCallback *aCb,
|
||||||
nsISupports *aClosure,
|
nsISupports *aClosure,
|
||||||
CategoriesSeen *aCategoriesSeen);
|
CategoriesSeen *aCategoriesSeen);
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ private:
|
|||||||
nsTHashtable<nsCStringHashKey> mMozillaLibraries;
|
nsTHashtable<nsCStringHashKey> mMozillaLibraries;
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(MapsReporter, nsIMemoryMultiReporter)
|
NS_IMPL_ISUPPORTS1(MapsReporter, nsIMemoryReporter)
|
||||||
|
|
||||||
MapsReporter::MapsReporter()
|
MapsReporter::MapsReporter()
|
||||||
: mSearchedForLibxul(false)
|
: mSearchedForLibxul(false)
|
||||||
@@ -173,7 +173,7 @@ MapsReporter::MapsReporter()
|
|||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
MapsReporter::CollectReports(nsIMemoryMultiReporterCallback *aCb,
|
MapsReporter::CollectReports(nsIMemoryReporterCallback *aCb,
|
||||||
nsISupports *aClosure)
|
nsISupports *aClosure)
|
||||||
{
|
{
|
||||||
CategoriesSeen categoriesSeen;
|
CategoriesSeen categoriesSeen;
|
||||||
@@ -258,7 +258,7 @@ MapsReporter::FindLibxul()
|
|||||||
nsresult
|
nsresult
|
||||||
MapsReporter::ParseMapping(
|
MapsReporter::ParseMapping(
|
||||||
FILE *aFile,
|
FILE *aFile,
|
||||||
nsIMemoryMultiReporterCallback *aCb,
|
nsIMemoryReporterCallback *aCb,
|
||||||
nsISupports *aClosure,
|
nsISupports *aClosure,
|
||||||
CategoriesSeen *aCategoriesSeen)
|
CategoriesSeen *aCategoriesSeen)
|
||||||
{
|
{
|
||||||
@@ -461,7 +461,7 @@ MapsReporter::ParseMapBody(
|
|||||||
FILE *aFile,
|
FILE *aFile,
|
||||||
const nsACString &aName,
|
const nsACString &aName,
|
||||||
const nsACString &aDescription,
|
const nsACString &aDescription,
|
||||||
nsIMemoryMultiReporterCallback *aCb,
|
nsIMemoryReporterCallback *aCb,
|
||||||
nsISupports *aClosure,
|
nsISupports *aClosure,
|
||||||
CategoriesSeen *aCategoriesSeen)
|
CategoriesSeen *aCategoriesSeen)
|
||||||
{
|
{
|
||||||
@@ -520,11 +520,11 @@ MapsReporter::ParseMapBody(
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ResidentUniqueReporter MOZ_FINAL : public MemoryReporterBase
|
class ResidentUniqueReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ResidentUniqueReporter()
|
ResidentUniqueReporter()
|
||||||
: MemoryReporterBase("resident-unique", KIND_OTHER, UNITS_BYTES,
|
: MemoryUniReporter("resident-unique", KIND_OTHER, UNITS_BYTES,
|
||||||
"Memory mapped by the process that is present in physical memory and not "
|
"Memory mapped by the process that is present in physical memory and not "
|
||||||
"shared with any other processes. This is also known as the process's unique "
|
"shared with any other processes. This is also known as the process's unique "
|
||||||
"set size (USS). This is the amount of RAM we'd expect to be freed if we "
|
"set size (USS). This is the amount of RAM we'd expect to be freed if we "
|
||||||
@@ -540,9 +540,9 @@ private:
|
|||||||
// little to do with whether the pages are actually shared. smaps on the
|
// little to do with whether the pages are actually shared. smaps on the
|
||||||
// other hand appears to give us the correct information.
|
// other hand appears to give us the correct information.
|
||||||
//
|
//
|
||||||
// We could calculate this data during the smaps multi-reporter, but the
|
// We could calculate this data within the smaps reporter, but the overhead
|
||||||
// overhead of the smaps reporter is considerable (we don't even run the
|
// of the smaps reporter is considerable (we don't even run the smaps
|
||||||
// smaps reporter in normal about:memory operation). Hopefully this
|
// reporter in normal about:memory operation). Hopefully this
|
||||||
// implementation is fast enough not to matter.
|
// implementation is fast enough not to matter.
|
||||||
|
|
||||||
*aAmount = 0;
|
*aAmount = 0;
|
||||||
@@ -568,8 +568,8 @@ private:
|
|||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIMemoryMultiReporter> reporter = new MapsReporter();
|
nsCOMPtr<nsIMemoryReporter> reporter = new MapsReporter();
|
||||||
NS_RegisterMemoryMultiReporter(reporter);
|
NS_RegisterMemoryReporter(reporter);
|
||||||
|
|
||||||
NS_RegisterMemoryReporter(new ResidentUniqueReporter());
|
NS_RegisterMemoryReporter(new ResidentUniqueReporter());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -917,7 +917,7 @@ private:
|
|||||||
CC_BeforeUnlinkCallback mBeforeUnlinkCB;
|
CC_BeforeUnlinkCallback mBeforeUnlinkCB;
|
||||||
CC_ForgetSkippableCallback mForgetSkippableCB;
|
CC_ForgetSkippableCallback mForgetSkippableCB;
|
||||||
|
|
||||||
nsCOMPtr<nsIMemoryMultiReporter> mReporter;
|
nsCOMPtr<nsIMemoryReporter> mReporter;
|
||||||
|
|
||||||
nsPurpleBuffer mPurpleBuf;
|
nsPurpleBuffer mPurpleBuf;
|
||||||
|
|
||||||
@@ -2398,10 +2398,10 @@ nsCycleCollector::CollectWhite(nsICycleCollectorListener *aListener)
|
|||||||
// Memory reporter
|
// Memory reporter
|
||||||
////////////////////////
|
////////////////////////
|
||||||
|
|
||||||
class CycleCollectorMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
class CycleCollectorReporter MOZ_FINAL : public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CycleCollectorMultiReporter(nsCycleCollector* aCollector)
|
CycleCollectorReporter(nsCycleCollector* aCollector)
|
||||||
: mCollector(aCollector)
|
: mCollector(aCollector)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@@ -2413,7 +2413,7 @@ class CycleCollectorMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback* aCb,
|
NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCb,
|
||||||
nsISupports* aClosure)
|
nsISupports* aClosure)
|
||||||
{
|
{
|
||||||
size_t objectSize, graphNodesSize, graphEdgesSize, whiteNodesSize,
|
size_t objectSize, graphNodesSize, graphEdgesSize, whiteNodesSize,
|
||||||
@@ -2465,7 +2465,7 @@ class CycleCollectorMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
|||||||
nsCycleCollector* mCollector;
|
nsCycleCollector* mCollector;
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(CycleCollectorMultiReporter, nsIMemoryMultiReporter)
|
NS_IMPL_ISUPPORTS1(CycleCollectorReporter, nsIMemoryReporter)
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
@@ -2492,7 +2492,7 @@ nsCycleCollector::nsCycleCollector() :
|
|||||||
|
|
||||||
nsCycleCollector::~nsCycleCollector()
|
nsCycleCollector::~nsCycleCollector()
|
||||||
{
|
{
|
||||||
NS_UnregisterMemoryMultiReporter(mReporter);
|
NS_UnregisterMemoryReporter(mReporter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -2508,7 +2508,7 @@ nsCycleCollector::RegisterJSRuntime(CycleCollectedJSRuntime *aJSRuntime)
|
|||||||
// instead.
|
// instead.
|
||||||
static bool registered = false;
|
static bool registered = false;
|
||||||
if (!registered) {
|
if (!registered) {
|
||||||
NS_RegisterMemoryMultiReporter(new CycleCollectorMultiReporter(this));
|
NS_RegisterMemoryReporter(new CycleCollectorReporter(this));
|
||||||
registered = true;
|
registered = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,55 +17,22 @@ interface nsICancelableRunnable;
|
|||||||
* reporter.
|
* reporter.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
[scriptable, function, uuid(3a61be3b-b93b-461a-a4f8-388214f558b1)]
|
||||||
* An nsIMemoryReporter reports a single memory measurement as an object.
|
interface nsIMemoryReporterCallback : nsISupports
|
||||||
* Use this when it makes sense to gather this measurement without gathering
|
|
||||||
* related measurements at the same time.
|
|
||||||
*
|
|
||||||
* Note that the |amount| field may be implemented as a function, and so
|
|
||||||
* accessing it can trigger significant computation; the other fields can
|
|
||||||
* be accessed without triggering this computation. (Compare and contrast
|
|
||||||
* this with nsIMemoryMultiReporter.)
|
|
||||||
*
|
|
||||||
* aboutMemory.js is the most important consumer of memory reports. It
|
|
||||||
* places the following constraints on reports.
|
|
||||||
*
|
|
||||||
* - There must be an "explicit" tree. It represents non-overlapping
|
|
||||||
* regions of memory that have been explicitly allocated with an
|
|
||||||
* OS-level allocation (e.g. mmap/VirtualAlloc/vm_allocate) or a
|
|
||||||
* heap-level allocation (e.g. malloc/calloc/operator new). Reporters
|
|
||||||
* in this tree must have kind HEAP or NONHEAP, units BYTES, and a
|
|
||||||
* description that is a sentence (i.e. starts with a capital letter and
|
|
||||||
* ends with a period, or similar).
|
|
||||||
*
|
|
||||||
* - The "size", "rss", "pss" and "swap" trees are optional. They
|
|
||||||
* represent regions of virtual memory that the process has mapped.
|
|
||||||
* Reporters in this category must have kind NONHEAP, units BYTES, and a
|
|
||||||
* non-empty description.
|
|
||||||
*
|
|
||||||
* - The "compartments" and "ghost-windows" trees are optional. They are
|
|
||||||
* used by about:compartments. Reporters in these trees must have kind
|
|
||||||
* OTHER, units COUNT, an amount of 1, and a description that's an empty
|
|
||||||
* string.
|
|
||||||
*
|
|
||||||
* - All other reports are unconstrained except that they must have a
|
|
||||||
* description that is a sentence.
|
|
||||||
*/
|
|
||||||
[scriptable, uuid(b2c39f65-1799-4b92-a806-ab3cf6af3cfa)]
|
|
||||||
interface nsIMemoryReporter : nsISupports
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* The name of the process containing this reporter. Each reporter initially
|
* The arguments to the callback are as follows.
|
||||||
* has "" in this field, indicating that it applies to the current process.
|
*
|
||||||
* (This is true even for reporters in a child process.) When a reporter
|
*
|
||||||
* from a child process is copied into the main process, the copy has its
|
* |process| The name of the process containing this reporter. Each
|
||||||
* 'process' field set appropriately.
|
* reporter initially has "" in this field, indicating that it applies to the
|
||||||
*/
|
* current process. (This is true even for reporters in a child process.)
|
||||||
readonly attribute ACString process;
|
* When a reporter from a child process is copied into the main process, the
|
||||||
|
* copy has its 'process' field set appropriately.
|
||||||
/*
|
*
|
||||||
* The path that this memory usage should be reported under. Paths are
|
*
|
||||||
* '/'-delimited, eg. "a/b/c".
|
* |path| The path that this memory usage should be reported under. Paths
|
||||||
|
* are '/'-delimited, eg. "a/b/c".
|
||||||
*
|
*
|
||||||
* Each reporter can be viewed as representing a leaf node in a tree.
|
* Each reporter can be viewed as representing a leaf node in a tree.
|
||||||
* Internal nodes of the tree don't have reporters. So, for example, the
|
* Internal nodes of the tree don't have reporters. So, for example, the
|
||||||
@@ -98,11 +65,9 @@ interface nsIMemoryReporter : nsISupports
|
|||||||
*
|
*
|
||||||
* The paths of all reporters form a set of trees. Trees can be
|
* The paths of all reporters form a set of trees. Trees can be
|
||||||
* "degenerate", i.e. contain a single entry with no '/'.
|
* "degenerate", i.e. contain a single entry with no '/'.
|
||||||
*/
|
*
|
||||||
readonly attribute AUTF8String path;
|
*
|
||||||
|
* |kind| There are three kinds of memory reporters.
|
||||||
/*
|
|
||||||
* There are three kinds of memory reporters.
|
|
||||||
*
|
*
|
||||||
* - HEAP: reporters measuring memory allocated by the heap allocator,
|
* - HEAP: reporters measuring memory allocated by the heap allocator,
|
||||||
* e.g. by calling malloc, calloc, realloc, memalign, operator new, or
|
* e.g. by calling malloc, calloc, realloc, memalign, operator new, or
|
||||||
@@ -120,19 +85,9 @@ interface nsIMemoryReporter : nsISupports
|
|||||||
*
|
*
|
||||||
* The kind only matters for reporters in the "explicit" tree;
|
* The kind only matters for reporters in the "explicit" tree;
|
||||||
* aboutMemory.js uses it to calculate "heap-unclassified".
|
* aboutMemory.js uses it to calculate "heap-unclassified".
|
||||||
*/
|
*
|
||||||
const int32_t KIND_NONHEAP = 0;
|
*
|
||||||
const int32_t KIND_HEAP = 1;
|
* |units| The units on the reporter's amount. One of the following.
|
||||||
const int32_t KIND_OTHER = 2;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The reporter kind. See KIND_* above.
|
|
||||||
*/
|
|
||||||
readonly attribute int32_t kind;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The amount reported by a memory reporter must have one of the following
|
|
||||||
* units, but you may of course add new units as necessary:
|
|
||||||
*
|
*
|
||||||
* - BYTES: The amount contains a number of bytes.
|
* - BYTES: The amount contains a number of bytes.
|
||||||
*
|
*
|
||||||
@@ -156,67 +111,84 @@ interface nsIMemoryReporter : nsISupports
|
|||||||
* be 1234.
|
* be 1234.
|
||||||
*
|
*
|
||||||
* Values greater than 100% are allowed.
|
* Values greater than 100% are allowed.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* |amount| The numeric value reported by this memory reporter. Accesses
|
||||||
|
* can fail if something goes wrong when getting the amount.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* |description| A human-readable description of this memory usage report.
|
||||||
*/
|
*/
|
||||||
const int32_t UNITS_BYTES = 0;
|
|
||||||
const int32_t UNITS_COUNT = 1;
|
|
||||||
const int32_t UNITS_COUNT_CUMULATIVE = 2;
|
|
||||||
const int32_t UNITS_PERCENTAGE = 3;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The units on the reporter's amount. See UNITS_* above.
|
|
||||||
*/
|
|
||||||
readonly attribute int32_t units;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The numeric value reported by this memory reporter. Accesses can fail if
|
|
||||||
* something goes wrong when getting the amount.
|
|
||||||
*/
|
|
||||||
readonly attribute int64_t amount;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A human-readable description of this memory usage report.
|
|
||||||
*/
|
|
||||||
readonly attribute AUTF8String description;
|
|
||||||
};
|
|
||||||
|
|
||||||
[scriptable, function, uuid(5b15f3fa-ba15-443c-8337-7770f5f0ce5d)]
|
|
||||||
interface nsIMemoryMultiReporterCallback : nsISupports
|
|
||||||
{
|
|
||||||
void callback(in ACString process, in AUTF8String path, in int32_t kind,
|
void callback(in ACString process, in AUTF8String path, in int32_t kind,
|
||||||
in int32_t units, in int64_t amount,
|
in int32_t units, in int64_t amount,
|
||||||
in AUTF8String description, in nsISupports closure);
|
in AUTF8String description, in nsISupports closure);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* An nsIMemoryMultiReporter reports multiple memory measurements via a
|
* An nsIMemoryReporter reports one or more memory measurements via a
|
||||||
* callback function which is called once for each measurement. Use this
|
* callback function which is called once for each measurement.
|
||||||
* when you want to gather multiple measurements in a single operation (eg.
|
|
||||||
* a single traversal of a large data structure).
|
|
||||||
*
|
*
|
||||||
* The arguments to the callback deliberately match the fields in
|
* An nsIMemoryReporter that reports a single measurement is sometimes called a
|
||||||
* nsIMemoryReporter, but note that seeing any of these arguments requires
|
* "uni-reporter". One that reports multiple measurements is sometimes called
|
||||||
* calling collectReports which will trigger all relevant computation.
|
* a "multi-reporter".
|
||||||
* (Compare and contrast this with nsIMemoryReporter, which allows all
|
*
|
||||||
* fields except |amount| to be accessed without triggering computation.)
|
* aboutMemory.js is the most important consumer of memory reports. It
|
||||||
|
* places the following constraints on reports.
|
||||||
|
*
|
||||||
|
* - There must be an "explicit" tree. It represents non-overlapping
|
||||||
|
* regions of memory that have been explicitly allocated with an
|
||||||
|
* OS-level allocation (e.g. mmap/VirtualAlloc/vm_allocate) or a
|
||||||
|
* heap-level allocation (e.g. malloc/calloc/operator new). Reporters
|
||||||
|
* in this tree must have kind HEAP or NONHEAP, units BYTES, and a
|
||||||
|
* description that is a sentence (i.e. starts with a capital letter and
|
||||||
|
* ends with a period, or similar).
|
||||||
|
*
|
||||||
|
* - The "size", "rss", "pss" and "swap" trees are optional. They
|
||||||
|
* represent regions of virtual memory that the process has mapped.
|
||||||
|
* Reporters in this category must have kind NONHEAP, units BYTES, and a
|
||||||
|
* non-empty description.
|
||||||
|
*
|
||||||
|
* - The "compartments" and "ghost-windows" trees are optional. They are
|
||||||
|
* used by about:compartments. Reporters in these trees must have kind
|
||||||
|
* OTHER, units COUNT, an amount of 1, and a description that's an empty
|
||||||
|
* string.
|
||||||
|
*
|
||||||
|
* - All other reports are unconstrained except that they must have a
|
||||||
|
* description that is a sentence.
|
||||||
*/
|
*/
|
||||||
[scriptable, uuid(24d61ead-237b-4969-a6bd-73fd8fed1d99)]
|
[scriptable, uuid(53248304-124b-43cd-99dc-6e5797b91618)]
|
||||||
interface nsIMemoryMultiReporter : nsISupports
|
interface nsIMemoryReporter : nsISupports
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* The name of the multi-reporter. Useful when only one multi-reporter
|
* The name of the reporter. Useful when only one reporter needs to be run.
|
||||||
* needs to be run. Must be unique; if multi-reporters share names it's
|
* Must be unique; if reporters share names it's likely the wrong one will
|
||||||
* likely the wrong one will be called in certain circumstances.
|
* be called in certain circumstances.
|
||||||
*/
|
*/
|
||||||
readonly attribute ACString name;
|
readonly attribute ACString name;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Run the multi-reporter.
|
* Run the reporter.
|
||||||
*/
|
*/
|
||||||
void collectReports(in nsIMemoryMultiReporterCallback callback,
|
void collectReports(in nsIMemoryReporterCallback callback,
|
||||||
in nsISupports closure);
|
in nsISupports closure);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Kinds. See the |kind| comment in nsIMemoryReporterCallback.
|
||||||
|
*/
|
||||||
|
const int32_t KIND_NONHEAP = 0;
|
||||||
|
const int32_t KIND_HEAP = 1;
|
||||||
|
const int32_t KIND_OTHER = 2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Units. See the |units| comment in nsIMemoryReporterCallback.
|
||||||
|
*/
|
||||||
|
const int32_t UNITS_BYTES = 0;
|
||||||
|
const int32_t UNITS_COUNT = 1;
|
||||||
|
const int32_t UNITS_COUNT_CUMULATIVE = 2;
|
||||||
|
const int32_t UNITS_PERCENTAGE = 3;
|
||||||
};
|
};
|
||||||
|
|
||||||
[scriptable, builtinclass, uuid(70b0e608-8dbf-4dc7-b88f-f1c745c1b48c)]
|
[scriptable, builtinclass, uuid(4db7040a-16f9-4249-879b-fe72729c7ef5)]
|
||||||
interface nsIMemoryReporterManager : nsISupports
|
interface nsIMemoryReporterManager : nsISupports
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@@ -224,12 +196,6 @@ interface nsIMemoryReporterManager : nsISupports
|
|||||||
*/
|
*/
|
||||||
nsISimpleEnumerator enumerateReporters ();
|
nsISimpleEnumerator enumerateReporters ();
|
||||||
|
|
||||||
/*
|
|
||||||
* Return an enumerator of nsIMemoryMultiReporters that are currently
|
|
||||||
* registered.
|
|
||||||
*/
|
|
||||||
nsISimpleEnumerator enumerateMultiReporters ();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register the given nsIMemoryReporter. After a reporter is registered,
|
* Register the given nsIMemoryReporter. After a reporter is registered,
|
||||||
* it will be available via enumerateReporters(). The Manager service
|
* it will be available via enumerateReporters(). The Manager service
|
||||||
@@ -237,31 +203,17 @@ interface nsIMemoryReporterManager : nsISupports
|
|||||||
*/
|
*/
|
||||||
void registerReporter (in nsIMemoryReporter reporter);
|
void registerReporter (in nsIMemoryReporter reporter);
|
||||||
|
|
||||||
/*
|
|
||||||
* Register the given nsIMemoryMultiReporter. After a multi-reporter is
|
|
||||||
* registered, it will be available via enumerateMultiReporters(). The
|
|
||||||
* Manager service will hold a strong reference to the given
|
|
||||||
* multi-reporter.
|
|
||||||
*/
|
|
||||||
void registerMultiReporter (in nsIMemoryMultiReporter reporter);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unregister the given memory reporter.
|
* Unregister the given memory reporter.
|
||||||
*/
|
*/
|
||||||
void unregisterReporter (in nsIMemoryReporter reporter);
|
void unregisterReporter (in nsIMemoryReporter reporter);
|
||||||
|
|
||||||
/*
|
|
||||||
* Unregister the given memory multi-reporter.
|
|
||||||
*/
|
|
||||||
void unregisterMultiReporter (in nsIMemoryMultiReporter reporter);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* These functions should only be used for testing purposes.
|
* These functions should only be used for testing purposes.
|
||||||
*/
|
*/
|
||||||
void blockRegistration();
|
void blockRegistration();
|
||||||
void unblockRegistration();
|
void unblockRegistration();
|
||||||
void registerReporterEvenIfBlocked(in nsIMemoryReporter aReporter);
|
void registerReporterEvenIfBlocked(in nsIMemoryReporter aReporter);
|
||||||
void registerMultiReporterEvenIfBlocked(in nsIMemoryMultiReporter aReporter);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize.
|
* Initialize.
|
||||||
@@ -280,8 +232,8 @@ interface nsIMemoryReporterManager : nsISupports
|
|||||||
* (eg. via mmap, VirtualAlloc) and at the heap level (eg. via malloc,
|
* (eg. via mmap, VirtualAlloc) and at the heap level (eg. via malloc,
|
||||||
* calloc, operator new). (Nb: it covers all heap allocations, but will
|
* calloc, operator new). (Nb: it covers all heap allocations, but will
|
||||||
* miss any OS-level ones not covered by memory reporters.) This reporter
|
* miss any OS-level ones not covered by memory reporters.) This reporter
|
||||||
* is special-cased because it's interesting, and is moderately difficult
|
* is special-cased because it's interesting, and is difficult to compute
|
||||||
* to compute in JS. Accesses can fail.
|
* from JavaScript code. Accesses can fail.
|
||||||
*/
|
*/
|
||||||
readonly attribute int64_t explicit;
|
readonly attribute int64_t explicit;
|
||||||
|
|
||||||
@@ -307,10 +259,7 @@ interface nsIMemoryReporterManager : nsISupports
|
|||||||
// instead of nsCOMPtr<nsIMemoryReporter>.
|
// instead of nsCOMPtr<nsIMemoryReporter>.
|
||||||
|
|
||||||
XPCOM_API(nsresult) NS_RegisterMemoryReporter(nsIMemoryReporter* aReporter);
|
XPCOM_API(nsresult) NS_RegisterMemoryReporter(nsIMemoryReporter* aReporter);
|
||||||
XPCOM_API(nsresult) NS_RegisterMemoryMultiReporter(nsIMemoryMultiReporter* aReporter);
|
|
||||||
|
|
||||||
XPCOM_API(nsresult) NS_UnregisterMemoryReporter(nsIMemoryReporter* aReporter);
|
XPCOM_API(nsresult) NS_UnregisterMemoryReporter(nsIMemoryReporter* aReporter);
|
||||||
XPCOM_API(nsresult) NS_UnregisterMemoryMultiReporter(nsIMemoryMultiReporter* aReporter);
|
|
||||||
|
|
||||||
#if defined(MOZ_DMD)
|
#if defined(MOZ_DMD)
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
@@ -375,10 +324,11 @@ void RunReporters();
|
|||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
// The following base class reduces the amount of boilerplate code required for
|
// The following base class reduces the amount of boilerplate code required for
|
||||||
// memory reporters. You just need to provide the following.
|
// memory uni-reporters. You just need to provide the following.
|
||||||
// - The constant values: path, kind, units, and description. They are passed
|
// - The constant values: nameAndPath (which serves as both the reporters name,
|
||||||
// to the MemoryReporterBase constructor.
|
// and the path in its single report), kind, units, and description. They
|
||||||
// - A (private) Amount() or (public) GetAmount() method. It can use the
|
// are passed to the MemoryUniReporter constructor.
|
||||||
|
// - A (private) Amount() or (public) GetAmount() method. It can use the
|
||||||
// MallocSizeOf method if necessary. (There is also
|
// MallocSizeOf method if necessary. (There is also
|
||||||
// MallocSizeOfOn{Alloc,Free}, which can be useful.) Use Amount() if the
|
// MallocSizeOfOn{Alloc,Free}, which can be useful.) Use Amount() if the
|
||||||
// reporter is infallible, and GetAmount() otherwise. (If you fail to
|
// reporter is infallible, and GetAmount() otherwise. (If you fail to
|
||||||
@@ -390,58 +340,45 @@ namespace mozilla {
|
|||||||
// - "explicit/dom/xyzzy" --> DOMXyzzyReporter
|
// - "explicit/dom/xyzzy" --> DOMXyzzyReporter
|
||||||
// - "js-compartments/system" --> JSCompartmentsSystemReporter
|
// - "js-compartments/system" --> JSCompartmentsSystemReporter
|
||||||
//
|
//
|
||||||
class MemoryReporterBase : public nsIMemoryReporter
|
class MemoryUniReporter : public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MemoryReporterBase(const char* aPath, int32_t aKind, int32_t aUnits,
|
MemoryUniReporter(const char* aNameAndPath, int32_t aKind, int32_t aUnits,
|
||||||
const char* aDescription)
|
const char* aDescription)
|
||||||
: mPath(aPath)
|
: mNameAndPath(aNameAndPath)
|
||||||
, mKind(aKind)
|
, mKind(aKind)
|
||||||
, mUnits(aUnits)
|
, mUnits(aUnits)
|
||||||
, mDescription(aDescription)
|
, mDescription(aDescription)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual ~MemoryReporterBase() {}
|
virtual ~MemoryUniReporter() {}
|
||||||
|
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||||||
|
|
||||||
NS_IMETHOD GetProcess(nsACString& aProcess)
|
NS_IMETHOD GetName(nsACString& aName)
|
||||||
{
|
{
|
||||||
aProcess.Truncate();
|
aName.Assign(mNameAndPath);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHOD GetPath(nsACString& aPath)
|
NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCallback,
|
||||||
|
nsISupports* aClosure)
|
||||||
{
|
{
|
||||||
aPath.Assign(mPath);
|
int64_t amount;
|
||||||
return NS_OK;
|
nsresult rv = GetAmount(&amount);
|
||||||
}
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
NS_IMETHOD GetKind(int32_t* aKind)
|
return aCallback->Callback(EmptyCString(), mNameAndPath, mKind, mUnits,
|
||||||
{
|
amount, mDescription, aClosure);
|
||||||
*aKind = mKind;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHOD GetUnits(int32_t* aUnits)
|
|
||||||
{
|
|
||||||
*aUnits = mUnits;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
NS_IMETHOD GetAmount(int64_t* aAmount)
|
NS_IMETHOD GetAmount(int64_t* aAmount)
|
||||||
{
|
{
|
||||||
*aAmount = Amount();
|
*aAmount = Amount();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHOD GetDescription(nsACString& aDescription)
|
|
||||||
{
|
|
||||||
aDescription.Assign(mDescription);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual int64_t Amount()
|
virtual int64_t Amount()
|
||||||
{
|
{
|
||||||
// We only reach here if neither GetAmount() nor Amount() was overridden.
|
// We only reach here if neither GetAmount() nor Amount() was overridden.
|
||||||
@@ -453,7 +390,7 @@ protected:
|
|||||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_ON_ALLOC_FUN(MallocSizeOfOnAlloc)
|
NS_MEMORY_REPORTER_MALLOC_SIZEOF_ON_ALLOC_FUN(MallocSizeOfOnAlloc)
|
||||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_ON_FREE_FUN(MallocSizeOfOnFree)
|
NS_MEMORY_REPORTER_MALLOC_SIZEOF_ON_FREE_FUN(MallocSizeOfOnFree)
|
||||||
|
|
||||||
const nsCString mPath;
|
const nsCString mNameAndPath;
|
||||||
const int32_t mKind;
|
const int32_t mKind;
|
||||||
const int32_t mUnits;
|
const int32_t mUnits;
|
||||||
const nsCString mDescription;
|
const nsCString mDescription;
|
||||||
|
|||||||
@@ -672,32 +672,35 @@ DumpReport(nsIGZFileWriter *aWriter, bool aIsFirst,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
class DumpMultiReporterCallback MOZ_FINAL : public nsIMemoryMultiReporterCallback
|
class DumpReporterCallback MOZ_FINAL : public nsIMemoryReporterCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
NS_IMETHOD Callback(const nsACString &aProcess, const nsACString &aPath,
|
DumpReporterCallback(bool* aIsFirstPtr) : mIsFirstPtr(aIsFirstPtr) {}
|
||||||
int32_t aKind, int32_t aUnits, int64_t aAmount,
|
|
||||||
const nsACString &aDescription,
|
|
||||||
nsISupports *aData)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIGZFileWriter> writer = do_QueryInterface(aData);
|
|
||||||
NS_ENSURE_TRUE(writer, NS_ERROR_FAILURE);
|
|
||||||
|
|
||||||
// The |isFirst = false| assumes that at least one single reporter is
|
NS_IMETHOD Callback(const nsACString &aProcess, const nsACString &aPath,
|
||||||
// present and so will have been processed in
|
int32_t aKind, int32_t aUnits, int64_t aAmount,
|
||||||
// DumpProcessMemoryReportsToGZFileWriter() below.
|
const nsACString &aDescription,
|
||||||
return DumpReport(writer, /* isFirst = */ false, aProcess, aPath,
|
nsISupports *aData)
|
||||||
aKind, aUnits, aAmount, aDescription);
|
{
|
||||||
return NS_OK;
|
nsCOMPtr<nsIGZFileWriter> writer = do_QueryInterface(aData);
|
||||||
}
|
NS_ENSURE_TRUE(writer, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
// The |isFirst = false| assumes that at least one single reporter is
|
||||||
|
// present and so will have been processed in
|
||||||
|
// DumpProcessMemoryReportsToGZFileWriter() below.
|
||||||
|
bool isFirst = *mIsFirstPtr;
|
||||||
|
*mIsFirstPtr = false;
|
||||||
|
return DumpReport(writer, isFirst, aProcess, aPath, aKind, aUnits, aAmount,
|
||||||
|
aDescription);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool* mIsFirstPtr;
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(
|
NS_IMPL_ISUPPORTS1(DumpReporterCallback, nsIMemoryReporterCallback)
|
||||||
DumpMultiReporterCallback
|
|
||||||
, nsIMemoryMultiReporterCallback
|
|
||||||
)
|
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
@@ -795,8 +798,6 @@ DMDWrite(void* aState, const char* aFmt, va_list ap)
|
|||||||
static nsresult
|
static nsresult
|
||||||
DumpProcessMemoryReportsToGZFileWriter(nsIGZFileWriter *aWriter)
|
DumpProcessMemoryReportsToGZFileWriter(nsIGZFileWriter *aWriter)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
// Increment this number if the format changes.
|
// Increment this number if the format changes.
|
||||||
//
|
//
|
||||||
// This is the first write to the file, and it causes |aWriter| to allocate
|
// This is the first write to the file, and it causes |aWriter| to allocate
|
||||||
@@ -814,53 +815,15 @@ DumpProcessMemoryReportsToGZFileWriter(nsIGZFileWriter *aWriter)
|
|||||||
DUMP(aWriter, ",\n");
|
DUMP(aWriter, ",\n");
|
||||||
DUMP(aWriter, " \"reports\": ");
|
DUMP(aWriter, " \"reports\": ");
|
||||||
|
|
||||||
// Process single reporters.
|
// Process reporters.
|
||||||
bool isFirst = true;
|
bool isFirst = true;
|
||||||
bool more;
|
bool more;
|
||||||
nsCOMPtr<nsISimpleEnumerator> e;
|
nsCOMPtr<nsISimpleEnumerator> e;
|
||||||
mgr->EnumerateReporters(getter_AddRefs(e));
|
mgr->EnumerateReporters(getter_AddRefs(e));
|
||||||
|
nsRefPtr<DumpReporterCallback> cb = new DumpReporterCallback(&isFirst);
|
||||||
while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) {
|
while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) {
|
||||||
nsCOMPtr<nsIMemoryReporter> r;
|
nsCOMPtr<nsIMemoryReporter> r;
|
||||||
e->GetNext(getter_AddRefs(r));
|
e->GetNext(getter_AddRefs(r));
|
||||||
|
|
||||||
nsCString process;
|
|
||||||
rv = r->GetProcess(process);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsCString path;
|
|
||||||
rv = r->GetPath(path);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
int32_t kind;
|
|
||||||
rv = r->GetKind(&kind);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
int32_t units;
|
|
||||||
rv = r->GetUnits(&units);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
int64_t amount;
|
|
||||||
rv = r->GetAmount(&amount);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsCString description;
|
|
||||||
rv = r->GetDescription(description);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = DumpReport(aWriter, isFirst, process, path, kind, units, amount,
|
|
||||||
description);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
isFirst = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process multi-reporters.
|
|
||||||
nsCOMPtr<nsISimpleEnumerator> e2;
|
|
||||||
mgr->EnumerateMultiReporters(getter_AddRefs(e2));
|
|
||||||
nsRefPtr<DumpMultiReporterCallback> cb = new DumpMultiReporterCallback();
|
|
||||||
while (NS_SUCCEEDED(e2->HasMoreElements(&more)) && more) {
|
|
||||||
nsCOMPtr<nsIMemoryMultiReporter> r;
|
|
||||||
e2->GetNext(getter_AddRefs(r));
|
|
||||||
r->CollectReports(cb, aWriter);
|
r->CollectReports(cb, aWriter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -327,11 +327,11 @@ static nsresult GetResidentFast(int64_t* aN)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define HAVE_PRIVATE_REPORTER
|
#define HAVE_PRIVATE_REPORTER
|
||||||
class PrivateReporter MOZ_FINAL : public MemoryReporterBase
|
class PrivateReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PrivateReporter()
|
PrivateReporter()
|
||||||
: MemoryReporterBase("private", KIND_OTHER, UNITS_BYTES,
|
: MemoryUniReporter("private", KIND_OTHER, UNITS_BYTES,
|
||||||
"Memory that cannot be shared with other processes, including memory that is "
|
"Memory that cannot be shared with other processes, including memory that is "
|
||||||
"committed and marked MEM_PRIVATE, data that is not mapped, and executable "
|
"committed and marked MEM_PRIVATE, data that is not mapped, and executable "
|
||||||
"pages that have been written to.")
|
"pages that have been written to.")
|
||||||
@@ -356,11 +356,11 @@ public:
|
|||||||
#endif // XP_<PLATFORM>
|
#endif // XP_<PLATFORM>
|
||||||
|
|
||||||
#ifdef HAVE_VSIZE_AND_RESIDENT_REPORTERS
|
#ifdef HAVE_VSIZE_AND_RESIDENT_REPORTERS
|
||||||
class VsizeReporter MOZ_FINAL : public MemoryReporterBase
|
class VsizeReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VsizeReporter()
|
VsizeReporter()
|
||||||
: MemoryReporterBase("vsize", KIND_OTHER, UNITS_BYTES,
|
: MemoryUniReporter("vsize", KIND_OTHER, UNITS_BYTES,
|
||||||
"Memory mapped by the process, including code and data segments, the heap, "
|
"Memory mapped by the process, including code and data segments, the heap, "
|
||||||
"thread stacks, memory explicitly mapped by the process via mmap and similar "
|
"thread stacks, memory explicitly mapped by the process via mmap and similar "
|
||||||
"operations, and memory shared with other processes. This is the vsize figure "
|
"operations, and memory shared with other processes. This is the vsize figure "
|
||||||
@@ -373,11 +373,11 @@ public:
|
|||||||
NS_IMETHOD GetAmount(int64_t* aAmount) { return GetVsize(aAmount); }
|
NS_IMETHOD GetAmount(int64_t* aAmount) { return GetVsize(aAmount); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class ResidentReporter MOZ_FINAL : public MemoryReporterBase
|
class ResidentReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ResidentReporter()
|
ResidentReporter()
|
||||||
: MemoryReporterBase("resident", KIND_OTHER, UNITS_BYTES,
|
: MemoryUniReporter("resident", KIND_OTHER, UNITS_BYTES,
|
||||||
"Memory mapped by the process that is present in physical memory, also known "
|
"Memory mapped by the process that is present in physical memory, also known "
|
||||||
"as the resident set size (RSS). This is the best single figure to use when "
|
"as the resident set size (RSS). This is the best single figure to use when "
|
||||||
"considering the memory resources used by the process, but it depends both on "
|
"considering the memory resources used by the process, but it depends both on "
|
||||||
@@ -389,11 +389,11 @@ public:
|
|||||||
NS_IMETHOD GetAmount(int64_t* aAmount) { return GetResident(aAmount); }
|
NS_IMETHOD GetAmount(int64_t* aAmount) { return GetResident(aAmount); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class ResidentFastReporter MOZ_FINAL : public MemoryReporterBase
|
class ResidentFastReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ResidentFastReporter()
|
ResidentFastReporter()
|
||||||
: MemoryReporterBase("resident-fast", KIND_OTHER, UNITS_BYTES,
|
: MemoryUniReporter("resident-fast", KIND_OTHER, UNITS_BYTES,
|
||||||
"This is the same measurement as 'resident', but it tries to be as fast as "
|
"This is the same measurement as 'resident', but it tries to be as fast as "
|
||||||
"possible at the expense of accuracy. On most platforms this is identical to "
|
"possible at the expense of accuracy. On most platforms this is identical to "
|
||||||
"the 'resident' measurement, but on Mac it may over-count. You should use "
|
"the 'resident' measurement, but on Mac it may over-count. You should use "
|
||||||
@@ -412,11 +412,11 @@ public:
|
|||||||
|
|
||||||
#define HAVE_PAGE_FAULT_REPORTERS 1
|
#define HAVE_PAGE_FAULT_REPORTERS 1
|
||||||
|
|
||||||
class PageFaultsSoftReporter MOZ_FINAL : public MemoryReporterBase
|
class PageFaultsSoftReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PageFaultsSoftReporter()
|
PageFaultsSoftReporter()
|
||||||
: MemoryReporterBase("page-faults-soft", KIND_OTHER,
|
: MemoryUniReporter("page-faults-soft", KIND_OTHER,
|
||||||
UNITS_COUNT_CUMULATIVE,
|
UNITS_COUNT_CUMULATIVE,
|
||||||
"The number of soft page faults (also known as 'minor page faults') that "
|
"The number of soft page faults (also known as 'minor page faults') that "
|
||||||
"have occurred since the process started. A soft page fault occurs when the "
|
"have occurred since the process started. A soft page fault occurs when the "
|
||||||
@@ -441,11 +441,11 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class PageFaultsHardReporter MOZ_FINAL : public MemoryReporterBase
|
class PageFaultsHardReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PageFaultsHardReporter()
|
PageFaultsHardReporter()
|
||||||
: MemoryReporterBase("page-faults-hard", KIND_OTHER,
|
: MemoryUniReporter("page-faults-hard", KIND_OTHER,
|
||||||
UNITS_COUNT_CUMULATIVE,
|
UNITS_COUNT_CUMULATIVE,
|
||||||
"The number of hard page faults (also known as 'major page faults') that have "
|
"The number of hard page faults (also known as 'major page faults') that have "
|
||||||
"occurred since the process started. A hard page fault occurs when a process "
|
"occurred since the process started. A hard page fault occurs when a process "
|
||||||
@@ -479,11 +479,11 @@ public:
|
|||||||
|
|
||||||
#ifdef HAVE_JEMALLOC_STATS
|
#ifdef HAVE_JEMALLOC_STATS
|
||||||
|
|
||||||
class HeapAllocatedReporter MOZ_FINAL : public MemoryReporterBase
|
class HeapAllocatedReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HeapAllocatedReporter()
|
HeapAllocatedReporter()
|
||||||
: MemoryReporterBase("heap-allocated", KIND_OTHER, UNITS_BYTES,
|
: MemoryUniReporter("heap-allocated", KIND_OTHER, UNITS_BYTES,
|
||||||
"Memory mapped by the heap allocator that is currently allocated to the "
|
"Memory mapped by the heap allocator that is currently allocated to the "
|
||||||
"application. This may exceed the amount of memory requested by the "
|
"application. This may exceed the amount of memory requested by the "
|
||||||
"application because the allocator regularly rounds up request sizes. (The "
|
"application because the allocator regularly rounds up request sizes. (The "
|
||||||
@@ -498,14 +498,14 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class HeapOverheadWasteReporter MOZ_FINAL : public MemoryReporterBase
|
class HeapOverheadWasteReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// We mark this and the other heap-overhead reporters as KIND_NONHEAP
|
// We mark this and the other heap-overhead reporters as KIND_NONHEAP
|
||||||
// because KIND_HEAP memory means "counted in heap-allocated", which this
|
// because KIND_HEAP memory means "counted in heap-allocated", which this
|
||||||
// is not.
|
// is not.
|
||||||
HeapOverheadWasteReporter()
|
HeapOverheadWasteReporter()
|
||||||
: MemoryReporterBase("explicit/heap-overhead/waste",
|
: MemoryUniReporter("explicit/heap-overhead/waste",
|
||||||
KIND_NONHEAP, UNITS_BYTES,
|
KIND_NONHEAP, UNITS_BYTES,
|
||||||
"Committed bytes which do not correspond to an active allocation and which the "
|
"Committed bytes which do not correspond to an active allocation and which the "
|
||||||
"allocator is not intentionally keeping alive (i.e., not 'heap-bookkeeping' or "
|
"allocator is not intentionally keeping alive (i.e., not 'heap-bookkeeping' or "
|
||||||
@@ -522,11 +522,11 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class HeapOverheadBookkeepingReporter MOZ_FINAL : public MemoryReporterBase
|
class HeapOverheadBookkeepingReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HeapOverheadBookkeepingReporter()
|
HeapOverheadBookkeepingReporter()
|
||||||
: MemoryReporterBase("explicit/heap-overhead/bookkeeping",
|
: MemoryUniReporter("explicit/heap-overhead/bookkeeping",
|
||||||
KIND_NONHEAP, UNITS_BYTES,
|
KIND_NONHEAP, UNITS_BYTES,
|
||||||
"Committed bytes which the heap allocator uses for internal data structures.")
|
"Committed bytes which the heap allocator uses for internal data structures.")
|
||||||
{}
|
{}
|
||||||
@@ -539,11 +539,11 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class HeapOverheadPageCacheReporter MOZ_FINAL : public MemoryReporterBase
|
class HeapOverheadPageCacheReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HeapOverheadPageCacheReporter()
|
HeapOverheadPageCacheReporter()
|
||||||
: MemoryReporterBase("explicit/heap-overhead/page-cache",
|
: MemoryUniReporter("explicit/heap-overhead/page-cache",
|
||||||
KIND_NONHEAP, UNITS_BYTES,
|
KIND_NONHEAP, UNITS_BYTES,
|
||||||
"Memory which the allocator could return to the operating system, but hasn't. "
|
"Memory which the allocator could return to the operating system, but hasn't. "
|
||||||
"The allocator keeps this memory around as an optimization, so it doesn't "
|
"The allocator keeps this memory around as an optimization, so it doesn't "
|
||||||
@@ -559,11 +559,11 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class HeapCommittedReporter MOZ_FINAL : public MemoryReporterBase
|
class HeapCommittedReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HeapCommittedReporter()
|
HeapCommittedReporter()
|
||||||
: MemoryReporterBase("heap-committed", KIND_OTHER, UNITS_BYTES,
|
: MemoryUniReporter("heap-committed", KIND_OTHER, UNITS_BYTES,
|
||||||
"Memory mapped by the heap allocator that is committed, i.e. in physical "
|
"Memory mapped by the heap allocator that is committed, i.e. in physical "
|
||||||
"memory or paged to disk. This value corresponds to 'heap-allocated' + "
|
"memory or paged to disk. This value corresponds to 'heap-allocated' + "
|
||||||
"'heap-waste' + 'heap-bookkeeping' + 'heap-page-cache', but because "
|
"'heap-waste' + 'heap-bookkeeping' + 'heap-page-cache', but because "
|
||||||
@@ -580,11 +580,11 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class HeapOverheadRatioReporter MOZ_FINAL : public MemoryReporterBase
|
class HeapOverheadRatioReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HeapOverheadRatioReporter()
|
HeapOverheadRatioReporter()
|
||||||
: MemoryReporterBase("heap-overhead-ratio", KIND_OTHER,
|
: MemoryUniReporter("heap-overhead-ratio", KIND_OTHER,
|
||||||
UNITS_PERCENTAGE,
|
UNITS_PERCENTAGE,
|
||||||
"Ratio of committed, unused bytes to allocated bytes; i.e., "
|
"Ratio of committed, unused bytes to allocated bytes; i.e., "
|
||||||
"'heap-overhead' / 'heap-allocated'. This measures the overhead of "
|
"'heap-overhead' / 'heap-allocated'. This measures the overhead of "
|
||||||
@@ -607,11 +607,11 @@ private:
|
|||||||
// However, the obvious time to register it is when the table is initialized,
|
// However, the obvious time to register it is when the table is initialized,
|
||||||
// and that happens before XPCOM components are initialized, which means the
|
// and that happens before XPCOM components are initialized, which means the
|
||||||
// NS_RegisterMemoryReporter call fails. So instead we do it here.
|
// NS_RegisterMemoryReporter call fails. So instead we do it here.
|
||||||
class AtomTablesReporter MOZ_FINAL : public MemoryReporterBase
|
class AtomTablesReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AtomTablesReporter()
|
AtomTablesReporter()
|
||||||
: MemoryReporterBase("explicit/atom-tables", KIND_HEAP, UNITS_BYTES,
|
: MemoryUniReporter("explicit/atom-tables", KIND_HEAP, UNITS_BYTES,
|
||||||
"Memory used by the dynamic and static atoms tables.")
|
"Memory used by the dynamic and static atoms tables.")
|
||||||
{}
|
{}
|
||||||
private:
|
private:
|
||||||
@@ -623,10 +623,10 @@ private:
|
|||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dmd {
|
namespace dmd {
|
||||||
|
|
||||||
class DMDMultiReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
class DMDReporter MOZ_FINAL : public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DMDMultiReporter()
|
DMDReporter()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
@@ -637,7 +637,7 @@ public:
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback* aCallback,
|
NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCallback,
|
||||||
nsISupports* aClosure)
|
nsISupports* aClosure)
|
||||||
{
|
{
|
||||||
dmd::Sizes sizes;
|
dmd::Sizes sizes;
|
||||||
@@ -677,7 +677,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(DMDMultiReporter, nsIMemoryMultiReporter)
|
NS_IMPL_ISUPPORTS1(DMDReporter, nsIMemoryReporter)
|
||||||
|
|
||||||
} // namespace dmd
|
} // namespace dmd
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
@@ -725,7 +725,7 @@ nsMemoryReporterManager::Init()
|
|||||||
RegisterReporter(new AtomTablesReporter);
|
RegisterReporter(new AtomTablesReporter);
|
||||||
|
|
||||||
#ifdef MOZ_DMD
|
#ifdef MOZ_DMD
|
||||||
RegisterMultiReporter(new mozilla::dmd::DMDMultiReporter);
|
RegisterReporter(new mozilla::dmd::DMDReporter);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(XP_LINUX)
|
#if defined(XP_LINUX)
|
||||||
@@ -803,7 +803,6 @@ nsMemoryReporterManager::nsMemoryReporterManager()
|
|||||||
mIsRegistrationBlocked(false)
|
mIsRegistrationBlocked(false)
|
||||||
{
|
{
|
||||||
mReporters.Init();
|
mReporters.Init();
|
||||||
mMultiReporters.Init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsMemoryReporterManager::~nsMemoryReporterManager()
|
nsMemoryReporterManager::~nsMemoryReporterManager()
|
||||||
@@ -827,23 +826,6 @@ nsMemoryReporterManager::EnumerateReporters(nsISimpleEnumerator** aResult)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsMemoryReporterManager::EnumerateMultiReporters(nsISimpleEnumerator** aResult)
|
|
||||||
{
|
|
||||||
// Memory multi-reporters are not necessarily threadsafe, so
|
|
||||||
// EnumerateMultiReporters() must be called from the main thread.
|
|
||||||
if (!NS_IsMainThread()) {
|
|
||||||
MOZ_CRASH();
|
|
||||||
}
|
|
||||||
|
|
||||||
mozilla::MutexAutoLock autoLock(mMutex);
|
|
||||||
|
|
||||||
nsRefPtr<HashtableEnumerator> enumerator =
|
|
||||||
new HashtableEnumerator(mMultiReporters);
|
|
||||||
enumerator.forget(aResult);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
DebugAssertRefcountIsNonZero(nsISupports* aObj)
|
DebugAssertRefcountIsNonZero(nsISupports* aObj)
|
||||||
{
|
{
|
||||||
@@ -899,41 +881,6 @@ nsMemoryReporterManager::RegisterReporterEvenIfBlocked(
|
|||||||
return RegisterReporterHelper(aReporter, /* force = */ true);
|
return RegisterReporterHelper(aReporter, /* force = */ true);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsMemoryReporterManager::RegisterMultiReporterHelper(
|
|
||||||
nsIMemoryMultiReporter* aReporter, bool aForce)
|
|
||||||
{
|
|
||||||
// This method is thread-safe.
|
|
||||||
mozilla::MutexAutoLock autoLock(mMutex);
|
|
||||||
|
|
||||||
if ((mIsRegistrationBlocked && !aForce) ||
|
|
||||||
mMultiReporters.Contains(aReporter)) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIMemoryMultiReporter> kungFuDeathGrip = aReporter;
|
|
||||||
mMultiReporters.PutEntry(aReporter);
|
|
||||||
}
|
|
||||||
|
|
||||||
DebugAssertRefcountIsNonZero(aReporter);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsMemoryReporterManager::RegisterMultiReporter(nsIMemoryMultiReporter* aReporter)
|
|
||||||
{
|
|
||||||
return RegisterMultiReporterHelper(aReporter, /* force = */ false);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsMemoryReporterManager::RegisterMultiReporterEvenIfBlocked(
|
|
||||||
nsIMemoryMultiReporter* aReporter)
|
|
||||||
{
|
|
||||||
return RegisterMultiReporterHelper(aReporter, /* force = */ true);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsMemoryReporterManager::UnregisterReporter(nsIMemoryReporter* aReporter)
|
nsMemoryReporterManager::UnregisterReporter(nsIMemoryReporter* aReporter)
|
||||||
{
|
{
|
||||||
@@ -948,20 +895,6 @@ nsMemoryReporterManager::UnregisterReporter(nsIMemoryReporter* aReporter)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsMemoryReporterManager::UnregisterMultiReporter(nsIMemoryMultiReporter* aReporter)
|
|
||||||
{
|
|
||||||
// This method is thread-safe.
|
|
||||||
mozilla::MutexAutoLock autoLock(mMutex);
|
|
||||||
|
|
||||||
if (!mMultiReporters.Contains(aReporter)) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
mMultiReporters.RemoveEntry(aReporter);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsMemoryReporterManager::BlockRegistration()
|
nsMemoryReporterManager::BlockRegistration()
|
||||||
{
|
{
|
||||||
@@ -998,7 +931,7 @@ nsMemoryReporterManager::GetResident(int64_t* aResident)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This is just a wrapper for int64_t that implements nsISupports, so it can be
|
// This is just a wrapper for int64_t that implements nsISupports, so it can be
|
||||||
// passed to nsIMemoryMultiReporter::CollectReports.
|
// passed to nsIMemoryReporter::CollectReports.
|
||||||
class Int64Wrapper MOZ_FINAL : public nsISupports {
|
class Int64Wrapper MOZ_FINAL : public nsISupports {
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
@@ -1007,7 +940,7 @@ public:
|
|||||||
};
|
};
|
||||||
NS_IMPL_ISUPPORTS0(Int64Wrapper)
|
NS_IMPL_ISUPPORTS0(Int64Wrapper)
|
||||||
|
|
||||||
class ExplicitNonHeapCountingCallback MOZ_FINAL : public nsIMemoryMultiReporterCallback
|
class ExplicitCallback MOZ_FINAL : public nsIMemoryReporterCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
@@ -1015,23 +948,20 @@ public:
|
|||||||
NS_IMETHOD Callback(const nsACString& aProcess, const nsACString& aPath,
|
NS_IMETHOD Callback(const nsACString& aProcess, const nsACString& aPath,
|
||||||
int32_t aKind, int32_t aUnits, int64_t aAmount,
|
int32_t aKind, int32_t aUnits, int64_t aAmount,
|
||||||
const nsACString& aDescription,
|
const nsACString& aDescription,
|
||||||
nsISupports* aWrappedExplicitNonHeap)
|
nsISupports* aWrappedExplicit)
|
||||||
{
|
{
|
||||||
if (aKind == nsIMemoryReporter::KIND_NONHEAP &&
|
if (aPath.Equals("heap-allocated") ||
|
||||||
PromiseFlatCString(aPath).Find("explicit") == 0 &&
|
(aKind == nsIMemoryReporter::KIND_NONHEAP &&
|
||||||
aAmount != int64_t(-1))
|
PromiseFlatCString(aPath).Find("explicit") == 0))
|
||||||
{
|
{
|
||||||
Int64Wrapper* wrappedPRInt64 =
|
Int64Wrapper* wrappedInt64 =
|
||||||
static_cast<Int64Wrapper*>(aWrappedExplicitNonHeap);
|
static_cast<Int64Wrapper*>(aWrappedExplicit);
|
||||||
wrappedPRInt64->mValue += aAmount;
|
wrappedInt64->mValue += aAmount;
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
NS_IMPL_ISUPPORTS1(
|
NS_IMPL_ISUPPORTS1(ExplicitCallback, nsIMemoryReporterCallback)
|
||||||
ExplicitNonHeapCountingCallback
|
|
||||||
, nsIMemoryMultiReporterCallback
|
|
||||||
)
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsMemoryReporterManager::GetExplicit(int64_t* aExplicit)
|
nsMemoryReporterManager::GetExplicit(int64_t* aExplicit)
|
||||||
@@ -1044,63 +974,25 @@ nsMemoryReporterManager::GetExplicit(int64_t* aExplicit)
|
|||||||
nsresult rv;
|
nsresult rv;
|
||||||
bool more;
|
bool more;
|
||||||
|
|
||||||
// Get "heap-allocated" and all the KIND_NONHEAP measurements from normal
|
// For each reporter we call CollectReports and filter out the
|
||||||
// (i.e. non-multi) "explicit" reporters.
|
// non-explicit, non-NONHEAP measurements (except for "heap-allocated").
|
||||||
int64_t heapAllocated = int64_t(-1);
|
// That's lots of wasted work, and we used to have a GetExplicitNonHeap()
|
||||||
int64_t explicitNonHeapNormalSize = 0;
|
// method which did this more efficiently, but it ended up being more
|
||||||
|
// trouble than it was worth.
|
||||||
|
|
||||||
|
nsRefPtr<ExplicitCallback> cb = new ExplicitCallback();
|
||||||
|
nsRefPtr<Int64Wrapper> wrappedExplicitSize = new Int64Wrapper();
|
||||||
|
|
||||||
nsCOMPtr<nsISimpleEnumerator> e;
|
nsCOMPtr<nsISimpleEnumerator> e;
|
||||||
EnumerateReporters(getter_AddRefs(e));
|
EnumerateReporters(getter_AddRefs(e));
|
||||||
while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) {
|
while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) {
|
||||||
nsCOMPtr<nsIMemoryReporter> r;
|
nsCOMPtr<nsIMemoryReporter> r;
|
||||||
e->GetNext(getter_AddRefs(r));
|
e->GetNext(getter_AddRefs(r));
|
||||||
|
r->CollectReports(cb, wrappedExplicitSize);
|
||||||
int32_t kind;
|
|
||||||
rv = r->GetKind(&kind);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsCString path;
|
|
||||||
rv = r->GetPath(path);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// We're only interested in NONHEAP explicit reporters and
|
|
||||||
// the 'heap-allocated' reporter.
|
|
||||||
if (kind == nsIMemoryReporter::KIND_NONHEAP &&
|
|
||||||
path.Find("explicit") == 0)
|
|
||||||
{
|
|
||||||
// Just skip any NONHEAP reporters that fail, because
|
|
||||||
// "heap-allocated" is the most important one.
|
|
||||||
int64_t amount;
|
|
||||||
rv = r->GetAmount(&amount);
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
explicitNonHeapNormalSize += amount;
|
|
||||||
}
|
|
||||||
} else if (path.Equals("heap-allocated")) {
|
|
||||||
// If we don't have "heap-allocated", give up, because the result
|
|
||||||
// would be horribly inaccurate.
|
|
||||||
rv = r->GetAmount(&heapAllocated);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// For each multi-reporter we call CollectReports and filter out the
|
*aExplicit = wrappedExplicitSize->mValue;
|
||||||
// non-explicit, non-NONHEAP measurements. That's lots of wasted work,
|
|
||||||
// and we used to have a GetExplicitNonHeap() method which did this more
|
|
||||||
// efficiently, but it ended up being more trouble than it was worth.
|
|
||||||
|
|
||||||
nsRefPtr<ExplicitNonHeapCountingCallback> cb =
|
|
||||||
new ExplicitNonHeapCountingCallback();
|
|
||||||
nsRefPtr<Int64Wrapper> wrappedExplicitNonHeapMultiSize =
|
|
||||||
new Int64Wrapper();
|
|
||||||
nsCOMPtr<nsISimpleEnumerator> e2;
|
|
||||||
EnumerateMultiReporters(getter_AddRefs(e2));
|
|
||||||
while (NS_SUCCEEDED(e2->HasMoreElements(&more)) && more) {
|
|
||||||
nsCOMPtr<nsIMemoryMultiReporter> r;
|
|
||||||
e2->GetNext(getter_AddRefs(r));
|
|
||||||
r->CollectReports(cb, wrappedExplicitNonHeapMultiSize);
|
|
||||||
}
|
|
||||||
int64_t explicitNonHeapMultiSize = wrappedExplicitNonHeapMultiSize->mValue;
|
|
||||||
|
|
||||||
*aExplicit = heapAllocated + explicitNonHeapNormalSize + explicitNonHeapMultiSize;
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
#endif // HAVE_JEMALLOC_STATS
|
#endif // HAVE_JEMALLOC_STATS
|
||||||
}
|
}
|
||||||
@@ -1205,7 +1097,7 @@ nsMemoryReporterManager::MinimizeMemoryUsage(nsIRunnable* aCallback,
|
|||||||
// Most memory reporters don't need thread safety, but some do. Make them all
|
// Most memory reporters don't need thread safety, but some do. Make them all
|
||||||
// thread-safe just to be safe. Memory reporters are created and destroyed
|
// thread-safe just to be safe. Memory reporters are created and destroyed
|
||||||
// infrequently enough that the performance cost should be negligible.
|
// infrequently enough that the performance cost should be negligible.
|
||||||
NS_IMPL_ISUPPORTS1(MemoryReporterBase, nsIMemoryReporter)
|
NS_IMPL_ISUPPORTS1(MemoryUniReporter, nsIMemoryReporter)
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
NS_RegisterMemoryReporter(nsIMemoryReporter* aReporter)
|
NS_RegisterMemoryReporter(nsIMemoryReporter* aReporter)
|
||||||
@@ -1217,16 +1109,6 @@ NS_RegisterMemoryReporter(nsIMemoryReporter* aReporter)
|
|||||||
return mgr->RegisterReporter(aReporter);
|
return mgr->RegisterReporter(aReporter);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
|
||||||
NS_RegisterMemoryMultiReporter(nsIMemoryMultiReporter* aReporter)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIMemoryReporterManager> mgr = do_GetService("@mozilla.org/memory-reporter-manager;1");
|
|
||||||
if (!mgr) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
return mgr->RegisterMultiReporter(aReporter);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
NS_UnregisterMemoryReporter(nsIMemoryReporter* aReporter)
|
NS_UnregisterMemoryReporter(nsIMemoryReporter* aReporter)
|
||||||
{
|
{
|
||||||
@@ -1237,22 +1119,12 @@ NS_UnregisterMemoryReporter(nsIMemoryReporter* aReporter)
|
|||||||
return mgr->UnregisterReporter(aReporter);
|
return mgr->UnregisterReporter(aReporter);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
|
||||||
NS_UnregisterMemoryMultiReporter(nsIMemoryMultiReporter* aReporter)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIMemoryReporterManager> mgr = do_GetService("@mozilla.org/memory-reporter-manager;1");
|
|
||||||
if (!mgr) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
return mgr->UnregisterMultiReporter(aReporter);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(MOZ_DMD)
|
#if defined(MOZ_DMD)
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dmd {
|
namespace dmd {
|
||||||
|
|
||||||
class NullMultiReporterCallback : public nsIMemoryMultiReporterCallback
|
class NullReporterCallback : public nsIMemoryReporterCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
@@ -1267,8 +1139,8 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
NS_IMPL_ISUPPORTS1(
|
NS_IMPL_ISUPPORTS1(
|
||||||
NullMultiReporterCallback
|
NullReporterCallback
|
||||||
, nsIMemoryMultiReporterCallback
|
, nsIMemoryReporterCallback
|
||||||
)
|
)
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1277,48 +1149,15 @@ RunReporters()
|
|||||||
nsCOMPtr<nsIMemoryReporterManager> mgr =
|
nsCOMPtr<nsIMemoryReporterManager> mgr =
|
||||||
do_GetService("@mozilla.org/memory-reporter-manager;1");
|
do_GetService("@mozilla.org/memory-reporter-manager;1");
|
||||||
|
|
||||||
// Do vanilla reporters.
|
nsRefPtr<NullReporterCallback> cb = new NullReporterCallback();
|
||||||
|
|
||||||
|
bool more;
|
||||||
nsCOMPtr<nsISimpleEnumerator> e;
|
nsCOMPtr<nsISimpleEnumerator> e;
|
||||||
mgr->EnumerateReporters(getter_AddRefs(e));
|
mgr->EnumerateReporters(getter_AddRefs(e));
|
||||||
bool more;
|
|
||||||
while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) {
|
while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) {
|
||||||
nsCOMPtr<nsIMemoryReporter> r;
|
nsCOMPtr<nsIMemoryReporter> r;
|
||||||
e->GetNext(getter_AddRefs(r));
|
e->GetNext(getter_AddRefs(r));
|
||||||
|
r->CollectReports(cb, nullptr);
|
||||||
int32_t kind;
|
|
||||||
nsresult rv = r->GetKind(&kind);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
nsCString path;
|
|
||||||
rv = r->GetPath(path);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We're only interested in HEAP explicit reporters. (In particular,
|
|
||||||
// some heap blocks are deliberately measured once inside an "explicit"
|
|
||||||
// reporter and once outside, which isn't a problem. This condition
|
|
||||||
// prevents them being reported as double-counted. See bug 811018
|
|
||||||
// comment 2.)
|
|
||||||
if (kind == nsIMemoryReporter::KIND_HEAP &&
|
|
||||||
path.Find("explicit") == 0)
|
|
||||||
{
|
|
||||||
// Just getting the amount is enough for the reporter to report to
|
|
||||||
// DMD.
|
|
||||||
int64_t amount;
|
|
||||||
(void)r->GetAmount(&amount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do multi-reporters.
|
|
||||||
nsCOMPtr<nsISimpleEnumerator> e2;
|
|
||||||
mgr->EnumerateMultiReporters(getter_AddRefs(e2));
|
|
||||||
nsRefPtr<NullMultiReporterCallback> cb = new NullMultiReporterCallback();
|
|
||||||
while (NS_SUCCEEDED(e2->HasMoreElements(&more)) && more) {
|
|
||||||
nsCOMPtr<nsIMemoryMultiReporter> r;
|
|
||||||
e2->GetNext(getter_AddRefs(r));
|
|
||||||
r->CollectReports(cb, nullptr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,11 +24,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
nsresult RegisterReporterHelper(nsIMemoryReporter *reporter, bool aForce);
|
nsresult RegisterReporterHelper(nsIMemoryReporter *reporter, bool aForce);
|
||||||
nsresult RegisterMultiReporterHelper(nsIMemoryMultiReporter *reporter,
|
|
||||||
bool aForce);
|
|
||||||
|
|
||||||
nsTHashtable<nsISupportsHashKey> mReporters;
|
nsTHashtable<nsISupportsHashKey> mReporters;
|
||||||
nsTHashtable<nsISupportsHashKey> mMultiReporters;
|
|
||||||
Mutex mMutex;
|
Mutex mMutex;
|
||||||
bool mIsRegistrationBlocked;
|
bool mIsRegistrationBlocked;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -334,11 +334,11 @@ NS_InitXPCOM(nsIServiceManager* *result,
|
|||||||
return NS_InitXPCOM2(result, binDirectory, nullptr);
|
return NS_InitXPCOM2(result, binDirectory, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
class ICUReporter MOZ_FINAL : public MemoryReporterBase
|
class ICUReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ICUReporter()
|
ICUReporter()
|
||||||
: MemoryReporterBase("explicit/icu", KIND_HEAP, UNITS_BYTES,
|
: MemoryUniReporter("explicit/icu", KIND_HEAP, UNITS_BYTES,
|
||||||
"Memory used by ICU, a Unicode and globalization support library.")
|
"Memory used by ICU, a Unicode and globalization support library.")
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|||||||
@@ -402,11 +402,11 @@ CategoryEnumerator::enumfunc_createenumerator(const char* aStr, CategoryNode* aN
|
|||||||
|
|
||||||
NS_IMPL_QUERY_INTERFACE1(nsCategoryManager, nsICategoryManager)
|
NS_IMPL_QUERY_INTERFACE1(nsCategoryManager, nsICategoryManager)
|
||||||
|
|
||||||
class XPCOMCategoryManagerReporter MOZ_FINAL : public MemoryReporterBase
|
class XPCOMCategoryManagerReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XPCOMCategoryManagerReporter()
|
XPCOMCategoryManagerReporter()
|
||||||
: MemoryReporterBase("explicit/xpcom/category-manager",
|
: MemoryUniReporter("explicit/xpcom/category-manager",
|
||||||
KIND_HEAP, UNITS_BYTES,
|
KIND_HEAP, UNITS_BYTES,
|
||||||
"Memory used for the XPCOM category manager.")
|
"Memory used for the XPCOM category manager.")
|
||||||
{}
|
{}
|
||||||
|
|||||||
@@ -280,11 +280,11 @@ CloneAndAppend(nsIFile* aBase, const nsACString& append)
|
|||||||
// nsComponentManagerImpl
|
// nsComponentManagerImpl
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class XPCOMComponentManagerReporter MOZ_FINAL : public MemoryReporterBase
|
class XPCOMComponentManagerReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XPCOMComponentManagerReporter()
|
XPCOMComponentManagerReporter()
|
||||||
: MemoryReporterBase("explicit/xpcom/component-manager",
|
: MemoryUniReporter("explicit/xpcom/component-manager",
|
||||||
KIND_HEAP, UNITS_BYTES,
|
KIND_HEAP, UNITS_BYTES,
|
||||||
"Memory used for the XPCOM component manager.")
|
"Memory used for the XPCOM component manager.")
|
||||||
{}
|
{}
|
||||||
|
|||||||
@@ -48,18 +48,18 @@ GetObserverServiceLog()
|
|||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
class ObserverServiceReporter MOZ_FINAL : public nsIMemoryMultiReporter
|
class ObserverServiceReporter MOZ_FINAL : public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
NS_DECL_NSIMEMORYMULTIREPORTER
|
NS_DECL_NSIMEMORYREPORTER
|
||||||
protected:
|
protected:
|
||||||
static const size_t kSuspectReferentCount = 1000;
|
static const size_t kSuspectReferentCount = 1000;
|
||||||
static PLDHashOperator CountReferents(nsObserverList* aObserverList,
|
static PLDHashOperator CountReferents(nsObserverList* aObserverList,
|
||||||
void* aClosure);
|
void* aClosure);
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(ObserverServiceReporter, nsIMemoryMultiReporter)
|
NS_IMPL_ISUPPORTS1(ObserverServiceReporter, nsIMemoryReporter)
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
ObserverServiceReporter::GetName(nsACString& aName)
|
ObserverServiceReporter::GetName(nsACString& aName)
|
||||||
@@ -128,7 +128,7 @@ ObserverServiceReporter::CountReferents(nsObserverList* aObserverList,
|
|||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
ObserverServiceReporter::CollectReports(nsIMemoryMultiReporterCallback* cb,
|
ObserverServiceReporter::CollectReports(nsIMemoryReporterCallback* cb,
|
||||||
nsISupports* aClosure)
|
nsISupports* aClosure)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||||
@@ -220,14 +220,14 @@ void
|
|||||||
nsObserverService::RegisterReporter()
|
nsObserverService::RegisterReporter()
|
||||||
{
|
{
|
||||||
mReporter = new ObserverServiceReporter();
|
mReporter = new ObserverServiceReporter();
|
||||||
NS_RegisterMemoryMultiReporter(mReporter);
|
NS_RegisterMemoryReporter(mReporter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsObserverService::Shutdown()
|
nsObserverService::Shutdown()
|
||||||
{
|
{
|
||||||
if (mReporter) {
|
if (mReporter) {
|
||||||
NS_UnregisterMemoryMultiReporter(mReporter);
|
NS_UnregisterMemoryReporter(mReporter);
|
||||||
}
|
}
|
||||||
|
|
||||||
mShuttingDown = true;
|
mShuttingDown = true;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
#define NS_OBSERVERSERVICE_CID \
|
#define NS_OBSERVERSERVICE_CID \
|
||||||
{ 0xd07f5195, 0xe3d1, 0x11d2, { 0x8a, 0xcd, 0x0, 0x10, 0x5a, 0x1b, 0x88, 0x60 } }
|
{ 0xd07f5195, 0xe3d1, 0x11d2, { 0x8a, 0xcd, 0x0, 0x10, 0x5a, 0x1b, 0x88, 0x60 } }
|
||||||
|
|
||||||
class nsIMemoryMultiReporter;
|
class nsIMemoryReporter;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
class ObserverServiceReporter;
|
class ObserverServiceReporter;
|
||||||
@@ -47,7 +47,7 @@ private:
|
|||||||
|
|
||||||
bool mShuttingDown;
|
bool mShuttingDown;
|
||||||
nsTHashtable<nsObserverList> mObserverTopicTable;
|
nsTHashtable<nsObserverList> mObserverTopicTable;
|
||||||
nsCOMPtr<nsIMemoryMultiReporter> mReporter;
|
nsCOMPtr<nsIMemoryReporter> mReporter;
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsObserverService, NS_OBSERVERSERVICE_CID)
|
NS_DEFINE_STATIC_IID_ACCESSOR(nsObserverService, NS_OBSERVERSERVICE_CID)
|
||||||
|
|||||||
@@ -40,11 +40,11 @@ XPTInterfaceInfoManager::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf)
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
class XPTIWorkingSetReporter MOZ_FINAL : public MemoryReporterBase
|
class XPTIWorkingSetReporter MOZ_FINAL : public MemoryUniReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XPTIWorkingSetReporter()
|
XPTIWorkingSetReporter()
|
||||||
: MemoryReporterBase("explicit/xpti-working-set", KIND_HEAP, UNITS_BYTES,
|
: MemoryUniReporter("explicit/xpti-working-set", KIND_HEAP, UNITS_BYTES,
|
||||||
"Memory used by the XPCOM typelib system.")
|
"Memory used by the XPCOM typelib system.")
|
||||||
{}
|
{}
|
||||||
private:
|
private:
|
||||||
|
|||||||
Reference in New Issue
Block a user