Bug 910517 (3rd attempt) - Remove nsIMemoryReporter, and rename nsIMemoryMultiReporter as nsIMemoryReporter. r=mmcr8.

--HG--
rename : content/canvas/src/WebGLMemoryMultiReporterWrapper.h => content/canvas/src/WebGLMemoryReporterWrapper.h
extra : rebase_source : 2b2a1b2667d6562fcf803ec48b4a8c10fdd519a3
This commit is contained in:
Nicholas Nethercote 2013-08-27 16:24:51 -07:00
Родитель 6b5008db95
Коммит 7983bb2a7f
67 изменённых файлов: 859 добавлений и 1299 удалений

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

4
netwerk/cache/nsDiskCacheDevice.cpp поставляемый
Просмотреть файл

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

4
netwerk/cache/nsMemoryCacheDevice.cpp поставляемый
Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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