mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 13:55:43 +00:00
Bug 913260 (part 2) - Tweak ghost window reporters. r=mccr8.
This commit is contained in:
parent
12216d4f00
commit
0069cbfda7
@ -9,8 +9,10 @@
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIEffectiveTLDService.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "XPCJSMemoryReporter.h"
|
||||
@ -19,6 +21,8 @@
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
StaticRefPtr<nsWindowMemoryReporter> sWindowReporter;
|
||||
|
||||
nsWindowMemoryReporter::nsWindowMemoryReporter()
|
||||
: mCheckForGhostWindowsCallbackPending(false)
|
||||
{
|
||||
@ -31,27 +35,22 @@ NS_IMPL_ISUPPORTS3(nsWindowMemoryReporter, nsIMemoryReporter, nsIObserver,
|
||||
void
|
||||
nsWindowMemoryReporter::Init()
|
||||
{
|
||||
// The memory reporter manager will own this object.
|
||||
nsRefPtr<nsWindowMemoryReporter> windowReporter = new nsWindowMemoryReporter();
|
||||
NS_RegisterMemoryReporter(windowReporter);
|
||||
MOZ_ASSERT(!sWindowReporter);
|
||||
sWindowReporter = new nsWindowMemoryReporter();
|
||||
ClearOnShutdown(&sWindowReporter);
|
||||
NS_RegisterMemoryReporter(sWindowReporter);
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
||||
if (os) {
|
||||
// DOM_WINDOW_DESTROYED_TOPIC announces what we call window "detachment",
|
||||
// when a window's docshell is set to NULL.
|
||||
os->AddObserver(windowReporter, DOM_WINDOW_DESTROYED_TOPIC,
|
||||
os->AddObserver(sWindowReporter, DOM_WINDOW_DESTROYED_TOPIC,
|
||||
/* weakRef = */ true);
|
||||
os->AddObserver(windowReporter, "after-minimize-memory-usage",
|
||||
os->AddObserver(sWindowReporter, "after-minimize-memory-usage",
|
||||
/* weakRef = */ true);
|
||||
}
|
||||
|
||||
nsRefPtr<GhostURLsReporter> ghostURLsReporter =
|
||||
new GhostURLsReporter(windowReporter);
|
||||
NS_RegisterMemoryReporter(ghostURLsReporter);
|
||||
|
||||
nsRefPtr<NumGhostsReporter> numGhostsReporter =
|
||||
new NumGhostsReporter(windowReporter);
|
||||
NS_RegisterMemoryReporter(numGhostsReporter);
|
||||
NS_RegisterMemoryReporter(new GhostWindowsReporter());
|
||||
}
|
||||
|
||||
static already_AddRefed<nsIURI>
|
||||
@ -311,6 +310,52 @@ GetWindows(const uint64_t& aId, nsGlobalWindow*& aWindow, void* aClosure)
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
struct ReportGhostWindowsEnumeratorData
|
||||
{
|
||||
nsIMemoryReporterCallback* callback;
|
||||
nsISupports* closure;
|
||||
nsresult rv;
|
||||
};
|
||||
|
||||
static PLDHashOperator
|
||||
ReportGhostWindowsEnumerator(nsUint64HashKey* aIDHashKey, void* aClosure)
|
||||
{
|
||||
ReportGhostWindowsEnumeratorData *data =
|
||||
static_cast<ReportGhostWindowsEnumeratorData*>(aClosure);
|
||||
|
||||
nsGlobalWindow::WindowByIdTable* windowsById =
|
||||
nsGlobalWindow::GetWindowsTable();
|
||||
if (!windowsById) {
|
||||
NS_WARNING("Couldn't get window-by-id hashtable?");
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
nsGlobalWindow* window = windowsById->Get(aIDHashKey->GetKey());
|
||||
if (!window) {
|
||||
NS_WARNING("Could not look up window?");
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
nsAutoCString path;
|
||||
path.AppendLiteral("ghost-windows/");
|
||||
AppendWindowURI(window, path);
|
||||
|
||||
nsresult rv = data->callback->Callback(
|
||||
/* process = */ EmptyCString(),
|
||||
path,
|
||||
nsIMemoryReporter::KIND_OTHER,
|
||||
nsIMemoryReporter::UNITS_COUNT,
|
||||
/* amount = */ 1,
|
||||
/* description = */ NS_LITERAL_CSTRING("A ghost window."),
|
||||
data->closure);
|
||||
|
||||
if (NS_FAILED(rv) && NS_SUCCEEDED(data->rv)) {
|
||||
data->rv = rv;
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowMemoryReporter::GetName(nsACString &aName)
|
||||
{
|
||||
@ -331,12 +376,18 @@ nsWindowMemoryReporter::CollectReports(nsIMemoryReporterCallback* aCb,
|
||||
WindowArray windows;
|
||||
windowsById->Enumerate(GetWindows, &windows);
|
||||
|
||||
// Get the IDs of all the "ghost" windows.
|
||||
// Get the IDs of all the "ghost" windows, and call aCb->Callback() for each
|
||||
// one.
|
||||
nsTHashtable<nsUint64HashKey> ghostWindows;
|
||||
CheckForGhostWindows(&ghostWindows);
|
||||
ReportGhostWindowsEnumeratorData reportGhostWindowsEnumData =
|
||||
{ aCb, aClosure, NS_OK };
|
||||
ghostWindows.EnumerateEntries(ReportGhostWindowsEnumerator,
|
||||
&reportGhostWindowsEnumData);
|
||||
nsresult rv = reportGhostWindowsEnumData.rv;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
WindowPaths windowPaths;
|
||||
|
||||
WindowPaths topWindowPaths;
|
||||
|
||||
// Collect window memory usage.
|
||||
@ -344,17 +395,17 @@ nsWindowMemoryReporter::CollectReports(nsIMemoryReporterCallback* aCb,
|
||||
nsCOMPtr<amIAddonManager> addonManager =
|
||||
do_GetService("@mozilla.org/addons/integration;1");
|
||||
for (uint32_t i = 0; i < windows.Length(); i++) {
|
||||
nsresult rv = CollectWindowReports(windows[i], addonManager,
|
||||
&windowTotalSizes, &ghostWindows,
|
||||
&windowPaths, &topWindowPaths, aCb,
|
||||
aClosure);
|
||||
rv = CollectWindowReports(windows[i], addonManager,
|
||||
&windowTotalSizes, &ghostWindows,
|
||||
&windowPaths, &topWindowPaths, aCb,
|
||||
aClosure);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// Report JS memory usage. We do this from here because the JS memory
|
||||
// reporter needs to be passed |windowPaths|.
|
||||
nsresult rv = xpc::JSReporter::CollectReports(&windowPaths, &topWindowPaths,
|
||||
aCb, aClosure);
|
||||
rv = xpc::JSReporter::CollectReports(&windowPaths, &topWindowPaths,
|
||||
aCb, aClosure);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
#define REPORT(_path, _amount, _desc) \
|
||||
@ -662,94 +713,10 @@ nsWindowMemoryReporter::CheckForGhostWindows(
|
||||
&ghostEnumData);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsWindowMemoryReporter::GhostURLsReporter,
|
||||
nsIMemoryReporter)
|
||||
|
||||
nsWindowMemoryReporter::
|
||||
GhostURLsReporter::GhostURLsReporter(
|
||||
nsWindowMemoryReporter* aWindowReporter)
|
||||
: mWindowReporter(aWindowReporter)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowMemoryReporter::
|
||||
GhostURLsReporter::GetName(nsACString& aName)
|
||||
{
|
||||
aName.AssignLiteral("ghost-windows-multi");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
struct ReportGhostWindowsEnumeratorData
|
||||
{
|
||||
nsIMemoryReporterCallback* callback;
|
||||
nsISupports* closure;
|
||||
nsresult rv;
|
||||
};
|
||||
|
||||
static PLDHashOperator
|
||||
ReportGhostWindowsEnumerator(nsUint64HashKey* aIDHashKey, void* aClosure)
|
||||
{
|
||||
ReportGhostWindowsEnumeratorData *data =
|
||||
static_cast<ReportGhostWindowsEnumeratorData*>(aClosure);
|
||||
|
||||
nsGlobalWindow::WindowByIdTable* windowsById =
|
||||
nsGlobalWindow::GetWindowsTable();
|
||||
if (!windowsById) {
|
||||
NS_WARNING("Couldn't get window-by-id hashtable?");
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
nsGlobalWindow* window = windowsById->Get(aIDHashKey->GetKey());
|
||||
if (!window) {
|
||||
NS_WARNING("Could not look up window?");
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
nsAutoCString path;
|
||||
path.AppendLiteral("ghost-windows/");
|
||||
AppendWindowURI(window, path);
|
||||
|
||||
nsresult rv = data->callback->Callback(
|
||||
/* process = */ EmptyCString(),
|
||||
path,
|
||||
nsIMemoryReporter::KIND_OTHER,
|
||||
nsIMemoryReporter::UNITS_COUNT,
|
||||
/* amount = */ 1,
|
||||
/* description = */ NS_LITERAL_CSTRING("A ghost window."),
|
||||
data->closure);
|
||||
|
||||
if (NS_FAILED(rv) && NS_SUCCEEDED(data->rv)) {
|
||||
data->rv = rv;
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowMemoryReporter::
|
||||
GhostURLsReporter::CollectReports(
|
||||
nsIMemoryReporterCallback* aCb,
|
||||
nsISupports* aClosure)
|
||||
{
|
||||
// Get the IDs of all the ghost windows in existance.
|
||||
nsTHashtable<nsUint64HashKey> ghostWindows;
|
||||
mWindowReporter->CheckForGhostWindows(&ghostWindows);
|
||||
|
||||
ReportGhostWindowsEnumeratorData reportGhostWindowsEnumData =
|
||||
{ aCb, aClosure, NS_OK };
|
||||
|
||||
// Call aCb->Callback() for each ghost window.
|
||||
ghostWindows.EnumerateEntries(ReportGhostWindowsEnumerator,
|
||||
&reportGhostWindowsEnumData);
|
||||
|
||||
return reportGhostWindowsEnumData.rv;
|
||||
}
|
||||
|
||||
int64_t
|
||||
nsWindowMemoryReporter::NumGhostsReporter::Amount()
|
||||
nsWindowMemoryReporter::GhostWindowsReporter::Amount()
|
||||
{
|
||||
nsTHashtable<nsUint64HashKey> ghostWindows;
|
||||
mWindowReporter->CheckForGhostWindows(&ghostWindows);
|
||||
sWindowReporter->CheckForGhostWindows(&ghostWindows);
|
||||
return ghostWindows.Count();
|
||||
}
|
||||
|
@ -120,31 +120,14 @@ public:
|
||||
static void Init();
|
||||
|
||||
private:
|
||||
/**
|
||||
* 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 nsIMemoryReporter
|
||||
{
|
||||
public:
|
||||
GhostURLsReporter(nsWindowMemoryReporter* aWindowReporter);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMEMORYREPORTER
|
||||
|
||||
private:
|
||||
nsRefPtr<nsWindowMemoryReporter> mWindowReporter;
|
||||
};
|
||||
|
||||
/**
|
||||
* nsGhostWindowReporter generates the "ghost-windows" report, which counts
|
||||
* the number of ghost windows present.
|
||||
*/
|
||||
class NumGhostsReporter MOZ_FINAL : public mozilla::MemoryUniReporter
|
||||
class GhostWindowsReporter MOZ_FINAL : public mozilla::MemoryUniReporter
|
||||
{
|
||||
public:
|
||||
NumGhostsReporter(nsWindowMemoryReporter* aWindowReporter)
|
||||
GhostWindowsReporter()
|
||||
: 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 "
|
||||
@ -154,13 +137,10 @@ private:
|
||||
"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)
|
||||
{}
|
||||
|
||||
private:
|
||||
int64_t Amount() MOZ_OVERRIDE;
|
||||
|
||||
nsRefPtr<nsWindowMemoryReporter> mWindowReporter;
|
||||
};
|
||||
|
||||
// Protect ctor, use Init() instead.
|
||||
|
Loading…
Reference in New Issue
Block a user