Bug 682431 (part 2) - Add memory reporters for URIs and Links. r=biesi,bz,jlebar.
authorNicholas Nethercote <nnethercote@mozilla.com>
Sun, 19 Feb 2012 19:51:48 -0800
changeset 91129 e7c45d258c4e7c511d97c87d8dc8bcc0fff124e4
parent 91128 2893c5e0be5de24947b35923078ee2ba3e6fbf3e
child 91130 129ab3b6dff8754e673f1f6150d2dbf139a7a8c5
push idunknown
push userunknown
push dateunknown
reviewersbiesi, bz, jlebar
bugs682431
milestone13.0a1
Bug 682431 (part 2) - Add memory reporters for URIs and Links. r=biesi,bz,jlebar.
caps/src/nsNullPrincipalURI.cpp
caps/src/nsNullPrincipalURI.h
content/base/src/Link.cpp
content/base/src/Link.h
content/html/content/src/nsHTMLAnchorElement.cpp
content/html/content/src/nsHTMLAreaElement.cpp
content/html/content/src/nsHTMLLinkElement.cpp
image/decoders/icon/nsIconURI.cpp
netwerk/base/src/nsSimpleURI.cpp
netwerk/base/src/nsSimpleURI.h
netwerk/base/src/nsStandardURL.cpp
netwerk/base/src/nsStandardURL.h
toolkit/components/places/tests/cpp/mock_Link.h
xpcom/base/Makefile.in
xpcom/base/nsISizeOf.h
--- 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___ */