Bug 1102525 (part 1) - Add InfallibleAllocPolicy to mozalloc. r=glandium.
authorNicholas Nethercote <nnethercote@mozilla.com>
Mon, 08 Dec 2014 14:45:10 -0800
changeset 246331 c207ff1b40fd558a72b0f03ddf0a6edcf16f0117
parent 246330 2112c70ecc8b6d088588fb35d46ef5bc9d460f18
child 246332 96c0e71d648d4735a8d3e9da2fc9038f334906e5
push id698
push userjlund@mozilla.com
push dateMon, 23 Mar 2015 22:08:11 +0000
treeherdermozilla-release@b0c0ae7b02a3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersglandium
bugs1102525
milestone37.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 1102525 (part 1) - Add InfallibleAllocPolicy to mozalloc. r=glandium.
memory/mozalloc/mozalloc.h
memory/replace/dmd/DMD.cpp
mfbt/AllocPolicy.h
--- a/memory/mozalloc/mozalloc.h
+++ b/memory/mozalloc/mozalloc.h
@@ -16,16 +16,18 @@
 #include <string.h>
 #if defined(__cplusplus)
 #  include <new>
 #endif
 #include "xpcom-config.h"
 
 #if defined(__cplusplus)
 #include "mozilla/fallible.h"
+#include "mozilla/NullPtr.h"
+#include "mozilla/TemplateLib.h"
 #endif
 #include "mozilla/Attributes.h"
 
 #define MOZALLOC_HAVE_XMALLOC
 
 #if defined(MOZALLOC_EXPORT)
 /* do nothing: it's been defined to __declspec(dllexport) by
  * mozalloc*.cpp on platforms where that's required. */
@@ -289,12 +291,54 @@ void operator delete(void* ptr, const mo
 }
 
 MOZALLOC_INLINE
 void operator delete[](void* ptr, const mozilla::fallible_t&) MOZALLOC_THROW_IF_HAS_EXCEPTIONS
 {
     moz_free(ptr);
 }
 
+
+/*
+ * This policy is identical to MallocAllocPolicy, except it uses
+ * moz_xmalloc/moz_xcalloc/moz_xrealloc/moz_free instead of
+ * malloc/calloc/realloc/free.
+ */
+class InfallibleAllocPolicy
+{
+public:
+    template <typename T>
+    T* pod_malloc(size_t aNumElems)
+    {
+        if (aNumElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) {
+            return nullptr;
+        }
+        return static_cast<T*>(moz_xmalloc(aNumElems * sizeof(T)));
+    }
+
+    template <typename T>
+    T* pod_calloc(size_t aNumElems)
+    {
+        return static_cast<T*>(moz_xcalloc(aNumElems, sizeof(T)));
+    }
+
+    template <typename T>
+    T* pod_realloc(T* aPtr, size_t aOldSize, size_t aNewSize)
+    {
+        if (aNewSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value) {
+            return nullptr;
+        }
+        return static_cast<T*>(moz_xrealloc(aPtr, aNewSize * sizeof(T)));
+    }
+
+    void free_(void* aPtr)
+    {
+        moz_free(aPtr);
+    }
+
+    void reportAllocOverflow() const
+    {
+    }
+};
+
 #endif  /* ifdef __cplusplus */
 
-
 #endif /* ifndef mozilla_mozalloc_h */
--- a/memory/replace/dmd/DMD.cpp
+++ b/memory/replace/dmd/DMD.cpp
@@ -106,22 +106,28 @@ StatusMsg(const char* aFmt, ...)
 
 static const malloc_table_t* gMallocTable = nullptr;
 
 // Whether DMD finished initializing.
 static bool gIsDMDInitialized = false;
 
 // This provides infallible allocations (they abort on OOM).  We use it for all
 // of DMD's own allocations, which fall into the following three cases.
+//
 // - Direct allocations (the easy case).
+//
 // - Indirect allocations in js::{Vector,HashSet,HashMap} -- this class serves
 //   as their AllocPolicy.
+//
 // - Other indirect allocations (e.g. NS_StackWalk) -- see the comments on
 //   Thread::mBlockIntercepts and in replace_malloc for how these work.
 //
+// It would be nice if we could use the InfallibleAllocPolicy from mozalloc,
+// but DMD cannot use mozalloc.
+//
 class InfallibleAllocPolicy
 {
   static void ExitOnFailure(const void* aP);
 
 public:
   static void* malloc_(size_t aSize)
   {
     void* p = gMallocTable->malloc(aSize);
--- a/mfbt/AllocPolicy.h
+++ b/mfbt/AllocPolicy.h
@@ -50,32 +50,34 @@ namespace mozilla {
  * extra behaviors.
  */
 class MallocAllocPolicy
 {
 public:
   template <typename T>
   T* pod_malloc(size_t aNumElems)
   {
-    if (aNumElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value)
-        return nullptr;
+    if (aNumElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) {
+      return nullptr;
+    }
     return static_cast<T*>(malloc(aNumElems * sizeof(T)));
   }
 
   template <typename T>
   T* pod_calloc(size_t aNumElems)
   {
     return static_cast<T*>(calloc(aNumElems, sizeof(T)));
   }
 
   template <typename T>
   T* pod_realloc(T* aPtr, size_t aOldSize, size_t aNewSize)
   {
-    if (aNewSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value)
-        return nullptr;
+    if (aNewSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value) {
+      return nullptr;
+    }
     return static_cast<T*>(realloc(aPtr, aNewSize * sizeof(T)));
   }
 
   void free_(void* aPtr)
   {
     free(aPtr);
   }