2013-01-18 09:21:43 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* 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/. */
|
2011-06-29 15:01:07 +04:00
|
|
|
|
2013-06-15 06:48:28 +04:00
|
|
|
#include "amIAddonManager.h"
|
2012-02-24 06:43:33 +04:00
|
|
|
#include "nsWindowMemoryReporter.h"
|
2017-08-10 07:14:09 +03:00
|
|
|
#include "nsWindowSizes.h"
|
2011-06-29 15:06:43 +04:00
|
|
|
#include "nsGlobalWindow.h"
|
2013-03-22 04:05:20 +04:00
|
|
|
#include "nsIDocument.h"
|
2013-10-23 01:53:26 +04:00
|
|
|
#include "nsIDOMWindowCollection.h"
|
2013-09-19 06:01:29 +04:00
|
|
|
#include "mozilla/ClearOnShutdown.h"
|
2013-09-25 07:31:00 +04:00
|
|
|
#include "mozilla/Preferences.h"
|
2013-09-19 06:01:29 +04:00
|
|
|
#include "mozilla/Services.h"
|
|
|
|
#include "mozilla/StaticPtr.h"
|
2012-04-03 06:28:04 +04:00
|
|
|
#include "nsNetCID.h"
|
|
|
|
#include "nsPrintfCString.h"
|
2012-07-06 08:12:37 +04:00
|
|
|
#include "XPCJSMemoryReporter.h"
|
2013-08-13 21:51:50 +04:00
|
|
|
#include "js/MemoryMetrics.h"
|
2016-06-09 13:42:21 +03:00
|
|
|
#include "nsQueryObject.h"
|
2013-08-15 22:17:48 +04:00
|
|
|
#include "nsServiceManagerUtils.h"
|
2018-02-19 13:07:44 +03:00
|
|
|
#ifdef MOZ_XUL
|
|
|
|
#include "nsXULPrototypeCache.h"
|
|
|
|
#endif
|
2011-06-29 15:01:07 +04:00
|
|
|
|
2012-04-03 06:28:04 +04:00
|
|
|
using namespace mozilla;
|
2011-06-29 15:01:07 +04:00
|
|
|
|
2013-09-19 06:01:29 +04:00
|
|
|
StaticRefPtr<nsWindowMemoryReporter> sWindowReporter;
|
|
|
|
|
2014-03-08 17:38:52 +04:00
|
|
|
/**
|
|
|
|
* Don't trigger a ghost window check when a DOM window is detached if we've
|
|
|
|
* run it this recently.
|
|
|
|
*/
|
|
|
|
const int32_t kTimeBetweenChecks = 45; /* seconds */
|
|
|
|
|
2012-02-24 06:43:33 +04:00
|
|
|
nsWindowMemoryReporter::nsWindowMemoryReporter()
|
2014-03-08 17:38:53 +04:00
|
|
|
: mLastCheckForGhostWindows(TimeStamp::NowLoRes()),
|
|
|
|
mCycleCollectorIsRunning(false),
|
2017-07-11 23:58:20 +03:00
|
|
|
mCheckTimerWaitingForCCEnd(false),
|
|
|
|
mGhostWindowCount(0)
|
2014-03-08 17:38:52 +04:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
nsWindowMemoryReporter::~nsWindowMemoryReporter()
|
2011-06-29 15:01:07 +04:00
|
|
|
{
|
2014-03-08 17:38:52 +04:00
|
|
|
KillCheckTimer();
|
2011-06-29 15:01:07 +04:00
|
|
|
}
|
|
|
|
|
2014-04-27 11:06:00 +04:00
|
|
|
NS_IMPL_ISUPPORTS(nsWindowMemoryReporter, nsIMemoryReporter, nsIObserver,
|
|
|
|
nsISupportsWeakReference)
|
2011-06-29 15:01:07 +04:00
|
|
|
|
2013-10-23 01:53:26 +04:00
|
|
|
static nsresult
|
2017-11-06 22:48:02 +03:00
|
|
|
AddNonJSSizeOfWindowAndItsDescendents(nsGlobalWindowOuter* aWindow,
|
2013-10-23 01:53:26 +04:00
|
|
|
nsTabSizes* aSizes)
|
|
|
|
{
|
|
|
|
// Measure the window.
|
2017-07-28 13:10:04 +03:00
|
|
|
SizeOfState state(moz_malloc_size_of);
|
|
|
|
nsWindowSizes windowSizes(state);
|
2017-08-10 07:13:22 +03:00
|
|
|
aWindow->AddSizeOfIncludingThis(windowSizes);
|
2013-10-23 01:53:26 +04:00
|
|
|
|
|
|
|
// Measure the inner window, if there is one.
|
2017-11-06 22:48:02 +03:00
|
|
|
nsGlobalWindowInner* inner = aWindow->GetCurrentInnerWindowInternal();
|
2013-10-23 01:53:26 +04:00
|
|
|
if (inner) {
|
2017-08-10 07:13:22 +03:00
|
|
|
inner->AddSizeOfIncludingThis(windowSizes);
|
2013-10-23 01:53:26 +04:00
|
|
|
}
|
|
|
|
|
2017-07-28 13:10:04 +03:00
|
|
|
windowSizes.addToTabSizes(aSizes);
|
|
|
|
|
2015-10-27 00:37:32 +03:00
|
|
|
nsCOMPtr<nsIDOMWindowCollection> frames = aWindow->GetFrames();
|
2013-10-23 01:53:26 +04:00
|
|
|
|
|
|
|
uint32_t length;
|
2015-10-27 00:37:32 +03:00
|
|
|
nsresult rv = frames->GetLength(&length);
|
2013-10-23 01:53:26 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
// Measure this window's descendents.
|
|
|
|
for (uint32_t i = 0; i < length; i++) {
|
2016-01-30 20:05:36 +03:00
|
|
|
nsCOMPtr<mozIDOMWindowProxy> child;
|
2013-10-23 01:53:26 +04:00
|
|
|
rv = frames->Item(i, getter_AddRefs(child));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
NS_ENSURE_STATE(child);
|
|
|
|
|
2017-11-06 22:48:02 +03:00
|
|
|
nsGlobalWindowOuter* childWin = nsGlobalWindowOuter::Cast(child);
|
2013-10-23 01:53:26 +04:00
|
|
|
|
|
|
|
rv = AddNonJSSizeOfWindowAndItsDescendents(childWin, aSizes);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
2016-01-30 20:05:36 +03:00
|
|
|
NonJSSizeOfTab(nsPIDOMWindowOuter* aWindow, size_t* aDomSize, size_t* aStyleSize, size_t* aOtherSize)
|
2013-10-23 01:53:26 +04:00
|
|
|
{
|
2017-11-04 01:25:38 +03:00
|
|
|
nsGlobalWindowOuter* window = nsGlobalWindowOuter::Cast(aWindow);
|
2013-10-23 01:53:26 +04:00
|
|
|
|
|
|
|
nsTabSizes sizes;
|
|
|
|
nsresult rv = AddNonJSSizeOfWindowAndItsDescendents(window, &sizes);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
*aDomSize = sizes.mDom;
|
|
|
|
*aStyleSize = sizes.mStyle;
|
|
|
|
*aOtherSize = sizes.mOther;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ void
|
2012-02-24 06:43:33 +04:00
|
|
|
nsWindowMemoryReporter::Init()
|
2011-06-29 15:01:07 +04:00
|
|
|
{
|
2013-09-19 06:01:29 +04:00
|
|
|
MOZ_ASSERT(!sWindowReporter);
|
|
|
|
sWindowReporter = new nsWindowMemoryReporter();
|
|
|
|
ClearOnShutdown(&sWindowReporter);
|
2013-11-07 09:35:30 +04:00
|
|
|
RegisterStrongMemoryReporter(sWindowReporter);
|
2013-10-23 01:53:26 +04:00
|
|
|
RegisterNonJSSizeOfTab(NonJSSizeOfTab);
|
2012-04-03 06:28:04 +04:00
|
|
|
|
|
|
|
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
|
|
|
if (os) {
|
2013-09-19 06:01:29 +04:00
|
|
|
os->AddObserver(sWindowReporter, "after-minimize-memory-usage",
|
2012-04-03 06:28:05 +04:00
|
|
|
/* weakRef = */ true);
|
2014-03-08 17:38:53 +04:00
|
|
|
os->AddObserver(sWindowReporter, "cycle-collector-begin",
|
|
|
|
/* weakRef = */ true);
|
|
|
|
os->AddObserver(sWindowReporter, "cycle-collector-end",
|
|
|
|
/* weakRef = */ true);
|
2012-04-03 06:28:04 +04:00
|
|
|
}
|
2012-04-03 06:28:05 +04:00
|
|
|
|
2017-09-07 02:06:58 +03:00
|
|
|
RegisterGhostWindowsDistinguishedAmount(GhostWindowsDistinguishedAmount);
|
2011-06-29 15:01:07 +04:00
|
|
|
}
|
|
|
|
|
2016-01-22 21:27:54 +03:00
|
|
|
/* static */ nsWindowMemoryReporter*
|
|
|
|
nsWindowMemoryReporter::Get()
|
|
|
|
{
|
|
|
|
return sWindowReporter;
|
|
|
|
}
|
|
|
|
|
2012-04-03 06:28:04 +04:00
|
|
|
static already_AddRefed<nsIURI>
|
2017-11-06 22:48:02 +03:00
|
|
|
GetWindowURI(nsGlobalWindowInner* aWindow)
|
2011-06-29 15:01:07 +04:00
|
|
|
{
|
2016-01-30 20:05:36 +03:00
|
|
|
NS_ENSURE_TRUE(aWindow, nullptr);
|
2012-04-03 06:28:04 +04:00
|
|
|
|
2016-01-30 20:05:36 +03:00
|
|
|
nsCOMPtr<nsIDocument> doc = aWindow->GetExtantDoc();
|
2011-12-09 09:42:20 +04:00
|
|
|
nsCOMPtr<nsIURI> uri;
|
2011-06-29 15:01:07 +04:00
|
|
|
|
2011-12-09 09:42:20 +04:00
|
|
|
if (doc) {
|
|
|
|
uri = doc->GetDocumentURI();
|
|
|
|
}
|
2011-06-29 15:01:07 +04:00
|
|
|
|
2011-12-09 09:42:20 +04:00
|
|
|
if (!uri) {
|
2012-04-03 06:28:04 +04:00
|
|
|
nsCOMPtr<nsIScriptObjectPrincipal> scriptObjPrincipal =
|
2016-01-30 20:05:36 +03:00
|
|
|
do_QueryObject(aWindow);
|
2013-04-28 15:52:10 +04:00
|
|
|
NS_ENSURE_TRUE(scriptObjPrincipal, nullptr);
|
2012-04-03 06:28:04 +04:00
|
|
|
|
2012-10-09 23:17:53 +04:00
|
|
|
// GetPrincipal() will print a warning if the window does not have an outer
|
|
|
|
// window, so check here for an outer window first. This code is
|
|
|
|
// functionally correct if we leave out the GetOuterWindow() check, but we
|
|
|
|
// end up printing a lot of warnings during debug mochitests.
|
2016-01-30 20:05:36 +03:00
|
|
|
if (aWindow->GetOuterWindow()) {
|
2012-10-09 23:17:53 +04:00
|
|
|
nsIPrincipal* principal = scriptObjPrincipal->GetPrincipal();
|
|
|
|
if (principal) {
|
|
|
|
principal->GetURI(getter_AddRefs(uri));
|
|
|
|
}
|
2011-12-09 09:42:20 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-03 06:28:04 +04:00
|
|
|
return uri.forget();
|
|
|
|
}
|
|
|
|
|
2017-11-06 22:48:02 +03:00
|
|
|
// Forward to the inner window if we need to when getting the window's URI.
|
|
|
|
static already_AddRefed<nsIURI>
|
|
|
|
GetWindowURI(nsGlobalWindowOuter* aWindow)
|
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(aWindow, nullptr);
|
|
|
|
return GetWindowURI(aWindow->GetCurrentInnerWindowInternal());
|
|
|
|
}
|
|
|
|
|
2012-04-03 06:28:04 +04:00
|
|
|
static void
|
2017-11-06 22:48:02 +03:00
|
|
|
AppendWindowURI(nsGlobalWindowInner *aWindow, nsACString& aStr, bool aAnonymize)
|
2012-04-03 06:28:04 +04:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIURI> uri = GetWindowURI(aWindow);
|
|
|
|
|
2012-03-13 10:00:18 +04:00
|
|
|
if (uri) {
|
2014-05-21 10:06:54 +04:00
|
|
|
if (aAnonymize && !aWindow->IsChromeWindow()) {
|
2016-12-14 19:32:21 +03:00
|
|
|
aStr.AppendPrintf("<anonymized-%" PRIu64 ">", aWindow->WindowID());
|
2014-05-21 10:06:54 +04:00
|
|
|
} else {
|
2016-08-26 09:02:31 +03:00
|
|
|
nsCString spec = uri->GetSpecOrDefault();
|
2011-12-09 09:42:20 +04:00
|
|
|
|
2014-05-21 10:06:54 +04:00
|
|
|
// A hack: replace forward slashes with '\\' so they aren't
|
|
|
|
// treated as path separators. Users of the reporters
|
|
|
|
// (such as about:memory) have to undo this change.
|
|
|
|
spec.ReplaceChar('/', '\\');
|
2011-12-09 09:42:20 +04:00
|
|
|
|
2014-05-21 10:06:54 +04:00
|
|
|
aStr += spec;
|
|
|
|
}
|
2012-03-13 10:00:18 +04:00
|
|
|
} else {
|
2012-04-03 06:28:04 +04:00
|
|
|
// If we're unable to find a URI, we're dealing with a chrome window with
|
|
|
|
// no document in it (or somesuch), so we call this a "system window".
|
2012-03-13 10:00:18 +04:00
|
|
|
aStr += NS_LITERAL_CSTRING("[system]");
|
|
|
|
}
|
2011-06-29 15:01:07 +04:00
|
|
|
}
|
2011-06-29 15:06:43 +04:00
|
|
|
|
2013-12-08 09:38:32 +04:00
|
|
|
MOZ_DEFINE_MALLOC_SIZE_OF(WindowsMallocSizeOf)
|
2011-12-09 09:42:20 +04:00
|
|
|
|
2012-07-06 08:12:37 +04:00
|
|
|
// The key is the window ID.
|
|
|
|
typedef nsDataHashtable<nsUint64HashKey, nsCString> WindowPaths;
|
|
|
|
|
2016-08-24 08:23:45 +03:00
|
|
|
static void
|
2014-01-10 19:15:53 +04:00
|
|
|
ReportAmount(const nsCString& aBasePath, const char* aPathTail,
|
|
|
|
size_t aAmount, const nsCString& aDescription,
|
|
|
|
uint32_t aKind, uint32_t aUnits,
|
2016-08-24 08:23:45 +03:00
|
|
|
nsIHandleReportCallback* aHandleReport,
|
|
|
|
nsISupports* aData)
|
2014-01-10 19:15:53 +04:00
|
|
|
{
|
|
|
|
if (aAmount == 0) {
|
2016-08-24 08:23:45 +03:00
|
|
|
return;
|
2014-01-10 19:15:53 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
nsAutoCString path(aBasePath);
|
|
|
|
path += aPathTail;
|
|
|
|
|
2016-08-24 08:23:45 +03:00
|
|
|
aHandleReport->Callback(
|
|
|
|
EmptyCString(), path, aKind, aUnits, aAmount, aDescription, aData);
|
2014-01-10 19:15:53 +04:00
|
|
|
}
|
|
|
|
|
2016-08-24 08:23:45 +03:00
|
|
|
static void
|
2014-01-10 19:15:53 +04:00
|
|
|
ReportSize(const nsCString& aBasePath, const char* aPathTail,
|
|
|
|
size_t aAmount, const nsCString& aDescription,
|
2016-08-24 08:23:45 +03:00
|
|
|
nsIHandleReportCallback* aHandleReport,
|
|
|
|
nsISupports* aData)
|
2014-01-10 19:15:53 +04:00
|
|
|
{
|
2016-08-24 08:23:45 +03:00
|
|
|
ReportAmount(aBasePath, aPathTail, aAmount, aDescription,
|
|
|
|
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
|
|
|
|
aHandleReport, aData);
|
2014-01-10 19:15:53 +04:00
|
|
|
}
|
|
|
|
|
2016-08-24 08:23:45 +03:00
|
|
|
static void
|
2014-01-10 19:15:53 +04:00
|
|
|
ReportCount(const nsCString& aBasePath, const char* aPathTail,
|
|
|
|
size_t aAmount, const nsCString& aDescription,
|
2016-08-24 08:23:45 +03:00
|
|
|
nsIHandleReportCallback* aHandleReport,
|
|
|
|
nsISupports* aData)
|
2014-01-10 19:15:53 +04:00
|
|
|
{
|
2016-08-24 08:23:45 +03:00
|
|
|
ReportAmount(aBasePath, aPathTail, aAmount, aDescription,
|
|
|
|
nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT,
|
|
|
|
aHandleReport, aData);
|
2014-01-10 19:15:53 +04:00
|
|
|
}
|
|
|
|
|
2016-08-24 08:23:45 +03:00
|
|
|
static void
|
2017-11-06 22:48:02 +03:00
|
|
|
CollectWindowReports(nsGlobalWindowInner *aWindow,
|
2013-06-15 06:48:28 +04:00
|
|
|
amIAddonManager *addonManager,
|
2012-02-21 19:10:11 +04:00
|
|
|
nsWindowSizes *aWindowTotalSizes,
|
2012-04-03 06:28:04 +04:00
|
|
|
nsTHashtable<nsUint64HashKey> *aGhostWindowIDs,
|
2012-07-06 08:12:37 +04:00
|
|
|
WindowPaths *aWindowPaths,
|
2013-03-17 07:36:37 +04:00
|
|
|
WindowPaths *aTopWindowPaths,
|
2016-08-24 08:23:45 +03:00
|
|
|
nsIHandleReportCallback *aHandleReport,
|
|
|
|
nsISupports *aData,
|
2014-05-21 10:06:54 +04:00
|
|
|
bool aAnonymize)
|
2012-01-03 06:19:14 +04:00
|
|
|
{
|
2014-01-08 05:02:23 +04:00
|
|
|
nsAutoCString windowPath("explicit/");
|
2012-04-02 18:37:04 +04:00
|
|
|
|
2012-04-03 06:28:04 +04:00
|
|
|
// Avoid calling aWindow->GetTop() if there's no outer window. It will work
|
|
|
|
// just fine, but will spew a lot of warnings.
|
2017-11-06 22:48:02 +03:00
|
|
|
nsGlobalWindowOuter *top = nullptr;
|
2013-06-15 06:48:28 +04:00
|
|
|
nsCOMPtr<nsIURI> location;
|
2012-04-03 06:28:04 +04:00
|
|
|
if (aWindow->GetOuterWindow()) {
|
|
|
|
// Our window should have a null top iff it has a null docshell.
|
2015-10-27 00:37:32 +03:00
|
|
|
MOZ_ASSERT(!!aWindow->GetTopInternal() == !!aWindow->GetDocShell());
|
|
|
|
top = aWindow->GetTopInternal();
|
2013-06-15 06:48:28 +04:00
|
|
|
if (top) {
|
|
|
|
location = GetWindowURI(top);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!location) {
|
|
|
|
location = GetWindowURI(aWindow);
|
|
|
|
}
|
|
|
|
|
2013-06-30 20:39:10 +04:00
|
|
|
if (addonManager && location) {
|
2013-06-15 06:48:28 +04:00
|
|
|
bool ok;
|
|
|
|
nsAutoCString id;
|
|
|
|
if (NS_SUCCEEDED(addonManager->MapURIToAddonID(location, id, &ok)) && ok) {
|
2014-05-21 10:06:54 +04:00
|
|
|
// Add-on names are not privacy-sensitive, so we can use them with
|
|
|
|
// impunity.
|
2013-06-15 06:48:28 +04:00
|
|
|
windowPath += NS_LITERAL_CSTRING("add-ons/") + id +
|
|
|
|
NS_LITERAL_CSTRING("/");
|
|
|
|
}
|
2012-04-03 06:28:04 +04:00
|
|
|
}
|
|
|
|
|
2013-06-15 06:48:28 +04:00
|
|
|
windowPath += NS_LITERAL_CSTRING("window-objects/");
|
|
|
|
|
2012-03-13 10:00:18 +04:00
|
|
|
if (top) {
|
2012-04-03 06:28:04 +04:00
|
|
|
windowPath += NS_LITERAL_CSTRING("top(");
|
2017-11-06 22:48:02 +03:00
|
|
|
AppendWindowURI(top->GetCurrentInnerWindowInternal(), windowPath, aAnonymize);
|
2016-12-14 19:32:21 +03:00
|
|
|
windowPath.AppendPrintf(", id=%" PRIu64 ")", top->WindowID());
|
2011-12-09 09:42:20 +04:00
|
|
|
|
2013-03-17 07:36:37 +04:00
|
|
|
aTopWindowPaths->Put(aWindow->WindowID(), windowPath);
|
|
|
|
|
|
|
|
windowPath += aWindow->IsFrozen() ? NS_LITERAL_CSTRING("/cached/")
|
|
|
|
: NS_LITERAL_CSTRING("/active/");
|
2011-12-09 09:42:20 +04:00
|
|
|
} else {
|
2012-04-03 06:28:04 +04:00
|
|
|
if (aGhostWindowIDs->Contains(aWindow->WindowID())) {
|
|
|
|
windowPath += NS_LITERAL_CSTRING("top(none)/ghost/");
|
|
|
|
} else {
|
|
|
|
windowPath += NS_LITERAL_CSTRING("top(none)/detached/");
|
|
|
|
}
|
2011-12-09 09:42:20 +04:00
|
|
|
}
|
|
|
|
|
2012-03-13 10:00:18 +04:00
|
|
|
windowPath += NS_LITERAL_CSTRING("window(");
|
2014-05-21 10:06:54 +04:00
|
|
|
AppendWindowURI(aWindow, windowPath, aAnonymize);
|
2012-03-13 10:00:18 +04:00
|
|
|
windowPath += NS_LITERAL_CSTRING(")");
|
|
|
|
|
2014-01-08 05:02:23 +04:00
|
|
|
// Use |windowPath|, but replace "explicit/" with "event-counts/".
|
|
|
|
nsCString censusWindowPath(windowPath);
|
2017-09-16 05:22:58 +03:00
|
|
|
censusWindowPath.ReplaceLiteral(0, strlen("explicit"), "event-counts");
|
2013-10-28 13:47:18 +04:00
|
|
|
|
2012-07-06 08:12:37 +04:00
|
|
|
// Remember the path for later.
|
2014-01-08 05:02:23 +04:00
|
|
|
aWindowPaths->Put(aWindow->WindowID(), windowPath);
|
2012-07-06 08:12:37 +04:00
|
|
|
|
2017-09-25 02:59:50 +03:00
|
|
|
// Report the size from windowSizes and add to the appropriate total in
|
|
|
|
// aWindowTotalSizes.
|
|
|
|
#define REPORT_SIZE(_pathTail, _field, _desc) \
|
|
|
|
ReportSize(windowPath, _pathTail, windowSizes._field, \
|
|
|
|
NS_LITERAL_CSTRING(_desc), aHandleReport, aData); \
|
|
|
|
aWindowTotalSizes->_field += windowSizes._field;
|
|
|
|
|
|
|
|
// Report the size, which is a sum of other sizes, and so doesn't require
|
|
|
|
// updating aWindowTotalSizes.
|
|
|
|
#define REPORT_SUM_SIZE(_pathTail, _amount, _desc) \
|
2016-08-24 08:23:45 +03:00
|
|
|
ReportSize(windowPath, _pathTail, _amount, NS_LITERAL_CSTRING(_desc), \
|
|
|
|
aHandleReport, aData);
|
2013-10-28 13:47:18 +04:00
|
|
|
|
2017-09-25 02:59:50 +03:00
|
|
|
// Like REPORT_SIZE, but for a count.
|
|
|
|
#define REPORT_COUNT(_pathTail, _field, _desc) \
|
|
|
|
ReportCount(censusWindowPath, _pathTail, windowSizes._field, \
|
|
|
|
NS_LITERAL_CSTRING(_desc), aHandleReport, aData); \
|
|
|
|
aWindowTotalSizes->_field += windowSizes._field;
|
2012-02-21 19:10:11 +04:00
|
|
|
|
2017-07-28 13:10:04 +03:00
|
|
|
// This SizeOfState contains the SeenPtrs used for all memory reporting of
|
|
|
|
// this window.
|
|
|
|
SizeOfState state(WindowsMallocSizeOf);
|
|
|
|
nsWindowSizes windowSizes(state);
|
2017-08-10 07:13:22 +03:00
|
|
|
aWindow->AddSizeOfIncludingThis(windowSizes);
|
2012-03-13 10:00:18 +04:00
|
|
|
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SIZE("/dom/element-nodes", mDOMElementNodesSize,
|
2013-10-28 13:47:18 +04:00
|
|
|
"Memory used by the element nodes in a window's DOM.");
|
|
|
|
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SIZE("/dom/text-nodes", mDOMTextNodesSize,
|
2013-10-28 13:47:18 +04:00
|
|
|
"Memory used by the text nodes in a window's DOM.");
|
|
|
|
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SIZE("/dom/cdata-nodes", mDOMCDATANodesSize,
|
2013-10-28 13:47:18 +04:00
|
|
|
"Memory used by the CDATA nodes in a window's DOM.");
|
|
|
|
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SIZE("/dom/comment-nodes", mDOMCommentNodesSize,
|
2013-10-28 13:47:18 +04:00
|
|
|
"Memory used by the comment nodes in a window's DOM.");
|
|
|
|
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SIZE("/dom/event-targets", mDOMEventTargetsSize,
|
2013-10-28 13:47:18 +04:00
|
|
|
"Memory used by the event targets table in a window's DOM, and "
|
|
|
|
"the objects it points to, which include XHRs.");
|
|
|
|
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SIZE("/dom/performance/user-entries", mDOMPerformanceUserEntries,
|
2017-08-25 07:43:29 +03:00
|
|
|
"Memory used for performance user entries.");
|
2013-10-28 13:47:18 +04:00
|
|
|
|
2017-08-25 07:43:29 +03:00
|
|
|
REPORT_SIZE("/dom/performance/resource-entries",
|
2017-09-25 02:59:50 +03:00
|
|
|
mDOMPerformanceResourceEntries,
|
2017-08-25 07:43:29 +03:00
|
|
|
"Memory used for performance resource entries.");
|
2013-10-28 13:47:18 +04:00
|
|
|
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SIZE("/dom/other", mDOMOtherSize,
|
2013-10-28 13:47:18 +04:00
|
|
|
"Memory used by a window's DOM that isn't measured by the "
|
|
|
|
"other 'dom/' numbers.");
|
|
|
|
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SIZE("/layout/style-sheets", mLayoutStyleSheetsSize,
|
2013-10-28 13:47:18 +04:00
|
|
|
"Memory used by style sheets within a window.");
|
|
|
|
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SIZE("/layout/pres-shell", mLayoutPresShellSize,
|
2013-10-28 13:47:18 +04:00
|
|
|
"Memory used by layout's PresShell, along with any structures "
|
|
|
|
"allocated in its arena and not measured elsewhere, "
|
|
|
|
"within a window.");
|
|
|
|
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SIZE("/layout/gecko-style-sets", mLayoutGeckoStyleSets,
|
2017-08-30 11:21:26 +03:00
|
|
|
"Memory used by Gecko style sets within a window.");
|
|
|
|
|
|
|
|
REPORT_SIZE("/layout/servo-style-sets/stylist/rule-tree",
|
2017-09-25 02:59:50 +03:00
|
|
|
mLayoutServoStyleSetsStylistRuleTree,
|
2017-08-30 11:21:26 +03:00
|
|
|
"Memory used by rule trees within Servo style sets within a "
|
|
|
|
"window.");
|
|
|
|
|
Bug 1387958 - Measure the stylist during memory reporting. r=heycam.
Example output from the Obama Wikipedia page:
> ├──2,315,600 B (01.16%) -- stylist
> │ ├──1,916,928 B (00.96%) ── invalidation-map
> │ ├────228,800 B (00.11%) ── rule-tree
> │ ├────142,336 B (00.07%) ── element-and-pseudos-maps
> │ ├─────14,336 B (00.01%) ── revalidation-selectors
> │ ├──────9,648 B (00.00%) ── other
> │ └──────3,552 B (00.00%) ── precomputed-pseudos
This change requires new code to measure HashMaps, which uses the new
'malloc_enclosing_size_of' functions that can measure a heap block from an
interior pointer.
The patch changes MallocSizeOfFn to a newtype, and introduces
MallocEnclosingSizeOfFn alongside.
It also adds new traits: MallocSizeOfBox, MallocSizeOfVec, MallocSizeOfHash.
These each contain a single method that does shallow measurement of the
relevant type, which is often useful. (This is a different style to the
existing MallocSizeOf trait, which does deep measurement, but I'm moving away
from the always-deep-measurement style because it's less flexible.)
MozReview-Commit-ID: FgJCCmdw0ZF
--HG--
extra : rebase_source : c692c2073aa66020224489b97247c49de95a99a4
2017-09-05 04:38:45 +03:00
|
|
|
REPORT_SIZE("/layout/servo-style-sets/stylist/element-and-pseudos-maps",
|
2017-09-25 02:59:50 +03:00
|
|
|
mLayoutServoStyleSetsStylistElementAndPseudosMaps,
|
Bug 1387958 - Measure the stylist during memory reporting. r=heycam.
Example output from the Obama Wikipedia page:
> ├──2,315,600 B (01.16%) -- stylist
> │ ├──1,916,928 B (00.96%) ── invalidation-map
> │ ├────228,800 B (00.11%) ── rule-tree
> │ ├────142,336 B (00.07%) ── element-and-pseudos-maps
> │ ├─────14,336 B (00.01%) ── revalidation-selectors
> │ ├──────9,648 B (00.00%) ── other
> │ └──────3,552 B (00.00%) ── precomputed-pseudos
This change requires new code to measure HashMaps, which uses the new
'malloc_enclosing_size_of' functions that can measure a heap block from an
interior pointer.
The patch changes MallocSizeOfFn to a newtype, and introduces
MallocEnclosingSizeOfFn alongside.
It also adds new traits: MallocSizeOfBox, MallocSizeOfVec, MallocSizeOfHash.
These each contain a single method that does shallow measurement of the
relevant type, which is often useful. (This is a different style to the
existing MallocSizeOf trait, which does deep measurement, but I'm moving away
from the always-deep-measurement style because it's less flexible.)
MozReview-Commit-ID: FgJCCmdw0ZF
--HG--
extra : rebase_source : c692c2073aa66020224489b97247c49de95a99a4
2017-09-05 04:38:45 +03:00
|
|
|
"Memory used by element and pseudos maps within Servo style "
|
|
|
|
"sets within a window.");
|
|
|
|
|
|
|
|
REPORT_SIZE("/layout/servo-style-sets/stylist/invalidation-map",
|
2017-09-25 02:59:50 +03:00
|
|
|
mLayoutServoStyleSetsStylistInvalidationMap,
|
Bug 1387958 - Measure the stylist during memory reporting. r=heycam.
Example output from the Obama Wikipedia page:
> ├──2,315,600 B (01.16%) -- stylist
> │ ├──1,916,928 B (00.96%) ── invalidation-map
> │ ├────228,800 B (00.11%) ── rule-tree
> │ ├────142,336 B (00.07%) ── element-and-pseudos-maps
> │ ├─────14,336 B (00.01%) ── revalidation-selectors
> │ ├──────9,648 B (00.00%) ── other
> │ └──────3,552 B (00.00%) ── precomputed-pseudos
This change requires new code to measure HashMaps, which uses the new
'malloc_enclosing_size_of' functions that can measure a heap block from an
interior pointer.
The patch changes MallocSizeOfFn to a newtype, and introduces
MallocEnclosingSizeOfFn alongside.
It also adds new traits: MallocSizeOfBox, MallocSizeOfVec, MallocSizeOfHash.
These each contain a single method that does shallow measurement of the
relevant type, which is often useful. (This is a different style to the
existing MallocSizeOf trait, which does deep measurement, but I'm moving away
from the always-deep-measurement style because it's less flexible.)
MozReview-Commit-ID: FgJCCmdw0ZF
--HG--
extra : rebase_source : c692c2073aa66020224489b97247c49de95a99a4
2017-09-05 04:38:45 +03:00
|
|
|
"Memory used by invalidation maps within Servo style sets "
|
|
|
|
"within a window.");
|
|
|
|
|
|
|
|
REPORT_SIZE("/layout/servo-style-sets/stylist/revalidation-selectors",
|
2017-09-25 02:59:50 +03:00
|
|
|
mLayoutServoStyleSetsStylistRevalidationSelectors,
|
Bug 1387958 - Measure the stylist during memory reporting. r=heycam.
Example output from the Obama Wikipedia page:
> ├──2,315,600 B (01.16%) -- stylist
> │ ├──1,916,928 B (00.96%) ── invalidation-map
> │ ├────228,800 B (00.11%) ── rule-tree
> │ ├────142,336 B (00.07%) ── element-and-pseudos-maps
> │ ├─────14,336 B (00.01%) ── revalidation-selectors
> │ ├──────9,648 B (00.00%) ── other
> │ └──────3,552 B (00.00%) ── precomputed-pseudos
This change requires new code to measure HashMaps, which uses the new
'malloc_enclosing_size_of' functions that can measure a heap block from an
interior pointer.
The patch changes MallocSizeOfFn to a newtype, and introduces
MallocEnclosingSizeOfFn alongside.
It also adds new traits: MallocSizeOfBox, MallocSizeOfVec, MallocSizeOfHash.
These each contain a single method that does shallow measurement of the
relevant type, which is often useful. (This is a different style to the
existing MallocSizeOf trait, which does deep measurement, but I'm moving away
from the always-deep-measurement style because it's less flexible.)
MozReview-Commit-ID: FgJCCmdw0ZF
--HG--
extra : rebase_source : c692c2073aa66020224489b97247c49de95a99a4
2017-09-05 04:38:45 +03:00
|
|
|
"Memory used by selectors for cache revalidation within Servo "
|
|
|
|
"style sets within a window.");
|
|
|
|
|
|
|
|
REPORT_SIZE("/layout/servo-style-sets/stylist/other",
|
2017-09-25 02:59:50 +03:00
|
|
|
mLayoutServoStyleSetsStylistOther,
|
Bug 1387958 - Measure the stylist during memory reporting. r=heycam.
Example output from the Obama Wikipedia page:
> ├──2,315,600 B (01.16%) -- stylist
> │ ├──1,916,928 B (00.96%) ── invalidation-map
> │ ├────228,800 B (00.11%) ── rule-tree
> │ ├────142,336 B (00.07%) ── element-and-pseudos-maps
> │ ├─────14,336 B (00.01%) ── revalidation-selectors
> │ ├──────9,648 B (00.00%) ── other
> │ └──────3,552 B (00.00%) ── precomputed-pseudos
This change requires new code to measure HashMaps, which uses the new
'malloc_enclosing_size_of' functions that can measure a heap block from an
interior pointer.
The patch changes MallocSizeOfFn to a newtype, and introduces
MallocEnclosingSizeOfFn alongside.
It also adds new traits: MallocSizeOfBox, MallocSizeOfVec, MallocSizeOfHash.
These each contain a single method that does shallow measurement of the
relevant type, which is often useful. (This is a different style to the
existing MallocSizeOf trait, which does deep measurement, but I'm moving away
from the always-deep-measurement style because it's less flexible.)
MozReview-Commit-ID: FgJCCmdw0ZF
--HG--
extra : rebase_source : c692c2073aa66020224489b97247c49de95a99a4
2017-09-05 04:38:45 +03:00
|
|
|
"Memory used by other Stylist data within Servo style sets "
|
|
|
|
"within a window.");
|
|
|
|
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SIZE("/layout/servo-style-sets/other", mLayoutServoStyleSetsOther,
|
2017-08-30 11:21:26 +03:00
|
|
|
"Memory used by other parts of Servo style sets within a "
|
|
|
|
"window.");
|
2017-08-25 07:43:29 +03:00
|
|
|
|
2017-09-08 17:12:25 +03:00
|
|
|
REPORT_SIZE("/layout/servo-element-data-objects",
|
2017-09-25 02:59:50 +03:00
|
|
|
mLayoutServoElementDataObjects,
|
2017-09-08 17:12:25 +03:00
|
|
|
"Memory used for Servo ElementData objects, but not the things"
|
|
|
|
"hanging off them.");
|
|
|
|
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SIZE("/layout/text-runs", mLayoutTextRunsSize,
|
2017-08-25 07:43:29 +03:00
|
|
|
"Memory used for text-runs (glyph layout) in the PresShell's "
|
|
|
|
"frame tree, within a window.");
|
|
|
|
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SIZE("/layout/pres-contexts", mLayoutPresContextSize,
|
2017-08-25 07:43:29 +03:00
|
|
|
"Memory used for the PresContext in the PresShell's frame "
|
|
|
|
"within a window.");
|
|
|
|
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SIZE("/layout/frame-properties", mLayoutFramePropertiesSize,
|
2017-08-25 07:43:29 +03:00
|
|
|
"Memory used for frame properties attached to frames "
|
|
|
|
"within a window.");
|
|
|
|
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SIZE("/layout/computed-values/dom", mLayoutComputedValuesDom,
|
2017-08-25 07:50:26 +03:00
|
|
|
"Memory used by ComputedValues objects accessible from DOM "
|
|
|
|
"elements.");
|
|
|
|
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SIZE("/layout/computed-values/non-dom", mLayoutComputedValuesNonDom,
|
2017-08-25 07:50:26 +03:00
|
|
|
"Memory used by ComputedValues objects not accessible from DOM "
|
|
|
|
"elements.");
|
|
|
|
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SIZE("/layout/computed-values/visited", mLayoutComputedValuesVisited,
|
2017-08-25 07:50:26 +03:00
|
|
|
"Memory used by ComputedValues objects used for visited styles.");
|
|
|
|
|
2018-02-22 15:19:50 +03:00
|
|
|
REPORT_SIZE("/layout/computed-values/stale", mLayoutComputedValuesStale,
|
|
|
|
"Memory used by ComputedValues and style structs it holds that "
|
|
|
|
"is no longer used but still alive.");
|
|
|
|
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SIZE("/property-tables", mPropertyTablesSize,
|
2017-08-25 07:43:29 +03:00
|
|
|
"Memory used for the property tables within a window.");
|
|
|
|
|
2018-02-16 15:02:28 +03:00
|
|
|
REPORT_SIZE("/bindings", mBindingsSize,
|
|
|
|
"Memory used by bindings within a window.");
|
|
|
|
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_COUNT("/dom/event-targets", mDOMEventTargetsCount,
|
2017-08-25 07:43:29 +03:00
|
|
|
"Number of non-node event targets in the event targets table "
|
|
|
|
"in a window's DOM, such as XHRs.");
|
|
|
|
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_COUNT("/dom/event-listeners", mDOMEventListenersCount,
|
2017-08-25 07:43:29 +03:00
|
|
|
"Number of event listeners in a window, including event "
|
|
|
|
"listeners on nodes and other event targets.");
|
|
|
|
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SIZE("/layout/line-boxes", mArenaSizes.mLineBoxes,
|
2013-10-28 13:47:18 +04:00
|
|
|
"Memory used by line boxes within a window.");
|
2012-06-06 21:35:40 +04:00
|
|
|
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SIZE("/layout/rule-nodes", mArenaSizes.mRuleNodes,
|
2013-10-28 13:47:18 +04:00
|
|
|
"Memory used by CSS rule nodes within a window.");
|
2012-06-06 21:35:40 +04:00
|
|
|
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SIZE("/layout/style-contexts", mArenaSizes.mStyleContexts,
|
2013-10-28 13:47:18 +04:00
|
|
|
"Memory used by style contexts within a window.");
|
2012-06-06 21:35:40 +04:00
|
|
|
|
2017-08-25 07:59:44 +03:00
|
|
|
// There are many different kinds of style structs, but it is likely that
|
|
|
|
// only a few matter. Implement a cutoff so we don't bloat about:memory with
|
|
|
|
// many uninteresting entries.
|
|
|
|
const size_t STYLE_SUNDRIES_THRESHOLD =
|
|
|
|
js::MemoryReportingSundriesThreshold();
|
|
|
|
|
|
|
|
// This is the Gecko style structs, which are in the nsPresArena.
|
|
|
|
size_t geckoStyleSundriesSize = 0;
|
|
|
|
#define STYLE_STRUCT(name_, cb_) \
|
|
|
|
{ \
|
|
|
|
size_t size = \
|
|
|
|
windowSizes.mArenaSizes.mGeckoStyleSizes.NS_STYLE_SIZES_FIELD(name_); \
|
|
|
|
if (size < STYLE_SUNDRIES_THRESHOLD) { \
|
|
|
|
geckoStyleSundriesSize += size; \
|
|
|
|
} else { \
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SUM_SIZE( \
|
|
|
|
"/layout/gecko-style-structs/" # name_, size, \
|
|
|
|
"Memory used by the " #name_ " Gecko style structs within a window."); \
|
2017-08-25 07:59:44 +03:00
|
|
|
} \
|
|
|
|
aWindowTotalSizes->mArenaSizes.mGeckoStyleSizes.NS_STYLE_SIZES_FIELD(name_) += \
|
|
|
|
size; \
|
|
|
|
}
|
|
|
|
#define STYLE_STRUCT_LIST_IGNORE_VARIABLES
|
|
|
|
#include "nsStyleStructList.h"
|
|
|
|
#undef STYLE_STRUCT
|
|
|
|
#undef STYLE_STRUCT_LIST_IGNORE_VARIABLES
|
|
|
|
|
|
|
|
if (geckoStyleSundriesSize > 0) {
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SUM_SIZE(
|
|
|
|
"/layout/gecko-style-structs/sundries", geckoStyleSundriesSize,
|
|
|
|
"The sum of all memory used by Gecko style structs which were too small "
|
|
|
|
"to be shown individually.");
|
2017-08-25 07:59:44 +03:00
|
|
|
}
|
2015-05-27 05:08:42 +03:00
|
|
|
|
2012-06-06 21:29:16 +04:00
|
|
|
// There are many different kinds of frames, but it is very likely
|
|
|
|
// that only a few matter. Implement a cutoff so we don't bloat
|
|
|
|
// about:memory with many uninteresting entries.
|
2012-10-17 18:44:31 +04:00
|
|
|
const size_t FRAME_SUNDRIES_THRESHOLD =
|
|
|
|
js::MemoryReportingSundriesThreshold();
|
|
|
|
|
2012-06-06 21:29:16 +04:00
|
|
|
size_t frameSundriesSize = 0;
|
Bug 1387956 - Overhaul ComputedValues measurement, and add style structs measurement. r=bholley.
This patch moves measurement of ComputedValues objects from Rust to C++.
Measurement now happens (a) via DOM elements and (b) remaining elements via
the frame tree. Likewise for the style structs hanging off ComputedValues
objects.
Here is an example of the output.
> ├──27,600,448 B (26.49%) -- active/window(https://en.wikipedia.org/wiki/Barack_Obama)
> │ ├──12,772,544 B (12.26%) -- layout
> │ │ ├───4,483,744 B (04.30%) -- frames
> │ │ │ ├──1,653,552 B (01.59%) ── nsInlineFrame
> │ │ │ ├──1,415,760 B (01.36%) ── nsTextFrame
> │ │ │ ├────431,376 B (00.41%) ── nsBlockFrame
> │ │ │ ├────340,560 B (00.33%) ── nsHTMLScrollFrame
> │ │ │ ├────302,544 B (00.29%) ── nsContinuingTextFrame
> │ │ │ ├────156,408 B (00.15%) ── nsBulletFrame
> │ │ │ ├─────73,024 B (00.07%) ── nsPlaceholderFrame
> │ │ │ ├─────27,656 B (00.03%) ── sundries
> │ │ │ ├─────23,520 B (00.02%) ── nsTableCellFrame
> │ │ │ ├─────16,704 B (00.02%) ── nsImageFrame
> │ │ │ ├─────15,488 B (00.01%) ── nsTableRowFrame
> │ │ │ ├─────13,776 B (00.01%) ── nsTableColFrame
> │ │ │ └─────13,376 B (00.01%) ── nsTableFrame
> │ │ ├───3,412,192 B (03.28%) -- servo-style-structs
> │ │ │ ├──1,288,224 B (01.24%) ── Display
> │ │ │ ├────742,400 B (00.71%) ── Position
> │ │ │ ├────308,736 B (00.30%) ── Font
> │ │ │ ├────226,512 B (00.22%) ── Background
> │ │ │ ├────218,304 B (00.21%) ── TextReset
> │ │ │ ├────214,896 B (00.21%) ── Text
> │ │ │ ├────130,560 B (00.13%) ── Border
> │ │ │ ├─────81,408 B (00.08%) ── UIReset
> │ │ │ ├─────61,440 B (00.06%) ── Padding
> │ │ │ ├─────38,176 B (00.04%) ── UserInterface
> │ │ │ ├─────29,232 B (00.03%) ── Margin
> │ │ │ ├─────21,824 B (00.02%) ── sundries
> │ │ │ ├─────20,080 B (00.02%) ── Color
> │ │ │ ├─────20,080 B (00.02%) ── Column
> │ │ │ └─────10,320 B (00.01%) ── Effects
> │ │ ├───2,227,680 B (02.14%) -- computed-values
> │ │ │ ├──1,182,928 B (01.14%) ── non-dom
> │ │ │ └──1,044,752 B (01.00%) ── dom
> │ │ ├───1,500,016 B (01.44%) ── text-runs
> │ │ ├─────492,640 B (00.47%) ── line-boxes
> │ │ ├─────326,688 B (00.31%) ── frame-properties
> │ │ ├─────301,760 B (00.29%) ── pres-shell
> │ │ ├──────27,648 B (00.03%) ── pres-contexts
> │ │ └─────────176 B (00.00%) ── style-sets
The 'servo-style-structs' and 'computed-values' sub-trees are new. (Prior to
this patch, ComputedValues under DOM elements were tallied under the the
'dom/element-nodes' sub-tree, and ComputedValues not under DOM element were
ignored.) 'servo-style-structs/sundries' aggregates all the style structs that
are smaller than 8 KiB.
Other notable things done by the patch are as follows.
- It significantly changes the signatures of the methods measuring nsINode and
its subclasses, in order to handle the tallying of style structs separately
from element-nodes. Likewise for nsIFrame.
- It renames the 'layout/style-structs' sub-tree as
'layout/gecko-style-structs', to clearly distinguish it from the new
'layout/servo-style-structs' sub-tree.
- It adds some FFI functions to access various Rust-side data structures from
C++ code.
- There is a nasty hack used twice to measure Arcs, by stepping backwards from
an interior pointer to a base pointer. It works, but I want to replace it
with something better eventually. The "XXX WARNING" comments have details.
- It makes DMD print a line to the console if it sees a pointer it doesn't
recognise. This is useful for detecting when we are measuring an interior
pointer instead of a base pointer, which is bad but easy to do when Arcs are
involved.
- It removes the Rust code for measuring CVs, because it's now all done on the
C++ side.
MozReview-Commit-ID: BKebACLKtCi
--HG--
extra : rebase_source : 4d9a8c6b198a0ff025b811759a6bfa9f33a260ba
2017-08-11 09:37:33 +03:00
|
|
|
#define FRAME_ID(classname, ...) \
|
|
|
|
{ \
|
|
|
|
size_t size = windowSizes.mArenaSizes.NS_ARENA_SIZES_FIELD(classname); \
|
|
|
|
if (size < FRAME_SUNDRIES_THRESHOLD) { \
|
|
|
|
frameSundriesSize += size; \
|
|
|
|
} else { \
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SUM_SIZE( \
|
|
|
|
"/layout/frames/" # classname, size, \
|
|
|
|
"Memory used by frames of type " #classname " within a window."); \
|
Bug 1387956 - Overhaul ComputedValues measurement, and add style structs measurement. r=bholley.
This patch moves measurement of ComputedValues objects from Rust to C++.
Measurement now happens (a) via DOM elements and (b) remaining elements via
the frame tree. Likewise for the style structs hanging off ComputedValues
objects.
Here is an example of the output.
> ├──27,600,448 B (26.49%) -- active/window(https://en.wikipedia.org/wiki/Barack_Obama)
> │ ├──12,772,544 B (12.26%) -- layout
> │ │ ├───4,483,744 B (04.30%) -- frames
> │ │ │ ├──1,653,552 B (01.59%) ── nsInlineFrame
> │ │ │ ├──1,415,760 B (01.36%) ── nsTextFrame
> │ │ │ ├────431,376 B (00.41%) ── nsBlockFrame
> │ │ │ ├────340,560 B (00.33%) ── nsHTMLScrollFrame
> │ │ │ ├────302,544 B (00.29%) ── nsContinuingTextFrame
> │ │ │ ├────156,408 B (00.15%) ── nsBulletFrame
> │ │ │ ├─────73,024 B (00.07%) ── nsPlaceholderFrame
> │ │ │ ├─────27,656 B (00.03%) ── sundries
> │ │ │ ├─────23,520 B (00.02%) ── nsTableCellFrame
> │ │ │ ├─────16,704 B (00.02%) ── nsImageFrame
> │ │ │ ├─────15,488 B (00.01%) ── nsTableRowFrame
> │ │ │ ├─────13,776 B (00.01%) ── nsTableColFrame
> │ │ │ └─────13,376 B (00.01%) ── nsTableFrame
> │ │ ├───3,412,192 B (03.28%) -- servo-style-structs
> │ │ │ ├──1,288,224 B (01.24%) ── Display
> │ │ │ ├────742,400 B (00.71%) ── Position
> │ │ │ ├────308,736 B (00.30%) ── Font
> │ │ │ ├────226,512 B (00.22%) ── Background
> │ │ │ ├────218,304 B (00.21%) ── TextReset
> │ │ │ ├────214,896 B (00.21%) ── Text
> │ │ │ ├────130,560 B (00.13%) ── Border
> │ │ │ ├─────81,408 B (00.08%) ── UIReset
> │ │ │ ├─────61,440 B (00.06%) ── Padding
> │ │ │ ├─────38,176 B (00.04%) ── UserInterface
> │ │ │ ├─────29,232 B (00.03%) ── Margin
> │ │ │ ├─────21,824 B (00.02%) ── sundries
> │ │ │ ├─────20,080 B (00.02%) ── Color
> │ │ │ ├─────20,080 B (00.02%) ── Column
> │ │ │ └─────10,320 B (00.01%) ── Effects
> │ │ ├───2,227,680 B (02.14%) -- computed-values
> │ │ │ ├──1,182,928 B (01.14%) ── non-dom
> │ │ │ └──1,044,752 B (01.00%) ── dom
> │ │ ├───1,500,016 B (01.44%) ── text-runs
> │ │ ├─────492,640 B (00.47%) ── line-boxes
> │ │ ├─────326,688 B (00.31%) ── frame-properties
> │ │ ├─────301,760 B (00.29%) ── pres-shell
> │ │ ├──────27,648 B (00.03%) ── pres-contexts
> │ │ └─────────176 B (00.00%) ── style-sets
The 'servo-style-structs' and 'computed-values' sub-trees are new. (Prior to
this patch, ComputedValues under DOM elements were tallied under the the
'dom/element-nodes' sub-tree, and ComputedValues not under DOM element were
ignored.) 'servo-style-structs/sundries' aggregates all the style structs that
are smaller than 8 KiB.
Other notable things done by the patch are as follows.
- It significantly changes the signatures of the methods measuring nsINode and
its subclasses, in order to handle the tallying of style structs separately
from element-nodes. Likewise for nsIFrame.
- It renames the 'layout/style-structs' sub-tree as
'layout/gecko-style-structs', to clearly distinguish it from the new
'layout/servo-style-structs' sub-tree.
- It adds some FFI functions to access various Rust-side data structures from
C++ code.
- There is a nasty hack used twice to measure Arcs, by stepping backwards from
an interior pointer to a base pointer. It works, but I want to replace it
with something better eventually. The "XXX WARNING" comments have details.
- It makes DMD print a line to the console if it sees a pointer it doesn't
recognise. This is useful for detecting when we are measuring an interior
pointer instead of a base pointer, which is bad but easy to do when Arcs are
involved.
- It removes the Rust code for measuring CVs, because it's now all done on the
C++ side.
MozReview-Commit-ID: BKebACLKtCi
--HG--
extra : rebase_source : 4d9a8c6b198a0ff025b811759a6bfa9f33a260ba
2017-08-11 09:37:33 +03:00
|
|
|
} \
|
|
|
|
aWindowTotalSizes->mArenaSizes.NS_ARENA_SIZES_FIELD(classname) += size; \
|
2012-06-06 21:29:16 +04:00
|
|
|
}
|
2017-05-26 13:11:11 +03:00
|
|
|
#define ABSTRACT_FRAME_ID(...)
|
2012-06-06 21:29:16 +04:00
|
|
|
#include "nsFrameIdList.h"
|
|
|
|
#undef FRAME_ID
|
2017-05-26 13:11:11 +03:00
|
|
|
#undef ABSTRACT_FRAME_ID
|
2012-06-06 21:29:16 +04:00
|
|
|
|
|
|
|
if (frameSundriesSize > 0) {
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SUM_SIZE(
|
|
|
|
"/layout/frames/sundries", frameSundriesSize,
|
|
|
|
"The sum of all memory used by frames which were too small to be shown "
|
|
|
|
"individually.");
|
2012-06-06 21:29:16 +04:00
|
|
|
}
|
2013-01-18 09:21:43 +04:00
|
|
|
|
2017-08-25 07:59:44 +03:00
|
|
|
// This is the Servo style structs.
|
|
|
|
size_t servoStyleSundriesSize = 0;
|
Bug 1387956 - Overhaul ComputedValues measurement, and add style structs measurement. r=bholley.
This patch moves measurement of ComputedValues objects from Rust to C++.
Measurement now happens (a) via DOM elements and (b) remaining elements via
the frame tree. Likewise for the style structs hanging off ComputedValues
objects.
Here is an example of the output.
> ├──27,600,448 B (26.49%) -- active/window(https://en.wikipedia.org/wiki/Barack_Obama)
> │ ├──12,772,544 B (12.26%) -- layout
> │ │ ├───4,483,744 B (04.30%) -- frames
> │ │ │ ├──1,653,552 B (01.59%) ── nsInlineFrame
> │ │ │ ├──1,415,760 B (01.36%) ── nsTextFrame
> │ │ │ ├────431,376 B (00.41%) ── nsBlockFrame
> │ │ │ ├────340,560 B (00.33%) ── nsHTMLScrollFrame
> │ │ │ ├────302,544 B (00.29%) ── nsContinuingTextFrame
> │ │ │ ├────156,408 B (00.15%) ── nsBulletFrame
> │ │ │ ├─────73,024 B (00.07%) ── nsPlaceholderFrame
> │ │ │ ├─────27,656 B (00.03%) ── sundries
> │ │ │ ├─────23,520 B (00.02%) ── nsTableCellFrame
> │ │ │ ├─────16,704 B (00.02%) ── nsImageFrame
> │ │ │ ├─────15,488 B (00.01%) ── nsTableRowFrame
> │ │ │ ├─────13,776 B (00.01%) ── nsTableColFrame
> │ │ │ └─────13,376 B (00.01%) ── nsTableFrame
> │ │ ├───3,412,192 B (03.28%) -- servo-style-structs
> │ │ │ ├──1,288,224 B (01.24%) ── Display
> │ │ │ ├────742,400 B (00.71%) ── Position
> │ │ │ ├────308,736 B (00.30%) ── Font
> │ │ │ ├────226,512 B (00.22%) ── Background
> │ │ │ ├────218,304 B (00.21%) ── TextReset
> │ │ │ ├────214,896 B (00.21%) ── Text
> │ │ │ ├────130,560 B (00.13%) ── Border
> │ │ │ ├─────81,408 B (00.08%) ── UIReset
> │ │ │ ├─────61,440 B (00.06%) ── Padding
> │ │ │ ├─────38,176 B (00.04%) ── UserInterface
> │ │ │ ├─────29,232 B (00.03%) ── Margin
> │ │ │ ├─────21,824 B (00.02%) ── sundries
> │ │ │ ├─────20,080 B (00.02%) ── Color
> │ │ │ ├─────20,080 B (00.02%) ── Column
> │ │ │ └─────10,320 B (00.01%) ── Effects
> │ │ ├───2,227,680 B (02.14%) -- computed-values
> │ │ │ ├──1,182,928 B (01.14%) ── non-dom
> │ │ │ └──1,044,752 B (01.00%) ── dom
> │ │ ├───1,500,016 B (01.44%) ── text-runs
> │ │ ├─────492,640 B (00.47%) ── line-boxes
> │ │ ├─────326,688 B (00.31%) ── frame-properties
> │ │ ├─────301,760 B (00.29%) ── pres-shell
> │ │ ├──────27,648 B (00.03%) ── pres-contexts
> │ │ └─────────176 B (00.00%) ── style-sets
The 'servo-style-structs' and 'computed-values' sub-trees are new. (Prior to
this patch, ComputedValues under DOM elements were tallied under the the
'dom/element-nodes' sub-tree, and ComputedValues not under DOM element were
ignored.) 'servo-style-structs/sundries' aggregates all the style structs that
are smaller than 8 KiB.
Other notable things done by the patch are as follows.
- It significantly changes the signatures of the methods measuring nsINode and
its subclasses, in order to handle the tallying of style structs separately
from element-nodes. Likewise for nsIFrame.
- It renames the 'layout/style-structs' sub-tree as
'layout/gecko-style-structs', to clearly distinguish it from the new
'layout/servo-style-structs' sub-tree.
- It adds some FFI functions to access various Rust-side data structures from
C++ code.
- There is a nasty hack used twice to measure Arcs, by stepping backwards from
an interior pointer to a base pointer. It works, but I want to replace it
with something better eventually. The "XXX WARNING" comments have details.
- It makes DMD print a line to the console if it sees a pointer it doesn't
recognise. This is useful for detecting when we are measuring an interior
pointer instead of a base pointer, which is bad but easy to do when Arcs are
involved.
- It removes the Rust code for measuring CVs, because it's now all done on the
C++ side.
MozReview-Commit-ID: BKebACLKtCi
--HG--
extra : rebase_source : 4d9a8c6b198a0ff025b811759a6bfa9f33a260ba
2017-08-11 09:37:33 +03:00
|
|
|
#define STYLE_STRUCT(name_, cb_) \
|
|
|
|
{ \
|
2017-08-25 07:59:44 +03:00
|
|
|
size_t size = windowSizes.mServoStyleSizes.NS_STYLE_SIZES_FIELD(name_); \
|
Bug 1387956 - Overhaul ComputedValues measurement, and add style structs measurement. r=bholley.
This patch moves measurement of ComputedValues objects from Rust to C++.
Measurement now happens (a) via DOM elements and (b) remaining elements via
the frame tree. Likewise for the style structs hanging off ComputedValues
objects.
Here is an example of the output.
> ├──27,600,448 B (26.49%) -- active/window(https://en.wikipedia.org/wiki/Barack_Obama)
> │ ├──12,772,544 B (12.26%) -- layout
> │ │ ├───4,483,744 B (04.30%) -- frames
> │ │ │ ├──1,653,552 B (01.59%) ── nsInlineFrame
> │ │ │ ├──1,415,760 B (01.36%) ── nsTextFrame
> │ │ │ ├────431,376 B (00.41%) ── nsBlockFrame
> │ │ │ ├────340,560 B (00.33%) ── nsHTMLScrollFrame
> │ │ │ ├────302,544 B (00.29%) ── nsContinuingTextFrame
> │ │ │ ├────156,408 B (00.15%) ── nsBulletFrame
> │ │ │ ├─────73,024 B (00.07%) ── nsPlaceholderFrame
> │ │ │ ├─────27,656 B (00.03%) ── sundries
> │ │ │ ├─────23,520 B (00.02%) ── nsTableCellFrame
> │ │ │ ├─────16,704 B (00.02%) ── nsImageFrame
> │ │ │ ├─────15,488 B (00.01%) ── nsTableRowFrame
> │ │ │ ├─────13,776 B (00.01%) ── nsTableColFrame
> │ │ │ └─────13,376 B (00.01%) ── nsTableFrame
> │ │ ├───3,412,192 B (03.28%) -- servo-style-structs
> │ │ │ ├──1,288,224 B (01.24%) ── Display
> │ │ │ ├────742,400 B (00.71%) ── Position
> │ │ │ ├────308,736 B (00.30%) ── Font
> │ │ │ ├────226,512 B (00.22%) ── Background
> │ │ │ ├────218,304 B (00.21%) ── TextReset
> │ │ │ ├────214,896 B (00.21%) ── Text
> │ │ │ ├────130,560 B (00.13%) ── Border
> │ │ │ ├─────81,408 B (00.08%) ── UIReset
> │ │ │ ├─────61,440 B (00.06%) ── Padding
> │ │ │ ├─────38,176 B (00.04%) ── UserInterface
> │ │ │ ├─────29,232 B (00.03%) ── Margin
> │ │ │ ├─────21,824 B (00.02%) ── sundries
> │ │ │ ├─────20,080 B (00.02%) ── Color
> │ │ │ ├─────20,080 B (00.02%) ── Column
> │ │ │ └─────10,320 B (00.01%) ── Effects
> │ │ ├───2,227,680 B (02.14%) -- computed-values
> │ │ │ ├──1,182,928 B (01.14%) ── non-dom
> │ │ │ └──1,044,752 B (01.00%) ── dom
> │ │ ├───1,500,016 B (01.44%) ── text-runs
> │ │ ├─────492,640 B (00.47%) ── line-boxes
> │ │ ├─────326,688 B (00.31%) ── frame-properties
> │ │ ├─────301,760 B (00.29%) ── pres-shell
> │ │ ├──────27,648 B (00.03%) ── pres-contexts
> │ │ └─────────176 B (00.00%) ── style-sets
The 'servo-style-structs' and 'computed-values' sub-trees are new. (Prior to
this patch, ComputedValues under DOM elements were tallied under the the
'dom/element-nodes' sub-tree, and ComputedValues not under DOM element were
ignored.) 'servo-style-structs/sundries' aggregates all the style structs that
are smaller than 8 KiB.
Other notable things done by the patch are as follows.
- It significantly changes the signatures of the methods measuring nsINode and
its subclasses, in order to handle the tallying of style structs separately
from element-nodes. Likewise for nsIFrame.
- It renames the 'layout/style-structs' sub-tree as
'layout/gecko-style-structs', to clearly distinguish it from the new
'layout/servo-style-structs' sub-tree.
- It adds some FFI functions to access various Rust-side data structures from
C++ code.
- There is a nasty hack used twice to measure Arcs, by stepping backwards from
an interior pointer to a base pointer. It works, but I want to replace it
with something better eventually. The "XXX WARNING" comments have details.
- It makes DMD print a line to the console if it sees a pointer it doesn't
recognise. This is useful for detecting when we are measuring an interior
pointer instead of a base pointer, which is bad but easy to do when Arcs are
involved.
- It removes the Rust code for measuring CVs, because it's now all done on the
C++ side.
MozReview-Commit-ID: BKebACLKtCi
--HG--
extra : rebase_source : 4d9a8c6b198a0ff025b811759a6bfa9f33a260ba
2017-08-11 09:37:33 +03:00
|
|
|
if (size < STYLE_SUNDRIES_THRESHOLD) { \
|
2017-08-25 07:59:44 +03:00
|
|
|
servoStyleSundriesSize += size; \
|
Bug 1387956 - Overhaul ComputedValues measurement, and add style structs measurement. r=bholley.
This patch moves measurement of ComputedValues objects from Rust to C++.
Measurement now happens (a) via DOM elements and (b) remaining elements via
the frame tree. Likewise for the style structs hanging off ComputedValues
objects.
Here is an example of the output.
> ├──27,600,448 B (26.49%) -- active/window(https://en.wikipedia.org/wiki/Barack_Obama)
> │ ├──12,772,544 B (12.26%) -- layout
> │ │ ├───4,483,744 B (04.30%) -- frames
> │ │ │ ├──1,653,552 B (01.59%) ── nsInlineFrame
> │ │ │ ├──1,415,760 B (01.36%) ── nsTextFrame
> │ │ │ ├────431,376 B (00.41%) ── nsBlockFrame
> │ │ │ ├────340,560 B (00.33%) ── nsHTMLScrollFrame
> │ │ │ ├────302,544 B (00.29%) ── nsContinuingTextFrame
> │ │ │ ├────156,408 B (00.15%) ── nsBulletFrame
> │ │ │ ├─────73,024 B (00.07%) ── nsPlaceholderFrame
> │ │ │ ├─────27,656 B (00.03%) ── sundries
> │ │ │ ├─────23,520 B (00.02%) ── nsTableCellFrame
> │ │ │ ├─────16,704 B (00.02%) ── nsImageFrame
> │ │ │ ├─────15,488 B (00.01%) ── nsTableRowFrame
> │ │ │ ├─────13,776 B (00.01%) ── nsTableColFrame
> │ │ │ └─────13,376 B (00.01%) ── nsTableFrame
> │ │ ├───3,412,192 B (03.28%) -- servo-style-structs
> │ │ │ ├──1,288,224 B (01.24%) ── Display
> │ │ │ ├────742,400 B (00.71%) ── Position
> │ │ │ ├────308,736 B (00.30%) ── Font
> │ │ │ ├────226,512 B (00.22%) ── Background
> │ │ │ ├────218,304 B (00.21%) ── TextReset
> │ │ │ ├────214,896 B (00.21%) ── Text
> │ │ │ ├────130,560 B (00.13%) ── Border
> │ │ │ ├─────81,408 B (00.08%) ── UIReset
> │ │ │ ├─────61,440 B (00.06%) ── Padding
> │ │ │ ├─────38,176 B (00.04%) ── UserInterface
> │ │ │ ├─────29,232 B (00.03%) ── Margin
> │ │ │ ├─────21,824 B (00.02%) ── sundries
> │ │ │ ├─────20,080 B (00.02%) ── Color
> │ │ │ ├─────20,080 B (00.02%) ── Column
> │ │ │ └─────10,320 B (00.01%) ── Effects
> │ │ ├───2,227,680 B (02.14%) -- computed-values
> │ │ │ ├──1,182,928 B (01.14%) ── non-dom
> │ │ │ └──1,044,752 B (01.00%) ── dom
> │ │ ├───1,500,016 B (01.44%) ── text-runs
> │ │ ├─────492,640 B (00.47%) ── line-boxes
> │ │ ├─────326,688 B (00.31%) ── frame-properties
> │ │ ├─────301,760 B (00.29%) ── pres-shell
> │ │ ├──────27,648 B (00.03%) ── pres-contexts
> │ │ └─────────176 B (00.00%) ── style-sets
The 'servo-style-structs' and 'computed-values' sub-trees are new. (Prior to
this patch, ComputedValues under DOM elements were tallied under the the
'dom/element-nodes' sub-tree, and ComputedValues not under DOM element were
ignored.) 'servo-style-structs/sundries' aggregates all the style structs that
are smaller than 8 KiB.
Other notable things done by the patch are as follows.
- It significantly changes the signatures of the methods measuring nsINode and
its subclasses, in order to handle the tallying of style structs separately
from element-nodes. Likewise for nsIFrame.
- It renames the 'layout/style-structs' sub-tree as
'layout/gecko-style-structs', to clearly distinguish it from the new
'layout/servo-style-structs' sub-tree.
- It adds some FFI functions to access various Rust-side data structures from
C++ code.
- There is a nasty hack used twice to measure Arcs, by stepping backwards from
an interior pointer to a base pointer. It works, but I want to replace it
with something better eventually. The "XXX WARNING" comments have details.
- It makes DMD print a line to the console if it sees a pointer it doesn't
recognise. This is useful for detecting when we are measuring an interior
pointer instead of a base pointer, which is bad but easy to do when Arcs are
involved.
- It removes the Rust code for measuring CVs, because it's now all done on the
C++ side.
MozReview-Commit-ID: BKebACLKtCi
--HG--
extra : rebase_source : 4d9a8c6b198a0ff025b811759a6bfa9f33a260ba
2017-08-11 09:37:33 +03:00
|
|
|
} else { \
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SUM_SIZE( \
|
|
|
|
"/layout/servo-style-structs/" # name_, size, \
|
|
|
|
"Memory used by the " #name_ " Servo style structs within a window."); \
|
Bug 1387956 - Overhaul ComputedValues measurement, and add style structs measurement. r=bholley.
This patch moves measurement of ComputedValues objects from Rust to C++.
Measurement now happens (a) via DOM elements and (b) remaining elements via
the frame tree. Likewise for the style structs hanging off ComputedValues
objects.
Here is an example of the output.
> ├──27,600,448 B (26.49%) -- active/window(https://en.wikipedia.org/wiki/Barack_Obama)
> │ ├──12,772,544 B (12.26%) -- layout
> │ │ ├───4,483,744 B (04.30%) -- frames
> │ │ │ ├──1,653,552 B (01.59%) ── nsInlineFrame
> │ │ │ ├──1,415,760 B (01.36%) ── nsTextFrame
> │ │ │ ├────431,376 B (00.41%) ── nsBlockFrame
> │ │ │ ├────340,560 B (00.33%) ── nsHTMLScrollFrame
> │ │ │ ├────302,544 B (00.29%) ── nsContinuingTextFrame
> │ │ │ ├────156,408 B (00.15%) ── nsBulletFrame
> │ │ │ ├─────73,024 B (00.07%) ── nsPlaceholderFrame
> │ │ │ ├─────27,656 B (00.03%) ── sundries
> │ │ │ ├─────23,520 B (00.02%) ── nsTableCellFrame
> │ │ │ ├─────16,704 B (00.02%) ── nsImageFrame
> │ │ │ ├─────15,488 B (00.01%) ── nsTableRowFrame
> │ │ │ ├─────13,776 B (00.01%) ── nsTableColFrame
> │ │ │ └─────13,376 B (00.01%) ── nsTableFrame
> │ │ ├───3,412,192 B (03.28%) -- servo-style-structs
> │ │ │ ├──1,288,224 B (01.24%) ── Display
> │ │ │ ├────742,400 B (00.71%) ── Position
> │ │ │ ├────308,736 B (00.30%) ── Font
> │ │ │ ├────226,512 B (00.22%) ── Background
> │ │ │ ├────218,304 B (00.21%) ── TextReset
> │ │ │ ├────214,896 B (00.21%) ── Text
> │ │ │ ├────130,560 B (00.13%) ── Border
> │ │ │ ├─────81,408 B (00.08%) ── UIReset
> │ │ │ ├─────61,440 B (00.06%) ── Padding
> │ │ │ ├─────38,176 B (00.04%) ── UserInterface
> │ │ │ ├─────29,232 B (00.03%) ── Margin
> │ │ │ ├─────21,824 B (00.02%) ── sundries
> │ │ │ ├─────20,080 B (00.02%) ── Color
> │ │ │ ├─────20,080 B (00.02%) ── Column
> │ │ │ └─────10,320 B (00.01%) ── Effects
> │ │ ├───2,227,680 B (02.14%) -- computed-values
> │ │ │ ├──1,182,928 B (01.14%) ── non-dom
> │ │ │ └──1,044,752 B (01.00%) ── dom
> │ │ ├───1,500,016 B (01.44%) ── text-runs
> │ │ ├─────492,640 B (00.47%) ── line-boxes
> │ │ ├─────326,688 B (00.31%) ── frame-properties
> │ │ ├─────301,760 B (00.29%) ── pres-shell
> │ │ ├──────27,648 B (00.03%) ── pres-contexts
> │ │ └─────────176 B (00.00%) ── style-sets
The 'servo-style-structs' and 'computed-values' sub-trees are new. (Prior to
this patch, ComputedValues under DOM elements were tallied under the the
'dom/element-nodes' sub-tree, and ComputedValues not under DOM element were
ignored.) 'servo-style-structs/sundries' aggregates all the style structs that
are smaller than 8 KiB.
Other notable things done by the patch are as follows.
- It significantly changes the signatures of the methods measuring nsINode and
its subclasses, in order to handle the tallying of style structs separately
from element-nodes. Likewise for nsIFrame.
- It renames the 'layout/style-structs' sub-tree as
'layout/gecko-style-structs', to clearly distinguish it from the new
'layout/servo-style-structs' sub-tree.
- It adds some FFI functions to access various Rust-side data structures from
C++ code.
- There is a nasty hack used twice to measure Arcs, by stepping backwards from
an interior pointer to a base pointer. It works, but I want to replace it
with something better eventually. The "XXX WARNING" comments have details.
- It makes DMD print a line to the console if it sees a pointer it doesn't
recognise. This is useful for detecting when we are measuring an interior
pointer instead of a base pointer, which is bad but easy to do when Arcs are
involved.
- It removes the Rust code for measuring CVs, because it's now all done on the
C++ side.
MozReview-Commit-ID: BKebACLKtCi
--HG--
extra : rebase_source : 4d9a8c6b198a0ff025b811759a6bfa9f33a260ba
2017-08-11 09:37:33 +03:00
|
|
|
} \
|
2017-08-25 07:59:44 +03:00
|
|
|
aWindowTotalSizes->mServoStyleSizes.NS_STYLE_SIZES_FIELD(name_) += size; \
|
Bug 1387956 - Overhaul ComputedValues measurement, and add style structs measurement. r=bholley.
This patch moves measurement of ComputedValues objects from Rust to C++.
Measurement now happens (a) via DOM elements and (b) remaining elements via
the frame tree. Likewise for the style structs hanging off ComputedValues
objects.
Here is an example of the output.
> ├──27,600,448 B (26.49%) -- active/window(https://en.wikipedia.org/wiki/Barack_Obama)
> │ ├──12,772,544 B (12.26%) -- layout
> │ │ ├───4,483,744 B (04.30%) -- frames
> │ │ │ ├──1,653,552 B (01.59%) ── nsInlineFrame
> │ │ │ ├──1,415,760 B (01.36%) ── nsTextFrame
> │ │ │ ├────431,376 B (00.41%) ── nsBlockFrame
> │ │ │ ├────340,560 B (00.33%) ── nsHTMLScrollFrame
> │ │ │ ├────302,544 B (00.29%) ── nsContinuingTextFrame
> │ │ │ ├────156,408 B (00.15%) ── nsBulletFrame
> │ │ │ ├─────73,024 B (00.07%) ── nsPlaceholderFrame
> │ │ │ ├─────27,656 B (00.03%) ── sundries
> │ │ │ ├─────23,520 B (00.02%) ── nsTableCellFrame
> │ │ │ ├─────16,704 B (00.02%) ── nsImageFrame
> │ │ │ ├─────15,488 B (00.01%) ── nsTableRowFrame
> │ │ │ ├─────13,776 B (00.01%) ── nsTableColFrame
> │ │ │ └─────13,376 B (00.01%) ── nsTableFrame
> │ │ ├───3,412,192 B (03.28%) -- servo-style-structs
> │ │ │ ├──1,288,224 B (01.24%) ── Display
> │ │ │ ├────742,400 B (00.71%) ── Position
> │ │ │ ├────308,736 B (00.30%) ── Font
> │ │ │ ├────226,512 B (00.22%) ── Background
> │ │ │ ├────218,304 B (00.21%) ── TextReset
> │ │ │ ├────214,896 B (00.21%) ── Text
> │ │ │ ├────130,560 B (00.13%) ── Border
> │ │ │ ├─────81,408 B (00.08%) ── UIReset
> │ │ │ ├─────61,440 B (00.06%) ── Padding
> │ │ │ ├─────38,176 B (00.04%) ── UserInterface
> │ │ │ ├─────29,232 B (00.03%) ── Margin
> │ │ │ ├─────21,824 B (00.02%) ── sundries
> │ │ │ ├─────20,080 B (00.02%) ── Color
> │ │ │ ├─────20,080 B (00.02%) ── Column
> │ │ │ └─────10,320 B (00.01%) ── Effects
> │ │ ├───2,227,680 B (02.14%) -- computed-values
> │ │ │ ├──1,182,928 B (01.14%) ── non-dom
> │ │ │ └──1,044,752 B (01.00%) ── dom
> │ │ ├───1,500,016 B (01.44%) ── text-runs
> │ │ ├─────492,640 B (00.47%) ── line-boxes
> │ │ ├─────326,688 B (00.31%) ── frame-properties
> │ │ ├─────301,760 B (00.29%) ── pres-shell
> │ │ ├──────27,648 B (00.03%) ── pres-contexts
> │ │ └─────────176 B (00.00%) ── style-sets
The 'servo-style-structs' and 'computed-values' sub-trees are new. (Prior to
this patch, ComputedValues under DOM elements were tallied under the the
'dom/element-nodes' sub-tree, and ComputedValues not under DOM element were
ignored.) 'servo-style-structs/sundries' aggregates all the style structs that
are smaller than 8 KiB.
Other notable things done by the patch are as follows.
- It significantly changes the signatures of the methods measuring nsINode and
its subclasses, in order to handle the tallying of style structs separately
from element-nodes. Likewise for nsIFrame.
- It renames the 'layout/style-structs' sub-tree as
'layout/gecko-style-structs', to clearly distinguish it from the new
'layout/servo-style-structs' sub-tree.
- It adds some FFI functions to access various Rust-side data structures from
C++ code.
- There is a nasty hack used twice to measure Arcs, by stepping backwards from
an interior pointer to a base pointer. It works, but I want to replace it
with something better eventually. The "XXX WARNING" comments have details.
- It makes DMD print a line to the console if it sees a pointer it doesn't
recognise. This is useful for detecting when we are measuring an interior
pointer instead of a base pointer, which is bad but easy to do when Arcs are
involved.
- It removes the Rust code for measuring CVs, because it's now all done on the
C++ side.
MozReview-Commit-ID: BKebACLKtCi
--HG--
extra : rebase_source : 4d9a8c6b198a0ff025b811759a6bfa9f33a260ba
2017-08-11 09:37:33 +03:00
|
|
|
}
|
|
|
|
#define STYLE_STRUCT_LIST_IGNORE_VARIABLES
|
|
|
|
#include "nsStyleStructList.h"
|
|
|
|
#undef STYLE_STRUCT
|
|
|
|
#undef STYLE_STRUCT_LIST_IGNORE_VARIABLES
|
|
|
|
|
2017-08-25 07:59:44 +03:00
|
|
|
if (servoStyleSundriesSize > 0) {
|
2017-09-25 02:59:50 +03:00
|
|
|
REPORT_SUM_SIZE(
|
|
|
|
"/layout/servo-style-structs/sundries", servoStyleSundriesSize,
|
|
|
|
"The sum of all memory used by Servo style structs which were too "
|
|
|
|
"small to be shown individually.");
|
Bug 1387956 - Overhaul ComputedValues measurement, and add style structs measurement. r=bholley.
This patch moves measurement of ComputedValues objects from Rust to C++.
Measurement now happens (a) via DOM elements and (b) remaining elements via
the frame tree. Likewise for the style structs hanging off ComputedValues
objects.
Here is an example of the output.
> ├──27,600,448 B (26.49%) -- active/window(https://en.wikipedia.org/wiki/Barack_Obama)
> │ ├──12,772,544 B (12.26%) -- layout
> │ │ ├───4,483,744 B (04.30%) -- frames
> │ │ │ ├──1,653,552 B (01.59%) ── nsInlineFrame
> │ │ │ ├──1,415,760 B (01.36%) ── nsTextFrame
> │ │ │ ├────431,376 B (00.41%) ── nsBlockFrame
> │ │ │ ├────340,560 B (00.33%) ── nsHTMLScrollFrame
> │ │ │ ├────302,544 B (00.29%) ── nsContinuingTextFrame
> │ │ │ ├────156,408 B (00.15%) ── nsBulletFrame
> │ │ │ ├─────73,024 B (00.07%) ── nsPlaceholderFrame
> │ │ │ ├─────27,656 B (00.03%) ── sundries
> │ │ │ ├─────23,520 B (00.02%) ── nsTableCellFrame
> │ │ │ ├─────16,704 B (00.02%) ── nsImageFrame
> │ │ │ ├─────15,488 B (00.01%) ── nsTableRowFrame
> │ │ │ ├─────13,776 B (00.01%) ── nsTableColFrame
> │ │ │ └─────13,376 B (00.01%) ── nsTableFrame
> │ │ ├───3,412,192 B (03.28%) -- servo-style-structs
> │ │ │ ├──1,288,224 B (01.24%) ── Display
> │ │ │ ├────742,400 B (00.71%) ── Position
> │ │ │ ├────308,736 B (00.30%) ── Font
> │ │ │ ├────226,512 B (00.22%) ── Background
> │ │ │ ├────218,304 B (00.21%) ── TextReset
> │ │ │ ├────214,896 B (00.21%) ── Text
> │ │ │ ├────130,560 B (00.13%) ── Border
> │ │ │ ├─────81,408 B (00.08%) ── UIReset
> │ │ │ ├─────61,440 B (00.06%) ── Padding
> │ │ │ ├─────38,176 B (00.04%) ── UserInterface
> │ │ │ ├─────29,232 B (00.03%) ── Margin
> │ │ │ ├─────21,824 B (00.02%) ── sundries
> │ │ │ ├─────20,080 B (00.02%) ── Color
> │ │ │ ├─────20,080 B (00.02%) ── Column
> │ │ │ └─────10,320 B (00.01%) ── Effects
> │ │ ├───2,227,680 B (02.14%) -- computed-values
> │ │ │ ├──1,182,928 B (01.14%) ── non-dom
> │ │ │ └──1,044,752 B (01.00%) ── dom
> │ │ ├───1,500,016 B (01.44%) ── text-runs
> │ │ ├─────492,640 B (00.47%) ── line-boxes
> │ │ ├─────326,688 B (00.31%) ── frame-properties
> │ │ ├─────301,760 B (00.29%) ── pres-shell
> │ │ ├──────27,648 B (00.03%) ── pres-contexts
> │ │ └─────────176 B (00.00%) ── style-sets
The 'servo-style-structs' and 'computed-values' sub-trees are new. (Prior to
this patch, ComputedValues under DOM elements were tallied under the the
'dom/element-nodes' sub-tree, and ComputedValues not under DOM element were
ignored.) 'servo-style-structs/sundries' aggregates all the style structs that
are smaller than 8 KiB.
Other notable things done by the patch are as follows.
- It significantly changes the signatures of the methods measuring nsINode and
its subclasses, in order to handle the tallying of style structs separately
from element-nodes. Likewise for nsIFrame.
- It renames the 'layout/style-structs' sub-tree as
'layout/gecko-style-structs', to clearly distinguish it from the new
'layout/servo-style-structs' sub-tree.
- It adds some FFI functions to access various Rust-side data structures from
C++ code.
- There is a nasty hack used twice to measure Arcs, by stepping backwards from
an interior pointer to a base pointer. It works, but I want to replace it
with something better eventually. The "XXX WARNING" comments have details.
- It makes DMD print a line to the console if it sees a pointer it doesn't
recognise. This is useful for detecting when we are measuring an interior
pointer instead of a base pointer, which is bad but easy to do when Arcs are
involved.
- It removes the Rust code for measuring CVs, because it's now all done on the
C++ side.
MozReview-Commit-ID: BKebACLKtCi
--HG--
extra : rebase_source : 4d9a8c6b198a0ff025b811759a6bfa9f33a260ba
2017-08-11 09:37:33 +03:00
|
|
|
}
|
|
|
|
|
2013-10-28 13:47:18 +04:00
|
|
|
#undef REPORT_SIZE
|
2017-09-25 02:59:50 +03:00
|
|
|
#undef REPORT_SUM_SIZE
|
2013-10-28 13:47:18 +04:00
|
|
|
#undef REPORT_COUNT
|
2011-06-29 16:29:29 +04:00
|
|
|
}
|
|
|
|
|
2017-11-06 22:48:02 +03:00
|
|
|
typedef nsTArray< RefPtr<nsGlobalWindowInner> > WindowArray;
|
2011-12-09 09:42:20 +04:00
|
|
|
|
2011-06-29 15:01:07 +04:00
|
|
|
NS_IMETHODIMP
|
2016-08-24 08:23:45 +03:00
|
|
|
nsWindowMemoryReporter::CollectReports(nsIHandleReportCallback* aHandleReport,
|
|
|
|
nsISupports* aData, bool aAnonymize)
|
2011-12-09 09:42:20 +04:00
|
|
|
{
|
2017-11-06 22:48:02 +03:00
|
|
|
nsGlobalWindowInner::InnerWindowByIdTable* windowsById =
|
|
|
|
nsGlobalWindowInner::GetWindowsTable();
|
2011-12-09 09:42:20 +04:00
|
|
|
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;
|
2016-01-29 02:14:45 +03:00
|
|
|
for (auto iter = windowsById->Iter(); !iter.Done(); iter.Next()) {
|
|
|
|
windows.AppendElement(iter.Data());
|
|
|
|
}
|
2011-12-09 09:42:20 +04:00
|
|
|
|
2016-08-24 08:23:45 +03:00
|
|
|
// Get the IDs of all the "ghost" windows, and call aHandleReport->Callback()
|
|
|
|
// for each one.
|
2012-04-03 06:28:04 +04:00
|
|
|
nsTHashtable<nsUint64HashKey> ghostWindows;
|
|
|
|
CheckForGhostWindows(&ghostWindows);
|
2015-07-22 19:42:01 +03:00
|
|
|
for (auto iter = ghostWindows.ConstIter(); !iter.Done(); iter.Next()) {
|
2017-11-06 22:48:02 +03:00
|
|
|
nsGlobalWindowInner::InnerWindowByIdTable* windowsById =
|
|
|
|
nsGlobalWindowInner::GetWindowsTable();
|
2015-07-22 19:42:01 +03:00
|
|
|
if (!windowsById) {
|
|
|
|
NS_WARNING("Couldn't get window-by-id hashtable?");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2017-11-06 22:48:02 +03:00
|
|
|
nsGlobalWindowInner* window = windowsById->Get(iter.Get()->GetKey());
|
2015-07-22 19:42:01 +03:00
|
|
|
if (!window) {
|
|
|
|
NS_WARNING("Could not look up window?");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsAutoCString path;
|
|
|
|
path.AppendLiteral("ghost-windows/");
|
|
|
|
AppendWindowURI(window, path, aAnonymize);
|
|
|
|
|
2016-08-24 08:23:45 +03:00
|
|
|
aHandleReport->Callback(
|
2015-07-22 19:42:01 +03:00
|
|
|
/* process = */ EmptyCString(),
|
|
|
|
path,
|
|
|
|
nsIMemoryReporter::KIND_OTHER,
|
|
|
|
nsIMemoryReporter::UNITS_COUNT,
|
|
|
|
/* amount = */ 1,
|
|
|
|
/* description = */ NS_LITERAL_CSTRING("A ghost window."),
|
2016-08-24 08:23:45 +03:00
|
|
|
aData);
|
2015-07-22 19:42:01 +03:00
|
|
|
}
|
2012-04-03 06:28:04 +04:00
|
|
|
|
2017-09-07 02:06:58 +03:00
|
|
|
MOZ_COLLECT_REPORT(
|
|
|
|
"ghost-windows", KIND_OTHER, UNITS_COUNT, ghostWindows.Count(),
|
|
|
|
"The number of ghost windows present (the number of nodes underneath "
|
|
|
|
"explicit/window-objects/top(none)/ghost, modulo race conditions). A ghost "
|
2017-11-08 20:48:54 +03:00
|
|
|
"window is not shown in any tab, is not in a tab group with any "
|
|
|
|
"non-detached windows, and has met these criteria for at least "
|
2017-09-07 02:06:58 +03:00
|
|
|
"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.");
|
|
|
|
|
2012-07-06 08:12:37 +04:00
|
|
|
WindowPaths windowPaths;
|
2013-03-17 07:36:37 +04:00
|
|
|
WindowPaths topWindowPaths;
|
|
|
|
|
2011-12-09 09:42:20 +04:00
|
|
|
// Collect window memory usage.
|
2017-07-28 13:10:04 +03:00
|
|
|
SizeOfState fakeState(nullptr); // this won't be used
|
|
|
|
nsWindowSizes windowTotalSizes(fakeState);
|
2013-10-28 08:53:00 +04:00
|
|
|
nsCOMPtr<amIAddonManager> addonManager;
|
2015-07-04 04:29:00 +03:00
|
|
|
if (XRE_IsParentProcess()) {
|
2013-10-28 08:53:00 +04:00
|
|
|
// Only try to access the service from the main process.
|
|
|
|
addonManager = do_GetService("@mozilla.org/addons/integration;1");
|
|
|
|
}
|
2012-08-22 19:56:38 +04:00
|
|
|
for (uint32_t i = 0; i < windows.Length(); i++) {
|
2016-08-24 08:23:45 +03:00
|
|
|
CollectWindowReports(windows[i], addonManager,
|
|
|
|
&windowTotalSizes, &ghostWindows,
|
|
|
|
&windowPaths, &topWindowPaths, aHandleReport,
|
|
|
|
aData, aAnonymize);
|
2011-12-09 09:42:20 +04:00
|
|
|
}
|
2011-06-29 15:06:43 +04:00
|
|
|
|
2012-07-06 08:12:37 +04:00
|
|
|
// Report JS memory usage. We do this from here because the JS memory
|
2013-08-28 03:24:51 +04:00
|
|
|
// reporter needs to be passed |windowPaths|.
|
2016-08-24 08:23:45 +03:00
|
|
|
xpc::JSReporter::CollectReports(&windowPaths, &topWindowPaths,
|
|
|
|
aHandleReport, aData, aAnonymize);
|
2012-07-06 08:12:37 +04:00
|
|
|
|
2018-02-19 13:07:44 +03:00
|
|
|
#ifdef MOZ_XUL
|
|
|
|
nsXULPrototypeCache::CollectMemoryReports(aHandleReport, aData);
|
|
|
|
#endif
|
|
|
|
|
2016-08-24 08:23:45 +03:00
|
|
|
#define REPORT(_path, _amount, _desc) \
|
|
|
|
aHandleReport->Callback(EmptyCString(), NS_LITERAL_CSTRING(_path), \
|
|
|
|
KIND_OTHER, UNITS_BYTES, _amount, \
|
|
|
|
NS_LITERAL_CSTRING(_desc), aData);
|
2012-02-21 19:10:11 +04:00
|
|
|
|
2017-08-25 07:43:29 +03:00
|
|
|
REPORT("window-objects/dom/element-nodes",
|
|
|
|
windowTotalSizes.mDOMElementNodesSize,
|
2012-06-05 18:49:48 +04:00
|
|
|
"This is the sum of all windows' 'dom/element-nodes' numbers.");
|
|
|
|
|
2013-10-28 13:47:18 +04:00
|
|
|
REPORT("window-objects/dom/text-nodes", windowTotalSizes.mDOMTextNodesSize,
|
2012-06-05 18:49:48 +04:00
|
|
|
"This is the sum of all windows' 'dom/text-nodes' numbers.");
|
|
|
|
|
2013-10-28 13:47:18 +04:00
|
|
|
REPORT("window-objects/dom/cdata-nodes", windowTotalSizes.mDOMCDATANodesSize,
|
2012-06-05 18:49:48 +04:00
|
|
|
"This is the sum of all windows' 'dom/cdata-nodes' numbers.");
|
|
|
|
|
2013-10-28 13:47:18 +04:00
|
|
|
REPORT("window-objects/dom/comment-nodes", windowTotalSizes.mDOMCommentNodesSize,
|
2012-06-05 18:49:48 +04:00
|
|
|
"This is the sum of all windows' 'dom/comment-nodes' numbers.");
|
|
|
|
|
2013-10-28 13:47:18 +04:00
|
|
|
REPORT("window-objects/dom/event-targets", windowTotalSizes.mDOMEventTargetsSize,
|
2013-01-18 09:21:43 +04:00
|
|
|
"This is the sum of all windows' 'dom/event-targets' numbers.");
|
|
|
|
|
2017-08-25 07:44:24 +03:00
|
|
|
REPORT("window-objects/dom/performance",
|
|
|
|
windowTotalSizes.mDOMPerformanceUserEntries +
|
|
|
|
windowTotalSizes.mDOMPerformanceResourceEntries,
|
|
|
|
"This is the sum of all windows' 'dom/performance/' numbers.");
|
|
|
|
|
2013-10-28 13:47:18 +04:00
|
|
|
REPORT("window-objects/dom/other", windowTotalSizes.mDOMOtherSize,
|
2013-01-18 09:21:43 +04:00
|
|
|
"This is the sum of all windows' 'dom/other' numbers.");
|
|
|
|
|
2017-09-07 07:36:42 +03:00
|
|
|
REPORT("window-objects/layout/style-sheets",
|
|
|
|
windowTotalSizes.mLayoutStyleSheetsSize,
|
|
|
|
"This is the sum of all windows' 'layout/style-sheets' numbers.");
|
2013-01-18 09:21:43 +04:00
|
|
|
|
2017-08-25 07:43:29 +03:00
|
|
|
REPORT("window-objects/layout/pres-shell",
|
|
|
|
windowTotalSizes.mLayoutPresShellSize,
|
2013-01-18 09:21:43 +04:00
|
|
|
"This is the sum of all windows' 'layout/arenas' numbers.");
|
|
|
|
|
2017-08-30 11:21:26 +03:00
|
|
|
REPORT("window-objects/layout/gecko-style-sets",
|
|
|
|
windowTotalSizes.mLayoutGeckoStyleSets,
|
|
|
|
"This is the sum of all windows' 'layout/gecko-style-sets' numbers.");
|
|
|
|
|
|
|
|
REPORT("window-objects/layout/servo-style-sets",
|
|
|
|
windowTotalSizes.mLayoutServoStyleSetsStylistRuleTree +
|
Bug 1387958 - Measure the stylist during memory reporting. r=heycam.
Example output from the Obama Wikipedia page:
> ├──2,315,600 B (01.16%) -- stylist
> │ ├──1,916,928 B (00.96%) ── invalidation-map
> │ ├────228,800 B (00.11%) ── rule-tree
> │ ├────142,336 B (00.07%) ── element-and-pseudos-maps
> │ ├─────14,336 B (00.01%) ── revalidation-selectors
> │ ├──────9,648 B (00.00%) ── other
> │ └──────3,552 B (00.00%) ── precomputed-pseudos
This change requires new code to measure HashMaps, which uses the new
'malloc_enclosing_size_of' functions that can measure a heap block from an
interior pointer.
The patch changes MallocSizeOfFn to a newtype, and introduces
MallocEnclosingSizeOfFn alongside.
It also adds new traits: MallocSizeOfBox, MallocSizeOfVec, MallocSizeOfHash.
These each contain a single method that does shallow measurement of the
relevant type, which is often useful. (This is a different style to the
existing MallocSizeOf trait, which does deep measurement, but I'm moving away
from the always-deep-measurement style because it's less flexible.)
MozReview-Commit-ID: FgJCCmdw0ZF
--HG--
extra : rebase_source : c692c2073aa66020224489b97247c49de95a99a4
2017-09-05 04:38:45 +03:00
|
|
|
windowTotalSizes.mLayoutServoStyleSetsStylistElementAndPseudosMaps +
|
|
|
|
windowTotalSizes.mLayoutServoStyleSetsStylistInvalidationMap +
|
|
|
|
windowTotalSizes.mLayoutServoStyleSetsStylistRevalidationSelectors +
|
|
|
|
windowTotalSizes.mLayoutServoStyleSetsStylistOther +
|
2017-08-30 11:21:26 +03:00
|
|
|
windowTotalSizes.mLayoutServoStyleSetsOther,
|
|
|
|
"This is the sum of all windows' 'layout/servo-style-sets/' numbers.");
|
|
|
|
|
2017-09-08 17:12:25 +03:00
|
|
|
REPORT("window-objects/layout/servo-element-data-objects",
|
|
|
|
windowTotalSizes.mLayoutServoElementDataObjects,
|
|
|
|
"This is the sum of all windows' 'layout/servo-element-data-objects' "
|
|
|
|
"numbers.");
|
2017-08-25 07:43:29 +03:00
|
|
|
|
|
|
|
REPORT("window-objects/layout/text-runs", windowTotalSizes.mLayoutTextRunsSize,
|
|
|
|
"This is the sum of all windows' 'layout/text-runs' numbers.");
|
|
|
|
|
|
|
|
REPORT("window-objects/layout/pres-contexts",
|
|
|
|
windowTotalSizes.mLayoutPresContextSize,
|
|
|
|
"This is the sum of all windows' 'layout/pres-contexts' numbers.");
|
|
|
|
|
|
|
|
REPORT("window-objects/layout/frame-properties",
|
|
|
|
windowTotalSizes.mLayoutFramePropertiesSize,
|
|
|
|
"This is the sum of all windows' 'layout/frame-properties' numbers.");
|
|
|
|
|
2017-08-25 07:50:26 +03:00
|
|
|
REPORT("window-objects/layout/computed-values",
|
|
|
|
windowTotalSizes.mLayoutComputedValuesDom +
|
|
|
|
windowTotalSizes.mLayoutComputedValuesNonDom +
|
|
|
|
windowTotalSizes.mLayoutComputedValuesVisited,
|
|
|
|
"This is the sum of all windows' 'layout/computed-values/' numbers.");
|
|
|
|
|
2017-08-25 07:43:29 +03:00
|
|
|
REPORT("window-objects/property-tables",
|
|
|
|
windowTotalSizes.mPropertyTablesSize,
|
|
|
|
"This is the sum of all windows' 'property-tables' numbers.");
|
|
|
|
|
2012-06-12 07:32:26 +04:00
|
|
|
REPORT("window-objects/layout/line-boxes",
|
2017-08-10 07:14:09 +03:00
|
|
|
windowTotalSizes.mArenaSizes.mLineBoxes,
|
2012-06-06 21:35:40 +04:00
|
|
|
"This is the sum of all windows' 'layout/line-boxes' numbers.");
|
|
|
|
|
2012-06-12 07:32:26 +04:00
|
|
|
REPORT("window-objects/layout/rule-nodes",
|
2017-08-10 07:14:09 +03:00
|
|
|
windowTotalSizes.mArenaSizes.mRuleNodes,
|
2012-06-06 21:35:40 +04:00
|
|
|
"This is the sum of all windows' 'layout/rule-nodes' numbers.");
|
|
|
|
|
2012-06-12 07:32:26 +04:00
|
|
|
REPORT("window-objects/layout/style-contexts",
|
2017-08-10 07:14:09 +03:00
|
|
|
windowTotalSizes.mArenaSizes.mStyleContexts,
|
2012-06-06 21:35:40 +04:00
|
|
|
"This is the sum of all windows' 'layout/style-contexts' numbers.");
|
|
|
|
|
2017-08-25 07:59:44 +03:00
|
|
|
size_t geckoStyleTotal = 0;
|
|
|
|
#define STYLE_STRUCT(name_, cb_) \
|
|
|
|
geckoStyleTotal += \
|
|
|
|
windowTotalSizes.mArenaSizes.mGeckoStyleSizes.NS_STYLE_SIZES_FIELD(name_);
|
|
|
|
#define STYLE_STRUCT_LIST_IGNORE_VARIABLES
|
|
|
|
#include "nsStyleStructList.h"
|
|
|
|
#undef STYLE_STRUCT
|
|
|
|
#undef STYLE_STRUCT_LIST_IGNORE_VARIABLES
|
|
|
|
|
|
|
|
REPORT("window-objects/layout/gecko-style-structs", geckoStyleTotal,
|
|
|
|
"Memory used for style structs within windows. This is the sum of "
|
|
|
|
"all windows' 'layout/gecko-style-structs/' numbers.");
|
2015-05-27 05:08:42 +03:00
|
|
|
|
2012-06-06 21:29:16 +04:00
|
|
|
size_t frameTotal = 0;
|
2017-08-10 07:14:09 +03:00
|
|
|
#define FRAME_ID(classname, ...) \
|
|
|
|
frameTotal += windowTotalSizes.mArenaSizes.NS_ARENA_SIZES_FIELD(classname);
|
2017-05-26 13:11:11 +03:00
|
|
|
#define ABSTRACT_FRAME_ID(...)
|
2012-06-06 21:29:16 +04:00
|
|
|
#include "nsFrameIdList.h"
|
|
|
|
#undef FRAME_ID
|
2017-05-26 13:11:11 +03:00
|
|
|
#undef ABSTRACT_FRAME_ID
|
2012-06-06 21:29:16 +04:00
|
|
|
|
2012-06-12 07:32:26 +04:00
|
|
|
REPORT("window-objects/layout/frames", frameTotal,
|
2012-06-06 21:29:16 +04:00
|
|
|
"Memory used for layout frames within windows. "
|
|
|
|
"This is the sum of all windows' 'layout/frames/' numbers.");
|
|
|
|
|
2017-08-25 07:59:44 +03:00
|
|
|
size_t servoStyleTotal = 0;
|
Bug 1387956 - Overhaul ComputedValues measurement, and add style structs measurement. r=bholley.
This patch moves measurement of ComputedValues objects from Rust to C++.
Measurement now happens (a) via DOM elements and (b) remaining elements via
the frame tree. Likewise for the style structs hanging off ComputedValues
objects.
Here is an example of the output.
> ├──27,600,448 B (26.49%) -- active/window(https://en.wikipedia.org/wiki/Barack_Obama)
> │ ├──12,772,544 B (12.26%) -- layout
> │ │ ├───4,483,744 B (04.30%) -- frames
> │ │ │ ├──1,653,552 B (01.59%) ── nsInlineFrame
> │ │ │ ├──1,415,760 B (01.36%) ── nsTextFrame
> │ │ │ ├────431,376 B (00.41%) ── nsBlockFrame
> │ │ │ ├────340,560 B (00.33%) ── nsHTMLScrollFrame
> │ │ │ ├────302,544 B (00.29%) ── nsContinuingTextFrame
> │ │ │ ├────156,408 B (00.15%) ── nsBulletFrame
> │ │ │ ├─────73,024 B (00.07%) ── nsPlaceholderFrame
> │ │ │ ├─────27,656 B (00.03%) ── sundries
> │ │ │ ├─────23,520 B (00.02%) ── nsTableCellFrame
> │ │ │ ├─────16,704 B (00.02%) ── nsImageFrame
> │ │ │ ├─────15,488 B (00.01%) ── nsTableRowFrame
> │ │ │ ├─────13,776 B (00.01%) ── nsTableColFrame
> │ │ │ └─────13,376 B (00.01%) ── nsTableFrame
> │ │ ├───3,412,192 B (03.28%) -- servo-style-structs
> │ │ │ ├──1,288,224 B (01.24%) ── Display
> │ │ │ ├────742,400 B (00.71%) ── Position
> │ │ │ ├────308,736 B (00.30%) ── Font
> │ │ │ ├────226,512 B (00.22%) ── Background
> │ │ │ ├────218,304 B (00.21%) ── TextReset
> │ │ │ ├────214,896 B (00.21%) ── Text
> │ │ │ ├────130,560 B (00.13%) ── Border
> │ │ │ ├─────81,408 B (00.08%) ── UIReset
> │ │ │ ├─────61,440 B (00.06%) ── Padding
> │ │ │ ├─────38,176 B (00.04%) ── UserInterface
> │ │ │ ├─────29,232 B (00.03%) ── Margin
> │ │ │ ├─────21,824 B (00.02%) ── sundries
> │ │ │ ├─────20,080 B (00.02%) ── Color
> │ │ │ ├─────20,080 B (00.02%) ── Column
> │ │ │ └─────10,320 B (00.01%) ── Effects
> │ │ ├───2,227,680 B (02.14%) -- computed-values
> │ │ │ ├──1,182,928 B (01.14%) ── non-dom
> │ │ │ └──1,044,752 B (01.00%) ── dom
> │ │ ├───1,500,016 B (01.44%) ── text-runs
> │ │ ├─────492,640 B (00.47%) ── line-boxes
> │ │ ├─────326,688 B (00.31%) ── frame-properties
> │ │ ├─────301,760 B (00.29%) ── pres-shell
> │ │ ├──────27,648 B (00.03%) ── pres-contexts
> │ │ └─────────176 B (00.00%) ── style-sets
The 'servo-style-structs' and 'computed-values' sub-trees are new. (Prior to
this patch, ComputedValues under DOM elements were tallied under the the
'dom/element-nodes' sub-tree, and ComputedValues not under DOM element were
ignored.) 'servo-style-structs/sundries' aggregates all the style structs that
are smaller than 8 KiB.
Other notable things done by the patch are as follows.
- It significantly changes the signatures of the methods measuring nsINode and
its subclasses, in order to handle the tallying of style structs separately
from element-nodes. Likewise for nsIFrame.
- It renames the 'layout/style-structs' sub-tree as
'layout/gecko-style-structs', to clearly distinguish it from the new
'layout/servo-style-structs' sub-tree.
- It adds some FFI functions to access various Rust-side data structures from
C++ code.
- There is a nasty hack used twice to measure Arcs, by stepping backwards from
an interior pointer to a base pointer. It works, but I want to replace it
with something better eventually. The "XXX WARNING" comments have details.
- It makes DMD print a line to the console if it sees a pointer it doesn't
recognise. This is useful for detecting when we are measuring an interior
pointer instead of a base pointer, which is bad but easy to do when Arcs are
involved.
- It removes the Rust code for measuring CVs, because it's now all done on the
C++ side.
MozReview-Commit-ID: BKebACLKtCi
--HG--
extra : rebase_source : 4d9a8c6b198a0ff025b811759a6bfa9f33a260ba
2017-08-11 09:37:33 +03:00
|
|
|
#define STYLE_STRUCT(name_, cb_) \
|
2017-08-25 07:59:44 +03:00
|
|
|
servoStyleTotal += \
|
|
|
|
windowTotalSizes.mServoStyleSizes.NS_STYLE_SIZES_FIELD(name_);
|
Bug 1387956 - Overhaul ComputedValues measurement, and add style structs measurement. r=bholley.
This patch moves measurement of ComputedValues objects from Rust to C++.
Measurement now happens (a) via DOM elements and (b) remaining elements via
the frame tree. Likewise for the style structs hanging off ComputedValues
objects.
Here is an example of the output.
> ├──27,600,448 B (26.49%) -- active/window(https://en.wikipedia.org/wiki/Barack_Obama)
> │ ├──12,772,544 B (12.26%) -- layout
> │ │ ├───4,483,744 B (04.30%) -- frames
> │ │ │ ├──1,653,552 B (01.59%) ── nsInlineFrame
> │ │ │ ├──1,415,760 B (01.36%) ── nsTextFrame
> │ │ │ ├────431,376 B (00.41%) ── nsBlockFrame
> │ │ │ ├────340,560 B (00.33%) ── nsHTMLScrollFrame
> │ │ │ ├────302,544 B (00.29%) ── nsContinuingTextFrame
> │ │ │ ├────156,408 B (00.15%) ── nsBulletFrame
> │ │ │ ├─────73,024 B (00.07%) ── nsPlaceholderFrame
> │ │ │ ├─────27,656 B (00.03%) ── sundries
> │ │ │ ├─────23,520 B (00.02%) ── nsTableCellFrame
> │ │ │ ├─────16,704 B (00.02%) ── nsImageFrame
> │ │ │ ├─────15,488 B (00.01%) ── nsTableRowFrame
> │ │ │ ├─────13,776 B (00.01%) ── nsTableColFrame
> │ │ │ └─────13,376 B (00.01%) ── nsTableFrame
> │ │ ├───3,412,192 B (03.28%) -- servo-style-structs
> │ │ │ ├──1,288,224 B (01.24%) ── Display
> │ │ │ ├────742,400 B (00.71%) ── Position
> │ │ │ ├────308,736 B (00.30%) ── Font
> │ │ │ ├────226,512 B (00.22%) ── Background
> │ │ │ ├────218,304 B (00.21%) ── TextReset
> │ │ │ ├────214,896 B (00.21%) ── Text
> │ │ │ ├────130,560 B (00.13%) ── Border
> │ │ │ ├─────81,408 B (00.08%) ── UIReset
> │ │ │ ├─────61,440 B (00.06%) ── Padding
> │ │ │ ├─────38,176 B (00.04%) ── UserInterface
> │ │ │ ├─────29,232 B (00.03%) ── Margin
> │ │ │ ├─────21,824 B (00.02%) ── sundries
> │ │ │ ├─────20,080 B (00.02%) ── Color
> │ │ │ ├─────20,080 B (00.02%) ── Column
> │ │ │ └─────10,320 B (00.01%) ── Effects
> │ │ ├───2,227,680 B (02.14%) -- computed-values
> │ │ │ ├──1,182,928 B (01.14%) ── non-dom
> │ │ │ └──1,044,752 B (01.00%) ── dom
> │ │ ├───1,500,016 B (01.44%) ── text-runs
> │ │ ├─────492,640 B (00.47%) ── line-boxes
> │ │ ├─────326,688 B (00.31%) ── frame-properties
> │ │ ├─────301,760 B (00.29%) ── pres-shell
> │ │ ├──────27,648 B (00.03%) ── pres-contexts
> │ │ └─────────176 B (00.00%) ── style-sets
The 'servo-style-structs' and 'computed-values' sub-trees are new. (Prior to
this patch, ComputedValues under DOM elements were tallied under the the
'dom/element-nodes' sub-tree, and ComputedValues not under DOM element were
ignored.) 'servo-style-structs/sundries' aggregates all the style structs that
are smaller than 8 KiB.
Other notable things done by the patch are as follows.
- It significantly changes the signatures of the methods measuring nsINode and
its subclasses, in order to handle the tallying of style structs separately
from element-nodes. Likewise for nsIFrame.
- It renames the 'layout/style-structs' sub-tree as
'layout/gecko-style-structs', to clearly distinguish it from the new
'layout/servo-style-structs' sub-tree.
- It adds some FFI functions to access various Rust-side data structures from
C++ code.
- There is a nasty hack used twice to measure Arcs, by stepping backwards from
an interior pointer to a base pointer. It works, but I want to replace it
with something better eventually. The "XXX WARNING" comments have details.
- It makes DMD print a line to the console if it sees a pointer it doesn't
recognise. This is useful for detecting when we are measuring an interior
pointer instead of a base pointer, which is bad but easy to do when Arcs are
involved.
- It removes the Rust code for measuring CVs, because it's now all done on the
C++ side.
MozReview-Commit-ID: BKebACLKtCi
--HG--
extra : rebase_source : 4d9a8c6b198a0ff025b811759a6bfa9f33a260ba
2017-08-11 09:37:33 +03:00
|
|
|
#define STYLE_STRUCT_LIST_IGNORE_VARIABLES
|
|
|
|
#include "nsStyleStructList.h"
|
|
|
|
#undef STYLE_STRUCT
|
|
|
|
#undef STYLE_STRUCT_LIST_IGNORE_VARIABLES
|
|
|
|
|
2017-08-25 07:59:44 +03:00
|
|
|
REPORT("window-objects/layout/servo-style-structs", servoStyleTotal,
|
Bug 1387956 - Overhaul ComputedValues measurement, and add style structs measurement. r=bholley.
This patch moves measurement of ComputedValues objects from Rust to C++.
Measurement now happens (a) via DOM elements and (b) remaining elements via
the frame tree. Likewise for the style structs hanging off ComputedValues
objects.
Here is an example of the output.
> ├──27,600,448 B (26.49%) -- active/window(https://en.wikipedia.org/wiki/Barack_Obama)
> │ ├──12,772,544 B (12.26%) -- layout
> │ │ ├───4,483,744 B (04.30%) -- frames
> │ │ │ ├──1,653,552 B (01.59%) ── nsInlineFrame
> │ │ │ ├──1,415,760 B (01.36%) ── nsTextFrame
> │ │ │ ├────431,376 B (00.41%) ── nsBlockFrame
> │ │ │ ├────340,560 B (00.33%) ── nsHTMLScrollFrame
> │ │ │ ├────302,544 B (00.29%) ── nsContinuingTextFrame
> │ │ │ ├────156,408 B (00.15%) ── nsBulletFrame
> │ │ │ ├─────73,024 B (00.07%) ── nsPlaceholderFrame
> │ │ │ ├─────27,656 B (00.03%) ── sundries
> │ │ │ ├─────23,520 B (00.02%) ── nsTableCellFrame
> │ │ │ ├─────16,704 B (00.02%) ── nsImageFrame
> │ │ │ ├─────15,488 B (00.01%) ── nsTableRowFrame
> │ │ │ ├─────13,776 B (00.01%) ── nsTableColFrame
> │ │ │ └─────13,376 B (00.01%) ── nsTableFrame
> │ │ ├───3,412,192 B (03.28%) -- servo-style-structs
> │ │ │ ├──1,288,224 B (01.24%) ── Display
> │ │ │ ├────742,400 B (00.71%) ── Position
> │ │ │ ├────308,736 B (00.30%) ── Font
> │ │ │ ├────226,512 B (00.22%) ── Background
> │ │ │ ├────218,304 B (00.21%) ── TextReset
> │ │ │ ├────214,896 B (00.21%) ── Text
> │ │ │ ├────130,560 B (00.13%) ── Border
> │ │ │ ├─────81,408 B (00.08%) ── UIReset
> │ │ │ ├─────61,440 B (00.06%) ── Padding
> │ │ │ ├─────38,176 B (00.04%) ── UserInterface
> │ │ │ ├─────29,232 B (00.03%) ── Margin
> │ │ │ ├─────21,824 B (00.02%) ── sundries
> │ │ │ ├─────20,080 B (00.02%) ── Color
> │ │ │ ├─────20,080 B (00.02%) ── Column
> │ │ │ └─────10,320 B (00.01%) ── Effects
> │ │ ├───2,227,680 B (02.14%) -- computed-values
> │ │ │ ├──1,182,928 B (01.14%) ── non-dom
> │ │ │ └──1,044,752 B (01.00%) ── dom
> │ │ ├───1,500,016 B (01.44%) ── text-runs
> │ │ ├─────492,640 B (00.47%) ── line-boxes
> │ │ ├─────326,688 B (00.31%) ── frame-properties
> │ │ ├─────301,760 B (00.29%) ── pres-shell
> │ │ ├──────27,648 B (00.03%) ── pres-contexts
> │ │ └─────────176 B (00.00%) ── style-sets
The 'servo-style-structs' and 'computed-values' sub-trees are new. (Prior to
this patch, ComputedValues under DOM elements were tallied under the the
'dom/element-nodes' sub-tree, and ComputedValues not under DOM element were
ignored.) 'servo-style-structs/sundries' aggregates all the style structs that
are smaller than 8 KiB.
Other notable things done by the patch are as follows.
- It significantly changes the signatures of the methods measuring nsINode and
its subclasses, in order to handle the tallying of style structs separately
from element-nodes. Likewise for nsIFrame.
- It renames the 'layout/style-structs' sub-tree as
'layout/gecko-style-structs', to clearly distinguish it from the new
'layout/servo-style-structs' sub-tree.
- It adds some FFI functions to access various Rust-side data structures from
C++ code.
- There is a nasty hack used twice to measure Arcs, by stepping backwards from
an interior pointer to a base pointer. It works, but I want to replace it
with something better eventually. The "XXX WARNING" comments have details.
- It makes DMD print a line to the console if it sees a pointer it doesn't
recognise. This is useful for detecting when we are measuring an interior
pointer instead of a base pointer, which is bad but easy to do when Arcs are
involved.
- It removes the Rust code for measuring CVs, because it's now all done on the
C++ side.
MozReview-Commit-ID: BKebACLKtCi
--HG--
extra : rebase_source : 4d9a8c6b198a0ff025b811759a6bfa9f33a260ba
2017-08-11 09:37:33 +03:00
|
|
|
"Memory used for style structs within windows. This is the sum of "
|
|
|
|
"all windows' 'layout/servo-style-structs/' numbers.");
|
|
|
|
|
2012-02-21 19:10:11 +04:00
|
|
|
#undef REPORT
|
2013-01-18 09:21:43 +04:00
|
|
|
|
2011-06-29 15:01:07 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
uint32_t
|
2012-04-03 06:28:05 +04:00
|
|
|
nsWindowMemoryReporter::GetGhostTimeout()
|
|
|
|
{
|
|
|
|
return Preferences::GetUint("memory.ghost_window_timeout_seconds", 60);
|
|
|
|
}
|
|
|
|
|
2012-04-03 06:28:04 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsWindowMemoryReporter::Observe(nsISupports *aSubject, const char *aTopic,
|
2014-01-04 19:02:17 +04:00
|
|
|
const char16_t *aData)
|
2012-04-03 06:28:04 +04:00
|
|
|
{
|
2016-01-22 21:27:54 +03:00
|
|
|
if (!strcmp(aTopic, "after-minimize-memory-usage")) {
|
2012-04-03 06:28:05 +04:00
|
|
|
ObserveAfterMinimizeMemoryUsage();
|
2014-03-08 17:38:53 +04:00
|
|
|
} else if (!strcmp(aTopic, "cycle-collector-begin")) {
|
|
|
|
if (mCheckTimer) {
|
|
|
|
mCheckTimerWaitingForCCEnd = true;
|
|
|
|
KillCheckTimer();
|
|
|
|
}
|
|
|
|
mCycleCollectorIsRunning = true;
|
|
|
|
} else if (!strcmp(aTopic, "cycle-collector-end")) {
|
|
|
|
mCycleCollectorIsRunning = false;
|
|
|
|
if (mCheckTimerWaitingForCCEnd) {
|
|
|
|
mCheckTimerWaitingForCCEnd = false;
|
|
|
|
AsyncCheckForGhostWindows();
|
|
|
|
}
|
2012-04-03 06:28:05 +04:00
|
|
|
} else {
|
|
|
|
MOZ_ASSERT(false);
|
|
|
|
}
|
2012-04-02 18:37:04 +04:00
|
|
|
|
2012-04-03 06:28:05 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2012-04-03 06:28:04 +04:00
|
|
|
|
|
|
|
void
|
2017-11-06 22:48:02 +03:00
|
|
|
nsWindowMemoryReporter::ObserveDOMWindowDetached(nsGlobalWindowInner* aWindow)
|
2012-04-03 06:28:04 +04:00
|
|
|
{
|
2016-01-22 21:27:54 +03:00
|
|
|
nsWeakPtr weakWindow = do_GetWeakReference(static_cast<nsIDOMEventTarget*>(aWindow));
|
2012-04-03 06:28:04 +04:00
|
|
|
if (!weakWindow) {
|
|
|
|
NS_WARNING("Couldn't take weak reference to a window?");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mDetachedWindows.Put(weakWindow, TimeStamp());
|
|
|
|
|
2014-03-08 17:38:52 +04:00
|
|
|
AsyncCheckForGhostWindows();
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
void
|
2016-08-24 08:23:45 +03:00
|
|
|
nsWindowMemoryReporter::CheckTimerFired(nsITimer* aTimer, void* aData)
|
2014-03-08 17:38:52 +04:00
|
|
|
{
|
|
|
|
if (sWindowReporter) {
|
2014-03-08 17:38:53 +04:00
|
|
|
MOZ_ASSERT(!sWindowReporter->mCycleCollectorIsRunning);
|
2014-03-08 17:38:52 +04:00
|
|
|
sWindowReporter->CheckForGhostWindows();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsWindowMemoryReporter::AsyncCheckForGhostWindows()
|
|
|
|
{
|
|
|
|
if (mCheckTimer) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-03-08 17:38:53 +04:00
|
|
|
if (mCycleCollectorIsRunning) {
|
|
|
|
mCheckTimerWaitingForCCEnd = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-03-08 17:38:52 +04:00
|
|
|
// If more than kTimeBetweenChecks seconds have elapsed since the last check,
|
|
|
|
// timerDelay is 0. Otherwise, it is kTimeBetweenChecks, reduced by the time
|
|
|
|
// since the last check. Reducing the delay by the time since the last check
|
|
|
|
// prevents the timer from being completely starved if it is repeatedly killed
|
|
|
|
// and restarted.
|
|
|
|
int32_t timeSinceLastCheck = (TimeStamp::NowLoRes() - mLastCheckForGhostWindows).ToSeconds();
|
|
|
|
int32_t timerDelay = (kTimeBetweenChecks - std::min(timeSinceLastCheck, kTimeBetweenChecks)) * PR_MSEC_PER_SEC;
|
|
|
|
|
2017-10-16 09:15:40 +03:00
|
|
|
NS_NewTimerWithFuncCallback(getter_AddRefs(mCheckTimer),
|
|
|
|
CheckTimerFired, nullptr,
|
|
|
|
timerDelay, nsITimer::TYPE_ONE_SHOT,
|
|
|
|
"nsWindowMemoryReporter::AsyncCheckForGhostWindows_timer");
|
2012-04-03 06:28:05 +04:00
|
|
|
}
|
2012-04-03 06:28:04 +04:00
|
|
|
|
2012-04-03 06:28:05 +04:00
|
|
|
void
|
|
|
|
nsWindowMemoryReporter::ObserveAfterMinimizeMemoryUsage()
|
|
|
|
{
|
|
|
|
// Someone claims they've done enough GC/CCs so that all eligible windows
|
|
|
|
// have been free'd. So we deem that any windows which satisfy ghost
|
|
|
|
// criteria (1) and (2) now satisfy criterion (3) as well.
|
|
|
|
//
|
|
|
|
// To effect this change, we'll backdate some of our timestamps.
|
|
|
|
|
|
|
|
TimeStamp minTimeStamp = TimeStamp::Now() -
|
|
|
|
TimeDuration::FromSeconds(GetGhostTimeout());
|
|
|
|
|
2016-01-29 02:14:45 +03:00
|
|
|
for (auto iter = mDetachedWindows.Iter(); !iter.Done(); iter.Next()) {
|
|
|
|
TimeStamp& timeStamp = iter.Data();
|
|
|
|
if (!timeStamp.IsNull() && timeStamp > minTimeStamp) {
|
|
|
|
timeStamp = minTimeStamp;
|
2012-04-03 06:28:04 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Iterate over mDetachedWindows and update it to reflect the current state of
|
|
|
|
* the world. In particular:
|
|
|
|
*
|
|
|
|
* - Remove weak refs to windows which no longer exist.
|
|
|
|
*
|
|
|
|
* - Remove references to windows which are no longer detached.
|
|
|
|
*
|
|
|
|
* - Reset the timestamp on detached windows which share a domain with a
|
|
|
|
* non-detached window (they no longer meet ghost criterion (2)).
|
|
|
|
*
|
|
|
|
* - If a window now meets ghost criterion (2) but didn't before, set its
|
|
|
|
* timestamp to now.
|
|
|
|
*
|
|
|
|
* Additionally, if aOutGhostIDs is not null, fill it with the window IDs of
|
|
|
|
* all ghost windows we found.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
nsWindowMemoryReporter::CheckForGhostWindows(
|
2013-10-28 18:04:12 +04:00
|
|
|
nsTHashtable<nsUint64HashKey> *aOutGhostIDs /* = nullptr */)
|
2012-04-03 06:28:04 +04:00
|
|
|
{
|
2017-11-06 22:48:02 +03:00
|
|
|
nsGlobalWindowInner::InnerWindowByIdTable *windowsById =
|
|
|
|
nsGlobalWindowInner::GetWindowsTable();
|
2012-04-03 06:28:04 +04:00
|
|
|
if (!windowsById) {
|
|
|
|
NS_WARNING("GetWindowsTable returned null");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-03-08 17:38:52 +04:00
|
|
|
mLastCheckForGhostWindows = TimeStamp::NowLoRes();
|
|
|
|
KillCheckTimer();
|
|
|
|
|
2017-11-08 20:48:54 +03:00
|
|
|
nsTHashtable<nsPtrHashKey<TabGroup>> nonDetachedTabGroups;
|
2012-04-03 06:28:04 +04:00
|
|
|
|
2017-11-08 20:48:54 +03:00
|
|
|
// Populate nonDetachedTabGroups.
|
2015-10-27 08:22:10 +03:00
|
|
|
for (auto iter = windowsById->Iter(); !iter.Done(); iter.Next()) {
|
|
|
|
// Null outer window implies null top, but calling GetTop() when there's no
|
|
|
|
// outer window causes us to spew debug warnings.
|
2017-11-06 22:48:02 +03:00
|
|
|
nsGlobalWindowInner* window = iter.UserData();
|
2015-10-27 08:22:10 +03:00
|
|
|
if (!window->GetOuterWindow() || !window->GetTopInternal()) {
|
2017-11-08 20:48:54 +03:00
|
|
|
// This window is detached, so we don't care about its tab group.
|
2015-10-27 08:22:10 +03:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2017-11-08 20:48:54 +03:00
|
|
|
nonDetachedTabGroups.PutEntry(window->TabGroup());
|
2015-10-27 08:22:10 +03:00
|
|
|
}
|
2012-04-03 06:28:04 +04:00
|
|
|
|
|
|
|
// Update mDetachedWindows and write the ghost window IDs into aOutGhostIDs,
|
|
|
|
// if it's not null.
|
2016-01-29 02:14:45 +03:00
|
|
|
uint32_t ghostTimeout = GetGhostTimeout();
|
|
|
|
TimeStamp now = mLastCheckForGhostWindows;
|
2017-07-11 23:58:20 +03:00
|
|
|
mGhostWindowCount = 0;
|
2016-01-29 02:14:45 +03:00
|
|
|
for (auto iter = mDetachedWindows.Iter(); !iter.Done(); iter.Next()) {
|
|
|
|
nsWeakPtr weakKey = do_QueryInterface(iter.Key());
|
|
|
|
nsCOMPtr<mozIDOMWindow> iwindow = do_QueryReferent(weakKey);
|
|
|
|
if (!iwindow) {
|
|
|
|
// The window object has been destroyed. Stop tracking its weak ref in
|
|
|
|
// our hashtable.
|
|
|
|
iter.Remove();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsPIDOMWindowInner* window = nsPIDOMWindowInner::From(iwindow);
|
|
|
|
|
|
|
|
// Avoid calling GetTop() if we have no outer window. Nothing will break if
|
|
|
|
// we do, but it will spew debug output, which can cause our test logs to
|
|
|
|
// overflow.
|
|
|
|
nsCOMPtr<nsPIDOMWindowOuter> top;
|
|
|
|
if (window->GetOuterWindow()) {
|
|
|
|
top = window->GetOuterWindow()->GetTop();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (top) {
|
|
|
|
// The window is no longer detached, so we no longer want to track it.
|
|
|
|
iter.Remove();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
TimeStamp& timeStamp = iter.Data();
|
|
|
|
|
2017-11-08 20:48:54 +03:00
|
|
|
if (nonDetachedTabGroups.GetEntry(window->TabGroup())) {
|
|
|
|
// This window is in the same tab group as a non-detached
|
|
|
|
// window, so reset its clock.
|
2016-01-29 02:14:45 +03:00
|
|
|
timeStamp = TimeStamp();
|
|
|
|
} else {
|
2017-11-08 20:48:54 +03:00
|
|
|
// This window is not in the same tab group as a non-detached
|
|
|
|
// window, so it meets ghost criterion (2).
|
2016-01-29 02:14:45 +03:00
|
|
|
if (timeStamp.IsNull()) {
|
|
|
|
// This may become a ghost window later; start its clock.
|
|
|
|
timeStamp = now;
|
|
|
|
} else if ((now - timeStamp).ToSeconds() > ghostTimeout) {
|
|
|
|
// This definitely is a ghost window, so add it to aOutGhostIDs, if
|
|
|
|
// that is not null.
|
2017-07-11 23:58:20 +03:00
|
|
|
mGhostWindowCount++;
|
2016-01-29 02:14:45 +03:00
|
|
|
if (aOutGhostIDs && window) {
|
|
|
|
aOutGhostIDs->PutEntry(window->WindowID());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-04-03 06:28:04 +04:00
|
|
|
}
|
2012-04-03 06:28:05 +04:00
|
|
|
|
2013-09-20 02:52:30 +04:00
|
|
|
/* static */ int64_t
|
2017-09-07 02:06:58 +03:00
|
|
|
nsWindowMemoryReporter::GhostWindowsDistinguishedAmount()
|
2013-09-25 07:31:00 +04:00
|
|
|
{
|
2017-07-11 23:58:20 +03:00
|
|
|
return sWindowReporter->mGhostWindowCount;
|
2013-09-25 07:31:00 +04:00
|
|
|
}
|
2013-09-20 02:52:30 +04:00
|
|
|
|
2014-03-08 17:38:52 +04:00
|
|
|
void
|
|
|
|
nsWindowMemoryReporter::KillCheckTimer()
|
|
|
|
{
|
|
|
|
if (mCheckTimer) {
|
|
|
|
mCheckTimer->Cancel();
|
|
|
|
mCheckTimer = nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-21 00:55:40 +04:00
|
|
|
#ifdef DEBUG
|
|
|
|
/* static */ void
|
|
|
|
nsWindowMemoryReporter::UnlinkGhostWindows()
|
|
|
|
{
|
|
|
|
if (!sWindowReporter) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-11-06 22:48:02 +03:00
|
|
|
nsGlobalWindowInner::InnerWindowByIdTable* windowsById =
|
|
|
|
nsGlobalWindowInner::GetWindowsTable();
|
2014-02-21 00:55:40 +04:00
|
|
|
if (!windowsById) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Hold on to every window in memory so that window objects can't be
|
|
|
|
// destroyed while we're calling the UnlinkGhostWindows callback.
|
|
|
|
WindowArray windows;
|
2016-01-29 02:14:45 +03:00
|
|
|
for (auto iter = windowsById->Iter(); !iter.Done(); iter.Next()) {
|
|
|
|
windows.AppendElement(iter.Data());
|
|
|
|
}
|
2014-02-21 00:55:40 +04:00
|
|
|
|
|
|
|
// Get the IDs of all the "ghost" windows, and unlink them all.
|
|
|
|
nsTHashtable<nsUint64HashKey> ghostWindows;
|
|
|
|
sWindowReporter->CheckForGhostWindows(&ghostWindows);
|
2015-07-22 19:42:01 +03:00
|
|
|
for (auto iter = ghostWindows.ConstIter(); !iter.Done(); iter.Next()) {
|
2017-11-06 22:48:02 +03:00
|
|
|
nsGlobalWindowInner::InnerWindowByIdTable* windowsById =
|
|
|
|
nsGlobalWindowInner::GetWindowsTable();
|
2015-07-22 19:42:01 +03:00
|
|
|
if (!windowsById) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2017-11-06 22:48:02 +03:00
|
|
|
RefPtr<nsGlobalWindowInner> window = windowsById->Get(iter.Get()->GetKey());
|
2015-07-22 19:42:01 +03:00
|
|
|
if (window) {
|
|
|
|
window->RiskyUnlink();
|
|
|
|
}
|
|
|
|
}
|
2014-02-21 00:55:40 +04:00
|
|
|
}
|
|
|
|
#endif
|