Bug 1340921 - Introduce PMemoryStream for having PBlob and Multi-e10s happy - part 2 - PMemoryStream actor, r=mrbkap
authorAndrea Marchesini <amarchesini@mozilla.com>
Wed, 29 Mar 2017 10:40:38 +0200
changeset 350325 81292d0b435b3207cd4b0e9fdec8d3d14b24ee5b
parent 350324 f9a26f2c0e644862444b643c9506c4a5d76172bd
child 350326 90e0ee883a3e4a5c1ad08b711f668e2e6cbba8a3
push id31570
push userryanvm@gmail.com
push dateWed, 29 Mar 2017 13:42:06 +0000
treeherdermozilla-central@6ea713ccc9ab [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap
bugs1340921
milestone55.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 1340921 - Introduce PMemoryStream for having PBlob and Multi-e10s happy - part 2 - PMemoryStream actor, r=mrbkap
dom/file/ipc/MemoryStreamChild.h
dom/file/ipc/MemoryStreamParent.cpp
dom/file/ipc/MemoryStreamParent.h
dom/file/ipc/PBlob.ipdl
dom/file/ipc/PMemoryStream.ipdl
dom/file/ipc/moz.build
dom/ipc/ContentBridgeChild.cpp
dom/ipc/ContentBridgeChild.h
dom/ipc/ContentBridgeParent.cpp
dom/ipc/ContentBridgeParent.h
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
dom/ipc/PContentBridge.ipdl
dom/ipc/nsIContentChild.cpp
dom/ipc/nsIContentChild.h
dom/ipc/nsIContentParent.cpp
dom/ipc/nsIContentParent.h
ipc/glue/BackgroundChildImpl.cpp
ipc/glue/BackgroundChildImpl.h
ipc/glue/BackgroundParentImpl.cpp
ipc/glue/BackgroundParentImpl.h
ipc/glue/PBackground.ipdl
new file mode 100644
--- /dev/null
+++ b/dom/file/ipc/MemoryStreamChild.h
@@ -0,0 +1,22 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_ipc_MemoryStreamChild_h
+#define mozilla_dom_ipc_MemoryStreamChild_h
+
+#include "mozilla/ipc/PMemoryStreamChild.h"
+
+namespace mozilla {
+namespace dom {
+
+class MemoryStreamChild final : public mozilla::ipc::PMemoryStreamChild
+{
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_ipc_MemoryStreamChild_h
new file mode 100644
--- /dev/null
+++ b/dom/file/ipc/MemoryStreamParent.cpp
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "MemoryStreamParent.h"
+#include "nsIInputStream.h"
+
+namespace mozilla {
+namespace dom {
+
+MemoryStreamParent::MemoryStreamParent(uint64_t aSize)
+  : mSize(aSize)
+  , mCurSize(0)
+{}
+
+mozilla::ipc::IPCResult
+MemoryStreamParent::RecvAddChunk(nsTArray<unsigned char>&& aData)
+{
+  MOZ_ASSERT(mSize);
+
+  uint64_t dataLength = aData.Length();
+
+  if (!dataLength || mSize < (mCurSize += dataLength)) {
+    return IPC_FAIL_NO_REASON(this);
+  }
+
+  void* buffer = malloc(dataLength);
+  if (NS_WARN_IF(!buffer)) {
+    return IPC_FAIL_NO_REASON(this);
+  }
+
+  memcpy(buffer, aData.Elements(), dataLength);
+  mData.AppendElement(new MemoryBlobImpl::DataOwner(buffer, dataLength));
+
+  mCurSize += dataLength;
+  return IPC_OK();
+}
+
+void
+MemoryStreamParent::ActorDestroy(IProtocol::ActorDestroyReason)
+{
+}
+
+void
+MemoryStreamParent::GetStream(nsIInputStream** aInputStream)
+{
+  if (mCurSize != mSize) {
+    *aInputStream = nullptr;
+    return;
+  }
+
+  nsCOMPtr<nsIMultiplexInputStream> stream =
+    do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1");
+  if (NS_WARN_IF(!stream)) {
+    *aInputStream = nullptr;
+    return;
+  }
+
+  for (uint32_t i = 0; i < mData.Length(); ++i) {
+    nsCOMPtr<nsIInputStream> dataStream;
+    nsresult rv =
+      MemoryBlobImpl::DataOwnerAdapter::Create(mData[i], 0, mData[i]->mLength,
+                                               getter_AddRefs(dataStream));
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      *aInputStream = nullptr;
+      return;
+    }
+
+    stream->AppendStream(dataStream);
+  }
+
+  stream.forget(aInputStream);
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/file/ipc/MemoryStreamParent.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_ipc_MemoryStreamParent_h
+#define mozilla_dom_ipc_MemoryStreamParent_h
+
+#include "mozilla/ipc/PMemoryStreamParent.h"
+#include "mozilla/dom/MemoryBlobImpl.h"
+
+namespace mozilla {
+namespace dom {
+
+class MemoryStreamParent final : public mozilla::ipc::PMemoryStreamParent
+{
+public:
+  MemoryStreamParent(uint64_t aSize);
+
+  mozilla::ipc::IPCResult
+  RecvAddChunk(nsTArray<unsigned char>&& aData) override;
+
+  void
+  ActorDestroy(IProtocol::ActorDestroyReason) override;
+
+  void
+  GetStream(nsIInputStream** aInputStream);
+
+private:
+  uint64_t mSize;
+  uint64_t mCurSize;
+
+  nsTArray<RefPtr<MemoryBlobImpl::DataOwner>> mData;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_ipc_MemoryStreamParent_h
--- a/dom/file/ipc/PBlob.ipdl
+++ b/dom/file/ipc/PBlob.ipdl
@@ -4,16 +4,17 @@
 
 include protocol PBackground;
 include protocol PBlobStream;
 include protocol PContent;
 include protocol PContentBridge;
 include protocol PFileDescriptorSet;
 include protocol PChildToParentStream;
 include protocol PParentToChildStream;
+include protocol PMemoryStream;
 
 include BlobTypes;
 include DOMTypes;
 include InputStreamParams;
 
 namespace mozilla {
 namespace dom {
 
new file mode 100644
--- /dev/null
+++ b/dom/file/ipc/PMemoryStream.ipdl
@@ -0,0 +1,23 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+include protocol PBackground;
+include protocol PContent;
+include protocol PContentBridge;
+
+namespace mozilla {
+namespace ipc {
+
+protocol PMemoryStream
+{
+  manager PBackground or PContent or PContentBridge;
+
+parent:
+  async AddChunk(uint8_t[] data);
+
+  async __delete__();
+};
+
+} // namespace dom
+} // namespace mozilla
--- a/dom/file/ipc/moz.build
+++ b/dom/file/ipc/moz.build
@@ -2,27 +2,31 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 EXPORTS.mozilla.dom.ipc += [
     'BlobChild.h',
     'BlobParent.h',
+    'MemoryStreamChild.h',
+    'MemoryStreamParent.h',
     'nsIRemoteBlob.h',
 ]
 
 UNIFIED_SOURCES += [
     'Blob.cpp',
+    'MemoryStreamParent.cpp',
 ]
 
 IPDL_SOURCES += [
     'BlobTypes.ipdlh',
     'PBlob.ipdl',
     'PBlobStream.ipdl',
+    'PMemoryStream.ipdl',
 ]
 
 LOCAL_INCLUDES += [
     '/dom/file',
     '/dom/ipc',
     '/dom/workers',
 ]
 
--- a/dom/ipc/ContentBridgeChild.cpp
+++ b/dom/ipc/ContentBridgeChild.cpp
@@ -63,16 +63,22 @@ ContentBridgeChild::RecvAsyncMessage(con
 
 PBlobChild*
 ContentBridgeChild::SendPBlobConstructor(PBlobChild* actor,
                                          const BlobConstructorParams& params)
 {
   return PContentBridgeChild::SendPBlobConstructor(actor, params);
 }
 
+PMemoryStreamChild*
+ContentBridgeChild::SendPMemoryStreamConstructor(const uint64_t& aSize)
+{
+  return PContentBridgeChild::SendPMemoryStreamConstructor(aSize);
+}
+
 bool
 ContentBridgeChild::SendPBrowserConstructor(PBrowserChild* aActor,
                                             const TabId& aTabId,
                                             const IPCTabContext& aContext,
                                             const uint32_t& aChromeFlags,
                                             const ContentParentId& aCpID,
                                             const bool& aIsForBrowser)
 {
@@ -163,16 +169,28 @@ ContentBridgeChild::AllocPBlobChild(cons
 }
 
 bool
 ContentBridgeChild::DeallocPBlobChild(PBlobChild* aActor)
 {
   return nsIContentChild::DeallocPBlobChild(aActor);
 }
 
+PMemoryStreamChild*
+ContentBridgeChild::AllocPMemoryStreamChild(const uint64_t& aSize)
+{
+  return nsIContentChild::AllocPMemoryStreamChild(aSize);
+}
+
+bool
+ContentBridgeChild::DeallocPMemoryStreamChild(PMemoryStreamChild* aActor)
+{
+  return nsIContentChild::DeallocPMemoryStreamChild(aActor);
+}
+
 PChildToParentStreamChild*
 ContentBridgeChild::AllocPChildToParentStreamChild()
 {
   return nsIContentChild::AllocPChildToParentStreamChild();
 }
 
 bool
 ContentBridgeChild::DeallocPChildToParentStreamChild(PChildToParentStreamChild* aActor)
--- a/dom/ipc/ContentBridgeChild.h
+++ b/dom/ipc/ContentBridgeChild.h
@@ -31,16 +31,19 @@ public:
                                                    InfallibleTArray<jsipc::CpowEntry>&& aCpows,
                                                    const IPC::Principal& aPrincipal,
                                                    const ClonedMessageData& aData) override;
 
   virtual PBlobChild*
   SendPBlobConstructor(PBlobChild* actor,
                        const BlobConstructorParams& aParams) override;
 
+  virtual PMemoryStreamChild*
+  SendPMemoryStreamConstructor(const uint64_t& aSize) override;
+
   jsipc::CPOWManager* GetCPOWManager() override;
 
   virtual bool SendPBrowserConstructor(PBrowserChild* aActor,
                                        const TabId& aTabId,
                                        const IPCTabContext& aContext,
                                        const uint32_t& aChromeFlags,
                                        const ContentParentId& aCpID,
                                        const bool& aIsForBrowser) override;
@@ -77,16 +80,20 @@ protected:
                                                           const bool& aIsForBrowser) override;
 
   virtual mozilla::jsipc::PJavaScriptChild* AllocPJavaScriptChild() override;
   virtual bool DeallocPJavaScriptChild(mozilla::jsipc::PJavaScriptChild*) override;
 
   virtual PBlobChild* AllocPBlobChild(const BlobConstructorParams& aParams) override;
   virtual bool DeallocPBlobChild(PBlobChild*) override;
 
+  virtual PMemoryStreamChild*
+  AllocPMemoryStreamChild(const uint64_t& aSize) override;
+  virtual bool DeallocPMemoryStreamChild(PMemoryStreamChild*) override;
+
   virtual mozilla::ipc::PChildToParentStreamChild*
   AllocPChildToParentStreamChild() override;
 
   virtual bool
   DeallocPChildToParentStreamChild(mozilla::ipc::PChildToParentStreamChild* aActor) override;
 
   virtual PParentToChildStreamChild* AllocPParentToChildStreamChild() override;
 
--- a/dom/ipc/ContentBridgeParent.cpp
+++ b/dom/ipc/ContentBridgeParent.cpp
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/ContentBridgeParent.h"
 #include "mozilla/dom/TabParent.h"
 #include "mozilla/jsipc/CrossProcessObjectWrappers.h"
+#include "mozilla/dom/ipc/MemoryStreamParent.h"
 #include "nsXULAppAPI.h"
 #include "nsIObserverService.h"
 #include "base/task.h"
 
 using namespace mozilla::ipc;
 using namespace mozilla::jsipc;
 
 namespace mozilla {
@@ -123,16 +124,28 @@ ContentBridgeParent::AllocPBlobParent(co
 }
 
 bool
 ContentBridgeParent::DeallocPBlobParent(PBlobParent* aActor)
 {
   return nsIContentParent::DeallocPBlobParent(aActor);
 }
 
+PMemoryStreamParent*
+ContentBridgeParent::AllocPMemoryStreamParent(const uint64_t& aSize)
+{
+  return nsIContentParent::AllocPMemoryStreamParent(aSize);
+}
+
+bool
+ContentBridgeParent::DeallocPMemoryStreamParent(PMemoryStreamParent* aActor)
+{
+  return nsIContentParent::DeallocPMemoryStreamParent(aActor);
+}
+
 mozilla::jsipc::PJavaScriptParent *
 ContentBridgeParent::AllocPJavaScriptParent()
 {
   return nsIContentParent::AllocPJavaScriptParent();
 }
 
 bool
 ContentBridgeParent::DeallocPJavaScriptParent(PJavaScriptParent *parent)
--- a/dom/ipc/ContentBridgeParent.h
+++ b/dom/ipc/ContentBridgeParent.h
@@ -131,16 +131,21 @@ protected:
 
   virtual bool DeallocPBrowserParent(PBrowserParent*) override;
 
   virtual PBlobParent*
   AllocPBlobParent(const BlobConstructorParams& aParams) override;
 
   virtual bool DeallocPBlobParent(PBlobParent*) override;
 
+  virtual PMemoryStreamParent*
+  AllocPMemoryStreamParent(const uint64_t& aSize) override;
+
+  virtual bool DeallocPMemoryStreamParent(PMemoryStreamParent*) override;
+
   virtual PChildToParentStreamParent* AllocPChildToParentStreamParent() override;
 
   virtual bool
   DeallocPChildToParentStreamParent(PChildToParentStreamParent* aActor) override;
 
   virtual mozilla::ipc::PParentToChildStreamParent*
   AllocPParentToChildStreamParent() override;
 
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -1519,16 +1519,28 @@ ContentChild::DeallocPFileDescriptorSetC
 }
 
 bool
 ContentChild::DeallocPBrowserChild(PBrowserChild* aIframe)
 {
   return nsIContentChild::DeallocPBrowserChild(aIframe);
 }
 
+PMemoryStreamChild*
+ContentChild::AllocPMemoryStreamChild(const uint64_t& aSize)
+{
+  return nsIContentChild::AllocPMemoryStreamChild(aSize);
+}
+
+bool
+ContentChild::DeallocPMemoryStreamChild(PMemoryStreamChild* aActor)
+{
+  return nsIContentChild::DeallocPMemoryStreamChild(aActor);
+}
+
 PBlobChild*
 ContentChild::AllocPBlobChild(const BlobConstructorParams& aParams)
 {
   return nsIContentChild::AllocPBlobChild(aParams);
 }
 
 mozilla::PRemoteSpellcheckEngineChild *
 ContentChild::AllocPRemoteSpellcheckEngineChild()
@@ -1556,16 +1568,26 @@ ContentChild::SendPBlobConstructor(PBlob
 {
   if (IsShuttingDown()) {
     return nullptr;
   }
 
   return PContentChild::SendPBlobConstructor(aActor, aParams);
 }
 
+PMemoryStreamChild*
+ContentChild::SendPMemoryStreamConstructor(const uint64_t& aSize)
+{
+  if (IsShuttingDown()) {
+    return nullptr;
+  }
+
+  return PContentChild::SendPMemoryStreamConstructor(aSize);
+}
+
 PPresentationChild*
 ContentChild::AllocPPresentationChild()
 {
   MOZ_CRASH("We should never be manually allocating PPresentationChild actors");
   return nullptr;
 }
 
 bool
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -177,16 +177,22 @@ public:
 
   virtual bool DeallocPBrowserChild(PBrowserChild*) override;
 
   virtual PBlobChild*
   AllocPBlobChild(const BlobConstructorParams& aParams) override;
 
   virtual bool DeallocPBlobChild(PBlobChild* aActor) override;
 
+  virtual PMemoryStreamChild*
+  AllocPMemoryStreamChild(const uint64_t& aSize) override;
+
+  virtual bool
+  DeallocPMemoryStreamChild(PMemoryStreamChild* aActor) override;
+
   virtual PHalChild* AllocPHalChild() override;
   virtual bool DeallocPHalChild(PHalChild*) override;
 
   virtual PHeapSnapshotTempFileHelperChild*
   AllocPHeapSnapshotTempFileHelperChild() override;
 
   virtual bool
   DeallocPHeapSnapshotTempFileHelperChild(PHeapSnapshotTempFileHelperChild*) override;
@@ -484,16 +490,19 @@ public:
 #endif
 
   bool IsForBrowser() const { return mIsForBrowser; }
 
   virtual PBlobChild*
   SendPBlobConstructor(PBlobChild* actor,
                        const BlobConstructorParams& params) override;
 
+  virtual PMemoryStreamChild*
+  SendPMemoryStreamConstructor(const uint64_t& aSize) override;
+
   virtual PFileDescriptorSetChild*
   SendPFileDescriptorSetConstructor(const FileDescriptor&) override;
 
   virtual PFileDescriptorSetChild*
   AllocPFileDescriptorSetChild(const FileDescriptor&) override;
 
   virtual bool
   DeallocPFileDescriptorSetChild(PFileDescriptorSetChild*) override;
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -2815,16 +2815,28 @@ ContentParent::AllocPBlobParent(const Bl
 }
 
 bool
 ContentParent::DeallocPBlobParent(PBlobParent* aActor)
 {
   return nsIContentParent::DeallocPBlobParent(aActor);
 }
 
+PMemoryStreamParent*
+ContentParent::AllocPMemoryStreamParent(const uint64_t& aSize)
+{
+  return nsIContentParent::AllocPMemoryStreamParent(aSize);
+}
+
+bool
+ContentParent::DeallocPMemoryStreamParent(PMemoryStreamParent* aActor)
+{
+  return nsIContentParent::DeallocPMemoryStreamParent(aActor);
+}
+
 mozilla::ipc::IPCResult
 ContentParent::RecvPBlobConstructor(PBlobParent* aActor,
                                     const BlobConstructorParams& aParams)
 {
   const ParentBlobConstructorParams& params = aParams.get_ParentBlobConstructorParams();
   if (params.blobParams().type() == AnyBlobConstructorParams::TKnownBlobConstructorParams) {
     if (!aActor->SendCreatedFromKnownBlob()) {
       return IPC_FAIL_NO_REASON(this);
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -820,16 +820,21 @@ private:
 
   virtual bool DeallocPBrowserParent(PBrowserParent* frame) override;
 
   virtual PBlobParent*
   AllocPBlobParent(const BlobConstructorParams& aParams) override;
 
   virtual bool DeallocPBlobParent(PBlobParent* aActor) override;
 
+  virtual PMemoryStreamParent*
+  AllocPMemoryStreamParent(const uint64_t& aSize) override;
+
+  virtual bool DeallocPMemoryStreamParent(PMemoryStreamParent* aActor) override;
+
   virtual mozilla::ipc::IPCResult
   RecvPBlobConstructor(PBlobParent* aActor,
                        const BlobConstructorParams& params) override;
 
   virtual mozilla::ipc::IPCResult RecvNSSU2FTokenIsCompatibleVersion(const nsString& aVersion,
                                                                      bool* aIsCompatible) override;
 
   virtual mozilla::ipc::IPCResult RecvNSSU2FTokenIsRegistered(nsTArray<uint8_t>&& aKeyHandle,
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -15,16 +15,17 @@ include protocol PPSMContentDownloader;
 include protocol PExternalHelperApp;
 include protocol PHandlerService;
 include protocol PFileDescriptorSet;
 include protocol PHal;
 include protocol PHeapSnapshotTempFileHelper;
 include protocol PProcessHangMonitor;
 include protocol PImageBridge;
 include protocol PMedia;
+include protocol PMemoryStream;
 include protocol PNecko;
 include protocol PGMPContent;
 include protocol PGMPService;
 include protocol PPluginModule;
 include protocol PGMP;
 include protocol PPrinting;
 include protocol PChildToParentStream;
 include protocol PParentToChildStream;
@@ -278,16 +279,17 @@ nested(upto inside_cpow) sync protocol P
     manages PCycleCollectWithLogs;
     manages PPSMContentDownloader;
     manages PExternalHelperApp;
     manages PFileDescriptorSet;
     manages PHal;
     manages PHandlerService;
     manages PHeapSnapshotTempFileHelper;
     manages PMedia;
+    manages PMemoryStream;
     manages PNecko;
     manages POfflineCacheUpdate;
     manages PPrinting;
     manages PChildToParentStream;
     manages PParentToChildStream;
     manages PSpeechSynthesis;
     manages PStorage;
     manages PTestShell;
@@ -642,16 +644,18 @@ parent:
      * |pluginEpoch == newPluginEpoch|, then |plugins| will be left empty.
      */
     sync FindPlugins(uint32_t pluginEpoch) returns (nsresult aResult, PluginTag[] plugins, uint32_t newPluginEpoch);
 
     async PJavaScript();
 
     async PRemoteSpellcheckEngine();
 
+    async PMemoryStream(uint64_t aSize);
+
     async InitCrashReporter(Shmem shmem, NativeThreadId tid);
 
     /**
      * Is this token compatible with the provided version?
      *
      * |version| The offered version to test
      * Returns |True| if the offered version is compatible
      */
--- a/dom/ipc/PContentBridge.ipdl
+++ b/dom/ipc/PContentBridge.ipdl
@@ -5,16 +5,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 include protocol PBlob;
 include protocol PBrowser;
 include protocol PContent;
 include protocol PJavaScript;
 include protocol PFileDescriptorSet;
 include protocol PChildToParentStream;
+include protocol PMemoryStream;
 include protocol PParentToChildStream;
 
 include DOMTypes;
 include JavaScriptTypes;
 include PTabContext;
 
 using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h";
 using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h";
@@ -35,16 +36,17 @@ namespace dom {
  */
 nested(upto inside_cpow) sync protocol PContentBridge
 {
     manages PBlob;
     manages PBrowser;
     manages PFileDescriptorSet;
     manages PJavaScript;
     manages PChildToParentStream;
+    manages PMemoryStream;
     manages PParentToChildStream;
 
 child:
     async PParentToChildStream();
 
 child:
    /**
      * Sending an activate message moves focus to the child.
@@ -59,16 +61,18 @@ parent:
     sync SyncMessage(nsString aMessage, ClonedMessageData aData,
                      CpowEntry[] aCpows, Principal aPrincipal)
       returns (StructuredCloneData[] retval);
 
     async PJavaScript();
 
     async PChildToParentStream();
 
+    async PMemoryStream(uint64_t aSize);
+
 both:
     // Both the parent and the child can construct the PBrowser.
     // See the comment in PContent::PBrowser().
     async PBrowser(TabId tabId, IPCTabContext context, uint32_t chromeFlags,
                    ContentParentId cpId, bool isForBrowser);
 
     async PBlob(BlobConstructorParams params);
 
--- a/dom/ipc/nsIContentChild.cpp
+++ b/dom/ipc/nsIContentChild.cpp
@@ -15,16 +15,17 @@
 #include "mozilla/dom/ipc/StructuredCloneData.h"
 #include "mozilla/ipc/FileDescriptorSetChild.h"
 #include "mozilla/ipc/InputStreamUtils.h"
 #include "mozilla/ipc/IPCStreamAlloc.h"
 #include "mozilla/ipc/IPCStreamDestination.h"
 #include "mozilla/ipc/IPCStreamSource.h"
 #include "mozilla/ipc/PChildToParentStreamChild.h"
 #include "mozilla/ipc/PParentToChildStreamChild.h"
+#include "mozilla/dom/ipc/MemoryStreamChild.h"
 
 #include "nsPrintfCString.h"
 #include "xpcpublic.h"
 
 using namespace mozilla::ipc;
 using namespace mozilla::jsipc;
 
 namespace mozilla {
@@ -97,16 +98,29 @@ nsIContentChild::RecvPBrowserConstructor
   nsCOMPtr<nsIObserverService> os = services::GetObserverService();
   if (os) {
     os->NotifyObservers(static_cast<nsITabChild*>(tabChild), "tab-child-created", nullptr);
   }
 
   return IPC_OK();
 }
 
+PMemoryStreamChild*
+nsIContentChild::AllocPMemoryStreamChild(const uint64_t& aSize)
+{
+  return new MemoryStreamChild();
+}
+
+bool
+nsIContentChild::DeallocPMemoryStreamChild(PMemoryStreamChild* aActor)
+{
+  delete aActor;
+  return true;
+}
+
 PBlobChild*
 nsIContentChild::AllocPBlobChild(const BlobConstructorParams& aParams)
 {
   return BlobChild::Create(this, aParams);
 }
 
 bool
 nsIContentChild::DeallocPBlobChild(PBlobChild* aActor)
--- a/dom/ipc/nsIContentChild.h
+++ b/dom/ipc/nsIContentChild.h
@@ -59,16 +59,19 @@ public:
 
   BlobChild* GetOrCreateActorForBlob(Blob* aBlob);
   BlobChild* GetOrCreateActorForBlobImpl(BlobImpl* aImpl);
 
   virtual PBlobChild*
   SendPBlobConstructor(PBlobChild* aActor,
                        const BlobConstructorParams& aParams) = 0;
 
+  virtual mozilla::ipc::PMemoryStreamChild*
+  SendPMemoryStreamConstructor(const uint64_t& aSize) = 0;
+
   virtual bool
   SendPBrowserConstructor(PBrowserChild* aActor,
                           const TabId& aTabId,
                           const IPCTabContext& aContext,
                           const uint32_t& aChromeFlags,
                           const ContentParentId& aCpID,
                           const bool& aIsForBrowser) = 0;
 
@@ -95,16 +98,21 @@ protected:
                                                           const uint32_t& aChromeFlags,
                                                           const ContentParentId& aCpID,
                                                           const bool& aIsForBrowse);
 
   virtual PBlobChild* AllocPBlobChild(const BlobConstructorParams& aParams);
 
   virtual bool DeallocPBlobChild(PBlobChild* aActor);
 
+  virtual mozilla::ipc::PMemoryStreamChild*
+  AllocPMemoryStreamChild(const uint64_t& aSize);
+
+  virtual bool DeallocPMemoryStreamChild(mozilla::ipc::PMemoryStreamChild* aActor);
+
   virtual mozilla::ipc::PChildToParentStreamChild* AllocPChildToParentStreamChild();
 
   virtual bool
   DeallocPChildToParentStreamChild(mozilla::ipc::PChildToParentStreamChild* aActor);
 
   virtual mozilla::ipc::PParentToChildStreamChild* AllocPParentToChildStreamChild();
 
   virtual bool
--- a/dom/ipc/nsIContentParent.cpp
+++ b/dom/ipc/nsIContentParent.cpp
@@ -9,16 +9,17 @@
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/ContentBridgeParent.h"
 #include "mozilla/dom/PTabContext.h"
 #include "mozilla/dom/PermissionMessageUtils.h"
 #include "mozilla/dom/TabParent.h"
 #include "mozilla/dom/ipc/BlobParent.h"
+#include "mozilla/dom/ipc/MemoryStreamParent.h"
 #include "mozilla/dom/ipc/StructuredCloneData.h"
 #include "mozilla/jsipc/CrossProcessObjectWrappers.h"
 #include "mozilla/ipc/FileDescriptorSetParent.h"
 #include "mozilla/ipc/PFileDescriptorSetParent.h"
 #include "mozilla/ipc/IPCStreamAlloc.h"
 #include "mozilla/ipc/IPCStreamDestination.h"
 #include "mozilla/ipc/IPCStreamSource.h"
 #include "mozilla/Unused.h"
@@ -182,16 +183,29 @@ nsIContentParent::AllocPBlobParent(const
 
 bool
 nsIContentParent::DeallocPBlobParent(PBlobParent* aActor)
 {
   BlobParent::Destroy(aActor);
   return true;
 }
 
+PMemoryStreamParent*
+nsIContentParent::AllocPMemoryStreamParent(const uint64_t& aSize)
+{
+  return new MemoryStreamParent(aSize);
+}
+
+bool
+nsIContentParent::DeallocPMemoryStreamParent(PMemoryStreamParent* aActor)
+{
+  delete aActor;
+  return true;
+}
+
 BlobParent*
 nsIContentParent::GetOrCreateActorForBlob(Blob* aBlob)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aBlob);
 
   RefPtr<BlobImpl> blobImpl = aBlob->Impl();
   MOZ_ASSERT(blobImpl);
--- a/dom/ipc/nsIContentParent.h
+++ b/dom/ipc/nsIContentParent.h
@@ -31,16 +31,17 @@ namespace jsipc {
 class PJavaScriptParent;
 class CpowEntry;
 } // namespace jsipc
 
 namespace ipc {
 class PFileDescriptorSetParent;
 class PChildToParentStreamParent;
 class PParentToChildStreamParent;
+class PMemoryStreamParent;
 }
 
 namespace dom {
 
 class Blob;
 class BlobConstructorParams;
 class BlobImpl;
 class BlobParent;
@@ -116,16 +117,21 @@ protected: // IPDL methods
                                               const ContentParentId& aCpId,
                                               const bool& aIsForBrowser);
   virtual bool DeallocPBrowserParent(PBrowserParent* frame);
 
   virtual PBlobParent* AllocPBlobParent(const BlobConstructorParams& aParams);
 
   virtual bool DeallocPBlobParent(PBlobParent* aActor);
 
+  virtual mozilla::ipc::PMemoryStreamParent*
+  AllocPMemoryStreamParent(const uint64_t& aSize);
+
+  virtual bool DeallocPMemoryStreamParent(mozilla::ipc::PMemoryStreamParent* aActor);
+
   virtual mozilla::ipc::PFileDescriptorSetParent*
   AllocPFileDescriptorSetParent(const mozilla::ipc::FileDescriptor& aFD);
 
   virtual bool
   DeallocPFileDescriptorSetParent(mozilla::ipc::PFileDescriptorSetParent* aActor);
 
   virtual mozilla::ipc::PChildToParentStreamParent* AllocPChildToParentStreamParent();
 
--- a/ipc/glue/BackgroundChildImpl.cpp
+++ b/ipc/glue/BackgroundChildImpl.cpp
@@ -18,16 +18,17 @@
 #include "mozilla/dom/PBlobChild.h"
 #include "mozilla/dom/PFileSystemRequestChild.h"
 #include "mozilla/dom/FileSystemTaskBase.h"
 #include "mozilla/dom/asmjscache/AsmJSCache.h"
 #include "mozilla/dom/cache/ActorUtils.h"
 #include "mozilla/dom/indexedDB/PBackgroundIDBFactoryChild.h"
 #include "mozilla/dom/indexedDB/PBackgroundIndexedDBUtilsChild.h"
 #include "mozilla/dom/ipc/BlobChild.h"
+#include "mozilla/dom/ipc/MemoryStreamChild.h"
 #include "mozilla/dom/quota/PQuotaChild.h"
 #include "mozilla/dom/GamepadEventChannelChild.h"
 #include "mozilla/dom/GamepadTestChannelChild.h"
 #include "mozilla/dom/MessagePortChild.h"
 #include "mozilla/ipc/IPCStreamAlloc.h"
 #include "mozilla/ipc/PBackgroundTestChild.h"
 #include "mozilla/ipc/PChildToParentStreamChild.h"
 #include "mozilla/ipc/PParentToChildStreamChild.h"
@@ -210,16 +211,29 @@ bool
 BackgroundChildImpl::DeallocPBlobChild(PBlobChild* aActor)
 {
   MOZ_ASSERT(aActor);
 
   mozilla::dom::BlobChild::Destroy(aActor);
   return true;
 }
 
+PMemoryStreamChild*
+BackgroundChildImpl::AllocPMemoryStreamChild(const uint64_t& aSize)
+{
+  return new mozilla::dom::MemoryStreamChild();
+}
+
+bool
+BackgroundChildImpl::DeallocPMemoryStreamChild(PMemoryStreamChild* aActor)
+{
+  delete aActor;
+  return true;
+}
+
 PFileDescriptorSetChild*
 BackgroundChildImpl::AllocPFileDescriptorSetChild(
                                           const FileDescriptor& aFileDescriptor)
 {
   return new FileDescriptorSetChild(aFileDescriptor);
 }
 
 bool
--- a/ipc/glue/BackgroundChildImpl.h
+++ b/ipc/glue/BackgroundChildImpl.h
@@ -71,16 +71,22 @@ protected:
                                         override;
 
   virtual PBlobChild*
   AllocPBlobChild(const BlobConstructorParams& aParams) override;
 
   virtual bool
   DeallocPBlobChild(PBlobChild* aActor) override;
 
+  virtual PMemoryStreamChild*
+  AllocPMemoryStreamChild(const uint64_t& aSize) override;
+
+  virtual bool
+  DeallocPMemoryStreamChild(PMemoryStreamChild* aActor) override;
+
   virtual PFileDescriptorSetChild*
   AllocPFileDescriptorSetChild(const FileDescriptor& aFileDescriptor)
                                override;
 
   virtual bool
   DeallocPFileDescriptorSetChild(PFileDescriptorSetChild* aActor) override;
 
   virtual PCamerasChild*
--- a/ipc/glue/BackgroundParentImpl.cpp
+++ b/ipc/glue/BackgroundParentImpl.cpp
@@ -23,16 +23,17 @@
 #include "mozilla/dom/PGamepadEventChannelParent.h"
 #include "mozilla/dom/PGamepadTestChannelParent.h"
 #include "mozilla/dom/MessagePortParent.h"
 #include "mozilla/dom/ServiceWorkerRegistrar.h"
 #include "mozilla/dom/asmjscache/AsmJSCache.h"
 #include "mozilla/dom/cache/ActorUtils.h"
 #include "mozilla/dom/indexedDB/ActorsParent.h"
 #include "mozilla/dom/ipc/BlobParent.h"
+#include "mozilla/dom/ipc/MemoryStreamParent.h"
 #include "mozilla/dom/quota/ActorsParent.h"
 #include "mozilla/ipc/BackgroundParent.h"
 #include "mozilla/ipc/BackgroundUtils.h"
 #include "mozilla/ipc/IPCStreamAlloc.h"
 #include "mozilla/ipc/PBackgroundSharedTypes.h"
 #include "mozilla/ipc/PBackgroundTestParent.h"
 #include "mozilla/ipc/PChildToParentStreamParent.h"
 #include "mozilla/ipc/PParentToChildStreamParent.h"
@@ -261,16 +262,36 @@ BackgroundParentImpl::DeallocPBlobParent
   AssertIsInMainProcess();
   AssertIsOnBackgroundThread();
   MOZ_ASSERT(aActor);
 
   mozilla::dom::BlobParent::Destroy(aActor);
   return true;
 }
 
+PMemoryStreamParent*
+BackgroundParentImpl::AllocPMemoryStreamParent(const uint64_t& aSize)
+{
+  AssertIsInMainProcess();
+  AssertIsOnBackgroundThread();
+
+  return new mozilla::dom::MemoryStreamParent(aSize);
+}
+
+bool
+BackgroundParentImpl::DeallocPMemoryStreamParent(PMemoryStreamParent* aActor)
+{
+  AssertIsInMainProcess();
+  AssertIsOnBackgroundThread();
+  MOZ_ASSERT(aActor);
+
+  delete aActor;
+  return true;
+}
+
 mozilla::ipc::IPCResult
 BackgroundParentImpl::RecvPBlobConstructor(PBlobParent* aActor,
                                            const BlobConstructorParams& aParams)
 {
   const ParentBlobConstructorParams& params = aParams;
   if (params.blobParams().type() == AnyBlobConstructorParams::TKnownBlobConstructorParams) {
     if (!aActor->SendCreatedFromKnownBlob()) {
       return IPC_FAIL_NO_REASON(this);
--- a/ipc/glue/BackgroundParentImpl.h
+++ b/ipc/glue/BackgroundParentImpl.h
@@ -64,16 +64,22 @@ protected:
   RecvFlushPendingFileDeletions() override;
 
   virtual PBlobParent*
   AllocPBlobParent(const BlobConstructorParams& aParams) override;
 
   virtual bool
   DeallocPBlobParent(PBlobParent* aActor) override;
 
+  virtual PMemoryStreamParent*
+  AllocPMemoryStreamParent(const uint64_t& aSize) override;
+
+  virtual bool
+  DeallocPMemoryStreamParent(PMemoryStreamParent* aActor) override;
+
   virtual mozilla::ipc::IPCResult
   RecvPBlobConstructor(PBlobParent* aActor,
                        const BlobConstructorParams& params) override;
 
   virtual PFileDescriptorSetParent*
   AllocPFileDescriptorSetParent(const FileDescriptor& aFileDescriptor)
                                 override;
 
--- a/ipc/glue/PBackground.ipdl
+++ b/ipc/glue/PBackground.ipdl
@@ -10,16 +10,17 @@ include protocol PBlob;
 include protocol PBroadcastChannel;
 include protocol PCache;
 include protocol PCacheStorage;
 include protocol PCacheStreamControl;
 include protocol PFileDescriptorSet;
 include protocol PFileSystemRequest;
 include protocol PGamepadEventChannel;
 include protocol PGamepadTestChannel;
+include protocol PMemoryStream;
 include protocol PMessagePort;
 include protocol PCameras;
 include protocol PQuota;
 include protocol PChildToParentStream;
 include protocol PParentToChildStream;
 include protocol PServiceWorkerManager;
 include protocol PUDPSocket;
 include protocol PVsync;
@@ -54,16 +55,17 @@ sync protocol PBackground
   manages PBroadcastChannel;
   manages PCache;
   manages PCacheStorage;
   manages PCacheStreamControl;
   manages PFileDescriptorSet;
   manages PFileSystemRequest;
   manages PGamepadEventChannel;
   manages PGamepadTestChannel;
+  manages PMemoryStream;
   manages PMessagePort;
   manages PCameras;
   manages PQuota;
   manages PChildToParentStream;
   manages PParentToChildStream;
   manages PServiceWorkerManager;
   manages PUDPSocket;
   manages PVsync;
@@ -105,16 +107,18 @@ parent:
   async PQuota();
 
   async PFileSystemRequest(FileSystemParams params);
 
   async PGamepadEventChannel();
 
   async PGamepadTestChannel();
 
+  async PMemoryStream(uint64_t aSize);
+
 child:
   async PCache();
   async PCacheStreamControl();
 
   async PParentToChildStream();
 
 both:
   async PBlob(BlobConstructorParams params);