Bug 826521 (part 2) - Report memory used by event targets, especially XHRs. r=bz.

--HG--
extra : rebase_source : 543f0e367ce73477d62eca544137a101108a97be
This commit is contained in:
Nicholas Nethercote 2013-01-17 21:21:43 -08:00
parent 59b1ac9057
commit 23f321407b
7 changed files with 134 additions and 46 deletions

View File

@ -1,5 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 sw=2 et tw=80: */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -638,6 +638,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsXMLHttpRequest)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
NS_INTERFACE_MAP_ENTRY(nsISizeOfEventTarget)
NS_INTERFACE_MAP_END_INHERITING(nsXHREventTarget)
NS_IMPL_ADDREF_INHERITED(nsXMLHttpRequest, nsXHREventTarget)
@ -652,6 +653,33 @@ nsXMLHttpRequest::DisconnectFromOwner()
Abort();
}
size_t
nsXMLHttpRequest::SizeOfEventTargetIncludingThis(
nsMallocSizeOfFun aMallocSizeOf) const
{
size_t n = aMallocSizeOf(this);
n += mResponseBody.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
// Why is this safe? Because no-one else will report this string. The
// other possible sharers of this string are as follows.
//
// - The JS engine could hold copies if the JS code holds references, e.g.
// |var text = XHR.responseText|. However, those references will be via JS
// external strings, for which the JS memory reporter does *not* report the
// chars.
//
// - Binary extensions, but they're *extremely* unlikely to do any memory
// reporting.
//
n += mResponseText.SizeOfExcludingThisEvenIfShared(aMallocSizeOf);
return n;
// Measurement of the following members may be added later if DMD finds it is
// worthwhile:
// - lots
}
/* readonly attribute nsIChannel channel; */
NS_IMETHODIMP
nsXMLHttpRequest::GetChannel(nsIChannel **aChannel)

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -35,6 +36,7 @@
#include "nsDOMBlobBuilder.h"
#include "nsIPrincipal.h"
#include "nsIScriptObjectPrincipal.h"
#include "nsISizeOfEventTarget.h"
#include "mozilla/Assertions.h"
#include "mozilla/dom/BindingUtils.h"
@ -124,7 +126,8 @@ class nsXMLHttpRequest : public nsXHREventTarget,
public nsIInterfaceRequestor,
public nsSupportsWeakReference,
public nsIJSNativeInitializer,
public nsITimerCallback
public nsITimerCallback,
public nsISizeOfEventTarget
{
friend class nsXHRParseEndListener;
friend class nsXMLHttpRequestXPCOMifier;
@ -229,6 +232,10 @@ public:
NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
uint32_t argc, jsval* argv);
// nsISizeOfEventTarget
virtual size_t
SizeOfEventTargetIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
NS_FORWARD_NSIDOMEVENTTARGET(nsXHREventTarget::)
#ifdef DEBUG
@ -491,6 +498,7 @@ public:
void RootJSResultObjects();
virtual void DisconnectFromOwner();
protected:
friend class nsMultipartProxyListener;
@ -573,7 +581,7 @@ protected:
// accessed.
// Only used for DEFAULT and TEXT responseTypes.
nsString mResponseText;
// For DEFAULT responseType we use this to keep track of how far we've
// lazily decoded from mResponseBody to mResponseText
uint32_t mResponseBodyDecodedPos;

View File

@ -1,5 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=2 et tw=78: */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -23,6 +23,7 @@
#include "nsError.h"
#include "nsIIdleService.h"
#include "nsIPowerManagerService.h"
#include "nsISizeOfEventTarget.h"
#ifdef XP_WIN
#ifdef GetClassName
@ -11063,6 +11064,17 @@ nsPIDOMWindow::HasPerformanceSupport()
return Preferences::GetBool("dom.enable_performance", false);
}
static size_t
SizeOfEventTargetObjectsEntryExcludingThisFun(
nsPtrHashKey<nsDOMEventTargetHelper> *aEntry,
nsMallocSizeOfFun aMallocSizeOf,
void *arg)
{
nsISupports *supports = aEntry->GetKey();
nsCOMPtr<nsISizeOfEventTarget> iface = do_QueryInterface(supports);
return iface ? iface->SizeOfEventTargetIncludingThis(aMallocSizeOf) : 0;
}
void
nsGlobalWindow::SizeOfIncludingThis(nsWindowSizes* aWindowSizes) const
{
@ -11083,6 +11095,11 @@ nsGlobalWindow::SizeOfIncludingThis(nsWindowSizes* aWindowSizes) const
aWindowSizes->mDOMOther +=
mNavigator ?
mNavigator->SizeOfIncludingThis(aWindowSizes->mMallocSizeOf) : 0;
aWindowSizes->mDOMEventTargets +=
mEventTargetObjects.SizeOfExcludingThis(
SizeOfEventTargetObjectsEntryExcludingThisFun,
aWindowSizes->mMallocSizeOf);
}
// nsGlobalChromeWindow implementation

View File

@ -0,0 +1,39 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef nsISizeOfEventTarget_h___
#define nsISizeOfEventTarget_h___
#include "nsISupports.h"
#define NS_ISIZEOFEVENTTARGET_IID \
{0xa1e08cb9, 0x5455, 0x4593, \
{ 0xb4, 0x1f, 0x38, 0x7a, 0x85, 0x44, 0xd0, 0xb5 }}
/**
* This class is much the same as nsISizeOf, but is specifically for measuring
* the contents of nsGlobalWindow::mEventTargetObjects.
*
* We don't use nsISizeOf because if we did, any object belonging to
* mEventTargetObjects that implements nsISizeOf would be measured, which we
* may not want (perhaps because the object is also measured elsewhere).
*/
class nsISizeOfEventTarget : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISIZEOFEVENTTARGET_IID)
/**
* Measures the size of the things pointed to by the object, plus the object
* itself.
*/
virtual size_t
SizeOfEventTargetIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsISizeOfEventTarget, NS_ISIZEOFEVENTTARGET_IID)
#endif /* nsISizeOfEventTarget_h___ */

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -169,11 +170,6 @@ CollectWindowReports(nsGlobalWindow *aWindow,
nsWindowSizes windowSizes(WindowsMallocSizeOf);
aWindow->SizeOfIncludingThis(&windowSizes);
REPORT("/dom/other", windowSizes.mDOMOther,
"Memory used by a window's DOM, excluding element, text, CDATA, "
"and comment nodes.");
aWindowTotalSizes->mDOMOther += windowSizes.mDOMOther;
REPORT("/dom/element-nodes", windowSizes.mDOMElementNodes,
"Memory used by the element nodes in a window's DOM.");
aWindowTotalSizes->mDOMElementNodes += windowSizes.mDOMElementNodes;
@ -190,6 +186,16 @@ CollectWindowReports(nsGlobalWindow *aWindow,
"Memory used by the comment nodes in a window's DOM.");
aWindowTotalSizes->mDOMCommentNodes += windowSizes.mDOMCommentNodes;
REPORT("/dom/event-targets", windowSizes.mDOMEventTargets,
"Memory used by the event targets table in a window's DOM, and the "
"objects it points to, which include XHRs.");
aWindowTotalSizes->mDOMEventTargets += windowSizes.mDOMEventTargets;
REPORT("/dom/other", windowSizes.mDOMOther,
"Memory used by a window's DOM that isn't measured by the other "
"'dom/' numbers.");
aWindowTotalSizes->mDOMOther += windowSizes.mDOMOther;
REPORT("/property-tables",
windowSizes.mPropertyTables,
"Memory used for the property tables within a window.");
@ -263,7 +269,7 @@ CollectWindowReports(nsGlobalWindow *aWindow,
"The sum of all memory used by frames which were too small "
"to be shown individually.");
}
#undef REPORT
return NS_OK;
@ -332,66 +338,53 @@ nsWindowMemoryReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
NS_ENSURE_SUCCESS(rv, rv); \
} while (0)
REPORT("window-objects/dom/other", windowTotalSizes.mDOMOther,
"Memory used for the DOM within windows, "
"excluding element, text, CDATA, and comment nodes. "
"This is the sum of all windows' 'dom/other' numbers.");
REPORT("window-objects/dom/element-nodes", windowTotalSizes.mDOMElementNodes,
"Memory used for DOM element nodes within windows. "
"This is the sum of all windows' 'dom/element-nodes' numbers.");
REPORT("window-objects/dom/text-nodes", windowTotalSizes.mDOMTextNodes,
"Memory used for DOM text nodes within windows. "
"This is the sum of all windows' 'dom/text-nodes' numbers.");
REPORT("window-objects/dom/cdata-nodes", windowTotalSizes.mDOMCDATANodes,
"Memory used for DOM CDATA nodes within windows. "
"This is the sum of all windows' 'dom/cdata-nodes' numbers.");
REPORT("window-objects/dom/comment-nodes", windowTotalSizes.mDOMCommentNodes,
"Memory used for DOM comment nodes within windows. "
"This is the sum of all windows' 'dom/comment-nodes' numbers.");
REPORT("window-objects/dom/event-targets", windowTotalSizes.mDOMEventTargets,
"This is the sum of all windows' 'dom/event-targets' numbers.");
REPORT("window-objects/dom/other", windowTotalSizes.mDOMOther,
"This is the sum of all windows' 'dom/other' numbers.");
REPORT("window-objects/property-tables",
windowTotalSizes.mPropertyTables,
"Memory used for property tables within windows. "
"This is the sum of all windows' 'property-tables' numbers.");
REPORT("window-objects/style-sheets", windowTotalSizes.mStyleSheets,
"Memory used for style sheets within windows. "
REPORT("window-objects/style-sheets", windowTotalSizes.mStyleSheets,
"This is the sum of all windows' 'style-sheets' numbers.");
REPORT("window-objects/layout/pres-shell", windowTotalSizes.mLayoutPresShell,
"Memory used by layout PresShell and other related "
"areas within windows. This is the sum of all windows' "
"'layout/arenas' numbers.");
REPORT("window-objects/layout/pres-shell", windowTotalSizes.mLayoutPresShell,
"This is the sum of all windows' 'layout/arenas' numbers.");
REPORT("window-objects/layout/line-boxes",
windowTotalSizes.mArenaStats.mLineBoxes,
"Memory used for line-boxes within windows. "
windowTotalSizes.mArenaStats.mLineBoxes,
"This is the sum of all windows' 'layout/line-boxes' numbers.");
REPORT("window-objects/layout/rule-nodes",
windowTotalSizes.mArenaStats.mRuleNodes,
"Memory used for CSS rule nodes within windows. "
"This is the sum of all windows' 'layout/rule-nodes' numbers.");
REPORT("window-objects/layout/style-contexts",
windowTotalSizes.mArenaStats.mStyleContexts,
"Memory used for style contexts within windows. "
"This is the sum of all windows' 'layout/style-contexts' numbers.");
REPORT("window-objects/layout/style-sets", windowTotalSizes.mLayoutStyleSets,
"Memory used for style sets within windows. "
REPORT("window-objects/layout/style-sets", windowTotalSizes.mLayoutStyleSets,
"This is the sum of all windows' 'layout/style-sets' numbers.");
REPORT("window-objects/layout/text-runs", windowTotalSizes.mLayoutTextRuns,
"Memory used for text runs within windows. "
REPORT("window-objects/layout/text-runs", windowTotalSizes.mLayoutTextRuns,
"This is the sum of all windows' 'layout/text-runs' numbers.");
REPORT("window-objects/layout/pres-contexts", windowTotalSizes.mLayoutPresContext,
"Memory used for layout PresContexts within windows. "
"This is the sum of all windows' 'layout/pres-contexts' numbers.");
size_t frameTotal = 0;
@ -405,7 +398,7 @@ nsWindowMemoryReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
"This is the sum of all windows' 'layout/frames/' numbers.");
#undef REPORT
return NS_OK;
}
@ -463,7 +456,7 @@ BackdateTimeStampsEnumerator(nsISupports *aKey, TimeStamp &aTimeStamp,
void* aClosure)
{
TimeStamp *minTimeStamp = static_cast<TimeStamp*>(aClosure);
if (!aTimeStamp.IsNull() && aTimeStamp > *minTimeStamp) {
aTimeStamp = *minTimeStamp;
}

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
@ -34,6 +35,7 @@ public:
size_t mDOMTextNodes;
size_t mDOMCDATANodes;
size_t mDOMCommentNodes;
size_t mDOMEventTargets;
size_t mDOMOther;
size_t mStyleSheets;
size_t mLayoutPresShell;

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 50; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */