Bug 1518101: Use calloc instead of malloc followed by memset for inlined TypedArray data allocation. r=jonco
authorAndré Bargull <andre.bargull@gmail.com>
Mon, 07 Jan 2019 05:45:48 -0800
changeset 452901 19051af76b77ea0dc8e433b5e95d4714f35808d0
parent 452900 c69cf0bb19cd8d0814011546f5e3e2e6185eb0cd
child 452902 fcbace68967f0a0497456428b34050b5ecc3474b
push id35333
push userdvarga@mozilla.com
push dateTue, 08 Jan 2019 16:23:59 +0000
treeherdermozilla-central@1f7a8905fa7c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco
bugs1518101
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 1518101: Use calloc instead of malloc followed by memset for inlined TypedArray data allocation. r=jonco
js/src/gc/Nursery.cpp
js/src/gc/Nursery.h
js/src/jit/MacroAssembler.cpp
--- a/js/src/gc/Nursery.cpp
+++ b/js/src/gc/Nursery.cpp
@@ -451,16 +451,45 @@ void* js::Nursery::allocateBufferSameLoc
 
   if (!IsInsideNursery(obj)) {
     return obj->zone()->pod_malloc<uint8_t>(nbytes);
   }
 
   return allocate(nbytes);
 }
 
+void* js::Nursery::allocateZeroedBuffer(Zone* zone, size_t nbytes) {
+  MOZ_ASSERT(nbytes > 0);
+
+  if (nbytes <= MaxNurseryBufferSize) {
+    void* buffer = allocate(nbytes);
+    if (buffer) {
+      memset(buffer, 0, nbytes);
+      return buffer;
+    }
+  }
+
+  void* buffer = zone->pod_calloc<uint8_t>(nbytes);
+  if (buffer && !registerMallocedBuffer(buffer)) {
+    js_free(buffer);
+    return nullptr;
+  }
+  return buffer;
+}
+
+void* js::Nursery::allocateZeroedBuffer(JSObject* obj, size_t nbytes) {
+  MOZ_ASSERT(obj);
+  MOZ_ASSERT(nbytes > 0);
+
+  if (!IsInsideNursery(obj)) {
+    return obj->zone()->pod_calloc<uint8_t>(nbytes);
+  }
+  return allocateZeroedBuffer(obj->zone(), nbytes);
+}
+
 void* js::Nursery::reallocateBuffer(JSObject* obj, void* oldBuffer,
                                     size_t oldBytes, size_t newBytes) {
   if (!IsInsideNursery(obj)) {
     return obj->zone()->pod_realloc<uint8_t>((uint8_t*)oldBuffer, oldBytes,
                                              newBytes);
   }
 
   if (!isInside(oldBuffer)) {
--- a/js/src/gc/Nursery.h
+++ b/js/src/gc/Nursery.h
@@ -238,16 +238,27 @@ class Nursery {
 
   /*
    * Allocate a buffer for a given object, always using the nursery if obj is
    * in the nursery. The requested size must be less than or equal to
    * MaxNurseryBufferSize.
    */
   void* allocateBufferSameLocation(JSObject* obj, size_t nbytes);
 
+  /* Allocate a zero-initialized buffer for a given zone, using the nursery if
+   * possible.
+   */
+  void* allocateZeroedBuffer(JS::Zone* zone, size_t nbytes);
+
+  /*
+   * Allocate a zero-initialized buffer for a given object, using the nursery if
+   * possible and obj is in the nursery.
+   */
+  void* allocateZeroedBuffer(JSObject* obj, size_t nbytes);
+
   /* Resize an existing object buffer. */
   void* reallocateBuffer(JSObject* obj, void* oldBuffer, size_t oldBytes,
                          size_t newBytes);
 
   /* Free an object buffer. */
   void freeBuffer(void* buffer);
 
   /* The maximum number of bytes allowed to reside in nursery buffers. */
--- a/js/src/jit/MacroAssembler.cpp
+++ b/js/src/jit/MacroAssembler.cpp
@@ -1175,20 +1175,19 @@ static void AllocateObjectBufferWithInit
   }
 
   obj->setFixedSlot(TypedArrayObject::LENGTH_SLOT, Int32Value(count));
 
   size_t nbytes = count * obj->bytesPerElement();
   MOZ_ASSERT((CheckedUint32(nbytes) + sizeof(Value)).isValid());
 
   nbytes = JS_ROUNDUP(nbytes, sizeof(Value));
-  void* buf = cx->nursery().allocateBuffer(obj, nbytes);
+  void* buf = cx->nursery().allocateZeroedBuffer(obj, nbytes);
   if (buf) {
     obj->initPrivate(buf);
-    memset(buf, 0, nbytes);
   }
 }
 
 void MacroAssembler::initTypedArraySlots(Register obj, Register temp,
                                          Register lengthReg,
                                          LiveRegisterSet liveRegs, Label* fail,
                                          TypedArrayObject* templateObj,
                                          TypedArrayLength lengthKind) {