Bug 1441651 - Part 2 - pass Shmem and ByteBuf by rvalref to Send* IPC methods; r=nika,jrmuizel
authorAlex Gaynor <agaynor@mozilla.com>
Mon, 04 Mar 2019 16:35:30 +0000
changeset 462243 1c4fb23363e0fca41931986561ff580c129eaa6e
parent 462242 9adad198b9b4b54b5813cf8a367ab0db41c36635
child 462244 7fdcccd878addbfb83cd4587777a710ed070f6f5
push id35644
push useraciure@mozilla.com
push dateMon, 04 Mar 2019 21:48:23 +0000
treeherdermozilla-central@a9bb4a23d407 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnika, jrmuizel
bugs1441651
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1441651 - Part 2 - pass Shmem and ByteBuf by rvalref to Send* IPC methods; r=nika,jrmuizel Differential Revision: https://phabricator.services.mozilla.com/D19954
dom/base/nsContentUtils.cpp
dom/media/gmp/ChromiumCDMChild.cpp
dom/media/gmp/ChromiumCDMParent.cpp
dom/media/gmp/GMPSharedMemManager.cpp
dom/media/gmp/GMPSharedMemManager.h
dom/media/gmp/GMPVideoDecoderChild.cpp
dom/media/gmp/GMPVideoDecoderChild.h
dom/media/gmp/GMPVideoDecoderParent.h
dom/media/gmp/GMPVideoEncoderChild.cpp
dom/media/gmp/GMPVideoEncoderChild.h
dom/media/gmp/GMPVideoEncoderParent.h
dom/media/ipc/RemoteAudioDecoder.cpp
dom/media/ipc/RemoteDecoderChild.cpp
dom/media/ipc/RemoteVideoDecoder.cpp
dom/media/ipc/VideoDecoderChild.cpp
dom/media/ipc/VideoDecoderManagerParent.cpp
dom/media/systemservices/CamerasChild.cpp
dom/media/systemservices/CamerasParent.cpp
dom/plugins/ipc/PluginInstanceChild.cpp
dom/plugins/ipc/PluginInstanceParent.cpp
dom/plugins/ipc/PluginModuleParent.cpp
gfx/layers/BufferTexture.cpp
gfx/layers/composite/LayerManagerComposite.cpp
gfx/layers/ipc/ShadowLayers.cpp
gfx/layers/ipc/UiCompositorControllerChild.cpp
gfx/layers/wr/WebRenderBridgeChild.cpp
ipc/glue/CrashReporterClient.h
ipc/ipdl/ipdl/lower.py
ipc/ipdl/test/cxx/TestEndpointOpens.cpp
ipc/ipdl/test/cxx/TestShmem.cpp
ipc/ipdl/test/cxx/TestUniquePtrIPC.cpp
widget/nsDragServiceProxy.cpp
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -7503,30 +7503,30 @@ void nsContentUtils::TransferableToIPCTr
 
         Shmem dataAsShmem = ConvertToShmem(aChild, aParent, dataAsString);
         if (!dataAsShmem.IsReadable() || !dataAsShmem.Size<char>()) {
           continue;
         }
 
         IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
         item->flavor() = flavorStr;
-        item->data() = dataAsShmem;
+        item->data() = std::move(dataAsShmem);
       } else if (nsCOMPtr<nsIInputStream> stream = do_QueryInterface(data)) {
         // Images to be pasted on the clipboard are nsIInputStreams
         nsCString imageData;
         NS_ConsumeStream(stream, UINT32_MAX, imageData);
 
         Shmem imageDataShmem = ConvertToShmem(aChild, aParent, imageData);
         if (!imageDataShmem.IsReadable() || !imageDataShmem.Size<char>()) {
           continue;
         }
 
         IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
         item->flavor() = flavorStr;
-        item->data() = imageDataShmem;
+        item->data() = std::move(imageDataShmem);
       } else if (nsCOMPtr<imgIContainer> image = do_QueryInterface(data)) {
         // Images to be placed on the clipboard are imgIContainers.
         RefPtr<mozilla::gfx::SourceSurface> surface = image->GetFrame(
             imgIContainer::FRAME_CURRENT, imgIContainer::FLAG_SYNC_DECODE);
         if (!surface) {
           continue;
         }
         RefPtr<mozilla::gfx::DataSourceSurface> dataSurface =
@@ -7544,17 +7544,17 @@ void nsContentUtils::TransferableToIPCTr
 
         if (surfaceData.isNothing()) {
           continue;
         }
 
         IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
         item->flavor() = flavorStr;
         // Turn item->data() into an nsCString prior to accessing it.
-        item->data() = surfaceData.ref();
+        item->data() = std::move(surfaceData.ref());
 
         IPCDataTransferImage& imageDetails = item->imageDetails();
         mozilla::gfx::IntSize size = dataSurface->GetSize();
         imageDetails.width() = size.width;
         imageDetails.height() = size.height;
         imageDetails.stride() = stride;
         imageDetails.format() = dataSurface->GetFormat();
       } else {
@@ -7575,17 +7575,17 @@ void nsContentUtils::TransferableToIPCTr
               Shmem dataAsShmem = ConvertToShmem(aChild, aParent, data);
               if (!dataAsShmem.IsReadable() || !dataAsShmem.Size<char>()) {
                 continue;
               }
 
               IPCDataTransferItem* item =
                   aIPCDataTransfer->items().AppendElement();
               item->flavor() = type;
-              item->data() = dataAsShmem;
+              item->data() = std::move(dataAsShmem);
             }
 
             continue;
           }
 
           if (aParent) {
             bool isDir = false;
             if (NS_SUCCEEDED(file->IsDirectory(&isDir)) && isDir) {
--- a/dom/media/gmp/ChromiumCDMChild.cpp
+++ b/dom/media/gmp/ChromiumCDMChild.cpp
@@ -666,17 +666,17 @@ mozilla::ipc::IPCResult ChromiumCDMChild
   if (status != cdm::kSuccess || !buffer) {
     Unused << SendDecryptFailed(aId, status);
     return IPC_OK();
   }
 
   // Success! Return the decrypted sample to parent.
   MOZ_ASSERT(!HasShmemOfSize(outputShmemSize));
   ipc::Shmem shmem = buffer->ExtractShmem();
-  if (SendDecrypted(aId, cdm::kSuccess, shmem)) {
+  if (SendDecrypted(aId, cdm::kSuccess, std::move(shmem))) {
     // No need to deallocate the output shmem; it should have been returned
     // to the content process.
     autoDeallocateOutputShmem.release();
   }
 
   return IPC_OK();
 }
 
@@ -815,17 +815,17 @@ void ChromiumCDMChild::ReturnOutput(Wide
   uint64_t duration = 0;
   if (mFrameDurations.Find(aFrame.Timestamp(), duration)) {
     output.mDuration() = duration;
   }
 
   CDMBuffer* base = reinterpret_cast<CDMBuffer*>(aFrame.FrameBuffer());
   if (base->AsShmemBuffer()) {
     ipc::Shmem shmem = base->AsShmemBuffer()->ExtractShmem();
-    Unused << SendDecodedShmem(output, shmem);
+    Unused << SendDecodedShmem(output, std::move(shmem));
   } else {
     MOZ_ASSERT(base->AsArrayBuffer());
     Unused << SendDecodedData(output, base->AsArrayBuffer()->ExtractBuffer());
   }
 }
 
 mozilla::ipc::IPCResult ChromiumCDMChild::RecvDrain() {
   MOZ_ASSERT(IsOnMessageLoopThread());
--- a/dom/media/gmp/ChromiumCDMParent.cpp
+++ b/dom/media/gmp/ChromiumCDMParent.cpp
@@ -265,17 +265,17 @@ bool ChromiumCDMParent::InitCDMInputBuff
       break;
   }
 
   const nsTArray<uint8_t>& iv =
       encryptionScheme != GMPEncryptionScheme::kGMPEncryptionCbcs
           ? crypto.mIV
           : crypto.mConstantIV;
   aBuffer = gmp::CDMInputBuffer(
-      shmem, crypto.mKeyId, iv, aSample->mTime.ToMicroseconds(),
+      std::move(shmem), crypto.mKeyId, iv, aSample->mTime.ToMicroseconds(),
       aSample->mDuration.ToMicroseconds(), crypto.mPlainSizes,
       crypto.mEncryptedSizes, crypto.mCryptByteBlock, crypto.mSkipByteBlock,
       encryptionScheme);
   MOZ_ASSERT(
       aBuffer.mEncryptionScheme() == GMPEncryptionScheme::kGMPEncryptionNone ||
           aBuffer.mEncryptionScheme() ==
               GMPEncryptionScheme::kGMPEncryptionCenc ||
           aBuffer.mEncryptionScheme() ==
@@ -286,17 +286,17 @@ bool ChromiumCDMParent::InitCDMInputBuff
 }
 
 bool ChromiumCDMParent::SendBufferToCDM(uint32_t aSizeInBytes) {
   GMP_LOG("ChromiumCDMParent::SendBufferToCDM() size=%" PRIu32, aSizeInBytes);
   Shmem shmem;
   if (!AllocShmem(aSizeInBytes, Shmem::SharedMemory::TYPE_BASIC, &shmem)) {
     return false;
   }
-  if (!SendGiveBuffer(shmem)) {
+  if (!SendGiveBuffer(std::move(shmem))) {
     DeallocShmem(shmem);
     return false;
   }
   return true;
 }
 
 RefPtr<DecryptPromise> ChromiumCDMParent::Decrypt(MediaRawData* aSample) {
   if (mIsShutdown) {
@@ -708,17 +708,17 @@ ipc::IPCResult ChromiumCDMParent::RecvDe
         MediaResult(NS_ERROR_OUT_OF_MEMORY,
                     RESULT_DETAIL("Can't create VideoData")),
         __func__);
     return IPC_OK();
   }
 
   // Return the shmem to the CDM so the shmem can be reused to send us
   // another frame.
-  if (!SendGiveBuffer(aShmem)) {
+  if (!SendGiveBuffer(std::move(aShmem))) {
     mDecodePromise.RejectIfExists(
         MediaResult(NS_ERROR_OUT_OF_MEMORY,
                     RESULT_DETAIL("Can't return shmem to CDM process")),
         __func__);
     return IPC_OK();
   }
 
   // Don't need to deallocate the shmem since the CDM process is responsible
--- a/dom/media/gmp/GMPSharedMemManager.cpp
+++ b/dom/media/gmp/GMPSharedMemManager.cpp
@@ -63,17 +63,17 @@ bool GMPSharedMemManager::MgrDeallocShme
       MOZ_CRASH("Deallocating Shmem we already have in our cache!");
       // return true;
     }
   }
 
   // XXX This works; there are better pool algorithms.  We need to avoid
   // "falling off a cliff" with too low a number
   if (GetGmpFreelist(aClass).Length() > 10) {
-    Dealloc(GetGmpFreelist(aClass)[0]);
+    Dealloc(std::move(GetGmpFreelist(aClass)[0]));
     GetGmpFreelist(aClass).RemoveElementAt(0);
     // The allocation numbers will be fubar on the Child!
     mData->mGmpAllocated[aClass]--;
   }
   for (uint32_t i = 0; i < GetGmpFreelist(aClass).Length(); i++) {
     MOZ_ASSERT(GetGmpFreelist(aClass)[i].IsWritable());
     total += GetGmpFreelist(aClass)[i].Size<uint8_t>();
     if (size < GetGmpFreelist(aClass)[i].Size<uint8_t>()) {
--- a/dom/media/gmp/GMPSharedMemManager.h
+++ b/dom/media/gmp/GMPSharedMemManager.h
@@ -63,17 +63,17 @@ class GMPSharedMemManager {
   // crashed
   virtual uint32_t NumInUse(GMPSharedMem::GMPMemoryClasses aClass);
 
   // These have to be implemented using the AllocShmem/etc provided by the
   // IPDL-generated interfaces, so have the Parent/Child implement them.
   virtual bool Alloc(size_t aSize,
                      ipc::Shmem::SharedMemory::SharedMemoryType aType,
                      ipc::Shmem* aMem) = 0;
-  virtual void Dealloc(ipc::Shmem& aMem) = 0;
+  virtual void Dealloc(ipc::Shmem&& aMem) = 0;
 
  private:
   nsTArray<ipc::Shmem>& GetGmpFreelist(GMPSharedMem::GMPMemoryClasses aTypes) {
     return mData->mGmpFreelist[aTypes];
   }
 
   GMPSharedMem* mData;
 };
--- a/dom/media/gmp/GMPVideoDecoderChild.cpp
+++ b/dom/media/gmp/GMPVideoDecoderChild.cpp
@@ -202,18 +202,18 @@ bool GMPVideoDecoderChild::Alloc(size_t 
   rv = AllocShmem(aSize, aType, aMem);
 #  else
   rv = AllocUnsafeShmem(aSize, aType, aMem);
 #  endif
 #endif
   return rv;
 }
 
-void GMPVideoDecoderChild::Dealloc(Shmem& aMem) {
+void GMPVideoDecoderChild::Dealloc(Shmem&& aMem) {
 #ifndef SHMEM_ALLOC_IN_CHILD
-  SendParentShmemForPool(aMem);
+  SendParentShmemForPool(std::move(aMem));
 #else
   DeallocShmem(aMem);
 #endif
 }
 
 }  // namespace gmp
 }  // namespace mozilla
--- a/dom/media/gmp/GMPVideoDecoderChild.h
+++ b/dom/media/gmp/GMPVideoDecoderChild.h
@@ -38,17 +38,17 @@ class GMPVideoDecoderChild : public PGMP
   void InputDataExhausted() override;
   void DrainComplete() override;
   void ResetComplete() override;
   void Error(GMPErr aError) override;
 
   // GMPSharedMemManager
   bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType,
              Shmem* aMem) override;
-  void Dealloc(Shmem& aMem) override;
+  void Dealloc(Shmem&& aMem) override;
 
  private:
   virtual ~GMPVideoDecoderChild();
 
   // PGMPVideoDecoderChild
   mozilla::ipc::IPCResult RecvInitDecode(
       const GMPVideoCodec& aCodecSettings,
       InfallibleTArray<uint8_t>&& aCodecSpecific, const int32_t& aCoreCount);
--- a/dom/media/gmp/GMPVideoDecoderParent.h
+++ b/dom/media/gmp/GMPVideoDecoderParent.h
@@ -55,17 +55,17 @@ class GMPVideoDecoderParent final : publ
   bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType,
              Shmem* aMem) override {
 #ifdef GMP_SAFE_SHMEM
     return AllocShmem(aSize, aType, aMem);
 #else
     return AllocUnsafeShmem(aSize, aType, aMem);
 #endif
   }
-  void Dealloc(Shmem& aMem) override { DeallocShmem(aMem); }
+  void Dealloc(Shmem&& aMem) override { DeallocShmem(aMem); }
 
  private:
   ~GMPVideoDecoderParent();
 
   // PGMPVideoDecoderParent
   void ActorDestroy(ActorDestroyReason aWhy) override;
   mozilla::ipc::IPCResult RecvDecoded(
       const GMPVideoi420FrameData& aDecodedFrame) override;
--- a/dom/media/gmp/GMPVideoEncoderChild.cpp
+++ b/dom/media/gmp/GMPVideoEncoderChild.cpp
@@ -194,18 +194,18 @@ bool GMPVideoEncoderChild::Alloc(size_t 
   rv = AllocShmem(aSize, aType, aMem);
 #  else
   rv = AllocUnsafeShmem(aSize, aType, aMem);
 #  endif
 #endif
   return rv;
 }
 
-void GMPVideoEncoderChild::Dealloc(Shmem& aMem) {
+void GMPVideoEncoderChild::Dealloc(Shmem&& aMem) {
 #ifndef SHMEM_ALLOC_IN_CHILD
-  SendParentShmemForPool(aMem);
+  SendParentShmemForPool(std::move(aMem));
 #else
   DeallocShmem(aMem);
 #endif
 }
 
 }  // namespace gmp
 }  // namespace mozilla
--- a/dom/media/gmp/GMPVideoEncoderChild.h
+++ b/dom/media/gmp/GMPVideoEncoderChild.h
@@ -34,17 +34,17 @@ class GMPVideoEncoderChild : public PGMP
   void Encoded(GMPVideoEncodedFrame* aEncodedFrame,
                const uint8_t* aCodecSpecificInfo,
                uint32_t aCodecSpecificInfoLength) override;
   void Error(GMPErr aError) override;
 
   // GMPSharedMemManager
   bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType,
              Shmem* aMem) override;
-  void Dealloc(Shmem& aMem) override;
+  void Dealloc(Shmem&& aMem) override;
 
  private:
   virtual ~GMPVideoEncoderChild();
 
   // PGMPVideoEncoderChild
   mozilla::ipc::IPCResult RecvInitEncode(
       const GMPVideoCodec& aCodecSettings,
       InfallibleTArray<uint8_t>&& aCodecSpecific, const int32_t& aNumberOfCores,
--- a/dom/media/gmp/GMPVideoEncoderParent.h
+++ b/dom/media/gmp/GMPVideoEncoderParent.h
@@ -53,17 +53,17 @@ class GMPVideoEncoderParent : public GMP
   bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType,
              Shmem* aMem) override {
 #ifdef GMP_SAFE_SHMEM
     return AllocShmem(aSize, aType, aMem);
 #else
     return AllocUnsafeShmem(aSize, aType, aMem);
 #endif
   }
-  void Dealloc(Shmem& aMem) override { DeallocShmem(aMem); }
+  void Dealloc(Shmem&& aMem) override { DeallocShmem(aMem); }
 
  private:
   virtual ~GMPVideoEncoderParent(){};
 
   // PGMPVideoEncoderParent
   void ActorDestroy(ActorDestroyReason aWhy) override;
   mozilla::ipc::IPCResult RecvEncoded(
       const GMPVideoEncodedFrameData& aEncodedFrame,
--- a/dom/media/ipc/RemoteAudioDecoder.cpp
+++ b/dom/media/ipc/RemoteAudioDecoder.cpp
@@ -109,15 +109,15 @@ void RemoteAudioDecoderParent::ProcessDe
         audio->Data().Length() == buffer.Size<AudioDataValue>()) {
       PodCopy(buffer.get<AudioDataValue>(), audio->Data().Elements(),
               audio->Data().Length());
     }
 
     RemoteAudioDataIPDL output(
         MediaDataIPDL(data->mOffset, data->mTime, data->mTimecode,
                       data->mDuration, data->mKeyframe),
-        audio->mChannels, audio->mRate, audio->mChannelMap, buffer);
+        audio->mChannels, audio->mRate, audio->mChannelMap, std::move(buffer));
 
     Unused << SendOutput(output);
   }
 }
 
 }  // namespace mozilla
--- a/dom/media/ipc/RemoteDecoderChild.cpp
+++ b/dom/media/ipc/RemoteDecoderChild.cpp
@@ -109,17 +109,17 @@ RefPtr<MediaDataDecoder::DecodePromise> 
         NS_ERROR_DOM_MEDIA_DECODE_ERR, __func__);
   }
 
   memcpy(buffer.get<uint8_t>(), aSample->Data(), aSample->Size());
 
   MediaRawDataIPDL sample(
       MediaDataIPDL(aSample->mOffset, aSample->mTime, aSample->mTimecode,
                     aSample->mDuration, aSample->mKeyframe),
-      buffer);
+      std::move(buffer));
   SendInput(sample);
 
   return mDecodePromise.Ensure(__func__);
 }
 
 RefPtr<MediaDataDecoder::FlushPromise> RemoteDecoderChild::Flush() {
   AssertOnManagerThread();
   mDecodePromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
--- a/dom/media/ipc/RemoteVideoDecoder.cpp
+++ b/dom/media/ipc/RemoteVideoDecoder.cpp
@@ -179,17 +179,17 @@ void RemoteVideoDecoderParent::ProcessDe
     PlanarYCbCrImage* image =
         static_cast<PlanarYCbCrImage*>(video->mImage.get());
 
     SurfaceDescriptorBuffer sdBuffer;
     Shmem buffer;
     if (AllocShmem(image->GetDataSize(), Shmem::SharedMemory::TYPE_BASIC,
                    &buffer) &&
         image->GetDataSize() == buffer.Size<uint8_t>()) {
-      sdBuffer.data() = buffer;
+      sdBuffer.data() = std::move(buffer);
       image->BuildSurfaceDescriptorBuffer(sdBuffer);
     }
 
     RemoteVideoDataIPDL output(
         MediaDataIPDL(data->mOffset, data->mTime, data->mTimecode,
                       data->mDuration, data->mKeyframe),
         video->mDisplay, image->GetSize(), sdBuffer, video->mFrameID);
     Unused << SendOutput(output);
--- a/dom/media/ipc/VideoDecoderChild.cpp
+++ b/dom/media/ipc/VideoDecoderChild.cpp
@@ -238,17 +238,17 @@ RefPtr<MediaDataDecoder::DecodePromise> 
         NS_ERROR_DOM_MEDIA_DECODE_ERR, __func__);
   }
 
   memcpy(buffer.get<uint8_t>(), aSample->Data(), aSample->Size());
 
   MediaRawDataIPDL sample(
       MediaDataIPDL(aSample->mOffset, aSample->mTime, aSample->mTimecode,
                     aSample->mDuration, aSample->mKeyframe),
-      buffer);
+      std::move(buffer));
   SendInput(sample);
   return mDecodePromise.Ensure(__func__);
 }
 
 RefPtr<MediaDataDecoder::FlushPromise> VideoDecoderChild::Flush() {
   AssertOnManagerThread();
   mDecodePromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
   mDrainPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
--- a/dom/media/ipc/VideoDecoderManagerParent.cpp
+++ b/dom/media/ipc/VideoDecoderManagerParent.cpp
@@ -260,17 +260,17 @@ mozilla::ipc::IPCResult VideoDecoderMana
     *aResult = null_t();
     return IPC_OK();
   }
 
   dt->CopySurface(source, IntRect(0, 0, size.width, size.height), IntPoint());
   dt->Flush();
 
   *aResult = SurfaceDescriptorBuffer(RGBDescriptor(size, format, true),
-                                     MemoryOrShmem(buffer));
+                                     MemoryOrShmem(std::move(buffer)));
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 VideoDecoderManagerParent::RecvDeallocateSurfaceDescriptorGPUVideo(
     const SurfaceDescriptorGPUVideo& aSD) {
   mImageMap.erase(aSD.handle());
   mTextureMap.erase(aSD.handle());
--- a/dom/media/systemservices/CamerasChild.cpp
+++ b/dom/media/systemservices/CamerasChild.cpp
@@ -570,17 +570,17 @@ mozilla::ipc::IPCResult CamerasChild::Re
     mozilla::ipc::Shmem&& shmem, const VideoFrameProperties& prop) {
   MutexAutoLock lock(mCallbackMutex);
   if (Callback(capEngine, capId)) {
     unsigned char* image = shmem.get<unsigned char>();
     Callback(capEngine, capId)->DeliverFrame(image, prop);
   } else {
     LOG(("DeliverFrame called with dead callback"));
   }
-  SendReleaseFrame(shmem);
+  SendReleaseFrame(std::move(shmem));
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult CamerasChild::RecvDeviceChange() {
   this->OnDeviceChange();
   return IPC_OK();
 }
 
--- a/dom/media/systemservices/CamerasParent.cpp
+++ b/dom/media/systemservices/CamerasParent.cpp
@@ -273,24 +273,25 @@ int CamerasParent::DeliverFrameOverIPC(C
       LOG(("No usable Video shmem in DeliverFrame (out of buffers?)"));
       // We can skip this frame if we run out of buffers, it's not a real error.
       return 0;
     }
 
     // get() and Size() check for proper alignment of the segment
     memcpy(shMemBuff.GetBytes(), altbuffer, aProps.bufferSize());
 
-    if (!SendDeliverFrame(capEng, aStreamId, shMemBuff.Get(), aProps)) {
+    if (!SendDeliverFrame(capEng, aStreamId, std::move(shMemBuff.Get()),
+                          aProps)) {
       return -1;
     }
   } else {
     MOZ_ASSERT(buffer.Valid());
     // ShmemBuffer was available, we're all good. A single copy happened
     // in the original webrtc callback.
-    if (!SendDeliverFrame(capEng, aStreamId, buffer.Get(), aProps)) {
+    if (!SendDeliverFrame(capEng, aStreamId, std::move(buffer.Get()), aProps)) {
       return -1;
     }
   }
 
   return 0;
 }
 
 ShmemBuffer CamerasParent::GetBuffer(size_t aSize) {
--- a/dom/plugins/ipc/PluginInstanceChild.cpp
+++ b/dom/plugins/ipc/PluginInstanceChild.cpp
@@ -2717,18 +2717,18 @@ void PluginInstanceChild::NPN_SetCurrent
         return;
       }
 
       IntRect dirty = changed ? NPRectToIntRect(*changed)
                               : IntRect(IntPoint(0, 0), bitmap->mSize);
 
       // Need a holder since IPDL zaps the object for mysterious reasons.
       Shmem shmemHolder = bitmap->mShmem;
-      SendShowDirectBitmap(shmemHolder, bitmap->mFormat, bitmap->mStride,
-                           bitmap->mSize, dirty);
+      SendShowDirectBitmap(std::move(shmemHolder), bitmap->mFormat,
+                           bitmap->mStride, bitmap->mSize, dirty);
       break;
     }
 #if defined(XP_WIN)
     case NPDrawingModelAsyncWindowsDXGISurface: {
       WindowsHandle handle;
       if (!mDxgiSurfaces.Get(surface, &handle)) {
         return;
       }
@@ -3564,18 +3564,18 @@ bool PluginInstanceChild::ShowPluginFram
       mCurrentSurfaceActor = SendPPluginSurfaceConstructor(
           handle, mCurrentSurface->GetSize(), haveTransparentPixels);
     }
     currSurf = mCurrentSurfaceActor;
     s->Flush();
   } else
 #endif
       if (gfxSharedImageSurface::IsSharedImage(mCurrentSurface)) {
-    currSurf =
-        static_cast<gfxSharedImageSurface*>(mCurrentSurface.get())->GetShmem();
+    currSurf = std::move(
+        static_cast<gfxSharedImageSurface*>(mCurrentSurface.get())->GetShmem());
   } else {
     MOZ_CRASH("Surface type is not remotable");
     return false;
   }
 
   // Unused, except to possibly return a shmem to us
   SurfaceDescriptor returnSurf;
 
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -844,18 +844,18 @@ mozilla::ipc::IPCResult PluginInstancePa
     } else
 #endif
     {
       mFrontSurface->Flush();
     }
   }
 
   if (mFrontSurface && gfxSharedImageSurface::IsSharedImage(mFrontSurface))
-    *prevSurface =
-        static_cast<gfxSharedImageSurface*>(mFrontSurface.get())->GetShmem();
+    *prevSurface = std::move(
+        static_cast<gfxSharedImageSurface*>(mFrontSurface.get())->GetShmem());
   else
     *prevSurface = null_t();
 
   if (surface) {
     // Notify the cairo backend that this surface has changed behind
     // its back.
     gfxRect ur(updatedRect.left, updatedRect.top,
                updatedRect.right - updatedRect.left,
@@ -1156,17 +1156,17 @@ PluginInstanceParent::BackgroundDescript
   return SurfaceDescriptorX11(xsurf);
 #endif
 
 #ifdef XP_WIN
   MOZ_ASSERT(gfxSharedImageSurface::IsSharedImage(mBackground),
              "Expected shared image surface");
   gfxSharedImageSurface* shmem =
       static_cast<gfxSharedImageSurface*>(mBackground.get());
-  return shmem->GetShmem();
+  return mozilla::plugins::SurfaceDescriptor(std::move(shmem->GetShmem()));
 #endif
 
   // If this is ever used, which it shouldn't be, it will trigger a
   // hard assertion in IPDL-generated code.
   return mozilla::plugins::SurfaceDescriptor();
 }
 
 ImageContainer* PluginInstanceParent::GetImageContainer() {
@@ -1547,18 +1547,18 @@ int16_t PluginInstanceParent::NPP_Handle
         PLUGIN_LOG_DEBUG(("NPCocoaEventDrawRect on window of size 0."));
         return false;
       }
       if (!mShSurface.IsReadable()) {
         PLUGIN_LOG_DEBUG(("Shmem is not readable."));
         return false;
       }
 
-      if (!CallNPP_HandleEvent_Shmem(npremoteevent, mShSurface, &handled,
-                                     &mShSurface))
+      if (!CallNPP_HandleEvent_Shmem(npremoteevent, std::move(mShSurface),
+                                     &handled, &mShSurface))
         return false;  // no good way to handle errors here...
 
       if (!mShSurface.IsReadable()) {
         PLUGIN_LOG_DEBUG(
             ("Shmem not returned. Either the plugin crashed "
              "or we have a bug."));
         return false;
       }
--- a/dom/plugins/ipc/PluginModuleParent.cpp
+++ b/dom/plugins/ipc/PluginModuleParent.cpp
@@ -525,17 +525,17 @@ void PluginModuleChromeParent::OnProcess
 
 bool PluginModuleChromeParent::InitCrashReporter() {
   ipc::Shmem shmem;
   if (!ipc::CrashReporterClient::AllocShmem(this, &shmem)) {
     return false;
   }
 
   NativeThreadId threadId;
-  if (!CallInitCrashReporter(shmem, &threadId)) {
+  if (!CallInitCrashReporter(std::move(shmem), &threadId)) {
     return false;
   }
 
   {
     mozilla::MutexAutoLock lock(mCrashReporterMutex);
     mCrashReporter = MakeUnique<ipc::CrashReporterHost>(GeckoProcessType_Plugin,
                                                         shmem, threadId);
   }
--- a/gfx/layers/BufferTexture.cpp
+++ b/gfx/layers/BufferTexture.cpp
@@ -479,17 +479,18 @@ TextureData* MemoryTextureData::CreateSi
 }
 
 bool ShmemTextureData::Serialize(SurfaceDescriptor& aOutDescriptor) {
   MOZ_ASSERT(GetFormat() != gfx::SurfaceFormat::UNKNOWN);
   if (GetFormat() == gfx::SurfaceFormat::UNKNOWN) {
     return false;
   }
 
-  aOutDescriptor = SurfaceDescriptorBuffer(mDescriptor, MemoryOrShmem(mShmem));
+  aOutDescriptor =
+      SurfaceDescriptorBuffer(mDescriptor, MemoryOrShmem(std::move(mShmem)));
 
   return true;
 }
 
 ShmemTextureData* ShmemTextureData::Create(gfx::IntSize aSize,
                                            gfx::SurfaceFormat aFormat,
                                            gfx::BackendType aMoz2DBackend,
                                            LayersBackend aLayersBackend,
--- a/gfx/layers/composite/LayerManagerComposite.cpp
+++ b/gfx/layers/composite/LayerManagerComposite.cpp
@@ -1199,17 +1199,17 @@ void LayerManagerComposite::HandlePixels
     return;
   }
   CompositorOGL* compositor = mCompositor->AsCompositorOGL();
   GLContext* gl = compositor->gl();
   MOZ_ASSERT(gl);
   gl->fReadPixels(0, 0, bufferWidth, bufferHeight, LOCAL_GL_RGBA,
                   LOCAL_GL_UNSIGNED_BYTE, mem.get<uint8_t>());
   Unused << mScreenPixelsTarget->SendScreenPixels(
-      mem, ScreenIntSize(bufferWidth, bufferHeight));
+      std::move(mem), ScreenIntSize(bufferWidth, bufferHeight));
   mScreenPixelsTarget = nullptr;
 }
 #endif
 
 already_AddRefed<PaintedLayer> LayerManagerComposite::CreatePaintedLayer() {
   if (mDestroyed) {
     NS_WARNING("Call on destroyed layer manager");
     return nullptr;
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -959,17 +959,17 @@ bool ShadowLayerForwarder::AllocSurfaceD
     bufferDesc = reinterpret_cast<uintptr_t>(data);
   } else {
     mozilla::ipc::Shmem shmem;
     if (!GetTextureForwarder()->AllocUnsafeShmem(size, OptimalShmemType(),
                                                  &shmem)) {
       return false;
     }
 
-    bufferDesc = shmem;
+    bufferDesc = std::move(shmem);
   }
 
   // Use an intermediate buffer by default. Skipping the intermediate buffer is
   // only possible in certain configurations so let's keep it simple here for
   // now.
   const bool hasIntermediateBuffer = true;
   *aBuffer = SurfaceDescriptorBuffer(
       RGBDescriptor(aSize, format, hasIntermediateBuffer), bufferDesc);
--- a/gfx/layers/ipc/UiCompositorControllerChild.cpp
+++ b/gfx/layers/ipc/UiCompositorControllerChild.cpp
@@ -161,17 +161,17 @@ bool UiCompositorControllerChild::Enable
 }
 
 bool UiCompositorControllerChild::ToolbarPixelsToCompositor(
     Shmem& aMem, const ScreenIntSize& aSize) {
   if (!mIsOpen) {
     return false;
   }
 
-  return SendToolbarPixelsToCompositor(aMem, aSize);
+  return SendToolbarPixelsToCompositor(std::move(aMem), aSize);
 }
 
 void UiCompositorControllerChild::Destroy() {
   if (!IsOnUiThread()) {
     GetUiThread()->Dispatch(
         NewRunnableMethod("layers::UiCompositorControllerChild::Destroy", this,
                           &UiCompositorControllerChild::Destroy),
         nsIThread::DISPATCH_SYNC);
--- a/gfx/layers/wr/WebRenderBridgeChild.cpp
+++ b/gfx/layers/wr/WebRenderBridgeChild.cpp
@@ -93,17 +93,18 @@ void WebRenderBridgeChild::UpdateResourc
     return;
   }
 
   nsTArray<OpUpdateResource> resourceUpdates;
   nsTArray<RefCountedShmem> smallShmems;
   nsTArray<ipc::Shmem> largeShmems;
   aResources.Flush(resourceUpdates, smallShmems, largeShmems);
 
-  this->SendUpdateResources(resourceUpdates, smallShmems, largeShmems);
+  this->SendUpdateResources(resourceUpdates, smallShmems,
+                            std::move(largeShmems));
 }
 
 void WebRenderBridgeChild::EndTransaction(
     const wr::LayoutSize& aContentSize, wr::BuiltDisplayList& aDL,
     wr::IpcResourceUpdateQueue& aResources, const gfx::IntSize& aSize,
     TransactionId aTransactionId, const WebRenderScrollData& aScrollData,
     bool aContainsSVGGroup, const mozilla::VsyncId& aVsyncId,
     const mozilla::TimeStamp& aVsyncStartTime,
@@ -118,22 +119,22 @@ void WebRenderBridgeChild::EndTransactio
 
   TimeStamp fwdTime = TimeStamp::Now();
 
   nsTArray<OpUpdateResource> resourceUpdates;
   nsTArray<RefCountedShmem> smallShmems;
   nsTArray<ipc::Shmem> largeShmems;
   aResources.Flush(resourceUpdates, smallShmems, largeShmems);
 
-  this->SendSetDisplayList(aSize, mParentCommands, mDestroyedActors,
-                           GetFwdTransactionId(), aTransactionId, aContentSize,
-                           dlData, aDL.dl_desc, aScrollData, resourceUpdates,
-                           smallShmems, largeShmems, mIdNamespace,
-                           aContainsSVGGroup, aVsyncId, aVsyncStartTime,
-                           aRefreshStartTime, aTxnStartTime, aTxnURL, fwdTime);
+  this->SendSetDisplayList(
+      aSize, mParentCommands, mDestroyedActors, GetFwdTransactionId(),
+      aTransactionId, aContentSize, std::move(dlData), aDL.dl_desc, aScrollData,
+      resourceUpdates, smallShmems, std::move(largeShmems), mIdNamespace,
+      aContainsSVGGroup, aVsyncId, aVsyncStartTime, aRefreshStartTime,
+      aTxnStartTime, aTxnURL, fwdTime);
 
   mParentCommands.Clear();
   mDestroyedActors.Clear();
   mIsInTransaction = false;
 }
 
 void WebRenderBridgeChild::EndEmptyTransaction(
     const FocusTarget& aFocusTarget, const ScrollUpdatesMap& aUpdates,
@@ -153,18 +154,18 @@ void WebRenderBridgeChild::EndEmptyTrans
   if (aResources) {
     aResources->Flush(resourceUpdates, smallShmems, largeShmems);
     aResources.reset();
   }
 
   this->SendEmptyTransaction(
       aFocusTarget, aUpdates, aPaintSequenceNumber, mParentCommands,
       mDestroyedActors, GetFwdTransactionId(), aTransactionId, resourceUpdates,
-      smallShmems, largeShmems, mIdNamespace, aVsyncId, aVsyncStartTime,
-      aRefreshStartTime, aTxnStartTime, aTxnURL, fwdTime);
+      smallShmems, std::move(largeShmems), mIdNamespace, aVsyncId,
+      aVsyncStartTime, aRefreshStartTime, aTxnStartTime, aTxnURL, fwdTime);
   mParentCommands.Clear();
   mDestroyedActors.Clear();
   mIsInTransaction = false;
 }
 
 void WebRenderBridgeChild::ProcessWebRenderParentCommands() {
   MOZ_ASSERT(!mDestroyed);
 
--- a/ipc/glue/CrashReporterClient.h
+++ b/ipc/glue/CrashReporterClient.h
@@ -38,17 +38,17 @@ class CrashReporterClient {
 
     Shmem shmem;
     if (!AllocShmem(aToplevelProtocol, &shmem)) {
       return false;
     }
 
     InitSingletonWithShmem(shmem);
     Unused << aToplevelProtocol->SendInitCrashReporter(
-        shmem, CrashReporter::CurrentThreadId());
+        std::move(shmem), CrashReporter::CurrentThreadId());
     return true;
   }
 
   template <typename T>
   static bool AllocShmem(T* aToplevelProtocol, Shmem* aOutShmem) {
     // 16KB should be enough for most metadata - see bug 1278717 comment #11.
     static const size_t kShmemSize = 16 * 1024;
 
--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -693,16 +693,18 @@ necessarily a C++ reference."""
 
     def constPtrToType(self, side):
         return _cxxConstPtrToType(self.ipdltype, side)
 
     def inType(self, side):
         """Return this decl's C++ Type with inparam semantics."""
         if self.ipdltype.isIPDL() and self.ipdltype.isActor():
             return self.bareType(side)
+        elif _cxxTypeNeedsMoveForSend(self.ipdltype):
+            return self.rvalueRefType(side)
         return self.constRefType(side)
 
     def moveType(self, side):
         """Return this decl's C++ Type with move semantics."""
         if self.ipdltype.isIPDL() and self.ipdltype.isActor():
             return self.bareType(side)
         return self.rvalueRefType(side)
 
@@ -973,17 +975,17 @@ class MessageDecl(ipdl.ast.MessageDecl):
         if self.decl.type.isCtor():
             name += 'Constructor'
         return name
 
     def sendMethod(self):
         name = _sendPrefix(self.decl.type) + self.baseName()
         if self.decl.type.isCtor():
             name += 'Constructor'
-        return ExprVar(name)
+        return name
 
     def hasReply(self):
         return (self.decl.type.hasReply()
                 or self.decl.type.isCtor()
                 or self.decl.type.isDtor())
 
     def hasAsyncReturns(self):
         return (self.decl.type.isAsync() and
@@ -2101,17 +2103,17 @@ class _ParamTraits():
                 readcase.addstmt(cls.ifsideis(c.side,
                                               StmtBlock([cls.fatalError('wrong side!'),
                                                          StmtReturn.FALSE])))
                 c = c.other
             tmpvar = ExprVar('tmp')
             ct = c.bareType(fq=True)
             readcase.addstmts([
                 StmtDecl(Decl(ct, tmpvar.name), init=c.defaultValue(fq=True)),
-                StmtExpr(ExprAssn(ExprDeref(cls.var), tmpvar)),
+                StmtExpr(ExprAssn(ExprDeref(cls.var), ExprMove(tmpvar))),
                 cls._checkedRead(c.ipdltype,
                                  ExprAddrOf(ExprCall(ExprSelect(cls.var, '->',
                                                                 c.getTypeName()))),
                                  origenum,
                                  'variant ' + origenum + ' of union ' + uniontype.name()),
                 StmtReturn.TRUE,
             ])
             readswitch.addcase(caselabel, readcase)
@@ -2529,17 +2531,17 @@ def _generateCxxUnion(ud):
     for c in ud.components:
         copyctor = ConstructorDefn(ConstructorDecl(
             ud.name, params=[Decl(c.inType(), othervar.name)]))
         copyctor.addstmts([
             StmtExpr(c.callCtor(othervar)),
             StmtExpr(ExprAssn(mtypevar, c.enumvar()))])
         cls.addstmts([copyctor, Whitespace.NL])
 
-        if not _cxxTypeCanMove(c.ipdltype):
+        if not _cxxTypeCanMove(c.ipdltype) or _cxxTypeNeedsMoveForSend(c.ipdltype):
             continue
         movector = ConstructorDefn(ConstructorDecl(
             ud.name, params=[Decl(c.forceMoveType(), othervar.name)]))
         movector.addstmts([
             StmtExpr(c.callCtor(ExprMove(othervar))),
             StmtExpr(ExprAssn(mtypevar, c.enumvar()))])
         cls.addstmts([movector, Whitespace.NL])
 
@@ -2636,17 +2638,17 @@ def _generateCxxUnion(ud):
             maybeReconstruct(c, c.enumvar()),
             StmtExpr(c.callOperatorEq(rhsvar)),
             StmtExpr(ExprAssn(mtypevar, c.enumvar())),
             StmtReturn(ExprDeref(ExprVar.THIS))
         ])
         cls.addstmts([opeq, Whitespace.NL])
 
         # Union& operator=(T&&)
-        if not _cxxTypeCanMove(c.ipdltype):
+        if not _cxxTypeCanMove(c.ipdltype) or _cxxTypeNeedsMoveForSend(c.ipdltype):
             continue
 
         opeq = MethodDefn(MethodDecl(
             'operator=',
             params=[Decl(c.forceMoveType(), rhsvar.name)],
             ret=refClsType))
         opeq.addstmts([
             # might need to placement-delete old value first
@@ -4113,45 +4115,29 @@ class _GenerateProtocolActorCode(ipdl.as
         ifresolve.addelsestmts(desrej)
         ifresolve.addelsestmts(rejectcallback)
         case.addstmts(prologue)
         case.addstmts(getcallback)
         case.addstmt(ifresolve)
         case.addstmt(StmtReturn(_Result.Processed))
         return (lbl, case)
 
-    @staticmethod
-    def hasMoveableParams(md):
-        for param in md.decl.type.params:
-            if _cxxTypeCanMoveSend(param):
-                return True
-        return False
-
     def genAsyncSendMethod(self, md):
         method = MethodDefn(self.makeSendMethodDecl(md))
         msgvar, stmts = self.makeMessage(md, errfnSend)
         retvar, sendstmts = self.sendAsync(md, msgvar)
 
         method.addstmts(stmts
                         + [Whitespace.NL]
                         + self.genVerifyMessage(md.decl.type.verify, md.params,
                                                 errfnSend, ExprVar('msg__'))
                         + sendstmts
                         + [StmtReturn(retvar)])
 
-        if self.hasMoveableParams(md):
-            movemethod = MethodDefn(self.makeSendMethodDecl(md, paramsems='move'))
-            movemethod.addstmts(stmts
-                                + [Whitespace.NL]
-                                + self.genVerifyMessage(md.decl.type.verify, md.params,
-                                                        errfnSend, ExprVar('msg__'))
-                                + sendstmts
-                                + [StmtReturn(retvar)])
-        else:
-            movemethod = None
+        movemethod = None
 
         # Add the promise overload if we need one.
         if md.returns:
             promisemethod = MethodDefn(self.makeSendMethodDecl(md, promise=True))
             stmts = self.sendAsyncWithPromise(md)
             promisemethod.addstmts(stmts)
 
             (lbl, case) = self.genRecvAsyncReplyCase(md)
@@ -4180,31 +4166,17 @@ class _GenerateProtocolActorCode(ipdl.as
             + [Whitespace.NL,
                 StmtDecl(Decl(Type('Message'), replyvar.name))]
             + sendstmts
             + [failif]
             + desstmts
             + [Whitespace.NL,
                 StmtReturn.TRUE])
 
-        if self.hasMoveableParams(md):
-            movemethod = MethodDefn(self.makeSendMethodDecl(md, paramsems='move'))
-            movemethod.addstmts(
-                serstmts
-                + self.genVerifyMessage(md.decl.type.verify, md.params, errfnSend,
-                                        ExprVar('msg__'))
-                + [Whitespace.NL,
-                    StmtDecl(Decl(Type('Message'), replyvar.name))]
-                + sendstmts
-                + [failif]
-                + desstmts
-                + [Whitespace.NL,
-                    StmtReturn.TRUE])
-        else:
-            movemethod = None
+        movemethod = None
 
         return method, movemethod
 
     def genCtorRecvCase(self, md):
         lbl = CaseLabel(md.pqMsgId())
         case = StmtBlock()
         actorvar = md.actorDecl().var()
         actorhandle = self.handlevar
@@ -4674,17 +4646,17 @@ class _GenerateProtocolActorCode(ipdl.as
         rejectfn.addstmts([
             StmtExpr(ExprCall(ExprSelect(retpromise, '->', 'Reject'),
                               args=[ExprMove(ExprVar('aReason')),
                                     ExprVar('__func__')])),
         ])
 
         args = [p.var() for p in md.params] + [resolvefn, rejectfn]
         stmts += [Whitespace.NL,
-                  StmtExpr(ExprCall(ExprVar(md.sendMethod().name), args=args)),
+                  StmtExpr(ExprCall(ExprVar(md.sendMethod()), args=args)),
                   StmtReturn(retpromise)]
         return stmts
 
     def callAllocActor(self, md, retsems, side):
         return self.thisCall(
             _allocMethod(md.decl.type.constructedType(), side),
             args=md.makeCxxArgs(retsems=retsems, retcallsems='out',
                                 implicit=False))
@@ -4745,17 +4717,17 @@ class _GenerateProtocolActorCode(ipdl.as
             else:
                 returnsems = 'callback'
                 rettype = Type.VOID
         else:
             assert not promise
             returnsems = 'out'
             rettype = Type.BOOL
         decl = MethodDecl(
-            md.sendMethod().name,
+            md.sendMethod(),
             params=md.makeCxxParams(paramsems, returnsems=returnsems,
                                     side=self.side, implicit=implicit),
             warn_unused=(self.side == 'parent' and returnsems != 'callback'),
             ret=rettype)
         if md.decl.type.isCtor():
             decl.ret = md.actorDecl().bareType(self.side)
         return decl
 
--- a/ipc/ipdl/test/cxx/TestEndpointOpens.cpp
+++ b/ipc/ipdl/test/cxx/TestEndpointOpens.cpp
@@ -163,17 +163,17 @@ mozilla::ipc::IPCResult TestEndpointOpen
   if (!gChildThread->Start()) {
     fail("starting child thread");
   }
 
   TestEndpointOpensOpenedChild* a = new TestEndpointOpensOpenedChild();
   gChildThread->message_loop()->PostTask(
       NewRunnableFunction("OpenChild", OpenChild, a, std::move(child)));
 
-  if (!SendStartSubprotocol(parent)) {
+  if (!SendStartSubprotocol(std::move(parent))) {
     fail("send StartSubprotocol");
   }
 
   return IPC_OK();
 }
 
 void TestEndpointOpensChild::ActorDestroy(ActorDestroyReason why) {
   // Stops the thread and joins it
--- a/ipc/ipdl/test/cxx/TestShmem.cpp
+++ b/ipc/ipdl/test/cxx/TestShmem.cpp
@@ -26,17 +26,18 @@ void TestShmemParent::Main() {
 
   char* ptr = mem.get<char>();
   memcpy(ptr, "Hello!", sizeof("Hello!"));
 
   char* unsafeptr = unsafe.get<char>();
   memcpy(unsafeptr, "Hello!", sizeof("Hello!"));
 
   Shmem unsafecopy = unsafe;
-  if (!SendGive(mem, unsafe, size)) fail("can't send Give()");
+  if (!SendGive(std::move(mem), std::move(unsafe), size))
+    fail("can't send Give()");
 
   // uncomment the following line for a (nondeterministic) surprise!
   // char c1 = *ptr;  (void)c1;
 
   // uncomment the following line for a deterministic surprise!
   // char c2 = *mem.get<char>(); (void)c2;
 
   // unsafe shmem gets rid of those checks
@@ -86,17 +87,18 @@ mozilla::ipc::IPCResult TestShmemChild::
     fail("expected message was not written");
 
   char* unsafeptr = unsafe.get<char>();
 
   memcpy(mem.get<char>(), "And yourself!", sizeof("And yourself!"));
   memcpy(unsafeptr, "And yourself!", sizeof("And yourself!"));
 
   Shmem unsafecopy = unsafe;
-  if (!SendTake(mem, unsafe, expectedSize)) fail("can't send Take()");
+  if (!SendTake(std::move(mem), std::move(unsafe), expectedSize))
+    fail("can't send Take()");
 
   // these checks also shouldn't fail in the child
   char uc1 = *unsafeptr;
   (void)uc1;
   char uc2 = *unsafecopy.get<char>();
   (void)uc2;
 
   return IPC_OK();
--- a/ipc/ipdl/test/cxx/TestUniquePtrIPC.cpp
+++ b/ipc/ipdl/test/cxx/TestUniquePtrIPC.cpp
@@ -28,17 +28,17 @@ void TestUniquePtrIPCParent::Main() {
 
   if (a4) {
     fail("somehow turned null ptr into non-null by sending it");
   }
 
   // Pass UniquePtr by reference
   UniquePtr<DummyStruct> b = MakeUnique<DummyStruct>(1);
 
-  if (!SendTestSendReference(b)) {
+  if (!SendTestSendReference(std::move(b))) {
     fail("failed sending UniquePtr by reference");
   }
   if (b) {
     fail("did not move UniquePtr sent by reference");
   }
 }
 
 // ---------------------------------------------------------------------------
--- a/widget/nsDragServiceProxy.cpp
+++ b/widget/nsDragServiceProxy.cpp
@@ -63,17 +63,17 @@ nsresult nsDragServiceProxy::InvokeDragS
 
         // Save the surface data to shared memory.
         if (!surfaceData.IsReadable() || !surfaceData.get<char>()) {
           NS_WARNING("Failed to create shared memory for drag session.");
           return NS_ERROR_FAILURE;
         }
 
         mozilla::Unused << child->SendInvokeDragSession(
-            dataTransfers, aActionType, surfaceData, stride,
+            dataTransfers, aActionType, std::move(surfaceData), stride,
             dataSurface->GetFormat(), dragRect, IPC::Principal(principal));
         StartDragSession();
         return NS_OK;
       }
     }
   }
 
   mozilla::Unused << child->SendInvokeDragSession(