Bug 1517823 - Part 2: Pass arena to MallocProvider client. r=sfink
authorAndré Bargull <andre.bargull@gmail.com>
Mon, 07 Jan 2019 05:47:09 -0800
changeset 510012 752c683e631d73518b21da4b0924ac80ce1f6d5f
parent 510011 3d09512072a5b37eb90f38a9490f89264be90356
child 510013 d949e9cf60ab5852a24d43f737279709c9a257b5
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1517823
milestone66.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 1517823 - Part 2: Pass arena to MallocProvider client. r=sfink
js/src/builtin/TestingFunctions.cpp
js/src/gc/Zone.cpp
js/src/gc/Zone.h
js/src/util/AllocPolicy.cpp
js/src/vm/JSContext.h
js/src/vm/MallocProvider.h
js/src/vm/Runtime.cpp
js/src/vm/Runtime.h
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -3415,18 +3415,18 @@ static bool ReportOutOfMemory(JSContext*
 static bool ThrowOutOfMemory(JSContext* cx, unsigned argc, Value* vp) {
   JS_ReportOutOfMemory(cx);
   return false;
 }
 
 static bool ReportLargeAllocationFailure(JSContext* cx, unsigned argc,
                                          Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
-  void* buf = cx->runtime()->onOutOfMemoryCanGC(AllocFunction::Malloc,
-                                                JSRuntime::LARGE_ALLOCATION);
+  void* buf = cx->runtime()->onOutOfMemoryCanGC(
+      AllocFunction::Malloc, js::MallocArena, JSRuntime::LARGE_ALLOCATION);
   js_free(buf);
   args.rval().setUndefined();
   return true;
 }
 
 namespace heaptools {
 
 typedef UniqueTwoByteChars EdgeName;
--- a/js/src/gc/Zone.cpp
+++ b/js/src/gc/Zone.cpp
@@ -347,17 +347,18 @@ void Zone::notifyObservingDebuggers() {
 
     GlobalObject::DebuggerVector* dbgs = global->getDebuggers();
     if (!dbgs) {
       continue;
     }
 
     for (GlobalObject::DebuggerVector::Range r = dbgs->all(); !r.empty();
          r.popFront()) {
-      if (!r.front().unbarrieredGet()->debuggeeIsBeingCollected(rt->gc.majorGCCount())) {
+      if (!r.front().unbarrieredGet()->debuggeeIsBeingCollected(
+              rt->gc.majorGCCount())) {
 #ifdef DEBUG
         fprintf(stderr,
                 "OOM while notifying observing Debuggers of a GC: The "
                 "onGarbageCollection\n"
                 "hook will not be fired for this GC for some Debuggers!\n");
 #endif
         return;
       }
@@ -458,22 +459,23 @@ void Zone::traceAtomCache(JSTracer* trc)
   MOZ_ASSERT(hasKeptAtoms());
   for (auto r = atomCache().all(); !r.empty(); r.popFront()) {
     JSAtom* atom = r.front().asPtrUnbarriered();
     TraceRoot(trc, &atom, "kept atom");
     MOZ_ASSERT(r.front().asPtrUnbarriered() == atom);
   }
 }
 
-void* Zone::onOutOfMemory(js::AllocFunction allocFunc, size_t nbytes,
-                          void* reallocPtr) {
+void* Zone::onOutOfMemory(js::AllocFunction allocFunc, arena_id_t arena,
+                          size_t nbytes, void* reallocPtr) {
   if (!js::CurrentThreadCanAccessRuntime(runtime_)) {
     return nullptr;
   }
-  return runtimeFromMainThread()->onOutOfMemory(allocFunc, nbytes, reallocPtr);
+  return runtimeFromMainThread()->onOutOfMemory(allocFunc, arena, nbytes,
+                                                reallocPtr);
 }
 
 void Zone::reportAllocationOverflow() { js::ReportAllocationOverflow(nullptr); }
 
 void JS::Zone::maybeTriggerGCForTooMuchMalloc(js::gc::MemoryCounter& counter,
                                               TriggerKind trigger) {
   JSRuntime* rt = runtimeFromAnyThread();
 
--- a/js/src/gc/Zone.h
+++ b/js/src/gc/Zone.h
@@ -201,17 +201,18 @@ class Zone : public JS::shadow::Zone,
   // Iterate over all cells in the zone. See the definition of ZoneCellIter
   // in gc/GC-inl.h for the possible arguments and documentation.
   template <typename T, typename... Args>
   js::gc::ZoneCellIter<T> cellIter(Args&&... args) {
     return js::gc::ZoneCellIter<T>(const_cast<Zone*>(this),
                                    std::forward<Args>(args)...);
   }
 
-  MOZ_MUST_USE void* onOutOfMemory(js::AllocFunction allocFunc, size_t nbytes,
+  MOZ_MUST_USE void* onOutOfMemory(js::AllocFunction allocFunc,
+                                   arena_id_t arena, size_t nbytes,
                                    void* reallocPtr = nullptr);
   void reportAllocationOverflow();
 
   void beginSweepTypes();
 
   bool hasMarkedRealms();
 
   void scheduleGC() {
--- a/js/src/util/AllocPolicy.cpp
+++ b/js/src/util/AllocPolicy.cpp
@@ -7,14 +7,14 @@
 #include "js/AllocPolicy.h"
 
 #include "vm/JSContext.h"
 
 using namespace js;
 
 void* TempAllocPolicy::onOutOfMemory(AllocFunction allocFunc, size_t nbytes,
                                      void* reallocPtr) {
-  return cx_->onOutOfMemory(allocFunc, nbytes, reallocPtr);
+  return cx_->onOutOfMemory(allocFunc, js::MallocArena, nbytes, reallocPtr);
 }
 
 void TempAllocPolicy::reportAllocOverflow() const {
   ReportAllocationOverflow(cx_);
 }
--- a/js/src/vm/JSContext.h
+++ b/js/src/vm/JSContext.h
@@ -160,22 +160,22 @@ struct JSContext : public JS::RootingCon
   }
 
   template <typename T>
   inline bool isInsideCurrentCompartment(T thing) const {
     return thing->compartment() == compartment();
   }
 
   void* onOutOfMemory(js::AllocFunction allocFunc, size_t nbytes,
-                      void* reallocPtr = nullptr) {
+                      arena_id_t arena, void* reallocPtr = nullptr) {
     if (helperThread()) {
       addPendingOutOfMemory();
       return nullptr;
     }
-    return runtime_->onOutOfMemory(allocFunc, nbytes, reallocPtr, this);
+    return runtime_->onOutOfMemory(allocFunc, arena, nbytes, reallocPtr, this);
   }
 
   /* Clear the pending exception (if any) due to OOM. */
   void recoverFromOutOfMemory();
 
   /*
    * This variation of calloc will call the large-allocation-failure callback
    * on OOM and retry the allocation.
@@ -187,17 +187,17 @@ struct JSContext : public JS::RootingCon
       return p;
     }
     size_t bytes;
     if (MOZ_UNLIKELY(!js::CalculateAllocSize<T>(numElems, &bytes))) {
       reportAllocationOverflow();
       return nullptr;
     }
     p = static_cast<T*>(
-        runtime()->onOutOfMemoryCanGC(js::AllocFunction::Calloc, bytes));
+        runtime()->onOutOfMemoryCanGC(js::AllocFunction::Calloc, arena, bytes));
     if (!p) {
       return nullptr;
     }
     updateMallocCounter(bytes);
     return p;
   }
 
   void updateMallocCounter(size_t nbytes);
--- a/js/src/vm/MallocProvider.h
+++ b/js/src/vm/MallocProvider.h
@@ -90,17 +90,17 @@ struct MallocProvider {
     if (MOZ_LIKELY(p)) {
       return p;
     }
     size_t bytes;
     if (MOZ_UNLIKELY(!CalculateAllocSize<T>(numElems, &bytes))) {
       client()->reportAllocationOverflow();
       return nullptr;
     }
-    p = (T*)client()->onOutOfMemory(AllocFunction::Malloc, bytes);
+    p = (T*)client()->onOutOfMemory(AllocFunction::Malloc, arena, bytes);
     if (p) {
       client()->updateMallocCounter(bytes);
     }
     return p;
   }
 
   template <class T, class U>
   T* pod_malloc_with_extra(size_t numExtra) {
@@ -109,17 +109,18 @@ struct MallocProvider {
       client()->reportAllocationOverflow();
       return nullptr;
     }
     T* p = static_cast<T*>(js_malloc(bytes));
     if (MOZ_LIKELY(p)) {
       client()->updateMallocCounter(bytes);
       return p;
     }
-    p = (T*)client()->onOutOfMemory(AllocFunction::Malloc, bytes);
+    p = (T*)client()->onOutOfMemory(AllocFunction::Malloc, js::MallocArena,
+                                    bytes);
     if (p) {
       client()->updateMallocCounter(bytes);
     }
     return p;
   }
 
   template <class T>
   UniquePtr<T[], JS::FreePolicy> make_pod_array(size_t numElems) {
@@ -132,17 +133,17 @@ struct MallocProvider {
     if (MOZ_LIKELY(p)) {
       return p;
     }
     size_t bytes;
     if (MOZ_UNLIKELY(!CalculateAllocSize<T>(numElems, &bytes))) {
       client()->reportAllocationOverflow();
       return nullptr;
     }
-    p = (T*)client()->onOutOfMemory(AllocFunction::Calloc, bytes);
+    p = (T*)client()->onOutOfMemory(AllocFunction::Calloc, arena, bytes);
     if (p) {
       client()->updateMallocCounter(bytes);
     }
     return p;
   }
 
   template <class T, class U>
   T* pod_calloc_with_extra(size_t numExtra) {
@@ -151,17 +152,18 @@ struct MallocProvider {
       client()->reportAllocationOverflow();
       return nullptr;
     }
     T* p = static_cast<T*>(js_calloc(bytes));
     if (p) {
       client()->updateMallocCounter(bytes);
       return p;
     }
-    p = (T*)client()->onOutOfMemory(AllocFunction::Calloc, bytes);
+    p = (T*)client()->onOutOfMemory(AllocFunction::Calloc, js::MallocArena,
+                                    bytes);
     if (p) {
       client()->updateMallocCounter(bytes);
     }
     return p;
   }
 
   template <class T>
   UniquePtr<T[], JS::FreePolicy> make_zeroed_pod_array(size_t numElems) {
@@ -174,17 +176,18 @@ struct MallocProvider {
     if (MOZ_LIKELY(p)) {
       return p;
     }
     size_t bytes;
     if (MOZ_UNLIKELY(!CalculateAllocSize<T>(newSize, &bytes))) {
       client()->reportAllocationOverflow();
       return nullptr;
     }
-    p = (T*)client()->onOutOfMemory(AllocFunction::Realloc, bytes, prior);
+    p = (T*)client()->onOutOfMemory(AllocFunction::Realloc, js::MallocArena,
+                                    bytes, 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)
--- a/js/src/vm/Runtime.cpp
+++ b/js/src/vm/Runtime.cpp
@@ -685,37 +685,38 @@ js::HashNumber JSRuntime::randomHashCode
   return HashNumber(randomHashCodeGenerator_->next());
 }
 
 void JSRuntime::updateMallocCounter(size_t nbytes) {
   gc.updateMallocCounter(nbytes);
 }
 
 JS_FRIEND_API void* JSRuntime::onOutOfMemory(AllocFunction allocFunc,
-                                             size_t nbytes, void* reallocPtr,
+                                             arena_id_t arena, size_t nbytes,
+                                             void* reallocPtr,
                                              JSContext* maybecx) {
   MOZ_ASSERT_IF(allocFunc != AllocFunction::Realloc, !reallocPtr);
 
   if (JS::RuntimeHeapIsBusy()) {
     return nullptr;
   }
 
   if (!oom::IsSimulatedOOMAllocation()) {
     /*
      * Retry when we are done with the background sweeping and have stopped
      * all the allocations and released the empty GC chunks.
      */
     gc.onOutOfMallocMemory();
     void* p;
     switch (allocFunc) {
       case AllocFunction::Malloc:
-        p = js_malloc(nbytes);
+        p = js_arena_malloc(arena, nbytes);
         break;
       case AllocFunction::Calloc:
-        p = js_calloc(nbytes);
+        p = js_arena_calloc(arena, nbytes, 1);
         break;
       case AllocFunction::Realloc:
         p = js_realloc(reallocPtr, nbytes);
         break;
       default:
         MOZ_CRASH();
     }
     if (p) {
@@ -724,22 +725,22 @@ JS_FRIEND_API void* JSRuntime::onOutOfMe
   }
 
   if (maybecx) {
     ReportOutOfMemory(maybecx);
   }
   return nullptr;
 }
 
-void* JSRuntime::onOutOfMemoryCanGC(AllocFunction allocFunc, size_t bytes,
-                                    void* reallocPtr) {
+void* JSRuntime::onOutOfMemoryCanGC(AllocFunction allocFunc, arena_id_t arena,
+                                    size_t bytes, void* reallocPtr) {
   if (OnLargeAllocationFailure && bytes >= LARGE_ALLOCATION) {
     OnLargeAllocationFailure();
   }
-  return onOutOfMemory(allocFunc, bytes, reallocPtr);
+  return onOutOfMemory(allocFunc, arena, bytes, reallocPtr);
 }
 
 bool JSRuntime::activeGCInAtomsZone() {
   Zone* zone = unsafeAtomsZone();
   return (zone->needsIncrementalBarrier() &&
           !gc.isVerifyPreBarriersEnabled()) ||
          zone->wasGCStarted();
 }
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -829,23 +829,24 @@ struct JSRuntime : public js::MallocProv
 
   /*
    * This should be called after system malloc/calloc/realloc returns nullptr
    * to try to recove some memory or to report an error.  For realloc, the
    * original pointer must be passed as reallocPtr.
    *
    * The function must be called outside the GC lock.
    */
-  JS_FRIEND_API void* onOutOfMemory(js::AllocFunction allocator, size_t nbytes,
+  JS_FRIEND_API void* onOutOfMemory(js::AllocFunction allocator,
+                                    arena_id_t arena, size_t nbytes,
                                     void* reallocPtr = nullptr,
                                     JSContext* maybecx = nullptr);
 
   /*  onOutOfMemory but can call OnLargeAllocationFailure. */
   JS_FRIEND_API void* onOutOfMemoryCanGC(js::AllocFunction allocator,
-                                         size_t nbytes,
+                                         arena_id_t arena, size_t nbytes,
                                          void* reallocPtr = nullptr);
 
   static const unsigned LARGE_ALLOCATION = 25 * 1024 * 1024;
 
   void addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf,
                               JS::RuntimeSizes* rtSizes);
 
  private: