Bug 1044550: Move GMP shared mem cache from a global to per-GMPParent r=cpearce a=sylvestre
authorRandell Jesup <rjesup@jesup.org>
Sun, 27 Jul 2014 05:26:14 -0400
changeset 216194 e5466a63b5b9c1a68ad31fe47cef55d8a6765dc5
parent 216193 103b6ab5b984ea64ba5e9328d2f1adebdfc13480
child 216195 9dde3907962cba3d233f352f726402c502299220
push id3857
push userraliiev@mozilla.com
push dateTue, 02 Sep 2014 16:39:23 +0000
treeherdermozilla-beta@5638b907b505 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce, sylvestre
bugs1044550
milestone33.0a2
Bug 1044550: Move GMP shared mem cache from a global to per-GMPParent r=cpearce a=sylvestre
content/media/gmp/GMPChild.cpp
content/media/gmp/GMPChild.h
content/media/gmp/GMPParent.cpp
content/media/gmp/GMPParent.h
content/media/gmp/GMPSharedMemManager.cpp
content/media/gmp/GMPSharedMemManager.h
content/media/gmp/GMPVideoDecoderChild.cpp
content/media/gmp/GMPVideoDecoderChild.h
content/media/gmp/GMPVideoDecoderParent.cpp
content/media/gmp/GMPVideoDecoderParent.h
content/media/gmp/GMPVideoEncodedFrameImpl.cpp
content/media/gmp/GMPVideoEncoderChild.cpp
content/media/gmp/GMPVideoEncoderChild.h
content/media/gmp/GMPVideoEncoderParent.cpp
content/media/gmp/GMPVideoEncoderParent.h
content/media/gmp/GMPVideoPlaneImpl.cpp
--- a/content/media/gmp/GMPChild.cpp
+++ b/content/media/gmp/GMPChild.cpp
@@ -36,16 +36,22 @@ GMPChild::GMPChild()
   , mGMPMessageLoop(MessageLoop::current())
 {
 }
 
 GMPChild::~GMPChild()
 {
 }
 
+void
+GMPChild::CheckThread()
+{
+  MOZ_ASSERT(mGMPMessageLoop == MessageLoop::current());
+}
+
 bool
 GMPChild::Init(const std::string& aPluginPath,
                base::ProcessHandle aParentProcessHandle,
                MessageLoop* aIOLoop,
                IPC::Channel* aChannel)
 {
   if (!Open(aChannel, aParentProcessHandle, aIOLoop)) {
     return false;
--- a/content/media/gmp/GMPChild.h
+++ b/content/media/gmp/GMPChild.h
@@ -2,35 +2,40 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef GMPChild_h_
 #define GMPChild_h_
 
 #include "mozilla/gmp/PGMPChild.h"
+#include "GMPSharedMemManager.h"
 #include "gmp-entrypoints.h"
 #include "prlink.h"
 
 namespace mozilla {
 namespace gmp {
 
-class GMPChild : public PGMPChild
+class GMPChild : public PGMPChild,
+                 public GMPSharedMem
 {
 public:
   GMPChild();
   virtual ~GMPChild();
 
   bool Init(const std::string& aPluginPath,
             base::ProcessHandle aParentProcessHandle,
             MessageLoop* aIOLoop,
             IPC::Channel* aChannel);
   bool LoadPluginLibrary(const std::string& aPluginPath);
   MessageLoop* GMPMessageLoop();
 
+  // GMPSharedMem
+  virtual void CheckThread() MOZ_OVERRIDE;
+
 private:
   virtual PCrashReporterChild* AllocPCrashReporterChild(const NativeThreadId& aThread) MOZ_OVERRIDE;
   virtual bool DeallocPCrashReporterChild(PCrashReporterChild*) MOZ_OVERRIDE;
   virtual PGMPVideoDecoderChild* AllocPGMPVideoDecoderChild() MOZ_OVERRIDE;
   virtual bool DeallocPGMPVideoDecoderChild(PGMPVideoDecoderChild* aActor) MOZ_OVERRIDE;
   virtual PGMPVideoEncoderChild* AllocPGMPVideoEncoderChild() MOZ_OVERRIDE;
   virtual bool DeallocPGMPVideoEncoderChild(PGMPVideoEncoderChild* aActor) MOZ_OVERRIDE;
   virtual bool RecvPGMPVideoDecoderConstructor(PGMPVideoDecoderChild* aActor) MOZ_OVERRIDE;
--- a/content/media/gmp/GMPParent.cpp
+++ b/content/media/gmp/GMPParent.cpp
@@ -45,16 +45,22 @@ GMPParent::~GMPParent()
 nsresult
 GMPParent::CloneFrom(const GMPParent* aOther)
 {
   MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
   MOZ_ASSERT(aOther->mDirectory && aOther->mService, "null plugin directory");
   return Init(aOther->mService, aOther->mDirectory);
 }
 
+void
+GMPParent::CheckThread()
+{
+  MOZ_ASSERT(mGMPThread == NS_GetCurrentThread());
+}
+
 nsresult
 GMPParent::Init(GeckoMediaPluginService *aService, nsIFile* aPluginDir)
 {
   MOZ_ASSERT(aPluginDir);
   MOZ_ASSERT(aService);
   MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
 
   mService = aService;
--- a/content/media/gmp/GMPParent.h
+++ b/content/media/gmp/GMPParent.h
@@ -45,17 +45,18 @@ public:
 
 enum GMPState {
   GMPStateNotLoaded,
   GMPStateLoaded,
   GMPStateUnloading,
   GMPStateClosing
 };
 
-class GMPParent MOZ_FINAL : public PGMPParent
+class GMPParent MOZ_FINAL : public PGMPParent,
+                            public GMPSharedMem
 {
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(GMPParent)
 
   GMPParent();
 
   nsresult Init(GeckoMediaPluginService *aService, nsIFile* aPluginDir);
   nsresult CloneFrom(const GMPParent* aOther);
@@ -105,16 +106,19 @@ public:
   // that origin, or if it's not been set to work with any origin and has
   // not yet been loaded (i.e. it's not shared across origins).
   bool CanBeUsedFrom(const nsAString& aOrigin) const;
 
   already_AddRefed<nsIFile> GetDirectory() {
     return nsCOMPtr<nsIFile>(mDirectory).forget();
   }
 
+  // GMPSharedMem
+  virtual void CheckThread() MOZ_OVERRIDE;
+
 private:
   ~GMPParent();
   nsRefPtr<GeckoMediaPluginService> mService;
   bool EnsureProcessLoaded();
   nsresult ReadGMPMetaData();
 #ifdef MOZ_CRASHREPORTER
   void WriteExtraDataForMinidump(CrashReporter::AnnotationTable& notes);
   void GetCrashID(nsString& aResult);
--- a/content/media/gmp/GMPSharedMemManager.cpp
+++ b/content/media/gmp/GMPSharedMemManager.cpp
@@ -14,103 +14,72 @@ namespace gmp {
 
 // Really one set of pools on each side of the plugin API.
 
 // YUV buffers go from Encoder parent to child; pool there, and then return
 // with Decoded() frames to the Decoder parent and goes into the parent pool.
 // Compressed (encoded) data goes from the Decoder parent to the child;
 // pool there, and then return with Encoded() frames and goes into the parent
 // pool.
-static StaticAutoPtr<nsTArray<ipc::Shmem>> sGmpFreelist[GMPSharedMemManager::kGMPNumTypes];
-static uint32_t sGMPShmemManagerCount = 0;
-static uint32_t sGmpAllocated[GMPSharedMemManager::kGMPNumTypes]; // 0's
-
-GMPSharedMemManager::GMPSharedMemManager()
-{
-  if (!sGMPShmemManagerCount) {
-    for (uint32_t i = 0; i < GMPSharedMemManager::kGMPNumTypes; i++) {
-      sGmpFreelist[i] = new nsTArray<ipc::Shmem>();
-      sGmpAllocated[i] = 0;
-    }
-  }
-  sGMPShmemManagerCount++;
-}
-
-GMPSharedMemManager::~GMPSharedMemManager()
-{
-  MOZ_ASSERT(sGMPShmemManagerCount > 0);
-  sGMPShmemManagerCount--;
-  if (!sGMPShmemManagerCount) {
-    for (uint32_t i = 0; i < GMPSharedMemManager::kGMPNumTypes; i++) {
-      sGmpFreelist[i] = nullptr;
-    }
-  }
-}
-
-static nsTArray<ipc::Shmem>&
-GetGmpFreelist(GMPSharedMemManager::GMPMemoryClasses aTypes)
-{
-  return *(sGmpFreelist[aTypes]);
-}
 
 bool
-GMPSharedMemManager::MgrAllocShmem(GMPMemoryClasses aClass, size_t aSize,
+GMPSharedMemManager::MgrAllocShmem(GMPSharedMem::GMPMemoryClasses aClass, size_t aSize,
                                    ipc::Shmem::SharedMemory::SharedMemoryType aType,
                                    ipc::Shmem* aMem)
 {
-  CheckThread();
+  mData->CheckThread();
 
   // first look to see if we have a free buffer large enough
   for (uint32_t i = 0; i < GetGmpFreelist(aClass).Length(); i++) {
     MOZ_ASSERT(GetGmpFreelist(aClass)[i].IsWritable());
     if (aSize <= GetGmpFreelist(aClass)[i].Size<uint8_t>()) {
       *aMem = GetGmpFreelist(aClass)[i];
       GetGmpFreelist(aClass).RemoveElementAt(i);
       return true;
     }
   }
 
   // Didn't find a buffer free with enough space; allocate one
   size_t pagesize = ipc::SharedMemory::SystemPageSize();
   aSize = (aSize + (pagesize-1)) & ~(pagesize-1); // round up to page size
   bool retval = Alloc(aSize, aType, aMem);
   if (retval) {
-    sGmpAllocated[aClass]++;
+    mData->mGmpAllocated[aClass]++;
   }
   return retval;
 }
 
 bool
-GMPSharedMemManager::MgrDeallocShmem(GMPMemoryClasses aClass, ipc::Shmem& aMem)
+GMPSharedMemManager::MgrDeallocShmem(GMPSharedMem::GMPMemoryClasses aClass, ipc::Shmem& aMem)
 {
-  CheckThread();
+  mData->CheckThread();
 
   size_t size = aMem.Size<uint8_t>();
   size_t total = 0;
   // 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]);
     GetGmpFreelist(aClass).RemoveElementAt(0);
     // The allocation numbers will be fubar on the Child!
-    sGmpAllocated[aClass]--;
+    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>()) {
       GetGmpFreelist(aClass).InsertElementAt(i, aMem);
       return true;
     }
   }
   GetGmpFreelist(aClass).AppendElement(aMem);
 
   return true;
 }
 
 uint32_t
-GMPSharedMemManager::NumInUse(GMPMemoryClasses aClass)
+GMPSharedMemManager::NumInUse(GMPSharedMem::GMPMemoryClasses aClass)
 {
-  return sGmpAllocated[aClass] - GetGmpFreelist(aClass).Length();
+  return mData->mGmpAllocated[aClass] - GetGmpFreelist(aClass).Length();
 }
 
 }
 }
--- a/content/media/gmp/GMPSharedMemManager.h
+++ b/content/media/gmp/GMPSharedMemManager.h
@@ -7,48 +7,76 @@
 #define GMPSharedMemManager_h_
 
 #include "mozilla/ipc/Shmem.h"
 #include "nsTArray.h"
 
 namespace mozilla {
 namespace gmp {
 
-class GMPSharedMemManager
+class GMPSharedMemManager;
+
+class GMPSharedMem
 {
 public:
   typedef enum {
     kGMPFrameData = 0,
     kGMPEncodedData,
     kGMPNumTypes
   } GMPMemoryClasses;
 
   // This is a heuristic - max of 10 free in the Child pool, plus those
   // in-use for the encoder and decoder at the given moment and not yet
   // returned to the parent pool (which is not included).  If more than
   // this are needed, we presume the client has either crashed or hung
   // (perhaps temporarily).
   static const uint32_t kGMPBufLimit = 20;
 
-  GMPSharedMemManager();
-  virtual ~GMPSharedMemManager();
-
-  virtual bool MgrAllocShmem(GMPMemoryClasses aClass, size_t aSize,
-                             ipc::Shmem::SharedMemory::SharedMemoryType aType,
-                             ipc::Shmem* aMem);
-  virtual bool MgrDeallocShmem(GMPMemoryClasses aClass, ipc::Shmem& aMem);
-
-  // So we can know if data is "piling up" for the plugin - I.e. it's hung or crashed
-  virtual uint32_t NumInUse(GMPMemoryClasses aClass);
+  GMPSharedMem()
+  {
+    for (size_t i = 0; i < sizeof(mGmpAllocated)/sizeof(mGmpAllocated[0]); i++) {
+      mGmpAllocated[i] = 0;
+    }
+  }
+  virtual ~GMPSharedMem() {}
 
   // Parent and child impls will differ here
   virtual void CheckThread() = 0;
 
+protected:
+  friend class GMPSharedMemManager;
+
+  nsTArray<ipc::Shmem> mGmpFreelist[GMPSharedMem::kGMPNumTypes];
+  uint32_t mGmpAllocated[GMPSharedMem::kGMPNumTypes];
+};
+
+class GMPSharedMemManager
+{
+public:
+  GMPSharedMemManager(GMPSharedMem *aData) : mData(aData) {}
+  virtual ~GMPSharedMemManager() {}
+
+  virtual bool MgrAllocShmem(GMPSharedMem::GMPMemoryClasses aClass, size_t aSize,
+                             ipc::Shmem::SharedMemory::SharedMemoryType aType,
+                             ipc::Shmem* aMem);
+  virtual bool MgrDeallocShmem(GMPSharedMem::GMPMemoryClasses aClass, ipc::Shmem& aMem);
+
+  // So we can know if data is "piling up" for the plugin - I.e. it's hung or 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;
+
+private:
+  nsTArray<ipc::Shmem>& GetGmpFreelist(GMPSharedMem::GMPMemoryClasses aTypes)
+  {
+    return mData->mGmpFreelist[aTypes];
+  }
+
+  GMPSharedMem *mData;
 };
 
 } // namespace gmp
 } // namespace mozilla
 
 #endif // GMPSharedMemManager_h_
--- a/content/media/gmp/GMPVideoDecoderChild.cpp
+++ b/content/media/gmp/GMPVideoDecoderChild.cpp
@@ -9,17 +9,18 @@
 #include <stdio.h>
 #include "mozilla/unused.h"
 #include "GMPVideoEncodedFrameImpl.h"
 
 namespace mozilla {
 namespace gmp {
 
 GMPVideoDecoderChild::GMPVideoDecoderChild(GMPChild* aPlugin)
-: mPlugin(aPlugin),
+: GMPSharedMemManager(aPlugin),
+  mPlugin(aPlugin),
   mVideoDecoder(nullptr),
   mVideoHost(MOZ_THIS_IN_INITIALIZER_LIST())
 {
   MOZ_ASSERT(mPlugin);
 }
 
 GMPVideoDecoderChild::~GMPVideoDecoderChild()
 {
@@ -91,22 +92,16 @@ GMPVideoDecoderChild::DrainComplete()
 void
 GMPVideoDecoderChild::ResetComplete()
 {
   MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
 
   SendResetComplete();
 }
 
-void
-GMPVideoDecoderChild::CheckThread()
-{
-  MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
-}
-
 bool
 GMPVideoDecoderChild::RecvInitDecode(const GMPVideoCodec& aCodecSettings,
                                      const nsTArray<uint8_t>& aCodecSpecific,
                                      const int32_t& aCoreCount)
 {
   if (!mVideoDecoder) {
     return false;
   }
@@ -141,17 +136,17 @@ GMPVideoDecoderChild::RecvDecode(const G
 
   return true;
 }
 
 bool
 GMPVideoDecoderChild::RecvChildShmemForPool(Shmem& aFrameBuffer)
 {
   if (aFrameBuffer.IsWritable()) {
-    mVideoHost.SharedMemMgr()->MgrDeallocShmem(GMPSharedMemManager::kGMPFrameData,
+    mVideoHost.SharedMemMgr()->MgrDeallocShmem(GMPSharedMem::kGMPFrameData,
                                                aFrameBuffer);
   }
   return true;
 }
 
 bool
 GMPVideoDecoderChild::RecvReset()
 {
--- a/content/media/gmp/GMPVideoDecoderChild.h
+++ b/content/media/gmp/GMPVideoDecoderChild.h
@@ -33,30 +33,29 @@ public:
   virtual void Decoded(GMPVideoi420Frame* decodedFrame) MOZ_OVERRIDE;
   virtual void ReceivedDecodedReferenceFrame(const uint64_t pictureId) MOZ_OVERRIDE;
   virtual void ReceivedDecodedFrame(const uint64_t pictureId) MOZ_OVERRIDE;
   virtual void InputDataExhausted() MOZ_OVERRIDE;
   virtual void DrainComplete() MOZ_OVERRIDE;
   virtual void ResetComplete() MOZ_OVERRIDE;
 
   // GMPSharedMemManager
-  virtual void CheckThread();
-  virtual bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType, Shmem* aMem)
+  virtual bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType, Shmem* aMem) MOZ_OVERRIDE
   {
 #ifndef SHMEM_ALLOC_IN_CHILD
     return CallNeedShmem(aSize, aMem);
 #else
 #ifdef GMP_SAFE_SHMEM
     return AllocShmem(aSize, aType, aMem);
 #else
     return AllocUnsafeShmem(aSize, aType, aMem);
 #endif
 #endif
   }
-  virtual void Dealloc(Shmem& aMem)
+  virtual void Dealloc(Shmem& aMem) MOZ_OVERRIDE
   {
 #ifndef SHMEM_ALLOC_IN_CHILD
     SendParentShmemForPool(aMem);
 #else
     DeallocShmem(aMem);
 #endif
   }
 
--- a/content/media/gmp/GMPVideoDecoderParent.cpp
+++ b/content/media/gmp/GMPVideoDecoderParent.cpp
@@ -30,17 +30,18 @@ namespace gmp {
 //    on Shutdown -> Dead
 // Open: mIsOpen == true
 //    on Close -> Dead
 //    on ActorDestroy -> Dead
 //    on Shutdown -> Dead
 // Dead: mIsOpen == false
 
 GMPVideoDecoderParent::GMPVideoDecoderParent(GMPParent* aPlugin)
-  : mIsOpen(false)
+  : GMPSharedMemManager(aPlugin)
+  , mIsOpen(false)
   , mPlugin(aPlugin)
   , mCallback(nullptr)
   , mVideoHost(MOZ_THIS_IN_INITIALIZER_LIST())
 {
   MOZ_ASSERT(mPlugin);
 }
 
 GMPVideoDecoderParent::~GMPVideoDecoderParent()
@@ -111,18 +112,18 @@ GMPVideoDecoderParent::Decode(GMPVideoEn
 
   MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
 
   auto inputFrameImpl = static_cast<GMPVideoEncodedFrameImpl*>(aInputFrame);
 
   // Very rough kill-switch if the plugin stops processing.  If it's merely
   // hung and continues, we'll come back to life eventually.
   // 3* is because we're using 3 buffers per frame for i420 data for now.
-  if (NumInUse(kGMPFrameData) > 3*GMPSharedMemManager::kGMPBufLimit ||
-      NumInUse(kGMPEncodedData) > GMPSharedMemManager::kGMPBufLimit) {
+  if ((NumInUse(GMPSharedMem::kGMPFrameData) > 3*GMPSharedMem::kGMPBufLimit) ||
+      (NumInUse(GMPSharedMem::kGMPEncodedData) > GMPSharedMem::kGMPBufLimit)) {
     return NS_ERROR_FAILURE;
   }
 
   GMPVideoEncodedFrameData frameData;
   inputFrameImpl->RelinquishFrameData(frameData);
 
   if (!SendDecode(frameData,
                   aMissingFrames,
@@ -206,22 +207,16 @@ GMPVideoDecoderParent::ActorDestroy(Acto
   if (mPlugin) {
     // Ignore any return code. It is OK for this to fail without killing the process.
     mPlugin->VideoDecoderDestroyed(this);
     mPlugin = nullptr;
   }
   mVideoHost.ActorDestroyed();
 }
 
-void
-GMPVideoDecoderParent::CheckThread()
-{
-  MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
-}
-
 bool
 GMPVideoDecoderParent::RecvDecoded(const GMPVideoi420FrameData& aDecodedFrame)
 {
   if (!mCallback) {
     return false;
   }
 
   auto f = new GMPVideoi420FrameImpl(aDecodedFrame, &mVideoHost);
@@ -296,29 +291,29 @@ GMPVideoDecoderParent::RecvResetComplete
 
   return true;
 }
 
 bool
 GMPVideoDecoderParent::RecvParentShmemForPool(Shmem& aEncodedBuffer)
 {
   if (aEncodedBuffer.IsWritable()) {
-    mVideoHost.SharedMemMgr()->MgrDeallocShmem(GMPSharedMemManager::kGMPEncodedData,
+    mVideoHost.SharedMemMgr()->MgrDeallocShmem(GMPSharedMem::kGMPEncodedData,
                                                aEncodedBuffer);
   }
   return true;
 }
 
 bool
 GMPVideoDecoderParent::AnswerNeedShmem(const uint32_t& aFrameBufferSize,
                                        Shmem* aMem)
 {
   ipc::Shmem mem;
 
-  if (!mVideoHost.SharedMemMgr()->MgrAllocShmem(GMPSharedMemManager::kGMPFrameData,
+  if (!mVideoHost.SharedMemMgr()->MgrAllocShmem(GMPSharedMem::kGMPFrameData,
                                                 aFrameBufferSize,
                                                 ipc::SharedMemory::TYPE_BASIC, &mem))
   {
     return false;
   }
   *aMem = mem;
   mem = ipc::Shmem();
   return true;
--- a/content/media/gmp/GMPVideoDecoderParent.h
+++ b/content/media/gmp/GMPVideoDecoderParent.h
@@ -15,18 +15,18 @@
 #include "GMPVideoDecoderProxy.h"
 
 namespace mozilla {
 namespace gmp {
 
 class GMPParent;
 
 class GMPVideoDecoderParent MOZ_FINAL : public PGMPVideoDecoderParent
+                                      , public GMPVideoDecoderProxy
                                       , public GMPSharedMemManager
-                                      , public GMPVideoDecoderProxy
 {
 public:
   NS_INLINE_DECL_REFCOUNTING(GMPVideoDecoderParent)
 
   GMPVideoDecoderParent(GMPParent *aPlugin);
 
   GMPVideoHostImpl& Host();
   nsresult Shutdown();
@@ -41,26 +41,25 @@ public:
                           bool aMissingFrames,
                           const nsTArray<uint8_t>& aCodecSpecificInfo,
                           int64_t aRenderTimeMs = -1) MOZ_OVERRIDE;
   virtual nsresult Reset() MOZ_OVERRIDE;
   virtual nsresult Drain() MOZ_OVERRIDE;
   virtual const uint64_t ParentID() MOZ_OVERRIDE { return reinterpret_cast<uint64_t>(mPlugin.get()); }
 
   // GMPSharedMemManager
-  virtual void CheckThread();
-  virtual bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType, Shmem* aMem)
+  virtual bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType, Shmem* aMem) MOZ_OVERRIDE
   {
 #ifdef GMP_SAFE_SHMEM
     return AllocShmem(aSize, aType, aMem);
 #else
     return AllocUnsafeShmem(aSize, aType, aMem);
 #endif
   }
-  virtual void Dealloc(Shmem& aMem)
+  virtual void Dealloc(Shmem& aMem) MOZ_OVERRIDE
   {
     DeallocShmem(aMem);
   }
 
 private:
   ~GMPVideoDecoderParent();
 
   // PGMPVideoDecoderParent
--- a/content/media/gmp/GMPVideoEncodedFrameImpl.cpp
+++ b/content/media/gmp/GMPVideoEncodedFrameImpl.cpp
@@ -103,29 +103,29 @@ GMPVideoEncodedFrameImpl::RelinquishFram
 
   return true;
 }
 
 void
 GMPVideoEncodedFrameImpl::DestroyBuffer()
 {
   if (mHost && mBuffer.IsWritable()) {
-    mHost->SharedMemMgr()->MgrDeallocShmem(GMPSharedMemManager::kGMPEncodedData, mBuffer);
+    mHost->SharedMemMgr()->MgrDeallocShmem(GMPSharedMem::kGMPEncodedData, mBuffer);
   }
   mBuffer = ipc::Shmem();
 }
 
 GMPErr
 GMPVideoEncodedFrameImpl::CreateEmptyFrame(uint32_t aSize)
 {
   if (aSize == 0) {
     DestroyBuffer();
   } else if (aSize > AllocatedSize()) {
     DestroyBuffer();
-    if (!mHost->SharedMemMgr()->MgrAllocShmem(GMPSharedMemManager::kGMPEncodedData, aSize,
+    if (!mHost->SharedMemMgr()->MgrAllocShmem(GMPSharedMem::kGMPEncodedData, aSize,
                                               ipc::SharedMemory::TYPE_BASIC, &mBuffer) ||
         !Buffer()) {
       return GMPAllocErr;
     }
   }
   mSize = aSize;
 
   return GMPNoErr;
@@ -223,17 +223,17 @@ GMPVideoEncodedFrameImpl::SetAllocatedSi
     return;
   }
 
   if (!mHost) {
     return;
   }
 
   ipc::Shmem new_mem;
-  if (!mHost->SharedMemMgr()->MgrAllocShmem(GMPSharedMemManager::kGMPEncodedData, aNewSize,
+  if (!mHost->SharedMemMgr()->MgrAllocShmem(GMPSharedMem::kGMPEncodedData, aNewSize,
                                             ipc::SharedMemory::TYPE_BASIC, &new_mem) ||
       !new_mem.get<uint8_t>()) {
     return;
   }
 
   if (mBuffer.IsReadable()) {
     memcpy(new_mem.get<uint8_t>(), Buffer(), mSize);
   }
--- a/content/media/gmp/GMPVideoEncoderChild.cpp
+++ b/content/media/gmp/GMPVideoEncoderChild.cpp
@@ -9,17 +9,18 @@
 #include "mozilla/unused.h"
 #include "GMPVideoEncodedFrameImpl.h"
 #include "GMPVideoi420FrameImpl.h"
 
 namespace mozilla {
 namespace gmp {
 
 GMPVideoEncoderChild::GMPVideoEncoderChild(GMPChild* aPlugin)
-: mPlugin(aPlugin),
+: GMPSharedMemManager(aPlugin),
+  mPlugin(aPlugin),
   mVideoEncoder(nullptr),
   mVideoHost(MOZ_THIS_IN_INITIALIZER_LIST())
 {
   MOZ_ASSERT(mPlugin);
 }
 
 GMPVideoEncoderChild::~GMPVideoEncoderChild()
 {
@@ -52,22 +53,16 @@ GMPVideoEncoderChild::Encoded(GMPVideoEn
 
   nsTArray<uint8_t> codecSpecific;
   codecSpecific.AppendElements(aCodecSpecificInfo, aCodecSpecificInfoLength);
   SendEncoded(frameData, codecSpecific);
 
   aEncodedFrame->Destroy();
 }
 
-void
-GMPVideoEncoderChild::CheckThread()
-{
-  MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
-}
-
 bool
 GMPVideoEncoderChild::RecvInitEncode(const GMPVideoCodec& aCodecSettings,
                                      const nsTArray<uint8_t>& aCodecSpecific,
                                      const int32_t& aNumberOfCores,
                                      const uint32_t& aMaxPayloadSize)
 {
   if (!mVideoEncoder) {
     return false;
@@ -104,17 +99,17 @@ GMPVideoEncoderChild::RecvEncode(const G
 
   return true;
 }
 
 bool
 GMPVideoEncoderChild::RecvChildShmemForPool(Shmem& aEncodedBuffer)
 {
   if (aEncodedBuffer.IsWritable()) {
-    mVideoHost.SharedMemMgr()->MgrDeallocShmem(GMPSharedMemManager::kGMPEncodedData,
+    mVideoHost.SharedMemMgr()->MgrDeallocShmem(GMPSharedMem::kGMPEncodedData,
                                                aEncodedBuffer);
   }
   return true;
 }
 
 bool
 GMPVideoEncoderChild::RecvSetChannelParameters(const uint32_t& aPacketLoss,
                                                const uint32_t& aRTT)
--- a/content/media/gmp/GMPVideoEncoderChild.h
+++ b/content/media/gmp/GMPVideoEncoderChild.h
@@ -29,30 +29,29 @@ public:
   GMPVideoHostImpl& Host();
 
   // GMPVideoEncoderCallback
   virtual void Encoded(GMPVideoEncodedFrame* aEncodedFrame,
                        const uint8_t* aCodecSpecificInfo,
                        uint32_t aCodecSpecificInfoLength) MOZ_OVERRIDE;
 
   // GMPSharedMemManager
-  virtual void CheckThread();
-  virtual bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType, Shmem* aMem)
+  virtual bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType, Shmem* aMem) MOZ_OVERRIDE
   {
 #ifndef SHMEM_ALLOC_IN_CHILD
     return CallNeedShmem(aSize, aMem);
 #else
 #ifdef GMP_SAFE_SHMEM
     return AllocShmem(aSize, aType, aMem);
 #else
     return AllocUnsafeShmem(aSize, aType, aMem);
 #endif
 #endif
   }
-  virtual void Dealloc(Shmem& aMem)
+  virtual void Dealloc(Shmem& aMem) MOZ_OVERRIDE
   {
 #ifndef SHMEM_ALLOC_IN_CHILD
     SendParentShmemForPool(aMem);
 #else
     DeallocShmem(aMem);
 #endif
   }
 
--- a/content/media/gmp/GMPVideoEncoderParent.cpp
+++ b/content/media/gmp/GMPVideoEncoderParent.cpp
@@ -30,17 +30,18 @@ namespace gmp {
 //    on Shutdown -> Dead
 // Open: mIsOpen == true
 //    on Close -> Dead
 //    on ActorDestroy -> Dead
 //    on Shutdown -> Dead
 // Dead: mIsOpen == false
 
 GMPVideoEncoderParent::GMPVideoEncoderParent(GMPParent *aPlugin)
-: mIsOpen(false),
+: GMPSharedMemManager(aPlugin),
+  mIsOpen(false),
   mPlugin(aPlugin),
   mCallback(nullptr),
   mVideoHost(MOZ_THIS_IN_INITIALIZER_LIST())
 {
   MOZ_ASSERT(mPlugin);
 }
 
 GMPVideoEncoderParent::~GMPVideoEncoderParent()
@@ -111,18 +112,18 @@ GMPVideoEncoderParent::Encode(GMPVideoi4
 
   MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
 
   auto inputFrameImpl = static_cast<GMPVideoi420FrameImpl*>(aInputFrame);
 
   // Very rough kill-switch if the plugin stops processing.  If it's merely
   // hung and continues, we'll come back to life eventually.
   // 3* is because we're using 3 buffers per frame for i420 data for now.
-  if (NumInUse(kGMPFrameData) > 3*GMPSharedMemManager::kGMPBufLimit ||
-      NumInUse(kGMPEncodedData) > GMPSharedMemManager::kGMPBufLimit) {
+  if ((NumInUse(GMPSharedMem::kGMPFrameData) > 3*GMPSharedMem::kGMPBufLimit) ||
+      (NumInUse(GMPSharedMem::kGMPEncodedData) > GMPSharedMem::kGMPBufLimit)) {
     return GMPGenericErr;
   }
 
   GMPVideoi420FrameData frameData;
   inputFrameImpl->InitFrameData(frameData);
 
   if (!SendEncode(frameData,
                   aCodecSpecificInfo,
@@ -220,22 +221,16 @@ GMPVideoEncoderParent::ActorDestroy(Acto
   if (mPlugin) {
     // Ignore any return code. It is OK for this to fail without killing the process.
     mPlugin->VideoEncoderDestroyed(this);
     mPlugin = nullptr;
   }
   mVideoHost.ActorDestroyed();
 }
 
-void
-GMPVideoEncoderParent::CheckThread()
-{
-  MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
-}
-
 bool
 GMPVideoEncoderParent::RecvEncoded(const GMPVideoEncodedFrameData& aEncodedFrame,
                                    const nsTArray<uint8_t>& aCodecSpecificInfo)
 {
   if (!mCallback) {
     return false;
   }
 
@@ -248,29 +243,29 @@ GMPVideoEncoderParent::RecvEncoded(const
   //SendEncodedReturn(aEncodedFrame, aCodecSpecificInfo);
   return true;
 }
 
 bool
 GMPVideoEncoderParent::RecvParentShmemForPool(Shmem& aFrameBuffer)
 {
   if (aFrameBuffer.IsWritable()) {
-    mVideoHost.SharedMemMgr()->MgrDeallocShmem(GMPSharedMemManager::kGMPFrameData,
+    mVideoHost.SharedMemMgr()->MgrDeallocShmem(GMPSharedMem::kGMPFrameData,
                                                aFrameBuffer);
   }
   return true;
 }
 
 bool
 GMPVideoEncoderParent::AnswerNeedShmem(const uint32_t& aEncodedBufferSize,
                                        Shmem* aMem)
 {
   ipc::Shmem mem;
 
-  if (!mVideoHost.SharedMemMgr()->MgrAllocShmem(GMPSharedMemManager::kGMPEncodedData,
+  if (!mVideoHost.SharedMemMgr()->MgrAllocShmem(GMPSharedMem::kGMPEncodedData,
                                                 aEncodedBufferSize,
                                                 ipc::SharedMemory::TYPE_BASIC, &mem))
   {
     return false;
   }
   *aMem = mem;
   mem = ipc::Shmem();
   return true;
--- a/content/media/gmp/GMPVideoEncoderParent.h
+++ b/content/media/gmp/GMPVideoEncoderParent.h
@@ -42,26 +42,25 @@ public:
                         const nsTArray<uint8_t>& aCodecSpecificInfo,
                         const nsTArray<GMPVideoFrameType>& aFrameTypes) MOZ_OVERRIDE;
   virtual GMPErr SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT) MOZ_OVERRIDE;
   virtual GMPErr SetRates(uint32_t aNewBitRate, uint32_t aFrameRate) MOZ_OVERRIDE;
   virtual GMPErr SetPeriodicKeyFrames(bool aEnable) MOZ_OVERRIDE;
   virtual const uint64_t ParentID() MOZ_OVERRIDE { return reinterpret_cast<uint64_t>(mPlugin.get()); }
 
   // GMPSharedMemManager
-  virtual void CheckThread();
-  virtual bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType, Shmem* aMem)
+  virtual bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType, Shmem* aMem) MOZ_OVERRIDE
   {
 #ifdef GMP_SAFE_SHMEM
     return AllocShmem(aSize, aType, aMem);
 #else
     return AllocUnsafeShmem(aSize, aType, aMem);
 #endif
   }
-  virtual void Dealloc(Shmem& aMem)
+  virtual void Dealloc(Shmem& aMem) MOZ_OVERRIDE
   {
     DeallocShmem(aMem);
   }
 
 private:
   virtual ~GMPVideoEncoderParent();
 
   // PGMPVideoEncoderParent
--- a/content/media/gmp/GMPVideoPlaneImpl.cpp
+++ b/content/media/gmp/GMPVideoPlaneImpl.cpp
@@ -79,17 +79,17 @@ GMPPlaneImpl::MaybeResize(int32_t aNewSi
     return GMPNoErr;
   }
 
   if (!mHost) {
     return GMPGenericErr;
   }
 
   ipc::Shmem new_mem;
-  if (!mHost->SharedMemMgr()->MgrAllocShmem(GMPSharedMemManager::kGMPFrameData, aNewSize,
+  if (!mHost->SharedMemMgr()->MgrAllocShmem(GMPSharedMem::kGMPFrameData, aNewSize,
                                             ipc::SharedMemory::TYPE_BASIC, &new_mem) ||
       !new_mem.get<uint8_t>()) {
     return GMPAllocErr;
   }
 
   if (mBuffer.IsReadable()) {
     memcpy(new_mem.get<uint8_t>(), Buffer(), mSize);
   }
@@ -100,17 +100,17 @@ GMPPlaneImpl::MaybeResize(int32_t aNewSi
 
   return GMPNoErr;
 }
 
 void
 GMPPlaneImpl::DestroyBuffer()
 {
   if (mHost && mBuffer.IsWritable()) {
-    mHost->SharedMemMgr()->MgrDeallocShmem(GMPSharedMemManager::kGMPFrameData, mBuffer);
+    mHost->SharedMemMgr()->MgrDeallocShmem(GMPSharedMem::kGMPFrameData, mBuffer);
   }
   mBuffer = ipc::Shmem();
 }
 
 GMPErr
 GMPPlaneImpl::CreateEmptyPlane(int32_t aAllocatedSize, int32_t aStride, int32_t aPlaneSize)
 {
   if (aAllocatedSize < 1 || aStride < 1 || aPlaneSize < 1) {