Bug 1529298 - Make NoteViewBufferWasDetached a lambda instead of a global function. r=sfink
authorJeff Walden <jwalden@mit.edu>
Wed, 20 Feb 2019 13:33:15 -0800
changeset 519485 f487c864d2abb77498667161baf187b3ecb7f995
parent 519484 d8a4ce77f2f10639b3a5783b5961319d35342711
child 519486 715e9b139ebbd407ac64b5ee8737d0f042f74b4c
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1529298
milestone67.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 1529298 - Make NoteViewBufferWasDetached a lambda instead of a global function. r=sfink
js/src/vm/ArrayBufferObject.cpp
--- a/js/src/vm/ArrayBufferObject.cpp
+++ b/js/src/vm/ArrayBufferObject.cpp
@@ -445,25 +445,25 @@ bool ArrayBufferObject::class_constructo
 static uint8_t* AllocateArrayBufferContents(JSContext* cx, uint32_t nbytes) {
   auto* p = cx->pod_callocCanGC<uint8_t>(nbytes, js::ArrayBufferContentsArena);
   if (!p) {
     ReportOutOfMemory(cx);
   }
   return p;
 }
 
-static void NoteViewBufferWasDetached(
-    ArrayBufferViewObject* view, ArrayBufferObject::BufferContents newContents,
-    JSContext* cx) {
-  MOZ_ASSERT(!view->isSharedMemory());
-
-  view->notifyBufferDetached(newContents.data());
-
-  // Notify compiled jit code that the base pointer has moved.
-  MarkObjectStateChange(cx, view);
+static uint8_t* NewCopiedBufferContents(JSContext* cx,
+                                        Handle<ArrayBufferObject*> buffer) {
+  uint8_t* dataCopy = AllocateArrayBufferContents(cx, buffer->byteLength());
+  if (dataCopy) {
+    if (auto count = buffer->byteLength()) {
+      memcpy(dataCopy, buffer->dataPointer(), count);
+    }
+  }
+  return dataCopy;
 }
 
 /* static */ void ArrayBufferObject::detach(JSContext* cx,
                                             Handle<ArrayBufferObject*> buffer,
                                             BufferContents newContents) {
   cx->check(buffer);
   MOZ_ASSERT(!buffer->isPreparedForAsmJS());
 
@@ -482,34 +482,42 @@ static void NoteViewBufferWasDetached(
     if (!JSObject::getGroup(cx, cx->global())) {
       oomUnsafe.crash("ArrayBufferObject::detach");
     }
     MarkObjectGroupFlags(cx, cx->global(),
                          OBJECT_FLAG_TYPED_OBJECT_HAS_DETACHED_BUFFER);
     cx->zone()->detachedTypedObjects = 1;
   }
 
+  auto NoteViewBufferWasDetached = [&cx,
+                                    &newContents](ArrayBufferViewObject* view) {
+    MOZ_ASSERT(!view->isSharedMemory());
+
+    view->notifyBufferDetached(newContents.data());
+
+    // Notify compiled jit code that the base pointer has moved.
+    MarkObjectStateChange(cx, view);
+  };
+
   // Update all views of the buffer to account for the buffer having been
   // detached, and clear the buffer's data and list of views.
   //
   // Typed object buffers are not exposed and cannot be detached.
 
   auto& innerViews = ObjectRealm::get(buffer).innerViews.get();
   if (InnerViewTable::ViewVector* views =
           innerViews.maybeViewsUnbarriered(buffer)) {
     for (size_t i = 0; i < views->length(); i++) {
       JSObject* view = (*views)[i];
-      NoteViewBufferWasDetached(&view->as<ArrayBufferViewObject>(), newContents,
-                                cx);
+      NoteViewBufferWasDetached(&view->as<ArrayBufferViewObject>());
     }
     innerViews.removeViews(buffer);
   }
   if (JSObject* view = buffer->firstView()) {
-    NoteViewBufferWasDetached(&view->as<ArrayBufferViewObject>(), newContents,
-                              cx);
+    NoteViewBufferWasDetached(&view->as<ArrayBufferViewObject>());
     buffer->setFirstView(nullptr);
   }
 
   if (newContents.data() != buffer->dataPointer()) {
     buffer->setNewData(cx->runtime()->defaultFreeOp(), newContents, OwnsData);
   }
 
   buffer->setByteLength(0);
@@ -969,21 +977,21 @@ bool js::CreateWasmBuffer(JSContext* cx,
   if (buffer->isPreparedForAsmJS()) {
     return true;
   }
 
   // XXX User-owned, no-data, and is-inline were excluded above, so
   //     |ownsData()| having changed semantics in this patch doesn't matter
   //     here.
   if (!buffer->ownsData()) {
-    uint8_t* data = AllocateArrayBufferContents(cx, buffer->byteLength());
+    uint8_t* data = NewCopiedBufferContents(cx, buffer);
     if (!data) {
       return false;
     }
-    memcpy(data, buffer->dataPointer(), buffer->byteLength());
+
     buffer->changeContents(cx, BufferContents::createMalloced(data), OwnsData);
   }
 
   buffer->setIsPreparedForAsmJS();
   return true;
 }
 
 ArrayBufferObject::BufferContents ArrayBufferObject::createMappedContents(
@@ -1399,24 +1407,21 @@ ArrayBufferObject* ArrayBufferObject::cr
   if (hasStealableContents) {
     buffer->setOwnsData(DoesntOwnData);  // Do not free the stolen data.
     ArrayBufferObject::detach(cx, buffer, BufferContents::createNoData());
     return oldContents;
   }
 
   // Create a new chunk of memory to return since we cannot steal the
   // existing contents away from the buffer.
-  uint8_t* dataCopy = AllocateArrayBufferContents(cx, buffer->byteLength());
+  uint8_t* dataCopy = NewCopiedBufferContents(cx, buffer);
   if (!dataCopy) {
     return BufferContents::createFailed();
   }
 
-  if (buffer->byteLength() > 0) {
-    memcpy(dataCopy, oldContents.data(), buffer->byteLength());
-  }
   ArrayBufferObject::detach(cx, buffer, oldContents);
   return BufferContents::createMalloced(dataCopy);
 }
 
 /* static */ void ArrayBufferObject::addSizeOfExcludingThis(
     JSObject* obj, mozilla::MallocSizeOf mallocSizeOf, JS::ClassInfo* info) {
   ArrayBufferObject& buffer = AsArrayBuffer(obj);