Bug 1055280 - Move CountingAllocatorBase into its own header file. r=froydnj
authorAndrew McCreight <continuation@gmail.com>
Mon, 25 Aug 2014 12:34:00 -0700
changeset 223106 d5a6399121f1c495b70f9c69175bbae4ddf9dac5
parent 223105 4f7c6bf2b8feb44fedaa860d6e2c8242d3dc8ce4
child 223107 66ee1f1268d9a4952089e9242cb56e0d0d56070a
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1055280
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1055280 - Move CountingAllocatorBase into its own header file. r=froydnj
extensions/spellcheck/hunspell/src/mozHunspellAllocator.h
gfx/thebes/gfxAndroidPlatform.cpp
xpcom/base/CountingAllocatorBase.h
xpcom/base/moz.build
xpcom/base/nsIMemoryReporter.idl
xpcom/build/nsXPComInit.cpp
--- a/extensions/spellcheck/hunspell/src/mozHunspellAllocator.h
+++ b/extensions/spellcheck/hunspell/src/mozHunspellAllocator.h
@@ -2,15 +2,15 @@
 /* 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 mozHunspellAllocator_h__
 #define mozHunspellAllocator_h__
 
-#include "nsIMemoryReporter.h"
+#include "mozilla/CountingAllocatorBase.h"
 
 class HunspellAllocator : public mozilla::CountingAllocatorBase<HunspellAllocator>
 {
 };
 
 #endif
--- a/gfx/thebes/gfxAndroidPlatform.cpp
+++ b/gfx/thebes/gfxAndroidPlatform.cpp
@@ -3,16 +3,17 @@
 /* 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/. */
 
 #include "base/basictypes.h"
 
 #include "gfxAndroidPlatform.h"
 #include "mozilla/gfx/2D.h"
+#include "mozilla/CountingAllocatorBase.h"
 #include "mozilla/Preferences.h"
 
 #include "gfx2DGlue.h"
 #include "gfxFT2FontList.h"
 #include "gfxImageSurface.h"
 #include "mozilla/dom/ContentChild.h"
 #include "nsXULAppAPI.h"
 #include "nsIScreen.h"
new file mode 100644
--- /dev/null
+++ b/xpcom/base/CountingAllocatorBase.h
@@ -0,0 +1,138 @@
+/* -*- 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 CountingAllocatorBase_h
+#define CountingAllocatorBase_h
+
+#include "mozilla/Assertions.h"
+#include "mozilla/Atomics.h"
+#include "nsIMemoryReporter.h"
+
+namespace mozilla {
+
+// This CRTP class handles several details of wrapping allocators and should
+// be preferred to manually counting with MOZ_DEFINE_MALLOC_SIZE_OF_ON_ALLOC
+// and MOZ_DEFINE_MALLOC_SIZE_OF_ON_FREE.  The typical use is in a memory
+// reporter for a particular third party library:
+//
+//   class MyMemoryReporter : public CountingAllocatorBase<MyMemoryReporter>
+//   {
+//     ...
+//     NS_IMETHODIMP
+//     CollectReports(nsIHandleReportCallback* aHandleReport,
+//                    nsISupports* aData, bool aAnonymize)
+//     {
+//        return MOZ_COLLECT_REPORT(
+//          "explicit/path/to/somewhere", KIND_HEAP, UNITS_BYTES,
+//          MemoryAllocated(),
+//          "A description of what we are reporting."
+//     }
+//   };
+//
+//   ...somewhere later in the code...
+//   SetThirdPartyMemoryFunctions(MyMemoryReporter::CountingAlloc,
+//                                MyMemoryReporter::CountingFree);
+template<typename T>
+class CountingAllocatorBase
+{
+public:
+  CountingAllocatorBase()
+  {
+#ifdef DEBUG
+    // There must be only one instance of this class, due to |sAmount| being
+    // static.
+    static bool hasRun = false;
+    MOZ_ASSERT(!hasRun);
+    hasRun = true;
+#endif
+  }
+
+  static size_t
+  MemoryAllocated()
+  {
+    return sAmount;
+  }
+
+  static void*
+  CountingMalloc(size_t size)
+  {
+    void* p = malloc(size);
+    sAmount += MallocSizeOfOnAlloc(p);
+    return p;
+  }
+
+  static void*
+  CountingCalloc(size_t nmemb, size_t size)
+  {
+    void* p = calloc(nmemb, size);
+    sAmount += MallocSizeOfOnAlloc(p);
+    return p;
+  }
+
+  static void*
+  CountingRealloc(void* p, size_t size)
+  {
+    size_t oldsize = MallocSizeOfOnFree(p);
+    void *pnew = realloc(p, size);
+    if (pnew) {
+      size_t newsize = MallocSizeOfOnAlloc(pnew);
+      sAmount += newsize - oldsize;
+    } else if (size == 0) {
+      // We asked for a 0-sized (re)allocation of some existing pointer
+      // and received NULL in return.  0-sized allocations are permitted
+      // to either return NULL or to allocate a unique object per call (!).
+      // For a malloc implementation that chooses the second strategy,
+      // that allocation may fail (unlikely, but possible).
+      //
+      // Given a NULL return value and an allocation size of 0, then, we
+      // don't know if that means the original pointer was freed or if
+      // the allocation of the unique object failed.  If the original
+      // pointer was freed, then we have nothing to do here.  If the
+      // allocation of the unique object failed, the original pointer is
+      // still valid and we ought to undo the decrement from above.
+      // However, we have no way of knowing how the underlying realloc
+      // implementation is behaving.  Assuming that the original pointer
+      // was freed is the safest course of action.  We do, however, need
+      // to note that we freed memory.
+      sAmount -= oldsize;
+    } else {
+      // realloc failed.  The amount allocated hasn't changed.
+    }
+    return pnew;
+  }
+
+  // Some library code expects that realloc(x, 0) will free x, which is not
+  // the behavior of the version of jemalloc we're using, so this wrapped
+  // version of realloc is needed.
+  static void*
+  CountingFreeingRealloc(void* p, size_t size)
+  {
+    if (size == 0) {
+      CountingFree(p);
+      return nullptr;
+    }
+    return CountingRealloc(p, size);
+  }
+
+  static void
+  CountingFree(void* p)
+  {
+    sAmount -= MallocSizeOfOnFree(p);
+    free(p);
+  }
+
+private:
+  // |sAmount| can be (implicitly) accessed by multiple threads, so it
+  // must be thread-safe.
+  static Atomic<size_t> sAmount;
+
+  MOZ_DEFINE_MALLOC_SIZE_OF_ON_ALLOC(MallocSizeOfOnAlloc)
+  MOZ_DEFINE_MALLOC_SIZE_OF_ON_FREE(MallocSizeOfOnFree)
+};
+
+} // namespace mozilla
+
+#endif // CountingAllocatorBase_h
--- a/xpcom/base/moz.build
+++ b/xpcom/base/moz.build
@@ -67,16 +67,17 @@ if CONFIG['OS_ARCH'] == 'WINNT':
     ]
     if CONFIG['MOZ_DEBUG']:
         EXPORTS += ['pure.h']
         SOURCES += ['pure_api.c']
 
 EXPORTS.mozilla += [
     'AvailableMemoryTracker.h',
     'ClearOnShutdown.h',
+    'CountingAllocatorBase.h',
     'CycleCollectedJSRuntime.h',
     'Debug.h',
     'LinuxUtils.h',
     'nsMemoryInfoDumper.h',
     'StackWalk.h',
     'StaticMutex.h',
     'StaticPtr.h',
     'SystemMemoryReporter.h',
--- a/xpcom/base/nsIMemoryReporter.idl
+++ b/xpcom/base/nsIMemoryReporter.idl
@@ -439,17 +439,16 @@ interface nsIMemoryReporterManager : nsI
                  out double jsMilliseconds, out double nonJSMilliseconds);
 };
 
 %{C++
 
 #include "js/TypeDecls.h"
 #include "nsStringGlue.h"
 #include "nsTArray.h"
-#include "mozilla/Atomics.h"
 
 class nsPIDOMWindow;
 
 // nsIHandleReportCallback is a better name, but keep nsIMemoryReporterCallback
 // around for backwards compatibility.
 typedef nsIMemoryReporterCallback nsIHandleReportCallback;
 
 namespace mozilla {
@@ -569,140 +568,16 @@ void RunReportersForThisProcess();
       return moz_malloc_size_of(aPtr);                                        \
   }
 #define MOZ_DEFINE_MALLOC_SIZE_OF_ON_FREE(fn)                                 \
   static size_t fn(const void* aPtr)                                          \
   {                                                                           \
       return moz_malloc_size_of(aPtr);                                        \
   }
 
-namespace mozilla {
-
-// This CRTP class handles several details of wrapping allocators and should
-// be preferred to manually counting with MOZ_DEFINE_MALLOC_SIZE_OF_ON_ALLOC
-// and MOZ_DEFINE_MALLOC_SIZE_OF_ON_FREE.  The typical use is in a memory
-// reporter for a particular third party library:
-//
-//   class MyMemoryReporter : public CountingAllocatorBase<MyMemoryReporter>
-//   {
-//     ...
-//     NS_IMETHODIMP
-//     CollectReports(nsIHandleReportCallback* aHandleReport,
-//                    nsISupports* aData, bool aAnonymize)
-//     {
-//        return MOZ_COLLECT_REPORT(
-//          "explicit/path/to/somewhere", KIND_HEAP, UNITS_BYTES,
-//          MemoryAllocated(),
-//          "A description of what we are reporting."
-//     }
-//   };
-//
-//   ...somewhere later in the code...
-//   SetThirdPartyMemoryFunctions(MyMemoryReporter::CountingAlloc,
-//                                MyMemoryReporter::CountingFree);
-template<typename T>
-class CountingAllocatorBase
-{
-public:
-  CountingAllocatorBase()
-  {
-#ifdef DEBUG
-    // There must be only one instance of this class, due to |sAmount| being
-    // static.
-    static bool hasRun = false;
-    MOZ_ASSERT(!hasRun);
-    hasRun = true;
-#endif
-  }
-
-  static size_t
-  MemoryAllocated()
-  {
-    return sAmount;
-  }
-
-  static void*
-  CountingMalloc(size_t size)
-  {
-    void* p = malloc(size);
-    sAmount += MallocSizeOfOnAlloc(p);
-    return p;
-  }
-
-  static void*
-  CountingCalloc(size_t nmemb, size_t size)
-  {
-    void* p = calloc(nmemb, size);
-    sAmount += MallocSizeOfOnAlloc(p);
-    return p;
-  }
-
-  static void*
-  CountingRealloc(void* p, size_t size)
-  {
-    size_t oldsize = MallocSizeOfOnFree(p);
-    void *pnew = realloc(p, size);
-    if (pnew) {
-      size_t newsize = MallocSizeOfOnAlloc(pnew);
-      sAmount += newsize - oldsize;
-    } else if (size == 0) {
-      // We asked for a 0-sized (re)allocation of some existing pointer
-      // and received NULL in return.  0-sized allocations are permitted
-      // to either return NULL or to allocate a unique object per call (!).
-      // For a malloc implementation that chooses the second strategy,
-      // that allocation may fail (unlikely, but possible).
-      //
-      // Given a NULL return value and an allocation size of 0, then, we
-      // don't know if that means the original pointer was freed or if
-      // the allocation of the unique object failed.  If the original
-      // pointer was freed, then we have nothing to do here.  If the
-      // allocation of the unique object failed, the original pointer is
-      // still valid and we ought to undo the decrement from above.
-      // However, we have no way of knowing how the underlying realloc
-      // implementation is behaving.  Assuming that the original pointer
-      // was freed is the safest course of action.  We do, however, need
-      // to note that we freed memory.
-      sAmount -= oldsize;
-    } else {
-      // realloc failed.  The amount allocated hasn't changed.
-    }
-    return pnew;
-  }
-
-  // Some library code expects that realloc(x, 0) will free x, which is not
-  // the behavior of the version of jemalloc we're using, so this wrapped
-  // version of realloc is needed.
-  static void*
-  CountingFreeingRealloc(void* p, size_t size)
-  {
-    if (size == 0) {
-      CountingFree(p);
-      return nullptr;
-    }
-    return CountingRealloc(p, size);
-  }
-
-  static void
-  CountingFree(void* p)
-  {
-    sAmount -= MallocSizeOfOnFree(p);
-    free(p);
-  }
-
-private:
-  // |sAmount| can be (implicitly) accessed by multiple threads, so it
-  // must be thread-safe.
-  static Atomic<size_t> sAmount;
-
-  MOZ_DEFINE_MALLOC_SIZE_OF_ON_ALLOC(MallocSizeOfOnAlloc)
-  MOZ_DEFINE_MALLOC_SIZE_OF_ON_FREE(MallocSizeOfOnFree)
-};
-
-}
-
 // This macro assumes the presence of appropriate |aHandleReport| and |aData|
 // variables.
 #define MOZ_COLLECT_REPORT(path, kind, units, amount, description)            \
   aHandleReport->Callback(EmptyCString(), NS_LITERAL_CSTRING(path),           \
                           kind, units, amount,                                \
                           NS_LITERAL_CSTRING(description), aData)
 
 %}
--- a/xpcom/build/nsXPComInit.cpp
+++ b/xpcom/build/nsXPComInit.cpp
@@ -124,16 +124,17 @@ extern nsresult nsStringInputStreamConst
 
 #include "base/at_exit.h"
 #include "base/command_line.h"
 #include "base/message_loop.h"
 
 #include "mozilla/ipc/BrowserProcessSubThread.h"
 #include "mozilla/AvailableMemoryTracker.h"
 #include "mozilla/ClearOnShutdown.h"
+#include "mozilla/CountingAllocatorBase.h"
 #include "mozilla/SystemMemoryReporter.h"
 
 #include "mozilla/ipc/GeckoChildProcessHost.h"
 
 #ifdef MOZ_VISUAL_EVENT_TRACER
 #include "mozilla/VisualEventTracer.h"
 #endif