Bug 633305 - about:memory should display memory reporters that live in the child process r=cjones a=blocking-fennec

--HG--
extra : rebase_source : adf4e4f912ac6cab8c48b91da35e22a2b3ba0916
This commit is contained in:
Doug Turner 2011-02-16 10:43:23 -08:00
Родитель 5b67f3c803
Коммит 56bc86a196
11 изменённых файлов: 329 добавлений и 5 удалений

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

@ -59,7 +59,7 @@
#include "mozilla/dom/PCrashReporterChild.h"
#include "nsAudioStream.h"
#include "nsIMemoryReporter.h"
#include "nsIObserverService.h"
#include "nsTObserverArray.h"
#include "nsIObserver.h"
@ -82,6 +82,7 @@
#include "nsFrameMessageManager.h"
#include "nsIGeolocationProvider.h"
#include "mozilla/dom/PMemoryReportRequestChild.h"
#ifdef MOZ_PERMISSIONS
#include "nsPermission.h"
@ -101,6 +102,24 @@ using namespace mozilla::docshell;
namespace mozilla {
namespace dom {
class MemoryReportRequestChild : public PMemoryReportRequestChild
{
public:
MemoryReportRequestChild();
virtual ~MemoryReportRequestChild();
};
MemoryReportRequestChild::MemoryReportRequestChild()
{
MOZ_COUNT_CTOR(MemoryReportRequestChild);
}
MemoryReportRequestChild::~MemoryReportRequestChild()
{
MOZ_COUNT_DTOR(MemoryReportRequestChild);
}
class AlertObserver
{
public:
@ -260,6 +279,53 @@ ContentChild::InitXPCOM()
NS_WARNING("Couldn't register console listener for child process");
}
PMemoryReportRequestChild*
ContentChild::AllocPMemoryReportRequest()
{
return new MemoryReportRequestChild();
}
bool
ContentChild::RecvPMemoryReportRequestConstructor(PMemoryReportRequestChild* child)
{
InfallibleTArray<MemoryReport> reports;
nsCOMPtr<nsIMemoryReporterManager> mgr = do_GetService("@mozilla.org/memory-reporter-manager;1");
nsCOMPtr<nsISimpleEnumerator> r;
mgr->EnumerateReporters(getter_AddRefs(r));
PRBool more;
while (NS_SUCCEEDED(r->HasMoreElements(&more)) && more) {
nsCOMPtr<nsIMemoryReporter> report;
r->GetNext(getter_AddRefs(report));
nsCString path;
nsCString desc;
PRInt64 memoryUsed;
report->GetPath(getter_Copies(path));
report->GetDescription(getter_Copies(desc));
report->GetMemoryUsed(&memoryUsed);
MemoryReport memreport(nsPrintfCString("Content Process - %d - ", getpid()),
path,
desc,
memoryUsed);
reports.AppendElement(memreport);
}
child->Send__delete__(child, reports);
return true;
}
bool
ContentChild::DeallocPMemoryReportRequest(PMemoryReportRequestChild* actor)
{
delete actor;
return true;
}
PBrowserChild*
ContentChild::AllocPBrowser(const PRUint32& aChromeFlags)
{

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

@ -83,6 +83,15 @@ public:
virtual PCrashReporterChild* AllocPCrashReporter();
virtual bool DeallocPCrashReporter(PCrashReporterChild*);
virtual PMemoryReportRequestChild*
AllocPMemoryReportRequest();
virtual bool
DeallocPMemoryReportRequest(PMemoryReportRequestChild* actor);
virtual bool
RecvPMemoryReportRequestConstructor(PMemoryReportRequestChild* child);
virtual PTestShellChild* AllocPTestShell();
virtual bool DeallocPTestShell(PTestShellChild*);
virtual bool RecvPTestShellConstructor(PTestShellChild*);

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

@ -88,6 +88,10 @@
#include "mozilla/dom/StorageParent.h"
#include "nsAccelerometer.h"
#include "nsIMemoryReporter.h"
#include "nsMemoryReporterManager.h"
#include "mozilla/dom/PMemoryReportRequestParent.h"
#ifdef ANDROID
#include "gfxAndroidPlatform.h"
#endif
@ -103,6 +107,38 @@ namespace dom {
#define NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC "ipc:network:set-offline"
class MemoryReportRequestParent : public PMemoryReportRequestParent
{
public:
MemoryReportRequestParent();
virtual ~MemoryReportRequestParent();
virtual bool Recv__delete__(const InfallibleTArray<MemoryReport>& report);
private:
ContentParent* Owner()
{
return static_cast<ContentParent*>(Manager());
}
};
MemoryReportRequestParent::MemoryReportRequestParent()
{
MOZ_COUNT_CTOR(MemoryReportRequestParent);
}
bool
MemoryReportRequestParent::Recv__delete__(const InfallibleTArray<MemoryReport>& report)
{
Owner()->SetChildMemoryReporters(report);
return true;
}
MemoryReportRequestParent::~MemoryReportRequestParent()
{
MOZ_COUNT_DTOR(MemoryReportRequestParent);
}
ContentParent* ContentParent::gSingleton;
ContentParent*
@ -129,6 +165,7 @@ ContentParent::GetSingleton(PRBool aForceNew)
obs->AddObserver(
parent, NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC, PR_FALSE);
obs->AddObserver(parent, "child-memory-reporter-request", PR_FALSE);
obs->AddObserver(parent, "memory-pressure", PR_FALSE);
}
nsCOMPtr<nsIThreadInternal>
@ -197,10 +234,14 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
if (obs) {
obs->RemoveObserver(static_cast<nsIObserver*>(this), "xpcom-shutdown");
obs->RemoveObserver(static_cast<nsIObserver*>(this), "memory-pressure");
obs->RemoveObserver(static_cast<nsIObserver*>(this),
NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC);
obs->RemoveObserver(static_cast<nsIObserver*>(this), "child-memory-reporter-request");
obs->RemoveObserver(static_cast<nsIObserver*>(this), NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC);
}
// clear the child memory reporters
InfallibleTArray<MemoryReport> empty;
SetChildMemoryReporters(empty);
// remove the global remote preferences observers
nsCOMPtr<nsIPrefBranch2> prefs
(do_GetService(NS_PREFSERVICE_CONTRACTID));
@ -464,6 +505,10 @@ ContentParent::Observe(nsISupports* aSubject,
nsDependentString(aData)))
return NS_ERROR_NOT_AVAILABLE;
}
else if (!strcmp(aTopic, "child-memory-reporter-request")) {
SendPMemoryReportRequestConstructor();
}
return NS_OK;
}
@ -498,6 +543,48 @@ ContentParent::DeallocPCrashReporter(PCrashReporterParent* crashreporter)
return true;
}
PMemoryReportRequestParent*
ContentParent::AllocPMemoryReportRequest()
{
MemoryReportRequestParent* parent = new MemoryReportRequestParent();
return parent;
}
bool
ContentParent::DeallocPMemoryReportRequest(PMemoryReportRequestParent* actor)
{
delete actor;
return true;
}
void
ContentParent::SetChildMemoryReporters(const InfallibleTArray<MemoryReport>& report)
{
nsCOMPtr<nsIMemoryReporterManager> mgr = do_GetService("@mozilla.org/memory-reporter-manager;1");
for (PRUint32 i = 0; i < mMemoryReporters.Count(); i++)
mgr->UnregisterReporter(mMemoryReporters[i]);
for (PRUint32 i = 0; i < report.Length(); i++) {
nsCString prefix = report[i].prefix();
nsCString path = report[i].path();
nsCString desc = report[i].desc();
PRInt64 memoryUsed = report[i].memoryUsed();
nsRefPtr<nsMemoryReporter> r = new nsMemoryReporter(prefix,
path,
desc,
memoryUsed);
mMemoryReporters.AppendObject(r);
mgr->RegisterReporter(r);
}
nsCOMPtr<nsIObserverService> obs =
do_GetService("@mozilla.org/observer-service;1");
if (obs)
obs->NotifyObservers(nsnull, "child-memory-reporter-update", nsnull);
}
PTestShellParent*
ContentParent::AllocPTestShell()
{

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

@ -42,6 +42,7 @@
#include "base/waitable_event_watcher.h"
#include "mozilla/dom/PContentParent.h"
#include "mozilla/dom/PMemoryReportRequestParent.h"
#include "mozilla/ipc/GeckoChildProcessHost.h"
#include "nsIObserver.h"
@ -52,6 +53,8 @@
#include "nsIPermissionManager.h"
#include "nsIDOMGeoPositionCallback.h"
#include "nsIAccelerometer.h"
#include "nsIMemoryReporter.h"
#include "nsCOMArray.h"
namespace mozilla {
@ -98,6 +101,8 @@ public:
bool IsAlive();
void SetChildMemoryReporters(const InfallibleTArray<MemoryReport>& report);
protected:
void OnChannelConnected(int32 pid);
virtual void ActorDestroy(ActorDestroyReason why);
@ -119,6 +124,9 @@ private:
virtual PCrashReporterParent* AllocPCrashReporter();
virtual bool DeallocPCrashReporter(PCrashReporterParent* crashreporter);
virtual PMemoryReportRequestParent* AllocPMemoryReportRequest();
virtual bool DeallocPMemoryReportRequest(PMemoryReportRequestParent* actor);
virtual PTestShellParent* AllocPTestShell();
virtual bool DeallocPTestShell(PTestShellParent* shell);
@ -202,6 +210,12 @@ private:
bool mShouldCallUnblockChild;
nsCOMPtr<nsIThreadObserver> mOldObserver;
// 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;
bool mIsAlive;
nsCOMPtr<nsIPrefServiceInternal> mPrefService;
time_t mProcessStartTime;

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

@ -43,6 +43,7 @@ include protocol PTestShell;
include protocol PNecko;
include protocol PExternalHelperApp;
include protocol PStorage;
include protocol PMemoryReportRequest;
include "mozilla/chrome/RegistryMessageUtils.h";
include "mozilla/net/NeckoMessageUtils.h";
@ -96,10 +97,13 @@ rpc protocol PContent
manages PNecko;
manages PExternalHelperApp;
manages PStorage;
manages PMemoryReportRequest;
child:
PBrowser(PRUint32 chromeFlags);
PMemoryReportRequest();
PTestShell();
RegisterChrome(ChromePackage[] packages, ResourceMapping[] resources,

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

@ -0,0 +1,59 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Memory Reporting IPC
*
* The Initial Developer of the Original Code is
* The Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Doug Turner <dougt@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
include protocol PContent;
namespace mozilla {
namespace dom {
struct MemoryReport {
nsCString prefix;
nsCString path;
nsCString desc;
PRInt64 memoryUsed;
};
protocol PMemoryReportRequest {
manager PContent;
parent:
__delete__(MemoryReport[] report);
};
}
}

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

@ -42,4 +42,5 @@ IPDLSRCS = \
PCrashReporter.ipdl \
PDocumentRenderer.ipdl \
PContentPermissionRequest.ipdl \
PMemoryReportRequest.ipdl \
$(NULL)

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

@ -139,6 +139,7 @@ function updateMemoryStatus()
mo.removeChild(mo.lastChild);
var otherCount = 0;
for each (var rep in gMemReporters) {
var row = makeTableRow([rep.path, rep.description],
makeTableCell(formatNumber(rep.memoryUsed), "memValue"));
@ -154,8 +155,10 @@ function updateMemoryStatus()
}
}
function doLoad()
function updateMemoryReporters()
{
gMemReporters = [];
var mgr = Components
.classes["@mozilla.org/memory-reporter-manager;1"]
.getService(Components.interfaces.nsIMemoryReporterManager);
@ -165,7 +168,30 @@ function doLoad()
var mr = e.getNext().QueryInterface(Components.interfaces.nsIMemoryReporter);
gMemReporters[mr.path] = mr;
}
}
function ChildMemoryListener(subject, topic, data) {
updateMemoryReporters();
updateMemoryStatus();
}
function doLoad()
{
var os = Components.classes["@mozilla.org/observer-service;1"].
getService(Components.interfaces.nsIObserverService);
os.notifyObservers(null, "child-memory-reporter-request", null);
os.addObserver(ChildMemoryListener, "child-memory-reporter-update", false);
updateMemoryReporters();
updateMemoryStatus();
}
function doUnload()
{
var os = Components.classes["@mozilla.org/observer-service;1"].
getService(Components.interfaces.nsIObserverService);
os.removeObserver(ChildMemoryListener, "child-memory-reporter-update");
}

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

@ -48,7 +48,7 @@
src="chrome://global/content/aboutMemory.js"/>
</head>
<body onload="doLoad()">
<body onload="doLoad()" onunload="doUnload()">
<h1>Memory Usage</h1>
<div id="memOverview" class="memOverview memBox">

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

@ -288,6 +288,45 @@ nsMemoryReporterManager::UnregisterReporter(nsIMemoryReporter *reporter)
return NS_OK;
}
NS_IMPL_ISUPPORTS1(nsMemoryReporter, nsIMemoryReporter)
nsMemoryReporter::nsMemoryReporter(nsCString& prefix,
nsCString& path,
nsCString& desc,
PRInt64 memoryUsed)
: mDesc(desc)
, mMemoryUsed(memoryUsed)
{
if (!prefix.IsEmpty()) {
mPath.Append(prefix);
mPath.Append(NS_LITERAL_CSTRING(" - "));
}
mPath.Append(path);
}
nsMemoryReporter::~nsMemoryReporter()
{
}
NS_IMETHODIMP nsMemoryReporter::GetPath(char **aPath)
{
*aPath = strdup(mPath.get());
return NS_OK;
}
NS_IMETHODIMP nsMemoryReporter::GetDescription(char **aDescription)
{
*aDescription = strdup(mDesc.get());
return NS_OK;
}
NS_IMETHODIMP nsMemoryReporter::GetMemoryUsed(PRInt64 *aMemoryUsed)
{
*aMemoryUsed = mMemoryUsed;
return NS_OK;
}
NS_COM nsresult
NS_RegisterMemoryReporter (nsIMemoryReporter *reporter)
{

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

@ -5,6 +5,25 @@
using mozilla::Mutex;
class nsMemoryReporter : public nsIMemoryReporter
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIMEMORYREPORTER
nsMemoryReporter(nsCString& prefix,
nsCString& path,
nsCString& desc,
PRInt64 memoryUsed);
~nsMemoryReporter();
protected:
nsCString mPath, mDesc;
PRInt64 mMemoryUsed;
};
class nsMemoryReporterManager : public nsIMemoryReporterManager
{
public: