Bug 1081260 - Update the malloc counters if we successfully recover from OOM; r=jonco
authorTerrence Cole <terrence@mozilla.com>
Fri, 24 Apr 2015 10:58:22 -0700
changeset 240969 c18a8a916d4c8ab3b893c63335ce774f24b5972c
parent 240968 47ac094b1917b335ce292a4850fe5061918ab16d
child 240970 a12f0f05779c7d020bc130b844129be72a53110c
push id58979
push usertcole@mozilla.com
push dateFri, 24 Apr 2015 18:01:39 +0000
treeherdermozilla-inbound@c18a8a916d4c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco
bugs1081260
milestone40.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 1081260 - Update the malloc counters if we successfully recover from OOM; r=jonco
js/src/vm/MallocProvider.h
--- a/js/src/vm/MallocProvider.h
+++ b/js/src/vm/MallocProvider.h
@@ -54,26 +54,30 @@ struct MallocProvider
 {
     template <class T>
     T* pod_malloc() {
         return pod_malloc<T>(1);
     }
 
     template <class T>
     T* pod_malloc(size_t numElems) {
+        size_t bytes = numElems * sizeof(T);
         T* p = js_pod_malloc<T>(numElems);
         if (MOZ_LIKELY(p)) {
-            client()->updateMallocCounter(numElems * sizeof(T));
+            client()->updateMallocCounter(bytes);
             return p;
         }
         if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) {
             client()->reportAllocationOverflow();
             return nullptr;
         }
-        return (T*)client()->onOutOfMemory(AllocFunction::Malloc, numElems * sizeof(T));
+        p = (T*)client()->onOutOfMemory(AllocFunction::Malloc, bytes);
+        if (p)
+            client()->updateMallocCounter(bytes);
+        return p;
     }
 
     template <class T, class U>
     T* pod_malloc_with_extra(size_t numExtra) {
         if (MOZ_UNLIKELY(numExtra & mozilla::tl::MulOverflowMask<sizeof(U)>::value)) {
             client()->reportAllocationOverflow();
             return nullptr;
         }
@@ -82,61 +86,71 @@ struct MallocProvider
             client()->reportAllocationOverflow();
             return nullptr;
         }
         T* p = reinterpret_cast<T*>(js_pod_malloc<uint8_t>(bytes));
         if (MOZ_LIKELY(p)) {
             client()->updateMallocCounter(bytes);
             return p;
         }
-        return (T*)client()->onOutOfMemory(AllocFunction::Malloc, bytes);
+        p = (T*)client()->onOutOfMemory(AllocFunction::Malloc, bytes);
+        if (p)
+            client()->updateMallocCounter(bytes);
+        return p;
     }
 
     template <class T>
     mozilla::UniquePtr<T[], JS::FreePolicy>
     make_pod_array(size_t numElems) {
         return mozilla::UniquePtr<T[], JS::FreePolicy>(pod_malloc<T>(numElems));
     }
 
     template <class T>
     T* pod_calloc() {
         return pod_calloc<T>(1);
     }
 
     template <class T>
     T* pod_calloc(size_t numElems) {
+        size_t bytes = numElems * sizeof(T);
         T* p = js_pod_calloc<T>(numElems);
         if (MOZ_LIKELY(p)) {
-            client()->updateMallocCounter(numElems * sizeof(T));
+            client()->updateMallocCounter(bytes);
             return p;
         }
         if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) {
             client()->reportAllocationOverflow();
             return nullptr;
         }
-        return (T*)client()->onOutOfMemory(AllocFunction::Calloc, numElems * sizeof(T));
+        p = (T*)client()->onOutOfMemory(AllocFunction::Calloc, bytes);
+        if (p)
+            client()->updateMallocCounter(bytes);
+        return p;
     }
 
     template <class T, class U>
     T* pod_calloc_with_extra(size_t numExtra) {
         if (MOZ_UNLIKELY(numExtra & mozilla::tl::MulOverflowMask<sizeof(U)>::value)) {
             client()->reportAllocationOverflow();
             return nullptr;
         }
         size_t bytes = sizeof(T) + numExtra * sizeof(U);
         if (MOZ_UNLIKELY(bytes < sizeof(T))) {
             client()->reportAllocationOverflow();
             return nullptr;
         }
         T* p = reinterpret_cast<T*>(js_pod_calloc<uint8_t>(bytes));
-        if (MOZ_LIKELY(p)) {
+        if (p) {
             client()->updateMallocCounter(bytes);
             return p;
         }
-        return (T*)client()->onOutOfMemory(AllocFunction::Calloc, bytes);
+        p = (T*)client()->onOutOfMemory(AllocFunction::Calloc, bytes);
+        if (p)
+            client()->updateMallocCounter(bytes);
+        return p;
     }
 
     template <class T>
     mozilla::UniquePtr<T[], JS::FreePolicy>
     make_zeroed_pod_array(size_t numElems)
     {
         return mozilla::UniquePtr<T[], JS::FreePolicy>(pod_calloc<T>(numElems));
     }
@@ -150,17 +164,20 @@ struct MallocProvider
             if (newSize > oldSize)
                 client()->updateMallocCounter((newSize - oldSize) * sizeof(T));
             return p;
         }
         if (newSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value) {
             client()->reportAllocationOverflow();
             return nullptr;
         }
-        return (T*)client()->onOutOfMemory(AllocFunction::Realloc, newSize * sizeof(T), prior);
+        p = (T*)client()->onOutOfMemory(AllocFunction::Realloc, newSize * sizeof(T), prior);
+        if (p && newSize > oldSize)
+            client()->updateMallocCounter((newSize - oldSize) * sizeof(T));
+        return p;
     }
 
     JS_DECLARE_NEW_METHODS(new_, pod_malloc<uint8_t>, MOZ_ALWAYS_INLINE)
     JS_DECLARE_MAKE_METHODS(make_unique, new_, MOZ_ALWAYS_INLINE)
 
   private:
     Client* client() { return static_cast<Client*>(this); }
 };