☠☠ backed out by 1d72ff0f809f ☠ ☠ | |
author | Nicholas Nethercote <nnethercote@mozilla.com> |
Wed, 18 Sep 2013 19:01:29 -0700 | |
changeset 148607 | 8a8691a260121ee5863f44ce3883507e177db417 |
parent 148606 | 5cf98b6e4b18708957bfaa43a573f241f8b99943 |
child 148608 | 09c71a3e7b85211747236c168ec6524fe57c352b |
push id | 25349 |
push user | ryanvm@gmail.com |
push date | Wed, 25 Sep 2013 18:52:12 +0000 |
treeherder | mozilla-central@39f30376058c [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mccr8 |
bugs | 913260 |
milestone | 27.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
dom/base/nsWindowMemoryReporter.cpp | file | annotate | diff | comparison | revisions | |
dom/base/nsWindowMemoryReporter.h | file | annotate | diff | comparison | revisions |
--- a/dom/base/nsWindowMemoryReporter.cpp +++ b/dom/base/nsWindowMemoryReporter.cpp @@ -4,59 +4,58 @@ * 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/. */ #include "amIAddonManager.h" #include "nsWindowMemoryReporter.h" #include "nsGlobalWindow.h" #include "nsIDocument.h" #include "nsIEffectiveTLDService.h" +#include "mozilla/ClearOnShutdown.h" +#include "mozilla/Preferences.h" #include "mozilla/Services.h" -#include "mozilla/Preferences.h" +#include "mozilla/StaticPtr.h" #include "nsNetCID.h" #include "nsPrintfCString.h" #include "XPCJSMemoryReporter.h" #include "js/MemoryMetrics.h" #include "nsServiceManagerUtils.h" using namespace mozilla; +StaticRefPtr<nsWindowMemoryReporter> sWindowReporter; + nsWindowMemoryReporter::nsWindowMemoryReporter() : mCheckForGhostWindowsCallbackPending(false) { } NS_IMPL_ISUPPORTS3(nsWindowMemoryReporter, nsIMemoryReporter, nsIObserver, nsSupportsWeakReference) /* static */ 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> GetWindowURI(nsIDOMWindow *aWindow) { nsCOMPtr<nsPIDOMWindow> pWindow = do_QueryInterface(aWindow); NS_ENSURE_TRUE(pWindow, nullptr); @@ -306,16 +305,62 @@ static PLDHashOperator GetWindows(const uint64_t& aId, nsGlobalWindow*& aWindow, void* aClosure) { ((WindowArray *)aClosure)->AppendElement(aWindow); 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) { aName.AssignLiteral("window-objects"); return NS_OK; } NS_IMETHODIMP @@ -326,40 +371,46 @@ nsWindowMemoryReporter::CollectReports(n nsGlobalWindow::GetWindowsTable(); NS_ENSURE_TRUE(windowsById, NS_OK); // Hold on to every window in memory so that window objects can't be // destroyed while we're calling the memory reporter callback. 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. nsWindowSizes windowTotalSizes(NULL); 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) \ do { \ nsresult rv; \ rv = aCb->Callback(EmptyCString(), NS_LITERAL_CSTRING(_path), \ nsIMemoryReporter::KIND_OTHER, \ nsIMemoryReporter::UNITS_BYTES, _amount, \ @@ -657,99 +708,15 @@ nsWindowMemoryReporter::CheckForGhostWin // if it's not null. CheckForGhostWindowsEnumeratorData ghostEnumData = { &nonDetachedWindowDomains, aOutGhostIDs, tldService, GetGhostTimeout(), TimeStamp::Now() }; mDetachedWindows.Enumerate(CheckForGhostWindowsEnumerator, &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(); }
--- a/dom/base/nsWindowMemoryReporter.h +++ b/dom/base/nsWindowMemoryReporter.h @@ -116,56 +116,36 @@ public: NS_DECL_ISUPPORTS NS_DECL_NSIMEMORYREPORTER NS_DECL_NSIOBSERVER 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 " "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) {} private: int64_t Amount() MOZ_OVERRIDE; - - nsRefPtr<nsWindowMemoryReporter> mWindowReporter; }; // Protect ctor, use Init() instead. nsWindowMemoryReporter(); /** * Get the number of seconds for which a window must satisfy ghost criteria * (1) and (2) before we deem that it satisfies criterion (3).