b=392351, implement about:memory framework core r=shaver, sr=bsmedberg
authorvladimir@pobox.com
Wed, 05 Mar 2008 16:40:58 -0800
changeset 12634 ae6e49c31d9a86bf0f4e4a06475a365bafbddaeb
parent 12633 7e18de88cc9c8ba8beb545d07cf407d721d648d3
child 12635 b27259a63f3384bb7ae849e3cc22e647f66085e9
push idunknown
push userunknown
push dateunknown
reviewersshaver, bsmedberg
bugs392351
milestone1.9b5pre
b=392351, implement about:memory framework core r=shaver, sr=bsmedberg
xpcom/base/Makefile.in
xpcom/base/nsIMemoryReporter.idl
xpcom/base/nsMemoryReporterManager.cpp
xpcom/base/nsMemoryReporterManager.h
xpcom/build/nsXPCOMCIDInternal.h
xpcom/build/nsXPComInit.cpp
--- a/xpcom/base/Makefile.in
+++ b/xpcom/base/Makefile.in
@@ -61,16 +61,17 @@ CPPSRCS		= \
 		nsExceptionService.cpp \
 		nsMemoryImpl.cpp \
 		nsTraceRefcntImpl.cpp \
 		nsInterfaceRequestorAgg.cpp \
 		nsUUIDGenerator.cpp \
 		nsSystemInfo.cpp \
 		nsCycleCollector.cpp \
 		nsStackWalk.cpp \
+		nsMemoryReporterManager.cpp \
 		$(NULL)
 
 ifdef GC_LEAK_DETECTOR
 CSRCS += nsGarbageCollector.c
 CPPSRCS += nsLeakDetector.cpp
 REQUIRES	+= boehm
 endif
 
@@ -102,17 +103,17 @@ endif
 SDK_XPIDLSRCS   = \
 		nsIDebug.idl               \
 		nsIInterfaceRequestor.idl  \
 		nsIMemory.idl		   \
 		nsIProgrammingLanguage.idl \
 		nsISupports.idl		   \
 		nsITraceRefcnt.idl         \
 		nsIWeakReference.idl	   \
-		nsrootidl.idl		   \
+		nsrootidl.idl
 
 SDK_HEADERS     = \
 		nsError.h \
 		nsISupportsBase.h \
 		nscore.h \
 		nsCycleCollector.h \
 		nsObjCExceptions.h \
 
@@ -121,16 +122,17 @@ XPIDLSRCS	= \
 		nsIConsoleMessage.idl \
 		nsIConsoleService.idl \
 		nsIErrorService.idl \
 		nsIException.idl \
 		nsIExceptionService.idl \
 		nsIVersionComparator.idl \
 		nsIUUIDGenerator.idl \
 		nsIMutable.idl \
+		nsIMemoryReporter.idl \
 		$(NULL)
 
 ifdef GC_LEAK_DETECTOR
 XPIDLSRCS       += nsILeakDetector.idl
 endif
 
 ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
 XPIDLSRCS	+= nsIMacUtils.idl
new file mode 100644
--- /dev/null
+++ b/xpcom/base/nsIMemoryReporter.idl
@@ -0,0 +1,103 @@
+/* -*- 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) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Vladimir Vukicevic <vladimir@pobox.com> (original author)
+ *
+ * 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 ***** */
+
+#include "nsISupports.idl"
+#include "nsISimpleEnumerator.idl"
+
+[scriptable, uuid(d298b942-3e66-4cd3-9ff5-46abc69147a7)]
+interface nsIMemoryReporter : nsISupports
+{
+  /*
+   * The path that this memory usage should be reported under.
+   *
+   * Normally "/"-delimited for organization.
+   */
+  readonly attribute string path;
+
+  /*
+   * A human-readable description of this memory usage report
+   */
+  readonly attribute string description;
+
+  /*
+   * The current amount of memory in use, as reported by this memory
+   * reporter.
+   */
+  readonly attribute long long memoryUsed;
+};
+
+[scriptable, uuid(63fc8fbd-509b-4fdb-93b4-2e6caeeddab1)]
+interface nsIMemoryReporterManager : nsISupports
+{
+  /*
+   * Return an enumerator of nsIMemoryReporters that are currently registered.
+   */
+  nsISimpleEnumerator enumerateReporters ();
+
+  /*
+   * Register the given nsIMemoryReporter.  It is an error to register
+   * more than one reporter with the same path.  After a reporter is
+   * registered, it will be available via enumerateReporters().  The
+   * Manager service will hold a strong reference to the given reporter.
+   */
+  void registerReporter (in nsIMemoryReporter reporter);
+
+  /*
+   * Unregister the given memory reporter.
+   */
+  void unregisterReporter (in nsIMemoryReporter reporter);
+};
+
+%{C++
+
+#define NS_MEMORY_REPORTER_IMPLEMENT(_classname,_path,_desc,_usageFunction,_dataptr) \
+    class MemoryReporter_##_classname : public nsIMemoryReporter {      \
+    public:                                                             \
+      NS_DECL_ISUPPORTS                                                 \
+      NS_IMETHOD GetPath(char **memoryPath) { *memoryPath = strdup(_path); return NS_OK; } \
+      NS_IMETHOD GetDescription(char **desc) { *desc = strdup(_desc); return NS_OK; } \
+      NS_IMETHOD GetMemoryUsed(PRInt64 *memoryUsed) { *memoryUsed = _usageFunction(_dataptr); return NS_OK; } \
+    };                                                                  \
+    NS_IMPL_ISUPPORTS1(MemoryReporter_##_classname, nsIMemoryReporter)
+
+#define NS_MEMORY_REPORTER_NAME(_classname)  MemoryReporter_##_classname
+
+NS_COM nsresult NS_RegisterMemoryReporter (nsIMemoryReporter *reporter);
+NS_COM nsresult NS_UnregisterMemoryReporter (nsIMemoryReporter *reporter);
+
+%}
new file mode 100644
--- /dev/null
+++ b/xpcom/base/nsMemoryReporterManager.cpp
@@ -0,0 +1,52 @@
+
+#include "nsCOMPtr.h"
+#include "nsServiceManagerUtils.h"
+#include "nsMemoryReporterManager.h"
+
+#include "nsArrayEnumerator.h"
+
+NS_IMPL_ISUPPORTS1(nsMemoryReporterManager, nsIMemoryReporterManager)
+
+NS_IMETHODIMP
+nsMemoryReporterManager::EnumerateReporters(nsISimpleEnumerator **result)
+{
+    return NS_NewArrayEnumerator(result, mReporters);
+}
+
+NS_IMETHODIMP
+nsMemoryReporterManager::RegisterReporter(nsIMemoryReporter *reporter)
+{
+    if (mReporters.IndexOf(reporter) != -1)
+        return NS_ERROR_FAILURE;
+
+    mReporters.AppendObject(reporter);
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMemoryReporterManager::UnregisterReporter(nsIMemoryReporter *reporter)
+{
+    if (!mReporters.RemoveObject(reporter))
+        return NS_ERROR_FAILURE;
+
+    return NS_OK;
+}
+
+nsresult
+NS_RegisterMemoryReporter (nsIMemoryReporter *reporter)
+{
+    nsCOMPtr<nsIMemoryReporterManager> mgr = do_GetService("@mozilla.org/memory-reporter-manager;1");
+    if (mgr == nsnull)
+        return NS_ERROR_FAILURE;
+    return mgr->RegisterReporter(reporter);
+}
+
+nsresult
+NS_UnregisterMemoryReporter (nsIMemoryReporter *reporter)
+{
+    nsCOMPtr<nsIMemoryReporterManager> mgr = do_GetService("@mozilla.org/memory-reporter-manager;1");
+    if (mgr == nsnull)
+        return NS_ERROR_FAILURE;
+    return mgr->UnregisterReporter(reporter);
+}
+
new file mode 100644
--- /dev/null
+++ b/xpcom/base/nsMemoryReporterManager.h
@@ -0,0 +1,17 @@
+
+#include "nsIMemoryReporter.h"
+#include "nsCOMArray.h"
+
+class nsMemoryReporterManager : public nsIMemoryReporterManager
+{
+public:
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIMEMORYREPORTERMANAGER
+
+private:
+    nsCOMArray<nsIMemoryReporter> mReporters;
+};
+
+#define NS_MEMORY_REPORTER_MANAGER_CID \
+{ 0xfb97e4f5, 0x32dd, 0x497a, \
+{ 0xba, 0xa2, 0x7d, 0x1e, 0x55, 0x7, 0x99, 0x10 } }
--- a/xpcom/build/nsXPCOMCIDInternal.h
+++ b/xpcom/build/nsXPCOMCIDInternal.h
@@ -72,9 +72,14 @@
 #define NS_THREADPOOL_CONTRACTID "@mozilla.org/thread-pool;1"
 
 /**
  * The global proxy object manager.  This component is a singleton.
  * @implement nsIProxyObjectManager
  */
 #define NS_XPCOMPROXY_CONTRACTID "@mozilla.org/xpcomproxy;1"
 
+/**
+ * Memory reporter service CID
+ */
+#define NS_MEMORY_REPORTER_MANAGER_CONTRACTID "@mozilla.org/memory-reporter-manager;1"
+
 #endif  // nsXPCOMCIDInternal_h__
--- a/xpcom/build/nsXPComInit.cpp
+++ b/xpcom/build/nsXPComInit.cpp
@@ -131,16 +131,17 @@ NS_DECL_CLASSINFO(nsStringInputStream)
 #include "nsWindowsRegKey.h"
 #endif
 
 #ifdef XP_MACOSX
 #include "nsMacUtilsImpl.h"
 #endif
 
 #include "nsSystemInfo.h"
+#include "nsMemoryReporterManager.h"
 
 #include <locale.h>
 
 // Registry Factory creation function defined in nsRegistry.cpp
 // We hook into this function locally to create and register the registry
 // Since noone outside xpcom needs to know about this and nsRegistry.cpp
 // does not have a local include file, we are putting this definition
 // here rather than in nsIRegistry.h
@@ -224,16 +225,18 @@ NS_GENERIC_AGGREGATED_CONSTRUCTOR_INIT(n
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsUUIDGenerator, Init)
 
 #ifdef XP_MACOSX
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacUtilsImpl)
 #endif
 
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSystemInfo, Init)
 
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsMemoryReporterManager)
+
 static NS_METHOD
 nsThreadManagerGetSingleton(nsISupports* outer,
                             const nsIID& aIID,
                             void* *aInstancePtr)
 {
     NS_ASSERTION(aInstancePtr, "null outptr");
     NS_ENSURE_TRUE(!outer, NS_ERROR_NO_AGGREGATION);
 
@@ -439,16 +442,18 @@ static const nsModuleComponentInfo compo
     COMPONENT(WINDOWSREGKEY, nsWindowsRegKeyConstructor),
 #endif
 
 #ifdef XP_MACOSX
     COMPONENT(MACUTILSIMPL, nsMacUtilsImplConstructor),
 #endif
 
     COMPONENT(SYSTEMINFO, nsSystemInfoConstructor),
+#define NS_MEMORY_REPORTER_MANAGER_CLASSNAME "Memory Reporter Manager"
+    COMPONENT(MEMORY_REPORTER_MANAGER, nsMemoryReporterManagerConstructor),
 };
 
 #undef COMPONENT
 
 const int components_length = sizeof(components) / sizeof(components[0]);
 
 // gDebug will be freed during shutdown.
 static nsIDebug* gDebug = nsnull;