Bug 1264053 - MessagePort should support transferable objects in multi-e10s - part 2. r=sfink, a=sledru
authorAndrea Marchesini <amarchesini@mozilla.com>
Wed, 17 Aug 2016 07:54:00 +0200
changeset 347830 cf237b1047044713b1b0db79a3b0af318a2090c3
parent 347829 b6788af0c17645f95d93995904b63d7841f035ba
child 347831 5aec8a7d79ca1847abded71d6c43c8558d3473bc
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink, sledru
bugs1264053
milestone50.0a2
Bug 1264053 - MessagePort should support transferable objects in multi-e10s - part 2. r=sfink, a=sledru
dom/base/StructuredCloneHolder.cpp
js/public/StructuredClone.h
js/src/vm/StructuredClone.cpp
--- a/dom/base/StructuredCloneHolder.cpp
+++ b/dom/base/StructuredCloneHolder.cpp
@@ -275,25 +275,16 @@ StructuredCloneHolder::Write(JSContext* 
 {
   MOZ_ASSERT_IF(mStructuredCloneScope == StructuredCloneScope::SameProcessSameThread,
                 mCreationThread == NS_GetCurrentThread());
 
   if (!StructuredCloneHolderBase::Write(aCx, aValue, aTransfer)) {
     aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
     return;
   }
-
-  if (mStructuredCloneScope != StructuredCloneScope::SameProcessSameThread) {
-    for (uint32_t i = 0, len = mBlobImplArray.Length(); i < len; ++i) {
-      if (!mBlobImplArray[i]->MayBeClonedToOtherThreads()) {
-        aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
-        return;
-      }
-    }
-  }
 }
 
 void
 StructuredCloneHolder::Read(nsISupports* aParent,
                             JSContext* aCx,
                             JS::MutableHandle<JS::Value> aValue,
                             ErrorResult& aRv)
 {
@@ -700,16 +691,21 @@ bool
 WriteBlob(JSStructuredCloneWriter* aWriter,
           Blob* aBlob,
           StructuredCloneHolder* aHolder)
 {
   MOZ_ASSERT(aWriter);
   MOZ_ASSERT(aBlob);
   MOZ_ASSERT(aHolder);
 
+  if (JS_GetStructuredCloneScope(aWriter) != JS::StructuredCloneScope::SameProcessSameThread &&
+      !aBlob->Impl()->MayBeClonedToOtherThreads()) {
+    return false;
+  }
+
   ErrorResult rv;
   RefPtr<BlobImpl> blobImpl =
     EnsureBlobForBackgroundManager(aBlob->Impl(), nullptr, rv);
   if (NS_WARN_IF(rv.Failed())) {
     rv.SuppressException();
     return false;
   }
 
--- a/js/public/StructuredClone.h
+++ b/js/public/StructuredClone.h
@@ -285,9 +285,12 @@ JS_PUBLIC_API(bool)
 JS_WriteString(JSStructuredCloneWriter* w, JS::HandleString str);
 
 JS_PUBLIC_API(bool)
 JS_WriteTypedArray(JSStructuredCloneWriter* w, JS::HandleValue v);
 
 JS_PUBLIC_API(bool)
 JS_ObjectNotWritten(JSStructuredCloneWriter* w, JS::HandleObject obj);
 
+JS_PUBLIC_API(JS::StructuredCloneScope)
+JS_GetStructuredCloneScope(JSStructuredCloneWriter* w);
+
 #endif  /* js_StructuredClone_h */
--- a/js/src/vm/StructuredClone.cpp
+++ b/js/src/vm/StructuredClone.cpp
@@ -301,16 +301,18 @@ struct JSStructuredCloneWriter {
     bool write(HandleValue v);
 
     SCOutput& output() { return out; }
 
     bool extractBuffer(uint64_t** datap, size_t* sizep) {
         return out.extractBuffer(datap, sizep);
     }
 
+    JS::StructuredCloneScope cloneScope() const { return scope; }
+
   private:
     JSStructuredCloneWriter() = delete;
     JSStructuredCloneWriter(const JSStructuredCloneWriter&) = delete;
 
     JSContext* context() { return out.context(); }
 
     bool writeHeader();
     bool writeTransferMap();
@@ -449,16 +451,20 @@ DiscardTransferables(uint64_t* buffer, s
     MOZ_ASSERT(nbytes % sizeof(uint64_t) == 0);
     uint64_t* end = buffer + nbytes / sizeof(uint64_t);
     uint64_t* point = buffer;
     if (point == end)
         return; // Empty buffer
 
     uint32_t tag, data;
     SCInput::getPair(point++, &tag, &data);
+
+    if (tag == SCTAG_HEADER)
+        SCInput::getPair(point++, &tag, &data);
+
     if (tag != SCTAG_TRANSFER_MAP_HEADER)
         return;
 
     if (TransferableMapHeader(data) == SCTAG_TM_TRANSFERRED)
         return;
 
     // freeTransfer should not GC
     JS::AutoSuppressGCAnalysis nogc;
@@ -2518,8 +2524,14 @@ JS_WriteTypedArray(JSStructuredCloneWrit
 
 JS_PUBLIC_API(bool)
 JS_ObjectNotWritten(JSStructuredCloneWriter* w, HandleObject obj)
 {
     w->memory.remove(w->memory.lookup(obj));
 
     return true;
 }
+
+JS_PUBLIC_API(JS::StructuredCloneScope)
+JS_GetStructuredCloneScope(JSStructuredCloneWriter* w)
+{
+    return w->cloneScope();
+}