Bug 1052579 - Remove arenaId member that was introduced in D25705 r=sfink
authorChris Martin <cmartin@mozilla.com>
Thu, 02 May 2019 16:31:53 +0000
changeset 472343 596926f7e8125bcd9094a1183b2e887b592ae418
parent 472342 216f1bef7c4b8b6c14ca7c4d862524b92bb81bb9
child 472344 634737ac37d4c6bcc1a93206a144c5e58fa70aa4
push id84617
push userrvandermeulen@mozilla.com
push dateThu, 02 May 2019 20:21:30 +0000
treeherderautoland@596926f7e812 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1052579
milestone68.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 1052579 - Remove arenaId member that was introduced in D25705 r=sfink In D25705, I added a new arenaId member to the js::BaseAllocPolicy. This increased the size of everything that uses a JS AllocPolicy, which is a lot. This change follows suit from earlier work, which is to make everything allocation-related have an "arena" version and a "default" version that uses the arena version with the implied default arena. StringBuffer is then changed to use this new functionity to define its own alloc policy that uses the new StringBufferArena. Differential Revision: https://phabricator.services.mozilla.com/D29685
js/public/AllocPolicy.h
js/src/util/AllocPolicy.cpp
js/src/util/StringBuffer.cpp
js/src/util/StringBuffer.h
--- a/js/public/AllocPolicy.h
+++ b/js/public/AllocPolicy.h
@@ -20,49 +20,67 @@
 extern MOZ_COLD JS_PUBLIC_API void JS_ReportOutOfMemory(JSContext* cx);
 
 namespace js {
 
 enum class AllocFunction { Malloc, Calloc, Realloc };
 
 /* Base class allocation policies providing allocation methods. */
 class AllocPolicyBase {
-  const arena_id_t& arenaId_;
-
- protected:
-  arena_id_t getArenaId() { return arenaId_; }
-
  public:
-  explicit AllocPolicyBase(const arena_id_t& arenaId = js::MallocArena)
-      : arenaId_(arenaId) {}
+  template <typename T>
+  T* maybe_pod_arena_malloc(arena_id_t arenaId, size_t numElems) {
+    return js_pod_arena_malloc<T>(arenaId, numElems);
+  }
+  template <typename T>
+  T* maybe_pod_arena_calloc(arena_id_t arenaId, size_t numElems) {
+    return js_pod_arena_calloc<T>(arenaId, numElems);
+  }
+  template <typename T>
+  T* maybe_pod_arena_realloc(arena_id_t arenaId, T* p, size_t oldSize, size_t newSize) {
+    return js_pod_arena_realloc<T>(arenaId, p, oldSize, newSize);
+  }
+  template <typename T>
+  T* pod_arena_malloc(arena_id_t arenaId, size_t numElems) {
+    return maybe_pod_arena_malloc<T>(arenaId, numElems);
+  }
+  template <typename T>
+  T* pod_arena_calloc(arena_id_t arenaId, size_t numElems) {
+    return maybe_pod_arena_calloc<T>(arenaId, numElems);
+  }
+  template <typename T>
+  T* pod_arena_realloc(arena_id_t arenaId, T* p, size_t oldSize, size_t newSize) {
+    return maybe_pod_arena_realloc<T>(arenaId, p, oldSize, newSize);
+  }
 
   template <typename T>
   T* maybe_pod_malloc(size_t numElems) {
-    return js_pod_arena_malloc<T>(getArenaId(), numElems);
+    return maybe_pod_arena_malloc<T>(js::MallocArena, numElems);
   }
   template <typename T>
   T* maybe_pod_calloc(size_t numElems) {
-    return js_pod_arena_calloc<T>(getArenaId(), numElems);
+    return maybe_pod_arena_calloc<T>(js::MallocArena, numElems);
   }
   template <typename T>
   T* maybe_pod_realloc(T* p, size_t oldSize, size_t newSize) {
-    return js_pod_arena_realloc<T>(getArenaId(), p, oldSize, newSize);
+    return maybe_pod_arena_realloc<T>(js::MallocArena, p, oldSize, newSize);
   }
   template <typename T>
   T* pod_malloc(size_t numElems) {
-    return maybe_pod_malloc<T>(numElems);
+    return pod_arena_malloc<T>(js::MallocArena, numElems);
   }
   template <typename T>
   T* pod_calloc(size_t numElems) {
-    return maybe_pod_calloc<T>(numElems);
+    return pod_arena_calloc<T>(js::MallocArena, numElems);
   }
   template <typename T>
   T* pod_realloc(T* p, size_t oldSize, size_t newSize) {
-    return maybe_pod_realloc<T>(p, oldSize, newSize);
+    return pod_arena_realloc<T>(js::MallocArena, p, oldSize, newSize);
   }
+
   template <typename T>
   void free_(T* p, size_t numElems = 0) {
     js_free(p);
   }
 };
 
 /* Policy for using system memory functions and doing no error reporting. */
 class SystemAllocPolicy : public AllocPolicyBase {
@@ -84,62 +102,77 @@ MOZ_COLD JS_FRIEND_API void ReportOutOfM
  */
 class TempAllocPolicy : public AllocPolicyBase {
   JSContext* const cx_;
 
   /*
    * Non-inline helper to call JSRuntime::onOutOfMemory with minimal
    * code bloat.
    */
-  JS_FRIEND_API void* onOutOfMemory(AllocFunction allocFunc, size_t nbytes,
-                                    void* reallocPtr = nullptr);
+  JS_FRIEND_API void* onOutOfMemory(arena_id_t arenaId, AllocFunction allocFunc,
+                                    size_t nbytes, void* reallocPtr = nullptr);
 
   template <typename T>
-  T* onOutOfMemoryTyped(AllocFunction allocFunc, size_t numElems,
-                        void* reallocPtr = nullptr) {
+  T* onOutOfMemoryTyped(arena_id_t arenaId, AllocFunction allocFunc,
+                        size_t numElems, void* reallocPtr = nullptr) {
     size_t bytes;
     if (MOZ_UNLIKELY(!CalculateAllocSize<T>(numElems, &bytes))) {
       return nullptr;
     }
-    return static_cast<T*>(onOutOfMemory(allocFunc, bytes, reallocPtr));
+    return static_cast<T*>(
+        onOutOfMemory(arenaId, allocFunc, bytes, reallocPtr));
   }
 
  public:
-  MOZ_IMPLICIT TempAllocPolicy(JSContext* cx,
-                               const arena_id_t& arenaId = js::MallocArena)
-      : AllocPolicyBase(arenaId), cx_(cx) {}
+  MOZ_IMPLICIT TempAllocPolicy(JSContext* cx) : cx_(cx) {}
 
   template <typename T>
-  T* pod_malloc(size_t numElems) {
-    T* p = this->maybe_pod_malloc<T>(numElems);
+  T* pod_arena_malloc(arena_id_t arenaId, size_t numElems) {
+    T* p = this->maybe_pod_arena_malloc<T>(arenaId, numElems);
     if (MOZ_UNLIKELY(!p)) {
-      p = onOutOfMemoryTyped<T>(AllocFunction::Malloc, numElems);
+      p = onOutOfMemoryTyped<T>(arenaId, AllocFunction::Malloc, numElems);
     }
     return p;
   }
 
   template <typename T>
-  T* pod_calloc(size_t numElems) {
-    T* p = this->maybe_pod_calloc<T>(numElems);
+  T* pod_arena_calloc(arena_id_t arenaId, size_t numElems) {
+    T* p = this->maybe_pod_arena_calloc<T>(arenaId, numElems);
     if (MOZ_UNLIKELY(!p)) {
-      p = onOutOfMemoryTyped<T>(AllocFunction::Calloc, numElems);
+      p = onOutOfMemoryTyped<T>(arenaId, AllocFunction::Calloc, numElems);
     }
     return p;
   }
 
   template <typename T>
-  T* pod_realloc(T* prior, size_t oldSize, size_t newSize) {
-    T* p2 = this->maybe_pod_realloc<T>(prior, oldSize, newSize);
+  T* pod_arena_realloc(arena_id_t arenaId, T* prior, size_t oldSize, size_t newSize) {
+    T* p2 = this->maybe_pod_arena_realloc<T>(arenaId, prior, oldSize, newSize);
     if (MOZ_UNLIKELY(!p2)) {
-      p2 = onOutOfMemoryTyped<T>(AllocFunction::Realloc, newSize, prior);
+      p2 = onOutOfMemoryTyped<T>(arenaId, AllocFunction::Realloc, newSize,
+                                 prior);
     }
     return p2;
   }
 
   template <typename T>
+  T* pod_malloc(size_t numElems) {
+    return pod_arena_malloc<T>(js::MallocArena, numElems);
+  }
+
+  template <typename T>
+  T* pod_calloc(size_t numElems) {
+    return pod_arena_calloc<T>(js::MallocArena, numElems);
+  }
+
+  template <typename T>
+  T* pod_realloc(T* prior, size_t oldSize, size_t newSize) {
+    return pod_arena_realloc<T>(js::MallocArena, prior, oldSize, newSize);
+  }
+
+  template <typename T>
   void free_(T* p, size_t numElems = 0) {
     js_free(p);
   }
 
   JS_FRIEND_API void reportAllocOverflow() const;
 
   bool checkSimulatedOOM() const {
     if (js::oom::ShouldFailWithOOM()) {
--- a/js/src/util/AllocPolicy.cpp
+++ b/js/src/util/AllocPolicy.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "js/AllocPolicy.h"
 
 #include "vm/JSContext.h"
 
 using namespace js;
 
-void* TempAllocPolicy::onOutOfMemory(AllocFunction allocFunc, size_t nbytes,
+void* TempAllocPolicy::onOutOfMemory(arena_id_t arenaId,
+                                     AllocFunction allocFunc, size_t nbytes,
                                      void* reallocPtr) {
-  return cx_->onOutOfMemory(allocFunc, this->getArenaId(), nbytes, reallocPtr);
+  return cx_->onOutOfMemory(allocFunc, arenaId, nbytes, reallocPtr);
 }
 
 void TempAllocPolicy::reportAllocOverflow() const {
   ReportAllocationOverflow(cx_);
 }
--- a/js/src/util/StringBuffer.cpp
+++ b/js/src/util/StringBuffer.cpp
@@ -13,17 +13,17 @@
 #include "vm/StringType-inl.h"
 
 using namespace js;
 
 template <typename CharT, class Buffer>
 static CharT* ExtractWellSized(Buffer& cb) {
   size_t capacity = cb.capacity();
   size_t length = cb.length();
-  TempAllocPolicy allocPolicy = cb.allocPolicy();
+  StringBufferAllocPolicy allocPolicy = cb.allocPolicy();
 
   CharT* buf = cb.extractOrCopyRawBuffer();
   if (!buf) {
     return nullptr;
   }
 
   /* For medium/big buffers, avoid wasting more than 1/4 of the memory. */
   MOZ_ASSERT(capacity >= length);
@@ -45,17 +45,17 @@ char16_t* StringBuffer::stealChars() {
   }
 
   return ExtractWellSized<char16_t>(twoByteChars());
 }
 
 bool StringBuffer::inflateChars() {
   MOZ_ASSERT(isLatin1());
 
-  TwoByteCharBuffer twoByte(TempAllocPolicy{cx_, arenaId_});
+  TwoByteCharBuffer twoByte(StringBufferAllocPolicy{cx_, arenaId_});
 
   /*
    * Note: we don't use Vector::capacity() because it always returns a
    * value >= sInlineCapacity. Since Latin1CharBuffer::sInlineCapacity >
    * TwoByteCharBuffer::sInlineCapacitychars, we'd always malloc here.
    */
   size_t capacity = Max(reserved_, latin1Chars().length());
   if (!twoByte.reserve(capacity)) {
--- a/js/src/util/StringBuffer.h
+++ b/js/src/util/StringBuffer.h
@@ -11,31 +11,72 @@
 #include "mozilla/MaybeOneOf.h"
 #include "mozilla/Utf8.h"
 
 #include "js/Vector.h"
 #include "vm/JSContext.h"
 
 namespace js {
 
+class StringBufferAllocPolicy {
+  TempAllocPolicy impl_;
+
+  const arena_id_t& arenaId_;
+
+ public:
+  StringBufferAllocPolicy(JSContext* cx, const arena_id_t& arenaId)
+      : impl_(cx), arenaId_(arenaId) {}
+
+  template <typename T>
+  T* maybe_pod_malloc(size_t numElems) {
+    return impl_.maybe_pod_arena_malloc<T>(arenaId_, numElems);
+  }
+  template <typename T>
+  T* maybe_pod_calloc(size_t numElems) {
+    return impl_.maybe_pod_arena_calloc<T>(arenaId_, numElems);
+  }
+  template <typename T>
+  T* maybe_pod_realloc(T* p, size_t oldSize, size_t newSize) {
+    return impl_.maybe_pod_arena_realloc<T>(arenaId_, p, oldSize, newSize);
+  }
+  template <typename T>
+  T* pod_malloc(size_t numElems) {
+    return impl_.pod_arena_malloc<T>(arenaId_, numElems);
+  }
+  template <typename T>
+  T* pod_calloc(size_t numElems) {
+    return impl_.pod_arena_calloc<T>(arenaId_, numElems);
+  }
+  template <typename T>
+  T* pod_realloc(T* p, size_t oldSize, size_t newSize) {
+    return impl_.pod_arena_realloc<T>(arenaId_, p, oldSize, newSize);
+  }
+  template <typename T>
+  void free_(T* p, size_t numElems = 0) {
+    impl_.free_(p, numElems);
+  }
+  void reportAllocOverflow() const { impl_.reportAllocOverflow(); }
+  bool checkSimulatedOOM() const { return impl_.checkSimulatedOOM(); }
+};
+
 /*
  * String builder that eagerly checks for over-allocation past the maximum
  * string length.
  *
  * Any operation which would exceed the maximum string length causes an
  * exception report on the context and results in a failed return value.
  *
  * Well-sized extractions (which waste no more than 1/4 of their char
  * buffer space) are guaranteed for strings built by this interface.
  * See |extractWellSized|.
  */
 class StringBuffer {
  protected:
   template <typename CharT>
-  using BufferType = Vector<CharT, 64 / sizeof(CharT)>;
+  using BufferType = Vector<CharT, 64 / sizeof(CharT), StringBufferAllocPolicy>;
 
   /*
    * The Vector's buffer may be either stolen or copied, so we need to use
    * TempAllocPolicy and account for the memory manually when stealing.
    */
   using Latin1CharBuffer = BufferType<Latin1Char>;
   using TwoByteCharBuffer = BufferType<char16_t>;
 
@@ -96,17 +137,17 @@ class StringBuffer {
 
   template <typename CharT>
   JSFlatString* finishStringInternal(JSContext* cx);
 
  public:
   explicit StringBuffer(JSContext* cx,
                         const arena_id_t& arenaId = js::MallocArena)
       : cx_(cx), arenaId_(arenaId), reserved_(0) {
-    cb.construct<Latin1CharBuffer>(TempAllocPolicy{cx_, arenaId_});
+    cb.construct<Latin1CharBuffer>(StringBufferAllocPolicy{cx_, arenaId_});
   }
 
   void clear() {
     if (isLatin1()) {
       latin1Chars().clear();
     } else {
       twoByteChars().clear();
     }