Bug 682431 (part 2) - Add memory reporters for URIs and Links. r=biesi,bz,jlebar.
--- a/caps/src/nsNullPrincipalURI.cpp
+++ b/caps/src/nsNullPrincipalURI.cpp
@@ -62,21 +62,22 @@ nsNullPrincipalURI::nsNullPrincipalURI(c
static NS_DEFINE_CID(kNullPrincipalURIImplementationCID,
NS_NULLPRINCIPALURI_IMPLEMENTATION_CID);
NS_IMPL_THREADSAFE_ADDREF(nsNullPrincipalURI)
NS_IMPL_THREADSAFE_RELEASE(nsNullPrincipalURI)
NS_INTERFACE_MAP_BEGIN(nsNullPrincipalURI)
- NS_INTERFACE_MAP_ENTRY(nsISupports)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIURI)
if (aIID.Equals(kNullPrincipalURIImplementationCID))
foundInterface = static_cast<nsIURI *>(this);
else
NS_INTERFACE_MAP_ENTRY(nsIURI)
+ NS_INTERFACE_MAP_ENTRY(nsISizeOf)
NS_INTERFACE_MAP_END
////////////////////////////////////////////////////////////////////////////////
//// nsIURI
NS_IMETHODIMP
nsNullPrincipalURI::GetAsciiHost(nsACString &_host)
{
@@ -294,8 +295,24 @@ nsNullPrincipalURI::Resolve(const nsACSt
}
NS_IMETHODIMP
nsNullPrincipalURI::SchemeIs(const char *aScheme, bool *_schemeIs)
{
*_schemeIs = (0 == nsCRT::strcasecmp(mScheme.get(), aScheme));
return NS_OK;
}
+
+////////////////////////////////////////////////////////////////////////////////
+//// nsISizeOf
+
+size_t
+nsNullPrincipalURI::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
+{
+ return mScheme.SizeOfExcludingThisIfUnshared(aMallocSizeOf) +
+ mPath.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
+}
+
+size_t
+nsNullPrincipalURI::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const {
+ return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
+}
+
--- a/caps/src/nsNullPrincipalURI.h
+++ b/caps/src/nsNullPrincipalURI.h
@@ -40,30 +40,36 @@
/**
* This wraps nsSimpleURI so that all calls to it are done on the main thread.
*/
#ifndef __nsNullPrincipalURI_h__
#define __nsNullPrincipalURI_h__
#include "nsIURI.h"
+#include "nsISizeOf.h"
#include "nsAutoPtr.h"
#include "nsString.h"
// {51fcd543-3b52-41f7-b91b-6b54102236e6}
#define NS_NULLPRINCIPALURI_IMPLEMENTATION_CID \
{0x51fcd543, 0x3b52, 0x41f7, \
{0xb9, 0x1b, 0x6b, 0x54, 0x10, 0x22, 0x36, 0xe6} }
class nsNullPrincipalURI : public nsIURI
+ , public nsISizeOf
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIURI
+ // nsISizeOf
+ virtual size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
+ virtual size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
+
nsNullPrincipalURI(const nsCString &aSpec);
private:
nsCString mScheme;
nsCString mPath;
};
#endif // __nsNullPrincipalURI_h__
--- a/content/base/src/Link.cpp
+++ b/content/base/src/Link.cpp
@@ -36,16 +36,17 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "Link.h"
#include "nsEventStates.h"
#include "nsIURL.h"
+#include "nsISizeOf.h"
#include "nsContentUtils.h"
#include "nsEscape.h"
#include "nsGkAtoms.h"
#include "nsString.h"
#include "mozAutoDocUpdate.h"
#include "mozilla/Services.h"
@@ -526,10 +527,29 @@ Link::SetHrefAttribute(nsIURI *aURI)
NS_ASSERTION(aURI, "Null URI is illegal!");
nsCAutoString href;
(void)aURI->GetSpec(href);
(void)mElement->SetAttr(kNameSpaceID_None, nsGkAtoms::href,
NS_ConvertUTF8toUTF16(href), true);
}
+size_t
+Link::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
+{
+ size_t n = 0;
+
+ if (mCachedURI) {
+ nsCOMPtr<nsISizeOf> iface = do_QueryInterface(mCachedURI);
+ if (iface) {
+ n += iface->SizeOfIncludingThis(aMallocSizeOf);
+ }
+ }
+
+ // The following members don't need to be measured:
+ // - mElement, because it is a pointer-to-self used to avoid QIs
+ // - mHistory, because it is non-owning
+
+ return n;
+}
+
} // namespace dom
} // namespace mozilla
--- a/content/base/src/Link.h
+++ b/content/base/src/Link.h
@@ -126,16 +126,19 @@ public:
/**
* Checks if DNS Prefetching is ok
*
* @returns boolean
* Defaults to true; should be overridden for specialised cases
*/
virtual bool HasDeferredDNSPrefetchRequest() { return true; }
+ virtual size_t
+ SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
+
protected:
virtual ~Link();
bool HasCachedURI() const { return !!mCachedURI; }
private:
/**
* Unregisters from History so this node no longer gets notifications about
--- a/content/html/content/src/nsHTMLAnchorElement.cpp
+++ b/content/html/content/src/nsHTMLAnchorElement.cpp
@@ -91,18 +91,18 @@ public:
}
NS_SCRIPTABLE NS_IMETHOD SetInnerHTML(const nsAString& aInnerHTML) {
return nsGenericHTMLElement::SetInnerHTML(aInnerHTML);
}
// nsIDOMHTMLAnchorElement
NS_DECL_NSIDOMHTMLANCHORELEMENT
- // TODO: nsHTMLAnchorElement::SizeOfAnchorElement should call
- // Link::SizeOfExcludingThis(). See bug 682431.
+ // DOM memory reporter participant
+ NS_DECL_SIZEOF_EXCLUDING_THIS
// nsILink
NS_IMETHOD LinkAdded() { return NS_OK; }
NS_IMETHOD LinkRemoved() { return NS_OK; }
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIContent* aBindingParent,
bool aCompileEventHandlers);
@@ -515,8 +515,15 @@ nsHTMLAnchorElement::ParseAttribute(PRIn
}
nsEventStates
nsHTMLAnchorElement::IntrinsicState() const
{
return Link::LinkState() | nsGenericHTMLElement::IntrinsicState();
}
+size_t
+nsHTMLAnchorElement::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
+{
+ return nsGenericHTMLElement::SizeOfExcludingThis(aMallocSizeOf) +
+ Link::SizeOfExcludingThis(aMallocSizeOf);
+}
+
--- a/content/html/content/src/nsHTMLAreaElement.cpp
+++ b/content/html/content/src/nsHTMLAreaElement.cpp
@@ -56,18 +56,18 @@ class nsHTMLAreaElement : public nsGener
{
public:
nsHTMLAreaElement(already_AddRefed<nsINodeInfo> aNodeInfo);
virtual ~nsHTMLAreaElement();
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
- // TODO: nsHTMLAreaElement::SizeOfAnchorElement should call
- // Link::SizeOfExcludingThis(). See bug 682431.
+ // DOM memory reporter participant
+ NS_DECL_SIZEOF_EXCLUDING_THIS
// nsIDOMNode
NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
// nsIDOMElement
NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
// nsIDOMHTMLElement
@@ -330,8 +330,16 @@ nsHTMLAreaElement::GetHrefURI() const
return GetHrefURIForAnchors();
}
nsEventStates
nsHTMLAreaElement::IntrinsicState() const
{
return Link::LinkState() | nsGenericHTMLElement::IntrinsicState();
}
+
+size_t
+nsHTMLAreaElement::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
+{
+ return nsGenericHTMLElement::SizeOfExcludingThis(aMallocSizeOf) +
+ Link::SizeOfExcludingThis(aMallocSizeOf);
+}
+
--- a/content/html/content/src/nsHTMLLinkElement.cpp
+++ b/content/html/content/src/nsHTMLLinkElement.cpp
@@ -79,18 +79,18 @@ public:
NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
// nsIDOMHTMLElement
NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
// nsIDOMHTMLLinkElement
NS_DECL_NSIDOMHTMLLINKELEMENT
- // TODO: nsHTMLLinkElement::SizeOfAnchorElement should call
- // Link::SizeOfExcludingThis(). See bug 682431.
+ // DOM memory reporter participant
+ NS_DECL_SIZEOF_EXCLUDING_THIS
// nsILink
NS_IMETHOD LinkAdded();
NS_IMETHOD LinkRemoved();
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIContent* aBindingParent,
bool aCompileEventHandlers);
@@ -453,8 +453,16 @@ nsHTMLLinkElement::GetStyleSheetInfo(nsA
return;
}
nsEventStates
nsHTMLLinkElement::IntrinsicState() const
{
return Link::LinkState() | nsGenericHTMLElement::IntrinsicState();
}
+
+size_t
+nsHTMLLinkElement::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
+{
+ return nsGenericHTMLElement::SizeOfExcludingThis(aMallocSizeOf) +
+ Link::SizeOfExcludingThis(aMallocSizeOf);
+}
+
--- a/image/decoders/icon/nsIconURI.cpp
+++ b/image/decoders/icon/nsIconURI.cpp
@@ -93,17 +93,17 @@ nsMozIconURI::~nsMozIconURI()
}
NS_IMPL_THREADSAFE_ISUPPORTS2(nsMozIconURI, nsIMozIconURI, nsIURI)
#define MOZICON_SCHEME "moz-icon:"
#define MOZICON_SCHEME_LEN (sizeof(MOZICON_SCHEME) - 1)
////////////////////////////////////////////////////////////////////////////////
-// nsURI methods:
+// nsIURI methods:
NS_IMETHODIMP
nsMozIconURI::GetSpec(nsACString &aSpec)
{
aSpec = MOZICON_SCHEME;
if (mIconURL)
{
--- a/netwerk/base/src/nsSimpleURI.cpp
+++ b/netwerk/base/src/nsSimpleURI.cpp
@@ -76,16 +76,17 @@ nsSimpleURI::~nsSimpleURI()
NS_IMPL_ADDREF(nsSimpleURI)
NS_IMPL_RELEASE(nsSimpleURI)
NS_INTERFACE_TABLE_HEAD(nsSimpleURI)
NS_INTERFACE_TABLE5(nsSimpleURI, nsIURI, nsISerializable, nsIIPCSerializable, nsIClassInfo, nsIMutable)
NS_INTERFACE_TABLE_TO_MAP_SEGUE
if (aIID.Equals(kThisSimpleURIImplementationCID))
foundInterface = static_cast<nsIURI*>(this);
else
+ NS_INTERFACE_MAP_ENTRY(nsISizeOf)
NS_INTERFACE_MAP_END
////////////////////////////////////////////////////////////////////////////////
// nsISerializable methods:
NS_IMETHODIMP
nsSimpleURI::Read(nsIObjectInputStream* aStream)
{
@@ -651,8 +652,26 @@ nsSimpleURI::GetMutable(bool *value)
NS_IMETHODIMP
nsSimpleURI::SetMutable(bool value)
{
NS_ENSURE_ARG(mMutable || !value);
mMutable = value;
return NS_OK;
}
+
+//----------------------------------------------------------------------------
+// nsSimpleURI::nsISizeOf
+//----------------------------------------------------------------------------
+
+size_t
+nsSimpleURI::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
+{
+ return mScheme.SizeOfExcludingThisIfUnshared(aMallocSizeOf) +
+ mPath.SizeOfExcludingThisIfUnshared(aMallocSizeOf) +
+ mRef.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
+}
+
+size_t
+nsSimpleURI::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const {
+ return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
+}
+
--- a/netwerk/base/src/nsSimpleURI.h
+++ b/netwerk/base/src/nsSimpleURI.h
@@ -40,44 +40,56 @@
#include "nsIURL.h"
#include "nsAgg.h"
#include "nsISerializable.h"
#include "nsIIPCSerializable.h"
#include "nsString.h"
#include "nsIClassInfo.h"
#include "nsIMutable.h"
+#include "nsISizeOf.h"
#define NS_THIS_SIMPLEURI_IMPLEMENTATION_CID \
{ /* 0b9bb0c2-fee6-470b-b9b9-9fd9462b5e19 */ \
0x0b9bb0c2, \
0xfee6, \
0x470b, \
{0xb9, 0xb9, 0x9f, 0xd9, 0x46, 0x2b, 0x5e, 0x19} \
}
class nsSimpleURI : public nsIURI,
public nsISerializable,
public nsIIPCSerializable,
public nsIClassInfo,
- public nsIMutable
+ public nsIMutable,
+ public nsISizeOf
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIURI
NS_DECL_NSISERIALIZABLE
NS_DECL_NSIIPCSERIALIZABLE
NS_DECL_NSICLASSINFO
NS_DECL_NSIMUTABLE
// nsSimpleURI methods:
nsSimpleURI();
virtual ~nsSimpleURI();
+ // nsISizeOf
+ // Among the sub-classes that inherit (directly or indirectly) from
+ // nsSimpleURI, measurement of the following members may be added later if
+ // DMD finds it is worthwhile:
+ // - nsJSURI: mBaseURI
+ // - nsSimpleNestedURI: mInnerURI
+ // - nsBlobURI: mPrincipal
+ virtual size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
+ virtual size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
+
protected:
// enum used in a few places to specify how .ref attribute should be handled
enum RefHandlingEnum {
eIgnoreRef,
eHonorRef
};
// Helper to share code between Equals methods.
--- a/netwerk/base/src/nsStandardURL.cpp
+++ b/netwerk/base/src/nsStandardURL.cpp
@@ -973,16 +973,17 @@ NS_INTERFACE_MAP_BEGIN(nsStandardURL)
NS_INTERFACE_MAP_ENTRY(nsISerializable)
NS_INTERFACE_MAP_ENTRY(nsIIPCSerializable)
NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
NS_INTERFACE_MAP_ENTRY(nsIMutable)
// see nsStandardURL::Equals
if (aIID.Equals(kThisImplCID))
foundInterface = static_cast<nsIURI *>(this);
else
+ NS_INTERFACE_MAP_ENTRY(nsISizeOf)
NS_INTERFACE_MAP_END
//----------------------------------------------------------------------------
// nsStandardURL::nsIURI
//----------------------------------------------------------------------------
// result may contain unescaped UTF-8 characters
NS_IMETHODIMP
@@ -3063,8 +3064,31 @@ nsStandardURL::GetFlags(PRUint32 *aFlags
}
NS_IMETHODIMP
nsStandardURL::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
{
*aClassIDNoAlloc = kStandardURLCID;
return NS_OK;
}
+
+//----------------------------------------------------------------------------
+// nsStandardURL::nsISizeOf
+//----------------------------------------------------------------------------
+
+size_t
+nsStandardURL::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
+{
+ return mSpec.SizeOfExcludingThisIfUnshared(aMallocSizeOf) +
+ mOriginCharset.SizeOfExcludingThisIfUnshared(aMallocSizeOf) +
+ aMallocSizeOf(mHostA);
+
+ // Measurement of the following members may be added later if DMD finds it is
+ // worthwhile:
+ // - mParser
+ // - mFile
+}
+
+size_t
+nsStandardURL::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const {
+ return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
+}
+
--- a/netwerk/base/src/nsStandardURL.h
+++ b/netwerk/base/src/nsStandardURL.h
@@ -49,16 +49,17 @@
#include "nsIFile.h"
#include "nsIURLParser.h"
#include "nsIUnicodeEncoder.h"
#include "nsIObserver.h"
#include "nsIIOService.h"
#include "nsCOMPtr.h"
#include "nsURLHelper.h"
#include "nsIClassInfo.h"
+#include "nsISizeOf.h"
#include "prclist.h"
#ifdef NS_BUILD_REFCNT_LOGGING
#define DEBUG_DUMP_URLS_AT_SHUTDOWN
#endif
class nsIBinaryInputStream;
class nsIBinaryOutputStream;
@@ -70,28 +71,33 @@ class nsIPrefBranch;
// standard URL implementation
//-----------------------------------------------------------------------------
class nsStandardURL : public nsIFileURL
, public nsIStandardURL
, public nsISerializable
, public nsIIPCSerializable
, public nsIClassInfo
+ , public nsISizeOf
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIURI
NS_DECL_NSIURL
NS_DECL_NSIFILEURL
NS_DECL_NSISTANDARDURL
NS_DECL_NSISERIALIZABLE
NS_DECL_NSIIPCSERIALIZABLE
NS_DECL_NSICLASSINFO
NS_DECL_NSIMUTABLE
+ // nsISizeOf
+ virtual size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
+ virtual size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
+
nsStandardURL(bool aSupportsFileURL = false);
virtual ~nsStandardURL();
static void InitGlobalObjects();
static void ShutdownGlobalObjects();
public: /* internal -- HPUX compiler can't handle this being private */
//
@@ -110,17 +116,16 @@ public: /* internal -- HPUX compiler can
// is 'bar'.
void Merge(const nsCString &spec, const char separator, const URLSegment &right) {
if (mLen >= 0 &&
*(spec.get() + mPos + mLen) == separator &&
mPos + mLen + 1 == right.mPos) {
mLen += 1 + right.mLen;
}
}
-
};
//
// Pref observer
//
class nsPrefObserver : public nsIObserver
{
public:
--- a/toolkit/components/places/tests/cpp/mock_Link.h
+++ b/toolkit/components/places/tests/cpp/mock_Link.h
@@ -69,16 +69,21 @@ public:
{
// Notify our callback function.
mHandler(aState);
// Break the cycle so the object can be destroyed.
mDeathGrip = 0;
}
+ virtual size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
+ {
+ return 0; // the value shouldn't matter
+ }
+
~mock_Link() {
// Run the next test if we are supposed to.
if (mRunNextTest) {
run_next_test();
}
}
private:
@@ -130,12 +135,19 @@ Link::ResetLinkState(bool aNotify)
already_AddRefed<nsIURI>
Link::GetURI() const
{
NS_NOTREACHED("Unexpected call to Link::GetURI");
return nsnull; // suppress compiler warning
}
+size_t
+Link::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
+{
+ NS_NOTREACHED("Unexpected call to Link::SizeOfExcludingThis");
+ return 0;
+}
+
} // namespace dom
} // namespace mozilla
#endif // mock_Link_h__
--- a/xpcom/base/Makefile.in
+++ b/xpcom/base/Makefile.in
@@ -83,16 +83,17 @@ endif
EXPORTS = \
nsAgg.h \
nsAutoRef.h \
nsCom.h \
nsDebugImpl.h \
nsIAllocator.h \
nsIID.h \
+ nsISizeOf.h \
nsISupportsObsolete.h \
nsStackWalk.h \
nsTraceRefcntImpl.h \
nsWeakPtr.h \
nsInterfaceRequestorAgg.h \
dmd.h \
$(NULL)
new file mode 100644
--- /dev/null
+++ b/xpcom/base/nsISizeOf.h
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 50; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * mozilla.org
+ * Portions created by the Initial Developer are Copyright (C) 2012
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Nicholas Nethercote <nnethercote@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsISizeOf_h___
+#define nsISizeOf_h___
+
+#include "nsISupports.h"
+
+#define NS_ISIZEOF_IID \
+ {0x61d05579, 0xd7ec, 0x485c, \
+ { 0xa4, 0x0c, 0x31, 0xc7, 0x9a, 0x5c, 0xf9, 0xf3 }}
+
+class nsISizeOf : public nsISupports
+{
+public:
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISIZEOF_IID)
+
+ /**
+ * Measures the size of the things pointed to by the object.
+ */
+ virtual size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const = 0;
+
+ /**
+ * Like SizeOfExcludingThis, but also includes the size of the object itself.
+ */
+ virtual size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const = 0;
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(nsISizeOf, NS_ISIZEOF_IID)
+
+#endif /* nsISizeOf_h___ */