Backout 1391e924e9ee (bug 806503) for mochitest-1 failures on a CLOSED TREE
authorEd Morley <emorley@mozilla.com>
Thu, 10 Jan 2013 15:21:39 +0000
changeset 118407 ed308815b4a71239610cf057d0fe8dd8d106e5e2
parent 118406 b4b36e2c63ee3df8cbd2d6e8bd18141c29868373
child 118408 927268cb78116fd88bc8a8ad9b72304d509f4f4c
push id24166
push userMs2ger@gmail.com
push dateFri, 11 Jan 2013 13:57:41 +0000
treeherdermozilla-central@63c4b0f66a0c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs806503
milestone21.0a1
backs out1391e924e9ee6f8c4105462081c04f5325e2b335
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
Backout 1391e924e9ee (bug 806503) for mochitest-1 failures on a CLOSED TREE
content/base/public/nsDOMFile.h
content/base/src/nsDOMBlobBuilder.cpp
content/base/src/nsDOMBlobBuilder.h
dom/ipc/Blob.cpp
dom/ipc/Blob.h
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/DOMTypes.ipdlh
dom/ipc/PBlob.ipdl
dom/ipc/PContent.ipdl
dom/ipc/nsIRemoteBlob.h
dom/workers/File.cpp
--- a/content/base/public/nsDOMFile.h
+++ b/content/base/public/nsDOMFile.h
@@ -43,18 +43,16 @@ public:
 
   virtual already_AddRefed<nsIDOMBlob>
   CreateSlice(uint64_t aStart, uint64_t aLength,
               const nsAString& aContentType) = 0;
 
   virtual const nsTArray<nsCOMPtr<nsIDOMBlob> >*
   GetSubBlobs() const { return nullptr; }
 
-  virtual bool IsMemoryBacked() const { return false; }
-
   NS_DECL_NSIDOMBLOB
   NS_DECL_NSIDOMFILE
   NS_DECL_NSIXHRSENDABLE
   NS_DECL_NSIMUTABLE
 
   void
   SetLazyData(const nsAString& aName, const nsAString& aContentType,
               uint64_t aLength, uint64_t aLastModifiedDate)
@@ -347,19 +345,18 @@ protected:
 
 class nsDOMMemoryFile : public nsDOMFile
 {
 public:
   // Create as file
   nsDOMMemoryFile(void *aMemoryBuffer,
                   uint64_t aLength,
                   const nsAString& aName,
-                  const nsAString& aContentType,
-                  uint64_t aModDate = UINT64_MAX)
-    : nsDOMFile(aName, aContentType, aLength, aModDate),
+                  const nsAString& aContentType)
+    : nsDOMFile(aName, aContentType, aLength, UINT64_MAX),
       mDataOwner(new DataOwner(aMemoryBuffer, aLength))
   {
     NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data");
   }
 
   // Create as blob
   nsDOMMemoryFile(void *aMemoryBuffer,
                   uint64_t aLength,
@@ -367,20 +364,16 @@ public:
     : nsDOMFile(aContentType, aLength),
       mDataOwner(new DataOwner(aMemoryBuffer, aLength))
   {
     NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data");
   }
 
   NS_IMETHOD GetInternalStream(nsIInputStream**);
 
-  virtual bool IsMemoryBacked() const { return true; }
-  void* GetData() const { return mDataOwner->mData; }
-  uint64_t GetLength() const { return mDataOwner->mLength; }
-
 protected:
   // Create slice
   nsDOMMemoryFile(const nsDOMMemoryFile* aOther, uint64_t aStart,
                   uint64_t aLength, const nsAString& aContentType)
     : nsDOMFile(aContentType, aOther->mStart + aStart, aLength),
       mDataOwner(aOther->mDataOwner)
   {
     NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data");
--- a/content/base/src/nsDOMBlobBuilder.cpp
+++ b/content/base/src/nsDOMBlobBuilder.cpp
@@ -140,25 +140,25 @@ nsDOMMultipartFile::CreateSlice(uint64_t
   nsCOMPtr<nsIDOMBlob> blob = new nsDOMMultipartFile(blobs, aContentType);
   return blob.forget();
 }
 
 /* static */ nsresult
 nsDOMMultipartFile::NewFile(const nsAString& aName, nsISupports* *aNewObject)
 {
   nsCOMPtr<nsISupports> file =
-    do_QueryObject(new nsDOMMultipartFile(aName, EmptyString()));
+    do_QueryObject(new nsDOMMultipartFile(aName));
   file.forget(aNewObject);
   return NS_OK;
 }
 
 /* static */ nsresult
 nsDOMMultipartFile::NewBlob(nsISupports* *aNewObject)
 {
-  nsCOMPtr<nsISupports> file = do_QueryObject(new nsDOMMultipartFile(EmptyString()));
+  nsCOMPtr<nsISupports> file = do_QueryObject(new nsDOMMultipartFile());
   file.forget(aNewObject);
   return NS_OK;
 }
 
 static nsIDOMBlob*
 GetXPConnectNative(JSContext* aCx, JSObject* aObj) {
   nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(
     nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, aObj));
--- a/content/base/src/nsDOMBlobBuilder.h
+++ b/content/base/src/nsDOMBlobBuilder.h
@@ -11,42 +11,41 @@
 #include "mozilla/CheckedInt.h"
 #include "mozilla/Attributes.h"
 
 class nsDOMMultipartFile : public nsDOMFile,
                            public nsIJSNativeInitializer
 {
 public:
   // Create as a file
-  nsDOMMultipartFile(nsTArray<nsCOMPtr<nsIDOMBlob> >& aBlobs,
+  nsDOMMultipartFile(nsTArray<nsCOMPtr<nsIDOMBlob> > aBlobs,
                      const nsAString& aName,
                      const nsAString& aContentType)
     : nsDOMFile(aName, aContentType, UINT64_MAX),
       mBlobs(aBlobs)
   {
   }
 
   // Create as a blob
   nsDOMMultipartFile(nsTArray<nsCOMPtr<nsIDOMBlob> >& aBlobs,
                      const nsAString& aContentType)
     : nsDOMFile(aContentType, UINT64_MAX),
       mBlobs(aBlobs)
   {
   }
 
   // Create as a file to be later initialized
-  nsDOMMultipartFile(const nsAString& aName,
-                     const nsAString& aContentType)
-    : nsDOMFile(aName, aContentType, UINT64_MAX)
+  nsDOMMultipartFile(const nsAString& aName)
+    : nsDOMFile(aName, EmptyString(), UINT64_MAX)
   {
   }
 
   // Create as a blob to be later initialized
-  nsDOMMultipartFile(const nsAString& aContentType)
-    : nsDOMFile(aContentType, UINT64_MAX)
+  nsDOMMultipartFile()
+    : nsDOMFile(EmptyString(), UINT64_MAX)
   {
   }
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIJSNativeInitializer
   NS_IMETHOD Initialize(nsISupports* aOwner,
                         JSContext* aCx,
@@ -84,22 +83,16 @@ public:
     // Initialization will set the filename, so we can pass in an empty string
     // for now.
     return NewFile(EmptyString(), aNewObject);
   }
 
   virtual const nsTArray<nsCOMPtr<nsIDOMBlob> >*
   GetSubBlobs() const { return &mBlobs; }
 
-  void
-  AddBlob(nsIDOMBlob* aBlob)
-  {
-    mBlobs.AppendElement(aBlob);
-  }
-
 protected:
   nsTArray<nsCOMPtr<nsIDOMBlob> > mBlobs;
 };
 
 class BlobSet {
 public:
   BlobSet()
     : mData(nullptr), mDataLen(0), mDataBufferLen(0)
--- a/dom/ipc/Blob.cpp
+++ b/dom/ipc/Blob.cpp
@@ -16,17 +16,16 @@
 #include "nsIIPCSerializableInputStream.h"
 #include "nsIRemoteBlob.h"
 #include "nsISeekableStream.h"
 
 #include "mozilla/Monitor.h"
 #include "mozilla/unused.h"
 #include "mozilla/ipc/InputStreamUtils.h"
 #include "nsDOMFile.h"
-#include "nsDOMBlobBuilder.h"
 #include "nsThreadUtils.h"
 
 #include "ContentChild.h"
 #include "ContentParent.h"
 
 #define PRIVATE_REMOTE_INPUT_STREAM_IID \
   {0x30c7699f, 0x51d2, 0x48c8, {0xad, 0x56, 0xc0, 0x16, 0xd7, 0x6f, 0x71, 0x27}}
 
@@ -626,61 +625,27 @@ BlobTraits<Parent>::BaseType::NoteRunnab
       return;
     }
   }
 
   MOZ_NOT_REACHED("Runnable not in our array!");
 }
 
 template <ActorFlavorEnum ActorFlavor>
-class RemoteBlobBase : public nsIRemoteBlob
+class RemoteBlob : public nsDOMFile,
+                   public nsIRemoteBlob
 {
 public:
   typedef RemoteBlob<ActorFlavor> SelfType;
   typedef Blob<ActorFlavor> ActorType;
   typedef InputStreamActor<ActorFlavor> StreamActorType;
 
-  void
-  SetPBlob(void* aActor) MOZ_OVERRIDE
-  {
-    MOZ_ASSERT(!aActor || !mActor);
-    mActor = static_cast<ActorType*>(aActor);
-  }
-
-  virtual void*
-  GetPBlob() MOZ_OVERRIDE
-  {
-    return static_cast<typename ActorType::ProtocolType*>(mActor);
-  }
-
 private:
   ActorType* mActor;
 
-protected:
-  RemoteBlobBase()
-  : mActor(nullptr)
-  { }
-
-  virtual
-  ~RemoteBlobBase()
-  {
-    if (mActor) {
-      mActor->NoteDyingRemoteBlob();
-    }
-  }
-
-  ActorType* Actor() const { return mActor; }
-};
-
-template <ActorFlavorEnum ActorFlavor>
-class RemoteBlob : public nsDOMFile,
-                   public RemoteBlobBase<ActorFlavor>
-{
-  typedef Blob<ActorFlavor> ActorType;
-public:
   class StreamHelper : public nsRunnable
   {
     typedef Blob<ActorFlavor> ActorType;
     typedef InputStreamActor<ActorFlavor> StreamActorType;
 
     mozilla::Monitor mMonitor;
     ActorType* mActor;
     nsCOMPtr<nsIDOMBlob> mSourceBlob;
@@ -787,17 +752,16 @@ public:
 
   public:
     SliceHelper(ActorType* aActor)
     : mMonitor("RemoteBlob::SliceHelper::mMonitor"), mActor(aActor), mStart(0),
       mLength(0), mDone(false)
     {
       // This may be created on any thread.
       MOZ_ASSERT(aActor);
-      MOZ_ASSERT(aActor->HasManager());
     }
 
     nsresult
     GetSlice(uint64_t aStart, uint64_t aLength, const nsAString& aContentType,
              nsIDOMBlob** aSlice)
     {
       // This may be called on any thread.
       MOZ_ASSERT(aSlice);
@@ -854,30 +818,26 @@ public:
       MOZ_ASSERT(mActor);
       MOZ_ASSERT(!mSlice);
       MOZ_ASSERT(!mDone);
 
       NormalBlobConstructorParams normalParams;
       normalParams.contentType() = mContentType;
       normalParams.length() = mLength;
 
-      BlobConstructorNoMultipartParams params(normalParams);
-
-      ActorType* newActor = ActorType::Create(params);
+      ActorType* newActor = ActorType::Create(normalParams);
       MOZ_ASSERT(newActor);
-      mActor->PropagateManager(newActor);
 
       SlicedBlobConstructorParams slicedParams;
       slicedParams.contentType() = mContentType;
       slicedParams.begin() = mStart;
       slicedParams.end() = mStart + mLength;
       SetBlobOnParams(mActor, slicedParams);
 
-      BlobConstructorNoMultipartParams params2(slicedParams);
-      if (mActor->ConstructPBlobOnManager(newActor, params2)) {
+      if (mActor->Manager()->SendPBlobConstructor(newActor, slicedParams)) {
         mSlice = newActor->GetBlob();
       }
 
       mActor = nullptr;
 
       if (aNotify) {
         MonitorAutoLock lock(mMonitor);
         mDone = true;
@@ -889,156 +849,88 @@ public:
     }
   };
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
   RemoteBlob(const nsAString& aName, const nsAString& aContentType,
              uint64_t aLength, uint64_t aModDate)
-  : nsDOMFile(aName, aContentType, aLength, aModDate)
+  : nsDOMFile(aName, aContentType, aLength, aModDate), mActor(nullptr)
   {
     mImmutable = true;
   }
 
   RemoteBlob(const nsAString& aName, const nsAString& aContentType,
              uint64_t aLength)
-  : nsDOMFile(aName, aContentType, aLength)
+  : nsDOMFile(aName, aContentType, aLength), mActor(nullptr)
   {
     mImmutable = true;
   }
 
   RemoteBlob(const nsAString& aContentType, uint64_t aLength)
-  : nsDOMFile(aContentType, aLength)
+  : nsDOMFile(aContentType, aLength), mActor(nullptr)
   {
     mImmutable = true;
   }
 
   RemoteBlob()
   : nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX, UINT64_MAX)
+  , mActor(nullptr)
   {
     mImmutable = true;
   }
 
+  virtual ~RemoteBlob()
+  {
+    if (mActor) {
+      mActor->NoteDyingRemoteBlob();
+    }
+  }
+
+  void
+  SetActor(ActorType* aActor)
+  {
+    MOZ_ASSERT(!aActor || !mActor);
+    mActor = aActor;
+  }
+
   virtual already_AddRefed<nsIDOMBlob>
   CreateSlice(uint64_t aStart, uint64_t aLength, const nsAString& aContentType)
               MOZ_OVERRIDE
   {
-    ActorType* actor = RemoteBlobBase<ActorFlavor>::Actor();
-    if (!actor) {
+    if (!mActor) {
       return nullptr;
     }
 
-    nsRefPtr<SliceHelper> helper = new SliceHelper(actor);
+    nsRefPtr<SliceHelper> helper = new SliceHelper(mActor);
 
     nsCOMPtr<nsIDOMBlob> slice;
     nsresult rv =
       helper->GetSlice(aStart, aLength, aContentType, getter_AddRefs(slice));
     NS_ENSURE_SUCCESS(rv, nullptr);
 
     return slice.forget();
   }
 
   NS_IMETHOD
   GetInternalStream(nsIInputStream** aStream) MOZ_OVERRIDE
   {
-    ActorType* actor = RemoteBlobBase<ActorFlavor>::Actor();
-    if (!actor) {
+    if (!mActor) {
       return NS_ERROR_UNEXPECTED;
     }
 
-    nsRefPtr<StreamHelper> helper = new StreamHelper(actor, this);
+    nsRefPtr<StreamHelper> helper = new StreamHelper(mActor, this);
     return helper->GetStream(aStream);
   }
 
-  NS_IMETHOD
-  GetLastModifiedDate(JSContext* cx, JS::Value* aLastModifiedDate)
-  {
-    if (IsDateUnknown()) {
-      aLastModifiedDate->setNull();
-    } else {
-      JSObject* date = JS_NewDateObjectMsec(cx, mLastModificationDate);
-      if (!date) {
-        return NS_ERROR_OUT_OF_MEMORY;
-      }
-      aLastModifiedDate->setObject(*date);
-    }
-    return NS_OK;
-  }
-};
-
-template <ActorFlavorEnum ActorFlavor>
-class RemoteMemoryBlob : public nsDOMMemoryFile,
-                         public RemoteBlobBase<ActorFlavor>
-{
-public:
-  NS_DECL_ISUPPORTS_INHERITED
-
-  RemoteMemoryBlob(void* aMemoryBuffer,
-                   uint64_t aLength,
-                   const nsAString& aName,
-                   const nsAString& aContentType,
-                   uint64_t aModDate)
-  : nsDOMMemoryFile(aMemoryBuffer, aLength, aName, aContentType, aModDate)
-  {
-    mImmutable = true;
-  }
-
-  RemoteMemoryBlob(void* aMemoryBuffer,
-                   uint64_t aLength,
-                   const nsAString& aName,
-                   const nsAString& aContentType)
-  : nsDOMMemoryFile(aMemoryBuffer, aLength, aName, aContentType)
+  virtual void*
+  GetPBlob() MOZ_OVERRIDE
   {
-    mImmutable = true;
-  }
-
-  RemoteMemoryBlob(void* aMemoryBuffer,
-                   uint64_t aLength,
-                   const nsAString& aContentType)
-  : nsDOMMemoryFile(aMemoryBuffer, aLength, EmptyString(), aContentType)
-  {
-    mImmutable = true;
-  }
-
-  NS_IMETHOD
-  GetLastModifiedDate(JSContext* cx, JS::Value* aLastModifiedDate)
-  {
-    if (IsDateUnknown()) {
-      aLastModifiedDate->setNull();
-    } else {
-      JSObject* date = JS_NewDateObjectMsec(cx, mLastModificationDate);
-      if (!date) {
-        return NS_ERROR_OUT_OF_MEMORY;
-      }
-      aLastModifiedDate->setObject(*date);
-    }
-    return NS_OK;
-  }
-};
-
-template <ActorFlavorEnum ActorFlavor>
-class RemoteMultipartBlob : public nsDOMMultipartFile,
-                            public RemoteBlobBase<ActorFlavor>
-{
-
-public:
-  NS_DECL_ISUPPORTS_INHERITED
-
-  RemoteMultipartBlob(const nsAString& aName,
-                      const nsAString& aContentType)
-  : nsDOMMultipartFile(aName, aContentType)
-  {
-    mImmutable = true;
-  }
-
-  RemoteMultipartBlob(const nsAString& aName)
-  : nsDOMMultipartFile(aName)
-  {
-    mImmutable = true;
+    return static_cast<typename ActorType::ProtocolType*>(mActor);
   }
 
   NS_IMETHOD
   GetLastModifiedDate(JSContext* cx, JS::Value* aLastModifiedDate)
   {
     if (IsDateUnknown()) {
       aLastModifiedDate->setNull();
     } else {
@@ -1049,252 +941,93 @@ public:
       aLastModifiedDate->setObject(*date);
     }
     return NS_OK;
   }
 };
 
 template <ActorFlavorEnum ActorFlavor>
 Blob<ActorFlavor>::Blob(nsIDOMBlob* aBlob)
-: mBlob(aBlob), mRemoteBlob(nullptr), mRemoteMemoryBlob(nullptr),
-  mRemoteMultipartBlob(nullptr), mContentManager(nullptr),
-  mBlobManager(nullptr), mOwnsBlob(true), mBlobIsFile(false)
+: mBlob(aBlob), mRemoteBlob(nullptr), mOwnsBlob(true), mBlobIsFile(false)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aBlob);
   aBlob->AddRef();
 
   nsCOMPtr<nsIDOMFile> file = do_QueryInterface(aBlob);
   mBlobIsFile = !!file;
 }
 
 template <ActorFlavorEnum ActorFlavor>
-Blob<ActorFlavor>::Blob(nsRefPtr<RemoteBlobType>& aBlob,
-                        bool aBlobIsFile)
-: mBlob(nullptr), mRemoteBlob(nullptr), mRemoteMemoryBlob(nullptr),
-  mRemoteMultipartBlob(nullptr), mContentManager(nullptr),
-  mBlobManager(nullptr), mOwnsBlob(true), mBlobIsFile(aBlobIsFile)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(!mBlob);
-  MOZ_ASSERT(!mRemoteBlob);
-  MOZ_ASSERT(aBlob);
-
-  if (NS_FAILED(aBlob->SetMutable(false))) {
-    MOZ_NOT_REACHED("Failed to make remote blob immutable!");
-  }
-
-  aBlob->SetPBlob(this);
-  aBlob.forget(&mRemoteBlob);
-
-  mBlob = mRemoteBlob;
-}
-
-template <ActorFlavorEnum ActorFlavor>
-Blob<ActorFlavor>::Blob(nsRefPtr<RemoteMemoryBlobType>& aBlob,
-                        bool aBlobIsFile)
-: mBlob(nullptr), mRemoteBlob(nullptr), mRemoteMemoryBlob(nullptr),
-  mRemoteMultipartBlob(nullptr), mContentManager(nullptr),
-  mBlobManager(nullptr), mOwnsBlob(true), mBlobIsFile(aBlobIsFile)
+Blob<ActorFlavor>::Blob(const BlobConstructorParams& aParams)
+: mBlob(nullptr), mRemoteBlob(nullptr), mOwnsBlob(false), mBlobIsFile(false)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(!mBlob);
-  MOZ_ASSERT(!mRemoteMemoryBlob);
-  MOZ_ASSERT(aBlob);
+
+  nsRefPtr<RemoteBlobType> remoteBlob;
+
+  switch (aParams.type()) {
+    case BlobConstructorParams::TNormalBlobConstructorParams: {
+      const NormalBlobConstructorParams& params =
+        aParams.get_NormalBlobConstructorParams();
+      remoteBlob = new RemoteBlobType(params.contentType(), params.length());
+      break;
+    }
 
-  if (NS_FAILED(aBlob->SetMutable(false))) {
-    MOZ_NOT_REACHED("Failed to make remote blob immutable!");
+    case BlobConstructorParams::TFileBlobConstructorParams: {
+      const FileBlobConstructorParams& params =
+        aParams.get_FileBlobConstructorParams();
+      remoteBlob =
+        new RemoteBlobType(params.name(), params.contentType(),
+                           params.length(), params.modDate());
+      mBlobIsFile = true;
+      break;
+    }
+
+    case BlobConstructorParams::TMysteryBlobConstructorParams: {
+      remoteBlob = new RemoteBlobType();
+      mBlobIsFile = true;
+      break;
+    }
+
+    default:
+      MOZ_NOT_REACHED("Unknown params!");
   }
 
-  aBlob->SetPBlob(this);
-  aBlob.forget(&mRemoteMemoryBlob);
-
-  mBlob = mRemoteMemoryBlob;
-}
+  MOZ_ASSERT(remoteBlob);
 
-template <ActorFlavorEnum ActorFlavor>
-Blob<ActorFlavor>::Blob(nsRefPtr<RemoteMultipartBlobType>& aBlob,
-                        bool aBlobIsFile)
-: mBlob(nullptr), mRemoteBlob(nullptr), mRemoteMemoryBlob(nullptr),
-  mRemoteMultipartBlob(nullptr), mContentManager(nullptr),
-  mBlobManager(nullptr), mOwnsBlob(true), mBlobIsFile(aBlobIsFile)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(!mBlob);
-  MOZ_ASSERT(!mRemoteMultipartBlob);
-  MOZ_ASSERT(!mOwnsBlob);
-  MOZ_ASSERT(aBlob);
-
-  if (NS_FAILED(aBlob->SetMutable(false))) {
-    MOZ_NOT_REACHED("Failed to make remote blob immutable!");
-  }
-
-  aBlob->SetPBlob(this);
-  aBlob.forget(&mRemoteMultipartBlob);
-
-  mBlob = mRemoteMultipartBlob;
+  SetRemoteBlob(remoteBlob);
 }
 
 template <ActorFlavorEnum ActorFlavor>
 Blob<ActorFlavor>*
 Blob<ActorFlavor>::Create(const BlobConstructorParams& aParams)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   switch (aParams.type()) {
-    case BlobConstructorParams::TBlobConstructorNoMultipartParams: {
-      const BlobConstructorNoMultipartParams& params =
-        aParams.get_BlobConstructorNoMultipartParams();
-
-      switch (params.type()) {
-        case BlobConstructorNoMultipartParams::TBlobOrFileConstructorParams: {
-          const BlobOrFileConstructorParams& fileParams =
-            params.get_BlobOrFileConstructorParams();
-          nsRefPtr<RemoteBlobType> remoteBlob;
-          bool isFile = false;
-
-          switch (fileParams.type()) {
-            case BlobOrFileConstructorParams::TNormalBlobConstructorParams: {
-              const NormalBlobConstructorParams& normalParams =
-                fileParams.get_NormalBlobConstructorParams();
-              remoteBlob = new RemoteBlobType(normalParams.contentType(),
-                                              normalParams.length());
-              break;
-            }
-
-            case BlobOrFileConstructorParams::TFileBlobConstructorParams: {
-              const FileBlobConstructorParams& fbParams =
-                fileParams.get_FileBlobConstructorParams();
-              remoteBlob =
-                new RemoteBlobType(fbParams.name(), fbParams.contentType(),
-                                   fbParams.length(), fbParams.modDate());
-              isFile = true;
-              break;
-            }
-
-            default:
-              MOZ_NOT_REACHED("Unknown params!");
-          }
+    case BlobConstructorParams::TNormalBlobConstructorParams:
+    case BlobConstructorParams::TFileBlobConstructorParams:
+    case BlobConstructorParams::TMysteryBlobConstructorParams:
+      return new Blob<ActorFlavor>(aParams);
 
-          return new Blob<ActorFlavor>(remoteBlob, isFile);
-        }
-        case BlobConstructorNoMultipartParams::TMemoryBlobOrFileConstructorParams: {
-          const MemoryBlobOrFileConstructorParams& memoryParams =
-            params.get_MemoryBlobOrFileConstructorParams();
-          const BlobOrFileConstructorParams& internalParams =
-            memoryParams.constructorParams();
-          nsRefPtr<RemoteMemoryBlobType> remoteMemoryBlob;
-          bool isFile = false;
-
-          switch (internalParams.type()) {
-            case BlobOrFileConstructorParams::TNormalBlobConstructorParams: {
-              const NormalBlobConstructorParams& normalParams =
-                internalParams.get_NormalBlobConstructorParams();
-              MOZ_ASSERT(normalParams.length() == memoryParams.data().Length());
-
-              void* data =
-                BlobTraits<ActorFlavor>::Allocate(memoryParams.data().Length());
-              if (!data) {
-                return nullptr;
-              }
-              memcpy(data,
-                     memoryParams.data().Elements(),
-                     memoryParams.data().Length());
-              remoteMemoryBlob =
-                new RemoteMemoryBlobType(data,
-                                         memoryParams.data().Length(),
-                                         normalParams.contentType());
-              break;
-            }
-
-            case BlobOrFileConstructorParams::TFileBlobConstructorParams: {
-              const FileBlobConstructorParams& fbParams =
-                internalParams.get_FileBlobConstructorParams();
-              MOZ_ASSERT(fbParams.length() == memoryParams.data().Length());
+    case BlobConstructorParams::TSlicedBlobConstructorParams: {
+      const SlicedBlobConstructorParams& params =
+        aParams.get_SlicedBlobConstructorParams();
 
-              void* data =
-                BlobTraits<ActorFlavor>::Allocate(memoryParams.data().Length());
-              if (!data) {
-                return nullptr;
-              }
-              memcpy(data,
-                     memoryParams.data().Elements(),
-                     memoryParams.data().Length());
-              remoteMemoryBlob =
-                new RemoteMemoryBlobType(data,
-                                         memoryParams.data().Length(),
-                                         fbParams.name(),
-                                         fbParams.contentType(),
-                                         fbParams.modDate());
-              isFile = true;
-              break;
-            }
-
-            default:
-              MOZ_NOT_REACHED("Unknown params!");
-          }
-
-          return new Blob<ActorFlavor>(remoteMemoryBlob, isFile);
-        }
-        case BlobConstructorNoMultipartParams::TMysteryBlobConstructorParams: {
-          nsRefPtr<RemoteBlobType> remoteBlob = new RemoteBlobType();
-          return new Blob<ActorFlavor>(remoteBlob, true);
-        }
-
-        case BlobConstructorNoMultipartParams::TSlicedBlobConstructorParams: {
-          const SlicedBlobConstructorParams& slicedParams =
-            params.get_SlicedBlobConstructorParams();
-
-          nsCOMPtr<nsIDOMBlob> source =
-            GetBlobFromParams<ActorFlavor>(slicedParams);
-          MOZ_ASSERT(source);
+      nsCOMPtr<nsIDOMBlob> source = GetBlobFromParams<ActorFlavor>(params);
+      MOZ_ASSERT(source);
 
-          nsCOMPtr<nsIDOMBlob> slice;
-          nsresult rv =
-            source->Slice(slicedParams.begin(), slicedParams.end(),
-                          slicedParams.contentType(), 3,
-                          getter_AddRefs(slice));
-          NS_ENSURE_SUCCESS(rv, nullptr);
-
-          return new Blob<ActorFlavor>(slice);
-        }
-
-        default:
-          MOZ_NOT_REACHED("Unknown params!");
-      }
-    }
-
-    case BlobConstructorParams::TMultipartBlobOrFileConstructorParams: {
-      const MultipartBlobOrFileConstructorParams& params =
-        aParams.get_MultipartBlobOrFileConstructorParams();
+      nsCOMPtr<nsIDOMBlob> slice;
+      nsresult rv =
+        source->Slice(params.begin(), params.end(), params.contentType(), 3,
+                      getter_AddRefs(slice));
+      NS_ENSURE_SUCCESS(rv, nullptr);
 
-      nsRefPtr<RemoteMultipartBlobType> file;
-      const BlobOrFileConstructorParams& internalParams =
-        params.constructorParams();
-      switch (internalParams.type()) {
-        case BlobOrFileConstructorParams::TNormalBlobConstructorParams: {
-          const NormalBlobConstructorParams& normalParams =
-            internalParams.get_NormalBlobConstructorParams();
-          file = new RemoteMultipartBlobType(normalParams.contentType());
-          break;
-        }
-
-        case BlobOrFileConstructorParams::TFileBlobConstructorParams: {
-          const FileBlobConstructorParams& fbParams =
-            internalParams.get_FileBlobConstructorParams();
-          file = new RemoteMultipartBlobType(fbParams.name(),
-                                             fbParams.contentType());
-          break;
-        }
-
-        default:
-          MOZ_NOT_REACHED("Unknown params!");
-      }
-
-      return new Blob<ActorFlavor>(file);
+      return new Blob<ActorFlavor>(slice);
     }
 
     default:
       MOZ_NOT_REACHED("Unknown params!");
   }
 
   return nullptr;
 }
@@ -1306,18 +1039,17 @@ Blob<ActorFlavor>::GetBlob()
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mBlob);
 
   nsCOMPtr<nsIDOMBlob> blob;
 
   // Remote blobs are held alive until the first call to GetBlob. Thereafter we
   // only hold a weak reference. Normal blobs are held alive until the actor is
   // destroyed.
-  if (mOwnsBlob &&
-      (mRemoteBlob || mRemoteMemoryBlob || mRemoteMultipartBlob)) {
+  if (mRemoteBlob && mOwnsBlob) {
     blob = dont_AddRef(mBlob);
     mOwnsBlob = false;
   }
   else {
     blob = mBlob;
   }
 
   MOZ_ASSERT(blob);
@@ -1362,71 +1094,42 @@ Blob<ActorFlavor>::SetMysteryBlobInfo(co
   ToConcreteBlob(mBlob)->SetLazyData(voidString, aContentType,
                                      aLength, UINT64_MAX);
 
   NormalBlobConstructorParams params(aContentType, aLength);
   return ProtocolType::SendResolveMystery(params);
 }
 
 template <ActorFlavorEnum ActorFlavor>
-typename Blob<ActorFlavor>::ProtocolType*
-Blob<ActorFlavor>::ConstructPBlobOnManager(ProtocolType* aActor,
-                                           const BlobConstructorParams& aParams)
+void
+Blob<ActorFlavor>::SetRemoteBlob(nsRefPtr<RemoteBlobType>& aRemoteBlob)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(HasManager());
+  MOZ_ASSERT(!mBlob);
+  MOZ_ASSERT(!mRemoteBlob);
+  MOZ_ASSERT(!mOwnsBlob);
+  MOZ_ASSERT(aRemoteBlob);
 
-  if (mContentManager) {
-    return mContentManager->SendPBlobConstructor(aActor, aParams);
-  }
-
-  if (mBlobManager) {
-    return mBlobManager->SendPBlobConstructor(aActor, aParams);
+  if (NS_FAILED(aRemoteBlob->SetMutable(false))) {
+    MOZ_NOT_REACHED("Failed to make remote blob immutable!");
   }
 
-  MOZ_NOT_REACHED("Why don't I have a manager?!");
-  return nullptr;
-}
-
-template <ActorFlavorEnum ActorFlavor>
-void
-Blob<ActorFlavor>::SetManager(ContentManagerType* aManager)
-{
-  MOZ_ASSERT(!mContentManager && !mBlobManager);
-  MOZ_ASSERT(aManager);
-
-  mContentManager = aManager;
-}
+  aRemoteBlob->SetActor(this);
+  aRemoteBlob.forget(&mRemoteBlob);
 
-template <ActorFlavorEnum ActorFlavor>
-void
-Blob<ActorFlavor>::SetManager(BlobManagerType* aManager)
-{
-  MOZ_ASSERT(!mContentManager && !mBlobManager);
-  MOZ_ASSERT(aManager);
-
-  mBlobManager = aManager;
-}
-
-template <ActorFlavorEnum ActorFlavor>
-void
-Blob<ActorFlavor>::PropagateManager(Blob<ActorFlavor>* aActor) const
-{
-  MOZ_ASSERT(HasManager());
-
-  aActor->mContentManager = mContentManager;
-  aActor->mBlobManager = mBlobManager;
+  mBlob = mRemoteBlob;
+  mOwnsBlob = true;
 }
 
 template <ActorFlavorEnum ActorFlavor>
 void
 Blob<ActorFlavor>::NoteDyingRemoteBlob()
 {
   MOZ_ASSERT(mBlob);
-  MOZ_ASSERT(mRemoteBlob || mRemoteMemoryBlob || mRemoteMultipartBlob);
+  MOZ_ASSERT(mRemoteBlob);
   MOZ_ASSERT(!mOwnsBlob);
 
   // This may be called on any thread due to the fact that RemoteBlob is
   // designed to be passed between threads. We must start the shutdown process
   // on the main thread, so we proxy here if necessary.
   if (!NS_IsMainThread()) {
     nsCOMPtr<nsIRunnable> runnable =
       NS_NewNonOwningRunnableMethod(this,
@@ -1436,55 +1139,43 @@ Blob<ActorFlavor>::NoteDyingRemoteBlob()
     }
 
     return;
   }
 
   // Must do this before calling Send__delete__ or we'll crash there trying to
   // access a dangling pointer.
   mRemoteBlob = nullptr;
-  mRemoteMemoryBlob = nullptr;
-  mRemoteMultipartBlob = nullptr;
 
   mozilla::unused << ProtocolType::Send__delete__(this);
 }
 
 template <ActorFlavorEnum ActorFlavor>
 void
 Blob<ActorFlavor>::ActorDestroy(ActorDestroyReason aWhy)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mBlob);
 
   if (mRemoteBlob) {
-    mRemoteBlob->SetPBlob(nullptr);
-  }
-
-  if (mRemoteMemoryBlob) {
-    mRemoteMemoryBlob->SetPBlob(nullptr);
-  }
-
-  if (mRemoteMultipartBlob) {
-    mRemoteMultipartBlob->SetPBlob(nullptr);
+    mRemoteBlob->SetActor(nullptr);
   }
 
   if (mOwnsBlob) {
     mBlob->Release();
   }
 }
 
 template <ActorFlavorEnum ActorFlavor>
 bool
 Blob<ActorFlavor>::RecvResolveMystery(const ResolveMysteryParams& aParams)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mBlob);
   MOZ_ASSERT(!mRemoteBlob);
-  MOZ_ASSERT(!mRemoteMemoryBlob);
-  MOZ_ASSERT(!mRemoteMultipartBlob);
   MOZ_ASSERT(mOwnsBlob);
 
   if (!mBlobIsFile) {
     MOZ_ASSERT(false, "Must always be a file!");
     return false;
   }
 
   nsDOMFileBase* blob = ToConcreteBlob(mBlob);
@@ -1517,18 +1208,16 @@ Blob<ActorFlavor>::RecvResolveMystery(co
 
 template <>
 bool
 Blob<Parent>::RecvPBlobStreamConstructor(StreamType* aActor)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mBlob);
   MOZ_ASSERT(!mRemoteBlob);
-  MOZ_ASSERT(!mRemoteMemoryBlob);
-  MOZ_ASSERT(!mRemoteMultipartBlob);
 
   nsCOMPtr<nsIInputStream> stream;
   nsresult rv = mBlob->GetInternalStream(getter_AddRefs(stream));
   NS_ENSURE_SUCCESS(rv, false);
 
   nsCOMPtr<nsIIPCSerializableInputStream> serializableStream;
 
   nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryInterface(mBlob);
@@ -1574,18 +1263,16 @@ Blob<Parent>::RecvPBlobStreamConstructor
 
 template <>
 bool
 Blob<Child>::RecvPBlobStreamConstructor(StreamType* aActor)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mBlob);
   MOZ_ASSERT(!mRemoteBlob);
-  MOZ_ASSERT(!mRemoteMemoryBlob);
-  MOZ_ASSERT(!mRemoteMultipartBlob);
 
   nsCOMPtr<nsIInputStream> stream;
   nsresult rv = mBlob->GetInternalStream(getter_AddRefs(stream));
   NS_ENSURE_SUCCESS(rv, false);
 
   nsCOMPtr<nsIIPCSerializableInputStream> serializable =
     do_QueryInterface(stream);
   if (!serializable) {
@@ -1597,35 +1284,16 @@ Blob<Child>::RecvPBlobStreamConstructor(
   serializable->Serialize(params);
 
   MOZ_ASSERT(params.type() != InputStreamParams::T__None);
 
   return aActor->Send__delete__(aActor, params);
 }
 
 template <ActorFlavorEnum ActorFlavor>
-bool
-Blob<ActorFlavor>::RecvPBlobConstructor(ProtocolType* aActor,
-                                        const BlobConstructorParams& aParams)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  Blob<ActorFlavor>* subBlobActor = static_cast<Blob<ActorFlavor>*>(aActor);
-
-  if (!subBlobActor->ManagerIs(this)) {
-    // Somebody screwed up!
-    return false;
-  }
-
-  nsCOMPtr<nsIDOMBlob> blob = subBlobActor->GetBlob();
-  static_cast<nsDOMMultipartFile*>(mBlob)->AddBlob(blob);
-  return true;
-}
-
-template <ActorFlavorEnum ActorFlavor>
 typename Blob<ActorFlavor>::StreamType*
 Blob<ActorFlavor>::AllocPBlobStream()
 {
   MOZ_ASSERT(NS_IsMainThread());
   return new InputStreamActor<ActorFlavor>();
 }
 
 template <ActorFlavorEnum ActorFlavor>
@@ -1633,61 +1301,24 @@ bool
 Blob<ActorFlavor>::DeallocPBlobStream(StreamType* aActor)
 {
   MOZ_ASSERT(NS_IsMainThread());
   delete aActor;
   return true;
 }
 
 template <ActorFlavorEnum ActorFlavor>
-typename Blob<ActorFlavor>::ProtocolType*
-Blob<ActorFlavor>::AllocPBlob(const BlobConstructorParams& aParams)
-{
-  Blob<ActorFlavor>* actor = Blob<ActorFlavor>::Create(aParams);
-  actor->SetManager(this);
-  return actor;
-}
-
-template <ActorFlavorEnum ActorFlavor>
-bool
-Blob<ActorFlavor>::DeallocPBlob(ProtocolType* aActor)
-{
-  delete aActor;
-  return true;
-}
-
-template <ActorFlavorEnum ActorFlavor>
 NS_IMPL_ADDREF_INHERITED(RemoteBlob<ActorFlavor>, nsDOMFile)
 
 template <ActorFlavorEnum ActorFlavor>
 NS_IMPL_RELEASE_INHERITED(RemoteBlob<ActorFlavor>, nsDOMFile)
 
 template <ActorFlavorEnum ActorFlavor>
 NS_IMPL_QUERY_INTERFACE_INHERITED1(RemoteBlob<ActorFlavor>, nsDOMFile,
                                                             nsIRemoteBlob)
 
-template <ActorFlavorEnum ActorFlavor>
-NS_IMPL_ADDREF_INHERITED(RemoteMemoryBlob<ActorFlavor>, nsDOMMemoryFile)
-
-template <ActorFlavorEnum ActorFlavor>
-NS_IMPL_RELEASE_INHERITED(RemoteMemoryBlob<ActorFlavor>, nsDOMMemoryFile)
-
-template <ActorFlavorEnum ActorFlavor>
-NS_IMPL_QUERY_INTERFACE_INHERITED1(RemoteMemoryBlob<ActorFlavor>, nsDOMMemoryFile,
-                                                                  nsIRemoteBlob)
-
-template <ActorFlavorEnum ActorFlavor>
-NS_IMPL_ADDREF_INHERITED(RemoteMultipartBlob<ActorFlavor>, nsDOMMultipartFile)
-
-template <ActorFlavorEnum ActorFlavor>
-NS_IMPL_RELEASE_INHERITED(RemoteMultipartBlob<ActorFlavor>, nsDOMMultipartFile)
-
-template <ActorFlavorEnum ActorFlavor>
-NS_IMPL_QUERY_INTERFACE_INHERITED1(RemoteMultipartBlob<ActorFlavor>, nsDOMMultipartFile,
-                                                                     nsIRemoteBlob)
-
 // Explicit instantiation of both classes.
 template class Blob<Parent>;
 template class Blob<Child>;
 
 } // namespace ipc
 } // namespace dom
 } // namespace mozilla
--- a/dom/ipc/Blob.h
+++ b/dom/ipc/Blob.h
@@ -37,18 +37,16 @@ template <ActorFlavorEnum>
 struct BlobTraits
 { };
 
 template <>
 struct BlobTraits<Parent>
 {
   typedef mozilla::dom::PBlobParent ProtocolType;
   typedef mozilla::dom::PBlobStreamParent StreamType;
-  typedef mozilla::dom::PContentParent ContentManagerType;
-  typedef ProtocolType BlobManagerType;
 
   // BaseType on the parent side is a bit more complicated than for the child
   // side. In the case of nsIInputStreams backed by files we need to ensure that
   // the files are actually opened and closed on a background thread before we
   // can send their file handles across to the child. The child process could
   // crash during this process so we need to make sure we cancel the intended
   // response in such a case. We do that by holding an array of
   // nsRevocableEventPtr. If the child crashes then this actor will be destroyed
@@ -63,88 +61,56 @@ struct BlobTraits<Parent>
     class OpenStreamRunnable;
     friend class OpenStreamRunnable;
 
     void
     NoteRunnableCompleted(OpenStreamRunnable* aRunnable);
 
     nsTArray<nsRevocableEventPtr<OpenStreamRunnable> > mOpenStreamRunnables;
   };
-
-  static void*
-  Allocate(size_t aSize)
-  {
-    // We want fallible allocation in the parent.
-    return moz_malloc(aSize);
-  }
 };
 
 template <>
 struct BlobTraits<Child>
 {
   typedef mozilla::dom::PBlobChild ProtocolType;
   typedef mozilla::dom::PBlobStreamChild StreamType;
-  typedef mozilla::dom::PContentChild ContentManagerType;
-  typedef ProtocolType BlobManagerType;
 
   class BaseType : public ProtocolType
   {
   protected:
     BaseType()
     { }
 
     virtual ~BaseType()
     { }
   };
-
-  static void*
-  Allocate(size_t aSize)
-  {
-    // We want infallible allocation in the child.
-    return moz_xmalloc(aSize);
-  }
 };
 
 template <ActorFlavorEnum>
-class RemoteBlobBase;
-template <ActorFlavorEnum>
 class RemoteBlob;
-template <ActorFlavorEnum>
-class RemoteMemoryBlob;
-template <ActorFlavorEnum>
-class RemoteMultipartBlob;
 
 template <ActorFlavorEnum ActorFlavor>
 class Blob : public BlobTraits<ActorFlavor>::BaseType
 {
-  friend class RemoteBlobBase<ActorFlavor>;
+  friend class RemoteBlob<ActorFlavor>;
 
 public:
   typedef typename BlobTraits<ActorFlavor>::ProtocolType ProtocolType;
   typedef typename BlobTraits<ActorFlavor>::StreamType StreamType;
   typedef typename BlobTraits<ActorFlavor>::BaseType BaseType;
-  typedef typename BlobTraits<ActorFlavor>::ContentManagerType ContentManagerType;
-  typedef typename BlobTraits<ActorFlavor>::BlobManagerType BlobManagerType;
   typedef RemoteBlob<ActorFlavor> RemoteBlobType;
-  typedef RemoteMemoryBlob<ActorFlavor> RemoteMemoryBlobType;
-  typedef RemoteMultipartBlob<ActorFlavor> RemoteMultipartBlobType;
   typedef mozilla::ipc::IProtocolManager<
                       mozilla::ipc::RPCChannel::RPCListener>::ActorDestroyReason
           ActorDestroyReason;
   typedef mozilla::dom::BlobConstructorParams BlobConstructorParams;
 
 protected:
   nsIDOMBlob* mBlob;
   RemoteBlobType* mRemoteBlob;
-  RemoteMemoryBlobType* mRemoteMemoryBlob;
-  RemoteMultipartBlobType* mRemoteMultipartBlob;
-
-  ContentManagerType* mContentManager;
-  BlobManagerType* mBlobManager;
-
   bool mOwnsBlob;
   bool mBlobIsFile;
 
 public:
   // This create function is called on the sending side.
   static Blob*
   Create(nsIDOMBlob* aBlob)
   {
@@ -165,88 +131,44 @@ public:
   bool
   SetMysteryBlobInfo(const nsString& aName, const nsString& aContentType,
                      uint64_t aLength, uint64_t aLastModifiedDate);
 
   // Use this for non-file blobs.
   bool
   SetMysteryBlobInfo(const nsString& aContentType, uint64_t aLength);
 
-  ProtocolType*
-  ConstructPBlobOnManager(ProtocolType* aActor,
-                          const BlobConstructorParams& aParams);
-
-  bool
-  ManagerIs(const ContentManagerType* aManager) const
-  {
-    return aManager == mContentManager;
-  }
-
-  bool
-  ManagerIs(const BlobManagerType* aManager) const
-  {
-    return aManager == mBlobManager;
-  }
-
-#ifdef DEBUG
-  bool
-  HasManager() const
-  {
-    return !!mContentManager || !!mBlobManager;
-  }
-#endif
-
-  void
-  SetManager(ContentManagerType* aManager);
-  void
-  SetManager(BlobManagerType* aManager);
-
-  void
-  PropagateManager(Blob<ActorFlavor>* aActor) const;
-
 private:
   // This constructor is called on the sending side.
   Blob(nsIDOMBlob* aBlob);
 
-  // These constructors are called on the receiving side.
-  Blob(nsRefPtr<RemoteBlobType>& aBlob,
-       bool aIsFile);
-  Blob(nsRefPtr<RemoteMemoryBlobType>& aBlob,
-       bool aIsFile);
-  Blob(nsRefPtr<RemoteMultipartBlobType>& aBlob,
-       bool aIsFile);
+  // This constructor is called on the receiving side.
+  Blob(const BlobConstructorParams& aParams);
+
+  void
+  SetRemoteBlob(nsRefPtr<RemoteBlobType>& aRemoteBlob);
 
   void
   NoteDyingRemoteBlob();
 
   // These methods are only called by the IPDL message machinery.
   virtual void
   ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
 
   virtual bool
   RecvResolveMystery(const ResolveMysteryParams& aParams) MOZ_OVERRIDE;
 
   virtual bool
   RecvPBlobStreamConstructor(StreamType* aActor) MOZ_OVERRIDE;
 
-  virtual bool
-  RecvPBlobConstructor(ProtocolType* aActor,
-                       const BlobConstructorParams& aParams) MOZ_OVERRIDE;
-
   virtual StreamType*
   AllocPBlobStream() MOZ_OVERRIDE;
 
   virtual bool
   DeallocPBlobStream(StreamType* aActor) MOZ_OVERRIDE;
-
-  virtual ProtocolType*
-  AllocPBlob(const BlobConstructorParams& params) MOZ_OVERRIDE;
-
-  virtual bool
-  DeallocPBlob(ProtocolType* actor) MOZ_OVERRIDE;
 };
 
 } // namespace ipc
 
 typedef mozilla::dom::ipc::Blob<mozilla::dom::ipc::Child> BlobChild;
 typedef mozilla::dom::ipc::Blob<mozilla::dom::ipc::Parent> BlobParent;
 
 } // namespace dom
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -541,150 +541,91 @@ ContentChild::DeallocPBrowser(PBrowserCh
     TabChild* child = static_cast<TabChild*>(iframe);
     NS_RELEASE(child);
     return true;
 }
 
 PBlobChild*
 ContentChild::AllocPBlob(const BlobConstructorParams& aParams)
 {
-  BlobChild* actor = BlobChild::Create(aParams);
-  actor->SetManager(this);
-  return actor;
+  return BlobChild::Create(aParams);
 }
 
 bool
 ContentChild::DeallocPBlob(PBlobChild* aActor)
 {
   delete aActor;
   return true;
 }
 
-bool
-ContentChild::GetParamsForBlob(nsDOMFileBase* aBlob,
-                               BlobConstructorParams* aOutParams)
+BlobChild*
+ContentChild::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
 {
-  BlobConstructorParams resultParams;
+  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+  NS_ASSERTION(aBlob, "Null pointer!");
+
+  nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryInterface(aBlob);
+  if (remoteBlob) {
+    BlobChild* actor =
+      static_cast<BlobChild*>(static_cast<PBlobChild*>(remoteBlob->GetPBlob()));
+    NS_ASSERTION(actor, "Null actor?!");
 
-  if (!(aBlob->IsMemoryBacked() || aBlob->GetSubBlobs()) &&
-      (aBlob->IsSizeUnknown() || aBlob->IsDateUnknown())) {
+    return actor;
+  }
+
+  // XXX This is only safe so long as all blob implementations in our tree
+  //     inherit nsDOMFileBase. If that ever changes then this will need to grow
+  //     a real interface or something.
+  const nsDOMFileBase* blob = static_cast<nsDOMFileBase*>(aBlob);
+
+  BlobConstructorParams params;
+
+  if (blob->IsSizeUnknown() || blob->IsDateUnknown()) {
     // We don't want to call GetSize or GetLastModifiedDate
     // yet since that may stat a file on the main thread
     // here. Instead we'll learn the size lazily from the
     // other process.
-    resultParams = MysteryBlobConstructorParams();
+    params = MysteryBlobConstructorParams();
   }
   else {
-    BlobOrFileConstructorParams params;
-
     nsString contentType;
     nsresult rv = aBlob->GetType(contentType);
-    NS_ENSURE_SUCCESS(rv, false);
+    NS_ENSURE_SUCCESS(rv, nullptr);
 
     uint64_t length;
     rv = aBlob->GetSize(&length);
-    NS_ENSURE_SUCCESS(rv, false);
+    NS_ENSURE_SUCCESS(rv, nullptr);
 
-    nsCOMPtr<nsIDOMFile> file;
-    static_cast<nsIDOMBlob*>(aBlob)->QueryInterface(NS_GET_IID(nsIDOMFile),
-                                          (void**)getter_AddRefs(file));
+    nsCOMPtr<nsIDOMFile> file = do_QueryInterface(aBlob);
     if (file) {
       FileBlobConstructorParams fileParams;
 
       rv = file->GetName(fileParams.name());
-      NS_ENSURE_SUCCESS(rv, false);
+      NS_ENSURE_SUCCESS(rv, nullptr);
 
       rv = file->GetMozLastModifiedDate(&fileParams.modDate());
-      NS_ENSURE_SUCCESS(rv, false);
+      NS_ENSURE_SUCCESS(rv, nullptr);
 
       fileParams.contentType() = contentType;
       fileParams.length() = length;
 
       params = fileParams;
     } else {
       NormalBlobConstructorParams blobParams;
       blobParams.contentType() = contentType;
       blobParams.length() = length;
       params = blobParams;
     }
-
-    MOZ_ASSERT(!(aBlob->IsMemoryBacked() &&
-                 aBlob->GetSubBlobs()), "Can't be both!");
-
-    if (aBlob->IsMemoryBacked()) {
-      const nsDOMMemoryFile* memoryBlob =
-        static_cast<const nsDOMMemoryFile*>(aBlob);
-
-      InfallibleTArray<uint8_t> data;
-      data.SetLength(memoryBlob->GetLength());
-      memcpy(data.Elements(), memoryBlob->GetData(), memoryBlob->GetLength());
-
-      MemoryBlobOrFileConstructorParams memoryParams(params, data);
-      resultParams = memoryParams;
-    }
-    else if (aBlob->GetSubBlobs()) {
-      MultipartBlobOrFileConstructorParams multipartParams(params);
-      resultParams = multipartParams;
-    }
-    else {
-      resultParams = BlobConstructorNoMultipartParams(params);
-    }
-  }
-
-  *aOutParams = resultParams;
-
-  return true;
-}
-
-BlobChild*
-ContentChild::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-  NS_ASSERTION(aBlob, "Null pointer!");
-
-  // XXX This is only safe so long as all blob implementations in our tree
-  //     inherit nsDOMFileBase. If that ever changes then this will need to grow
-  //     a real interface or something.
-  nsDOMFileBase* blob = static_cast<nsDOMFileBase*>(aBlob);
-
-  nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryInterface(aBlob);
-  if (remoteBlob) {
-    BlobChild* actor =
-      static_cast<BlobChild*>(static_cast<PBlobChild*>(remoteBlob->GetPBlob()));
-    NS_ASSERTION(actor, "Null actor?!");
-
-    return actor;
-  }
-
-  BlobConstructorParams params;
-  if (!GetParamsForBlob(blob, &params)) {
-    return nullptr;
   }
 
   BlobChild* actor = BlobChild::Create(aBlob);
   NS_ENSURE_TRUE(actor, nullptr);
 
-  SendPBlobConstructor(actor, params);
-
-  actor->SetManager(this);
-
-  if (const nsTArray<nsCOMPtr<nsIDOMBlob> >* subBlobs = blob->GetSubBlobs()) {
-    for (uint32_t i = 0; i < subBlobs->Length(); ++i) {
-      BlobConstructorParams subParams;
-      nsDOMFileBase* subBlob =
-        static_cast<nsDOMFileBase*>(subBlobs->ElementAt(i).get());
-      if (!GetParamsForBlob(subBlob, &subParams)) {
-        return nullptr;
-      }
-
-      BlobChild* subActor = BlobChild::Create(aBlob);
-      actor->SendPBlobConstructor(subActor, subParams);
-
-      subActor->SetManager(actor);
-    }
+  if (!SendPBlobConstructor(actor, params)) {
+    return nullptr;
   }
 
   return actor;
 }
 
 PCrashReporterChild*
 ContentChild::AllocPCrashReporter(const mozilla::dom::NativeThreadId& id,
                                   const uint32_t& processType)
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -12,17 +12,16 @@
 #include "mozilla/dom/TabContext.h"
 #include "mozilla/dom/ipc/Blob.h"
 
 #include "nsTArray.h"
 #include "nsIConsoleListener.h"
 
 struct ChromePackage;
 class nsIDOMBlob;
-class nsDOMFileBase;
 class nsIObserver;
 struct ResourceMapping;
 struct OverrideMapping;
 
 namespace mozilla {
 
 namespace ipc {
 class OptionalURIParams;
@@ -194,18 +193,16 @@ public:
 #endif
 
     // Get the directory for IndexedDB files. We query the parent for this and
     // cache the value
     nsString &GetIndexedDBPath();
 
     uint64_t GetID() { return mID; }
 
-    bool GetParamsForBlob(nsDOMFileBase* aBlob,
-                          BlobConstructorParams* aOutParams);
     BlobChild* GetOrCreateActorForBlob(nsIDOMBlob* aBlob);
 
 private:
     virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
 
     virtual void ProcessingError(Result what) MOZ_OVERRIDE;
 
     /**
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -1413,161 +1413,96 @@ ContentParent::DeallocPDeviceStorageRequ
   DeviceStorageRequestParent *parent = static_cast<DeviceStorageRequestParent*>(doomed);
   NS_RELEASE(parent);
   return true;
 }
 
 PBlobParent*
 ContentParent::AllocPBlob(const BlobConstructorParams& aParams)
 {
-  BlobParent* actor = BlobParent::Create(aParams);
-  actor->SetManager(this);
-  return actor;
+  return BlobParent::Create(aParams);
 }
 
 bool
 ContentParent::DeallocPBlob(PBlobParent* aActor)
 {
   delete aActor;
   return true;
 }
 
-bool
-ContentParent::GetParamsForBlob(nsDOMFileBase* aBlob,
-                                BlobConstructorParams* aOutParams)
+BlobParent*
+ContentParent::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
 {
-  BlobConstructorParams resultParams;
+  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+  NS_ASSERTION(aBlob, "Null pointer!");
+
+  nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryInterface(aBlob);
+  if (remoteBlob) {
+    BlobParent* actor =
+      static_cast<BlobParent*>(
+        static_cast<PBlobParent*>(remoteBlob->GetPBlob()));
+    NS_ASSERTION(actor, "Null actor?!");
 
-  if (!(aBlob->IsMemoryBacked() || aBlob->GetSubBlobs()) &&
-      (aBlob->IsSizeUnknown() || aBlob->IsDateUnknown())) {
+    if (static_cast<ContentParent*>(actor->Manager()) == this) {
+      return actor;
+    }
+  }
+
+  // XXX This is only safe so long as all blob implementations in our tree
+  //     inherit nsDOMFileBase. If that ever changes then this will need to grow
+  //     a real interface or something.
+  const nsDOMFileBase* blob = static_cast<nsDOMFileBase*>(aBlob);
+
+  BlobConstructorParams params;
+
+  if (blob->IsSizeUnknown() || blob->IsDateUnknown()) {
     // We don't want to call GetSize or GetLastModifiedDate
     // yet since that may stat a file on the main thread
     // here. Instead we'll learn the size lazily from the
     // other process.
-    resultParams = MysteryBlobConstructorParams();
+    params = MysteryBlobConstructorParams();
   }
   else {
-    BlobOrFileConstructorParams params;
-
     nsString contentType;
     nsresult rv = aBlob->GetType(contentType);
-    NS_ENSURE_SUCCESS(rv, false);
+    NS_ENSURE_SUCCESS(rv, nullptr);
 
     uint64_t length;
     rv = aBlob->GetSize(&length);
-    NS_ENSURE_SUCCESS(rv, false);
+    NS_ENSURE_SUCCESS(rv, nullptr);
 
-    nsCOMPtr<nsIDOMFile> file;
-    static_cast<nsIDOMBlob*>(aBlob)->QueryInterface(NS_GET_IID(nsIDOMFile),
-                                          (void**)getter_AddRefs(file));
+    nsCOMPtr<nsIDOMFile> file = do_QueryInterface(aBlob);
     if (file) {
       FileBlobConstructorParams fileParams;
 
-      rv = file->GetName(fileParams.name());
-      NS_ENSURE_SUCCESS(rv, false);
+      rv = file->GetMozLastModifiedDate(&fileParams.modDate());
+      NS_ENSURE_SUCCESS(rv, nullptr);
 
-      rv = file->GetMozLastModifiedDate(&fileParams.modDate());
-      NS_ENSURE_SUCCESS(rv, false);
+      rv = file->GetName(fileParams.name());
+      NS_ENSURE_SUCCESS(rv, nullptr);
 
       fileParams.contentType() = contentType;
       fileParams.length() = length;
 
       params = fileParams;
     } else {
       NormalBlobConstructorParams blobParams;
       blobParams.contentType() = contentType;
       blobParams.length() = length;
       params = blobParams;
     }
-
-    MOZ_ASSERT(!(aBlob->IsMemoryBacked() &&
-                 aBlob->GetSubBlobs()), "Can't be both!");
-
-    if (aBlob->IsMemoryBacked()) {
-      const nsDOMMemoryFile* memoryBlob =
-        static_cast<const nsDOMMemoryFile*>(aBlob);
-
-      FallibleTArray<uint8_t> data;
-      if (!data.SetLength(memoryBlob->GetLength())) {
-        return false;
-      }
-      memcpy(data.Elements(), memoryBlob->GetData(), memoryBlob->GetLength());
-
-      MemoryBlobOrFileConstructorParams memoryParams(params, data);
-      resultParams = memoryParams;
-    }
-    else if (aBlob->GetSubBlobs()) {
-      MultipartBlobOrFileConstructorParams multipartParams(params);
-      resultParams = multipartParams;
-    }
-    else {
-      resultParams = BlobConstructorNoMultipartParams(params);
-    }
-  }
-
-  *aOutParams = resultParams;
-
-  return true;
-}
-
-BlobParent*
-ContentParent::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-  NS_ASSERTION(aBlob, "Null pointer!");
-
-  // XXX This is only safe so long as all blob implementations in our tree
-  //     inherit nsDOMFileBase. If that ever changes then this will need to grow
-  //     a real interface or something.
-  nsDOMFileBase* blob = static_cast<nsDOMFileBase*>(aBlob);
-
-  nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryInterface(aBlob);
-  if (remoteBlob) {
-    BlobParent* actor =
-      static_cast<BlobParent*>(
-        static_cast<PBlobParent*>(remoteBlob->GetPBlob()));
-    NS_ASSERTION(actor, "Null actor?!");
-
-    if (actor->ManagerIs(this)) {
-      return actor;
-    }
-  }
-
-  BlobConstructorParams params;
-  if (!GetParamsForBlob(blob, &params)) {
-    return nullptr;
   }
 
   BlobParent* actor = BlobParent::Create(aBlob);
   NS_ENSURE_TRUE(actor, nullptr);
 
   if (!SendPBlobConstructor(actor, params)) {
     return nullptr;
   }
 
-  actor->SetManager(this);
-
-  if (const nsTArray<nsCOMPtr<nsIDOMBlob> >* subBlobs = blob->GetSubBlobs()) {
-    for (uint32_t i = 0; i < subBlobs->Length(); ++i) {
-      BlobConstructorParams subParams;
-      nsDOMFileBase* subBlob =
-        static_cast<nsDOMFileBase*>(subBlobs->ElementAt(i).get());
-      if (!GetParamsForBlob(subBlob, &subParams)) {
-        return nullptr;
-      }
-
-      BlobParent* subActor = BlobParent::Create(aBlob);
-      if (!actor->SendPBlobConstructor(subActor, subParams)) {
-        return nullptr;
-      }
-
-      subActor->SetManager(actor);
-    }
-  }
-
   return actor;
 }
 
 void
 ContentParent::KillHard()
 {
     mForceKillTask = nullptr;
     // This ensures the process is eventually killed, but doesn't
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -30,17 +30,16 @@
 
 #define CHILD_PROCESS_SHUTDOWN_MESSAGE NS_LITERAL_STRING("child-process-shutdown")
 
 #define CONTENT_PARENT_UNKNOWN_CHILD_ID -1
 
 class mozIApplication;
 class nsConsoleService;
 class nsIDOMBlob;
-class nsDOMFileBase;
 
 namespace mozilla {
 
 namespace ipc {
 class OptionalURIParams;
 class URIParams;
 class TestShellParent;
 } // namespace ipc
@@ -126,19 +125,18 @@ public:
     GeckoChildProcessHost* Process() {
         return mSubprocess;
     }
 
     bool NeedsPermissionsUpdate() {
         return mSendPermissionUpdates;
     }
 
-    bool GetParamsForBlob(nsDOMFileBase* aBlob,
-                          BlobConstructorParams* aOutParams);
     BlobParent* GetOrCreateActorForBlob(nsIDOMBlob* aBlob);
+
     /**
      * Kill our subprocess and make sure it dies.  Should only be used
      * in emergency situations since it bypasses the normal shutdown
      * process.
      */
     void KillHard();
 
     uint64_t ChildID() { return mChildID; }
--- a/dom/ipc/DOMTypes.ipdlh
+++ b/dom/ipc/DOMTypes.ipdlh
@@ -26,54 +26,10 @@ struct NormalBlobConstructorParams
 struct FileBlobConstructorParams
 {
   nsString name;
   nsString contentType;
   uint64_t length;
   uint64_t modDate;
 };
 
-union BlobOrFileConstructorParams
-{
-  NormalBlobConstructorParams;
-  FileBlobConstructorParams;
-};
-
-struct MemoryBlobOrFileConstructorParams
-{
-  BlobOrFileConstructorParams constructorParams;
-  uint8_t[] data;
-};
-
-struct SlicedBlobConstructorParams
-{
-  PBlob source;
-  uint64_t begin;
-  uint64_t end;
-  nsString contentType;
-};
-
-struct MysteryBlobConstructorParams
-{
-  // Nothing is known about this type of blob.
-};
-
-union BlobConstructorNoMultipartParams
-{
-  BlobOrFileConstructorParams;
-  MemoryBlobOrFileConstructorParams;
-  SlicedBlobConstructorParams;
-  MysteryBlobConstructorParams;
-};
-
-struct MultipartBlobOrFileConstructorParams
-{
-  BlobOrFileConstructorParams constructorParams;
-};
-
-union BlobConstructorParams
-{
-  BlobConstructorNoMultipartParams;
-  MultipartBlobOrFileConstructorParams;
-};
-
 } // namespace dom
 } // namespace mozilla
--- a/dom/ipc/PBlob.ipdl
+++ b/dom/ipc/PBlob.ipdl
@@ -13,23 +13,21 @@ namespace dom {
 union ResolveMysteryParams
 {
   NormalBlobConstructorParams;
   FileBlobConstructorParams;
 };
 
 protocol PBlob
 {
-  manager PContent or PBlob;
+  manager PContent;
   manages PBlobStream;
-  manages PBlob;
 
 both:
   __delete__();
 
-  PBlob(BlobConstructorParams params);
   PBlobStream();
 
   ResolveMystery(ResolveMysteryParams params);
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -112,16 +112,37 @@ union DeviceStorageParams
 {
   DeviceStorageAddParams;
   DeviceStorageGetParams;
   DeviceStorageDeleteParams;
   DeviceStorageEnumerationParams;
   DeviceStorageStatParams;
 };
 
+struct SlicedBlobConstructorParams
+{
+  PBlob source;
+  uint64_t begin;
+  uint64_t end;
+  nsString contentType;
+};
+
+struct MysteryBlobConstructorParams
+{
+  // Nothing is known about this type of blob.
+};
+
+union BlobConstructorParams
+{
+  NormalBlobConstructorParams;
+  FileBlobConstructorParams;
+  SlicedBlobConstructorParams;
+  MysteryBlobConstructorParams;
+};
+
 // An IPCTabContext which corresponds to a PBrowser opened by a child when it
 // receives window.open().
 //
 // If isBrowserElement is false, this PopupIPCTabContext corresponds to an app
 // frame, and the frame's app-id and app-frame-owner-app-id will be equal to the
 // opener's values.
 //
 // If isBrowserElement is true, the frame's browserFrameOwnerAppId will be equal
--- a/dom/ipc/nsIRemoteBlob.h
+++ b/dom/ipc/nsIRemoteBlob.h
@@ -7,24 +7,22 @@
 
 #include "nsISupports.h"
 
 #ifndef NS_NO_VTABLE
 #define NS_NO_VTABLE
 #endif
 
 #define NS_IREMOTEBLOB_IID \
-  {0x1f569fbc, 0xf588, 0x41c5, {0xa0, 0x73, 0x92, 0x0d, 0xf5, 0x9f, 0x1b, 0xdb}}
+  {0x74ce3cdd, 0xbfc9, 0x4edb, {0x98, 0x26, 0x50, 0xcf, 0x00, 0x26, 0x58, 0x70}}
 
 class NS_NO_VTABLE nsIRemoteBlob : public nsISupports
 {
 public: 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IREMOTEBLOB_IID)
 
   // This will either return a PBlobChild or PBlobParent.
   virtual void* GetPBlob() = 0;
-
-  virtual void SetPBlob(void* aActor) = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIRemoteBlob, NS_IREMOTEBLOB_IID)
 
 #endif // mozilla_dom_ipc_nsIRemoteBlob_h
--- a/dom/workers/File.cpp
+++ b/dom/workers/File.cpp
@@ -82,17 +82,17 @@ private:
   Unwrap(JSContext* aCx, JSObject* aObj)
   {
     return GetPrivate(aObj);
   }
 
   static JSBool
   Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
-    nsRefPtr<nsDOMMultipartFile> file = new nsDOMMultipartFile(EmptyString());
+    nsRefPtr<nsDOMMultipartFile> file = new nsDOMMultipartFile();
     nsresult rv = file->InitBlob(aCx, aArgc, JS_ARGV(aCx, aVp), Unwrap);
     if (NS_FAILED(rv)) {
       ThrowDOMExceptionForNSResult(aCx, rv);
       return false;
     }
 
     JSObject* obj = file::CreateBlob(aCx, file);
     if (!obj) {