Bug 1266595: Replace Chromium Task with Runnable. r=froydnj
authorKyle Huey <khuey@kylehuey.com>
Wed, 27 Apr 2016 17:06:05 -0700
changeset 334198 30dcf34cfb753d94c79f40bd1af15d3b75e981a5
parent 334197 5f3d4dd4380f0ac3dc7f9a7bfd66ea534b631475
child 334199 e78a24e7938b2f8ef1e134d13a9b93fa418b2061
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1266595
milestone49.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 1266595: Replace Chromium Task with Runnable. r=froydnj
dom/ipc/ContentBridgeChild.cpp
dom/ipc/ContentBridgeParent.cpp
dom/ipc/ContentChild.cpp
dom/ipc/ContentParent.cpp
dom/ipc/PreallocatedProcessManager.cpp
dom/ipc/ProcessHangMonitor.cpp
dom/media/MediaManager.cpp
dom/media/MediaManager.h
dom/media/gmp/GMPChild.cpp
dom/media/gmp/GMPContentChild.cpp
dom/media/gmp/GMPContentParent.cpp
dom/media/gmp/GMPDecryptorChild.cpp
dom/media/gmp/GMPPlatform.cpp
dom/media/gmp/GMPProcessParent.cpp
dom/media/gmp/GMPServiceChild.cpp
dom/media/gmp/GMPServiceParent.cpp
dom/media/gmp/GMPStorageChild.cpp
dom/media/gmp/GMPVideoDecoderChild.cpp
dom/media/gmp/GMPVideoEncoderChild.cpp
dom/media/omx/MediaOmxReader.cpp
dom/media/systemservices/CamerasParent.cpp
dom/media/systemservices/CamerasParent.h
dom/media/systemservices/CamerasUtils.h
dom/media/systemservices/MediaSystemResourceManager.cpp
dom/media/systemservices/MediaUtils.h
dom/media/webaudio/blink/ReverbConvolver.cpp
dom/plugins/ipc/BrowserStreamChild.cpp
dom/plugins/ipc/ChildAsyncCall.cpp
dom/plugins/ipc/ChildAsyncCall.h
dom/plugins/ipc/PluginInstanceChild.cpp
dom/plugins/ipc/PluginInstanceChild.h
dom/plugins/ipc/PluginInstanceParent.cpp
dom/plugins/ipc/PluginInstanceParent.h
dom/plugins/ipc/PluginModuleChild.cpp
dom/plugins/ipc/PluginModuleParent.cpp
dom/plugins/ipc/PluginModuleParent.h
dom/plugins/ipc/PluginProcessParent.cpp
dom/plugins/ipc/PluginProcessParent.h
dom/plugins/ipc/TaskFactory.h
gfx/layers/AtomicRefCountedWithFinalize.h
gfx/layers/apz/public/GeckoContentController.h
gfx/layers/apz/src/AsyncPanZoomAnimation.h
gfx/layers/apz/src/AsyncPanZoomController.cpp
gfx/layers/apz/src/AsyncPanZoomController.h
gfx/layers/apz/src/GestureEventListener.cpp
gfx/layers/apz/src/GestureEventListener.h
gfx/layers/apz/test/gtest/APZTestCommon.h
gfx/layers/apz/util/APZThreadUtils.cpp
gfx/layers/apz/util/APZThreadUtils.h
gfx/layers/apz/util/ActiveElementManager.cpp
gfx/layers/apz/util/ActiveElementManager.h
gfx/layers/apz/util/ChromeProcessController.cpp
gfx/layers/apz/util/ChromeProcessController.h
gfx/layers/client/CompositableClient.cpp
gfx/layers/client/TextureClient.cpp
gfx/layers/client/TextureClient.h
gfx/layers/client/TextureClientRecycleAllocator.cpp
gfx/layers/ipc/CompositorBridgeChild.cpp
gfx/layers/ipc/CompositorBridgeParent.cpp
gfx/layers/ipc/CompositorBridgeParent.h
gfx/layers/ipc/ImageBridgeChild.cpp
gfx/layers/ipc/ImageBridgeParent.cpp
gfx/layers/ipc/RemoteContentController.cpp
gfx/layers/ipc/RemoteContentController.h
gfx/layers/ipc/SharedBufferManagerChild.cpp
gfx/layers/ipc/SharedBufferManagerParent.cpp
gfx/thebes/SoftwareVsyncSource.cpp
gfx/thebes/SoftwareVsyncSource.h
gfx/thebes/gfxWindowsPlatform.cpp
gfx/vr/ipc/VRManagerChild.cpp
gfx/vr/ipc/VRManagerParent.cpp
ipc/chromium/moz.build
ipc/chromium/src/base/message_loop.cc
ipc/chromium/src/base/message_loop.h
ipc/chromium/src/base/object_watcher.cc
ipc/chromium/src/base/object_watcher.h
ipc/chromium/src/base/task.h
ipc/chromium/src/base/thread.cc
ipc/chromium/src/base/timer.cc
ipc/chromium/src/base/timer.h
ipc/chromium/src/base/tracked.cc
ipc/chromium/src/base/tracked.h
ipc/chromium/src/base/tracked_objects.cc
ipc/chromium/src/base/tracked_objects.h
ipc/chromium/src/base/waitable_event_watcher.h
ipc/chromium/src/base/waitable_event_watcher_posix.cc
ipc/chromium/src/base/win_util.cc
ipc/chromium/src/base/win_util.h
ipc/chromium/src/chrome/common/child_process_host.cc
ipc/chromium/src/chrome/common/child_thread.cc
ipc/chromium/src/chrome/common/ipc_channel_win.cc
ipc/chromium/src/chrome/common/process_watcher_posix_sigchld.cc
ipc/chromium/src/chrome/common/process_watcher_win.cc
ipc/glue/BackgroundImpl.cpp
ipc/glue/GeckoChildProcessHost.cpp
ipc/glue/MessageChannel.cpp
ipc/glue/MessageChannel.h
ipc/glue/MessageLink.cpp
toolkit/xre/nsEmbedFunctions.cpp
widget/android/AndroidBridge.cpp
widget/android/AndroidBridge.h
widget/android/AndroidContentController.cpp
widget/android/AndroidContentController.h
widget/android/nsAppShell.cpp
widget/nsBaseWidget.cpp
xpcom/base/nsDumpUtils.cpp
xpcom/base/nsDumpUtils.h
xpcom/base/nsMessageLoop.cpp
--- a/dom/ipc/ContentBridgeChild.cpp
+++ b/dom/ipc/ContentBridgeChild.cpp
@@ -22,24 +22,24 @@ NS_IMPL_ISUPPORTS(ContentBridgeChild,
                   nsIContentChild)
 
 ContentBridgeChild::ContentBridgeChild(Transport* aTransport)
   : mTransport(aTransport)
 {}
 
 ContentBridgeChild::~ContentBridgeChild()
 {
-  XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new DeleteTask<Transport>(mTransport));
+  RefPtr<DeleteTask<Transport>> task = new DeleteTask<Transport>(mTransport);
+  XRE_GetIOMessageLoop()->PostTask(task.forget());
 }
 
 void
 ContentBridgeChild::ActorDestroy(ActorDestroyReason aWhy)
 {
   MessageLoop::current()->PostTask(
-    FROM_HERE,
     NewRunnableMethod(this, &ContentBridgeChild::DeferredDestroy));
 }
 
 /*static*/ ContentBridgeChild*
 ContentBridgeChild::Create(Transport* aTransport, ProcessId aOtherPid)
 {
   RefPtr<ContentBridgeChild> bridge =
     new ContentBridgeChild(aTransport);
--- a/dom/ipc/ContentBridgeParent.cpp
+++ b/dom/ipc/ContentBridgeParent.cpp
@@ -21,28 +21,28 @@ NS_IMPL_ISUPPORTS(ContentBridgeParent,
                   nsIObserver)
 
 ContentBridgeParent::ContentBridgeParent(Transport* aTransport)
   : mTransport(aTransport)
 {}
 
 ContentBridgeParent::~ContentBridgeParent()
 {
-  XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new DeleteTask<Transport>(mTransport));
+  RefPtr<DeleteTask<Transport>> task = new DeleteTask<Transport>(mTransport);
+  XRE_GetIOMessageLoop()->PostTask(task.forget());
 }
 
 void
 ContentBridgeParent::ActorDestroy(ActorDestroyReason aWhy)
 {
   nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
   if (os) {
     os->RemoveObserver(this, "content-child-shutdown");
   }
   MessageLoop::current()->PostTask(
-    FROM_HERE,
     NewRunnableMethod(this, &ContentBridgeParent::DeferredDestroy));
 }
 
 /*static*/ ContentBridgeParent*
 ContentBridgeParent::Create(Transport* aTransport, ProcessId aOtherPid)
 {
   RefPtr<ContentBridgeParent> bridge =
     new ContentBridgeParent(aTransport);
@@ -164,17 +164,16 @@ ContentBridgeParent::DeallocPBrowserPare
 }
 
 void
 ContentBridgeParent::NotifyTabDestroyed()
 {
   int32_t numLiveTabs = ManagedPBrowserParent().Count();
   if (numLiveTabs == 1) {
     MessageLoop::current()->PostTask(
-      FROM_HERE,
       NewRunnableMethod(this, &ContentBridgeParent::Close));
   }
 }
 
 // This implementation is identical to ContentParent::GetCPOWManager but we can't
 // move it to nsIContentParent because it calls ManagedPJavaScriptParent() which
 // only exists in PContentParent and PContentBridgeParent.
 jsipc::CPOWManager*
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -1513,17 +1513,17 @@ ContentChild::RecvBidiKeyboardNotify(con
   // possible implementation of nsIBidiKeyboard is PuppetBidiKeyboard).
   PuppetBidiKeyboard* bidi = static_cast<PuppetBidiKeyboard*>(nsContentUtils::GetBidiKeyboard());
   if (bidi) {
     bidi->SetIsLangRTL(aIsLangRTL);
   }
   return true;
 }
 
-static CancelableTask* sFirstIdleTask;
+static CancelableRunnable* sFirstIdleTask;
 
 static void FirstIdle(void)
 {
   MOZ_ASSERT(sFirstIdleTask);
   sFirstIdleTask = nullptr;
   ContentChild::GetSingleton()->SendFirstIdle();
 }
 
@@ -1594,18 +1594,19 @@ ContentChild::RecvPBrowserConstructor(PB
     os->NotifyObservers(tc, "tab-child-created", nullptr);
   }
 
   static bool hasRunOnce = false;
   if (!hasRunOnce) {
       hasRunOnce = true;
 
     MOZ_ASSERT(!sFirstIdleTask);
-    sFirstIdleTask = NewRunnableFunction(FirstIdle);
-    MessageLoop::current()->PostIdleTask(FROM_HERE, sFirstIdleTask);
+    RefPtr<CancelableRunnable> firstIdleTask = NewRunnableFunction(FirstIdle);
+    sFirstIdleTask = firstIdleTask;
+    MessageLoop::current()->PostIdleTask(firstIdleTask.forget());
 
     // Redo InitProcessAttributes() when the app or browser is really
     // launching so the attributes will be correct.
     mID = aCpID;
     mIsForApp = aIsForApp;
     mIsForBrowser = aIsForBrowser;
     InitProcessAttributes();
   }
@@ -2621,18 +2622,17 @@ ContentChild::RecvAppInit()
   // BrowserElementChild.js.
   if (mIsForApp || mIsForBrowser) {
     PreloadSlowThings();
   }
 
 #ifdef MOZ_NUWA_PROCESS
   if (IsNuwaProcess()) {
     ContentChild::GetSingleton()->RecvGarbageCollect();
-    MessageLoop::current()->PostTask(
-      FROM_HERE, NewRunnableFunction(OnFinishNuwaPreparation));
+    MessageLoop::current()->PostTask(NewRunnableFunction(OnFinishNuwaPreparation));
   }
 #endif
 
   return true;
 }
 
 bool
 ContentChild::RecvLastPrivateDocShellDestroyed()
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -795,18 +795,17 @@ ContentParent::JoinAllSubprocesses()
     printf_stderr("There are no live subprocesses.");
     return;
   }
 
   printf_stderr("Subprocesses are still alive.  Doing emergency join.\n");
 
   bool done = false;
   Monitor monitor("mozilla.dom.ContentParent.JoinAllSubprocesses");
-  XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
-                                   NewRunnableFunction(
+  XRE_GetIOMessageLoop()->PostTask(NewRunnableFunction(
                                      &ContentParent::JoinProcessesIOThread,
                                      &processes, &monitor, &done));
   {
     MonitorAutoLock lock(monitor);
     while (!done) {
       lock.Wait();
     }
   }
@@ -2175,17 +2174,16 @@ ContentParent::ActorDestroy(ActorDestroy
     }
     }
   }
 
   // Destroy any processes created by this ContentParent
   for(uint32_t i = 0; i < childIDArray.Length(); i++) {
     ContentParent* cp = cpm->GetContentProcessById(childIDArray[i]);
     MessageLoop::current()->PostTask(
-      FROM_HERE,
       NewRunnableMethod(cp, &ContentParent::ShutDownProcess,
                         SEND_SHUTDOWN_MESSAGE));
   }
   cpm->RemoveContentProcess(this->ChildID());
 
   if (mDriverCrashGuard) {
     mDriverCrashGuard->NotifyCrashed();
   }
@@ -2259,17 +2257,16 @@ ContentParent::NotifyTabDestroyed(const 
   // because of popup windows.  When the last one closes, shut
   // us down.
   ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
   nsTArray<TabId> tabIds = cpm->GetTabParentsByProcessId(this->ChildID());
   if (tabIds.Length() == 1) {
     // In the case of normal shutdown, send a shutdown message to child to
     // allow it to perform shutdown tasks.
     MessageLoop::current()->PostTask(
-      FROM_HERE,
       NewRunnableMethod(this, &ContentParent::ShutDownProcess,
                         SEND_SHUTDOWN_MESSAGE));
   }
 }
 
 jsipc::CPOWManager*
 ContentParent::GetCPOWManager()
 {
@@ -3624,17 +3621,16 @@ ContentParent::KillHard(const char* aRea
   }
 
   if (mSubprocess) {
     mSubprocess->SetAlreadyDead();
   }
 
   // EnsureProcessTerminated has responsibilty for closing otherProcessHandle.
   XRE_GetIOMessageLoop()->PostTask(
-    FROM_HERE,
     NewRunnableFunction(&ProcessWatcher::EnsureProcessTerminated,
                         otherProcessHandle, /*force=*/true));
 }
 
 bool
 ContentParent::IsPreallocated() const
 {
   return mAppManifestURL == MAGIC_PREALLOCATED_APP_MANIFEST_URL;
--- a/dom/ipc/PreallocatedProcessManager.cpp
+++ b/dom/ipc/PreallocatedProcessManager.cpp
@@ -200,31 +200,29 @@ PreallocatedProcessManagerImpl::Enable()
 void
 PreallocatedProcessManagerImpl::AllocateAfterDelay()
 {
   if (!mEnabled || mPreallocatedAppProcess) {
     return;
   }
 
   MessageLoop::current()->PostDelayedTask(
-    FROM_HERE,
     NewRunnableMethod(this, &PreallocatedProcessManagerImpl::AllocateOnIdle),
     Preferences::GetUint("dom.ipc.processPrelaunch.delayMs",
                          DEFAULT_ALLOCATE_DELAY));
 }
 
 void
 PreallocatedProcessManagerImpl::AllocateOnIdle()
 {
   if (!mEnabled || mPreallocatedAppProcess) {
     return;
   }
 
   MessageLoop::current()->PostIdleTask(
-    FROM_HERE,
     NewRunnableMethod(this, &PreallocatedProcessManagerImpl::AllocateNow));
 }
 
 void
 PreallocatedProcessManagerImpl::AllocateNow()
 {
   if (!mEnabled || mPreallocatedAppProcess) {
     return;
@@ -240,20 +238,20 @@ PreallocatedProcessManagerImpl::Schedule
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (mPreallocateAppProcessTask) {
     // Make sure there is only one request running.
     return;
   }
 
-  mPreallocateAppProcessTask = NewRunnableMethod(
+  RefPtr<CancelableTask> task = NewRunnableMethod(
     this, &PreallocatedProcessManagerImpl::DelayedNuwaFork);
-  MessageLoop::current()->PostDelayedTask(
-    FROM_HERE, mPreallocateAppProcessTask,
+  mPreallocateAppProcessTask = task;
+  MessageLoop::current()->PostDelayedTask(task.forget(),
     Preferences::GetUint("dom.ipc.processPrelaunch.delayMs",
                          DEFAULT_ALLOCATE_DELAY));
 }
 
 void
 PreallocatedProcessManagerImpl::DelayedNuwaFork()
 {
   MOZ_ASSERT(NS_IsMainThread());
--- a/dom/ipc/ProcessHangMonitor.cpp
+++ b/dom/ipc/ProcessHangMonitor.cpp
@@ -260,17 +260,18 @@ HangMonitorChild::HangMonitorChild(Proce
 {
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
 }
 
 HangMonitorChild::~HangMonitorChild()
 {
   // For some reason IPDL doesn't automatically delete the channel for a
   // bridged protocol (bug 1090570). So we have to do it ourselves.
-  XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new DeleteTask<Transport>(GetTransport()));
+  RefPtr<DeleteTask<Transport>> task = new DeleteTask<Transport>(GetTransport());
+  XRE_GetIOMessageLoop()->PostTask(task.forget());
 
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(sInstance == this);
   sInstance = nullptr;
 }
 
 void
 HangMonitorChild::Shutdown()
@@ -298,17 +299,16 @@ HangMonitorChild::ActorDestroy(ActorDest
 {
   MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
 
   mIPCOpen = false;
 
   // We use a task here to ensure that IPDL is finished with this
   // HangMonitorChild before it gets deleted on the main thread.
   MonitorLoop()->PostTask(
-    FROM_HERE,
     NewRunnableMethod(this, &HangMonitorChild::ShutdownOnThread));
 }
 
 bool
 HangMonitorChild::RecvTerminateScript()
 {
   MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
 
@@ -386,17 +386,16 @@ HangMonitorChild::NotifySlowScript(nsITa
   TabId id;
   if (aTabChild) {
     RefPtr<TabChild> tabChild = static_cast<TabChild*>(aTabChild);
     id = tabChild->GetTabId();
   }
   nsAutoCString filename(aFileName);
 
   MonitorLoop()->PostTask(
-    FROM_HERE,
     NewRunnableMethod(this, &HangMonitorChild::NotifySlowScriptAsync,
                       id, filename, aLineNo));
   return SlowScriptAction::Continue;
 }
 
 bool
 HangMonitorChild::IsDebuggerStartupComplete()
 {
@@ -417,17 +416,16 @@ HangMonitorChild::NotifyPluginHang(uint3
 {
   // main thread in the child
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
 
   mSentReport = true;
 
   // bounce to background thread
   MonitorLoop()->PostTask(
-    FROM_HERE,
     NewRunnableMethod(this,
                       &HangMonitorChild::NotifyPluginHangAsync,
                       aPluginId));
 }
 
 void
 HangMonitorChild::NotifyPluginHangAsync(uint32_t aPluginId)
 {
@@ -443,17 +441,16 @@ HangMonitorChild::NotifyPluginHangAsync(
 void
 HangMonitorChild::ClearHang()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (mSentReport) {
     // bounce to background thread
     MonitorLoop()->PostTask(
-      FROM_HERE,
       NewRunnableMethod(this, &HangMonitorChild::ClearHangAsync));
 
     MonitorAutoLock lock(mMonitor);
     mSentReport = false;
     mTerminateScript = false;
     mStartDebugger = false;
     mFinishedStartingDebugger = false;
   }
@@ -482,17 +479,18 @@ HangMonitorParent::HangMonitorParent(Pro
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
   mReportHangs = mozilla::Preferences::GetBool("dom.ipc.reportProcessHangs", false);
 }
 
 HangMonitorParent::~HangMonitorParent()
 {
   // For some reason IPDL doesn't automatically delete the channel for a
   // bridged protocol (bug 1090570). So we have to do it ourselves.
-  XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new DeleteTask<Transport>(GetTransport()));
+  RefPtr<DeleteTask<Transport>> task = new DeleteTask<Transport>(GetTransport());
+  XRE_GetIOMessageLoop()->PostTask(task.forget());
 
 #ifdef MOZ_CRASHREPORTER
   MutexAutoLock lock(mBrowserCrashDumpHashLock);
 
   for (auto iter = mBrowserCrashDumpIds.Iter(); !iter.Done(); iter.Next()) {
     nsString crashId = iter.UserData();
     if (!crashId.IsEmpty()) {
       CrashReporter::DeleteMinidumpFilesForID(crashId);
@@ -509,17 +507,16 @@ HangMonitorParent::Shutdown()
   MonitorAutoLock lock(mMonitor);
 
   if (mProcess) {
     mProcess->Clear();
     mProcess = nullptr;
   }
 
   MonitorLoop()->PostTask(
-    FROM_HERE,
     NewRunnableMethod(this, &HangMonitorParent::ShutdownOnThread));
 
   while (!mShutdownDone) {
     mMonitor.Wait();
   }
 }
 
 void
@@ -831,17 +828,16 @@ HangMonitoredProcess::TerminateScript()
     return NS_ERROR_UNEXPECTED;
   }
 
   if (!mActor) {
     return NS_ERROR_UNEXPECTED;
   }
 
   ProcessHangMonitor::Get()->MonitorLoop()->PostTask(
-    FROM_HERE,
     NewRunnableMethod(mActor, &HangMonitorParent::TerminateScript));
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HangMonitoredProcess::BeginStartingDebugger()
 {
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
@@ -849,17 +845,16 @@ HangMonitoredProcess::BeginStartingDebug
     return NS_ERROR_UNEXPECTED;
   }
 
   if (!mActor) {
     return NS_ERROR_UNEXPECTED;
   }
 
   ProcessHangMonitor::Get()->MonitorLoop()->PostTask(
-    FROM_HERE,
     NewRunnableMethod(mActor, &HangMonitorParent::BeginStartingDebugger));
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HangMonitoredProcess::EndStartingDebugger()
 {
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
@@ -867,17 +862,16 @@ HangMonitoredProcess::EndStartingDebugge
     return NS_ERROR_UNEXPECTED;
   }
 
   if (!mActor) {
     return NS_ERROR_UNEXPECTED;
   }
 
   ProcessHangMonitor::Get()->MonitorLoop()->PostTask(
-    FROM_HERE,
     NewRunnableMethod(mActor, &HangMonitorParent::EndStartingDebugger));
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HangMonitoredProcess::TerminatePlugin()
 {
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
@@ -1047,34 +1041,32 @@ mozilla::CreateHangMonitorParent(Content
 
   ProcessHangMonitor* monitor = ProcessHangMonitor::GetOrCreate();
   HangMonitorParent* parent = new HangMonitorParent(monitor);
 
   HangMonitoredProcess* process = new HangMonitoredProcess(parent, aContentParent);
   parent->SetProcess(process);
 
   monitor->MonitorLoop()->PostTask(
-    FROM_HERE,
     NewRunnableMethod(parent, &HangMonitorParent::Open,
                       aTransport, aOtherPid, XRE_GetIOMessageLoop()));
 
   return parent;
 }
 
 PProcessHangMonitorChild*
 mozilla::CreateHangMonitorChild(mozilla::ipc::Transport* aTransport,
                                 base::ProcessId aOtherPid)
 {
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
 
   ProcessHangMonitor* monitor = ProcessHangMonitor::GetOrCreate();
   HangMonitorChild* child = new HangMonitorChild(monitor);
 
   monitor->MonitorLoop()->PostTask(
-    FROM_HERE,
     NewRunnableMethod(child, &HangMonitorChild::Open,
                       aTransport, aOtherPid, XRE_GetIOMessageLoop()));
 
   return child;
 }
 
 MessageLoop*
 ProcessHangMonitor::MonitorLoop()
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -241,17 +241,17 @@ HostHasPermission(nsIURI &docURI)
   } while (end < domainWhiteList.Length());
 
   return false;
 }
 
 // Generic class for running long media operations like Start off the main
 // thread, and then (because nsDOMMediaStreams aren't threadsafe),
 // ProxyReleases mStream since it's cycle collected.
-class MediaOperationTask : public Task
+class MediaOperationTask : public Runnable
 {
 public:
   // so we can send Stop without AddRef()ing from the MSG thread
   MediaOperationTask(MediaOperation aType,
     GetUserMediaCallbackMediaStreamListener* aListener,
     DOMMediaStream* aStream,
     OnTracksAvailableCallback* aOnTracksAvailableCallback,
     AudioDevice* aAudioDevice,
@@ -275,45 +275,45 @@ public:
   ~MediaOperationTask()
   {
     // MediaStreams can be released on any thread.
   }
 
   void
   ReturnCallbackError(nsresult rv, const char* errorLog);
 
-  void
-  Run()
+  NS_IMETHOD
+  Run() override
   {
     SourceMediaStream *source = mListener->GetSourceStream();
     // No locking between these is required as all the callbacks for the
     // same MediaStream will occur on the same thread.
     if (!source) // means the stream was never Activated()
-      return;
+      return NS_OK;
 
     switch (mType) {
       case MEDIA_START:
         {
           NS_ASSERTION(!NS_IsMainThread(), "Never call on main thread");
           nsresult rv;
 
           if (mAudioDevice) {
             rv = mAudioDevice->GetSource()->Start(source, kAudioTrack,
                                                   mListener->GetPrincipalHandle());
             if (NS_FAILED(rv)) {
               ReturnCallbackError(rv, "Starting audio failed");
-              return;
+              return NS_OK;
             }
           }
           if (mVideoDevice) {
             rv = mVideoDevice->GetSource()->Start(source, kVideoTrack,
                                                   mListener->GetPrincipalHandle());
             if (NS_FAILED(rv)) {
               ReturnCallbackError(rv, "Starting video failed");
-              return;
+              return NS_OK;
             }
           }
           // Start() queued the tracks to be added synchronously to avoid races
           source->FinishAddTracks();
 
           source->SetPullEnabled(true);
           source->AdvanceKnownTracksTime(STREAM_TIME_MAX);
 
@@ -372,16 +372,18 @@ public:
           }
         }
         break;
 
       default:
         MOZ_ASSERT(false,"invalid MediaManager operation");
         break;
     }
+
+    return NS_OK;
   }
 
 private:
   MediaOperation mType;
   RefPtr<DOMMediaStream> mStream;
   nsAutoPtr<OnTracksAvailableCallback> mOnTracksAvailableCallback;
   RefPtr<AudioDevice> mAudioDevice; // threadsafe
   RefPtr<VideoDevice> mVideoDevice; // threadsafe
@@ -969,21 +971,22 @@ public:
     // Note: includes JS callbacks; must be released on MainThread
     TracksAvailableCallback* tracksAvailableCallback =
       new TracksAvailableCallback(mManager, mOnSuccess, mWindowID, domStream);
 
     // Dispatch to the media thread to ask it to start the sources,
     // because that can take a while.
     // Pass ownership of domStream to the MediaOperationTask
     // to ensure it's kept alive until the MediaOperationTask runs (at least).
-    MediaManager::PostTask(FROM_HERE,
+    RefPtr<Runnable> mediaOperation =
         new MediaOperationTask(MEDIA_START, mListener, domStream,
                                tracksAvailableCallback,
                                mAudioDevice, mVideoDevice,
-                               false, mWindowID, mOnFailure.forget()));
+                               false, mWindowID, mOnFailure.forget());
+    MediaManager::PostTask(mediaOperation.forget());
     // We won't need mOnFailure now.
     mOnFailure = nullptr;
 
     if (!MediaManager::IsPrivateBrowsing(window)) {
       // Call GetOriginKey again, this time w/persist = true, to promote
       // deviceIds to persistent, in case they're not already. Fire'n'forget.
       RefPtr<Pledge<nsCString>> p = media::GetOriginKey(mOrigin, false, true);
     }
@@ -1063,18 +1066,17 @@ MediaManager::SelectSettings(
 {
   MOZ_ASSERT(NS_IsMainThread());
   RefPtr<PledgeChar> p = new PledgeChar();
   uint32_t id = mOutstandingCharPledges.Append(*p);
 
   // Algorithm accesses device capabilities code and must run on media thread.
   // Modifies passed-in aSources.
 
-  MediaManager::PostTask(FROM_HERE, NewTaskFrom([id, aConstraints,
-                                                 aSources]() mutable {
+  MediaManager::PostTask(NewTaskFrom([id, aConstraints, aSources]() mutable {
     auto& sources = **aSources;
 
     // Since the advanced part of the constraints algorithm needs to know when
     // a candidate set is overconstrained (zero members), we must split up the
     // list into videos and audios, and put it back together again at the end.
 
     nsTArray<RefPtr<VideoDevice>> videos;
     nsTArray<RefPtr<AudioDevice>> audios;
@@ -1100,37 +1102,37 @@ MediaManager::SelectSettings(
     }
     if (audios.Length() && IsOn(aConstraints.mAudio)) {
       badConstraint = MediaConstraintsHelper::SelectSettings(
           GetInvariant(aConstraints.mAudio), audios);
       for (auto& audio : audios) {
         sources.AppendElement(audio);
       }
     }
-    NS_DispatchToMainThread(do_AddRef(NewRunnableFrom([id, badConstraint]() mutable {
+    NS_DispatchToMainThread(NewRunnableFrom([id, badConstraint]() mutable {
       RefPtr<MediaManager> mgr = MediaManager_GetInstance();
       RefPtr<PledgeChar> p = mgr->mOutstandingCharPledges.Remove(id);
       if (p) {
         p->Resolve(badConstraint);
       }
       return NS_OK;
-    })));
+    }));
   }));
   return p.forget();
 }
 
 /**
  * Runs on a seperate thread and is responsible for enumerating devices.
  * Depending on whether a picture or stream was asked for, either
  * ProcessGetUserMedia is called, and the results are sent back to the DOM.
  *
  * Do not run this on the main thread. The success and error callbacks *MUST*
  * be dispatched on the main thread!
  */
-class GetUserMediaTask : public Task
+class GetUserMediaTask : public Runnable
 {
 public:
   GetUserMediaTask(
     const MediaStreamConstraints& aConstraints,
     already_AddRefed<nsIDOMGetUserMediaSuccessCallback> aOnSuccess,
     already_AddRefed<nsIDOMGetUserMediaErrorCallback> aOnFailure,
     uint64_t aWindowID, GetUserMediaCallbackMediaStreamListener *aListener,
     MediaEnginePrefs &aPrefs,
@@ -1163,18 +1165,18 @@ public:
     MOZ_ASSERT(!mOnSuccess);
     MOZ_ASSERT(!mOnFailure);
 
     NS_DispatchToMainThread(runnable.forget());
     // Do after ErrorCallbackRunnable Run()s, as it checks active window list
     NS_DispatchToMainThread(do_AddRef(new GetUserMediaListenerRemove(mWindowID, mListener)));
   }
 
-  void
-  Run()
+  NS_IMETHOD
+  Run() override
   {
     MOZ_ASSERT(!NS_IsMainThread());
     MOZ_ASSERT(mOnSuccess);
     MOZ_ASSERT(mOnFailure);
     MOZ_ASSERT(mDeviceChosen);
 
     // Allocate a video or audio device and return a MediaStream via
     // a GetUserMediaStreamRunnable.
@@ -1183,43 +1185,44 @@ public:
 
     if (mAudioDevice) {
       rv = mAudioDevice->Allocate(GetInvariant(mConstraints.mAudio),
                                   mPrefs, mOrigin);
       if (NS_FAILED(rv)) {
         LOG(("Failed to allocate audiosource %d",rv));
         Fail(NS_LITERAL_STRING("SourceUnavailableError"),
              NS_LITERAL_STRING("Failed to allocate audiosource"));
-        return;
+        return NS_OK;
       }
     }
     if (mVideoDevice) {
       rv = mVideoDevice->Allocate(GetInvariant(mConstraints.mVideo),
                                   mPrefs, mOrigin);
       if (NS_FAILED(rv)) {
         LOG(("Failed to allocate videosource %d\n",rv));
         if (mAudioDevice) {
           mAudioDevice->GetSource()->Deallocate();
         }
         Fail(NS_LITERAL_STRING("SourceUnavailableError"),
              NS_LITERAL_STRING("Failed to allocate videosource"));
-        return;
+        return NS_OK;
       }
     }
     PeerIdentity* peerIdentity = nullptr;
     if (!mConstraints.mPeerIdentity.IsEmpty()) {
       peerIdentity = new PeerIdentity(mConstraints.mPeerIdentity);
     }
 
     NS_DispatchToMainThread(do_AddRef(
         new GetUserMediaStreamRunnable(mOnSuccess, mOnFailure, mWindowID,
                                        mListener, mOrigin, mAudioDevice,
                                        mVideoDevice, peerIdentity)));
     MOZ_ASSERT(!mOnSuccess);
     MOZ_ASSERT(!mOnFailure);
+    return NS_OK;
   }
 
   nsresult
   Denied(const nsAString& aName,
          const nsAString& aMessage = EmptyString())
   {
     MOZ_ASSERT(mOnSuccess);
     MOZ_ASSERT(mOnFailure);
@@ -1301,17 +1304,17 @@ public:
   // This object must take ownership of task
   GetUserMediaRunnableWrapper(GetUserMediaTask* task) :
     mTask(task) {
   }
 
   ~GetUserMediaRunnableWrapper() {
   }
 
-  NS_IMETHOD Run() {
+  NS_IMETHOD Run() override {
     mTask->Run();
     return NS_OK;
   }
 
 private:
   nsAutoPtr<GetUserMediaTask> mTask;
 };
 #endif
@@ -1346,20 +1349,20 @@ MediaManager::EnumerateRawDevices(uint64
     }
   }
 
   if (!aFake) {
     // Fake tracks only make sense when we have a fake stream.
     aFakeTracks = false;
   }
 
-  MediaManager::PostTask(FROM_HERE, NewTaskFrom([id, aWindowId, audioLoopDev,
-                                                 videoLoopDev, aVideoType,
-                                                 aAudioType, aFake,
-                                                 aFakeTracks]() mutable {
+  MediaManager::PostTask(NewTaskFrom([id, aWindowId, audioLoopDev,
+                                      videoLoopDev, aVideoType,
+                                      aAudioType, aFake,
+                                      aFakeTracks]() mutable {
     // Only enumerate what's asked for, and only fake cams and mics.
     bool hasVideo = aVideoType != MediaSourceEnum::Other;
     bool hasAudio = aAudioType != MediaSourceEnum::Other;
     bool fakeCams = aFake && aVideoType == MediaSourceEnum::Camera;
     bool fakeMics = aFake && aAudioType == MediaSourceEnum::Microphone;
 
     RefPtr<MediaEngine> fakeBackend, realBackend;
     if (fakeCams || fakeMics) {
@@ -1384,28 +1387,28 @@ MediaManager::EnumerateRawDevices(uint64
       nsTArray<RefPtr<AudioDevice>> audios;
       GetSources(fakeMics? fakeBackend : realBackend, aAudioType,
                  &MediaEngine::EnumerateAudioDevices, audios, audioLoopDev);
       for (auto& source : audios) {
         result->AppendElement(source);
       }
     }
     SourceSet* handoff = result.release();
-    NS_DispatchToMainThread(do_AddRef(NewRunnableFrom([id, handoff]() mutable {
+    NS_DispatchToMainThread(NewRunnableFrom([id, handoff]() mutable {
       UniquePtr<SourceSet> result(handoff); // grab result
       RefPtr<MediaManager> mgr = MediaManager_GetInstance();
       if (!mgr) {
         return NS_OK;
       }
       RefPtr<PledgeSourceSet> p = mgr->mOutstandingPledges.Remove(id);
       if (p) {
         p->Resolve(result.release());
       }
       return NS_OK;
-    })));
+    }));
   }));
   return p.forget();
 }
 
 MediaManager::MediaManager()
   : mMediaThread(nullptr)
   , mBackend(nullptr) {
   mPrefs.mFreq         = 1000; // 1KHz test tone
@@ -1593,26 +1596,29 @@ MediaManager::StartupInit()
       free(pAdapterInfo);
     }
   }
 #endif
 }
 
 /* static */
 void
-MediaManager::PostTask(const tracked_objects::Location& from_here, Task* task)
+MediaManager::PostTask(already_AddRefed<Runnable> task)
 {
   if (sInShutdown) {
     // Can't safely delete task here since it may have items with specific
     // thread-release requirements.
+    // XXXkhuey well then who is supposed to delete it?! We don't signal
+    // that we failed ...
+    MOZ_CRASH();
     return;
   }
   NS_ASSERTION(Get(), "MediaManager singleton?");
   NS_ASSERTION(Get()->mMediaThread, "No thread yet");
-  Get()->mMediaThread->message_loop()->PostTask(from_here, task);
+  Get()->mMediaThread->message_loop()->PostTask(Move(task));
 }
 
 /* static */ nsresult
 MediaManager::NotifyRecordingStatusChange(nsPIDOMWindowInner* aWindow,
                                           const nsString& aMsg,
                                           const bool& aIsAudio,
                                           const bool& aIsVideo)
 {
@@ -2118,21 +2124,21 @@ MediaManager::GetUserMedia(nsPIDOMWindow
           rv = devicesCopy->AppendElement(device);
           if (NS_WARN_IF(NS_FAILED(rv))) {
             return;
           }
         }
       }
 
       // Pass callbacks and MediaStreamListener along to GetUserMediaTask.
-      nsAutoPtr<GetUserMediaTask> task (new GetUserMediaTask(c, onSuccess.forget(),
-                                                             onFailure.forget(),
-                                                             windowID, listener,
-                                                             prefs, origin,
-                                                             devices->release()));
+      RefPtr<GetUserMediaTask> task (new GetUserMediaTask(c, onSuccess.forget(),
+                                                          onFailure.forget(),
+                                                          windowID, listener,
+                                                          prefs, origin,
+                                                          devices->release()));
       // Store the task w/callbacks.
       mActiveCallbacks.Put(callID, task.forget());
 
       // Add a WindowID cross-reference so OnNavigation can tear things down
       nsTArray<nsString>* array;
       if (!mCallIds.Get(windowID, &array)) {
         array = new nsTArray<nsString>();
         mCallIds.Put(windowID, array);
@@ -2370,19 +2376,19 @@ MediaManager::GetUserMediaDevices(nsPIDO
   // Ignore passed-in constraints, instead locate + return already-constrained list.
 
   nsTArray<nsString>* callIDs;
   if (!mCallIds.Get(aWindowId, &callIDs)) {
     return NS_ERROR_UNEXPECTED;
   }
 
   for (auto& callID : *callIDs) {
-    GetUserMediaTask* task;
+    RefPtr<GetUserMediaTask> task;
     if (!aCallID.Length() || aCallID == callID) {
-      if (mActiveCallbacks.Get(callID, &task)) {
+      if (mActiveCallbacks.Get(callID, getter_AddRefs(task))) {
         nsCOMPtr<nsIWritableVariant> array = MediaManager_ToJSArray(*task->mSourceSet);
         onSuccess->OnSuccess(array);
         return NS_OK;
       }
     }
   }
   return NS_ERROR_UNEXPECTED;
 }
@@ -2611,25 +2617,25 @@ MediaManager::Shutdown()
   mCallIds.Clear();
 #ifdef MOZ_WEBRTC
   StopWebRtcLog();
 #endif
 
   // Because mMediaThread is not an nsThread, we must dispatch to it so it can
   // clean up BackgroundChild. Continue stopping thread once this is done.
 
-  class ShutdownTask : public Task
+  class ShutdownTask : public Runnable
   {
   public:
     ShutdownTask(MediaManager* aManager,
-                 Runnable* aReply)
+                 already_AddRefed<Runnable> aReply)
       : mManager(aManager)
       , mReply(aReply) {}
   private:
-    void
+    NS_IMETHOD
     Run() override
     {
       LOG(("MediaManager Thread Shutdown"));
       MOZ_ASSERT(MediaManager::IsInMediaThread());
       // Must shutdown backend on MediaManager thread, since that's where we started it from!
       {
         if (mManager->mBackend) {
           mManager->mBackend->Shutdown(); // ok to invoke multiple times
@@ -2637,49 +2643,52 @@ MediaManager::Shutdown()
       }
       mozilla::ipc::BackgroundChild::CloseForCurrentThread();
       // must explicitly do this before dispatching the reply, since the reply may kill us with Stop()
       mManager->mBackend = nullptr; // last reference, will invoke Shutdown() again
 
       if (NS_FAILED(NS_DispatchToMainThread(mReply.forget()))) {
         LOG(("Will leak thread: DispatchToMainthread of reply runnable failed in MediaManager shutdown"));
       }
+
+      return NS_OK;
     }
     RefPtr<MediaManager> mManager;
     RefPtr<Runnable> mReply;
   };
 
   // Post ShutdownTask to execute on mMediaThread and pass in a lambda
   // callback to be executed back on this thread once it is done.
   //
   // The lambda callback "captures" the 'this' pointer for member access.
   // This is safe since this is guaranteed to be here since sSingleton isn't
   // cleared until the lambda function clears it.
 
   // note that this == sSingleton
   RefPtr<MediaManager> that(sSingleton);
   // Release the backend (and call Shutdown()) from within the MediaManager thread
   // Don't use MediaManager::PostTask() because we're sInShutdown=true here!
-  mMediaThread->message_loop()->PostTask(FROM_HERE, new ShutdownTask(this,
+  RefPtr<ShutdownTask> shutdown = new ShutdownTask(this,
       media::NewRunnableFrom([this, that]() mutable {
     LOG(("MediaManager shutdown lambda running, releasing MediaManager singleton and thread"));
     if (mMediaThread) {
       mMediaThread->Stop();
     }
 
     // Remove async shutdown blocker
 
     nsCOMPtr<nsIAsyncShutdownClient> shutdownPhase = GetShutdownPhase();
     shutdownPhase->RemoveBlocker(sSingleton->mShutdownBlocker);
 
     // we hold a ref to 'that' which is the same as sSingleton
     sSingleton = nullptr;
 
     return NS_OK;
-  })));
+  }));
+  mMediaThread->message_loop()->PostTask(shutdown.forget());
 }
 
 nsresult
 MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
   const char16_t* aData)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
@@ -2692,18 +2701,18 @@ MediaManager::Observe(nsISupports* aSubj
     }
   } else if (!strcmp(aTopic, "last-pb-context-exited")) {
     // Clear memory of private-browsing-specific deviceIds. Fire and forget.
     media::SanitizeOriginKeys(0, true);
     return NS_OK;
   } else if (!strcmp(aTopic, "getUserMedia:privileged:allow") ||
              !strcmp(aTopic, "getUserMedia:response:allow")) {
     nsString key(aData);
-    nsAutoPtr<GetUserMediaTask> task;
-    mActiveCallbacks.RemoveAndForget(key, task);
+    RefPtr<GetUserMediaTask> task;
+    mActiveCallbacks.Remove(key, getter_AddRefs(task));
     if (!task) {
       return NS_OK;
     }
 
     if (aSubject) {
       // A particular device or devices were chosen by the user.
       // NOTE: does not allow setting a device to null; assumes nullptr
       nsCOMPtr<nsISupportsArray> array(do_QueryInterface(aSubject));
@@ -2740,33 +2749,33 @@ MediaManager::Observe(nsISupports* aSubj
         }
       }
     }
 
     if (sInShutdown) {
       return task->Denied(NS_LITERAL_STRING("In shutdown"));
     }
     // Reuse the same thread to save memory.
-    MediaManager::PostTask(FROM_HERE, task.forget());
+    MediaManager::PostTask(task.forget());
     return NS_OK;
 
   } else if (!strcmp(aTopic, "getUserMedia:response:deny")) {
     nsString errorMessage(NS_LITERAL_STRING("SecurityError"));
 
     if (aSubject) {
       nsCOMPtr<nsISupportsString> msg(do_QueryInterface(aSubject));
       MOZ_ASSERT(msg);
       msg->GetData(errorMessage);
       if (errorMessage.IsEmpty())
         errorMessage.AssignLiteral(MOZ_UTF16("InternalError"));
     }
 
     nsString key(aData);
-    nsAutoPtr<GetUserMediaTask> task;
-    mActiveCallbacks.RemoveAndForget(key, task);
+    RefPtr<GetUserMediaTask> task;
+    mActiveCallbacks.Remove(key, getter_AddRefs(task));
     if (task) {
       task->Denied(errorMessage);
     }
     return NS_OK;
 
   } else if (!strcmp(aTopic, "getUserMedia:revoke")) {
     nsresult rv;
     // may be windowid or screen:windowid
@@ -3076,22 +3085,23 @@ GetUserMediaCallbackMediaStreamListener:
   if (mStopped) {
     return;
   }
 
   // We can't take a chance on blocking here, so proxy this to another
   // thread.
   // Pass a ref to us (which is threadsafe) so it can query us for the
   // source stream info.
-  MediaManager::PostTask(FROM_HERE,
+  RefPtr<MediaOperationTask> mediaOperation =
     new MediaOperationTask(MEDIA_STOP,
                            this, nullptr, nullptr,
                            !mAudioStopped ? mAudioDevice.get() : nullptr,
                            !mVideoStopped ? mVideoDevice.get() : nullptr,
-                           false, mWindowID, nullptr));
+                           false, mWindowID, nullptr);
+  MediaManager::PostTask(mediaOperation.forget());
   mStopped = mAudioStopped = mVideoStopped = true;
 }
 
 // Doesn't kill audio
 void
 GetUserMediaCallbackMediaStreamListener::StopSharing()
 {
   MOZ_ASSERT(NS_IsMainThread());
@@ -3141,19 +3151,19 @@ GetUserMediaCallbackMediaStreamListener:
     p->Resolve(false);
     return p.forget();
   }
 
   RefPtr<MediaManager> mgr = MediaManager::GetInstance();
   uint32_t id = mgr->mOutstandingVoidPledges.Append(*p);
   uint64_t windowId = aWindow->WindowID();
 
-  MediaManager::PostTask(FROM_HERE, NewTaskFrom([id, windowId,
-                                                 audioDevice, videoDevice,
-                                                 aConstraints]() mutable {
+  MediaManager::PostTask(NewTaskFrom([id, windowId,
+                                      audioDevice, videoDevice,
+                                      aConstraints]() mutable {
     MOZ_ASSERT(MediaManager::IsInMediaThread());
     RefPtr<MediaManager> mgr = MediaManager::GetInstance();
     const char* badConstraint = nullptr;
     nsresult rv = NS_OK;
 
     if (audioDevice) {
       rv = audioDevice->Restart(aConstraints, mgr->mPrefs);
       if (rv == NS_ERROR_NOT_AVAILABLE) {
@@ -3166,18 +3176,18 @@ GetUserMediaCallbackMediaStreamListener:
       rv = videoDevice->Restart(aConstraints, mgr->mPrefs);
       if (rv == NS_ERROR_NOT_AVAILABLE) {
         nsTArray<RefPtr<VideoDevice>> videos;
         videos.AppendElement(videoDevice);
         badConstraint = MediaConstraintsHelper::SelectSettings(aConstraints,
                                                                videos);
       }
     }
-    NS_DispatchToMainThread(do_AddRef(NewRunnableFrom([id, windowId, rv,
-                                                       badConstraint]() mutable {
+    NS_DispatchToMainThread(NewRunnableFrom([id, windowId, rv,
+                                             badConstraint]() mutable {
       MOZ_ASSERT(NS_IsMainThread());
       RefPtr<MediaManager> mgr = MediaManager_GetInstance();
       if (!mgr) {
         return NS_OK;
       }
       RefPtr<PledgeVoid> p = mgr->mOutstandingVoidPledges.Remove(id);
       if (p) {
         if (NS_SUCCEEDED(rv)) {
@@ -3199,17 +3209,17 @@ GetUserMediaCallbackMediaStreamListener:
                   new MediaStreamError(window->AsInner(),
                                        NS_LITERAL_STRING("InternalError"));
               p->Reject(error);
             }
           }
         }
       }
       return NS_OK;
-    })));
+    }));
   }));
   return p.forget();
 }
 
 // Stop backend for track
 
 void
 GetUserMediaCallbackMediaStreamListener::StopTrack(TrackID aTrackID)
@@ -3236,22 +3246,23 @@ GetUserMediaCallbackMediaStreamListener:
   }
 
   if ((stopAudio || mAudioStopped || !mAudioDevice) &&
       (stopVideo || mVideoStopped || !mVideoDevice)) {
     Stop();
     return;
   }
 
-  MediaManager::PostTask(FROM_HERE,
+  RefPtr<MediaOperationTask> mediaOperation =
     new MediaOperationTask(MEDIA_STOP_TRACK,
                            this, nullptr, nullptr,
                            stopAudio ? mAudioDevice.get() : nullptr,
                            stopVideo ? mVideoDevice.get() : nullptr,
-                           false , mWindowID, nullptr));
+                           false , mWindowID, nullptr);
+  MediaManager::PostTask(mediaOperation.forget());
   mAudioStopped |= stopAudio;
   mVideoStopped |= stopVideo;
 }
 
 void
 GetUserMediaCallbackMediaStreamListener::NotifyFinished()
 {
   MOZ_ASSERT(NS_IsMainThread());
@@ -3266,21 +3277,22 @@ GetUserMediaCallbackMediaStreamListener:
   }
 }
 
 // Called from the MediaStreamGraph thread
 void
 GetUserMediaCallbackMediaStreamListener::NotifyDirectListeners(MediaStreamGraph* aGraph,
                                                                bool aHasListeners)
 {
-  MediaManager::PostTask(FROM_HERE,
+  RefPtr<MediaOperationTask> mediaOperation =
     new MediaOperationTask(MEDIA_DIRECT_LISTENERS,
                            this, nullptr, nullptr,
                            mAudioDevice, mVideoDevice,
-                           aHasListeners, mWindowID, nullptr));
+                           aHasListeners, mWindowID, nullptr);
+  MediaManager::PostTask(mediaOperation.forget());
 }
 
 // this can be in response to our own RemoveListener() (via ::Remove()), or
 // because the DOM GC'd the DOMLocalMediaStream/etc we're attached to.
 void
 GetUserMediaCallbackMediaStreamListener::NotifyRemoved()
 {
   MOZ_ASSERT(NS_IsMainThread());
--- a/dom/media/MediaManager.h
+++ b/dom/media/MediaManager.h
@@ -419,17 +419,17 @@ public:
   static already_AddRefed<MediaManager> GetInstance();
 
   // NOTE: never Dispatch(....,NS_DISPATCH_SYNC) to the MediaManager
   // thread from the MainThread, as we NS_DISPATCH_SYNC to MainThread
   // from MediaManager thread.
   static MediaManager* Get();
   static MediaManager* GetIfExists();
   static void StartupInit();
-  static void PostTask(const tracked_objects::Location& from_here, Task* task);
+  static void PostTask(already_AddRefed<Runnable> task);
 #ifdef DEBUG
   static bool IsInMediaThread();
 #endif
 
   static bool Exists()
   {
     return !!sSingleton;
   }
@@ -531,17 +531,17 @@ private:
   void IterateWindowListeners(nsPIDOMWindowInner *aWindow,
                               WindowListenerCallback aCallback,
                               void *aData);
 
   void StopMediaStreams();
 
   // ONLY access from MainThread so we don't need to lock
   WindowTable mActiveWindows;
-  nsClassHashtable<nsStringHashKey, GetUserMediaTask> mActiveCallbacks;
+  nsRefPtrHashtable<nsStringHashKey, GetUserMediaTask> mActiveCallbacks;
   nsClassHashtable<nsUint64HashKey, nsTArray<nsString>> mCallIds;
 
   // Always exists
   nsAutoPtr<base::Thread> mMediaThread;
   nsCOMPtr<nsIAsyncShutdownBlocker> mShutdownBlocker;
 
   // ONLY accessed from MediaManagerThread
   RefPtr<MediaEngine> mBackend;
--- a/dom/media/gmp/GMPChild.cpp
+++ b/dom/media/gmp/GMPChild.cpp
@@ -620,18 +620,19 @@ GMPChild::AllocPGMPContentChild(Transpor
 
 void
 GMPChild::GMPContentChildActorDestroy(GMPContentChild* aGMPContentChild)
 {
   for (uint32_t i = mGMPContentChildren.Length(); i > 0; i--) {
     UniquePtr<GMPContentChild>& toDestroy = mGMPContentChildren[i - 1];
     if (toDestroy.get() == aGMPContentChild) {
       SendPGMPContentChildDestroyed();
-      MessageLoop::current()->PostTask(FROM_HERE,
-                                       new DeleteTask<GMPContentChild>(toDestroy.release()));
+      RefPtr<DeleteTask<GMPContentChild>> task =
+        new DeleteTask<GMPContentChild>(toDestroy.release());
+      MessageLoop::current()->PostTask(task.forget());
       mGMPContentChildren.RemoveElementAt(i - 1);
       break;
     }
   }
 }
 
 } // namespace gmp
 } // namespace mozilla
--- a/dom/media/gmp/GMPContentChild.cpp
+++ b/dom/media/gmp/GMPContentChild.cpp
@@ -17,18 +17,18 @@ GMPContentChild::GMPContentChild(GMPChil
   : mGMPChild(aChild)
 {
   MOZ_COUNT_CTOR(GMPContentChild);
 }
 
 GMPContentChild::~GMPContentChild()
 {
   MOZ_COUNT_DTOR(GMPContentChild);
-  XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
-                                   new DeleteTask<Transport>(GetTransport()));
+  RefPtr<DeleteTask<Transport>> task = new DeleteTask<Transport>(GetTransport());
+  XRE_GetIOMessageLoop()->PostTask(task.forget());
 }
 
 MessageLoop*
 GMPContentChild::GMPMessageLoop()
 {
   return mGMPChild->GMPMessageLoop();
 }
 
--- a/dom/media/gmp/GMPContentParent.cpp
+++ b/dom/media/gmp/GMPContentParent.cpp
@@ -38,18 +38,18 @@ GMPContentParent::GMPContentParent(GMPPa
   if (mParent) {
     SetDisplayName(mParent->GetDisplayName());
     SetPluginId(mParent->GetPluginId());
   }
 }
 
 GMPContentParent::~GMPContentParent()
 {
-  XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
-                                   new DeleteTask<Transport>(GetTransport()));
+  RefPtr<DeleteTask<Transport>> task = new DeleteTask<Transport>(GetTransport());
+  XRE_GetIOMessageLoop()->PostTask(task.forget());
 }
 
 class ReleaseGMPContentParent : public Runnable
 {
 public:
   explicit ReleaseGMPContentParent(GMPContentParent* aToRelease)
     : mToRelease(aToRelease)
   {
--- a/dom/media/gmp/GMPDecryptorChild.cpp
+++ b/dom/media/gmp/GMPDecryptorChild.cpp
@@ -56,18 +56,18 @@ GMPDecryptorChild::CallOnGMPThread(Metho
 {
   if (ON_GMP_THREAD()) {
     // Use forwarding reference when we can.
     CallMethod(aMethod, Forward<ParamType>(aParams)...);
   } else {
     // Use const reference when we have to.
     auto m = &GMPDecryptorChild::CallMethod<
         decltype(aMethod), typename AddConstReference<ParamType>::Type...>;
-    auto t = NewRunnableMethod(this, m, aMethod, Forward<ParamType>(aParams)...);
-    mPlugin->GMPMessageLoop()->PostTask(FROM_HERE, t);
+    RefPtr<mozilla::Runnable> t = NewRunnableMethod(this, m, aMethod, Forward<ParamType>(aParams)...);
+    mPlugin->GMPMessageLoop()->PostTask(t.forget());
   }
 }
 
 void
 GMPDecryptorChild::Init(GMPDecryptor* aSession)
 {
   MOZ_ASSERT(aSession);
   mSession = aSession;
@@ -165,18 +165,18 @@ GMPDecryptorChild::KeyStatusChanged(cons
 }
 
 void
 GMPDecryptorChild::Decrypted(GMPBuffer* aBuffer, GMPErr aResult)
 {
   if (!ON_GMP_THREAD()) {
     // We should run this whole method on the GMP thread since the buffer needs
     // to be deleted after the SendDecrypted call.
-    auto t = NewRunnableMethod(this, &GMPDecryptorChild::Decrypted, aBuffer, aResult);
-    mPlugin->GMPMessageLoop()->PostTask(FROM_HERE, t);
+    RefPtr<Runnable> t = NewRunnableMethod(this, &GMPDecryptorChild::Decrypted, aBuffer, aResult);
+    mPlugin->GMPMessageLoop()->PostTask(t.forget());
     return;
   }
 
   if (!aBuffer) {
     NS_WARNING("GMPDecryptorCallback passed bull GMPBuffer");
     return;
   }
 
--- a/dom/media/gmp/GMPPlatform.cpp
+++ b/dom/media/gmp/GMPPlatform.cpp
@@ -68,17 +68,17 @@ public:
   void Post()
   {
     // We assert here for two reasons.
     // 1) Nobody should be blocking the main thread.
     // 2) This prevents deadlocks when doing sync calls to main which if the
     //    main thread tries to do a sync call back to the calling thread.
     MOZ_ASSERT(!IsOnChildMainThread());
 
-    mMessageLoop->PostTask(FROM_HERE, NewRunnableMethod(this, &SyncRunnable::Run));
+    mMessageLoop->PostTask(NewRunnableMethod(this, &SyncRunnable::Run));
     MonitorAutoLock lock(mMonitor);
     while (!mDone) {
       lock.Wait();
     }
   }
 
   void Run()
   {
@@ -116,17 +116,17 @@ CreateThread(GMPThread** aThread)
 GMPErr
 RunOnMainThread(GMPTask* aTask)
 {
   if (!aTask || !sMainLoop) {
     return GMPGenericErr;
   }
 
   RefPtr<Runnable> r = new Runnable(aTask);
-  sMainLoop->PostTask(FROM_HERE, NewRunnableMethod(r.get(), &Runnable::Run));
+  sMainLoop->PostTask(NewRunnableMethod(r.get(), &Runnable::Run));
 
   return GMPNoErr;
 }
 
 GMPErr
 SyncRunOnMainThread(GMPTask* aTask)
 {
   if (!aTask || !sMainLoop || IsOnChildMainThread()) {
@@ -249,17 +249,17 @@ GMPThreadImpl::Post(GMPTask* aTask)
     if (!started) {
       NS_WARNING("Unable to start GMPThread!");
       return;
     }
   }
 
   RefPtr<Runnable> r = new Runnable(aTask);
 
-  mThread.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(r.get(), &Runnable::Run));
+  mThread.message_loop()->PostTask(NewRunnableMethod(r.get(), &Runnable::Run));
 }
 
 void
 GMPThreadImpl::Join()
 {
   {
     MutexAutoLock lock(mMutex);
     if (mThread.IsRunning()) {
--- a/dom/media/gmp/GMPProcessParent.cpp
+++ b/dom/media/gmp/GMPProcessParent.cpp
@@ -80,17 +80,17 @@ GMPProcessParent::Launch(int32_t aTimeou
 
   return SyncLaunch(args, aTimeoutMs, base::GetCurrentProcessArchitecture());
 }
 
 void
 GMPProcessParent::Delete(nsCOMPtr<nsIRunnable> aCallback)
 {
   mDeletedCallback = aCallback;
-  XRE_GetIOMessageLoop()->PostTask(FROM_HERE, NewRunnableMethod(this, &GMPProcessParent::DoDelete));
+  XRE_GetIOMessageLoop()->PostTask(NewRunnableMethod(this, &GMPProcessParent::DoDelete));
 }
 
 void
 GMPProcessParent::DoDelete()
 {
   MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
   Join();
 
--- a/dom/media/gmp/GMPServiceChild.cpp
+++ b/dom/media/gmp/GMPServiceChild.cpp
@@ -247,18 +247,18 @@ GeckoMediaPluginServiceChild::RemoveGMPC
 }
 
 GMPServiceChild::GMPServiceChild()
 {
 }
 
 GMPServiceChild::~GMPServiceChild()
 {
-  XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
-                                   new DeleteTask<Transport>(GetTransport()));
+  RefPtr<DeleteTask<Transport>> task = new DeleteTask<Transport>(GetTransport());
+  XRE_GetIOMessageLoop()->PostTask(task.forget());
 }
 
 PGMPContentParent*
 GMPServiceChild::AllocPGMPContentParent(Transport* aTransport,
                                         ProcessId aOtherPid)
 {
   MOZ_ASSERT(!mContentParents.GetWeak(aOtherPid));
 
--- a/dom/media/gmp/GMPServiceParent.cpp
+++ b/dom/media/gmp/GMPServiceParent.cpp
@@ -1776,18 +1776,18 @@ GeckoMediaPluginServiceParent::ClearStor
   if (NS_FAILED(DeleteDir(path))) {
     NS_WARNING("Failed to delete GMP storage directory");
   }
   NS_DispatchToMainThread(new NotifyObserversTask("gmp-clear-storage-complete"), NS_DISPATCH_NORMAL);
 }
 
 GMPServiceParent::~GMPServiceParent()
 {
-  XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
-                                   new DeleteTask<Transport>(GetTransport()));
+  RefPtr<DeleteTask<Transport>> task = new DeleteTask<Transport>(GetTransport());
+  XRE_GetIOMessageLoop()->PostTask(task.forget());
 }
 
 bool
 GMPServiceParent::RecvLoadGMP(const nsCString& aNodeId,
                               const nsCString& aAPI,
                               nsTArray<nsCString>&& aTags,
                               nsTArray<ProcessId>&& aAlreadyBridgedTo,
                               ProcessId* aId,
--- a/dom/media/gmp/GMPStorageChild.cpp
+++ b/dom/media/gmp/GMPStorageChild.cpp
@@ -10,17 +10,17 @@
 #define ON_GMP_THREAD() (mPlugin->GMPMessageLoop() == MessageLoop::current())
 
 #define CALL_ON_GMP_THREAD(_func, ...) \
   do { \
     if (ON_GMP_THREAD()) { \
       _func(__VA_ARGS__); \
     } else { \
       mPlugin->GMPMessageLoop()->PostTask( \
-        FROM_HERE, NewRunnableMethod(this, &GMPStorageChild::_func, ##__VA_ARGS__) \
+        NewRunnableMethod(this, &GMPStorageChild::_func, ##__VA_ARGS__) \
       ); \
     } \
   } while(false)
 
 static nsTArray<uint8_t>
 ToArray(const uint8_t* aData, uint32_t aDataSize)
 {
   nsTArray<uint8_t> data;
--- a/dom/media/gmp/GMPVideoDecoderChild.cpp
+++ b/dom/media/gmp/GMPVideoDecoderChild.cpp
@@ -221,18 +221,17 @@ GMPVideoDecoderChild::Alloc(size_t aSize
   MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
 
   bool rv;
 #ifndef SHMEM_ALLOC_IN_CHILD
   ++mNeedShmemIntrCount;
   rv = CallNeedShmem(aSize, aMem);
   --mNeedShmemIntrCount;
   if (mPendingDecodeComplete) {
-    auto t = NewRunnableMethod(this, &GMPVideoDecoderChild::RecvDecodingComplete);
-    mPlugin->GMPMessageLoop()->PostTask(FROM_HERE, t);
+    mPlugin->GMPMessageLoop()->PostTask(NewRunnableMethod(this, &GMPVideoDecoderChild::RecvDecodingComplete));
   }
 #else
 #ifdef GMP_SAFE_SHMEM
   rv = AllocShmem(aSize, aType, aMem);
 #else
   rv = AllocUnsafeShmem(aSize, aType, aMem);
 #endif
 #endif
--- a/dom/media/gmp/GMPVideoEncoderChild.cpp
+++ b/dom/media/gmp/GMPVideoEncoderChild.cpp
@@ -202,18 +202,17 @@ GMPVideoEncoderChild::Alloc(size_t aSize
   MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
 
   bool rv;
 #ifndef SHMEM_ALLOC_IN_CHILD
   ++mNeedShmemIntrCount;
   rv = CallNeedShmem(aSize, aMem);
   --mNeedShmemIntrCount;
   if (mPendingEncodeComplete) {
-    auto t = NewRunnableMethod(this, &GMPVideoEncoderChild::RecvEncodingComplete);
-    mPlugin->GMPMessageLoop()->PostTask(FROM_HERE, t);
+    mPlugin->GMPMessageLoop()->PostTask(NewRunnableMethod(this, &GMPVideoEncoderChild::RecvEncodingComplete));
   }
 #else
 #ifdef GMP_SAFE_SHMEM
   rv = AllocShmem(aSize, aType, aMem);
 #else
   rv = AllocUnsafeShmem(aSize, aType, aMem);
 #endif
 #endif
--- a/dom/media/omx/MediaOmxReader.cpp
+++ b/dom/media/omx/MediaOmxReader.cpp
@@ -26,29 +26,30 @@ using namespace mozilla::gfx;
 using namespace mozilla::media;
 using namespace android;
 
 namespace mozilla {
 
 extern LazyLogModule gMediaDecoderLog;
 #define DECODER_LOG(type, msg) MOZ_LOG(gMediaDecoderLog, type, msg)
 
-class MediaOmxReader::ProcessCachedDataTask : public Task
+class MediaOmxReader::ProcessCachedDataTask : public Runnable
 {
 public:
   ProcessCachedDataTask(MediaOmxReader* aOmxReader, int64_t aOffset)
   : mOmxReader(aOmxReader),
     mOffset(aOffset)
   { }
 
-  void Run()
+  NS_IMETHOD Run() override
   {
     MOZ_ASSERT(!NS_IsMainThread());
     MOZ_ASSERT(mOmxReader.get());
     mOmxReader->ProcessCachedData(mOffset);
+    return NS_OK;
   }
 
 private:
   RefPtr<MediaOmxReader> mOmxReader;
   int64_t                  mOffset;
 };
 
 // When loading an MP3 stream from a file, we need to parse the file's
@@ -100,18 +101,18 @@ private:
       mLength -= length;
       mOffset += length;
     }
 
     if (static_cast<uint64_t>(mOffset) < mFullLength) {
       // We cannot read data in the main thread because it
       // might block for too long. Instead we post an IO task
       // to the IO thread if there is more data available.
-      XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
-          new ProcessCachedDataTask(mOmxReader.get(), mOffset));
+      RefPtr<Runnable> task = new ProcessCachedDataTask(mOmxReader.get(), mOffset);
+      XRE_GetIOMessageLoop()->PostTask(task.forget());
     }
   }
 
   RefPtr<MediaOmxReader>         mOmxReader;
   uint64_t                         mLength;
   int64_t                          mOffset;
   uint64_t                         mFullLength;
 };
--- a/dom/media/systemservices/CamerasParent.cpp
+++ b/dom/media/systemservices/CamerasParent.cpp
@@ -160,35 +160,35 @@ CamerasParent::Observe(nsISupports *aSub
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   MOZ_ASSERT(obs);
   obs->RemoveObserver(this, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID);
   StopVideoCapture();
   return NS_OK;
 }
 
 nsresult
-CamerasParent::DispatchToVideoCaptureThread(Runnable *event)
+CamerasParent::DispatchToVideoCaptureThread(Runnable* event)
 {
   // Don't try to dispatch if we're already on the right thread.
   // There's a potential deadlock because the mThreadMonitor is likely
   // to be taken already.
   MOZ_ASSERT(!mVideoCaptureThread ||
              mVideoCaptureThread->thread_id() != PlatformThread::CurrentId());
 
   MonitorAutoLock lock(mThreadMonitor);
 
   while(mChildIsAlive && mWebRTCAlive &&
         (!mVideoCaptureThread || !mVideoCaptureThread->IsRunning())) {
     mThreadMonitor.Wait();
   }
   if (!mVideoCaptureThread || !mVideoCaptureThread->IsRunning()) {
     return NS_ERROR_FAILURE;
   }
-  mVideoCaptureThread->message_loop()->PostTask(FROM_HERE,
-                                                new RunnableTask(event));
+  RefPtr<Runnable> addrefedEvent = event;
+  mVideoCaptureThread->message_loop()->PostTask(addrefedEvent.forget());
   return NS_OK;
 }
 
 void
 CamerasParent::StopVideoCapture()
 {
   LOG((__PRETTY_FUNCTION__));
   // We are called from the main thread (xpcom-shutdown) or
--- a/dom/media/systemservices/CamerasParent.h
+++ b/dom/media/systemservices/CamerasParent.h
@@ -124,17 +124,18 @@ protected:
   void StopCapture(const int& aCapEngine, const int& capnum);
   int ReleaseCaptureDevice(const int& aCapEngine, const int& capnum);
 
   bool SetupEngine(CaptureEngine aCapEngine);
   bool EnsureInitialized(int aEngine);
   void CloseEngines();
   void StopIPC();
   void StopVideoCapture();
-  nsresult DispatchToVideoCaptureThread(Runnable *event);
+  // Can't take already_AddRefed because it can fail in stupid ways.
+  nsresult DispatchToVideoCaptureThread(Runnable* event);
 
   EngineHelper mEngines[CaptureEngine::MaxEngine];
   nsTArray<CallbackHelper*> mCallbacks;
 
   // image buffers
   mozilla::ShmemPool mShmemPool;
 
   // PBackground parent thread
--- a/dom/media/systemservices/CamerasUtils.h
+++ b/dom/media/systemservices/CamerasUtils.h
@@ -34,27 +34,12 @@ public:
     return NS_OK;
   }
 
 private:
   ~ThreadDestructor() {}
   nsCOMPtr<nsIThread> mThread;
 };
 
-class RunnableTask : public Task
-{
-public:
-  explicit RunnableTask(Runnable* aRunnable)
-    : mRunnable(aRunnable) {}
-
-  void Run() override {
-    mRunnable->Run();
-  }
-
-private:
-  ~RunnableTask() {}
-  RefPtr<Runnable> mRunnable;
-};
-
 }
 }
 
 #endif // mozilla_CameraUtils_h
--- a/dom/media/systemservices/MediaSystemResourceManager.cpp
+++ b/dom/media/systemservices/MediaSystemResourceManager.cpp
@@ -34,30 +34,16 @@ MediaSystemResourceManager::Shutdown()
 {
   MOZ_ASSERT(InImageBridgeChildThread());
   if (sSingleton) {
     sSingleton->CloseIPC();
     sSingleton = nullptr;
   }
 }
 
-class RunnableCallTask : public Task
-{
-public:
-  explicit RunnableCallTask(nsIRunnable* aRunnable)
-    : mRunnable(aRunnable) {}
-
-  void Run() override
-  {
-    mRunnable->Run();
-  }
-protected:
-  nsCOMPtr<nsIRunnable> mRunnable;
-};
-
 /* static */ void
 MediaSystemResourceManager::Init()
 {
   if (!ImageBridgeChild::IsCreated()) {
     NS_WARNING("ImageBridge does not exist");
     return;
   }
 
@@ -72,28 +58,27 @@ MediaSystemResourceManager::Init()
     }
     return;
   }
 
   ReentrantMonitor barrier("MediaSystemResourceManager::Init");
   ReentrantMonitorAutoEnter autoMon(barrier);
   bool done = false;
 
-  nsCOMPtr<nsIRunnable> runnable =
+  RefPtr<Runnable> runnable =
     NS_NewRunnableFunction([&]() {
       if (!sSingleton) {
         sSingleton = new MediaSystemResourceManager();
       }
       ReentrantMonitorAutoEnter autoMon(barrier);
       done = true;
       barrier.NotifyAll();
     });
 
-  ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask(
-    FROM_HERE, new RunnableCallTask(runnable));
+  ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask(runnable.forget());
 
   // should stop the thread until done.
   while (!done) {
     barrier.Wait();
   }
 
 }
 
@@ -209,17 +194,16 @@ MediaSystemResourceManager::Acquire(Medi
   }
   // State Check
   if (aClient->mResourceState != MediaSystemResourceClient::RESOURCE_STATE_START) {
     HandleAcquireResult(aClient->mId, false);
     return;
   }
   aClient->mResourceState = MediaSystemResourceClient::RESOURCE_STATE_WAITING;
   ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask(
-    FROM_HERE,
     NewRunnableMethod(
       this,
       &MediaSystemResourceManager::DoAcquire,
       aClient->mId));
 }
 
 bool
 MediaSystemResourceManager::AcquireSyncNoWait(MediaSystemResourceClient* aClient)
@@ -253,17 +237,16 @@ MediaSystemResourceManager::AcquireSyncN
     }
     // Hold barrier Monitor until acquire task end.
     aClient->mAcquireSyncWaitMonitor = &barrier;
     aClient->mAcquireSyncWaitDone = &done;
     aClient->mResourceState = MediaSystemResourceClient::RESOURCE_STATE_WAITING;
   }
 
   ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask(
-    FROM_HERE,
     NewRunnableMethod(
       this,
       &MediaSystemResourceManager::DoAcquire,
       aClient->mId));
 
   // should stop the thread until done.
   while (!done) {
     barrier.Wait();
@@ -321,17 +304,16 @@ MediaSystemResourceManager::ReleaseResou
 
       aClient->mResourceState = MediaSystemResourceClient::RESOURCE_STATE_END;
       return;
     }
 
     aClient->mResourceState = MediaSystemResourceClient::RESOURCE_STATE_END;
 
     ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask(
-      FROM_HERE,
       NewRunnableMethod(
         this,
         &MediaSystemResourceManager::DoRelease,
         aClient->mId));
   }
 }
 
 void
@@ -350,17 +332,16 @@ MediaSystemResourceManager::RecvResponse
   HandleAcquireResult(aId, aSuccess);
 }
 
 void
 MediaSystemResourceManager::HandleAcquireResult(uint32_t aId, bool aSuccess)
 {
   if (!InImageBridgeChildThread()) {
     ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask(
-      FROM_HERE,
       NewRunnableMethod(
         this,
         &MediaSystemResourceManager::HandleAcquireResult,
         aId,
         aSuccess));
     return;
   }
 
--- a/dom/media/systemservices/MediaUtils.h
+++ b/dom/media/systemservices/MediaUtils.h
@@ -195,41 +195,46 @@ private:
   Run()
   {
     return mOnRun();
   }
   OnRunType mOnRun;
 };
 
 template<typename OnRunType>
-LambdaRunnable<OnRunType>*
+already_AddRefed<LambdaRunnable<OnRunType>>
 NewRunnableFrom(OnRunType&& aOnRun)
 {
-  return new LambdaRunnable<OnRunType>(Forward<OnRunType>(aOnRun));
+  typedef LambdaRunnable<OnRunType> LambdaType;
+  RefPtr<LambdaType> lambda = new LambdaType(Forward<OnRunType>(aOnRun));
+  return lambda.forget();
 }
 
 template<typename OnRunType>
-class LambdaTask : public Task
+class LambdaTask : public Runnable
 {
 public:
   explicit LambdaTask(OnRunType&& aOnRun) : mOnRun(Move(aOnRun)) {}
 private:
-  void
-  Run()
+  NS_IMETHOD
+  Run() override
   {
-    return mOnRun();
+    mOnRun();
+    return NS_OK;
   }
   OnRunType mOnRun;
 };
 
 template<typename OnRunType>
-LambdaTask<OnRunType>*
+already_AddRefed<LambdaTask<OnRunType>>
 NewTaskFrom(OnRunType&& aOnRun)
 {
-  return new LambdaTask<OnRunType>(Forward<OnRunType>(aOnRun));
+  typedef LambdaTask<OnRunType> LambdaType;
+  RefPtr<LambdaType> lambda = new LambdaType(Forward<OnRunType>(aOnRun));
+  return lambda.forget();
 }
 
 /* media::CoatCheck - There and back again. Park an object in exchange for an id.
  *
  * A common problem with calling asynchronous functions that do work on other
  * threads or processes is how to pass in a heap object for use once the
  * function completes, without requiring that object to have threadsafe
  * refcounting, contain mutexes, be marshaled, or leak if things fail
--- a/dom/media/webaudio/blink/ReverbConvolver.cpp
+++ b/dom/media/webaudio/blink/ReverbConvolver.cpp
@@ -153,18 +153,18 @@ ReverbConvolver::ReverbConvolver(const f
 
     // Start up background thread
     // FIXME: would be better to up the thread priority here.  It doesn't need to be real-time, but higher than the default...
     if (this->useBackgroundThreads() && m_backgroundStages.Length() > 0) {
         if (!m_backgroundThread.Start()) {
           NS_WARNING("Cannot start convolver thread.");
           return;
         }
-        CancelableTask* task = NewRunnableMethod(this, &ReverbConvolver::backgroundThreadEntry);
-        m_backgroundThread.message_loop()->PostTask(FROM_HERE, task);
+        m_backgroundThread.message_loop()->PostTask(
+	  NewRunnableMethod(this, &ReverbConvolver::backgroundThreadEntry));
     }
 }
 
 ReverbConvolver::~ReverbConvolver()
 {
     // Wait for background thread to stop
     if (useBackgroundThreads() && m_backgroundThread.IsRunning()) {
         m_wantsToExit = true;
--- a/dom/plugins/ipc/BrowserStreamChild.cpp
+++ b/dom/plugins/ipc/BrowserStreamChild.cpp
@@ -185,17 +185,17 @@ BrowserStreamChild::NPN_DestroyStream(NP
     SendNPN_DestroyStream(reason);
 
   EnsureDeliveryPending();
 }
 
 void
 BrowserStreamChild::EnsureDeliveryPending()
 {
-  MessageLoop::current()->PostTask(FROM_HERE,
+  MessageLoop::current()->PostTask(
     mDeliveryTracker.NewRunnableMethod(&BrowserStreamChild::Deliver));
 }
 
 void
 BrowserStreamChild::Deliver()
 {
   while (kStreamOpen == mStreamStatus && mPendingData.Length()) {
     if (DeliverPendingData() && kStreamOpen == mStreamStatus) {
--- a/dom/plugins/ipc/ChildAsyncCall.cpp
+++ b/dom/plugins/ipc/ChildAsyncCall.cpp
@@ -14,36 +14,39 @@ namespace plugins {
 ChildAsyncCall::ChildAsyncCall(PluginInstanceChild* instance,
                                PluginThreadCallback aFunc, void* aUserData)
   : mInstance(instance)
   , mFunc(aFunc)
   , mData(aUserData)
 {
 }
 
-void
+nsresult
 ChildAsyncCall::Cancel()
 {
   mInstance = nullptr;
   mFunc = nullptr;
   mData = nullptr;
+  return NS_OK;
 }
 
 void
 ChildAsyncCall::RemoveFromAsyncList()
 {
   if (mInstance) {
     MutexAutoLock lock(mInstance->mAsyncCallMutex);
     mInstance->mPendingAsyncCalls.RemoveElement(this);
   }
 }
 
-void
+NS_IMETHODIMP
 ChildAsyncCall::Run()
 {
   RemoveFromAsyncList();
 
   if (mFunc)
     mFunc(mData);
+
+  return NS_OK;
 }
 
 } // namespace plugins
 } // namespace mozilla
--- a/dom/plugins/ipc/ChildAsyncCall.h
+++ b/dom/plugins/ipc/ChildAsyncCall.h
@@ -4,33 +4,33 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_plugins_ChildAsyncCall_h
 #define mozilla_plugins_ChildAsyncCall_h
 
 #include "PluginMessageUtils.h"
-#include "base/task.h"
+#include "nsThreadUtils.h"
 
 namespace mozilla {
 namespace plugins {
 
 typedef void (*PluginThreadCallback)(void*);
 
 class PluginInstanceChild;
 
-class ChildAsyncCall : public CancelableTask
+class ChildAsyncCall : public CancelableRunnable
 {
 public:
   ChildAsyncCall(PluginInstanceChild* instance,
                  PluginThreadCallback aFunc, void* aUserData);
 
-  void Run() override;
-  void Cancel() override;
+  NS_IMETHOD Run() override;
+  nsresult Cancel() override;
   
 protected:
   PluginInstanceChild* mInstance;
   PluginThreadCallback mFunc;
   void* mData;
 
   void RemoveFromAsyncList();
 };
--- a/dom/plugins/ipc/PluginInstanceChild.cpp
+++ b/dom/plugins/ipc/PluginInstanceChild.cpp
@@ -190,18 +190,16 @@ PluginInstanceChild::PluginInstanceChild
     , mLayersRendering(false)
 #ifdef XP_WIN
     , mCurrentSurfaceActor(nullptr)
     , mBackSurfaceActor(nullptr)
 #endif
     , mAccumulatedInvalidRect(0,0,0,0)
     , mIsTransparent(false)
     , mSurfaceType(gfxSurfaceType::Max)
-    , mCurrentInvalidateTask(nullptr)
-    , mCurrentAsyncSetWindowTask(nullptr)
     , mPendingPluginCall(false)
     , mDoAlphaExtraction(false)
     , mHasPainted(false)
     , mSurfaceDifferenceRect(0,0,0,0)
     , mDestroyed(false)
 #ifdef XP_WIN
     , mLastKeyEventConsumed(false)
 #endif // #ifdef XP_WIN
@@ -2619,48 +2617,50 @@ PluginInstanceChild::FlashThrottleAsyncM
 { 
     if (mInstance) {
         return mWindowed ? mInstance->mPluginWndProc :
                            mInstance->mWinlessThrottleOldWndProc;
     }
     return nullptr;
 }
  
-void
+NS_IMETHODIMP
 PluginInstanceChild::FlashThrottleAsyncMsg::Run()
 {
     RemoveFromAsyncList();
 
     // GetProc() checks mInstance, and pulls the procedure from
     // PluginInstanceChild. We don't transport sub-class procedure
     // ptrs around in FlashThrottleAsyncMsg msgs.
     if (!GetProc())
-        return;
+        return NS_OK;
   
     // deliver the event to flash 
     CallWindowProc(GetProc(), GetWnd(), GetMsg(), GetWParam(), GetLParam());
+    return NS_OK;
 }
 
 void
 PluginInstanceChild::FlashThrottleMessage(HWND aWnd,
                                           UINT aMsg,
                                           WPARAM aWParam,
                                           LPARAM aLParam,
                                           bool isWindowed)
 {
     // We reuse ChildAsyncCall so we get the cancelation work
     // that's done in Destroy.
-    FlashThrottleAsyncMsg* task = new FlashThrottleAsyncMsg(this,
-        aWnd, aMsg, aWParam, aLParam, isWindowed);
+    RefPtr<FlashThrottleAsyncMsg> task =
+        new FlashThrottleAsyncMsg(this, aWnd, aMsg, aWParam,
+                                  aLParam, isWindowed);
     {
         MutexAutoLock lock(mAsyncCallMutex);
         mPendingAsyncCalls.AppendElement(task);
     }
-    MessageLoop::current()->PostDelayedTask(FROM_HERE,
-        task, kFlashWMUSERMessageThrottleDelayMs);
+    MessageLoop::current()->PostDelayedTask(task.forget(),
+                                            kFlashWMUSERMessageThrottleDelayMs);
 }
 
 #endif // OS_WIN
 
 bool
 PluginInstanceChild::AnswerSetPluginFocus()
 {
     MOZ_LOG(GetPluginLog(), LogLevel::Debug, ("%s", FULLFUNCTION));
@@ -2792,44 +2792,45 @@ public:
                        const bool aSeekable)
         : ChildAsyncCall(aInstance, nullptr, nullptr)
         , mBrowserStreamChild(aBrowserStreamChild)
         , mMimeType(aMimeType)
         , mSeekable(aSeekable)
     {
     }
 
-    void Run() override
+    NS_IMETHOD Run() override
     {
         RemoveFromAsyncList();
 
         uint16_t stype = NP_NORMAL;
         NPError rv = mInstance->DoNPP_NewStream(mBrowserStreamChild, mMimeType,
                                                 mSeekable, &stype);
         DebugOnly<bool> sendOk =
             mBrowserStreamChild->SendAsyncNPP_NewStreamResult(rv, stype);
         MOZ_ASSERT(sendOk);
+        return NS_OK;
     }
 
 private:
     BrowserStreamChild* mBrowserStreamChild;
     const nsCString     mMimeType;
     const bool          mSeekable;
 };
 
 bool
 PluginInstanceChild::RecvAsyncNPP_NewStream(PBrowserStreamChild* actor,
                                             const nsCString& mimeType,
                                             const bool& seekable)
 {
     // Reusing ChildAsyncCall so that the task is cancelled properly on Destroy
     BrowserStreamChild* child = static_cast<BrowserStreamChild*>(actor);
-    NewStreamAsyncCall* task = new NewStreamAsyncCall(this, child, mimeType,
-                                                      seekable);
-    PostChildAsyncCall(task);
+    RefPtr<NewStreamAsyncCall> task =
+        new NewStreamAsyncCall(this, child, mimeType, seekable);
+    PostChildAsyncCall(task.forget());
     return true;
 }
 
 PBrowserStreamChild*
 PluginInstanceChild::AllocPBrowserStreamChild(const nsCString& url,
                                               const uint32_t& length,
                                               const uint32_t& lastmodified,
                                               PStreamNotifyChild* notifyData,
@@ -3298,17 +3299,18 @@ PluginInstanceChild::RecvAsyncSetWindow(
     // RPC call, and both Flash and Java don't expect to receive setwindow calls
     // at arbitrary times.
     mCurrentAsyncSetWindowTask =
         NewRunnableMethod<PluginInstanceChild,
                           void (PluginInstanceChild::*)(const gfxSurfaceType&, const NPRemoteWindow&, bool),
                           const gfxSurfaceType&, const NPRemoteWindow&, bool>
         (this, &PluginInstanceChild::DoAsyncSetWindow,
          aSurfaceType, aWindow, true);
-    MessageLoop::current()->PostTask(FROM_HERE, mCurrentAsyncSetWindowTask);
+    RefPtr<Runnable> addrefedTask = mCurrentAsyncSetWindowTask;
+    MessageLoop::current()->PostTask(addrefedTask.forget());
 
     return true;
 }
 
 void
 PluginInstanceChild::DoAsyncSetWindow(const gfxSurfaceType& aSurfaceType,
                                       const NPRemoteWindow& aWindow,
                                       bool aIsAsync)
@@ -4217,17 +4219,18 @@ PluginInstanceChild::AsyncShowPluginFram
     // paints via paint events - it will drive painting via its own events
     // and/or DidComposite callbacks.
     if (IsUsingDirectDrawing()) {
         return;
     }
 
     mCurrentInvalidateTask =
         NewRunnableMethod(this, &PluginInstanceChild::InvalidateRectDelayed);
-    MessageLoop::current()->PostTask(FROM_HERE, mCurrentInvalidateTask);
+    RefPtr<Runnable> addrefedTask = mCurrentInvalidateTask;
+    MessageLoop::current()->PostTask(addrefedTask.forget());
 }
 
 void
 PluginInstanceChild::InvalidateRect(NPRect* aInvalidRect)
 {
     NS_ASSERTION(aInvalidRect, "Null pointer!");
 
 #ifdef OS_WIN
@@ -4373,28 +4376,30 @@ PluginInstanceChild::UnscheduleTimer(uin
         return;
 
     mTimers.RemoveElement(id, ChildTimer::IDComparator());
 }
 
 void
 PluginInstanceChild::AsyncCall(PluginThreadCallback aFunc, void* aUserData)
 {
-    ChildAsyncCall* task = new ChildAsyncCall(this, aFunc, aUserData);
-    PostChildAsyncCall(task);
+    RefPtr<ChildAsyncCall> task = new ChildAsyncCall(this, aFunc, aUserData);
+    PostChildAsyncCall(task.forget());
 }
 
 void
-PluginInstanceChild::PostChildAsyncCall(ChildAsyncCall* aTask)
+PluginInstanceChild::PostChildAsyncCall(already_AddRefed<ChildAsyncCall> aTask)
 {
+    RefPtr<ChildAsyncCall> task = aTask;
+
     {
         MutexAutoLock lock(mAsyncCallMutex);
-        mPendingAsyncCalls.AppendElement(aTask);
-    }
-    ProcessChild::message_loop()->PostTask(FROM_HERE, aTask);
+        mPendingAsyncCalls.AppendElement(task);
+    }
+    ProcessChild::message_loop()->PostTask(task.forget());
 }
 
 void
 PluginInstanceChild::SwapSurfaces()
 {
     RefPtr<gfxASurface> tmpsurf = mCurrentSurface;
 #ifdef XP_WIN
     PPluginSurfaceChild* tmpactor = mCurrentSurfaceActor;
--- a/dom/plugins/ipc/PluginInstanceChild.h
+++ b/dom/plugins/ipc/PluginInstanceChild.h
@@ -254,17 +254,17 @@ public:
     void Invalidate();
 #endif // definied(MOZ_WIDGET_COCOA)
 
     uint32_t ScheduleTimer(uint32_t interval, bool repeat, TimerFunc func);
     void UnscheduleTimer(uint32_t id);
 
     void AsyncCall(PluginThreadCallback aFunc, void* aUserData);
     // This function is a more general version of AsyncCall
-    void PostChildAsyncCall(ChildAsyncCall* aTask);
+    void PostChildAsyncCall(already_AddRefed<ChildAsyncCall> aTask);
 
     int GetQuirks();
 
     void NPN_URLRedirectResponse(void* notifyData, NPBool allow);
 
 
     NPError NPN_InitAsyncSurface(NPSize *size, NPImageFormat format,
                                  void *initData, NPAsyncSurface *surface);
@@ -379,17 +379,17 @@ private:
           : ChildAsyncCall(aInst, nullptr, nullptr),
           mWnd(aWnd),
           mMsg(aMsg),
           mWParam(aWParam),
           mLParam(aLParam),
           mWindowed(isWindowed)
         {}
 
-        void Run() override;
+        NS_IMETHOD Run() override;
 
         WNDPROC GetProc();
         HWND GetWnd() { return mWnd; }
         UINT GetMsg() { return mMsg; }
         WPARAM GetWParam() { return mWParam; }
         LPARAM GetLParam() { return mLParam; }
 
       private:
@@ -441,17 +441,17 @@ private:
     };
     nsRefPtrHashtable<nsPtrHashKey<NPAsyncSurface>, DirectBitmap> mDirectBitmaps;
 
 #if defined(XP_WIN)
     nsDataHashtable<nsPtrHashKey<NPAsyncSurface>, WindowsHandle> mDxgiSurfaces;
 #endif
 
     mozilla::Mutex mAsyncInvalidateMutex;
-    CancelableTask *mAsyncInvalidateTask;
+    CancelableRunnable *mAsyncInvalidateTask;
 
     // Cached scriptable actors to avoid IPC churn
     PluginScriptableObjectChild* mCachedWindowActor;
     PluginScriptableObjectChild* mCachedElementActor;
 
 #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
     NPSetWindowCallbackStruct mWsInfo;
 #ifdef MOZ_WIDGET_GTK
@@ -632,20 +632,20 @@ private:
     // and does not remember their transparent state
     // and p->getvalue return always false
     bool mIsTransparent;
 
     // Surface type optimized of parent process
     gfxSurfaceType mSurfaceType;
 
     // Keep InvalidateRect task pointer to be able Cancel it on Destroy
-    CancelableTask *mCurrentInvalidateTask;
+    RefPtr<CancelableRunnable> mCurrentInvalidateTask;
 
     // Keep AsyncSetWindow task pointer to be able to Cancel it on Destroy
-    CancelableTask *mCurrentAsyncSetWindowTask;
+    RefPtr<CancelableRunnable> mCurrentAsyncSetWindowTask;
 
     // True while plugin-child in plugin call
     // Use to prevent plugin paint re-enter
     bool mPendingPluginCall;
 
     // On some platforms, plugins may not support rendering to a surface with
     // alpha, or not support rendering to an image surface.
     // In those cases we need to draw to a temporary platform surface; we cache
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -146,17 +146,16 @@ PluginInstanceParent::PluginInstancePare
     , mNestedEventState(false)
 #endif // defined(XP_WIN)
 #if defined(XP_MACOSX)
     , mShWidth(0)
     , mShHeight(0)
     , mShColorSpace(nullptr)
 #endif
 #if defined(XP_WIN)
-    , mCaptureRefreshTask(nullptr)
     , mValidFirstCapture(false)
     , mIsScrolling(false)
 #endif
 {
 #if defined(OS_WIN)
     if (!sPluginInstanceList) {
         sPluginInstanceList = new nsClassHashtable<nsVoidPtrHashKey, PluginInstanceParent>();
     }
@@ -1220,17 +1219,18 @@ void
 PluginInstanceParent::ScheduleScrollCapture(int aTimeout)
 {
     if (mCaptureRefreshTask) {
         return;
     }
     CAPTURE_LOG("delayed scroll capture requested.");
     mCaptureRefreshTask =
         NewRunnableMethod(this, &PluginInstanceParent::ScheduledUpdateScrollCaptureCallback);
-    MessageLoop::current()->PostDelayedTask(FROM_HERE, mCaptureRefreshTask,
+    RefPtr<Runnable> addrefedTask = mCaptureRefreshTask;
+    MessageLoop::current()->PostDelayedTask(addrefedTask.forget(),
                                             kScrollCaptureDelayMs);
 }
 
 void
 PluginInstanceParent::ScheduledUpdateScrollCaptureCallback()
 {
     CAPTURE_LOG("taking delayed scrollcapture.");
     mCaptureRefreshTask = nullptr;
--- a/dom/plugins/ipc/PluginInstanceParent.h
+++ b/dom/plugins/ipc/PluginInstanceParent.h
@@ -469,17 +469,17 @@ private:
 
 #if defined(XP_WIN)
     void ScheduleScrollCapture(int aTimeout);
     void ScheduledUpdateScrollCaptureCallback();
     bool UpdateScrollCapture(bool& aRequestNewCapture);
     void CancelScheduledScrollCapture();
 
     RefPtr<gfxASurface> mScrollCapture;
-    CancelableTask* mCaptureRefreshTask;
+    RefPtr<CancelableRunnable> mCaptureRefreshTask;
     bool mValidFirstCapture;
     bool mIsScrolling;
 #endif
 };
 
 
 } // namespace plugins
 } // namespace mozilla
--- a/dom/plugins/ipc/PluginModuleChild.cpp
+++ b/dom/plugins/ipc/PluginModuleChild.cpp
@@ -161,17 +161,18 @@ PluginModuleChild::PluginModuleChild(boo
 
 PluginModuleChild::~PluginModuleChild()
 {
     if (mTransport) {
         // For some reason IPDL doesn't automatically delete the channel for a
         // bridged protocol (bug 1090570). So we have to do it ourselves. This
         // code is only invoked for PluginModuleChild instances created via
         // bridging; otherwise mTransport is null.
-        XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new DeleteTask<Transport>(mTransport));
+        RefPtr<DeleteTask<Transport>> task = new DeleteTask<Transport>(mTransport);
+        XRE_GetIOMessageLoop()->PostTask(task.forget());
     }
 
     if (mIsChrome) {
         MOZ_ASSERT(gChromeInstance == this);
 
         // We don't unload the plugin library in case it uses atexit handlers or
         // other similar hooks.
 
@@ -826,17 +827,19 @@ PluginModuleChild::ActorDestroy(ActorDes
 {
     if (!mIsChrome) {
         PluginModuleChild* chromeInstance = PluginModuleChild::GetChrome();
         if (chromeInstance) {
             chromeInstance->SendNotifyContentModuleDestroyed();
         }
 
         // Destroy ourselves once we finish other teardown activities.
-        MessageLoop::current()->PostTask(FROM_HERE, new DeleteTask<PluginModuleChild>(this));
+        RefPtr<DeleteTask<PluginModuleChild>> task =
+            new DeleteTask<PluginModuleChild>(this);
+        MessageLoop::current()->PostTask(task.forget());
         return;
     }
 
     if (AbnormalShutdown == why) {
         NS_WARNING("shutting down early because of crash!");
         ProcessChild::QuickExit();
     }
 
@@ -2201,36 +2204,38 @@ class AsyncNewResultSender : public Chil
 {
 public:
     AsyncNewResultSender(PluginInstanceChild* aInstance, NPError aResult)
         : ChildAsyncCall(aInstance, nullptr, nullptr)
         , mResult(aResult)
     {
     }
 
-    void Run() override
+    NS_IMETHOD Run() override
     {
         RemoveFromAsyncList();
         DebugOnly<bool> sendOk = mInstance->SendAsyncNPP_NewResult(mResult);
         MOZ_ASSERT(sendOk);
+        return NS_OK;
     }
 
 private:
     NPError  mResult;
 };
 
 static void
 RunAsyncNPP_New(void* aChildInstance)
 {
     MOZ_ASSERT(aChildInstance);
     PluginInstanceChild* childInstance =
         static_cast<PluginInstanceChild*>(aChildInstance);
     NPError rv = childInstance->DoNPP_New();
-    AsyncNewResultSender* task = new AsyncNewResultSender(childInstance, rv);
-    childInstance->PostChildAsyncCall(task);
+    RefPtr<AsyncNewResultSender> task =
+        new AsyncNewResultSender(childInstance, rv);
+    childInstance->PostChildAsyncCall(task.forget());
 }
 
 bool
 PluginModuleChild::RecvAsyncNPP_New(PPluginInstanceChild* aActor)
 {
     PLUGIN_LOG_DEBUG_METHOD;
     PluginInstanceChild* childInstance =
         reinterpret_cast<PluginInstanceChild*>(aActor);
--- a/dom/plugins/ipc/PluginModuleParent.cpp
+++ b/dom/plugins/ipc/PluginModuleParent.cpp
@@ -145,17 +145,17 @@ mozilla::plugins::SetupBridge(uint32_t a
     return true;
 }
 
 #ifdef MOZ_CRASHREPORTER_INJECTOR
 
 /**
  * Use for executing CreateToolhelp32Snapshot off main thread
  */
-class mozilla::plugins::FinishInjectorInitTask : public CancelableTask
+class mozilla::plugins::FinishInjectorInitTask : public mozilla::CancelableRunnable
 {
 public:
     FinishInjectorInitTask()
         : mMutex("FlashInjectorInitTask::mMutex")
         , mParent(nullptr)
         , mMainThreadMsgLoop(MessageLoop::current())
     {
         MOZ_ASSERT(NS_IsMainThread());
@@ -164,44 +164,41 @@ public:
     void Init(PluginModuleChromeParent* aParent)
     {
         MOZ_ASSERT(aParent);
         mParent = aParent;
     }
 
     void PostToMainThread()
     {
+        RefPtr<Runnable> self = this;
         mSnapshot.own(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0));
-        bool deleteThis = false;
         {   // Scope for lock
             mozilla::MutexAutoLock lock(mMutex);
             if (mMainThreadMsgLoop) {
-                mMainThreadMsgLoop->PostTask(FROM_HERE, this);
-            } else {
-                deleteThis = true;
+                mMainThreadMsgLoop->PostTask(self.forget());
             }
         }
-        if (deleteThis) {
-            delete this;
-        }
     }
 
-    void Run() override
+    NS_IMETHOD Run() override
     {
         mParent->DoInjection(mSnapshot);
         // We don't need to hold this lock during DoInjection, but we do need
         // to obtain it before returning from Run() to ensure that
         // PostToMainThread has completed before we return.
         mozilla::MutexAutoLock lock(mMutex);
+        return NS_OK;
     }
 
-    void Cancel() override
+    nsresult Cancel() override
     {
         mozilla::MutexAutoLock lock(mMutex);
         mMainThreadMsgLoop = nullptr;
+        return NS_OK;
     }
 
 private:
     mozilla::Mutex            mMutex;
     nsAutoHandle              mSnapshot;
     PluginModuleChromeParent* mParent;
     MessageLoop*              mMainThreadMsgLoop;
 };
@@ -705,18 +702,19 @@ PluginModuleParent::~PluginModuleParent(
 PluginModuleContentParent::PluginModuleContentParent(bool aAllowAsyncInit)
     : PluginModuleParent(false, aAllowAsyncInit)
 {
     Preferences::RegisterCallback(TimeoutChanged, kContentTimeoutPref, this);
 }
 
 PluginModuleContentParent::~PluginModuleContentParent()
 {
-    XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
-                                     new DeleteTask<Transport>(GetTransport()));
+    RefPtr<DeleteTask<Transport>> task = new DeleteTask<Transport>(GetTransport());
+    XRE_GetIOMessageLoop()->PostTask(task.forget());
+                                     
 
     Preferences::UnregisterCallback(TimeoutChanged, kContentTimeoutPref, this);
 }
 
 bool PluginModuleChromeParent::sInstantiated = false;
 
 PluginModuleChromeParent::PluginModuleChromeParent(const char* aFilePath,
                                                    uint32_t aPluginId,
@@ -901,17 +899,16 @@ PluginModuleChromeParent::CleanupFromTim
 {
     if (mShutdown) {
       return;
     }
 
     if (!OkToCleanup()) {
         // there's still plugin code on the C++ stack, try again
         MessageLoop::current()->PostDelayedTask(
-            FROM_HERE,
             mChromeTaskFactory.NewRunnableMethod(
                 &PluginModuleChromeParent::CleanupFromTimeout, aFromHangUI), 10);
         return;
     }
 
     /* If the plugin container was terminated by the Plugin Hang UI, 
        then either the I/O thread detects a channel error, or the 
        main thread must set the error (whomever gets there first).
@@ -1166,17 +1163,16 @@ CreatePluginMinidump(base::ProcessId pro
 }
 #endif
 
 bool
 PluginModuleChromeParent::ShouldContinueFromReplyTimeout()
 {
     if (mIsFlashPlugin) {
         MessageLoop::current()->PostTask(
-            FROM_HERE,
             mTaskFactory.NewRunnableMethod(
                 &PluginModuleChromeParent::NotifyFlashHang));
     }
 
 #ifdef XP_WIN
     if (LaunchHangUI()) {
         return true;
     }
@@ -1344,17 +1340,16 @@ PluginModuleChromeParent::TerminateChild
       mPluginCpuUsageOnHang.Clear();
     }
 #endif
 
     // this must run before the error notification from the channel,
     // or not at all
     bool isFromHangUI = aMsgLoop != MessageLoop::current();
     aMsgLoop->PostTask(
-        FROM_HERE,
         mChromeTaskFactory.NewRunnableMethod(
             &PluginModuleChromeParent::CleanupFromTimeout, isFromHangUI));
 
     if (!childOpened || !KillProcess(geckoChildProcess, 1, false)) {
         NS_WARNING("failed to kill subprocess!");
     }
 }
 
@@ -1594,17 +1589,16 @@ PluginModuleParent::ActorDestroy(ActorDe
 {
     switch (why) {
     case AbnormalShutdown: {
         mShutdown = true;
         // Defer the PluginCrashed method so that we don't re-enter
         // and potentially modify the actor child list while enumerating it.
         if (mPlugin)
             MessageLoop::current()->PostTask(
-                FROM_HERE,
                 mTaskFactory.NewRunnableMethod(
                     &PluginModuleParent::NotifyPluginCrashed));
         break;
     }
     case NormalShutdown:
         mShutdown = true;
         break;
 
@@ -1650,17 +1644,16 @@ PluginModuleParent::NotifyFlashHang()
 }
 
 void
 PluginModuleParent::NotifyPluginCrashed()
 {
     if (!OkToCleanup()) {
         // there's still plugin code on the C++ stack.  try again
         MessageLoop::current()->PostDelayedTask(
-            FROM_HERE,
             mTaskFactory.NewRunnableMethod(
                 &PluginModuleParent::NotifyPluginCrashed), 10);
         return;
     }
 
     if (mPlugin)
         mPlugin->PluginCrashed(mPluginDumpID, mBrowserDumpID);
 }
@@ -3151,17 +3144,16 @@ PluginModuleChromeParent::InitializeInje
                           NS_LITERAL_CSTRING(FLASH_PLUGIN_PREFIX)))
         return;
 
     TimeStamp th32Start = TimeStamp::Now();
     mFinishInitTask = mChromeTaskFactory.NewTask<FinishInjectorInitTask>();
     mFinishInitTask->Init(this);
     if (!::QueueUserWorkItem(&PluginModuleChromeParent::GetToolhelpSnapshot,
                              mFinishInitTask, WT_EXECUTEDEFAULT)) {
-        delete mFinishInitTask;
         mFinishInitTask = nullptr;
         return;
     }
     TimeStamp th32End = TimeStamp::Now();
     mTimeBlocked += (th32End - th32Start);
 }
 
 void
--- a/dom/plugins/ipc/PluginModuleParent.h
+++ b/dom/plugins/ipc/PluginModuleParent.h
@@ -603,33 +603,34 @@ private:
     void InitializeInjector();
     void DoInjection(const nsAutoHandle& aSnapshot);
     static DWORD WINAPI GetToolhelpSnapshot(LPVOID aContext);
 
     void OnCrash(DWORD processID) override;
 
     DWORD mFlashProcess1;
     DWORD mFlashProcess2;
-    mozilla::plugins::FinishInjectorInitTask* mFinishInitTask;
+    RefPtr<mozilla::plugins::FinishInjectorInitTask> mFinishInitTask;
 #endif
 
     void OnProcessLaunched(const bool aSucceeded);
 
     class LaunchedTask : public LaunchCompleteTask
     {
     public:
         explicit LaunchedTask(PluginModuleChromeParent* aModule)
             : mModule(aModule)
         {
             MOZ_ASSERT(aModule);
         }
 
-        void Run() override
+        NS_IMETHOD Run() override
         {
             mModule->OnProcessLaunched(mLaunchSucceeded);
+            return NS_OK;
         }
 
     private:
         PluginModuleChromeParent* mModule;
     };
 
     friend class LaunchedTask;
 
--- a/dom/plugins/ipc/PluginProcessParent.cpp
+++ b/dom/plugins/ipc/PluginProcessParent.cpp
@@ -197,18 +197,17 @@ PluginProcessParent::Delete()
   MessageLoop* currentLoop = MessageLoop::current();
   MessageLoop* ioLoop = XRE_GetIOMessageLoop();
 
   if (currentLoop == ioLoop) {
       delete this;
       return;
   }
 
-  ioLoop->PostTask(FROM_HERE,
-                   NewRunnableMethod(this, &PluginProcessParent::Delete));
+  ioLoop->PostTask(NewRunnableMethod(this, &PluginProcessParent::Delete));
 }
 
 void
 PluginProcessParent::SetCallRunnableImmediately(bool aCallImmediately)
 {
     mRunCompleteTaskImmediately = aCallImmediately;
 }
 
@@ -242,27 +241,27 @@ PluginProcessParent::WaitUntilConnected(
 }
 
 void
 PluginProcessParent::OnChannelConnected(int32_t peer_pid)
 {
     GeckoChildProcessHost::OnChannelConnected(peer_pid);
     if (mLaunchCompleteTask && !mRunCompleteTaskImmediately) {
         mLaunchCompleteTask->SetLaunchSucceeded();
-        mMainMsgLoop->PostTask(FROM_HERE, mTaskFactory.NewRunnableMethod(
+        mMainMsgLoop->PostTask(mTaskFactory.NewRunnableMethod(
                                    &PluginProcessParent::RunLaunchCompleteTask));
     }
 }
 
 void
 PluginProcessParent::OnChannelError()
 {
     GeckoChildProcessHost::OnChannelError();
     if (mLaunchCompleteTask && !mRunCompleteTaskImmediately) {
-        mMainMsgLoop->PostTask(FROM_HERE, mTaskFactory.NewRunnableMethod(
+        mMainMsgLoop->PostTask(mTaskFactory.NewRunnableMethod(
                                    &PluginProcessParent::RunLaunchCompleteTask));
     }
 }
 
 bool
 PluginProcessParent::IsConnected()
 {
     mozilla::MonitorAutoLock lock(mMonitor);
--- a/dom/plugins/ipc/PluginProcessParent.h
+++ b/dom/plugins/ipc/PluginProcessParent.h
@@ -20,17 +20,17 @@
 #include "mozilla/plugins/TaskFactory.h"
 #include "mozilla/UniquePtr.h"
 #include "nsCOMPtr.h"
 #include "nsIRunnable.h"
 
 namespace mozilla {
 namespace plugins {
 
-class LaunchCompleteTask : public Task
+class LaunchCompleteTask : public Runnable
 {
 public:
     LaunchCompleteTask()
         : mLaunchSucceeded(false)
     {
     }
 
     void SetLaunchSucceeded() { mLaunchSucceeded = true; }
--- a/dom/plugins/ipc/TaskFactory.h
+++ b/dom/plugins/ipc/TaskFactory.h
@@ -31,67 +31,72 @@ private:
   public:
     template<typename... Args>
     explicit TaskWrapper(RevocableStore* store, Args&&... args)
       : TaskType(mozilla::Forward<Args>(args)...)
       , revocable_(store)
     {
     }
 
-    virtual void Run() {
+    NS_IMETHOD Run() override {
       if (!revocable_.revoked())
         TaskType::Run();
+      return NS_OK;
     }
 
   private:
     Revocable revocable_;
   };
 
 public:
   explicit TaskFactory(T* object) : object_(object) { }
 
   template <typename TaskParamType, typename... Args>
-  inline TaskParamType* NewTask(Args&&... args)
+  inline already_AddRefed<TaskParamType> NewTask(Args&&... args)
   {
     typedef TaskWrapper<TaskParamType> TaskWrapper;
-    TaskWrapper* task = new TaskWrapper(this, mozilla::Forward<Args>(args)...);
-    return task;
+    RefPtr<TaskWrapper> task =
+      new TaskWrapper(this, mozilla::Forward<Args>(args)...);
+    return task.forget();
   }
 
   template <class Method>
-  inline Task* NewRunnableMethod(Method method) {
+  inline already_AddRefed<Runnable> NewRunnableMethod(Method method) {
     typedef TaskWrapper<RunnableMethod<Method, Tuple0> > TaskWrapper;
 
-    TaskWrapper* task = new TaskWrapper(this);
+    RefPtr<TaskWrapper> task = new TaskWrapper(this);
     task->Init(object_, method, base::MakeTuple());
-    return task;
+    return task.forget();
   }
 
   template <class Method, class A>
-  inline Task* NewRunnableMethod(Method method, const A& a) {
+  inline already_AddRefed<Runnable> NewRunnableMethod(Method method, const A& a) {
     typedef TaskWrapper<RunnableMethod<Method, Tuple1<A> > > TaskWrapper;
 
-    TaskWrapper* task = new TaskWrapper(this);
+    RefPtr<TaskWrapper> task = new TaskWrapper(this);
     task->Init(object_, method, base::MakeTuple(a));
-    return task;
+    return task.forget();
   }
 
 protected:
   template <class Method, class Params>
-  class RunnableMethod : public Task {
+  class RunnableMethod : public Runnable {
    public:
     RunnableMethod() { }
 
     void Init(T* obj, Method meth, const Params& params) {
       obj_ = obj;
       meth_ = meth;
       params_ = params;
     }
 
-    virtual void Run() { DispatchToMethod(obj_, meth_, params_); }
+    NS_IMETHOD Run() override {
+      DispatchToMethod(obj_, meth_, params_);
+      return NS_OK;
+    }
 
    private:
     T* obj_;
     Method meth_;
     Params params_;
   };
 
 private:
--- a/gfx/layers/AtomicRefCountedWithFinalize.h
+++ b/gfx/layers/AtomicRefCountedWithFinalize.h
@@ -146,17 +146,16 @@ private:
         derived->Finalize();
         if (MOZ_LIKELY(!mMessageLoopToPostDestructionTo)) {
           delete derived;
         } else {
           if (MOZ_LIKELY(NS_IsMainThread())) {
             delete derived;
           } else {
             mMessageLoopToPostDestructionTo->PostTask(
-              FROM_HERE,
               NewRunnableFunction(&DestroyToBeCalledOnMainThread, derived));
           }
         }
       } else if (1 == currCount && recycleCallback) {
         // There is nothing enforcing this in the code, except how the callers
         // are being careful to never let the reference count go down if there
         // is a callback.
         MOZ_ASSERT(!IsDead());
--- a/gfx/layers/apz/public/GeckoContentController.h
+++ b/gfx/layers/apz/public/GeckoContentController.h
@@ -9,19 +9,20 @@
 
 #include "FrameMetrics.h"               // for FrameMetrics, etc
 #include "Units.h"                      // for CSSPoint, CSSRect, etc
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT_HELPER2
 #include "mozilla/EventForwards.h"      // for Modifiers
 #include "nsISupportsImpl.h"
 #include "ThreadSafeRefcountingWithMainThreadDestruction.h"
 
-class Task;
+namespace mozilla {
 
-namespace mozilla {
+class Runnable;
+
 namespace layers {
 
 class GeckoContentController
 {
 public:
   /**
    * At least one class deriving from GeckoContentController needs to do
    * synchronous cleanup on the main thread, so we use
@@ -64,17 +65,17 @@ public:
                              const ScrollableLayerGuid& aGuid,
                              uint64_t aInputBlockId) = 0;
 
   /**
    * Schedules a runnable to run on the controller/UI thread at some time
    * in the future.
    * This method must always be called on the controller thread.
    */
-  virtual void PostDelayedTask(Task* aTask, int aDelayMs) = 0;
+  virtual void PostDelayedTask(already_AddRefed<Runnable> aRunnable, int aDelayMs) = 0;
 
   /**
    * APZ uses |FrameMetrics::mCompositionBounds| for hit testing. Sometimes,
    * widget code has knowledge of a touch-sensitive region that should
    * additionally constrain hit testing for all frames associated with the
    * controller. This method allows APZ to query the controller for such a
    * region. A return value of true indicates that the controller has such a
    * region, and it is returned in |aOutRegion|.
--- a/gfx/layers/apz/src/AsyncPanZoomAnimation.h
+++ b/gfx/layers/apz/src/AsyncPanZoomAnimation.h
@@ -41,17 +41,17 @@ public:
 
     return DoSample(aFrameMetrics, aDelta);
   }
 
   /**
    * Get the deferred tasks in |mDeferredTasks| and place them in |aTasks|. See
    * |mDeferredTasks| for more information.  Clears |mDeferredTasks|.
    */
-  nsTArray<Task*> TakeDeferredTasks() {
+  nsTArray<RefPtr<Runnable>> TakeDeferredTasks() {
     return Move(mDeferredTasks);
   }
 
   virtual WheelScrollAnimation* AsWheelScrollAnimation() {
     return nullptr;
   }
   virtual SmoothScrollAnimation* AsSmoothScrollAnimation() {
     return nullptr;
@@ -66,15 +66,15 @@ protected:
   virtual ~AsyncPanZoomAnimation()
   { }
 
   /**
    * Tasks scheduled for execution after the APZC's mMonitor is released.
    * Derived classes can add tasks here in Sample(), and the APZC can call
    * ExecuteDeferredTasks() to execute them.
    */
-  nsTArray<Task*> mDeferredTasks;
+  nsTArray<RefPtr<Runnable>> mDeferredTasks;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif // mozilla_layers_AsyncPanZoomAnimation_h_
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -18,17 +18,16 @@
 #include "InputData.h"                  // for MultiTouchInput, etc
 #include "InputBlockState.h"            // for InputBlockState, TouchBlockState
 #include "InputQueue.h"                 // for InputQueue
 #include "OverscrollHandoffState.h"     // for OverscrollHandoffState
 #include "Units.h"                      // for CSSRect, CSSPoint, etc
 #include "UnitTransforms.h"             // for TransformTo
 #include "base/message_loop.h"          // for MessageLoop
 #include "base/task.h"                  // for NewRunnableMethod, etc
-#include "base/tracked.h"               // for FROM_HERE
 #include "gfxPrefs.h"                   // for gfxPrefs
 #include "gfxTypes.h"                   // for gfxFloat
 #include "LayersLogging.h"              // for print_stderr
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/BasicEvents.h"        // for Modifiers, MODIFIER_*
 #include "mozilla/ClearOnShutdown.h"    // for ClearOnShutdown
 #include "mozilla/ComputedTimingFunction.h" // for ComputedTimingFunction
 #include "mozilla/EventForwards.h"      // for nsEventStatus_*
@@ -3057,17 +3056,17 @@ AsyncPanZoomController::RequestContentRe
   }
 
   controller->RequestContentRepaint(aFrameMetrics);
   mExpectedGeckoMetrics = aFrameMetrics;
   mLastPaintRequestMetrics = aFrameMetrics;
 }
 
 bool AsyncPanZoomController::UpdateAnimation(const TimeStamp& aSampleTime,
-                                             nsTArray<Task*>* aOutDeferredTasks)
+                                             nsTArray<RefPtr<Runnable>>* aOutDeferredTasks)
 {
   APZThreadUtils::AssertOnCompositorThread();
 
   // This function may get called multiple with the same sample time, because
   // there may be multiple layers with this APZC, and each layer invokes this
   // function during composition. However we only want to do one animation step
   // per composition so we need to deduplicate these calls first.
   if (mLastSampleTime == aSampleTime) {
@@ -3158,17 +3157,17 @@ bool AsyncPanZoomController::AdvanceAnim
 
   // The eventual return value of this function. The compositor needs to know
   // whether or not to advance by a frame as soon as it can. For example, if a
   // fling is happening, it has to keep compositing so that the animation is
   // smooth. If an animation frame is requested, it is the compositor's
   // responsibility to schedule a composite.
   mAsyncTransformAppliedToContent = false;
   bool requestAnimationFrame = false;
-  nsTArray<Task*> deferredTasks;
+  nsTArray<RefPtr<Runnable>> deferredTasks;
 
   {
     ReentrantMonitorAutoEnter lock(mMonitor);
 
     requestAnimationFrame = UpdateAnimation(aSampleTime, &deferredTasks);
 
     { // scope lock
       MutexAutoLock lock(mCheckerboardEventLock);
@@ -3182,17 +3181,17 @@ bool AsyncPanZoomController::AdvanceAnim
   }
 
   // Execute any deferred tasks queued up by mAnimation's Sample() (called by
   // UpdateAnimation()). This needs to be done after the monitor is released
   // since the tasks are allowed to call APZCTreeManager methods which can grab
   // the tree lock.
   for (uint32_t i = 0; i < deferredTasks.Length(); ++i) {
     deferredTasks[i]->Run();
-    delete deferredTasks[i];
+    deferredTasks[i] = nullptr;
   }
 
   // One of the deferred tasks may have started a new animation. In this case,
   // we want to ask the compositor to schedule a new composite.
   requestAnimationFrame |= (mAnimation != nullptr);
 
   return requestAnimationFrame;
 }
@@ -3847,22 +3846,23 @@ void AsyncPanZoomController::UpdateZoomC
 
 ZoomConstraints
 AsyncPanZoomController::GetZoomConstraints() const
 {
   return mZoomConstraints;
 }
 
 
-void AsyncPanZoomController::PostDelayedTask(Task* aTask, int aDelayMs) {
+void AsyncPanZoomController::PostDelayedTask(already_AddRefed<Runnable> aTask, int aDelayMs) {
   APZThreadUtils::AssertOnControllerThread();
   RefPtr<GeckoContentController> controller = GetGeckoContentController();
   if (controller) {
-    controller->PostDelayedTask(aTask, aDelayMs);
+    controller->PostDelayedTask(Move(aTask), aDelayMs);
   }
+  // XXX khuey what is supposed to happen if there's no controller? We were leaking tasks ...
 }
 
 bool AsyncPanZoomController::Matches(const ScrollableLayerGuid& aGuid)
 {
   return aGuid == GetGuid();
 }
 
 bool AsyncPanZoomController::HasTreeManager(const APZCTreeManager* aTreeManager) const
--- a/gfx/layers/apz/src/AsyncPanZoomController.h
+++ b/gfx/layers/apz/src/AsyncPanZoomController.h
@@ -141,33 +141,33 @@ public:
    * or in UpdateZoomConstraints()).
    */
   ZoomConstraints GetZoomConstraints() const;
 
   /**
    * Schedules a runnable to run on the controller/UI thread at some time
    * in the future.
    */
-  void PostDelayedTask(Task* aTask, int aDelayMs);
+  void PostDelayedTask(already_AddRefed<Runnable> aTask, int aDelayMs);
 
   // --------------------------------------------------------------------------
   // These methods must only be called on the compositor thread.
   //
 
   /**
    * Advances any animations currently running to the given timestamp.
    * This may be called multiple times with the same timestamp.
    *
    * The return value indicates whether or not any currently running animation
    * should continue. If true, the compositor should schedule another composite.
    */
   bool AdvanceAnimations(const TimeStamp& aSampleTime);
 
   bool UpdateAnimation(const TimeStamp& aSampleTime,
-                       nsTArray<Task*>* aOutDeferredTasks);
+                       nsTArray<RefPtr<Runnable>>* aOutDeferredTasks);
 
   /**
    * A shadow layer update has arrived. |aScrollMetdata| is the new ScrollMetadata
    * for the container layer corresponding to this APZC.
    * |aIsFirstPaint| is a flag passed from the shadow
    * layers code indicating that the scroll metadata being sent with this call are
    * the initial metadata and the initial paint of the frame has just happened.
    */
--- a/gfx/layers/apz/src/GestureEventListener.cpp
+++ b/gfx/layers/apz/src/GestureEventListener.cpp
@@ -492,21 +492,22 @@ void GestureEventListener::CancelLongTap
   if (mLongTapTimeoutTask) {
     mLongTapTimeoutTask->Cancel();
     mLongTapTimeoutTask = nullptr;
   }
 }
 
 void GestureEventListener::CreateLongTapTimeoutTask()
 {
-  mLongTapTimeoutTask =
+  RefPtr<CancelableRunnable> task =
     NewRunnableMethod(this, &GestureEventListener::HandleInputTimeoutLongTap);
 
+  mLongTapTimeoutTask = task;
   mAsyncPanZoomController->PostDelayedTask(
-    mLongTapTimeoutTask,
+    task.forget(),
     gfxPrefs::UiClickHoldContextMenusDelay());
 }
 
 void GestureEventListener::CancelMaxTapTimeoutTask()
 {
   if (mState == GESTURE_FIRST_SINGLE_TOUCH_MAX_TAP_DOWN) {
     // being in this state means the timer has just been triggered
     return;
@@ -518,19 +519,20 @@ void GestureEventListener::CancelMaxTapT
   }
 }
 
 void GestureEventListener::CreateMaxTapTimeoutTask()
 {
   mLastTapInput = mLastTouchInput;
 
   TouchBlockState* block = mAsyncPanZoomController->GetInputQueue()->CurrentTouchBlock();
-  mMaxTapTimeoutTask =
+  RefPtr<CancelableRunnable> task =
     NewRunnableMethod(this, &GestureEventListener::HandleInputTimeoutMaxTap,
                       block->IsDuringFastFling());
 
+  mMaxTapTimeoutTask = task;
   mAsyncPanZoomController->PostDelayedTask(
-    mMaxTapTimeoutTask,
+    task.forget(),
     MAX_TAP_TIME);
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/apz/src/GestureEventListener.h
+++ b/gfx/layers/apz/src/GestureEventListener.h
@@ -9,19 +9,20 @@
 
 #include "InputData.h"                  // for MultiTouchInput, etc
 #include "Units.h"
 #include "mozilla/EventForwards.h"      // for nsEventStatus
 #include "mozilla/RefPtr.h"             // for RefPtr
 #include "nsISupportsImpl.h"
 #include "nsTArray.h"                   // for nsTArray
 
-class CancelableTask;
+namespace mozilla {
 
-namespace mozilla {
+class CancelableRunnable;
+
 namespace layers {
 
 class AsyncPanZoomController;
 
 /**
  * Platform-non-specific, generalized gesture event listener. This class
  * intercepts all touches events on their way to AsyncPanZoomController and
  * determines whether or not they are part of a gesture.
@@ -209,30 +210,30 @@ private:
    * we can cancel it if any other touch event happens.
    *
    * The task is supposed to be non-null if in GESTURE_FIRST_SINGLE_TOUCH_DOWN
    * and GESTURE_FIRST_SINGLE_TOUCH_MAX_TAP_DOWN states.
    *
    * CancelLongTapTimeoutTask: Cancel the mLongTapTimeoutTask and also set
    * it to null.
    */
-  CancelableTask *mLongTapTimeoutTask;
+  RefPtr<CancelableRunnable> mLongTapTimeoutTask;
   void CancelLongTapTimeoutTask();
   void CreateLongTapTimeoutTask();
 
   /**
    * Task used to timeout a single tap or a double tap.
    *
    * The task is supposed to be non-null if in GESTURE_FIRST_SINGLE_TOUCH_DOWN,
    * GESTURE_FIRST_SINGLE_TOUCH_UP and GESTURE_SECOND_SINGLE_TOUCH_DOWN states.
    *
    * CancelMaxTapTimeoutTask: Cancel the mMaxTapTimeoutTask and also set
    * it to null.
    */
-  CancelableTask *mMaxTapTimeoutTask;
+  RefPtr<CancelableRunnable> mMaxTapTimeoutTask;
   void CancelMaxTapTimeoutTask();
   void CreateMaxTapTimeoutTask();
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif
--- a/gfx/layers/apz/test/gtest/APZTestCommon.h
+++ b/gfx/layers/apz/test/gtest/APZTestCommon.h
@@ -36,18 +36,16 @@ using namespace mozilla::gfx;
 using namespace mozilla::layers;
 using ::testing::_;
 using ::testing::NiceMock;
 using ::testing::AtLeast;
 using ::testing::AtMost;
 using ::testing::MockFunction;
 using ::testing::InSequence;
 
-class Task;
-
 template<class T>
 class ScopedGfxPref {
 public:
   ScopedGfxPref(T (*aGetPrefFunc)(void), void (*aSetPrefFunc)(T), T aVal)
     : mSetPrefFunc(aSetPrefFunc)
   {
     mOldVal = aGetPrefFunc();
     aSetPrefFunc(aVal);
@@ -76,17 +74,20 @@ static TimeStamp GetStartupTime() {
 class MockContentController : public GeckoContentController {
 public:
   MOCK_METHOD1(RequestContentRepaint, void(const FrameMetrics&));
   MOCK_METHOD2(RequestFlingSnap, void(const FrameMetrics::ViewID& aScrollId, const mozilla::CSSPoint& aDestination));
   MOCK_METHOD2(AcknowledgeScrollUpdate, void(const FrameMetrics::ViewID&, const uint32_t& aScrollGeneration));
   MOCK_METHOD3(HandleDoubleTap, void(const CSSPoint&, Modifiers, const ScrollableLayerGuid&));
   MOCK_METHOD3(HandleSingleTap, void(const CSSPoint&, Modifiers, const ScrollableLayerGuid&));
   MOCK_METHOD4(HandleLongTap, void(const CSSPoint&, Modifiers, const ScrollableLayerGuid&, uint64_t));
-  MOCK_METHOD2(PostDelayedTask, void(Task* aTask, int aDelayMs));
+  // Can't use the macros with already_AddRefed :(
+  void PostDelayedTask(already_AddRefed<Runnable> aTask, int aDelayMs) {
+    RefPtr<Runnable> task = aTask;
+  }
   MOCK_METHOD3(NotifyAPZStateChange, void(const ScrollableLayerGuid& aGuid, APZStateChange aChange, int aArg));
   MOCK_METHOD0(NotifyFlushComplete, void());
 };
 
 class MockContentControllerDelayed : public MockContentController {
 public:
   MockContentControllerDelayed()
     : mTime(GetStartupTime())
@@ -104,62 +105,63 @@ public:
   void AdvanceBy(const TimeDuration& aIncrement) {
     TimeStamp target = mTime + aIncrement;
     while (mTaskQueue.Length() > 0 && mTaskQueue[0].second <= target) {
       RunNextDelayedTask();
     }
     mTime = target;
   }
 
-  void PostDelayedTask(Task* aTask, int aDelayMs) {
+  void PostDelayedTask(already_AddRefed<Runnable> aTask, int aDelayMs) {
+    RefPtr<Runnable> task = aTask;
     TimeStamp runAtTime = mTime + TimeDuration::FromMilliseconds(aDelayMs);
     int insIndex = mTaskQueue.Length();
     while (insIndex > 0) {
       if (mTaskQueue[insIndex - 1].second <= runAtTime) {
         break;
       }
       insIndex--;
     }
-    mTaskQueue.InsertElementAt(insIndex, std::make_pair(aTask, runAtTime));
+    mTaskQueue.InsertElementAt(insIndex, std::make_pair(task, runAtTime));
   }
 
   // Run all the tasks in the queue, returning the number of tasks
   // run. Note that if a task queues another task while running, that
   // new task will not be run. Therefore, there may be still be tasks
   // in the queue after this function is called. Only when the return
   // value is 0 is the queue guaranteed to be empty.
   int RunThroughDelayedTasks() {
-    nsTArray<std::pair<Task*, TimeStamp>> runQueue;
+    nsTArray<std::pair<RefPtr<Runnable>, TimeStamp>> runQueue;
     runQueue.SwapElements(mTaskQueue);
     int numTasks = runQueue.Length();
     for (int i = 0; i < numTasks; i++) {
       mTime = runQueue[i].second;
       runQueue[i].first->Run();
 
       // Deleting the task is important in order to release the reference to
       // the callee object.
-      delete runQueue[i].first;
+      runQueue[i].first = nullptr;
     }
     return numTasks;
   }
 
 private:
   void RunNextDelayedTask() {
-    std::pair<Task*, TimeStamp> next = mTaskQueue[0];
+    std::pair<RefPtr<Runnable>, TimeStamp> next = mTaskQueue[0];
     mTaskQueue.RemoveElementAt(0);
     mTime = next.second;
     next.first->Run();
     // Deleting the task is important in order to release the reference to
     // the callee object.
-    delete next.first;
+    next.first = nullptr;
   }
 
   // The following array is sorted by timestamp (tasks are inserted in order by
   // timestamp).
-  nsTArray<std::pair<Task*, TimeStamp>> mTaskQueue;
+  nsTArray<std::pair<RefPtr<Runnable>, TimeStamp>> mTaskQueue;
   TimeStamp mTime;
 };
 
 class TestAPZCTreeManager : public APZCTreeManager {
 public:
   explicit TestAPZCTreeManager(MockContentControllerDelayed* aMcc) : mcc(aMcc) {}
 
   RefPtr<InputQueue> GetInputQueue() const {
--- a/gfx/layers/apz/util/APZThreadUtils.cpp
+++ b/gfx/layers/apz/util/APZThreadUtils.cpp
@@ -48,54 +48,53 @@ APZThreadUtils::AssertOnControllerThread
 APZThreadUtils::AssertOnCompositorThread()
 {
   if (GetThreadAssertionsEnabled()) {
     Compositor::AssertOnCompositorThread();
   }
 }
 
 /*static*/ void
-APZThreadUtils::RunOnControllerThread(Task* aTask)
+APZThreadUtils::RunOnControllerThread(already_AddRefed<Runnable> aTask)
 {
+  RefPtr<Runnable> task = aTask;
+
 #ifdef MOZ_ANDROID_APZ
   // This is needed while nsWindow::ConfigureAPZControllerThread is not propper
   // implemented.
   if (AndroidBridge::IsJavaUiThread()) {
-    aTask->Run();
-    delete aTask;
+    task->Run();
   } else {
-    AndroidBridge::Bridge()->PostTaskToUiThread(aTask, 0);
+    AndroidBridge::Bridge()->PostTaskToUiThread(task.forget(), 0);
   }
 #else
   if (!sControllerThread) {
     // Could happen on startup
     NS_WARNING("Dropping task posted to controller thread");
-    delete aTask;
     return;
   }
 
   if (sControllerThread == MessageLoop::current()) {
-    aTask->Run();
-    delete aTask;
+    task->Run();
   } else {
-    sControllerThread->PostTask(FROM_HERE, aTask);
+    sControllerThread->PostTask(task.forget());
   }
 #endif
 }
 
 /*static*/ void
-APZThreadUtils::RunDelayedTaskOnCurrentThread(Task* aTask,
+APZThreadUtils::RunDelayedTaskOnCurrentThread(already_AddRefed<Runnable> aTask,
                                               const TimeDuration& aDelay)
 {
   if (MessageLoop* messageLoop = MessageLoop::current()) {
-    messageLoop->PostDelayedTask(FROM_HERE, aTask, aDelay.ToMilliseconds());
+    messageLoop->PostDelayedTask(Move(aTask), aDelay.ToMilliseconds());
   } else {
 #ifdef MOZ_ANDROID_APZ
     // Fennec does not have a MessageLoop::current() on the controller thread.
-    AndroidBridge::Bridge()->PostTaskToUiThread(aTask, aDelay.ToMilliseconds());
+    AndroidBridge::Bridge()->PostTaskToUiThread(Move(aTask), aDelay.ToMilliseconds());
 #else
     // Other platforms should.
     MOZ_RELEASE_ASSERT(false, "This non-Fennec platform should have a MessageLoop::current()");
 #endif
   }
 }
 
 /*static*/ bool
--- a/gfx/layers/apz/util/APZThreadUtils.h
+++ b/gfx/layers/apz/util/APZThreadUtils.h
@@ -5,19 +5,20 @@
 
 #ifndef mozilla_layers_APZThreadUtils_h
 #define mozilla_layers_APZThreadUtils_h
 
 #include "base/message_loop.h"
 #include "mozilla/TimeStamp.h"  // for TimeDuration
 #include "nsITimer.h"
 
-class Task;
+namespace mozilla {
 
-namespace mozilla {
+class Runnable;
+
 namespace layers {
 
 class APZThreadUtils
 {
 public:
   /**
    * In the gtest environment everything runs on one thread, so we
    * shouldn't assert that we're on a particular thread. This enables
@@ -45,22 +46,22 @@ public:
    */
   static void AssertOnCompositorThread();
 
   /**
    * Run the given task on the APZ "controller thread" for this platform. If
    * this function is called from the controller thread itself then the task is
    * run immediately without getting queued.
    */
-  static void RunOnControllerThread(Task* aTask);
+  static void RunOnControllerThread(already_AddRefed<Runnable> aTask);
 
   /**
    * Runs the given task on the current thread after a delay of |aDelay|.
    */
-  static void RunDelayedTaskOnCurrentThread(Task* aTask,
+  static void RunDelayedTaskOnCurrentThread(already_AddRefed<Runnable> aTask,
                                             const TimeDuration& aDelay);
 
   /**
    * Returns true if currently on APZ "controller thread".
    */
   static bool IsControllerThread();
 };
 
--- a/gfx/layers/apz/util/ActiveElementManager.cpp
+++ b/gfx/layers/apz/util/ActiveElementManager.cpp
@@ -89,20 +89,20 @@ ActiveElementManager::TriggerElementActi
   // Otherwise, wait a bit to see if the user will pan or not.
   if (!mCanBePan) {
     SetActive(mTarget);
   } else {
     CancelTask();   // this is only needed because of bug 1169802. Fixing that
                     // bug properly should make this unnecessary.
     MOZ_ASSERT(mSetActiveTask == nullptr);
 
-    mSetActiveTask = NewRunnableMethod(
+    RefPtr<CancelableRunnable> task = NewRunnableMethod(
         this, &ActiveElementManager::SetActiveTask, mTarget);
-    MessageLoop::current()->PostDelayedTask(
-        FROM_HERE, mSetActiveTask, sActivationDelayMs);
+    mSetActiveTask = task;
+    MessageLoop::current()->PostDelayedTask(task.forget(), sActivationDelayMs);
     AEM_LOG("Scheduling mSetActiveTask %p\n", mSetActiveTask);
   }
 }
 
 void
 ActiveElementManager::ClearActivation()
 {
   AEM_LOG("Clearing element activation\n");
--- a/gfx/layers/apz/util/ActiveElementManager.h
+++ b/gfx/layers/apz/util/ActiveElementManager.h
@@ -4,19 +4,20 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_layers_ActiveElementManager_h
 #define mozilla_layers_ActiveElementManager_h
 
 #include "nsCOMPtr.h"
 #include "nsISupportsImpl.h"
 
-class CancelableTask;
+namespace mozilla {
 
-namespace mozilla {
+class CancelableRunnable;
+
 namespace dom {
 class Element;
 class EventTarget;
 } // namespace dom
 
 namespace layers {
 
 /**
@@ -77,17 +78,17 @@ private:
    * Whether mCanBePan has been set for the current touch block.
    * We need to keep track of this to allow HandleTouchStart() and
    * SetTargetElement() to be called in either order.
    */
   bool mCanBePanSet;
   /**
    * A task for calling SetActive() after a timeout.
    */
-  CancelableTask* mSetActiveTask;
+  RefPtr<CancelableRunnable> mSetActiveTask;
   /**
    * See ActiveElementUsesStyle() documentation.
    */
   bool mActiveElementUsesStyle;
 
   // Helpers
   void TriggerElementActivation();
   void SetActive(dom::Element* aTarget);
--- a/gfx/layers/apz/util/ChromeProcessController.cpp
+++ b/gfx/layers/apz/util/ChromeProcessController.cpp
@@ -32,17 +32,16 @@ ChromeProcessController::ChromeProcessCo
   , mUILoop(MessageLoop::current())
 {
   // Otherwise we're initializing mUILoop incorrectly.
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aAPZEventState);
   MOZ_ASSERT(aAPZCTreeManager);
 
   mUILoop->PostTask(
-      FROM_HERE,
       NewRunnableMethod(this, &ChromeProcessController::InitializeRoot));
 }
 
 ChromeProcessController::~ChromeProcessController() {}
 
 void
 ChromeProcessController::InitializeRoot()
 {
@@ -58,27 +57,26 @@ ChromeProcessController::RequestContentR
   if (metrics.IsRootContent()) {
     APZCCallbackHelper::UpdateRootFrame(metrics);
   } else {
     APZCCallbackHelper::UpdateSubFrame(metrics);
   }
 }
 
 void
-ChromeProcessController::PostDelayedTask(Task* aTask, int aDelayMs)
+ChromeProcessController::PostDelayedTask(already_AddRefed<Runnable> aTask, int aDelayMs)
 {
-  MessageLoop::current()->PostDelayedTask(FROM_HERE, aTask, aDelayMs);
+  MessageLoop::current()->PostDelayedTask(Move(aTask), aDelayMs);
 }
 
 void
 ChromeProcessController::Destroy()
 {
   if (MessageLoop::current() != mUILoop) {
     mUILoop->PostTask(
-      FROM_HERE,
       NewRunnableMethod(this, &ChromeProcessController::Destroy));
     return;
   }
 
   MOZ_ASSERT(MessageLoop::current() == mUILoop);
   mWidget = nullptr;
 }
 
@@ -119,17 +117,16 @@ ChromeProcessController::GetRootContentD
 
 void
 ChromeProcessController::HandleDoubleTap(const mozilla::CSSPoint& aPoint,
                                          Modifiers aModifiers,
                                          const ScrollableLayerGuid& aGuid)
 {
   if (MessageLoop::current() != mUILoop) {
     mUILoop->PostTask(
-        FROM_HERE,
         NewRunnableMethod(this, &ChromeProcessController::HandleDoubleTap,
                           aPoint, aModifiers, aGuid));
     return;
   }
 
   nsCOMPtr<nsIDocument> document = GetRootContentDocument(aGuid.mScrollId);
   if (!document.get()) {
     return;
@@ -157,64 +154,60 @@ ChromeProcessController::HandleDoubleTap
 
 void
 ChromeProcessController::HandleSingleTap(const CSSPoint& aPoint,
                                          Modifiers aModifiers,
                                          const ScrollableLayerGuid& aGuid)
 {
   if (MessageLoop::current() != mUILoop) {
     mUILoop->PostTask(
-        FROM_HERE,
         NewRunnableMethod(this, &ChromeProcessController::HandleSingleTap,
                           aPoint, aModifiers, aGuid));
     return;
   }
 
   mAPZEventState->ProcessSingleTap(aPoint, aModifiers, aGuid);
 }
 
 void
 ChromeProcessController::HandleLongTap(const mozilla::CSSPoint& aPoint, Modifiers aModifiers,
                                        const ScrollableLayerGuid& aGuid,
                                        uint64_t aInputBlockId)
 {
   if (MessageLoop::current() != mUILoop) {
     mUILoop->PostTask(
-        FROM_HERE,
         NewRunnableMethod(this, &ChromeProcessController::HandleLongTap,
                           aPoint, aModifiers, aGuid, aInputBlockId));
     return;
   }
 
   mAPZEventState->ProcessLongTap(GetPresShell(), aPoint, aModifiers, aGuid,
       aInputBlockId);
 }
 
 void
 ChromeProcessController::NotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
                                               APZStateChange aChange,
                                               int aArg)
 {
   if (MessageLoop::current() != mUILoop) {
     mUILoop->PostTask(
-        FROM_HERE,
         NewRunnableMethod(this, &ChromeProcessController::NotifyAPZStateChange,
                           aGuid, aChange, aArg));
     return;
   }
 
   mAPZEventState->ProcessAPZStateChange(GetRootDocument(), aGuid.mScrollId, aChange, aArg);
 }
 
 void
 ChromeProcessController::NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId, const nsString& aEvent)
 {
   if (MessageLoop::current() != mUILoop) {
     mUILoop->PostTask(
-      FROM_HERE,
       NewRunnableMethod(this, &ChromeProcessController::NotifyMozMouseScrollEvent, aScrollId, aEvent));
     return;
   }
 
   APZCCallbackHelper::NotifyMozMouseScrollEvent(aScrollId, aEvent);
 }
 
 void
--- a/gfx/layers/apz/util/ChromeProcessController.h
+++ b/gfx/layers/apz/util/ChromeProcessController.h
@@ -34,17 +34,17 @@ protected:
 
 public:
   explicit ChromeProcessController(nsIWidget* aWidget, APZEventState* aAPZEventState, APZCTreeManager* aAPZCTreeManager);
   ~ChromeProcessController();
   virtual void Destroy() override;
 
   // GeckoContentController interface
   virtual void RequestContentRepaint(const FrameMetrics& aFrameMetrics) override;
-  virtual void PostDelayedTask(Task* aTask, int aDelayMs) override;
+  virtual void PostDelayedTask(already_AddRefed<Runnable> aTask, int aDelayMs) override;
   virtual void HandleDoubleTap(const mozilla::CSSPoint& aPoint, Modifiers aModifiers,
                                const ScrollableLayerGuid& aGuid) override;
   virtual void HandleSingleTap(const mozilla::CSSPoint& aPoint, Modifiers aModifiers,
                                const ScrollableLayerGuid& aGuid) override;
   virtual void HandleLongTap(const mozilla::CSSPoint& aPoint, Modifiers aModifiers,
                                const ScrollableLayerGuid& aGuid,
                                uint64_t aInputBlockId) override;
   virtual void NotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
--- a/gfx/layers/client/CompositableClient.cpp
+++ b/gfx/layers/client/CompositableClient.cpp
@@ -59,20 +59,20 @@ public:
 
 void
 RemoveTextureFromCompositableTracker::ReleaseTextureClient()
 {
   if (mTextureClient &&
       mTextureClient->GetAllocator() &&
       !mTextureClient->GetAllocator()->UsesImageBridge())
   {
-    TextureClientReleaseTask* task = new TextureClientReleaseTask(mTextureClient);
+    RefPtr<TextureClientReleaseTask> task = new TextureClientReleaseTask(mTextureClient);
     RefPtr<ClientIPCAllocator> allocator = mTextureClient->GetAllocator();
     mTextureClient = nullptr;
-    allocator->AsClientAllocator()->GetMessageLoop()->PostTask(FROM_HERE, task);
+    allocator->AsClientAllocator()->GetMessageLoop()->PostTask(task.forget());
   } else {
     mTextureClient = nullptr;
   }
 }
 
 /* static */ void
 CompositableClient::TransactionCompleteted(PCompositableChild* aActor, uint64_t aTransactionId)
 {
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -250,25 +250,24 @@ DeallocateTextureClient(TextureDeallocPa
   }
 
   // First make sure that the work is happening on the IPDL thread.
   if (ipdlMsgLoop && MessageLoop::current() != ipdlMsgLoop) {
     if (params.syncDeallocation) {
       bool done = false;
       ReentrantMonitor barrier("DeallocateTextureClient");
       ReentrantMonitorAutoEnter autoMon(barrier);
-      ipdlMsgLoop->PostTask(FROM_HERE,
-        NewRunnableFunction(DeallocateTextureClientSyncProxy,
-                            params, &barrier, &done));
+      ipdlMsgLoop->PostTask(NewRunnableFunction(DeallocateTextureClientSyncProxy,
+                                                params, &barrier, &done));
       while (!done) {
         barrier.Wait();
       }
     } else {
-      ipdlMsgLoop->PostTask(FROM_HERE,
-        NewRunnableFunction(DeallocateTextureClient, params));
+      ipdlMsgLoop->PostTask(NewRunnableFunction(DeallocateTextureClient,
+                                                params));
     }
     // The work has been forwarded to the IPDL thread, we are done.
     return;
   }
 
   // Below this line, we are either in the IPDL thread or ther is no IPDL
   // thread anymore.
 
--- a/gfx/layers/client/TextureClient.h
+++ b/gfx/layers/client/TextureClient.h
@@ -656,26 +656,27 @@ public:
   // Pointer to the pool this tile came from.
   TextureClientPool* mPoolTracker;
 #endif
 };
 
 /**
  * Task that releases TextureClient pointer on a specified thread.
  */
-class TextureClientReleaseTask : public Task
+class TextureClientReleaseTask : public Runnable
 {
 public:
     explicit TextureClientReleaseTask(TextureClient* aClient)
         : mTextureClient(aClient) {
     }
 
-    virtual void Run() override
+    NS_IMETHOD Run() override
     {
         mTextureClient = nullptr;
+        return NS_OK;
     }
 
 private:
     RefPtr<TextureClient> mTextureClient;
 };
 
 // Automatically lock and unlock a texture. Since texture locking is fallible,
 // Succeeded() must be checked on the guard object before proceeding.
--- a/gfx/layers/client/TextureClientRecycleAllocator.cpp
+++ b/gfx/layers/client/TextureClientRecycleAllocator.cpp
@@ -88,27 +88,28 @@ TextureClientRecycleAllocator::~TextureC
 }
 
 void
 TextureClientRecycleAllocator::SetMaxPoolSize(uint32_t aMax)
 {
   mMaxPooledSize = aMax;
 }
 
-class TextureClientRecycleTask : public Task
+class TextureClientRecycleTask : public Runnable
 {
 public:
   explicit TextureClientRecycleTask(TextureClient* aClient, TextureFlags aFlags)
     : mTextureClient(aClient)
     , mFlags(aFlags)
   {}
 
-  virtual void Run() override
+  NS_IMETHOD Run() override
   {
     mTextureClient->RecycleTexture(mFlags);
+    return NS_OK;
   }
 
 private:
   RefPtr<TextureClient> mTextureClient;
   TextureFlags mFlags;
 };
 
 already_AddRefed<TextureClient>
@@ -141,27 +142,27 @@ TextureClientRecycleAllocator::CreateOrR
 
   RefPtr<TextureClientHolder> textureHolder;
 
   {
     MutexAutoLock lock(mLock);
     if (!mPooledClients.empty()) {
       textureHolder = mPooledClients.top();
       mPooledClients.pop();
-      Task* task = nullptr;
+      RefPtr<Runnable> task;
       // If a pooled TextureClient is not compatible, release it.
       if (!aHelper.IsCompatible(textureHolder->GetTextureClient())) {
         // Release TextureClient.
         task = new TextureClientReleaseTask(textureHolder->GetTextureClient());
         textureHolder->ClearTextureClient();
         textureHolder = nullptr;
       } else {
         task = new TextureClientRecycleTask(textureHolder->GetTextureClient(), aHelper.mTextureFlags);
       }
-      mSurfaceAllocator->GetMessageLoop()->PostTask(FROM_HERE, task);
+      mSurfaceAllocator->GetMessageLoop()->PostTask(task.forget());
     }
   }
 
   if (!textureHolder) {
     // Allocate new TextureClient
     RefPtr<TextureClient> texture = aHelper.Allocate(mSurfaceAllocator);
     if (!texture) {
       return nullptr;
--- a/gfx/layers/ipc/CompositorBridgeChild.cpp
+++ b/gfx/layers/ipc/CompositorBridgeChild.cpp
@@ -5,17 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/layers/CompositorBridgeChild.h"
 #include "mozilla/layers/CompositorBridgeParent.h"
 #include <stddef.h>                     // for size_t
 #include "ClientLayerManager.h"         // for ClientLayerManager
 #include "base/message_loop.h"          // for MessageLoop
 #include "base/task.h"                  // for NewRunnableMethod, etc
-#include "base/tracked.h"               // for FROM_HERE
 #include "mozilla/layers/LayerTransactionChild.h"
 #include "mozilla/layers/PLayerTransactionChild.h"
 #include "mozilla/mozalloc.h"           // for operator new, etc
 #include "nsDebug.h"                    // for NS_RUNTIMEABORT
 #include "nsIObserver.h"                // for nsIObserver
 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
 #include "nsTArray.h"                   // for nsTArray, nsTArray_Impl
 #include "nsXULAppAPI.h"                // for XRE_GetIOMessageLoop, etc
@@ -41,18 +40,18 @@ Atomic<int32_t> CompositableForwarder::s
 CompositorBridgeChild::CompositorBridgeChild(ClientLayerManager *aLayerManager)
   : mLayerManager(aLayerManager)
   , mCanSend(false)
 {
 }
 
 CompositorBridgeChild::~CompositorBridgeChild()
 {
-  XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
-                                   new DeleteTask<Transport>(GetTransport()));
+  RefPtr<DeleteTask<Transport>> task = new DeleteTask<Transport>(GetTransport());
+  XRE_GetIOMessageLoop()->PostTask(task.forget());
 
   if (mCanSend) {
     gfxCriticalError() << "CompositorBridgeChild was not deinitialized";
   }
 }
 
 bool
 CompositorBridgeChild::IsSameProcess() const
@@ -106,17 +105,17 @@ CompositorBridgeChild::Destroy()
   // CompositorBridgeParent to the CompositorBridgeChild (e.g. caused by the destruction
   // of shared memory). We need to ensure this gets processed by the
   // CompositorBridgeChild before it gets destroyed. It suffices to ensure that
   // events already in the MessageLoop get processed before the
   // CompositorBridgeChild is destroyed, so we add a task to the MessageLoop to
   // handle compositor desctruction.
 
   // From now on we can't send any message message.
-  MessageLoop::current()->PostTask(FROM_HERE,
+  MessageLoop::current()->PostTask(
              NewRunnableFunction(DeferredDestroyCompositor, mCompositorBridgeParent, selfRef));
 }
 
 // static
 void
 CompositorBridgeChild::ShutDown()
 {
   if (sCompositorBridge) {
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -10,17 +10,16 @@
 #include <map>                          // for _Rb_tree_iterator, etc
 #include <utility>                      // for pair
 #include "LayerTransactionParent.h"     // for LayerTransactionParent
 #include "RenderTrace.h"                // for RenderTraceLayers
 #include "base/message_loop.h"          // for MessageLoop
 #include "base/process.h"               // for ProcessId
 #include "base/task.h"                  // for CancelableTask, etc
 #include "base/thread.h"                // for Thread
-#include "base/tracked.h"               // for FROM_HERE
 #include "gfxContext.h"                 // for gfxContext
 #include "gfxPlatform.h"                // for gfxPlatform
 #ifdef MOZ_WIDGET_GTK
 #include "gfxPlatformGtk.h"             // for gfxPlatform
 #endif
 #include "gfxPrefs.h"                   // for gfxPrefs
 #include "mozilla/AutoRestore.h"        // for AutoRestore
 #include "mozilla/ClearOnShutdown.h"    // for ClearOnShutdown
@@ -357,20 +356,20 @@ CompositorVsyncScheduler::~CompositorVsy
 void
 CompositorVsyncScheduler::SetDisplay(bool aDisplayEnable)
 {
   // SetDisplay() is usually called from nsScreenManager at main thread. Post
   // to compositor thread if needs.
   if (!CompositorBridgeParent::IsInCompositorThread()) {
     MOZ_ASSERT(NS_IsMainThread());
     MonitorAutoLock lock(mSetDisplayMonitor);
-    mSetDisplayTask = NewRunnableMethod(this,
-                                        &CompositorVsyncScheduler::SetDisplay,
-                                        aDisplayEnable);
-    ScheduleTask(mSetDisplayTask, 0);
+    RefPtr<CancelableRunnable> task =
+      NewRunnableMethod(this, &CompositorVsyncScheduler::SetDisplay, aDisplayEnable);
+    mSetDisplayTask = task;
+    ScheduleTask(task.forget(), 0);
     return;
   } else {
     MonitorAutoLock lock(mSetDisplayMonitor);
     mSetDisplayTask = nullptr;
   }
 
   if (mDisplayEnabled == aDisplayEnable) {
     return;
@@ -422,20 +421,21 @@ CompositorVsyncScheduler::Destroy()
 }
 
 void
 CompositorVsyncScheduler::PostCompositeTask(TimeStamp aCompositeTimestamp)
 {
   // can be called from the compositor or vsync thread
   MonitorAutoLock lock(mCurrentCompositeTaskMonitor);
   if (mCurrentCompositeTask == nullptr) {
-    mCurrentCompositeTask = NewRunnableMethod(this,
-                                              &CompositorVsyncScheduler::Composite,
-                                              aCompositeTimestamp);
-    ScheduleTask(mCurrentCompositeTask, 0);
+    RefPtr<CancelableRunnable> task =
+      NewRunnableMethod(this, &CompositorVsyncScheduler::Composite,
+                        aCompositeTimestamp);
+    mCurrentCompositeTask = task;
+    ScheduleTask(task.forget(), 0);
   }
 }
 
 void
 CompositorVsyncScheduler::ScheduleComposition()
 {
   MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread());
   if (mAsapScheduling) {
@@ -475,19 +475,20 @@ CompositorVsyncScheduler::CancelCurrentS
  * next vsync?
  * How many skipped vsync events until we stop listening to vsync events?
  */
 void
 CompositorVsyncScheduler::SetNeedsComposite()
 {
   if (!CompositorBridgeParent::IsInCompositorThread()) {
     MonitorAutoLock lock(mSetNeedsCompositeMonitor);
-    mSetNeedsCompositeTask = NewRunnableMethod(this,
-                                              &CompositorVsyncScheduler::SetNeedsComposite);
-    ScheduleTask(mSetNeedsCompositeTask, 0);
+    RefPtr<CancelableRunnable> task =
+      NewRunnableMethod(this, &CompositorVsyncScheduler::SetNeedsComposite);
+    mSetNeedsCompositeTask = task;
+    ScheduleTask(task.forget(), 0);
     return;
   } else {
     MonitorAutoLock lock(mSetNeedsCompositeMonitor);
     mSetNeedsCompositeTask = nullptr;
   }
 
 #ifdef MOZ_WIDGET_GONK
 #if ANDROID_VERSION >= 19
@@ -654,21 +655,22 @@ void CompositorBridgeParent::ShutDown()
 }
 
 MessageLoop* CompositorBridgeParent::CompositorLoop()
 {
   return CompositorThread() ? CompositorThread()->message_loop() : nullptr;
 }
 
 void
-CompositorVsyncScheduler::ScheduleTask(CancelableTask* aTask, int aTime)
+CompositorVsyncScheduler::ScheduleTask(already_AddRefed<CancelableRunnable> aTask,
+                                       int aTime)
 {
   MOZ_ASSERT(CompositorBridgeParent::CompositorLoop());
   MOZ_ASSERT(aTime >= 0);
-  CompositorBridgeParent::CompositorLoop()->PostDelayedTask(FROM_HERE, aTask, aTime);
+  CompositorBridgeParent::CompositorLoop()->PostDelayedTask(Move(aTask), aTime);
 }
 
 void
 CompositorVsyncScheduler::ResumeComposition()
 {
   MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread());
   mLastCompose = TimeStamp::Now();
   ComposeToTarget(nullptr);
@@ -709,20 +711,20 @@ CompositorBridgeParent::CompositorBridge
   MOZ_ASSERT(CompositorThread(),
              "The compositor thread must be Initialized before instanciating a CompositorBridgeParent.");
   MOZ_COUNT_CTOR(CompositorBridgeParent);
   mCompositorID = 0;
   // FIXME: This holds on the the fact that right now the only thing that
   // can destroy this instance is initialized on the compositor thread after
   // this task has been processed.
   MOZ_ASSERT(CompositorLoop());
-  CompositorLoop()->PostTask(FROM_HERE, NewRunnableFunction(&AddCompositor,
-                                                          this, &mCompositorID));
-
-  CompositorLoop()->PostTask(FROM_HERE, NewRunnableFunction(SetThreadPriority));
+  CompositorLoop()->PostTask(NewRunnableFunction(&AddCompositor,
+                                                 this, &mCompositorID));
+
+  CompositorLoop()->PostTask(NewRunnableFunction(SetThreadPriority));
 
 
   { // scope lock
     MonitorAutoLock lock(*sIndirectLayerTreesLock);
     sIndirectLayerTrees[mRootLayerTreeID].mParent = this;
   }
 
   // The Compositor uses the APZ pref directly since it needs to know whether
@@ -975,35 +977,32 @@ CompositorBridgeParent::ActorDestroy(Act
   mCompositorScheduler->Destroy();
 
   // There are chances that the ref count reaches zero on the main thread shortly
   // after this function returns while some ipdl code still needs to run on
   // this thread.
   // We must keep the compositor parent alive untill the code handling message
   // reception is finished on this thread.
   mSelfRef = this;
-  MessageLoop::current()->PostTask(FROM_HERE,
-                                   NewRunnableMethod(this,&CompositorBridgeParent::DeferredDestroy));
+  MessageLoop::current()->PostTask(NewRunnableMethod(this,&CompositorBridgeParent::DeferredDestroy));
 }
 
 
 void
 CompositorBridgeParent::ScheduleRenderOnCompositorThread()
 {
-  CancelableTask *renderTask = NewRunnableMethod(this, &CompositorBridgeParent::ScheduleComposition);
   MOZ_ASSERT(CompositorLoop());
-  CompositorLoop()->PostTask(FROM_HERE, renderTask);
+  CompositorLoop()->PostTask(NewRunnableMethod(this, &CompositorBridgeParent::ScheduleComposition));
 }
 
 void
 CompositorBridgeParent::InvalidateOnCompositorThread()
 {
-  CancelableTask *renderTask = NewRunnableMethod(this, &CompositorBridgeParent::Invalidate);
   MOZ_ASSERT(CompositorLoop());
-  CompositorLoop()->PostTask(FROM_HERE, renderTask);
+  CompositorLoop()->PostTask(NewRunnableMethod(this, &CompositorBridgeParent::Invalidate));
 }
 
 void
 CompositorBridgeParent::PauseComposition()
 {
   MOZ_ASSERT(IsInCompositorThread(),
              "PauseComposition() can only be called on the compositor thread");
 
@@ -1083,64 +1082,58 @@ CompositorBridgeParent::ResumeCompositio
  * This will execute a pause synchronously, waiting to make sure that the compositor
  * really is paused.
  */
 void
 CompositorBridgeParent::SchedulePauseOnCompositorThread()
 {
   MonitorAutoLock lock(mPauseCompositionMonitor);
 
-  CancelableTask *pauseTask = NewRunnableMethod(this,
-                                                &CompositorBridgeParent::PauseComposition);
   MOZ_ASSERT(CompositorLoop());
-  CompositorLoop()->PostTask(FROM_HERE, pauseTask);
+  CompositorLoop()->PostTask(NewRunnableMethod(this, &CompositorBridgeParent::PauseComposition));
 
   // Wait until the pause has actually been processed by the compositor thread
   lock.Wait();
 }
 
 bool
 CompositorBridgeParent::ScheduleResumeOnCompositorThread()
 {
   MonitorAutoLock lock(mResumeCompositionMonitor);
 
-  CancelableTask *resumeTask =
-    NewRunnableMethod(this, &CompositorBridgeParent::ResumeComposition);
   MOZ_ASSERT(CompositorLoop());
-  CompositorLoop()->PostTask(FROM_HERE, resumeTask);
+  CompositorLoop()->PostTask(NewRunnableMethod(this, &CompositorBridgeParent::ResumeComposition));
 
   // Wait until the resume has actually been processed by the compositor thread
   lock.Wait();
 
   return !mPaused;
 }
 
 bool
 CompositorBridgeParent::ScheduleResumeOnCompositorThread(int width, int height)
 {
   MonitorAutoLock lock(mResumeCompositionMonitor);
 
-  CancelableTask *resumeTask =
-    NewRunnableMethod(this, &CompositorBridgeParent::ResumeCompositionAndResize, width, height);
   MOZ_ASSERT(CompositorLoop());
-  CompositorLoop()->PostTask(FROM_HERE, resumeTask);
+  CompositorLoop()->PostTask(NewRunnableMethod(this, &CompositorBridgeParent::ResumeCompositionAndResize, width, height));
 
   // Wait until the resume has actually been processed by the compositor thread
   lock.Wait();
 
   return !mPaused;
 }
 
 void
-CompositorBridgeParent::ScheduleTask(CancelableTask* task, int time)
+CompositorBridgeParent::ScheduleTask(already_AddRefed<CancelableRunnable> task, int time)
 {
   if (time == 0) {
-    MessageLoop::current()->PostTask(FROM_HERE, task);
+    MessageLoop::current()->PostTask(Move(task));
   } else {
-    MessageLoop::current()->PostDelayedTask(FROM_HERE, task, time);
+    MessageLoop::current()->PostDelayedTask(Move(task), time);
   }
 }
 
 void
 CompositorBridgeParent::NotifyShadowTreeTransaction(uint64_t aId, bool aIsFirstPaint,
     bool aScheduleComposite, uint32_t aPaintSequenceNumber,
     bool aIsRepeatTransaction)
 {
@@ -1367,18 +1360,19 @@ CompositorBridgeParent::ScheduleRotation
   MOZ_ASSERT(IsInCompositorThread());
 
   if (!aIsFirstPaint &&
       !mCompositionManager->IsFirstPaint() &&
       mCompositionManager->RequiresReorientation(aTargetConfig.orientation())) {
     if (mForceCompositionTask != nullptr) {
       mForceCompositionTask->Cancel();
     }
-    mForceCompositionTask = NewRunnableMethod(this, &CompositorBridgeParent::ForceComposition);
-    ScheduleTask(mForceCompositionTask, gfxPrefs::OrientationSyncMillis());
+    RefPtr<CancelableRunnable> task = NewRunnableMethod(this, &CompositorBridgeParent::ForceComposition);
+    mForceCompositionTask = task;
+    ScheduleTask(task.forget(), gfxPrefs::OrientationSyncMillis());
   }
 }
 
 void
 CompositorBridgeParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
                                             const uint64_t& aTransactionId,
                                             const TargetConfig& aTargetConfig,
                                             const InfallibleTArray<PluginWindowData>& aUnused,
@@ -1523,48 +1517,51 @@ CompositorBridgeParent::FlushApzRepaints
 void
 CompositorBridgeParent::GetAPZTestData(const LayerTransactionParent* aLayerTree,
                                        APZTestData* aOutData)
 {
   MonitorAutoLock lock(*sIndirectLayerTreesLock);
   *aOutData = sIndirectLayerTrees[mRootLayerTreeID].mApzTestData;
 }
 
-class NotifyAPZConfirmedTargetTask : public Task
+class NotifyAPZConfirmedTargetTask : public Runnable
 {
 public:
   explicit NotifyAPZConfirmedTargetTask(const RefPtr<APZCTreeManager>& aAPZCTM,
                                         const uint64_t& aInputBlockId,
                                         const nsTArray<ScrollableLayerGuid>& aTargets)
    : mAPZCTM(aAPZCTM),
      mInputBlockId(aInputBlockId),
      mTargets(aTargets)
   {
   }
 
-  virtual void Run() override {
+  NS_IMETHOD Run() override {
     mAPZCTM->SetTargetAPZC(mInputBlockId, mTargets);
+    return NS_OK;
   }
 
 private:
   RefPtr<APZCTreeManager> mAPZCTM;
   uint64_t mInputBlockId;
   nsTArray<ScrollableLayerGuid> mTargets;
 };
 
 void
 CompositorBridgeParent::SetConfirmedTargetAPZC(const LayerTransactionParent* aLayerTree,
                                          const uint64_t& aInputBlockId,
                                          const nsTArray<ScrollableLayerGuid>& aTargets)
 {
   if (!mApzcTreeManager) {
     return;
   }
-  APZThreadUtils::RunOnControllerThread(new NotifyAPZConfirmedTargetTask(
-    mApzcTreeManager, aInputBlockId, aTargets));
+  RefPtr<Runnable> task =
+    new NotifyAPZConfirmedTargetTask(mApzcTreeManager, aInputBlockId, aTargets);
+  APZThreadUtils::RunOnControllerThread(task.forget());
+
 }
 
 void
 CompositorBridgeParent::InitializeLayerManager(const nsTArray<LayersBackend>& aBackendHints)
 {
   NS_ASSERTION(!mLayerManager, "Already initialised mLayerManager");
   NS_ASSERTION(!mCompositor,   "Already initialised mCompositor");
 
@@ -1771,18 +1768,17 @@ CompositorBridgeParent::DeallocateLayerT
   MOZ_ASSERT(NS_IsMainThread());
   // Here main thread notifies compositor to remove an element from
   // sIndirectLayerTrees. This removed element might be queried soon.
   // Checking the elements of sIndirectLayerTrees exist or not before using.
   if (!CompositorLoop()) {
     gfxCriticalError() << "Attempting to post to a invalid Compositor Loop";
     return;
   }
-  CompositorLoop()->PostTask(FROM_HERE,
-                             NewRunnableFunction(&EraseLayerState, aId));
+  CompositorLoop()->PostTask(NewRunnableFunction(&EraseLayerState, aId));
 }
 
 /* static */ void
 CompositorBridgeParent::SwapLayerTreeObservers(uint64_t aLayerId, uint64_t aOtherLayerId)
 {
   EnsureLayerTreeMapReady();
   MonitorAutoLock lock(*sIndirectLayerTreesLock);
   NS_ASSERTION(sIndirectLayerTrees.find(aLayerId) != sIndirectLayerTrees.end(),
@@ -1822,18 +1818,17 @@ ScopedLayerTreeRegistration::~ScopedLaye
 }
 
 /*static*/ void
 CompositorBridgeParent::SetControllerForLayerTree(uint64_t aLayersId,
                                                   GeckoContentController* aController)
 {
   // This ref is adopted by UpdateControllerForLayersId().
   aController->AddRef();
-  CompositorLoop()->PostTask(FROM_HERE,
-                             NewRunnableFunction(&UpdateControllerForLayersId,
+  CompositorLoop()->PostTask(NewRunnableFunction(&UpdateControllerForLayersId,
                                                  aLayersId,
                                                  aController));
 }
 
 /*static*/ APZCTreeManager*
 CompositorBridgeParent::GetAPZCTreeManager(uint64_t aLayersId)
 {
   EnsureLayerTreeMapReady();
@@ -1866,17 +1861,17 @@ InsertVsyncProfilerMarker(TimeStamp aVsy
 #endif
 }
 
 /*static */ void
 CompositorBridgeParent::PostInsertVsyncProfilerMarker(TimeStamp aVsyncTimestamp)
 {
   // Called in the vsync thread
   if (profiler_is_active() && sCompositorThreadHolder) {
-    CompositorLoop()->PostTask(FROM_HERE,
+    CompositorLoop()->PostTask(
       NewRunnableFunction(InsertVsyncProfilerMarker, aVsyncTimestamp));
   }
 }
 
 /* static */ void
 CompositorBridgeParent::RequestNotifyLayerTreeReady(uint64_t aLayersId, CompositorUpdateObserver* aObserver)
 {
   EnsureLayerTreeMapReady();
@@ -2106,17 +2101,17 @@ CompositorBridgeParent::InvalidateRemote
 bool
 CompositorBridgeParent::ResetCompositor(const nsTArray<LayersBackend>& aBackendHints,
                                         TextureFactoryIdentifier* aOutIdentifier)
 {
   Maybe<TextureFactoryIdentifier> newIdentifier;
   {
     MonitorAutoLock lock(mResetCompositorMonitor);
 
-    CompositorLoop()->PostTask(FROM_HERE,
+    CompositorLoop()->PostTask(
       NewRunnableMethod(this,
                         &CompositorBridgeParent::ResetCompositorTask,
                         aBackendHints,
                         &newIdentifier));
 
     mResetCompositorMonitor.Wait();
   }
 
@@ -2216,17 +2211,16 @@ CompositorBridgeParent::Create(Transport
 
   if (aProcessHost) {
     cpcp->mSubprocess = aProcessHost;
     aProcessHost->AssociateActor();
   }
 
   cpcp->mSelfRef = cpcp;
   CompositorLoop()->PostTask(
-    FROM_HERE,
     NewRunnableFunction(OpenCompositor, cpcp.get(),
                         aTransport, aOtherPid, XRE_GetIOMessageLoop()));
   // The return value is just compared to null for success checking,
   // we're not sharing a ref.
   return cpcp.get();
 }
 
 static void
@@ -2279,17 +2273,17 @@ CrossProcessCompositorBridgeParent::Acto
 
   if (mSubprocess) {
     mSubprocess->DissociateActor();
     mSubprocess = nullptr;
   }
 
   // We must keep this object alive untill the code handling message
   // reception is finished on this thread.
-  MessageLoop::current()->PostTask(FROM_HERE,
+  MessageLoop::current()->PostTask(
       NewRunnableMethod(this, &CrossProcessCompositorBridgeParent::DeferredDestroy));
 }
 
 PLayerTransactionParent*
 CrossProcessCompositorBridgeParent::AllocPLayerTransactionParent(
   const nsTArray<LayersBackend>&,
   const uint64_t& aId,
   TextureFactoryIdentifier* aTextureFactoryIdentifier,
@@ -2524,37 +2518,33 @@ CompositorBridgeParent::UpdatePluginWind
   mLastPluginUpdateLayerTreeId = aId;
   mCachedPluginData = lts.mPluginData;
   return true;
 }
 
 void
 CompositorBridgeParent::ScheduleShowAllPluginWindows()
 {
-  CancelableTask *pluginTask =
-    NewRunnableMethod(this, &CompositorBridgeParent::ShowAllPluginWindows);
   MOZ_ASSERT(CompositorLoop());
-  CompositorLoop()->PostTask(FROM_HERE, pluginTask);
+  CompositorLoop()->PostTask(NewRunnableMethod(this, &CompositorBridgeParent::ShowAllPluginWindows));
 }
 
 void
 CompositorBridgeParent::ShowAllPluginWindows()
 {
   MOZ_ASSERT(!NS_IsMainThread());
   mDeferPluginWindows = false;
   ScheduleComposition();
 }
 
 void
 CompositorBridgeParent::ScheduleHideAllPluginWindows()
 {
-  CancelableTask *pluginTask =
-    NewRunnableMethod(this, &CompositorBridgeParent::HideAllPluginWindows);
   MOZ_ASSERT(CompositorLoop());
-  CompositorLoop()->PostTask(FROM_HERE, pluginTask);
+  CompositorLoop()->PostTask(NewRunnableMethod(this, &CompositorBridgeParent::HideAllPluginWindows));
 }
 
 void
 CompositorBridgeParent::HideAllPluginWindows()
 {
   MOZ_ASSERT(!NS_IsMainThread());
   // No plugins in the cache implies no plugins to manage
   // in this content.
@@ -2737,18 +2727,18 @@ CrossProcessCompositorBridgeParent::Defe
   mCompositorThreadHolder = nullptr;
   mSelfRef = nullptr;
 }
 
 CrossProcessCompositorBridgeParent::~CrossProcessCompositorBridgeParent()
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(XRE_GetIOMessageLoop());
-  XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
-                                   new DeleteTask<Transport>(mTransport));
+  RefPtr<DeleteTask<Transport>> task = new DeleteTask<Transport>(mTransport);
+  XRE_GetIOMessageLoop()->PostTask(task.forget());
 }
 
 IToplevelProtocol*
 CrossProcessCompositorBridgeParent::CloneToplevel(
   const InfallibleTArray<mozilla::ipc::ProtocolFdMapping>& aFds,
   base::ProcessHandle aPeerProcess,
   mozilla::ipc::ProtocolCloneContext* aCtx)
 {
--- a/gfx/layers/ipc/CompositorBridgeParent.h
+++ b/gfx/layers/ipc/CompositorBridgeParent.h
@@ -34,21 +34,23 @@
 #include "mozilla/layers/PCompositorBridgeParent.h"
 #include "mozilla/layers/ShadowLayersManager.h" // for ShadowLayersManager
 #include "mozilla/layers/APZTestData.h"
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsISupportsImpl.h"
 #include "ThreadSafeRefcountingWithMainThreadDestruction.h"
 #include "mozilla/VsyncDispatcher.h"
 
-class CancelableTask;
 class MessageLoop;
 class nsIWidget;
 
 namespace mozilla {
+
+class CancelableRunnable;
+
 namespace gfx {
 class DrawTarget;
 } // namespace gfx
 
 namespace ipc {
 class GeckoChildProcessHost;
 } // namespace ipc
 
@@ -121,17 +123,17 @@ public:
   void SetDisplay(bool aDisplayEnable);
 #endif
 #endif
 
   bool NotifyVsync(TimeStamp aVsyncTimestamp);
   void SetNeedsComposite();
   void OnForceComposeToTarget();
 
-  void ScheduleTask(CancelableTask*, int);
+  void ScheduleTask(already_AddRefed<CancelableRunnable>, int);
   void ResumeComposition();
   void ComposeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect = nullptr);
   void PostCompositeTask(TimeStamp aCompositeTimestamp);
   void Destroy();
   void ScheduleComposition();
   void CancelCurrentCompositeTask();
   bool NeedsComposite();
   void Composite(TimeStamp aVsyncTimestamp);
@@ -188,26 +190,26 @@ private:
   bool mAsapScheduling;
   bool mIsObservingVsync;
   uint32_t mNeedsComposite;
   int32_t mVsyncNotificationsSkipped;
   RefPtr<CompositorVsyncDispatcher> mCompositorVsyncDispatcher;
   RefPtr<CompositorVsyncScheduler::Observer> mVsyncObserver;
 
   mozilla::Monitor mCurrentCompositeTaskMonitor;
-  CancelableTask* mCurrentCompositeTask;
+  RefPtr<CancelableRunnable> mCurrentCompositeTask;
 
   mozilla::Monitor mSetNeedsCompositeMonitor;
-  CancelableTask* mSetNeedsCompositeTask;
+  RefPtr<CancelableRunnable> mSetNeedsCompositeTask;
 
 #ifdef MOZ_WIDGET_GONK
 #if ANDROID_VERSION >= 19
   bool mDisplayEnabled;
   mozilla::Monitor mSetDisplayMonitor;
-  CancelableTask* mSetDisplayTask;
+  RefPtr<CancelableRunnable> mSetDisplayTask;
 #endif
 #endif
 };
 
 class CompositorUpdateObserver
 {
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorUpdateObserver);
@@ -519,17 +521,17 @@ protected:
   void DeferredDestroy();
 
   virtual PLayerTransactionParent*
     AllocPLayerTransactionParent(const nsTArray<LayersBackend>& aBackendHints,
                                  const uint64_t& aId,
                                  TextureFactoryIdentifier* aTextureFactoryIdentifier,
                                  bool* aSuccess) override;
   virtual bool DeallocPLayerTransactionParent(PLayerTransactionParent* aLayers) override;
-  virtual void ScheduleTask(CancelableTask*, int);
+  virtual void ScheduleTask(already_AddRefed<CancelableRunnable>, int);
   void CompositeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect = nullptr);
 
   void SetEGLSurfaceSize(int width, int height);
 
   void InitializeLayerManager(const nsTArray<LayersBackend>& aBackendHints);
   void PauseComposition();
   void ResumeComposition();
   void ResumeCompositionAndResize(int width, int height);
@@ -581,17 +583,17 @@ protected:
   mozilla::Monitor mPauseCompositionMonitor;
   mozilla::Monitor mResumeCompositionMonitor;
   mozilla::Monitor mResetCompositorMonitor;
 
   uint64_t mCompositorID;
   const uint64_t mRootLayerTreeID;
 
   bool mOverrideComposeReadiness;
-  CancelableTask* mForceCompositionTask;
+  RefPtr<CancelableRunnable> mForceCompositionTask;
 
   RefPtr<APZCTreeManager> mApzcTreeManager;
 
   RefPtr<CompositorThreadHolder> mCompositorThreadHolder;
   RefPtr<CompositorVsyncScheduler> mCompositorScheduler;
   // This makes sure the compositorParent is not destroyed before receiving
   // confirmation that the channel is closed.
   // mSelfRef is cleared in DeferredDestroy which is scheduled by ActorDestroy.
--- a/gfx/layers/ipc/ImageBridgeChild.cpp
+++ b/gfx/layers/ipc/ImageBridgeChild.cpp
@@ -9,17 +9,16 @@
 #include "ImageContainer.h"             // for ImageContainer
 #include "Layers.h"                     // for Layer, etc
 #include "ShadowLayers.h"               // for ShadowLayerForwarder
 #include "base/message_loop.h"          // for MessageLoop
 #include "base/platform_thread.h"       // for PlatformThread
 #include "base/process.h"               // for ProcessId
 #include "base/task.h"                  // for NewRunnableFunction, etc
 #include "base/thread.h"                // for Thread
-#include "base/tracked.h"               // for FROM_HERE
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/Monitor.h"            // for Monitor, MonitorAutoLock
 #include "mozilla/ReentrantMonitor.h"   // for ReentrantMonitor, etc
 #include "mozilla/ipc/MessageChannel.h" // for MessageChannel, etc
 #include "mozilla/ipc/Transport.h"      // for Transport
 #include "mozilla/gfx/Point.h"          // for IntSize
 #include "mozilla/layers/AsyncCanvasRenderer.h"
 #include "mozilla/media/MediaSystemResourceManager.h" // for MediaSystemResourceManager
@@ -349,18 +348,19 @@ ImageBridgeChild::ImageBridgeChild()
   SetMessageLoopToPostDestructionTo(MessageLoop::current());
 
   mTxn = new CompositableTransaction();
 }
 ImageBridgeChild::~ImageBridgeChild()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
-                                   new DeleteTask<Transport>(GetTransport()));
+  RefPtr<DeleteTask<Transport>> task = new DeleteTask<Transport>(GetTransport());
+
+  XRE_GetIOMessageLoop()->PostTask(task.forget());
 
   delete mTxn;
 }
 
 void
 ImageBridgeChild::MarkShutDown()
 {
   MOZ_ASSERT(!mShuttingDown);
@@ -432,18 +432,17 @@ ConnectImageBridgeInChildProcess(Transpo
 {
   // Bind the IPC channel to the image bridge thread.
   sImageBridgeChildSingleton->Open(aTransport, aOtherPid,
                                    XRE_GetIOMessageLoop(),
                                    ipc::ChildSide);
 #ifdef MOZ_NUWA_PROCESS
   if (IsNuwaProcess()) {
     sImageBridgeChildThread
-      ->message_loop()->PostTask(FROM_HERE,
-                                 NewRunnableFunction(NuwaMarkCurrentThread,
+      ->message_loop()->PostTask(NewRunnableFunction(NuwaMarkCurrentThread,
                                                      (void (*)(void *))nullptr,
                                                      (void *)nullptr));
   }
 #endif
 }
 
 static void ReleaseImageClientNow(ImageClient* aClient,
                                   PImageContainerChild* aChild)
@@ -476,17 +475,16 @@ void ImageBridgeChild::DispatchReleaseIm
       MOZ_ASSERT(aClient->GetIPDLActor() == nullptr);
       aClient->Release();
     }
     delete aChild;
     return;
   }
 
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
-    FROM_HERE,
     NewRunnableFunction(&ReleaseImageClientNow, aClient, aChild));
 }
 
 static void ReleaseCanvasClientNow(CanvasClient* aClient)
 {
   MOZ_ASSERT(InImageBridgeChildThread());
   aClient->Release();
 }
@@ -505,17 +503,16 @@ void ImageBridgeChild::DispatchReleaseCa
     // has already shut down, along with the CompositableChild, which means no
     // message will be sent and it is safe to run this code from any thread.
     MOZ_ASSERT(aClient->GetIPDLActor() == nullptr);
     aClient->Release();
     return;
   }
 
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
-    FROM_HERE,
     NewRunnableFunction(&ReleaseCanvasClientNow, aClient));
 }
 
 static void ReleaseTextureClientNow(TextureClient* aClient)
 {
   MOZ_ASSERT(InImageBridgeChildThread());
   RELEASE_MANUALLY(aClient);
 }
@@ -534,17 +531,16 @@ void ImageBridgeChild::DispatchReleaseTe
     // has already shut down, along with the TextureChild, which means no
     // message will be sent and it is safe to run this code from any thread.
     MOZ_ASSERT(aClient->GetIPDLActor() == nullptr);
     RELEASE_MANUALLY(aClient);
     return;
   }
 
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
-    FROM_HERE,
     NewRunnableFunction(&ReleaseTextureClientNow, aClient));
 }
 
 static void UpdateImageClientNow(ImageClient* aClient, RefPtr<ImageContainer>&& aContainer)
 {
   if (!ImageBridgeChild::IsCreated() || ImageBridgeChild::IsShutDown()) {
     NS_WARNING("Something is holding on to graphics resources after the shutdown"
                "of the graphics subsystem!");
@@ -570,17 +566,16 @@ void ImageBridgeChild::DispatchImageClie
     return;
   }
 
   if (InImageBridgeChildThread()) {
     UpdateImageClientNow(aClient, aContainer);
     return;
   }
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
-    FROM_HERE,
     NewRunnableFunction(&UpdateImageClientNow, aClient, RefPtr<ImageContainer>(aContainer)));
 }
 
 static void UpdateAsyncCanvasRendererSync(AsyncCanvasRenderer* aWrapper,
                                           ReentrantMonitor* aBarrier,
                                           bool* const outDone)
 {
   ImageBridgeChild::UpdateAsyncCanvasRendererNow(aWrapper);
@@ -600,17 +595,16 @@ void ImageBridgeChild::UpdateAsyncCanvas
     return;
   }
 
   ReentrantMonitor barrier("UpdateAsyncCanvasRenderer Lock");
   ReentrantMonitorAutoEnter autoMon(barrier);
   bool done = false;
 
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
-    FROM_HERE,
     NewRunnableFunction(&UpdateAsyncCanvasRendererSync, aWrapper, &barrier, &done));
 
   // should stop the thread until the CanvasClient has been created on
   // the other thread
   while (!done) {
     barrier.Wait();
   }
 }
@@ -691,17 +685,16 @@ void ImageBridgeChild::FlushAllImages(Im
 
   RefPtr<AsyncTransactionWaiter> waiter;
 #ifdef MOZ_WIDGET_GONK
   waiter = new AsyncTransactionWaiter();
   // This increment is balanced by the decrement in FlushAllImagesSync
   waiter->IncrementWaitCount();
 #endif
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
-    FROM_HERE,
     NewRunnableFunction(&FlushAllImagesSync, aClient, aContainer, waiter, &barrier, &done));
 
   while (!done) {
     barrier.Wait();
   }
 
 #ifdef MOZ_WIDGET_GONK
   waiter->WaitComplete();
@@ -785,21 +778,19 @@ ImageBridgeChild::StartUpInChildProcess(
 
   sImageBridgeChildThread = new ImageBridgeThread();
   if (!sImageBridgeChildThread->Start()) {
     return nullptr;
   }
 
   sImageBridgeChildSingleton = new ImageBridgeChild();
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
-    FROM_HERE,
     NewRunnableFunction(ConnectImageBridgeInChildProcess,
                         aTransport, aOtherPid));
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
-    FROM_HERE,
     NewRunnableFunction(CallSendImageBridgeThreadId,
                         sImageBridgeChildSingleton.get()));
 
   return sImageBridgeChildSingleton;
 }
 
 void ImageBridgeChild::ShutDown()
 {
@@ -810,29 +801,29 @@ void ImageBridgeChild::ShutDown()
   if (ImageBridgeChild::IsCreated()) {
     MOZ_ASSERT(!sImageBridgeChildSingleton->mShuttingDown);
 
     {
       ReentrantMonitor barrier("ImageBridge ShutdownStep1 lock");
       ReentrantMonitorAutoEnter autoMon(barrier);
 
       bool done = false;
-      sImageBridgeChildSingleton->GetMessageLoop()->PostTask(FROM_HERE,
+      sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
                       NewRunnableFunction(&ImageBridgeShutdownStep1, &barrier, &done));
       while (!done) {
         barrier.Wait();
       }
     }
 
     {
       ReentrantMonitor barrier("ImageBridge ShutdownStep2 lock");
       ReentrantMonitorAutoEnter autoMon(barrier);
 
       bool done = false;
-      sImageBridgeChildSingleton->GetMessageLoop()->PostTask(FROM_HERE,
+      sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
                       NewRunnableFunction(&ImageBridgeShutdownStep2, &barrier, &done));
       while (!done) {
         barrier.Wait();
       }
     }
 
     sImageBridgeChildSingleton = nullptr;
 
@@ -849,17 +840,16 @@ bool ImageBridgeChild::StartUpOnThread(T
     if (!aThread->IsRunning()) {
       aThread->Start();
     }
     sImageBridgeChildSingleton = new ImageBridgeChild();
     sImageBridgeParentSingleton = new ImageBridgeParent(
       CompositorBridgeParent::CompositorLoop(), nullptr, base::GetCurrentProcId());
     sImageBridgeChildSingleton->ConnectAsync(sImageBridgeParentSingleton);
     sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
-      FROM_HERE,
       NewRunnableFunction(CallSendImageBridgeThreadId,
                           sImageBridgeChildSingleton.get()));
     return true;
   } else {
     return false;
   }
 }
 
@@ -871,18 +861,18 @@ bool InImageBridgeChildThread()
 
 MessageLoop * ImageBridgeChild::GetMessageLoop() const
 {
   return sImageBridgeChildThread ? sImageBridgeChildThread->message_loop() : nullptr;
 }
 
 void ImageBridgeChild::ConnectAsync(ImageBridgeParent* aParent)
 {
-  GetMessageLoop()->PostTask(FROM_HERE, NewRunnableFunction(&ConnectImageBridge,
-                                                            this, aParent));
+  GetMessageLoop()->PostTask(NewRunnableFunction(&ConnectImageBridge,
+                                                 this, aParent));
 }
 
 void
 ImageBridgeChild::IdentifyCompositorTextureHost(const TextureFactoryIdentifier& aIdentifier)
 {
   if (sImageBridgeChildSingleton) {
     sImageBridgeChildSingleton->IdentifyTextureHost(aIdentifier);
   }
@@ -895,17 +885,17 @@ ImageBridgeChild::CreateImageClient(Comp
   if (InImageBridgeChildThread()) {
     return CreateImageClientNow(aType, aImageContainer);
   }
   ReentrantMonitor barrier("CreateImageClient Lock");
   ReentrantMonitorAutoEnter autoMon(barrier);
   bool done = false;
 
   RefPtr<ImageClient> result = nullptr;
-  GetMessageLoop()->PostTask(FROM_HERE,
+  GetMessageLoop()->PostTask(
       NewRunnableFunction(&CreateImageClientSync, &result, &barrier, aType,
                           aImageContainer, &done));
   // should stop the thread until the ImageClient has been created on
   // the other thread
   while (!done) {
     barrier.Wait();
   }
   return result.forget();
@@ -935,18 +925,17 @@ ImageBridgeChild::CreateCanvasClient(Can
   if (InImageBridgeChildThread()) {
     return CreateCanvasClientNow(aType, aFlag);
   }
   ReentrantMonitor barrier("CreateCanvasClient Lock");
   ReentrantMonitorAutoEnter autoMon(barrier);
   bool done = false;
 
   RefPtr<CanvasClient> result = nullptr;
-  GetMessageLoop()->PostTask(FROM_HERE,
-                             NewRunnableFunction(&CreateCanvasClientSync,
+  GetMessageLoop()->PostTask(NewRunnableFunction(&CreateCanvasClientSync,
                                  &barrier, aType, aFlag, &result, &done));
   // should stop the thread until the CanvasClient has been created on the
   // other thread
   while (!done) {
     barrier.Wait();
   }
   return result.forget();
 }
@@ -1035,18 +1024,17 @@ ImageBridgeChild::DispatchAllocShmemInte
   ReentrantMonitor barrier("AllocatorProxy alloc");
   ReentrantMonitorAutoEnter autoMon(barrier);
 
   AllocShmemParams params = {
     this, aSize, aType, aShmem, aUnsafe, true
   };
   bool done = false;
 
-  GetMessageLoop()->PostTask(FROM_HERE,
-                             NewRunnableFunction(&ProxyAllocShmemNow,
+  GetMessageLoop()->PostTask(NewRunnableFunction(&ProxyAllocShmemNow,
                                                  &params,
                                                  &barrier,
                                                  &done));
   while (!done) {
     barrier.Wait();
   }
   return params.mSuccess;
 }
@@ -1072,18 +1060,17 @@ ImageBridgeChild::DeallocShmem(ipc::Shme
 {
   if (InImageBridgeChildThread()) {
     PImageBridgeChild::DeallocShmem(aShmem);
   } else {
     ReentrantMonitor barrier("AllocatorProxy Dealloc");
     ReentrantMonitorAutoEnter autoMon(barrier);
 
     bool done = false;
-    GetMessageLoop()->PostTask(FROM_HERE,
-                               NewRunnableFunction(&ProxyDeallocShmemNow,
+    GetMessageLoop()->PostTask(NewRunnableFunction(&ProxyDeallocShmemNow,
                                                    this,
                                                    &aShmem,
                                                    &barrier,
                                                    &done));
     while (!done) {
       barrier.Wait();
     }
   }
--- a/gfx/layers/ipc/ImageBridgeParent.cpp
+++ b/gfx/layers/ipc/ImageBridgeParent.cpp
@@ -5,17 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ImageBridgeParent.h"
 #include <stdint.h>                     // for uint64_t, uint32_t
 #include "CompositableHost.h"           // for CompositableParent, Create
 #include "base/message_loop.h"          // for MessageLoop
 #include "base/process.h"               // for ProcessId
 #include "base/task.h"                  // for CancelableTask, DeleteTask, etc
-#include "base/tracked.h"               // for FROM_HERE
 #include "mozilla/gfx/Point.h"                   // for IntSize
 #include "mozilla/Hal.h"                // for hal::SetCurrentThreadPriority()
 #include "mozilla/HalTypes.h"           // for hal::THREAD_PRIORITY_COMPOSITOR
 #include "mozilla/ipc/MessageChannel.h" // for MessageChannel, etc
 #include "mozilla/ipc/ProtocolUtils.h"
 #include "mozilla/ipc/Transport.h"      // for Transport
 #include "mozilla/ipc/GeckoChildProcessHost.h"
 #include "mozilla/media/MediaSystemResourceManagerParent.h" // for MediaSystemResourceManagerParent
@@ -78,18 +77,18 @@ ImageBridgeParent::ImageBridgeParent(Mes
 }
 
 ImageBridgeParent::~ImageBridgeParent()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (mTransport) {
     MOZ_ASSERT(XRE_GetIOMessageLoop());
-    XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
-                                     new DeleteTask<Transport>(mTransport));
+    RefPtr<DeleteTask<Transport>> task(new DeleteTask<Transport>(mTransport));
+    XRE_GetIOMessageLoop()->PostTask(task.forget());
   }
 
   nsTArray<PImageContainerParent*> parents;
   ManagedPImageContainerParent(parents);
   for (PImageContainerParent* p : parents) {
     delete p;
   }
 
@@ -103,17 +102,16 @@ ImageBridgeParent::ActorDestroy(ActorDes
   mClosed = true;
 
   if (mSubprocess) {
     mSubprocess->DissociateActor();
     mSubprocess = nullptr;
   }
 
   MessageLoop::current()->PostTask(
-    FROM_HERE,
     NewRunnableMethod(this, &ImageBridgeParent::DeferredDestroy));
 
   // It is very important that this method gets called at shutdown (be it a clean
   // or an abnormal shutdown), because DeferredDestroy is what clears mSelfRef.
   // If mSelfRef is not null and ActorDestroy is not called, the ImageBridgeParent
   // is leaked which causes the CompositorThreadHolder to be leaked and
   // CompsoitorParent's shutdown ends up spinning the event loop forever, waiting
   // for the compositor thread to terminate.
@@ -206,18 +204,17 @@ ImageBridgeParent::Create(Transport* aTr
   MessageLoop* loop = CompositorBridgeParent::CompositorLoop();
   RefPtr<ImageBridgeParent> bridge = new ImageBridgeParent(loop, aTransport, aChildProcessId);
 
   if (aProcessHost) {
     bridge->mSubprocess = aProcessHost;
     aProcessHost->AssociateActor();
   }
 
-  loop->PostTask(FROM_HERE,
-                 NewRunnableFunction(ConnectImageBridgeInParentProcess,
+  loop->PostTask(NewRunnableFunction(ConnectImageBridgeInParentProcess,
                                      bridge.get(), aTransport, aChildProcessId));
   return bridge.get();
 }
 
 bool ImageBridgeParent::RecvWillClose()
 {
   // If there is any texture still alive we have to force it to deallocate the
   // device data (GL textures, etc.) now because shortly after SenStop() returns
--- a/gfx/layers/ipc/RemoteContentController.cpp
+++ b/gfx/layers/ipc/RemoteContentController.cpp
@@ -54,17 +54,16 @@ void
 RemoteContentController::HandleDoubleTap(const CSSPoint& aPoint,
                                          Modifiers aModifiers,
                                          const ScrollableLayerGuid& aGuid)
 {
   if (MessageLoop::current() != mUILoop) {
     // We have to send this message from the "UI thread" (main
     // thread).
     mUILoop->PostTask(
-      FROM_HERE,
       NewRunnableMethod(this, &RemoteContentController::HandleDoubleTap,
                         aPoint, aModifiers, aGuid));
     return;
   }
   if (CanSend()) {
     Unused << SendHandleDoubleTap(mBrowserParent->AdjustTapToChildWidget(aPoint),
             aModifiers, aGuid);
   }
@@ -74,17 +73,16 @@ void
 RemoteContentController::HandleSingleTap(const CSSPoint& aPoint,
                                          Modifiers aModifiers,
                                          const ScrollableLayerGuid& aGuid)
 {
   if (MessageLoop::current() != mUILoop) {
     // We have to send this message from the "UI thread" (main
     // thread).
     mUILoop->PostTask(
-      FROM_HERE,
       NewRunnableMethod(this, &RemoteContentController::HandleSingleTap,
                         aPoint, aModifiers, aGuid));
     return;
   }
 
   bool callTakeFocusForClickFromTap;
   layout::RenderFrameParent* frame;
   if (mBrowserParent && (frame = mBrowserParent->GetRenderFrame()) &&
@@ -108,35 +106,34 @@ RemoteContentController::HandleLongTap(c
                                        Modifiers aModifiers,
                                        const ScrollableLayerGuid& aGuid,
                                        uint64_t aInputBlockId)
 {
   if (MessageLoop::current() != mUILoop) {
     // We have to send this message from the "UI thread" (main
     // thread).
     mUILoop->PostTask(
-      FROM_HERE,
       NewRunnableMethod(this, &RemoteContentController::HandleLongTap,
                         aPoint, aModifiers, aGuid, aInputBlockId));
     return;
   }
   if (CanSend()) {
     Unused << SendHandleLongTap(mBrowserParent->AdjustTapToChildWidget(aPoint),
             aModifiers, aGuid, aInputBlockId);
   }
 }
 
 void
-RemoteContentController::PostDelayedTask(Task* aTask, int aDelayMs)
+RemoteContentController::PostDelayedTask(already_AddRefed<Runnable> aTask, int aDelayMs)
 {
 #ifdef MOZ_ANDROID_APZ
-  AndroidBridge::Bridge()->PostTaskToUiThread(aTask, aDelayMs);
+  AndroidBridge::Bridge()->PostTaskToUiThread(Move(aTask), aDelayMs);
 #else
   (MessageLoop::current() ? MessageLoop::current() : mUILoop)->
-     PostDelayedTask(FROM_HERE, aTask, aDelayMs);
+    PostDelayedTask(Move(aTask), aDelayMs);
 #endif
 }
 
 bool
 RemoteContentController::GetTouchSensitiveRegion(CSSRect* aOutRegion)
 {
   MutexAutoLock lock(mMutex);
   if (mTouchSensitiveRegion.IsEmpty()) {
@@ -149,33 +146,31 @@ RemoteContentController::GetTouchSensiti
 
 void
 RemoteContentController::NotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
                                               APZStateChange aChange,
                                               int aArg)
 {
   if (MessageLoop::current() != mUILoop) {
     mUILoop->PostTask(
-      FROM_HERE,
       NewRunnableMethod(this, &RemoteContentController::NotifyAPZStateChange,
                         aGuid, aChange, aArg));
     return;
   }
   if (CanSend()) {
     Unused << SendNotifyAPZStateChange(aGuid.mScrollId, aChange, aArg);
   }
 }
 
 void
 RemoteContentController::NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId,
                                                    const nsString& aEvent)
 {
   if (MessageLoop::current() != mUILoop) {
     mUILoop->PostTask(
-      FROM_HERE,
       NewRunnableMethod(this, &RemoteContentController::NotifyMozMouseScrollEvent,
                         aScrollId, aEvent));
     return;
   }
 
   if (mBrowserParent) {
     Unused << mBrowserParent->SendMouseScrollTestEvent(mLayersId, aScrollId, aEvent);
   }
--- a/gfx/layers/ipc/RemoteContentController.h
+++ b/gfx/layers/ipc/RemoteContentController.h
@@ -50,17 +50,17 @@ public:
                                Modifiers aModifiers,
                                const ScrollableLayerGuid& aGuid) override;
 
   virtual void HandleLongTap(const CSSPoint& aPoint,
                              Modifiers aModifiers,
                              const ScrollableLayerGuid& aGuid,
                              uint64_t aInputBlockId) override;
 
-  virtual void PostDelayedTask(Task* aTask, int aDelayMs) override;
+  virtual void PostDelayedTask(already_AddRefed<Runnable> aTask, int aDelayMs) override;
 
   virtual bool GetTouchSensitiveRegion(CSSRect* aOutRegion) override;
 
   virtual void NotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
                                     APZStateChange aChange,
                                     int aArg) override;
 
   virtual void NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId,
--- a/gfx/layers/ipc/SharedBufferManagerChild.cpp
+++ b/gfx/layers/ipc/SharedBufferManagerChild.cpp
@@ -2,17 +2,16 @@
  * vim: sw=2 ts=8 et :
  */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "base/task.h"                  // for NewRunnableFunction, etc
 #include "base/thread.h"                // for Thread
-#include "base/tracked.h"               // for FROM_HERE
 #include "mozilla/gfx/Logging.h"        // for gfxDebug
 #include "mozilla/layers/SharedBufferManagerChild.h"
 #include "mozilla/layers/SharedBufferManagerParent.h"
 #include "mozilla/StaticPtr.h"          // for StaticRefPtr
 #include "mozilla/ReentrantMonitor.h"   // for ReentrantMonitor, etc
 #include "nsThreadUtils.h"              // fo NS_IsMainThread
 
 #ifdef MOZ_NUWA_PROCESS
@@ -102,18 +101,17 @@ ConnectSharedBufferManagerInChildProcess
   SharedBufferManagerChild::sSharedBufferManagerChildSingleton->Open(aTransport,
                                                                      aOtherPid,
                                                                      XRE_GetIOMessageLoop(),
                                                                      ipc::ChildSide);
 
 #ifdef MOZ_NUWA_PROCESS
   if (IsNuwaProcess()) {
     SharedBufferManagerChild::sSharedBufferManagerChildThread
-      ->message_loop()->PostTask(FROM_HERE,
-                                 NewRunnableFunction(NuwaMarkCurrentThread,
+      ->message_loop()->PostTask(NewRunnableFunction(NuwaMarkCurrentThread,
                                                      (void (*)(void *))nullptr,
                                                      (void *)nullptr));
   }
 #endif
 }
 
 PSharedBufferManagerChild*
 SharedBufferManagerChild::StartUpInChildProcess(Transport* aTransport,
@@ -123,17 +121,16 @@ SharedBufferManagerChild::StartUpInChild
 
   sSharedBufferManagerChildThread = new base::Thread("BufferMgrChild");
   if (!sSharedBufferManagerChildThread->Start()) {
     return nullptr;
   }
 
   sSharedBufferManagerChildSingleton = new SharedBufferManagerChild();
   sSharedBufferManagerChildSingleton->GetMessageLoop()->PostTask(
-    FROM_HERE,
     NewRunnableFunction(ConnectSharedBufferManagerInChildProcess,
                         aTransport, aOtherPid));
 
   return sSharedBufferManagerChildSingleton;
 }
 
 void
 SharedBufferManagerChild::ShutDown()
@@ -178,17 +175,17 @@ SharedBufferManagerChild::DestroyManager
   if (!IsCreated()) {
     return;
   }
 
   ReentrantMonitor barrier("BufferManagerDestroyTask lock");
   ReentrantMonitorAutoEnter autoMon(barrier);
 
   bool done = false;
-  sSharedBufferManagerChildSingleton->GetMessageLoop()->PostTask(FROM_HERE,
+  sSharedBufferManagerChildSingleton->GetMessageLoop()->PostTask(
     NewRunnableFunction(&DeleteSharedBufferManagerSync, &barrier, &done));
   while (!done) {
     barrier.Wait();
   }
 
 }
 
 MessageLoop *
@@ -197,18 +194,18 @@ SharedBufferManagerChild::GetMessageLoop
   return sSharedBufferManagerChildThread != nullptr ?
       sSharedBufferManagerChildThread->message_loop() :
       nullptr;
 }
 
 void
 SharedBufferManagerChild::ConnectAsync(SharedBufferManagerParent* aParent)
 {
-  GetMessageLoop()->PostTask(FROM_HERE, NewRunnableFunction(&ConnectSharedBufferManager,
-                                                            this, aParent));
+  GetMessageLoop()->PostTask(NewRunnableFunction(&ConnectSharedBufferManager,
+                                                 this, aParent));
 }
 
 // dispatched function
 void
 SharedBufferManagerChild::AllocGrallocBufferSync(const GrallocParam& aParam,
                                                  Monitor* aBarrier,
                                                  bool* aDone)
 {
@@ -245,17 +242,16 @@ SharedBufferManagerChild::AllocGrallocBu
     return SharedBufferManagerChild::AllocGrallocBufferNow(aSize, aFormat, aUsage, aBuffer);
   }
 
   Monitor barrier("AllocSurfaceDescriptorGralloc Lock");
   MonitorAutoLock autoMon(barrier);
   bool done = false;
 
   GetMessageLoop()->PostTask(
-    FROM_HERE,
     NewRunnableFunction(&AllocGrallocBufferSync,
                         GrallocParam(aSize, aFormat, aUsage, aBuffer), &barrier, &done));
 
   while (!done) {
     barrier.Wait();
   }
   return true;
 }
@@ -300,18 +296,17 @@ SharedBufferManagerChild::DeallocGralloc
     return;
   }
 #endif
 
   if (InSharedBufferManagerChildThread()) {
     return SharedBufferManagerChild::DeallocGrallocBufferNow(aBuffer);
   }
 
-  GetMessageLoop()->PostTask(FROM_HERE, NewRunnableFunction(&DeallocGrallocBufferSync,
-                                                            aBuffer));
+  GetMessageLoop()->PostTask(NewRunnableFunction(&DeallocGrallocBufferSync, aBuffer));
 }
 
 void
 SharedBufferManagerChild::DeallocGrallocBufferNow(const mozilla::layers::MaybeMagicGrallocBufferHandle& aBuffer)
 {
 #ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
   NS_ASSERTION(aBuffer.type() != mozilla::layers::MaybeMagicGrallocBufferHandle::TMagicGrallocBufferHandle, "We shouldn't try to do IPC with real buffer");
 
--- a/gfx/layers/ipc/SharedBufferManagerParent.cpp
+++ b/gfx/layers/ipc/SharedBufferManagerParent.cpp
@@ -3,17 +3,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/layers/SharedBufferManagerParent.h"
 #include "base/message_loop.h"          // for MessageLoop
 #include "base/process.h"               // for ProcessId
 #include "base/task.h"                  // for CancelableTask, DeleteTask, etc
-#include "base/tracked.h"               // for FROM_HERE
 #include "base/thread.h"
 #include "mozilla/ipc/MessageChannel.h" // for MessageChannel, etc
 #include "mozilla/ipc/ProtocolUtils.h"
 #include "mozilla/ipc/Transport.h"      // for Transport
 #include "mozilla/UniquePtr.h"          // for UniquePtr
 #include "mozilla/unused.h"
 #include "nsIMemoryReporter.h"
 #ifdef MOZ_WIDGET_GONK
@@ -110,23 +109,23 @@ void InitGralloc() {
 #ifdef MOZ_WIDGET_GONK
   RegisterStrongMemoryReporter(new GrallocReporter());
 #endif
 }
 
 /**
  * Task that deletes SharedBufferManagerParent on a specified thread.
  */
-class DeleteSharedBufferManagerParentTask : public Task
+class DeleteSharedBufferManagerParentTask : public Runnable
 {
 public:
     explicit DeleteSharedBufferManagerParentTask(UniquePtr<SharedBufferManagerParent> aSharedBufferManager)
         : mSharedBufferManager(Move(aSharedBufferManager)) {
     }
-    virtual void Run() override {}
+    NS_IMETHOD Run() override { return NS_OK; }
 private:
     UniquePtr<SharedBufferManagerParent> mSharedBufferManager;
 };
 
 SharedBufferManagerParent::SharedBufferManagerParent(Transport* aTransport, base::ProcessId aOwner, base::Thread* aThread)
   : mTransport(aTransport)
   , mThread(aThread)
   , mMainMessageLoop(MessageLoop::current())
@@ -150,34 +149,34 @@ SharedBufferManagerParent::SharedBufferM
   mOwner = aOwner;
   sManagers[aOwner] = this;
 }
 
 SharedBufferManagerParent::~SharedBufferManagerParent()
 {
   MonitorAutoLock lock(*sManagerMonitor.get());
   if (mTransport) {
-    XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
-                                     new DeleteTask<Transport>(mTransport));
+    RefPtr<DeleteTask<Transport>> task = new DeleteTask<Transport>(mTransport);
+    XRE_GetIOMessageLoop()->PostTask(task.forget());
   }
   sManagers.erase(mOwner);
   delete mThread;
 }
 
 void
 SharedBufferManagerParent::ActorDestroy(ActorDestroyReason aWhy)
 {
   MutexAutoLock lock(mLock);
   mDestroyed = true;
 #ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
   mBuffers.clear();
 #endif
-  DeleteSharedBufferManagerParentTask* task =
+  RefPtr<DeleteSharedBufferManagerParentTask> task =
     new DeleteSharedBufferManagerParentTask(UniquePtr<SharedBufferManagerParent>(this));
-  mMainMessageLoop->PostTask(FROM_HERE, task);
+  mMainMessageLoop->PostTask(task.forget());
 }
 
 static void
 ConnectSharedBufferManagerInParentProcess(SharedBufferManagerParent* aManager,
                                           Transport* aTransport,
                                           base::ProcessId aOtherPid)
 {
   aManager->Open(aTransport, aOtherPid, XRE_GetIOMessageLoop(), ipc::ParentSide);
@@ -190,18 +189,17 @@ PSharedBufferManagerParent* SharedBuffer
   char thrname[128];
   base::snprintf(thrname, 128, "BufMgrParent#%d", aOtherPid);
   thread = new base::Thread(thrname);
 
   SharedBufferManagerParent* manager = new SharedBufferManagerParent(aTransport, aOtherPid, thread);
   if (!thread->IsRunning()) {
     thread->Start();
   }
-  thread->message_loop()->PostTask(FROM_HERE,
-                                   NewRunnableFunction(ConnectSharedBufferManagerInParentProcess,
+  thread->message_loop()->PostTask(NewRunnableFunction(ConnectSharedBufferManagerInParentProcess,
                                                        manager, aTransport, aOtherPid));
   return manager;
 }
 
 bool SharedBufferManagerParent::RecvAllocateGrallocBuffer(const IntSize& aSize, const uint32_t& aFormat, const uint32_t& aUsage, mozilla::layers::MaybeMagicGrallocBufferHandle* aHandle)
 {
 #ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
 
@@ -292,17 +290,17 @@ void SharedBufferManagerParent::DropGral
   MutexAutoLock mgrlock(mgr->mLock);
   if (mgr->mDestroyed) {
     return;
   }
 
   if (PlatformThread::CurrentId() == mgr->mThread->thread_id()) {
     MOZ_CRASH("GFX: SharedBufferManagerParent::DropGrallocBuffer should not be called on SharedBufferManagerParent thread");
   } else {
-    mgr->mThread->message_loop()->PostTask(FROM_HERE,
+    mgr->mThread->message_loop()->PostTask(
                                       NewRunnableFunction(&DropGrallocBufferSync, mgr, aDesc));
   }
   return;
 }
 
 void SharedBufferManagerParent::DropGrallocBufferImpl(mozilla::layers::SurfaceDescriptor aDesc)
 {
   MutexAutoLock lock(mLock);
--- a/gfx/thebes/SoftwareVsyncSource.cpp
+++ b/gfx/thebes/SoftwareVsyncSource.cpp
@@ -18,18 +18,17 @@ SoftwareVsyncSource::SoftwareVsyncSource
 SoftwareVsyncSource::~SoftwareVsyncSource()
 {
   MOZ_ASSERT(NS_IsMainThread());
   mGlobalDisplay->Shutdown();
   mGlobalDisplay = nullptr;
 }
 
 SoftwareDisplay::SoftwareDisplay()
-  : mCurrentVsyncTask(nullptr)
-  , mVsyncEnabled(false)
+  : mVsyncEnabled(false)
 {
   // Mimic 60 fps
   MOZ_ASSERT(NS_IsMainThread());
   const double rate = 1000.0 / (double) gfxPlatform::GetSoftwareVsyncRate();
   mVsyncRate = mozilla::TimeDuration::FromMilliseconds(rate);
   mVsyncThread = new base::Thread("SoftwareVsyncThread");
   MOZ_RELEASE_ASSERT(mVsyncThread->Start(), "Could not start software vsync thread");
 }
@@ -41,17 +40,17 @@ SoftwareDisplay::EnableVsync()
 {
   MOZ_ASSERT(mVsyncThread->IsRunning());
   if (NS_IsMainThread()) {
     if (mVsyncEnabled) {
       return;
     }
     mVsyncEnabled = true;
 
-    mVsyncThread->message_loop()->PostTask(FROM_HERE,
+    mVsyncThread->message_loop()->PostTask(
       NewRunnableMethod(this, &SoftwareDisplay::EnableVsync));
     return;
   }
 
   MOZ_ASSERT(IsInSoftwareVsyncThread());
   NotifyVsync(mozilla::TimeStamp::Now());
 }
 
@@ -60,17 +59,17 @@ SoftwareDisplay::DisableVsync()
 {
   MOZ_ASSERT(mVsyncThread->IsRunning());
   if (NS_IsMainThread()) {
     if (!mVsyncEnabled) {
       return;
     }
     mVsyncEnabled = false;
 
-    mVsyncThread->message_loop()->PostTask(FROM_HERE,
+    mVsyncThread->message_loop()->PostTask(
       NewRunnableMethod(this, &SoftwareDisplay::DisableVsync));
     return;
   }
 
   MOZ_ASSERT(IsInSoftwareVsyncThread());
   if (mCurrentVsyncTask) {
     mCurrentVsyncTask->Cancel();
     mCurrentVsyncTask = nullptr;
@@ -128,18 +127,19 @@ SoftwareDisplay::ScheduleNextVsync(mozil
     delay = mozilla::TimeDuration::FromMilliseconds(0);
     nextVsync = mozilla::TimeStamp::Now();
   }
 
   mCurrentVsyncTask = NewRunnableMethod(this,
       &SoftwareDisplay::NotifyVsync,
       nextVsync);
 
-  mVsyncThread->message_loop()->PostDelayedTask(FROM_HERE,
-      mCurrentVsyncTask,
+  RefPtr<mozilla::CancelableRunnable> addrefedTask = mCurrentVsyncTask;
+  mVsyncThread->message_loop()->PostDelayedTask(
+      addrefedTask.forget(),
       delay.ToMilliseconds());
 }
 
 void
 SoftwareDisplay::Shutdown()
 {
   MOZ_ASSERT(NS_IsMainThread());
   DisableVsync();
--- a/gfx/thebes/SoftwareVsyncSource.h
+++ b/gfx/thebes/SoftwareVsyncSource.h
@@ -9,18 +9,16 @@
 
 #include "mozilla/Monitor.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/TimeStamp.h"
 #include "base/thread.h"
 #include "nsISupportsImpl.h"
 #include "VsyncSource.h"
 
-class CancelableTask;
-
 class SoftwareDisplay final : public mozilla::gfx::VsyncSource::Display
 {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SoftwareDisplay)
 
 public:
   SoftwareDisplay();
   virtual void EnableVsync() override;
   virtual void DisableVsync() override;
@@ -33,17 +31,17 @@ public:
 
 protected:
   ~SoftwareDisplay();
 
 private:
   mozilla::TimeDuration mVsyncRate;
   // Use a chromium thread because nsITimers* fire on the main thread
   base::Thread* mVsyncThread;
-  CancelableTask* mCurrentVsyncTask; // only access on vsync thread
+  RefPtr<mozilla::CancelableRunnable> mCurrentVsyncTask; // only access on vsync thread
   bool mVsyncEnabled; // Only access on main thread
 }; // SoftwareDisplay
 
 // Fallback option to use a software timer to mimic vsync. Useful for gtests
 // To mimic a hardware vsync thread, we create a dedicated software timer
 // vsync thread.
 class SoftwareVsyncSource : public mozilla::gfx::VsyncSource
 {
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -2665,19 +2665,18 @@ public:
         { // scope lock
           MonitorAutoLock lock(mVsyncEnabledLock);
           if (mVsyncEnabled) {
             return;
           }
           mVsyncEnabled = true;
         }
 
-        CancelableTask* vsyncStart = NewRunnableMethod(this,
-            &D3DVsyncDisplay::VBlankLoop);
-        mVsyncThread->message_loop()->PostTask(FROM_HERE, vsyncStart);
+        mVsyncThread->message_loop()->PostTask(
+            NewRunnableMethod(this, &D3DVsyncDisplay::VBlankLoop));
       }
 
       virtual void DisableVsync() override
       {
         MOZ_ASSERT(NS_IsMainThread());
         MOZ_ASSERT(mVsyncThread->IsRunning());
         MonitorAutoLock lock(mVsyncEnabledLock);
         if (!mVsyncEnabled) {
@@ -2704,17 +2703,17 @@ public:
         NS_WARNING("DwmComposition dynamically disabled, falling back to software timers");
 
         TimeStamp nextVsync = aVsyncTimestamp + mSoftwareVsyncRate;
         TimeDuration delay = nextVsync - TimeStamp::Now();
         if (delay.ToMilliseconds() < 0) {
           delay = mozilla::TimeDuration::FromMilliseconds(0);
         }
 
-        mVsyncThread->message_loop()->PostDelayedTask(FROM_HERE,
+        mVsyncThread->message_loop()->PostDelayedTask(
             NewRunnableMethod(this, &D3DVsyncDisplay::VBlankLoop),
             delay.ToMilliseconds());
       }
 
       TimeStamp GetAdjustedVsyncTimeStamp(LARGE_INTEGER& aFrequency,
                                           QPC_TIME& aQpcVblankTime)
       {
         TimeStamp vsync = TimeStamp::Now();
--- a/gfx/vr/ipc/VRManagerChild.cpp
+++ b/gfx/vr/ipc/VRManagerChild.cpp
@@ -33,18 +33,18 @@ VRManagerChild::VRManagerChild()
 VRManagerChild::~VRManagerChild()
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_COUNT_DTOR(VRManagerChild);
 
   Transport* trans = GetTransport();
   if (trans) {
     MOZ_ASSERT(XRE_GetIOMessageLoop());
-    XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
-                                     new DeleteTask<Transport>(trans));
+    RefPtr<DeleteTask<Transport>> task = new DeleteTask<Transport>(trans);
+    XRE_GetIOMessageLoop()->PostTask(task.forget());
   }
 }
 
 /*static*/ VRManagerChild*
 VRManagerChild::Get()
 {
   MOZ_ASSERT(sVRManagerChildSingleton);
   return sVRManagerChildSingleton;
@@ -104,17 +104,17 @@ VRManagerChild::Destroy()
   // This must not be called from the destructor!
   MOZ_ASSERT(mRefCnt != 0);
 
   // Keep ourselves alive until everything has been shut down
   RefPtr<VRManagerChild> selfRef = this;
 
   // The DeferredDestroyVRManager task takes ownership of
   // the VRManagerChild and will release it when it runs.
-  MessageLoop::current()->PostTask(FROM_HERE,
+  MessageLoop::current()->PostTask(
              NewRunnableFunction(DeferredDestroy, selfRef));
 }
 
 bool
 VRManagerChild::RecvUpdateDeviceInfo(nsTArray<VRDeviceUpdate>&& aDeviceUpdates)
 {
   // mDevices could be a hashed container for more scalability, but not worth
   // it now as we expect < 10 entries.
--- a/gfx/vr/ipc/VRManagerParent.cpp
+++ b/gfx/vr/ipc/VRManagerParent.cpp
@@ -39,18 +39,18 @@ VRManagerParent::~VRManagerParent()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   MOZ_ASSERT(!mVRManagerHolder);
 
   Transport* trans = GetTransport();
   if (trans) {
     MOZ_ASSERT(XRE_GetIOMessageLoop());
-    XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
-                                     new DeleteTask<Transport>(trans));
+    RefPtr<DeleteTask<Transport>> task = new DeleteTask<Transport>(trans);
+    XRE_GetIOMessageLoop()->PostTask(task.forget());
   }
   MOZ_COUNT_DTOR(VRManagerParent);
 }
 
 void VRManagerParent::RegisterWithManager()
 {
   VRManager* vm = VRManager::Get();
   vm->AddVRManagerParent(this);
@@ -74,18 +74,17 @@ VRManagerParent::ConnectVRManagerInParen
 }
 
 /*static*/ VRManagerParent*
 VRManagerParent::CreateCrossProcess(Transport* aTransport, ProcessId aChildProcessId)
 {
   MessageLoop* loop = mozilla::layers::CompositorBridgeParent::CompositorLoop();
   RefPtr<VRManagerParent> vmp = new VRManagerParent(loop, aTransport, aChildProcessId);
   vmp->mSelfRef = vmp;
-  loop->PostTask(FROM_HERE,
-                 NewRunnableFunction(ConnectVRManagerInParentProcess,
+  loop->PostTask(NewRunnableFunction(ConnectVRManagerInParentProcess,
                                      vmp.get(), aTransport, aChildProcessId));
   return vmp.get();
 }
 
 /*static*/ void
 VRManagerParent::RegisterVRManagerInCompositorThread(VRManagerParent* aVRManager)
 {
   aVRManager->RegisterWithManager();
@@ -93,34 +92,32 @@ VRManagerParent::RegisterVRManagerInComp
 
 /*static*/ VRManagerParent*
 VRManagerParent::CreateSameProcess()
 {
   MessageLoop* loop = mozilla::layers::CompositorBridgeParent::CompositorLoop();
   RefPtr<VRManagerParent> vmp = new VRManagerParent(loop, nullptr, base::GetCurrentProcId());
   vmp->mCompositorThreadHolder = layers::GetCompositorThreadHolder();
   vmp->mSelfRef = vmp;
-  loop->PostTask(FROM_HERE,
-                 NewRunnableFunction(RegisterVRManagerInCompositorThread, vmp.get()));
+  loop->PostTask(NewRunnableFunction(RegisterVRManagerInCompositorThread, vmp.get()));
   return vmp.get();
 }
 
 void
 VRManagerParent::DeferredDestroy()
 {
   mCompositorThreadHolder = nullptr;
   mSelfRef = nullptr;
 }
 
 void
 VRManagerParent::ActorDestroy(ActorDestroyReason why)
 {
   UnregisterFromManager();
   MessageLoop::current()->PostTask(
-    FROM_HERE,
     NewRunnableMethod(this, &VRManagerParent::DeferredDestroy));
 }
 
 mozilla::ipc::IToplevelProtocol*
 VRManagerParent::CloneToplevel(const InfallibleTArray<mozilla::ipc::ProtocolFdMapping>& aFds,
                                base::ProcessHandle aPeerProcess,
                                mozilla::ipc::ProtocolCloneContext* aCtx)
 {
--- a/ipc/chromium/moz.build
+++ b/ipc/chromium/moz.build
@@ -21,18 +21,16 @@ UNIFIED_SOURCES += [
     'src/base/pickle.cc',
     'src/base/rand_util.cc',
     'src/base/revocable_store.cc',
     'src/base/string_piece.cc',
     'src/base/string_util.cc',
     'src/base/thread.cc',
     'src/base/time.cc',
     'src/base/timer.cc',
-    'src/base/tracked.cc',
-    'src/base/tracked_objects.cc',
     'src/chrome/common/child_process.cc',
     'src/chrome/common/child_process_host.cc',
     'src/chrome/common/child_process_info.cc',
     'src/chrome/common/child_thread.cc',
     'src/chrome/common/chrome_switches.cc',
     'src/chrome/common/ipc_channel.cc',
     'src/chrome/common/ipc_message.cc',
     'src/chrome/common/notification_service.cc',
--- a/ipc/chromium/src/base/message_loop.cc
+++ b/ipc/chromium/src/base/message_loop.cc
@@ -36,16 +36,19 @@
 #endif
 
 #include "MessagePump.h"
 
 using base::Time;
 using base::TimeDelta;
 using base::TimeTicks;
 
+using mozilla::Move;
+using mozilla::Runnable;
+
 static base::ThreadLocalPointer<MessageLoop>& get_tls_ptr() {
   static base::ThreadLocalPointer<MessageLoop> tls_ptr;
   return tls_ptr;
 }
 
 //------------------------------------------------------------------------------
 
 // Logical events for Histogram profiling. Run with -message-loop-histogrammer
@@ -235,86 +238,68 @@ void MessageLoop::RunInternal() {
 
 bool MessageLoop::ProcessNextDelayedNonNestableTask() {
   if (state_->run_depth > run_depth_base_)
     return false;
 
   if (deferred_non_nestable_work_queue_.empty())
     return false;
 
-  Task* task = deferred_non_nestable_work_queue_.front().task;
+  RefPtr<Runnable> task = deferred_non_nestable_work_queue_.front().task.forget();
   deferred_non_nestable_work_queue_.pop();
 
-  RunTask(task);
+  RunTask(task.forget());
   return true;
 }
 
 //------------------------------------------------------------------------------
 
 void MessageLoop::Quit() {
   DCHECK(current() == this);
   if (state_) {
     state_->quit_received = true;
   } else {
     NOTREACHED() << "Must be inside Run to call Quit";
   }
 }
 
-void MessageLoop::PostTask(
-    const tracked_objects::Location& from_here, Task* task) {
-  PostTask_Helper(from_here, task, 0);
-}
-
-void MessageLoop::PostDelayedTask(
-    const tracked_objects::Location& from_here, Task* task, int delay_ms) {
-  PostTask_Helper(from_here, task, delay_ms);
+void MessageLoop::PostTask(already_AddRefed<Runnable> task) {
+  PostTask_Helper(Move(task), 0);
 }
 
-void MessageLoop::PostIdleTask(
-    const tracked_objects::Location& from_here, Task* task) {
+void MessageLoop::PostDelayedTask(already_AddRefed<Runnable> task, int delay_ms) {
+  PostTask_Helper(Move(task), delay_ms);
+}
+
+void MessageLoop::PostIdleTask(already_AddRefed<Runnable> task) {
   DCHECK(current() == this);
 
-#ifdef MOZ_TASK_TRACER
-  task = mozilla::tasktracer::CreateTracedTask(task);
-  (static_cast<mozilla::tasktracer::TracedTask*>(task))->DispatchTask();
-#endif
-
-  task->SetBirthPlace(from_here);
-  PendingTask pending_task(task, false);
-  deferred_non_nestable_work_queue_.push(pending_task);
+  PendingTask pending_task(Move(task), false);
+  deferred_non_nestable_work_queue_.push(Move(pending_task));
 }
 
 // Possibly called on a background thread!
-void MessageLoop::PostTask_Helper(
-    const tracked_objects::Location& from_here, Task* task, int delay_ms) {
-
-#ifdef MOZ_TASK_TRACER
-  task = mozilla::tasktracer::CreateTracedTask(task);
-  (static_cast<mozilla::tasktracer::TracedTask*>(task))->DispatchTask(delay_ms);
-#endif
-
-  task->SetBirthPlace(from_here);
-
-  PendingTask pending_task(task, true);
+void MessageLoop::PostTask_Helper(already_AddRefed<Runnable> task, int delay_ms) {
+  PendingTask pending_task(Move(task), true);
 
   if (delay_ms > 0) {
     pending_task.delayed_run_time =
         TimeTicks::Now() + TimeDelta::FromMilliseconds(delay_ms);
   } else {
     DCHECK(delay_ms == 0) << "delay should not be negative";
   }
 
   // Warning: Don't try to short-circuit, and handle this thread's tasks more
   // directly, as it could starve handling of foreign threads.  Put every task
   // into this queue.
 
   RefPtr<base::MessagePump> pump;
   {
     AutoLock locked(incoming_queue_lock_);
-    incoming_queue_.push(pending_task);
+    incoming_queue_.push(Move(pending_task));
     pump = pump_;
   }
   // Since the incoming_queue_ may contain a task that destroys this message
   // loop, we cannot exit incoming_queue_lock_ until we are done with |this|.
   // We use a stack-based reference to the message pump so that we can call
   // ScheduleWork outside of incoming_queue_lock_.
 
   pump->ScheduleWork();
@@ -336,49 +321,50 @@ void MessageLoop::ScheduleWork() {
 }
 
 bool MessageLoop::NestableTasksAllowed() const {
   return nestable_tasks_allowed_;
 }
 
 //------------------------------------------------------------------------------
 
-void MessageLoop::RunTask(Task* task) {
+void MessageLoop::RunTask(already_AddRefed<Runnable> aTask) {
   DCHECK(nestable_tasks_allowed_);
   // Execute the task and assume the worst: It is probably not reentrant.
   nestable_tasks_allowed_ = false;
 
+  RefPtr<Runnable> task = aTask;
   task->Run();
-  delete task;
+  task = nullptr;
 
   nestable_tasks_allowed_ = true;
 }
 
-bool MessageLoop::DeferOrRunPendingTask(const PendingTask& pending_task) {
+bool MessageLoop::DeferOrRunPendingTask(PendingTask&& pending_task) {
   if (pending_task.nestable || state_->run_depth <= run_depth_base_) {
-    RunTask(pending_task.task);
+    RunTask(pending_task.task.forget());
     // Show that we ran a task (Note: a new one might arrive as a
     // consequence!).
     return true;
   }
 
   // We couldn't run the task now because we're in a nested message loop
   // and the task isn't nestable.
-  deferred_non_nestable_work_queue_.push(pending_task);
+  deferred_non_nestable_work_queue_.push(Move(pending_task));
   return false;
 }
 
 void MessageLoop::AddToDelayedWorkQueue(const PendingTask& pending_task) {
   // Move to the delayed work queue.  Initialize the sequence number
   // before inserting into the delayed_work_queue_.  The sequence number
   // is used to faciliate FIFO sorting when two tasks have the same
   // delayed_run_time value.
   PendingTask new_pending_task(pending_task);
   new_pending_task.sequence_num = next_sequence_num_++;
-  delayed_work_queue_.push(new_pending_task);
+  delayed_work_queue_.push(Move(new_pending_task));
 }
 
 void MessageLoop::ReloadWorkQueue() {
   // We can improve performance of our loading tasks from incoming_queue_ to
   // work_queue_ by waiting until the last minute (work_queue_ is empty) to
   // load.  That reduces the number of locks-per-task significantly when our
   // queues get large.
   if (!work_queue_.empty())
@@ -390,37 +376,24 @@ void MessageLoop::ReloadWorkQueue() {
     if (incoming_queue_.empty())
       return;
     std::swap(incoming_queue_, work_queue_);
     DCHECK(incoming_queue_.empty());
   }
 }
 
 bool MessageLoop::DeletePendingTasks() {
-#ifdef DEBUG
-  if (!work_queue_.empty()) {
-    Task* task = work_queue_.front().task;
-    tracked_objects::Location loc = task->GetBirthPlace();
-    printf("Unexpected task! %s:%s:%d\n",
-	   loc.function_name(), loc.file_name(), loc.line_number());
-  }
-#endif
-
   MOZ_ASSERT(work_queue_.empty());
   bool did_work = !deferred_non_nestable_work_queue_.empty();
   while (!deferred_non_nestable_work_queue_.empty()) {
-    Task* task = deferred_non_nestable_work_queue_.front().task;
     deferred_non_nestable_work_queue_.pop();
-    delete task;
   }
   did_work |= !delayed_work_queue_.empty();
   while (!delayed_work_queue_.empty()) {
-    Task* task = delayed_work_queue_.top().task;
     delayed_work_queue_.pop();
-    delete task;
   }
   return did_work;
 }
 
 bool MessageLoop::DoWork() {
   if (!nestable_tasks_allowed_) {
     // Task can't be executed right now.
     return false;
@@ -428,25 +401,26 @@ bool MessageLoop::DoWork() {
 
   for (;;) {
     ReloadWorkQueue();
     if (work_queue_.empty())
       break;
 
     // Execute oldest task.
     do {
-      PendingTask pending_task = work_queue_.front();
+      PendingTask pending_task = Move(work_queue_.front());
       work_queue_.pop();
       if (!pending_task.delayed_run_time.is_null()) {
+	// NB: Don't move, because we use this later!
         AddToDelayedWorkQueue(pending_task);
         // If we changed the topmost task, then it is time to re-schedule.
         if (delayed_work_queue_.top().task == pending_task.task)
           pump_->ScheduleDelayedWork(pending_task.delayed_run_time);
       } else {
-        if (DeferOrRunPendingTask(pending_task))
+        if (DeferOrRunPendingTask(Move(pending_task)))
           return true;
       }
     } while (!work_queue_.empty());
   }
 
   // Nothing happened.
   return false;
 }
@@ -463,17 +437,17 @@ bool MessageLoop::DoDelayedWork(TimeTick
   }
 
   PendingTask pending_task = delayed_work_queue_.top();
   delayed_work_queue_.pop();
 
   if (!delayed_work_queue_.empty())
     *next_delayed_work_time = delayed_work_queue_.top().delayed_run_time;
 
-  return DeferOrRunPendingTask(pending_task);
+  return DeferOrRunPendingTask(Move(pending_task));
 }
 
 bool MessageLoop::DoIdleWork() {
   if (ProcessNextDelayedNonNestableTask())
     return true;
 
   if (state_->quit_received)
     pump_->Quit();
--- a/ipc/chromium/src/base/message_loop.h
+++ b/ipc/chromium/src/base/message_loop.h
@@ -106,25 +106,22 @@ public:
   // such tasks get deferred until the top-most MessageLoop::Run is executing.
   //
   // The MessageLoop takes ownership of the Task, and deletes it after it has
   // been Run().
   //
   // NOTE: These methods may be called on any thread.  The Task will be invoked
   // on the thread that executes MessageLoop::Run().
 
-  void PostTask(
-      const tracked_objects::Location& from_here, Task* task);
+  void PostTask(already_AddRefed<mozilla::Runnable> task);
 
-  void PostDelayedTask(
-      const tracked_objects::Location& from_here, Task* task, int delay_ms);
+  void PostDelayedTask(already_AddRefed<mozilla::Runnable> task, int delay_ms);
 
   // PostIdleTask is not thread safe and should be called on this thread
-  void PostIdleTask(
-      const tracked_objects::Location& from_here, Task* task);
+  void PostIdleTask(already_AddRefed<mozilla::Runnable> task);
 
   // Run the message loop.
   void Run();
 
   // Signals the Run method to return after it is done processing all pending
   // messages.  This method may only be called on the same thread that called
   // Run, and Run must still be on the call stack.
   //
@@ -132,20 +129,21 @@ public:
   // that doing so is fairly dangerous if the target thread makes nested calls
   // to MessageLoop::Run.  The problem being that you won't know which nested
   // run loop you are quiting, so be careful!
   //
   void Quit();
 
   // Invokes Quit on the current MessageLoop when run.  Useful to schedule an
   // arbitrary MessageLoop to Quit.
-  class QuitTask : public Task {
+  class QuitTask : public mozilla::Runnable {
    public:
-    virtual void Run() override {
+    NS_IMETHOD Run() override {
       MessageLoop::current()->Quit();
+      return NS_OK;
     }
   };
 
   // A MessageLoop has a particular type, which indicates the set of
   // asynchronous events it may process in addition to tasks and timers.
   //
   // TYPE_DEFAULT
   //   This type of ML only supports tasks and timers.
@@ -277,25 +275,48 @@ public:
     ~AutoRunState();
    private:
     MessageLoop* loop_;
     RunState* previous_state_;
   };
 
   // This structure is copied around by value.
   struct PendingTask {
-    Task* task;                        // The task to run.
+    RefPtr<mozilla::Runnable> task;    // The task to run.
     base::TimeTicks delayed_run_time;  // The time when the task should be run.
     int sequence_num;                  // Secondary sort key for run time.
     bool nestable;                     // OK to dispatch from a nested loop.
 
-    PendingTask(Task* aTask, bool aNestable)
+    PendingTask(already_AddRefed<mozilla::Runnable> aTask, bool aNestable)
         : task(aTask), sequence_num(0), nestable(aNestable) {
     }
 
+    PendingTask(PendingTask&& aOther)
+        : task(aOther.task.forget()),
+          delayed_run_time(aOther.delayed_run_time),
+          sequence_num(aOther.sequence_num),
+          nestable(aOther.nestable) {
+    }
+
+    // std::priority_queue<T>::top is dumb, so we have to have this.
+    PendingTask(const PendingTask& aOther)
+        : task(aOther.task),
+          delayed_run_time(aOther.delayed_run_time),
+          sequence_num(aOther.sequence_num),
+          nestable(aOther.nestable) {
+    }
+    PendingTask& operator=(const PendingTask& aOther)
+    {
+      task = aOther.task;
+      delayed_run_time = aOther.delayed_run_time;
+      sequence_num = aOther.sequence_num;
+      nestable = aOther.nestable;
+      return *this;
+    }
+
     // Used to support sorting.
     bool operator<(const PendingTask& other) const;
   };
 
   typedef std::queue<PendingTask> TaskQueue;
   typedef std::priority_queue<PendingTask> DelayedTaskQueue;
 
 #if defined(OS_WIN)
@@ -327,41 +348,40 @@ public:
   // PostTask). If there are queued tasks, the oldest one is executed and
   // new_task is queued. new_task is optional and can be NULL. In this NULL
   // case, the method will run one pending task (if any exist). Returns true if
   // it executes a task.  Queued tasks accumulate only when there is a
   // non-nestable task currently processing, in which case the new_task is
   // appended to the list work_queue_.  Such re-entrancy generally happens when
   // an unrequested message pump (typical of a native dialog) is executing in
   // the context of a task.
-  bool QueueOrRunTask(Task* new_task);
+  bool QueueOrRunTask(already_AddRefed<mozilla::Runnable> new_task);
 
   // Runs the specified task and deletes it.
-  void RunTask(Task* task);
+  void RunTask(already_AddRefed<mozilla::Runnable> task);
 
   // Calls RunTask or queues the pending_task on the deferred task list if it
   // cannot be run right now.  Returns true if the task was run.
-  bool DeferOrRunPendingTask(const PendingTask& pending_task);
+  bool DeferOrRunPendingTask(PendingTask&& pending_task);
 
   // Adds the pending task to delayed_work_queue_.
   void AddToDelayedWorkQueue(const PendingTask& pending_task);
 
   // Load tasks from the incoming_queue_ into work_queue_ if the latter is
   // empty.  The former requires a lock to access, while the latter is directly
   // accessible on this thread.
   void ReloadWorkQueue();
 
   // Delete tasks that haven't run yet without running them.  Used in the
   // destructor to make sure all the task's destructors get called.  Returns
   // true if some work was done.
   bool DeletePendingTasks();
 
   // Post a task to our incomming queue.
-  void PostTask_Helper(const tracked_objects::Location& from_here, Task* task,
-                       int delay_ms);
+  void PostTask_Helper(already_AddRefed<mozilla::Runnable> task, int delay_ms);
 
   // base::MessagePump::Delegate methods:
   virtual bool DoWork() override;
   virtual bool DoDelayedWork(base::TimeTicks* next_delayed_work_time) override;
   virtual bool DoIdleWork() override;
 
   Type type_;
   int32_t id_;
--- a/ipc/chromium/src/base/object_watcher.cc
+++ b/ipc/chromium/src/base/object_watcher.cc
@@ -5,34 +5,37 @@
 #include "base/object_watcher.h"
 
 #include "base/logging.h"
 
 namespace base {
 
 //-----------------------------------------------------------------------------
 
-struct ObjectWatcher::Watch : public Task {
+class ObjectWatcher::Watch : public mozilla::Runnable {
+public:
   ObjectWatcher* watcher;    // The associated ObjectWatcher instance
   HANDLE object;             // The object being watched
   HANDLE wait_object;        // Returned by RegisterWaitForSingleObject
   MessageLoop* origin_loop;  // Used to get back to the origin thread
   Delegate* delegate;        // Delegate to notify when signaled
   bool did_signal;           // DoneWaiting was called
 
-  virtual void Run() {
+  NS_IMETHOD Run() override {
     // The watcher may have already been torn down, in which case we need to
     // just get out of dodge.
     if (!watcher)
-      return;
+      return NS_OK;
 
     DCHECK(did_signal);
     watcher->StopWatching();
 
     delegate->OnObjectSignaled(object);
+
+    return NS_OK;
   }
 };
 
 //-----------------------------------------------------------------------------
 
 ObjectWatcher::ObjectWatcher() : watch_(NULL) {
 }
 
@@ -41,35 +44,34 @@ ObjectWatcher::~ObjectWatcher() {
 }
 
 bool ObjectWatcher::StartWatching(HANDLE object, Delegate* delegate) {
   if (watch_) {
     NOTREACHED() << "Already watching an object";
     return false;
   }
 
-  Watch* watch = new Watch;
+  RefPtr<Watch> watch = new Watch;
   watch->watcher = this;
   watch->object = object;
   watch->origin_loop = MessageLoop::current();
   watch->delegate = delegate;
   watch->did_signal = false;
 
   // Since our job is to just notice when an object is signaled and report the
   // result back to this thread, we can just run on a Windows wait thread.
   DWORD wait_flags = WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE;
 
   if (!RegisterWaitForSingleObject(&watch->wait_object, object, DoneWaiting,
-                                   watch, INFINITE, wait_flags)) {
+                                   watch.get(), INFINITE, wait_flags)) {
     NOTREACHED() << "RegisterWaitForSingleObject failed: " << GetLastError();
-    delete watch;
     return false;
   }
 
-  watch_ = watch;
+  watch_ = watch.forget();
 
   // We need to know if the current message loop is going away so we can
   // prevent the wait thread from trying to access a dead message loop.
   MessageLoop::current()->AddDestructionObserver(this);
   return true;
 }
 
 bool ObjectWatcher::StopWatching() {
@@ -90,22 +92,16 @@ bool ObjectWatcher::StopWatching() {
   // since we expect that UnregisterWaitEx resulted in a memory barrier, but
   // just to be sure, we're going to be explicit.
   MemoryBarrier();
 
   // If the watch has been posted, then we need to make sure it knows not to do
   // anything once it is run.
   watch_->watcher = NULL;
 
-  // If DoneWaiting was called, then the watch would have been posted as a
-  // task, and will therefore be deleted by the MessageLoop.  Otherwise, we
-  // need to take care to delete it here.
-  if (!watch_->did_signal)
-    delete watch_;
-
   watch_ = NULL;
 
   MessageLoop::current()->RemoveDestructionObserver(this);
   return true;
 }
 
 HANDLE ObjectWatcher::GetWatchedObject() {
   if (!watch_)
@@ -114,24 +110,25 @@ HANDLE ObjectWatcher::GetWatchedObject()
   return watch_->object;
 }
 
 // static
 void CALLBACK ObjectWatcher::DoneWaiting(void* param, BOOLEAN timed_out) {
   DCHECK(!timed_out);
 
   Watch* watch = static_cast<Watch*>(param);
+  RefPtr<Watch> addrefedWatch = watch;
 
   // Record that we ran this function.
   watch->did_signal = true;
 
   // We rely on the locking in PostTask() to ensure that a memory barrier is
   // provided, which in turn ensures our change to did_signal can be observed
   // on the target thread.
-  watch->origin_loop->PostTask(FROM_HERE, watch);
+  watch->origin_loop->PostTask(addrefedWatch.forget());
 }
 
 void ObjectWatcher::WillDestroyCurrentMessageLoop() {
   // Need to shutdown the watch so that we don't try to access the MessageLoop
   // after this point.
   StopWatching();
 }
 
--- a/ipc/chromium/src/base/object_watcher.h
+++ b/ipc/chromium/src/base/object_watcher.h
@@ -78,17 +78,17 @@ class ObjectWatcher : public MessageLoop
  private:
   // Called on a background thread when done waiting.
   static void CALLBACK DoneWaiting(void* param, BOOLEAN timed_out);
 
   // MessageLoop::DestructionObserver implementation:
   virtual void WillDestroyCurrentMessageLoop();
 
   // Internal state.
-  struct Watch;
-  Watch* watch_;
+  class Watch;
+  RefPtr<Watch> watch_;
 
   DISALLOW_COPY_AND_ASSIGN(ObjectWatcher);
 };
 
 }  // namespace base
 
 #endif  // BASE_OBJECT_WATCHER_H_
--- a/ipc/chromium/src/base/task.h
+++ b/ipc/chromium/src/base/task.h
@@ -2,21 +2,21 @@
 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #ifndef BASE_TASK_H_
 #define BASE_TASK_H_
 
 #include "base/revocable_store.h"
-#include "base/tracked.h"
 #include "base/tuple.h"
 #include "mozilla/IndexSequence.h"
 #include "mozilla/Tuple.h"
 #include "nsISupportsImpl.h"
+#include "nsThreadUtils.h"
 
 // Helper functions so that we can call a function a pass it arguments that come
 // from a Tuple.
 
 namespace details {
 
 // Call the given method on the given object. Arguments are passed by move
 // semantics from the given tuple. If the tuple has length N, the sequence must
@@ -50,36 +50,16 @@ void DispatchTupleToMethod(ObjT* obj, Me
 // Same as above, but call a function.
 template<typename Function, typename... Args>
 void DispatchTupleToFunction(Function function, mozilla::Tuple<Args...>& arg)
 {
   details::CallFunction(typename mozilla::IndexSequenceFor<Args...>::Type(),
                         function, arg);
 }
 
-// Task ------------------------------------------------------------------------
-//
-// A task is a generic runnable thingy, usually used for running code on a
-// different thread or for scheduling future tasks off of the message loop.
-
-class Task : public tracked_objects::Tracked {
- public:
-  Task() {}
-  virtual ~Task() {}
-
-  // Tasks are automatically deleted after Run is called.
-  virtual void Run() = 0;
-};
-
-class CancelableTask : public Task {
- public:
-  // Not all tasks support cancellation.
-  virtual void Cancel() = 0;
-};
-
 // Scoped Factories ------------------------------------------------------------
 //
 // These scoped factory objects can be used by non-refcounted objects to safely
 // place tasks in a message loop.  Each factory guarantees that the tasks it
 // produces will not run after the factory is destroyed.  Commonly, factories
 // are declared as class members, so the class' tasks will automatically cancel
 // when the class instance is destroyed.
 //
@@ -105,17 +85,17 @@ class CancelableTask : public Task {
 //   void ScheduleSomeMethod() {
 //     // If you'd like to only only have one pending task at a time, test for
 //     // |empty| before manufacturing another task.
 //     if (!some_method_factory_.empty())
 //       return;
 //
 //     // The factories are not thread safe, so always invoke on
 //     // |MessageLoop::current()|.
-//     MessageLoop::current()->PostDelayedTask(FROM_HERE,
+//     MessageLoop::current()->PostDelayedTask(
 //         some_method_factory_.NewRunnableMethod(&MyClass::SomeMethod),
 //         kSomeMethodDelayMS);
 //   }
 // };
 
 // A ScopedTaskFactory produces tasks of type |TaskType| and prevents them from
 // running after it is destroyed.
 template<class TaskType>
@@ -127,19 +107,20 @@ class ScopedTaskFactory : public Revocab
   inline TaskType* NewTask() {
     return new TaskWrapper(this);
   }
 
   class TaskWrapper : public TaskType {
    public:
     explicit TaskWrapper(RevocableStore* store) : revocable_(store) { }
 
-    virtual void Run() {
+    NS_IMETHOD Run() override {
       if (!revocable_.revoked())
         TaskType::Run();
+      return NS_OK;
     }
 
     ~TaskWrapper() {
       NS_ASSERT_OWNINGTHREAD(TaskWrapper);
     }
 
    private:
     Revocable revocable_;
@@ -157,39 +138,43 @@ class ScopedTaskFactory : public Revocab
 // object.  This is particularly useful for generating callbacks for
 // non-reference counted objects when the factory is a member of the object.
 template<class T>
 class ScopedRunnableMethodFactory : public RevocableStore {
  public:
   explicit ScopedRunnableMethodFactory(T* object) : object_(object) { }
 
   template <class Method, typename... Elements>
-  inline Task* NewRunnableMethod(Method method, Elements&&... elements) {
+  inline already_AddRefed<mozilla::Runnable>
+  NewRunnableMethod(Method method, Elements&&... elements) {
     typedef mozilla::Tuple<typename mozilla::Decay<Elements>::Type...> ArgsTuple;
     typedef RunnableMethod<Method, ArgsTuple> Runnable;
     typedef typename ScopedTaskFactory<Runnable>::TaskWrapper TaskWrapper;
 
-    TaskWrapper* task = new TaskWrapper(this);
+    RefPtr<TaskWrapper> task = new TaskWrapper(this);
     task->Init(object_, method, mozilla::MakeTuple(mozilla::Forward<Elements>(elements)...));
-    return task;
+    return task.forget();
   }
 
  protected:
   template <class Method, class Params>
-  class RunnableMethod : public Task {
+  class RunnableMethod : public mozilla::Runnable {
    public:
     RunnableMethod() { }
 
     void Init(T* obj, Method meth, Params&& params) {
       obj_ = obj;
       meth_ = meth;
       params_ = mozilla::Forward<Params>(params);
     }
 
-    virtual void Run() { DispatchTupleToMethod(obj_, meth_, params_); }
+    NS_IMETHOD Run() override {
+      DispatchTupleToMethod(obj_, meth_, params_);
+      return NS_OK;
+    }
 
    private:
     T* MOZ_UNSAFE_REF("The validity of this pointer must be enforced by "
                       "external factors.") obj_;
     Method meth_;
     Params params_;
 
     DISALLOW_EVIL_CONSTRUCTORS(RunnableMethod);
@@ -200,25 +185,27 @@ class ScopedRunnableMethodFactory : publ
 
   DISALLOW_EVIL_CONSTRUCTORS(ScopedRunnableMethodFactory);
 };
 
 // General task implementations ------------------------------------------------
 
 // Task to delete an object
 template<class T>
-class DeleteTask : public CancelableTask {
+class DeleteTask : public mozilla::CancelableRunnable {
  public:
   explicit DeleteTask(T* obj) : obj_(obj) {
   }
-  virtual void Run() {
+  NS_IMETHOD Run() override {
     delete obj_;
+    return NS_OK;
   }
-  virtual void Cancel() {
+  virtual nsresult Cancel() override {
     obj_ = NULL;
+    return NS_OK;
   }
  private:
   T* MOZ_UNSAFE_REF("The validity of this pointer must be enforced by "
                     "external factors.") obj_;
 };
 
 // RunnableMethodTraits --------------------------------------------------------
 //
@@ -268,40 +255,42 @@ struct RunnableMethodTraits<const T> {
 // A                - the first parameter (if any) to the method
 // B                - the second parameter (if any) to the mathod
 //
 // Put these all together and you get an object that can call a method whose
 // signature is:
 //   R T::MyFunction([A[, B]])
 //
 // Usage:
-// PostTask(FROM_HERE, NewRunnableMethod(object, &Object::method[, a[, b]])
-// PostTask(FROM_HERE, NewRunnableFunction(&function[, a[, b]])
+// PostTask(NewRunnableMethod(object, &Object::method[, a[, b]])
+// PostTask(NewRunnableFunction(&function[, a[, b]])
 
 // RunnableMethod and NewRunnableMethod implementation -------------------------
 
 template <class T, class Method, class Params>
-class RunnableMethod : public CancelableTask,
+class RunnableMethod : public mozilla::CancelableRunnable,
                        public RunnableMethodTraits<T> {
  public:
   RunnableMethod(T* obj, Method meth, Params&& params)
       : obj_(obj), meth_(meth), params_(mozilla::Forward<Params>(params)) {
     this->RetainCallee(obj_);
   }
   ~RunnableMethod() {
     ReleaseCallee();
   }
 
-  virtual void Run() {
+  NS_IMETHOD Run() override {
     if (obj_)
       DispatchTupleToMethod(obj_, meth_, params_);
+    return NS_OK;
   }
 
-  virtual void Cancel() {
+  virtual nsresult Cancel() override {
     ReleaseCallee();
+    return NS_OK;
   }
 
  private:
   void ReleaseCallee() {
     if (obj_) {
       RunnableMethodTraits<T>::ReleaseCallee(obj_);
       obj_ = nullptr;
     }
@@ -310,47 +299,55 @@ class RunnableMethod : public Cancelable
   // This is owning because of the RetainCallee and ReleaseCallee calls in the
   // constructor and destructor.
   T* MOZ_OWNING_REF obj_;
   Method meth_;
   Params params_;
 };
 
 template <class T, class Method, typename... Args>
-inline CancelableTask* NewRunnableMethod(T* object, Method method, Args&&... args) {
+inline already_AddRefed<mozilla::CancelableRunnable>
+NewRunnableMethod(T* object, Method method, Args&&... args) {
   typedef mozilla::Tuple<typename mozilla::Decay<Args>::Type...> ArgsTuple;
-  return new RunnableMethod<T, Method, ArgsTuple>(
-      object, method, mozilla::MakeTuple(mozilla::Forward<Args>(args)...));
+  RefPtr<mozilla::CancelableRunnable> t =
+    new RunnableMethod<T, Method, ArgsTuple>(object, method,
+                                             mozilla::MakeTuple(mozilla::Forward<Args>(args)...));
+  return t.forget();
 }
 
 // RunnableFunction and NewRunnableFunction implementation ---------------------
 
 template <class Function, class Params>
-class RunnableFunction : public CancelableTask {
+class RunnableFunction : public mozilla::CancelableRunnable {
  public:
   RunnableFunction(Function function, Params&& params)
       : function_(function), params_(mozilla::Forward<Params>(params)) {
   }
 
   ~RunnableFunction() {
   }
 
-  virtual void Run() {
+  NS_IMETHOD Run() override {
     if (function_)
       DispatchTupleToFunction(function_, params_);
+    return NS_OK;
   }
 
-  virtual void Cancel() {
+  virtual nsresult Cancel() override {
     function_ = nullptr;
+    return NS_OK;
   }
 
   Function function_;
   Params params_;
 };
 
 template <class Function, typename... Args>
-inline CancelableTask* NewRunnableFunction(Function function, Args&&... args) {
+inline already_AddRefed<mozilla::CancelableRunnable>
+NewRunnableFunction(Function function, Args&&... args) {
   typedef mozilla::Tuple<typename mozilla::Decay<Args>::Type...> ArgsTuple;
-  return new RunnableFunction<Function, ArgsTuple>(
-      function, mozilla::MakeTuple(mozilla::Forward<Args>(args)...));
+  RefPtr<mozilla::CancelableRunnable> t =
+    new RunnableFunction<Function, ArgsTuple>(function,
+                                              mozilla::MakeTuple(mozilla::Forward<Args>(args)...));
+  return t.forget();
 }
 
 #endif  // BASE_TASK_H_
--- a/ipc/chromium/src/base/thread.cc
+++ b/ipc/chromium/src/base/thread.cc
@@ -13,21 +13,22 @@
 
 #ifdef MOZ_TASK_TRACER
 #include "GeckoTaskTracer.h"
 #endif
 
 namespace base {
 
 // This task is used to trigger the message loop to exit.
-class ThreadQuitTask : public Task {
+class ThreadQuitTask : public mozilla::Runnable {
  public:
-  virtual void Run() {
+  NS_IMETHOD Run() override {
     MessageLoop::current()->Quit();
     Thread::SetThreadWasQuitProperly(true);
+    return NS_OK;
   }
 };
 
 // Used to pass data to ThreadMain.  This structure is allocated on the stack
 // from within StartWithOptions.
 struct Thread::StartupData {
   // We get away with a const reference here because of how we are allocated.
   const Thread::Options& options;
@@ -108,18 +109,20 @@ bool Thread::StartWithOptions(const Opti
 void Thread::Stop() {
   if (!thread_was_started())
     return;
 
   // We should only be called on the same thread that started us.
   DCHECK_NE(thread_id_, PlatformThread::CurrentId());
 
   // StopSoon may have already been called.
-  if (message_loop_)
-    message_loop_->PostTask(FROM_HERE, new ThreadQuitTask());
+  if (message_loop_) {
+    RefPtr<ThreadQuitTask> task = new ThreadQuitTask();
+    message_loop_->PostTask(task.forget());
+  }
 
   // Wait for the thread to exit.  It should already have terminated but make
   // sure this assumption is valid.
   //
   // TODO(darin): Unfortunately, we need to keep message_loop_ around until
   // the thread exits.  Some consumers are abusing the API.  Make them stop.
   //
   PlatformThread::Join(thread_);
@@ -138,17 +141,18 @@ void Thread::StopSoon() {
   // We should only be called on the same thread that started us.
   DCHECK_NE(thread_id_, PlatformThread::CurrentId());
 
   // We had better have a message loop at this point!  If we do not, then it
   // most likely means that the thread terminated unexpectedly, probably due
   // to someone calling Quit() on our message loop directly.
   DCHECK(message_loop_);
 
-  message_loop_->PostTask(FROM_HERE, new ThreadQuitTask());
+  RefPtr<ThreadQuitTask> task = new ThreadQuitTask();
+  message_loop_->PostTask(task.forget());
 }
 
 void Thread::ThreadMain() {
   char aLocal;
   profiler_register_thread(name_.c_str(), &aLocal);
   mozilla::IOInterposer::RegisterCurrentThread();
 
   // The message loop for this thread.
--- a/ipc/chromium/src/base/timer.cc
+++ b/ipc/chromium/src/base/timer.cc
@@ -15,14 +15,15 @@ void BaseTimer_Helper::OrphanDelayedTask
   }
 }
 
 void BaseTimer_Helper::InitiateDelayedTask(TimerTask* timer_task) {
   OrphanDelayedTask();
 
   delayed_task_ = timer_task;
   delayed_task_->timer_ = this;
+  RefPtr<TimerTask> addrefedTask = timer_task;
   MessageLoop::current()->PostDelayedTask(
-      FROM_HERE, timer_task,
+      addrefedTask.forget(),
       static_cast<int>(timer_task->delay_.InMilliseconds()));
 }
 
 }  // namespace base
--- a/ipc/chromium/src/base/timer.h
+++ b/ipc/chromium/src/base/timer.h
@@ -64,48 +64,48 @@ class BaseTimer_Helper {
  public:
   // Stops the timer.
   ~BaseTimer_Helper() {
     OrphanDelayedTask();
   }
 
   // Returns true if the timer is running (i.e., not stopped).
   bool IsRunning() const {
-    return delayed_task_ != NULL;
+    return !!delayed_task_;
   }
 
   // Returns the current delay for this timer.  May only call this method when
   // the timer is running!
   TimeDelta GetCurrentDelay() const {
     DCHECK(IsRunning());
     return delayed_task_->delay_;
   }
 
  protected:
-  BaseTimer_Helper() : delayed_task_(NULL) {}
+  BaseTimer_Helper() {}
 
   // We have access to the timer_ member so we can orphan this task.
-  class TimerTask : public Task {
+  class TimerTask : public mozilla::Runnable {
    public:
     explicit TimerTask(TimeDelta delay) : delay_(delay) {
       // timer_ is set in InitiateDelayedTask.
     }
     virtual ~TimerTask() {}
     BaseTimer_Helper* timer_;
     TimeDelta delay_;
   };
 
   // Used to orphan delayed_task_ so that when it runs it does nothing.
   void OrphanDelayedTask();
 
   // Used to initiated a new delayed task.  This has the side-effect of
   // orphaning delayed_task_ if it is non-null.
   void InitiateDelayedTask(TimerTask* timer_task);
 
-  TimerTask* delayed_task_;
+  RefPtr<TimerTask> delayed_task_;
 
   DISALLOW_COPY_AND_ASSIGN(BaseTimer_Helper);
 };
 
 //-----------------------------------------------------------------------------
 // This class is an implementation detail of OneShotTimer and RepeatingTimer.
 // Please do not use this class directly.
 template <class Receiver, bool kIsRepeating>
@@ -124,17 +124,17 @@ class BaseTimer : public BaseTimer_Helpe
   // running.
   void Stop() {
     OrphanDelayedTask();
   }
 
   // Call this method to reset the timer delay of an already running timer.
   void Reset() {
     DCHECK(IsRunning());
-    InitiateDelayedTask(static_cast<TimerTask*>(delayed_task_)->Clone());
+    InitiateDelayedTask(static_cast<TimerTask*>(delayed_task_.get())->Clone());
   }
 
  private:
   typedef BaseTimer<Receiver, kIsRepeating> SelfType;
 
   class TimerTask : public BaseTimer_Helper::TimerTask {
    public:
     TimerTask(TimeDelta delay, Receiver* receiver, ReceiverMethod method)
@@ -145,24 +145,25 @@ class BaseTimer : public BaseTimer_Helpe
 
     virtual ~TimerTask() {
       // This task may be getting cleared because the MessageLoop has been
       // destructed.  If so, don't leave the Timer with a dangling pointer
       // to this now-defunct task.
       ClearBaseTimer();
     }
 
-    virtual void Run() {
+    NS_IMETHOD Run() override {
       if (!timer_)  // timer_ is null if we were orphaned.
-        return;
+        return NS_OK;
       if (kIsRepeating)
         ResetBaseTimer();
       else
         ClearBaseTimer();
       DispatchToMethod(receiver_, method_, Tuple0());
+      return NS_OK;
     }
 
     TimerTask* Clone() const {
       return new TimerTask(delay_, receiver_, method_);
     }
 
    private:
     // Inform the Base that the timer is no longer active.
deleted file mode 100644
--- a/ipc/chromium/src/base/tracked.cc
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/tracked.h"
-
-#include "base/string_util.h"
-#include "base/tracked_objects.h"
-
-using base::Time;
-
-namespace tracked_objects {
-
-//------------------------------------------------------------------------------
-void Location::Write(bool display_filename, bool display_function_name,
-                     std::string* output) const {
-  StringAppendF(output, "%s[%d] ",
-      display_filename ? file_name_ : "line",
-      line_number_);
-
-  if (display_function_name) {
-    WriteFunctionName(output);
-    output->push_back(' ');
-  }
-}
-
-void Location::WriteFunctionName(std::string* output) const {
-  // Translate "<" to "&lt;" for HTML safety.
-  // TODO(jar): Support ASCII or html for logging in ASCII.
-  for (const char *p = function_name_; *p; p++) {
-    switch (*p) {
-      case '<':
-        output->append("&lt;");
-        break;
-
-      case '>':
-        output->append("&gt;");
-        break;
-
-      default:
-        output->push_back(*p);
-        break;
-    }
-  }
-}
-
-//------------------------------------------------------------------------------
-
-#ifndef TRACK_ALL_TASK_OBJECTS
-
-Tracked::Tracked() {}
-Tracked::~Tracked() {}
-void Tracked::SetBirthPlace(const Location& from_here) {}
-bool Tracked::MissingBirthplace() const { return false; }
-void Tracked::ResetBirthTime() {}
-
-#else
-
-Tracked::Tracked() : tracked_births_(NULL), tracked_birth_time_(Time::Now()) {
-  if (!ThreadData::IsActive())
-    return;
-  SetBirthPlace(Location("NoFunctionName", "NeedToSetBirthPlace", -1));
-}
-
-Tracked::~Tracked() {
-  if (!ThreadData::IsActive() || !tracked_births_)
-    return;
-  ThreadData::current()->TallyADeath(*tracked_births_,
-                                     Time::Now() - tracked_birth_time_);
-}
-
-void Tracked::SetBirthPlace(const Location& from_here) {
-  if (!ThreadData::IsActive())
-    return;
-  if (tracked_births_)
-    tracked_births_->ForgetBirth();
-  ThreadData* current_thread_data = ThreadData::current();
-  if (!current_thread_data)
-    return;  // Shutdown started, and this thread wasn't registered.
-  tracked_births_ = current_thread_data->FindLifetime(from_here);
-  tracked_births_->RecordBirth();
-}
-
-Location Tracked::GetBirthPlace() const {
-  if (tracked_births_) {
-    return tracked_births_->location();
-  }
-  return Location();
-}
-
-void Tracked::ResetBirthTime() {
-  tracked_birth_time_ = Time::Now();
-}
-
-bool Tracked::MissingBirthplace() const {
-  return -1 == tracked_births_->location().line_number();
-}
-
-#endif  // NDEBUG
-
-}  // namespace tracked_objects
deleted file mode 100644
--- a/ipc/chromium/src/base/tracked.h
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-//------------------------------------------------------------------------------
-// Tracked is the base class for all tracked objects.  During construction, it
-// registers the fact that an instance was created, and at destruction time, it
-// records that event.  The instance may be tagged with a name, which is refered
-// to as its Location.  The Location is a file and line number, most
-// typically indicated where the object was constructed.  In some cases, as the
-// object's significance is refined (for example, a Task object is augmented to
-// do additonal things), its Location may be redefined to that later location.
-
-// Tracking includes (for each instance) recording the birth thread, death
-// thread, and duration of life (from construction to destruction).  All this
-// data is accumulated and filtered for review at about:objects.
-
-#ifndef BASE_TRACKED_H_
-#define BASE_TRACKED_H_
-
-#include <string>
-
-#include "base/time.h"
-
-#ifndef NDEBUG
-#ifndef TRACK_ALL_TASK_OBJECTS
-#define TRACK_ALL_TASK_OBJECTS
-#endif   // TRACK_ALL_TASK_OBJECTS
-#endif  // NDEBUG
-
-namespace tracked_objects {
-
-//------------------------------------------------------------------------------
-// Location provides basic info where of an object was constructed, or was
-// significantly brought to life.
-
-class Location {
- public:
-  // Constructor should be called with a long-lived char*, such as __FILE__.
-  // It assumes the provided value will persist as a global constant, and it
-  // will not make a copy of it.
-  Location(const char* aFunctionName, const char* aFilename, int aLineNumber)
-      : function_name_(aFunctionName),
-        file_name_(aFilename),
-        line_number_(aLineNumber) { }
-
-  // Provide a default constructor for easy of debugging.
-  Location()
-      : function_name_("Unknown"),
-        file_name_("Unknown"),
-        line_number_(-1) { }
-
-  // Comparison operator for insertion into a std::map<> hash tables.
-  // All we need is *some* (any) hashing distinction.  Strings should already
-  // be unique, so we don't bother with strcmp or such.
-  // Use line number as the primary key (because it is fast, and usually gets us
-  // a difference), and then pointers as secondary keys (just to get some
-  // distinctions).
-  bool operator < (const Location& other) const {
-    if (line_number_ != other.line_number_)
-      return line_number_ < other.line_number_;
-    if (file_name_ != other.file_name_)
-      return file_name_ < other.file_name_;
-    return function_name_ < other.function_name_;
-  }
-
-  const char* function_name() const { return function_name_; }
-  const char* file_name()     const { return file_name_; }
-  int line_number()           const { return line_number_; }
-
-  void Write(bool display_filename, bool display_function_name,
-             std::string* output) const;
-
-  // Write function_name_ in HTML with '<' and '>' properly encoded.
-  void WriteFunctionName(std::string* output) const;
-
- private:
-  const char* const function_name_;
-  const char* const file_name_;
-  const int line_number_;
-};
-
-
-//------------------------------------------------------------------------------
-// Define a macro to record the current source location.
-
-#define FROM_HERE tracked_objects::Location(__FUNCTION__, __FILE__, __LINE__)
-
-
-//------------------------------------------------------------------------------
-
-
-class Births;
-
-class Tracked {
- public:
-  Tracked();
-  virtual ~Tracked();
-
-  // Used to record the FROM_HERE location of a caller.
-  void SetBirthPlace(const Location& from_here);
-  Location GetBirthPlace() const;
-
-  // When a task sits around a long time, such as in a timer, or object watcher,
-  // this method should be called when the task becomes active, and its
-  // significant lifetime begins (and its waiting to be woken up has passed).
-  void ResetBirthTime();
-
-  bool MissingBirthplace() const;
-
- private:
-#ifdef TRACK_ALL_TASK_OBJECTS
-
-  // Pointer to instance were counts of objects with the same birth location
-  // (on the same thread) are stored.
-  Births* tracked_births_;
-  // The time this object was constructed.  If its life consisted of a long
-  // waiting period, and then it became active, then this value is generally
-  // reset before the object begins it active life.
-  base::Time tracked_birth_time_;
-
-#endif  // TRACK_ALL_TASK_OBJECTS
-
-  DISALLOW_COPY_AND_ASSIGN(Tracked);
-};
-
-}  // namespace tracked_objects
-
-#endif  // BASE_TRACKED_H_
deleted file mode 100644
--- a/ipc/chromium/src/base/tracked_objects.cc
+++ /dev/null
@@ -1,758 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/tracked_objects.h"
-
-#include <math.h>
-#if defined(OS_WIN)
-#include <windows.h>
-#endif
-
-#include "base/string_util.h"
-
-using base::TimeDelta;
-using mozilla::StaticMutexAutoLock;
-
-namespace tracked_objects {
-
-// A TLS slot to the TrackRegistry for the current thread.
-// static
-TLSSlot ThreadData::tls_index_(base::LINKER_INITIALIZED);
-
-//------------------------------------------------------------------------------
-// Death data tallies durations when a death takes place.
-
-void DeathData::RecordDeath(const TimeDelta& duration) {
-  ++count_;
-  life_duration_ += duration;
-  int64_t milliseconds = duration.InMilliseconds();
-  square_duration_ += milliseconds * milliseconds;
-}
-
-int DeathData::AverageMsDuration() const {
-  return static_cast<int>(life_duration_.InMilliseconds() / count_);
-}
-
-double DeathData::StandardDeviation() const {
-  double average = AverageMsDuration();
-  double variance = static_cast<float>(square_duration_)/count_
-                    - average * average;
-  return sqrt(variance);
-}
-
-
-void DeathData::AddDeathData(const DeathData& other) {
-  count_ += other.count_;
-  life_duration_ += other.life_duration_;
-  square_duration_ += other.square_duration_;
-}
-
-void DeathData::Write(std::string* output) const {
-  if (!count_)
-    return;
-  if (1 == count_)
-    StringAppendF(output, "(1)Life in %dms ", AverageMsDuration());
-  else
-    StringAppendF(output, "(%d)Lives %dms/life ", count_, AverageMsDuration());
-}
-
-void DeathData::Clear() {
-  count_ = 0;
-  life_duration_ = TimeDelta();
-  square_duration_ = 0;
-}
-
-//------------------------------------------------------------------------------
-
-BirthOnThread::BirthOnThread(const Location& location)
-    : location_(location),
-      birth_thread_(ThreadData::current()) { }
-
-//------------------------------------------------------------------------------
-Births::Births(const Location& location)
-    : BirthOnThread(location),
-      birth_count_(0) { }
-
-//------------------------------------------------------------------------------
-// ThreadData maintains the central data for all births and death.
-
-// static
-ThreadData* ThreadData::first_ = NULL;
-// static
-mozilla::StaticMutex ThreadData::list_lock_;
-
-// static
-ThreadData::Status ThreadData::status_ = ThreadData::UNINITIALIZED;
-
-ThreadData::ThreadData() : next_(NULL), message_loop_(MessageLoop::current()) {}
-
-// static
-ThreadData* ThreadData::current() {
-  if (!tls_index_.initialized())
-    return NULL;
-
-  ThreadData* registry = static_cast<ThreadData*>(tls_index_.Get());
-  if (!registry) {
-    // We have to create a new registry for ThreadData.
-    bool too_late_to_create = false;
-    {
-      registry = new ThreadData;
-      StaticMutexAutoLock lock(list_lock_);
-      // Use lock to insure we have most recent status.
-      if (!IsActive()) {
-        too_late_to_create = true;
-      } else {
-        // Use lock to insert into list.
-        registry->next_ = first_;
-        first_ = registry;
-      }
-    }  // Release lock.
-    if (too_late_to_create) {
-      delete registry;
-      registry = NULL;
-    } else {
-      tls_index_.Set(registry);
-    }
-  }
-  return registry;
-}
-
-Births* ThreadData::FindLifetime(const Location& location) {
-  if (!message_loop_)  // In case message loop wasn't yet around...
-    message_loop_ = MessageLoop::current();  // Find it now.
-
-  BirthMap::iterator it = birth_map_.find(location);
-  if (it != birth_map_.end())
-    return it->second;
-  Births* tracker = new Births(location);
-
-  // Lock since the map may get relocated now, and other threads sometimes
-  // snapshot it (but they lock before copying it).
-  AutoLock lock(lock_);
-  birth_map_[location] = tracker;
-  return tracker;
-}
-
-void ThreadData::TallyADeath(const Births& lifetimes,
-                             const TimeDelta& duration) {
-  if (!message_loop_)  // In case message loop wasn't yet around...
-    message_loop_ = MessageLoop::current();  // Find it now.
-
-  DeathMap::iterator it = death_map_.find(&lifetimes);
-  if (it != death_map_.end()) {
-    it->second.RecordDeath(duration);
-    return;
-  }
-
-  AutoLock lock(lock_);  // Lock since the map may get relocated now.
-  death_map_[&lifetimes].RecordDeath(duration);
-}
-
-// static
-ThreadData* ThreadData::first() {
-  StaticMutexAutoLock lock(list_lock_);
-  return first_;
-}
-
-const std::string ThreadData::ThreadName() const {
-  if (message_loop_)
-    return message_loop_->thread_name();
-  return "ThreadWithoutMessageLoop";
-}
-
-// This may be called from another thread.
-void ThreadData::SnapshotBirthMap(BirthMap *output) const {
-  AutoLock lock(*const_cast<Lock*>(&lock_));
-  for (BirthMap::const_iterator it = birth_map_.begin();
-       it != birth_map_.end(); ++it)
-    (*output)[it->first] = it->second;
-}
-
-// This may be called from another thread.
-void ThreadData::SnapshotDeathMap(DeathMap *output) const {
-  AutoLock lock(*const_cast<Lock*>(&lock_));
-  for (DeathMap::const_iterator it = death_map_.begin();
-       it != death_map_.end(); ++it)
-    (*output)[it->first] = it->second;
-}
-
-#ifdef OS_WIN
-void ThreadData::RunOnAllThreads(void (*function)()) {
-  ThreadData* list = first();  // Get existing list.
-
-  std::vector<MessageLoop*> message_loops;
-  for (ThreadData* it = list; it; it = it->next()) {
-    if (current() != it && it->message_loop())
-      message_loops.push_back(it->message_loop());
-  }
-
-  ThreadSafeDownCounter* counter =
-    new ThreadSafeDownCounter(message_loops.size() + 1);  // Extra one for us!
-
-  HANDLE completion_handle = CreateEventW(NULL, false, false, NULL);
-  // Tell all other threads to run.
-  for (size_t i = 0; i < message_loops.size(); ++i)
-    message_loops[i]->PostTask(FROM_HERE,
-        new RunTheStatic(function, completion_handle, counter));
-
-  // Also run Task on our thread.
-  RunTheStatic local_task(function, completion_handle, counter);
-  local_task.Run();
-
-  WaitForSingleObject(completion_handle, INFINITE);
-  int ret_val = CloseHandle(completion_handle);
-  DCHECK(ret_val);
-}
-#endif
-
-// static
-bool ThreadData::StartTracking(bool status) {
-#ifndef TRACK_ALL_TASK_OBJECTS
-  return false;  // Not compiled in.
-#else
-  if (!status) {
-    StaticMutexAutoLock lock(list_lock_);
-    DCHECK(status_ == ACTIVE || status_ == SHUTDOWN);
-    status_ = SHUTDOWN;
-    return true;
-  }
-  StaticMutexAutoLock lock(list_lock_);
-  DCHECK(status_ == UNINITIALIZED);
-  CHECK(tls_index_.Initialize(NULL));
-  status_ = ACTIVE;
-  return true;
-#endif
-}
-
-// static
-bool ThreadData::IsActive() {
-  return status_ == ACTIVE;
-}
-
-#ifdef OS_WIN
-// static
-void ThreadData::ShutdownMultiThreadTracking() {
-  // Using lock, guarantee that no new ThreadData instances will be created.
-  if (!StartTracking(false))
-    return;
-
-  RunOnAllThreads(ShutdownDisablingFurtherTracking);
-
-  // Now the *only* threads that might change the database are the threads with
-  // no messages loops.  They might still be adding data to their birth records,
-  // but since no objects are deleted on those threads, there will be no further
-  // access to to cross-thread data.
-  // We could do a cleanup on all threads except for the ones without
-  // MessageLoops, but we won't bother doing cleanup (destruction of data) yet.
-  return;
-}
-#endif
-
-// static
-void ThreadData::ShutdownSingleThreadedCleanup() {
-  // We must be single threaded... but be careful anyway.
-  if (!StartTracking(false))
-    return;
-  ThreadData* thread_data_list;
-  {
-    StaticMutexAutoLock lock(list_lock_);
-    thread_data_list = first_;
-    first_ = NULL;
-  }
-
-  while (thread_data_list) {
-    ThreadData* next_thread_data = thread_data_list;
-    thread_data_list = thread_data_list->next();
-
-    for (BirthMap::iterator it = next_thread_data->birth_map_.begin();
-         next_thread_data->birth_map_.end() != it; ++it)
-      delete it->second;  // Delete the Birth Records.
-    next_thread_data->birth_map_.clear();
-    next_thread_data->death_map_.clear();
-    delete next_thread_data;  // Includes all Death Records.
-  }
-
-  CHECK(tls_index_.initialized());
-  tls_index_.Free();
-  DCHECK(!tls_index_.initialized());
-  status_ = UNINITIALIZED;
-}
-
-// static
-void ThreadData::ShutdownDisablingFurtherTracking() {
-  // Redundantly set status SHUTDOWN on this thread.
-  if (!StartTracking(false))
-    return;
-}
-
-
-//------------------------------------------------------------------------------
-
-ThreadData::ThreadSafeDownCounter::ThreadSafeDownCounter(size_t count)
-    : remaining_count_(count) {
-  DCHECK(remaining_count_ > 0);
-}
-
-bool ThreadData::ThreadSafeDownCounter::LastCaller() {
-  {
-    AutoLock lock(lock_);
-    if (--remaining_count_)
-      return false;
-  }  // Release lock, so we can delete everything in this instance.
-  delete this;
-  return true;
-}
-
-//------------------------------------------------------------------------------
-#ifdef OS_WIN
-ThreadData::RunTheStatic::RunTheStatic(FunctionPointer function,
-                                       HANDLE completion_handle,
-                                       ThreadSafeDownCounter* counter)
-    : function_(function),
-      completion_handle_(completion_handle),
-      counter_(counter) {
-}
-
-void ThreadData::RunTheStatic::Run() {
-  function_();
-  if (counter_->LastCaller())
-    SetEvent(completion_handle_);
-}
-#endif
-
-//------------------------------------------------------------------------------
-// Individual 3-tuple of birth (place and thread) along with death thread, and
-// the accumulated stats for instances (DeathData).
-
-Snapshot::Snapshot(const BirthOnThread& birth_on_thread,
-                   const ThreadData& death_thread,
-                   const DeathData& death_data)
-    : birth_(&birth_on_thread),
-      death_thread_(&death_thread),
-      death_data_(death_data) {
-}
-
-Snapshot::Snapshot(const BirthOnThread& birth_on_thread, int count)
-    : birth_(&birth_on_thread),
-      death_thread_(NULL),
-      death_data_(DeathData(count)) {
-}
-
-const std::string Snapshot::DeathThreadName() const {
-  if (death_thread_)
-    return death_thread_->ThreadName();
-  return "Still_Alive";
-}
-
-void Snapshot::Write(std::string* output) const {
-  death_data_.Write(output);
-  StringAppendF(output, "%s->%s ",
-                birth_->birth_thread()->ThreadName().c_str(),
-                death_thread_->ThreadName().c_str());
-  birth_->location().Write(true, true, output);
-}
-
-void Snapshot::Add(const Snapshot& other) {
-  death_data_.AddDeathData(other.death_data_);
-}
-
-//------------------------------------------------------------------------------
-// DataCollector
-
-DataCollector::DataCollector() {
-  DCHECK(ThreadData::IsActive());
-
-  ThreadData* my_list = ThreadData::current()->first();
-
-  count_of_contributing_threads_ = 0;
-  for (ThreadData* thread_data = my_list;
-       thread_data;
-       thread_data = thread_data->next()) {
-    ++count_of_contributing_threads_;
-  }
-
-  // Gather data serially.  A different constructor could be used to do in
-  // parallel, and then invoke an OnCompletion task.
-  for (ThreadData* thread_data = my_list;
-       thread_data;
-       thread_data = thread_data->next()) {
-    Append(*thread_data);
-  }
-}
-
-void DataCollector::Append(const ThreadData& thread_data) {
-  // Get copy of data (which is done under ThreadData's lock).
-  ThreadData::BirthMap birth_map;
-  thread_data.SnapshotBirthMap(&birth_map);
-  ThreadData::DeathMap death_map;
-  thread_data.SnapshotDeathMap(&death_map);
-
-  // Use our lock to protect our accumulation activity.
-  AutoLock lock(accumulation_lock_);
-
-  DCHECK(count_of_contributing_threads_);
-
-  for (ThreadData::DeathMap::const_iterator it = death_map.begin();
-       it != death_map.end(); ++it) {
-    collection_.push_back(Snapshot(*it->first, thread_data, it->second));
-    global_birth_count_[it->first] -= it->first->birth_count();
-  }
-
-  for (ThreadData::BirthMap::const_iterator it = birth_map.begin();
-       it != birth_map.end(); ++it) {
-    global_birth_count_[it->second] += it->second->birth_count();
-  }
-
-  --count_of_contributing_threads_;
-}
-
-DataCollector::Collection* DataCollector::collection() {
-  DCHECK(!count_of_contributing_threads_);
-  return &collection_;
-}
-
-void DataCollector::AddListOfLivingObjects() {
-  DCHECK(!count_of_contributing_threads_);
-  for (BirthCount::iterator it = global_birth_count_.begin();
-       it != global_birth_count_.end(); ++it) {
-    if (it->second > 0)
-      collection_.push_back(Snapshot(*it->first, it->second));
-  }
-}
-
-//------------------------------------------------------------------------------
-// Aggregation
-
-void Aggregation::AddDeathSnapshot(const Snapshot& snapshot) {
-  AddBirth(snapshot.birth());
-  death_threads_[snapshot.death_thread()]++;
-  AddDeathData(snapshot.death_data());
-}
-
-void Aggregation::AddBirths(const Births& births) {
-  AddBirth(births);
-  birth_count_ += births.birth_count();
-}
-void Aggregation::AddBirth(const BirthOnThread& birth) {
-  AddBirthPlace(birth.location());
-  birth_threads_[birth.birth_thread()]++;
-}
-
-void Aggregation::AddBirthPlace(const Location& location) {
-  locations_[location]++;
-  birth_files_[location.file_name()]++;
-}
-
-void Aggregation::Write(std::string* output) const {
-  if (locations_.size() == 1) {
-    locations_.begin()->first.Write(true, true, output);
-  } else {
-    StringAppendF(output, "%d Locations. ", locations_.size());
-    if (birth_files_.size() > 1)
-      StringAppendF(output, "%d Files. ", birth_files_.size());
-    else
-      StringAppendF(output, "All born in %s. ",
-                    birth_files_.begin()->first.c_str());
-  }
-
-  if (birth_threads_.size() > 1)
-    StringAppendF(output, "%d BirthingThreads. ", birth_threads_.size());
-  else
-    StringAppendF(output, "All born on %s. ",
-                  birth_threads_.begin()->first->ThreadName().c_str());
-
-  if (death_threads_.size() > 1) {
-    StringAppendF(output, "%d DeathThreads. ", death_threads_.size());
-  } else {
-    if (death_threads_.begin()->first)
-      StringAppendF(output, "All deleted on %s. ",
-                  death_threads_.begin()->first->ThreadName().c_str());
-    else
-      output->append("All these objects are still alive.");
-  }
-
-  if (birth_count_ > 1)
-    StringAppendF(output, "Births=%d ", birth_count_);
-
-  DeathData::Write(output);
-}
-
-void Aggregation::Clear() {
-  birth_count_ = 0;
-  birth_files_.clear();
-  locations_.clear();
-  birth_threads_.clear();
-  DeathData::Clear();
-  death_threads_.clear();
-}
-
-//------------------------------------------------------------------------------
-// Comparison object for sorting.
-
-Comparator::Comparator()
-    : selector_(NIL),
-      tiebreaker_(NULL),
-      combined_selectors_(0),
-      use_tiebreaker_for_sort_only_(false) {}
-
-void Comparator::Clear() {
-  if (tiebreaker_) {
-    tiebreaker_->Clear();
-    delete tiebreaker_;
-    tiebreaker_ = NULL;
-  }
-  use_tiebreaker_for_sort_only_ = false;
-  selector_ = NIL;
-}
-
-void Comparator::Sort(DataCollector::Collection* collection) const {
-  std::sort(collection->begin(), collection->end(), *this);
-}
-
-
-bool Comparator::operator()(const Snapshot& left,
-                            const Snapshot& right) const {
-  switch (selector_) {
-    case BIRTH_THREAD:
-      if (left.birth_thread() != right.birth_thread() &&
-          left.birth_thread()->ThreadName() !=
-          right.birth_thread()->ThreadName())
-        return left.birth_thread()->ThreadName() <
-            right.birth_thread()->ThreadName();
-      break;
-
-    case DEATH_THREAD:
-      if (left.death_thread() != right.death_thread() &&
-          left.DeathThreadName() !=
-          right.DeathThreadName()) {
-        if (!left.death_thread())
-          return true;
-        if (!right.death_thread())
-          return false;
-        return left.DeathThreadName() <
-             right.DeathThreadName();
-      }
-      break;
-
-    case BIRTH_FILE:
-      if (left.location().file_name() != right.location().file_name()) {
-        int comp = strcmp(left.location().file_name(),
-                          right.location().file_name());
-        if (comp)
-          return 0 > comp;
-      }
-      break;
-
-    case BIRTH_FUNCTION:
-      if (left.location().function_name() != right.location().function_name()) {
-        int comp = strcmp(left.location().function_name(),
-                          right.location().function_name());
-        if (comp)
-          return 0 > comp;
-      }
-      break;
-
-    case BIRTH_LINE:
-      if (left.location().line_number() != right.location().line_number())
-        return left.location().line_number() <
-            right.location().line_number();
-      break;
-
-    case COUNT:
-      if (left.count() != right.count())
-        return left.count() > right.count();  // Sort large at front of vector.
-      break;
-
-    case AVERAGE_DURATION:
-      if (left.AverageMsDuration() != right.AverageMsDuration())
-        return left.AverageMsDuration() > right.AverageMsDuration();
-      break;
-
-    default:
-      break;
-  }
-  if (tiebreaker_)
-    return tiebreaker_->operator()(left, right);
-  return false;
-}
-
-bool Comparator::Equivalent(const Snapshot& left,
-                            const Snapshot& right) const {
-  switch (selector_) {
-    case BIRTH_THREAD:
-      if (left.birth_thread() != right.birth_thread() &&
-          left.birth_thread()->ThreadName() !=
-              right.birth_thread()->ThreadName())
-        return false;
-      break;
-
-    case DEATH_THREAD:
-      if (left.death_thread() != right.death_thread() &&
-          left.DeathThreadName() != right.DeathThreadName())
-        return false;
-      break;
-
-    case BIRTH_FILE:
-      if (left.location().file_name() != right.location().file_name()) {
-        int comp = strcmp(left.location().file_name(),
-                          right.location().file_name());
-        if (comp)
-          return false;
-      }
-      break;
-
-    case BIRTH_FUNCTION:
-      if (left.location().function_name() != right.location().function_name()) {
-        int comp = strcmp(left.location().function_name(),
-                          right.location().function_name());
-        if (comp)
-          return false;
-      }
-      break;
-
-    case COUNT:
-      if (left.count() != right.count())
-        return false;
-      break;
-
-    case AVERAGE_DURATION:
-      if (left.life_duration() != right.life_duration())
-        return false;
-      break;
-
-    default:
-      break;
-  }
-  if (tiebreaker_ && !use_tiebreaker_for_sort_only_)
-    return tiebreaker_->Equivalent(left, right);
-  return true;
-}
-
-bool Comparator::Acceptable(const Snapshot& sample) const {
-  if (required_.size()) {
-    switch (selector_) {
-      case BIRTH_THREAD:
-        if (sample.birth_thread()->ThreadName().find(required_) ==
-            std::string::npos)
-          return false;
-        break;
-
-      case DEATH_THREAD:
-        if (sample.DeathThreadName().find(required_) == std::string::npos)
-          return false;
-        break;
-
-      case BIRTH_FILE:
-        if (!strstr(sample.location().file_name(), required_.c_str()))
-          return false;
-        break;
-
-      case BIRTH_FUNCTION:
-        if (!strstr(sample.location().function_name(), required_.c_str()))
-          return false;
-        break;
-
-      default:
-        break;
-    }
-  }
-  if (tiebreaker_ && !use_tiebreaker_for_sort_only_)
-    return tiebreaker_->Acceptable(sample);
-  return true;
-}
-
-void Comparator::SetTiebreaker(Selector selector, const std::string required) {
-  if (selector == selector_ || NIL == selector)
-    return;
-  combined_selectors_ |= selector;
-  if (NIL == selector_) {
-    selector_ = selector;
-    if (required.size())
-      required_ = required;
-    return;
-  }
-  if (tiebreaker_) {
-    if (use_tiebreaker_for_sort_only_) {
-      Comparator* temp = new Comparator;
-      temp->tiebreaker_ = tiebreaker_;
-      tiebreaker_ = temp;
-    }
-  } else {
-    tiebreaker_ = new Comparator;
-    DCHECK(!use_tiebreaker_for_sort_only_);
-  }
-  tiebreaker_->SetTiebreaker(selector, required);
-}
-
-bool Comparator::IsGroupedBy(Selector selector) const {
-  return 0 != (selector & combined_selectors_);
-}
-
-void Comparator::SetSubgroupTiebreaker(Selector selector) {
-  if (selector == selector_ || NIL == selector)
-    return;
-  if (!tiebreaker_) {
-    use_tiebreaker_for_sort_only_ = true;
-    tiebreaker_ = new Comparator;
-    tiebreaker_->SetTiebreaker(selector, "");
-  } else {
-    tiebreaker_->SetSubgroupTiebreaker(selector);
-  }
-}
-
-bool Comparator::WriteSortGrouping(const Snapshot& sample,
-                                       std::string* output) const {
-  bool wrote_data = false;
-  switch (selector_) {
-    case BIRTH_THREAD:
-      StringAppendF(output, "All new on %s ",
-                    sample.birth_thread()->ThreadName().c_str());
-      wrote_data = true;
-      break;
-
-    case DEATH_THREAD:
-      if (sample.death_thread())
-        StringAppendF(output, "All deleted on %s ",
-                      sample.DeathThreadName().c_str());
-      else
-        output->append("All still alive ");
-      wrote_data = true;
-      break;
-
-    case BIRTH_FILE:
-      StringAppendF(output, "All born in %s ",
-                    sample.location().file_name());
-      break;
-
-    case BIRTH_FUNCTION:
-      output->append("All born in ");
-      sample.location().WriteFunctionName(output);
-      output->push_back(' ');
-      break;
-
-    default:
-      break;
-  }
-  if (tiebreaker_ && !use_tiebreaker_for_sort_only_) {
-    wrote_data |= tiebreaker_->WriteSortGrouping(sample, output);
-  }
-  return wrote_data;
-}
-
-void Comparator::WriteSnapshot(const Snapshot& sample,
-                               std::string* output) const {
-  sample.death_data().Write(output);
-  if (!(combined_selectors_ & BIRTH_THREAD) ||
-      !(combined_selectors_ & DEATH_THREAD))
-    StringAppendF(output, "%s->%s ",
-                  (combined_selectors_ & BIRTH_THREAD) ? "*" :
-                    sample.birth().birth_thread()->ThreadName().c_str(),
-                  (combined_selectors_ & DEATH_THREAD) ? "*" :
-                    sample.DeathThreadName().c_str());
-  sample.birth().location().Write(!(combined_selectors_ & BIRTH_FILE),
-                                  !(combined_selectors_ & BIRTH_FUNCTION),
-                                  output);
-}
-
-}  // namespace tracked_objects
deleted file mode 100644
--- a/ipc/chromium/src/base/tracked_objects.h
+++ /dev/null
@@ -1,499 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_TRACKED_OBJECTS_H_
-#define BASE_TRACKED_OBJECTS_H_
-
-//------------------------------------------------------------------------------
-#include <map>
-#include <string>
-#include <vector>
-
-#include "base/lock.h"
-#include "mozilla/StaticMutex.h"
-#include "base/message_loop.h"
-#include "base/thread_local_storage.h"
-#include "base/tracked.h"
-
-
-namespace tracked_objects {
-
-//------------------------------------------------------------------------------
-// For a specific thread, and a specific birth place, the collection of all
-// death info (with tallies for each death thread, to prevent access conflicts).
-class ThreadData;
-class BirthOnThread {
- public:
-  explicit BirthOnThread(const Location& location);
-
-  const Location location() const { return location_; }
-  const ThreadData* birth_thread() const { return birth_thread_; }
-
- private:
-  // File/lineno of birth.  This defines the essence of the type, as the context
-  // of the birth (construction) often tell what the item is for.  This field
-  // is const, and hence safe to access from any thread.
-  const Location location_;
-
-  // The thread that records births into this object.  Only this thread is
-  // allowed to access birth_count_ (which changes over time).
-  const ThreadData* birth_thread_;  // The thread this birth took place on.
-
-  DISALLOW_COPY_AND_ASSIGN(BirthOnThread);
-};
-
-//------------------------------------------------------------------------------
-// A class for accumulating counts of births (without bothering with a map<>).
-
-class Births: public BirthOnThread {
- public:
-  explicit Births(const Location& location);
-
-  int birth_count() const { return birth_count_; }
-
-  // When we have a birth we update the count for this BirhPLace.
-  void RecordBirth() { ++birth_count_; }
-
-  // When a birthplace is changed (updated), we need to decrement the counter
-  // for the old instance.
-  void ForgetBirth() { --birth_count_; }  // We corrected a birth place.
-
- private:
-  // The number of births on this thread for our location_.
-  int birth_count_;
-
-  DISALLOW_COPY_AND_ASSIGN(Births);
-};
-
-//------------------------------------------------------------------------------
-// Basic info summarizing multiple destructions of an object with a single
-// birthplace (fixed Location).  Used both on specific threads, and also used
-// in snapshots when integrating assembled data.
-
-class DeathData {
- public:
-  // Default initializer.
-  DeathData() : count_(0), square_duration_(0) {}
-
-  // When deaths have not yet taken place, and we gather data from all the
-  // threads, we create DeathData stats that tally the number of births without
-  // a corrosponding death.
-  explicit DeathData(int count) : count_(count), square_duration_(0) {}
-
-  void RecordDeath(const base::TimeDelta& duration);
-
-  // Metrics accessors.
-  int count() const { return count_; }
-  base::TimeDelta life_duration() const { return life_duration_; }
-  int64_t square_duration() const { return square_duration_; }
-  int AverageMsDuration() const;
-  double StandardDeviation() const;
-
-  // Accumulate metrics from other into this.
-  void AddDeathData(const DeathData& other);
-
-  // Simple print of internal state.
-  void Write(std::string* output) const;
-
-  void Clear();
-
- private:
-  int count_;                // Number of destructions.
-  base::TimeDelta life_duration_;    // Sum of all lifetime durations.
-  int64_t square_duration_;  // Sum of squares in milliseconds.
-};
-
-//------------------------------------------------------------------------------
-// A temporary collection of data that can be sorted and summarized.  It is
-// gathered (carefully) from many threads.  Instances are held in arrays and
-// processed, filtered, and rendered.
-// The source of this data was collected on many threads, and is asynchronously
-// changing.  The data in this instance is not asynchronously changing.
-
-class Snapshot {
- public:
-  // When snapshotting a full life cycle set (birth-to-death), use this:
-  Snapshot(const BirthOnThread& birth_on_thread, const ThreadData& death_thread,
-           const DeathData& death_data);
-
-  // When snapshotting a birth, with no death yet, use this:
-  Snapshot(const BirthOnThread& birth_on_thread, int count);
-
-
-  const ThreadData* birth_thread() const { return birth_->birth_thread(); }
-  const Location location() const { return birth_->location(); }
-  const BirthOnThread& birth() const { return *birth_; }
-  const ThreadData* death_thread() const {return death_thread_; }
-  const DeathData& death_data() const { return death_data_; }
-  const std::string DeathThreadName() const;
-
-  int count() const { return death_data_.count(); }
-  base::TimeDelta life_duration() const { return death_data_.life_duration(); }
-  int64_t square_duration() const { return death_data_.square_duration(); }
-  int AverageMsDuration() const { return death_data_.AverageMsDuration(); }
-
-  void Write(std::string* output) const;
-
-  void Add(const Snapshot& other);
-
- private:
-  const BirthOnThread* birth_;  // Includes Location and birth_thread.
-  const ThreadData* death_thread_;
-  DeathData death_data_;
-};
-//------------------------------------------------------------------------------
-// DataCollector is a container class for Snapshot and BirthOnThread count
-// items.  It protects the gathering under locks, so that it could be called via
-// Posttask on any threads, such as all the target threads in parallel.
-
-class DataCollector {
- public:
-  typedef std::vector<Snapshot> Collection;
-
-  // Construct with a list of how many threads should contribute.  This helps us
-  // determine (in the async case) when we are done with all contributions.
-  DataCollector();
-
-  // Add all stats from the indicated thread into our arrays.  This function is
-  // mutex protected, and *could* be called from any threads (although current
-  // implementation serialized calls to Append).
-  void Append(const ThreadData& thread_data);
-
-  // After the accumulation phase, the following access is to process data.
-  Collection* collection();
-
-  // After collection of death data is complete, we can add entries for all the
-  // remaining living objects.
-  void AddListOfLivingObjects();
-
- private:
-  // This instance may be provided to several threads to contribute data.  The
-  // following counter tracks how many more threads will contribute.  When it is
-  // zero, then all asynchronous contributions are complete, and locked access
-  // is no longer needed.
-  int count_of_contributing_threads_;
-
-  // The array that we collect data into.
-  Collection collection_;
-
-  // The total number of births recorded at each location for which we have not
-  // seen a death count.
-  typedef std::map<const BirthOnThread*, int> BirthCount;
-  BirthCount global_birth_count_;
-
-  Lock accumulation_lock_;  // Protects access during accumulation phase.
-
-  DISALLOW_COPY_AND_ASSIGN(DataCollector);
-};
-
-//------------------------------------------------------------------------------
-// Aggregation contains summaries (totals and subtotals) of groups of Snapshot
-// instances to provide printing of these collections on a single line.
-
-class Aggregation: public DeathData {
- public:
-  Aggregation() : birth_count_(0) {}
-
-  void AddDeathSnapshot(const Snapshot& snapshot);
-  void AddBirths(const Births& births);
-  void AddBirth(const BirthOnThread& birth);
-  void AddBirthPlace(const Location& location);
-  void Write(std::string* output) const;
-  void Clear();
-
- private:
-  int birth_count_;
-  std::map<std::string, int> birth_files_;
-  std::map<Location, int> locations_;
-  std::map<const ThreadData*, int> birth_threads_;
-  DeathData death_data_;
-  std::map<const ThreadData*, int> death_threads_;
-
-  DISALLOW_COPY_AND_ASSIGN(Aggregation);
-};
-
-//------------------------------------------------------------------------------
-// Comparator does the comparison of Snapshot instances.  It is
-// used to order the instances in a vector.  It orders them into groups (for
-// aggregation), and can also order instances within the groups (for detailed
-// rendering of the instances).
-
-class Comparator {
- public:
-  enum Selector {
-    NIL = 0,
-    BIRTH_THREAD = 1,
-    DEATH_THREAD = 2,
-    BIRTH_FILE = 4,
-    BIRTH_FUNCTION = 8,
-    BIRTH_LINE = 16,
-    COUNT = 32,
-    AVERAGE_DURATION = 64,
-    TOTAL_DURATION = 128
-  };
-
-  explicit Comparator();
-
-  // Reset the comparator to a NIL selector.  Reset() and recursively delete any
-  // tiebreaker_ entries.  NOTE: We can't use a standard destructor, because
-  // the sort algorithm makes copies of this object, and then deletes them,
-  // which would cause problems (either we'd make expensive deep copies, or we'd
-  // do more thna one delete on a tiebreaker_.
-  void Clear();
-
-  // The less() operator for sorting the array via std::sort().
-  bool operator()(const Snapshot& left, const Snapshot& right) const;
-
-  void Sort(DataCollector::Collection* collection) const;
-
-  // Check to see if the items are sort equivalents (should be aggregated).
-  bool Equivalent(const Snapshot& left, const Snapshot& right) const;
-
-  // Check to see if all required fields are present in the given sample.
-  bool Acceptable(const Snapshot& sample) const;
-
-  // A comparator can be refined by specifying what to do if the selected basis
-  // for comparison is insufficient to establish an ordering.  This call adds
-  // the indicated attribute as the new "least significant" basis of comparison.
-  void SetTiebreaker(Selector selector, const std::string required);
-
-  // Indicate if this instance is set up to sort by the given Selector, thereby
-  // putting that information in the SortGrouping, so it is not needed in each
-  // printed line.
-  bool IsGroupedBy(Selector selector) const;
-
-  // Using the tiebreakers as set above, we mostly get an ordering, which
-  // equivalent groups.  If those groups are displayed (rather than just being
-  // aggregated, then the following is used to order them (within the group).
-  void SetSubgroupTiebreaker(Selector selector);
-
-  // Output a header line that can be used to indicated what items will be
-  // collected in the group.  It lists all (potentially) tested attributes and
-  // their values (in the sample item).
-  bool WriteSortGrouping(const Snapshot& sample, std::string* output) const;
-
-  // Output a sample, with SortGroup details not displayed.
-  void WriteSnapshot(const Snapshot& sample, std::string* output) const;
-
- private:
-  // The selector directs this instance to compare based on the specified
-  // members of the tested elements.
-  enum Selector selector_;
-
-  // For filtering into acceptable and unacceptable snapshot instance, the
-  // following is required to be a substring of the selector_ field.
-  std::string required_;
-
-  // If this instance can't decide on an ordering, we can consult a tie-breaker
-  // which may have a different basis of comparison.
-  Comparator* tiebreaker_;
-
-  // We or together all the selectors we sort on (not counting sub-group
-  // selectors), so that we can tell if we've decided to group on any given
-  // criteria.
-  int combined_selectors_;
-
-  // Some tiebreakrs are for subgroup ordering, and not for basic ordering (in
-  // preparation for aggregation).  The subgroup tiebreakers are not consulted
-  // when deciding if two items are in equivalent groups.  This flag tells us
-  // to ignore the tiebreaker when doing Equivalent() testing.
-  bool use_tiebreaker_for_sort_only_;
-};
-
-
-//------------------------------------------------------------------------------
-// For each thread, we have a ThreadData that stores all tracking info generated
-// on this thread.  This prevents the need for locking as data accumulates.
-
-class ThreadData {
- public:
-  typedef std::map<Location, Births*> BirthMap;
-  typedef std::map<const Births*, DeathData> DeathMap;
-
-  ThreadData();
-
-  // Using Thread Local Store, find the current instance for collecting data.
-  // If an instance does not exist, construct one (and remember it for use on
-  // this thread.
-  // If shutdown has already started, and we don't yet have an instance, then
-  // return null.
-  static ThreadData* current();
-
-  // In this thread's data, find a place to record a new birth.
-  Births* FindLifetime(const Location& location);
-
-  // Find a place to record a death on this thread.
-  void TallyADeath(const Births& lifetimes, const base::TimeDelta& duration);
-
-  // (Thread safe) Get start of list of instances.
-  static ThreadData* first();
-  // Iterate through the null terminated list of instances.
-  ThreadData* next() const { return next_; }
-
-  MessageLoop* message_loop() const { return message_loop_; }
-  const std::string ThreadName() const;
-
-  // Using our lock, make a copy of the specified maps.  These calls may arrive
-  // from non-local threads.
-  void SnapshotBirthMap(BirthMap *output) const;
-  void SnapshotDeathMap(DeathMap *output) const;
-
-  static void RunOnAllThreads(void (*Func)());
-
-  // Set internal status_ to either become ACTIVE, or later, to be SHUTDOWN,
-  // based on argument being true or false respectively.
-  // IF tracking is not compiled in, this function will return false.
-  static bool StartTracking(bool status);
-  static bool IsActive();
-
-#ifdef OS_WIN
-  // WARNING: ONLY call this function when all MessageLoops are still intact for
-  // all registered threads.  IF you call it later, you will crash.
-  // Note: You don't need to call it at all, and you can wait till you are
-  // single threaded (again) to do the cleanup via
-  // ShutdownSingleThreadedCleanup().
-  // Start the teardown (shutdown) process in a multi-thread mode by disabling
-  // further additions to thread database on all threads.  First it makes a
-  // local (locked) change to prevent any more threads from registering.  Then
-  // it Posts a Task to all registered threads to be sure they are aware that no
-  // more accumulation can take place.
-  static void ShutdownMultiThreadTracking();
-#endif
-
-  // WARNING: ONLY call this function when you are running single threaded
-  // (again) and all message loops and threads have terminated.  Until that
-  // point some threads may still attempt to write into our data structures.
-  // Delete recursively all data structures, starting with the list of
-  // ThreadData instances.
-  static void ShutdownSingleThreadedCleanup();
-
- private:
-  // Current allowable states of the tracking system.  The states always
-  // proceed towards SHUTDOWN, and never go backwards.
-  enum Status {
-    UNINITIALIZED,
-    ACTIVE,
-    SHUTDOWN
-  };
-
-  // A class used to count down which is accessed by several threads.  This is
-  // used to make sure RunOnAllThreads() actually runs a task on the expected
-  // count of threads.
-  class ThreadSafeDownCounter {
-   public:
-    // Constructor sets the count, once and for all.
-    explicit ThreadSafeDownCounter(size_t count);
-
-    // Decrement the count, and return true if we hit zero.  Also delete this
-    // instance automatically when we hit zero.
-    bool LastCaller();
-
-   private:
-    size_t remaining_count_;
-    Lock lock_;  // protect access to remaining_count_.
-  };
-
-#ifdef OS_WIN
-  // A Task class that runs a static method supplied, and checks to see if this
-  // is the last tasks instance (on last thread) that will run the method.
-  // IF this is the last run, then the supplied event is signalled.
-  class RunTheStatic : public Task {
-   public:
-    typedef void (*FunctionPointer)();
-    RunTheStatic(FunctionPointer function,
-                 HANDLE completion_handle,
-                 ThreadSafeDownCounter* counter);
-    // Run the supplied static method, and optionally set the event.
-    void Run();
-
-   private:
-    FunctionPointer function_;
-    HANDLE completion_handle_;
-    // Make sure enough tasks are called before completion is signaled.
-    ThreadSafeDownCounter* counter_;
-
-    DISALLOW_COPY_AND_ASSIGN(RunTheStatic);
-  };
-#endif
-
-  // Each registered thread is called to set status_ to SHUTDOWN.
-  // This is done redundantly on every registered thread because it is not
-  // protected by a mutex.  Running on all threads guarantees we get the
-  // notification into the memory cache of all possible threads.
-  static void ShutdownDisablingFurtherTracking();
-
-  // We use thread local store to identify which ThreadData to interact with.
-  static TLSSlot tls_index_ ;
-
-  // Link to the most recently created instance (starts a null terminated list).
-  static ThreadData* first_;
-  // Protection for access to first_.
-  static mozilla::StaticMutex list_lock_;
-
-
-  // We set status_ to SHUTDOWN when we shut down the tracking service. This
-  // setting is redundantly established by all participating
-  // threads so that we are *guaranteed* (without locking) that all threads
-  // can "see" the status and avoid additional calls into the  service.
-  static Status status_;
-
-  // Link to next instance (null terminated list). Used to globally track all
-  // registered instances (corresponds to all registered threads where we keep
-  // data).
-  ThreadData* next_;
-
-  // The message loop where tasks needing to access this instance's private data
-  // should be directed.  Since some threads have no message loop, some
-  // instances have data that can't be (safely) modified externally.
-  MessageLoop* message_loop_;
-
-  // A map used on each thread to keep track of Births on this thread.
-  // This map should only be accessed on the thread it was constructed on.
-  // When a snapshot is needed, this structure can be locked in place for the
-  // duration of the snapshotting activity.
-  BirthMap birth_map_;
-
-  // Similar to birth_map_, this records informations about death of tracked
-  // instances (i.e., when a tracked instance was destroyed on this thread).
-  DeathMap death_map_;
-
-  // Lock to protect *some* access to BirthMap and DeathMap.  We only use
-  // locking protection when we are growing the maps, or using an iterator.  We
-  // only do writes to members from this thread, so the updates of values are
-  // atomic.  Folks can read from other threads, and get (via races) new or old
-  // data, but that is considered acceptable errors (mis-information).
-  Lock lock_;
-
-  DISALLOW_COPY_AND_ASSIGN(ThreadData);
-};
-
-
-//------------------------------------------------------------------------------
-// Provide simple way to to start global tracking, and to tear down tracking
-// when done.  Note that construction and destruction of this object must be
-// done when running in single threaded mode (before spawning a lot of threads
-// for construction, and after shutting down all the threads for destruction).
-
-class AutoTracking {
- public:
-  AutoTracking() { ThreadData::StartTracking(true); }
-
-  ~AutoTracking() {
-#ifndef NDEBUG  // Don't call these in a Release build: they just waste time.
-    // The following should ONLY be called when in single threaded mode. It is
-    // unsafe to do this cleanup if other threads are still active.
-    // It is also very unnecessary, so I'm only doing this in debug to satisfy
-    // purify (if we need to!).
-    ThreadData::ShutdownSingleThreadedCleanup();
-#endif
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(AutoTracking);
-};
-
-
-}  // namespace tracked_objects
-
-#endif  // BASE_TRACKED_OBJECTS_H_
--- a/ipc/chromium/src/base/waitable_event_watcher.h
+++ b/ipc/chromium/src/base/waitable_event_watcher.h
@@ -139,16 +139,16 @@ class WaitableEventWatcher
   // ---------------------------------------------------------------------------
   // Implementation of MessageLoop::DestructionObserver
   // ---------------------------------------------------------------------------
   void WillDestroyCurrentMessageLoop();
 
   MessageLoop* message_loop_;
   RefPtr<Flag> cancel_flag_;
   AsyncWaiter* waiter_;
-  AsyncCallbackTask* callback_task_;
+  RefPtr<AsyncCallbackTask> callback_task_;
   RefPtr<WaitableEvent::WaitableEventKernel> kernel_;
 #endif
 };
 
 }  // namespace base
 
 #endif  // BASE_WAITABLE_EVENT_WATCHER_H_
--- a/ipc/chromium/src/base/waitable_event_watcher_posix.cc
+++ b/ipc/chromium/src/base/waitable_event_watcher_posix.cc
@@ -54,28 +54,29 @@ class Flag final {
 };
 
 // -----------------------------------------------------------------------------
 // This is an asynchronous waiter which posts a task to a MessageLoop when
 // fired. An AsyncWaiter may only be in a single wait-list.
 // -----------------------------------------------------------------------------
 class AsyncWaiter final : public WaitableEvent::Waiter {
  public:
-  AsyncWaiter(MessageLoop* message_loop, Task* task, Flag* flag)
+  AsyncWaiter(MessageLoop* message_loop,
+	      already_AddRefed<mozilla::Runnable> task, Flag* flag)
       : message_loop_(message_loop),
         cb_task_(task),
         flag_(flag) { }
 
   bool Fire(WaitableEvent* event) {
     if (flag_->value()) {
       // If the callback has been canceled, we don't enqueue the task, we just
       // delete it instead.
-      delete cb_task_;
+      cb_task_ = nullptr;
     } else {
-      message_loop_->PostTask(FROM_HERE, cb_task_);
+      message_loop_->PostTask(cb_task_.forget());
     }
 
     // We are removed from the wait-list by the WaitableEvent itself. It only
     // remains to delete ourselves.
     delete this;
 
     // We can always return true because an AsyncWaiter is never in two
     // different wait-lists at the same time.
@@ -84,57 +85,57 @@ class AsyncWaiter final : public Waitabl
 
   // See StopWatching for discussion
   bool Compare(void* tag) {
     return tag == flag_.get();
   }
 
  private:
   MessageLoop *const message_loop_;
-  Task *const cb_task_;
+  RefPtr<mozilla::Runnable> cb_task_;
   RefPtr<Flag> flag_;
 };
 
 // -----------------------------------------------------------------------------
 // For async waits we need to make a callback in a MessageLoop thread. We do
 // this by posting this task, which calls the delegate and keeps track of when
 // the event is canceled.
 // -----------------------------------------------------------------------------
-class AsyncCallbackTask : public Task {
+class AsyncCallbackTask : public mozilla::Runnable {
  public:
   AsyncCallbackTask(Flag* flag, WaitableEventWatcher::Delegate* delegate,
                     WaitableEvent* event)
       : flag_(flag),
         delegate_(delegate),
         event_(event) {
   }
 
-  void Run() {
+  NS_IMETHOD Run() override {
     // Runs in MessageLoop thread.
     if (!flag_->value()) {
       // This is to let the WaitableEventWatcher know that the event has occured
       // because it needs to be able to return NULL from GetWatchedObject
       flag_->Set();
       delegate_->OnWaitableEventSignaled(event_);
     }
 
+    return NS_OK;
     // We are deleted by the MessageLoop
   }
 
  private:
   RefPtr<Flag> flag_;
   WaitableEventWatcher::Delegate *const delegate_;
   WaitableEvent *const event_;
 };
 
 WaitableEventWatcher::WaitableEventWatcher()
     : event_(NULL),
       message_loop_(NULL),
-      cancel_flag_(NULL),
-      callback_task_(NULL) {
+      cancel_flag_(NULL) {
 }
 
 WaitableEventWatcher::~WaitableEventWatcher() {
   StopWatching();
 }
 
 // -----------------------------------------------------------------------------
 // The Handle is how the user cancels a wait. After deleting the Handle we
@@ -167,26 +168,28 @@ bool WaitableEventWatcher::StartWatching
   AutoLock locked(kernel->lock_);
 
   if (kernel->signaled_) {
     if (!kernel->manual_reset_)
       kernel->signaled_ = false;
 
     // No hairpinning - we can't call the delegate directly here. We have to
     // enqueue a task on the MessageLoop as normal.
-    current_ml->PostTask(FROM_HERE, callback_task_);
+    RefPtr<AsyncCallbackTask> addrefedTask = callback_task_;
+    current_ml->PostTask(addrefedTask.forget());
     return true;
   }
 
   message_loop_ = current_ml;
   current_ml->AddDestructionObserver(this);
 
   event_ = event;
   kernel_ = kernel;
-  waiter_ = new AsyncWaiter(current_ml, callback_task_, cancel_flag_);
+  RefPtr<AsyncCallbackTask> addrefedTask = callback_task_;
+  waiter_ = new AsyncWaiter(current_ml, addrefedTask.forget(), cancel_flag_);
   event->Enqueue(waiter_);
 
   return true;
 }
 
 void WaitableEventWatcher::StopWatching() {
   if (message_loop_) {
     message_loop_->RemoveDestructionObserver(this);
@@ -234,17 +237,17 @@ void WaitableEventWatcher::StopWatching(
   // still exists. So if we find a waiter with the correct pointer value, and
   // which shares a Flag pointer, we have a real match.
   if (kernel_->Dequeue(waiter_, cancel_flag_.get())) {
     // Case 2: the waiter hasn't been signaled yet; it was still on the wait
     // list. We've removed it, thus we can delete it and the task (which cannot
     // have been enqueued with the MessageLoop because the waiter was never
     // signaled)
     delete waiter_;
-    delete callback_task_;
+    callback_task_ = nullptr;
     cancel_flag_ = NULL;
     return;
   }
 
   // Case 3: the waiter isn't on the wait-list, thus it was signaled. It may
   // not have run yet, so we set the flag to tell it not to bother enqueuing the
   // task on the MessageLoop, but to delete it instead. The Waiter deletes
   // itself once run.
--- a/ipc/chromium/src/base/win_util.cc
+++ b/ipc/chromium/src/base/win_util.cc
@@ -5,17 +5,16 @@
 #include "base/win_util.h"
 
 #include <map>
 #include <sddl.h>
 
 #include "base/logging.h"
 #include "base/singleton.h"
 #include "base/string_util.h"
-#include "base/tracked.h"
 
 namespace win_util {
 
 std::wstring FormatMessage(unsigned messageid) {
   wchar_t* string_buffer = NULL;
   unsigned string_length = ::FormatMessage(
       FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
       FORMAT_MESSAGE_IGNORE_INSERTS, NULL, messageid, 0,
--- a/ipc/chromium/src/base/win_util.h
+++ b/ipc/chromium/src/base/win_util.h
@@ -5,18 +5,16 @@
 #ifndef BASE_WIN_UTIL_H__
 #define BASE_WIN_UTIL_H__
 
 #include <windows.h>
 #include <aclapi.h>
 
 #include <string>
 
-#include "base/tracked.h"
-
 namespace win_util {
 
 // Uses the last Win32 error to generate a human readable message string.
 std::wstring FormatLastWin32Error();
 
 }  // namespace win_util
 
 #endif  // BASE_WIN_UTIL_H__
--- a/ipc/chromium/src/chrome/common/child_process_host.cc
+++ b/ipc/chromium/src/chrome/common/child_process_host.cc
@@ -22,26 +22,27 @@ typedef mozilla::ipc::BrowserProcessSubT
 using mozilla::ipc::FileDescriptor;
 
 namespace {
 typedef std::list<ChildProcessHost*> ChildProcessList;
 
 // The NotificationTask is used to notify about plugin process connection/
 // disconnection. It is needed because the notifications in the
 // NotificationService must happen in the main thread.
-class ChildNotificationTask : public Task {
+class ChildNotificationTask : public mozilla::Runnable {
  public:
   ChildNotificationTask(
       NotificationType notification_type, ChildProcessInfo* info)
       : notification_type_(notification_type), info_(*info) { }
 
-  virtual void Run() {
+  NS_IMETHOD Run() {
     NotificationService::current()->
         Notify(notification_type_, NotificationService::AllSources(),
                Details<ChildProcessInfo>(&info_));
+    return NS_OK;
   }
 
  private:
   NotificationType notification_type_;
   ChildProcessInfo info_;
 };
 
 }  // namespace
@@ -124,18 +125,18 @@ bool ChildProcessHost::Send(IPC::Message
 }
 
 void ChildProcessHost::Notify(NotificationType type) {
   MessageLoop* loop = ChromeThread::GetMessageLoop(ChromeThread::IO);
   if (!loop)
       loop = mozilla::ipc::ProcessChild::message_loop();
   if (!loop)
       loop = MessageLoop::current();
-  loop->PostTask(
-      FROM_HERE, new ChildNotificationTask(type, this));
+  RefPtr<ChildNotificationTask> task = new ChildNotificationTask(type, this);
+  loop->PostTask(task.forget());
 }
 
 void ChildProcessHost::OnWaitableEventSignaled(base::WaitableEvent *event) {
 #if defined(OS_WIN)
   HANDLE object = event->handle();
   DCHECK(handle());
   DCHECK_EQ(object, handle());
 
--- a/ipc/chromium/src/chrome/common/child_thread.cc
+++ b/ipc/chromium/src/chrome/common/child_thread.cc
@@ -28,25 +28,25 @@ ChildThread::~ChildThread() {
 #ifdef MOZ_NUWA_PROCESS
 #include "ipc/Nuwa.h"
 #endif
 
 bool ChildThread::Run() {
   bool r = StartWithOptions(options_);
 #ifdef MOZ_NUWA_PROCESS
   if (IsNuwaProcess()) {
-      message_loop()->PostTask(FROM_HERE,
-                               NewRunnableFunction(&ChildThread::MarkThread));
+      message_loop()->PostTask(NewRunnableFunction(&ChildThread::MarkThread));
   }
 #endif
   return r;
 }
 
 void ChildThread::OnChannelError() {
-  owner_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask());
+  RefPtr<mozilla::Runnable> task = new MessageLoop::QuitTask();
+  owner_loop_->PostTask(task.forget());
 }
 
 #ifdef MOZ_NUWA_PROCESS
 void ChildThread::MarkThread() {
     NuwaMarkCurrentThread(nullptr, nullptr);
     if (!NuwaCheckpointCurrentThread()) {
         NS_RUNTIMEABORT("Should not be here!");
     }
@@ -82,12 +82,13 @@ void ChildThread::Init() {
 void ChildThread::CleanUp() {
   // Need to destruct the SyncChannel to the browser before we go away because
   // it caches a pointer to this thread.
   channel_ = nullptr;
 }
 
 void ChildThread::OnProcessFinalRelease() {
   if (!check_with_browser_before_shutdown_) {
-    owner_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask());
+    RefPtr<mozilla::Runnable> task = new MessageLoop::QuitTask();
+    owner_loop_->PostTask(task.forget());
     return;
   }
 }
--- a/ipc/chromium/src/chrome/common/ipc_channel_win.cc
+++ b/ipc/chromium/src/chrome/common/ipc_channel_win.cc
@@ -260,17 +260,17 @@ bool Channel::ChannelImpl::Connect() {
   // Check to see if there is a client connected to our pipe...
   if (waiting_connect_)
     ProcessConnection();
 
   if (!input_state_.is_pending) {
     // Complete setup asynchronously. By not setting input_state_.is_pending
     // to true, we indicate to OnIOCompleted that this is the special
     // initialization signal.
-    MessageLoopForIO::current()->PostTask(FROM_HERE, factory_.NewRunnableMethod(
+    MessageLoopForIO::current()->PostTask(factory_.NewRunnableMethod(
         &Channel::ChannelImpl::OnIOCompleted, &input_state_.context, 0, 0));
   }
 
   if (!waiting_connect_)
     ProcessOutgoingMessages(NULL, 0);
   return true;
 }
 
--- a/ipc/chromium/src/chrome/common/process_watcher_posix_sigchld.cc
+++ b/ipc/chromium/src/chrome/common/process_watcher_posix_sigchld.cc
@@ -72,35 +72,37 @@ protected:
 
 private:
   DISALLOW_EVIL_CONSTRUCTORS(ChildReaper);
 };
 
 
 // Fear the reaper
 class ChildGrimReaper : public ChildReaper,
-                        public Task
+                        public mozilla::Runnable
 {
 public:
   explicit ChildGrimReaper(pid_t process) : ChildReaper(process)
   {
   } 
 
   virtual ~ChildGrimReaper()
   {
     if (process_)
       KillProcess();
   }
 
   // @override
-  virtual void Run()
+  NS_IMETHOD Run()
   {
     // we may have already been signaled by the time this runs
     if (process_)
       KillProcess();
+
+    return NS_OK;
   }
 
 private:
   void KillProcess()
   {
     DCHECK(process_);
 
     if (IsProcessDead(process_)) {
@@ -195,21 +197,21 @@ ProcessWatcher::EnsureProcessTerminated(
   DCHECK(process != base::GetCurrentProcId());
   DCHECK(process > 0);
 
   if (IsProcessDead(process))
     return;
 
   MessageLoopForIO* loop = MessageLoopForIO::current();
   if (force) {
-    ChildGrimReaper* reaper = new ChildGrimReaper(process);
+    RefPtr<ChildGrimReaper> reaper = new ChildGrimReaper(process);
 
     loop->CatchSignal(SIGCHLD, reaper, reaper);
     // |loop| takes ownership of |reaper|
-    loop->PostDelayedTask(FROM_HERE, reaper, kMaxWaitMs);
+    loop->PostDelayedTask(reaper.forget(), kMaxWaitMs);
   } else {
     ChildLaxReaper* reaper = new ChildLaxReaper(process);
 
     loop->CatchSignal(SIGCHLD, reaper, reaper);
     // |reaper| destroys itself after destruction notification
     loop->AddDestructionObserver(reaper);
   }
 }
--- a/ipc/chromium/src/chrome/common/process_watcher_win.cc
+++ b/ipc/chromium/src/chrome/common/process_watcher_win.cc
@@ -9,34 +9,36 @@
 #include "base/sys_info.h"
 #include "chrome/common/result_codes.h"
 
 // Maximum amount of time (in milliseconds) to wait for the process to exit.
 static const int kWaitInterval = 2000;
 
 namespace {
 
-class TimerExpiredTask : public Task, public base::ObjectWatcher::Delegate {
+class TimerExpiredTask : public mozilla::Runnable,
+                         public base::ObjectWatcher::Delegate {
  public:
   explicit TimerExpiredTask(base::ProcessHandle process) : process_(process) {
     watcher_.StartWatching(process_, this);
   }
 
   virtual ~TimerExpiredTask() {
     if (process_) {
       KillProcess();
       DCHECK(!process_) << "Make sure to close the handle.";
     }
   }
 
   // Task ---------------------------------------------------------------------
 
-  virtual void Run() {
+  NS_IMETHOD Run() override {
     if (process_)
       KillProcess();
+    return NS_OK;
   }
 
   // MessageLoop::Watcher -----------------------------------------------------
 
   virtual void OnObjectSignaled(HANDLE object) {
     // When we're called from KillProcess, the ObjectWatcher may still be
     // watching.  the process handle, so make sure it has stopped.
     watcher_.StopWatching();
@@ -80,12 +82,13 @@ void ProcessWatcher::EnsureProcessTermin
   }
 
   // If already signaled, then we are done!
   if (WaitForSingleObject(process, 0) == WAIT_OBJECT_0) {
     base::CloseProcessHandle(process);
     return;
   }
 
-  MessageLoop::current()->PostDelayedTask(FROM_HERE,
-                                          new TimerExpiredTask(process),
+  RefPtr<mozilla::Runnable> task = new TimerExpiredTask(process);
+
+  MessageLoop::current()->PostDelayedTask(task.forget(),
                                           kWaitInterval);
 }
--- a/ipc/glue/BackgroundImpl.cpp
+++ b/ipc/glue/BackgroundImpl.cpp
@@ -443,18 +443,20 @@ private:
   }
 
   static void
   DispatchFailureCallback(nsIEventTarget* aEventTarget);
 
   // This class is reference counted.
   ~ChildImpl()
   {
-    XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
-                                     new DeleteTask<Transport>(GetTransport()));
+    RefPtr<DeleteTask<Transport>> task =
+      new DeleteTask<Transport>(GetTransport());
+    XRE_GetIOMessageLoop()->PostTask(task.forget());
+
     AssertActorDestroyed();
   }
 
   void
   SetBoundThread()
   {
     THREADSAFETY_ASSERT(!mBoundThread);
 
@@ -1282,18 +1284,18 @@ ParentImpl::MainThreadActorDestroy()
   AssertIsInMainProcess();
   AssertIsOnMainThread();
   MOZ_ASSERT_IF(mIsOtherProcessActor, mContent);
   MOZ_ASSERT_IF(!mIsOtherProcessActor, !mContent);
   MOZ_ASSERT_IF(mIsOtherProcessActor, mTransport);
   MOZ_ASSERT_IF(!mIsOtherProcessActor, !mTransport);
 
   if (mTransport) {
-    XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
-                                     new DeleteTask<Transport>(mTransport));
+    RefPtr<DeleteTask<Transport>> task = new DeleteTask<Transport>(mTransport);
+    XRE_GetIOMessageLoop()->PostTask(task.forget());
     mTransport = nullptr;
   }
 
   mContent = nullptr;
 
   MOZ_ASSERT(sLiveActorCount);
   sLiveActorCount--;
 
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -346,33 +346,31 @@ void GeckoChildProcessHost::InitWindowsG
 bool
 GeckoChildProcessHost::SyncLaunch(std::vector<std::string> aExtraOpts, int aTimeoutMs, base::ProcessArchitecture arch)
 {
   PrepareLaunch();
 
   MessageLoop* ioLoop = XRE_GetIOMessageLoop();
   NS_ASSERTION(MessageLoop::current() != ioLoop, "sync launch from the IO thread NYI");
 
-  ioLoop->PostTask(FROM_HERE,
-                   NewRunnableMethod(this,
+  ioLoop->PostTask(NewRunnableMethod(this,
                                      &GeckoChildProcessHost::RunPerformAsyncLaunch,
                                      aExtraOpts, arch));
 
   return WaitUntilConnected(aTimeoutMs);
 }
 
 bool
 GeckoChildProcessHost::AsyncLaunch(std::vector<std::string> aExtraOpts,
                                    base::ProcessArchitecture arch)
 {
   PrepareLaunch();
 
   MessageLoop* ioLoop = XRE_GetIOMessageLoop();
-  ioLoop->PostTask(FROM_HERE,
-                   NewRunnableMethod(this,
+  ioLoop->PostTask(NewRunnableMethod(this,
                                      &GeckoChildProcessHost::RunPerformAsyncLaunch,
                                      aExtraOpts, arch));
 
   // This may look like the sync launch wait, but we only delay as
   // long as it takes to create the channel.
   MonitorAutoLock lock(mMonitor);
   while (mProcessState < CHANNEL_INITIALIZED) {
     lock.Wait();
@@ -420,18 +418,17 @@ GeckoChildProcessHost::WaitUntilConnecte
 }
 
 bool
 GeckoChildProcessHost::LaunchAndWaitForProcessHandle(StringVector aExtraOpts)
 {
   PrepareLaunch();
 
   MessageLoop* ioLoop = XRE_GetIOMessageLoop();
-  ioLoop->PostTask(FROM_HERE,
-                   NewRunnableMethod(this,
+  ioLoop->PostTask(NewRunnableMethod(this,
                                      &GeckoChildProcessHost::RunPerformAsyncLaunch,
                                      aExtraOpts, base::GetCurrentProcessArchitecture()));
 
   MonitorAutoLock lock(mMonitor);
   while (mProcessState < PROCESS_CREATED) {
     lock.Wait();
   }
   MOZ_ASSERT(mProcessState == PROCESS_ERROR || mChildProcessHandle);
@@ -475,29 +472,27 @@ GeckoChildProcessHost::SetAlreadyDead()
 }
 
 namespace {
 
 void
 DelayedDeleteSubprocess(GeckoChildProcessHost* aSubprocess)
 {
   XRE_GetIOMessageLoop()
-    ->PostTask(FROM_HERE,
-       new DeleteTask<GeckoChildProcessHost>(aSubprocess));
+    ->PostTask(mozilla::MakeAndAddRef<DeleteTask<GeckoChildProcessHost>>(aSubprocess));
 }
 
 }
 
 void
 GeckoChildProcessHost::DissociateActor()
 {
   if (!--mAssociatedActors) {
     MessageLoop::current()->
-      PostTask(FROM_HERE,
-        NewRunnableFunction(DelayedDeleteSubprocess, this));
+      PostTask(NewRunnableFunction(DelayedDeleteSubprocess, this));
   }
 }
 
 int32_t GeckoChildProcessHost::mChildCounter = 0;
 
 void
 GeckoChildProcessHost::SetChildLogName(const char* varName, const char* origLogName)
 {
--- a/ipc/glue/MessageChannel.cpp
+++ b/ipc/glue/MessageChannel.cpp
@@ -689,17 +689,16 @@ MessageChannel::Open(MessageChannel *aTa
       case UnknownSide: break;
     }
 
     mMonitor = new RefCountedMonitor();
 
     MonitorAutoLock lock(*mMonitor);
     mChannelState = ChannelOpening;
     aTargetLoop->PostTask(
-        FROM_HERE,
         NewRunnableMethod(aTargetChan, &MessageChannel::OnOpenAsSlave, this, oppSide));
 
     while (ChannelOpening == mChannelState)
         mMonitor->Wait();
     MOZ_RELEASE_ASSERT(ChannelConnected == mChannelState, "not connected when awoken");
     return (ChannelConnected == mChannelState);
 }
 
@@ -978,17 +977,18 @@ MessageChannel::OnMessageReceivedFromLin
     if (shouldWakeUp) {
         NotifyWorkerThread();
     }
 
     if (shouldPostTask) {
         if (!compress) {
             // If we compressed away the previous message, we'll re-use
             // its pending task.
-            mWorkerLoop->PostTask(FROM_HERE, new DequeueTask(mDequeueOneTask));
+            RefPtr<DequeueTask> task = new DequeueTask(mDequeueOneTask);
+            mWorkerLoop->PostTask(task.forget());
         }
     }
 }
 
 void
 MessageChannel::PeekMessages(mozilla::function<bool(const Message& aMsg)> aInvoke)
 {
     MonitorAutoLock lock(*mMonitor);
@@ -1800,24 +1800,26 @@ void
 MessageChannel::EnqueuePendingMessages()
 {
     AssertWorkerThread();
     mMonitor->AssertCurrentThreadOwns();
 
     MaybeUndeferIncall();
 
     for (size_t i = 0; i < mDeferred.size(); ++i) {
-        mWorkerLoop->PostTask(FROM_HERE, new DequeueTask(mDequeueOneTask));
+        RefPtr<DequeueTask> task = new DequeueTask(mDequeueOneTask);
+        mWorkerLoop->PostTask(task.forget());
     }
 
     // XXX performance tuning knob: could process all or k pending
     // messages here, rather than enqueuing for later processing
 
     for (size_t i = 0; i < mPending.size(); ++i) {
-        mWorkerLoop->PostTask(FROM_HERE, new DequeueTask(mDequeueOneTask));
+        RefPtr<DequeueTask> task = new DequeueTask(mDequeueOneTask);
+        mWorkerLoop->PostTask(task.forget());
     }
 }
 
 static inline bool
 IsTimeoutExpired(PRIntervalTime aStart, PRIntervalTime aTimeout)
 {
     return (aTimeout != PR_INTERVAL_NO_TIMEOUT) &&
            (aTimeout <= (PR_IntervalNow() - aStart));
@@ -1915,17 +1917,18 @@ MessageChannel::SetReplyTimeoutMs(int32_
 }
 
 void
 MessageChannel::OnChannelConnected(int32_t peer_id)
 {
     MOZ_RELEASE_ASSERT(!mPeerPidSet);
     mPeerPidSet = true;
     mPeerPid = peer_id;
-    mWorkerLoop->PostTask(FROM_HERE, new DequeueTask(mOnChannelConnectedTask));
+    RefPtr<DequeueTask> task = new DequeueTask(mOnChannelConnectedTask);
+    mWorkerLoop->PostTask(task.forget());
 }
 
 void
 MessageChannel::DispatchOnChannelConnected()
 {
     AssertWorkerThread();
     MOZ_RELEASE_ASSERT(mPeerPidSet);
     if (mListener)
@@ -2084,18 +2087,19 @@ MessageChannel::OnNotifyMaybeChannelErro
     {
         MonitorAutoLock lock(*mMonitor);
         // nothing to do here
     }
 
     if (IsOnCxxStack()) {
         mChannelErrorTask =
             NewRunnableMethod(this, &MessageChannel::OnNotifyMaybeChannelError);
+        RefPtr<Runnable> task = mChannelErrorTask;
         // 10 ms delay is completely arbitrary
-        mWorkerLoop->PostDelayedTask(FROM_HERE, mChannelErrorTask, 10);
+        mWorkerLoop->PostDelayedTask(task.forget(), 10);
         return;
     }
 
     NotifyMaybeChannelError();
 }
 
 void
 MessageChannel::PostErrorNotifyTask()
@@ -2103,17 +2107,18 @@ MessageChannel::PostErrorNotifyTask()
     mMonitor->AssertCurrentThreadOwns();
 
     if (mChannelErrorTask)
         return;
 
     // This must be the last code that runs on this thread!
     mChannelErrorTask =
         NewRunnableMethod(this, &MessageChannel::OnNotifyMaybeChannelError);
-    mWorkerLoop->PostTask(FROM_HERE, mChannelErrorTask);
+    RefPtr<Runnable> task = mChannelErrorTask;
+    mWorkerLoop->PostTask(task.forget());
 }
 
 // Special async message.
 class GoodbyeMessage : public IPC::Message
 {
 public:
     GoodbyeMessage() :
         IPC::Message(MSG_ROUTING_NONE, GOODBYE_MESSAGE_TYPE, PRIORITY_NORMAL)
@@ -2298,17 +2303,18 @@ MessageChannel::EndTimeout()
     mTimedOutMessageSeqno = 0;
     mTimedOutMessagePriority = 0;
 
     for (size_t i = 0; i < mPending.size(); i++) {
         // There may be messages in the queue that we expected to process from
         // OnMaybeDequeueOne. But during the timeout, that function will skip
         // some messages. Now they're ready to be processed, so we enqueue more
         // tasks.
-        mWorkerLoop->PostTask(FROM_HERE, new DequeueTask(mDequeueOneTask));
+        RefPtr<DequeueTask> task = new DequeueTask(mDequeueOneTask);
+        mWorkerLoop->PostTask(task.forget());
     }
 }
 
 void
 MessageChannel::CancelTransaction(int transaction)
 {
     mMonitor->AssertCurrentThreadOwns();
 
--- a/ipc/glue/MessageChannel.h
+++ b/ipc/glue/MessageChannel.h
@@ -457,58 +457,62 @@ class MessageChannel : HasResultCodes
                            "on worker thread but should not be!");
     }
 
   private:
     typedef IPC::Message::msgid_t msgid_t;
     typedef std::deque<Message> MessageQueue;
     typedef std::map<size_t, Message> MessageMap;
 
+    // XXXkhuey this can almost certainly die.
     // All dequeuing tasks require a single point of cancellation,
     // which is handled via a reference-counted task.
     class RefCountedTask
     {
       public:
-        explicit RefCountedTask(CancelableTask* aTask)
+        explicit RefCountedTask(already_AddRefed<CancelableRunnable> aTask)
           : mTask(aTask)
         { }
       private:
-        ~RefCountedTask() { delete mTask; }
+        ~RefCountedTask() { }
       public:
         void Run() { mTask->Run(); }
         void Cancel() { mTask->Cancel(); }
 
         NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RefCountedTask)
 
       private:
-        CancelableTask* mTask;
+        RefPtr<CancelableRunnable> mTask;
     };
 
     // Wrap an existing task which can be cancelled at any time
     // without the wrapper's knowledge.
-    class DequeueTask : public Task
+    class DequeueTask : public Runnable
     {
       public:
         explicit DequeueTask(RefCountedTask* aTask)
           : mTask(aTask)
         { }
-        void Run() override { mTask->Run(); }
+        NS_IMETHOD Run() override {
+          mTask->Run();
+          return NS_OK;
+        }
 
       private:
         RefPtr<RefCountedTask> mTask;
     };
 
   private:
     mozilla::WeakPtr<MessageListener> mListener;
     ChannelState mChannelState;
     RefPtr<RefCountedMonitor> mMonitor;
     Side mSide;
     MessageLink* mLink;
     MessageLoop* mWorkerLoop;           // thread where work is done
-    CancelableTask* mChannelErrorTask;  // NotifyMaybeChannelError runnable
+    RefPtr<CancelableRunnable> mChannelErrorTask;  // NotifyMaybeChannelError runnable
 
     // id() of mWorkerLoop.  This persists even after mWorkerLoop is cleared
     // during channel shutdown.
     int mWorkerLoopID;
 
     // A task encapsulating dequeuing one pending message.
     RefPtr<RefCountedTask> mDequeueOneTask;
 
--- a/ipc/glue/MessageLink.cpp
+++ b/ipc/glue/MessageLink.cpp
@@ -127,24 +127,22 @@ ProcessLink::Open(mozilla::ipc::Transpor
     {
         MonitorAutoLock lock(*mChan->mMonitor);
 
         if (needOpen) {
             // Transport::Connect() has not been called.  Call it so
             // we start polling our pipe and processing outgoing
             // messages.
             mIOLoop->PostTask(
-                FROM_HERE,
                 NewRunnableMethod(this, &ProcessLink::OnChannelOpened));
         } else {
             // Transport::Connect() has already been called.  Take
             // over the channel from the previous listener and process
             // any queued messages.
             mIOLoop->PostTask(
-                FROM_HERE,
                 NewRunnableMethod(this, &ProcessLink::OnTakeConnectedChannel));
         }
 
 #ifdef MOZ_NUWA_PROCESS
         if (IsNuwaProcess() && NS_IsMainThread() &&
             Preferences::GetBool("dom.ipc.processPrelaunch.testMode")) {
             // The pref value is turned on in a deadlock test against the Nuwa
             // process. The sleep here makes it easy to trigger the deadlock
@@ -163,17 +161,16 @@ ProcessLink::Open(mozilla::ipc::Transpor
 
 void
 ProcessLink::EchoMessage(Message *msg)
 {
     mChan->AssertWorkerThread();
     mChan->mMonitor->AssertCurrentThreadOwns();
 
     mIOLoop->PostTask(
-        FROM_HERE,
         NewRunnableMethod(this, &ProcessLink::OnEchoMessage, msg));
     // OnEchoMessage takes ownership of |msg|
 }
 
 void
 ProcessLink::SendMessage(Message *msg)
 {
     mChan->AssertWorkerThread();
@@ -211,28 +208,26 @@ ProcessLink::SendMessage(Message *msg)
                       jsstack ? jsstack : "<no JS stack>");
         JS_smprintf_free(jsstack);
         MOZ_CRASH();
     }
 #endif
 #endif
 
     mIOLoop->PostTask(
-        FROM_HERE,
         NewRunnableMethod(mTransport, &Transport::Send, msg));
 }
 
 void
 ProcessLink::SendClose()
 {
     mChan->AssertWorkerThread();
     mChan->mMonitor->AssertCurrentThreadOwns();
 
-    mIOLoop->PostTask(
-        FROM_HERE, NewRunnableMethod(this, &ProcessLink::OnCloseChannel));
+    mIOLoop->PostTask(NewRunnableMethod(this, &ProcessLink::OnCloseChannel));
 }
 
 ThreadLink::ThreadLink(MessageChannel *aChan, MessageChannel *aTargetChan)
   : MessageLink(aChan),
     mTargetChan(aTargetChan)
 {
 }
 
--- a/toolkit/xre/nsEmbedFunctions.cpp
+++ b/toolkit/xre/nsEmbedFunctions.cpp
@@ -787,17 +787,18 @@ XRE_RunAppShell()
       // event-loop system, we compromise here by processing any tasks
       // that might have been enqueued on MessagePump, *before*
       // MessagePump::ScheduleWork was able to successfully
       // DispatchToMainThread().
       MessageLoop* loop = MessageLoop::current();
       bool couldNest = loop->NestableTasksAllowed();
 
       loop->SetNestableTasksAllowed(true);
-      loop->PostTask(FROM_HERE, new MessageLoop::QuitTask());
+      RefPtr<Runnable> task = new MessageLoop::QuitTask();
+      loop->PostTask(task.forget());
       loop->Run();
 
       loop->SetNestableTasksAllowed(couldNest);
     }
 #endif  // XP_MACOSX
     return appShell->Run();
 }
 
--- a/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -2096,22 +2096,22 @@ AndroidBridge::ProgressiveUpdateCallback
 }
 
 class AndroidBridge::DelayedTask
 {
     using TimeStamp = mozilla::TimeStamp;
     using TimeDuration = mozilla::TimeDuration;
 
 public:
-    DelayedTask(Task* aTask)
+    DelayedTask(already_AddRefed<Runnable> aTask)
         : mTask(aTask)
         , mRunTime() // Null timestamp representing no delay.
     {}
 
-    DelayedTask(Task* aTask, int aDelayMs)
+    DelayedTask(already_AddRefed<Runnable> aTask, int aDelayMs)
         : mTask(aTask)
         , mRunTime(TimeStamp::Now() + TimeDuration::FromMilliseconds(aDelayMs))
     {}
 
     bool IsEarlierThan(const DelayedTask& aOther) const
     {
         if (mRunTime) {
             return aOther.mRunTime ? mRunTime < aOther.mRunTime : false;
@@ -2124,35 +2124,35 @@ public:
     int64_t MillisecondsToRunTime() const
     {
         if (mRunTime) {
             return int64_t((mRunTime - TimeStamp::Now()).ToMilliseconds());
         }
         return 0;
     }
 
-    UniquePtr<Task>&& GetTask()
+    already_AddRefed<Runnable> TakeTask()
     {
-        return static_cast<UniquePtr<Task>&&>(mTask);
+        return mTask.forget();
     }
 
 private:
-    UniquePtr<Task> mTask;
+    RefPtr<Runnable> mTask;
     const TimeStamp mRunTime;
 };
 
 
 void
-AndroidBridge::PostTaskToUiThread(Task* aTask, int aDelayMs)
+AndroidBridge::PostTaskToUiThread(already_AddRefed<Runnable> aTask, int aDelayMs)
 {
     // add the new task into the mUiTaskQueue, sorted with
     // the earliest task first in the queue
     size_t i;
-    DelayedTask newTask(aDelayMs ? DelayedTask(aTask, aDelayMs)
-                                 : DelayedTask(aTask));
+    DelayedTask newTask(aDelayMs ? DelayedTask(mozilla::Move(aTask), aDelayMs)
+                                 : DelayedTask(mozilla::Move(aTask)));
 
     {
         MutexAutoLock lock(mUiTaskQueueLock);
 
         for (i = 0; i < mUiTaskQueue.Length(); i++) {
             if (newTask.IsEarlierThan(mUiTaskQueue[i])) {
                 mUiTaskQueue.InsertElementAt(i, mozilla::Move(newTask));
                 break;
@@ -2183,17 +2183,17 @@ AndroidBridge::RunDelayedUiThreadTasks()
         if (timeLeft > 0) {
             // this task (and therefore all remaining tasks)
             // have not yet reached their runtime. return the
             // time left until we should be called again
             return timeLeft;
         }
 
         // Retrieve task before unlocking/running.
-        const UniquePtr<Task> nextTask(mUiTaskQueue[0].GetTask());
+        RefPtr<Runnable> nextTask(mUiTaskQueue[0].TakeTask());
         mUiTaskQueue.RemoveElementAt(0);
 
         // Unlock to allow posting new tasks reentrantly.
         MutexAutoUnlock unlock(mUiTaskQueueLock);
         nextTask->Run();
     }
     return -1;
 }
--- a/widget/android/AndroidBridge.h
+++ b/widget/android/AndroidBridge.h
@@ -34,26 +34,27 @@
 #include "mozilla/jni/Utils.h"
 #include "nsIObserver.h"
 
 // Some debug #defines
 // #define DEBUG_ANDROID_EVENTS
 // #define DEBUG_ANDROID_WIDGET
 
 class nsIObserver;
-class Task;
 
 namespace base {
 class Thread;
 } // end namespace base
 
 typedef void* EGLSurface;
 
 namespace mozilla {
 
+class Runnable;
+
 namespace hal {
 class BatteryInformation;
 class NetworkInformation;
 } // namespace hal
 
 namespace dom {
 namespace mobilemessage {
 class SmsFilterData;
@@ -413,17 +414,17 @@ protected:
     void (* Region_set)(void* region, void* rect);
 
 private:
     class DelayedTask;
     nsTArray<DelayedTask> mUiTaskQueue;
     mozilla::Mutex mUiTaskQueueLock;
 
 public:
-    void PostTaskToUiThread(Task* aTask, int aDelayMs);
+    void PostTaskToUiThread(already_AddRefed<Runnable> aTask, int aDelayMs);
     int64_t RunDelayedUiThreadTasks();
 
     void* GetPresentationWindow();
     void SetPresentationWindow(void* aPresentationWindow);
 
     EGLSurface GetPresentationSurface();
     void SetPresentationSurface(EGLSurface aPresentationSurface);
 private:
--- a/widget/android/AndroidContentController.cpp
+++ b/widget/android/AndroidContentController.cpp
@@ -82,19 +82,19 @@ AndroidContentController::HandleSingleTa
                                      NS_ConvertASCIItoUTF16(data).get());
         });
     }
 
     ChromeProcessController::HandleSingleTap(aPoint, aModifiers, aGuid);
 }
 
 void
-AndroidContentController::PostDelayedTask(Task* aTask, int aDelayMs)
+AndroidContentController::PostDelayedTask(already_AddRefed<Runnable> aTask, int aDelayMs)
 {
-    AndroidBridge::Bridge()->PostTaskToUiThread(aTask, aDelayMs);
+    AndroidBridge::Bridge()->PostTaskToUiThread(Move(aTask), aDelayMs);
 }
 void
 AndroidContentController::UpdateOverscrollVelocity(const float aX, const float aY)
 {
   if (mAndroidWindow) {
     mAndroidWindow->UpdateOverscrollVelocity(aX, aY);
   }
 }
--- a/widget/android/AndroidContentController.h
+++ b/widget/android/AndroidContentController.h
@@ -32,17 +32,17 @@ public:
       , mAndroidWindow(aWindow)
     {}
 
     // ChromeProcessController methods
     virtual void Destroy() override;
     void HandleSingleTap(const CSSPoint& aPoint,
                          Modifiers aModifiers,
                          const ScrollableLayerGuid& aGuid) override;
-    void PostDelayedTask(Task* aTask, int aDelayMs) override;
+    void PostDelayedTask(already_AddRefed<Runnable> aTask, int aDelayMs) override;
     void UpdateOverscrollVelocity(const float aX, const float aY) override;
     void UpdateOverscrollOffset(const float aX, const float aY) override;
     void SetScrollingRootContent(const bool isRootContent) override;
     void NotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
                               APZStateChange aChange,
                               int aArg) override;
 
     static void NotifyDefaultPrevented(mozilla::layers::APZCTreeManager* aManager,
--- a/widget/android/nsAppShell.cpp
+++ b/widget/android/nsAppShell.cpp
@@ -686,17 +686,17 @@ nsAppShell::LegacyGeckoEvent::Run()
     case AndroidGeckoEvent::THUMBNAIL: {
         if (!nsAppShell::Get()->mBrowserApp)
             break;
 
         int32_t tabId = curEvent->MetaState();
         const nsTArray<nsIntPoint>& points = curEvent->Points();
         RefCountedJavaObject* buffer = curEvent->ByteBuffer();
         RefPtr<ThumbnailRunnable> sr = new ThumbnailRunnable(nsAppShell::Get()->mBrowserApp, tabId, points, buffer);
-        MessageLoop::current()->PostIdleTask(FROM_HERE, NewRunnableMethod(sr.get(), &ThumbnailRunnable::Run));
+        MessageLoop::current()->PostIdleTask(NewRunnableMethod(sr.get(), &ThumbnailRunnable::Run));
         break;
     }
 
     case AndroidGeckoEvent::ZOOMEDVIEW: {
         if (!nsAppShell::Get()->mBrowserApp)
             break;
         int32_t tabId = curEvent->MetaState();
         const nsTArray<nsIntPoint>& points = curEvent->Points();
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -1099,70 +1099,70 @@ nsBaseWidget::ProcessUntransformedAPZEve
     } else if (WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent()) {
       mAPZEventState->ProcessMouseEvent(*mouseEvent, aGuid, aInputBlockId);
     }
   }
 
   return status;
 }
 
-class DispatchWheelEventOnMainThread : public Task
+class DispatchWheelEventOnMainThread : public Runnable
 {
 public:
   DispatchWheelEventOnMainThread(const ScrollWheelInput& aWheelInput,
                                  nsBaseWidget* aWidget,
                                  nsEventStatus aAPZResult,
                                  uint64_t aInputBlockId,
                                  ScrollableLayerGuid aGuid)
     : mWheelInput(aWheelInput)
     , mWidget(aWidget)
     , mAPZResult(aAPZResult)
     , mInputBlockId(aInputBlockId)
     , mGuid(aGuid)
   {
   }
 
-  void Run()
+  NS_IMETHOD Run() override
   {
     WidgetWheelEvent wheelEvent = mWheelInput.ToWidgetWheelEvent(mWidget);
     mWidget->ProcessUntransformedAPZEvent(&wheelEvent, mGuid, mInputBlockId, mAPZResult);
-    return;
+    return NS_OK;
   }
 
 private:
   ScrollWheelInput mWheelInput;
   nsBaseWidget* mWidget;
   nsEventStatus mAPZResult;
   uint64_t mInputBlockId;
   ScrollableLayerGuid mGuid;
 };
 
-class DispatchWheelInputOnControllerThread : public Task
+class DispatchWheelInputOnControllerThread : public Runnable
 {
 public:
   DispatchWheelInputOnControllerThread(const WidgetWheelEvent& aWheelEvent,
                                        APZCTreeManager* aAPZC,
                                        nsBaseWidget* aWidget)
     : mMainMessageLoop(MessageLoop::current())
     , mWheelInput(aWheelEvent)
     , mAPZC(aAPZC)
     , mWidget(aWidget)
     , mInputBlockId(0)
   {
   }
 
-  void Run()
+  NS_IMETHOD Run() override
   {
     mAPZResult = mAPZC->ReceiveInputEvent(mWheelInput, &mGuid, &mInputBlockId);
     if (mAPZResult == nsEventStatus_eConsumeNoDefault) {
-      return;
+      return NS_OK;
     }
-    mMainMessageLoop->PostTask(FROM_HERE,
-                               new DispatchWheelEventOnMainThread(mWheelInput, mWidget, mAPZResult, mInputBlockId, mGuid));
-    return;
+    RefPtr<Runnable> r = new DispatchWheelEventOnMainThread(mWheelInput, mWidget, mAPZResult, mInputBlockId, mGuid);
+    mMainMessageLoop->PostTask(r.forget());
+    return NS_OK;
   }
 
 private:
   MessageLoop* mMainMessageLoop;
   ScrollWheelInput mWheelInput;
   RefPtr<APZCTreeManager> mAPZC;
   nsBaseWidget* mWidget;
   nsEventStatus mAPZResult;
@@ -1182,17 +1182,18 @@ nsBaseWidget::DispatchInputEvent(WidgetI
       nsEventStatus result = mAPZC->ReceiveInputEvent(*aEvent, &guid, &inputBlockId);
       if (result == nsEventStatus_eConsumeNoDefault) {
           return result;
       }
       return ProcessUntransformedAPZEvent(aEvent, guid, inputBlockId, result);
     } else {
       WidgetWheelEvent* wheelEvent = aEvent->AsWheelEvent();
       if (wheelEvent) {
-        APZThreadUtils::RunOnControllerThread(new DispatchWheelInputOnControllerThread(*wheelEvent, mAPZC, this));
+        RefPtr<Runnable> r = new DispatchWheelInputOnControllerThread(*wheelEvent, mAPZC, this);
+        APZThreadUtils::RunOnControllerThread(r.forget());
         return nsEventStatus_eConsumeDoDefault;
       }
       MOZ_CRASH();
     }
   }
 
   nsEventStatus status;
   DispatchEvent(aEvent, status);
--- a/xpcom/base/nsDumpUtils.cpp
+++ b/xpcom/base/nsDumpUtils.cpp
@@ -70,17 +70,16 @@ void
 FdWatcher::Init()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsCOMPtr<nsIObserverService> os = services::GetObserverService();
   os->AddObserver(this, "xpcom-shutdown", /* ownsWeak = */ false);
 
   XRE_GetIOMessageLoop()->PostTask(
-    FROM_HERE,
     NewRunnableMethod(this, &FdWatcher::StartWatching));
 }
 
 // Implementations may call this function multiple times if they ensure that
 // it's safe to call OpenFd() multiple times and they call StopWatching()
 // first.
 void
 FdWatcher::StartWatching()
--- a/xpcom/base/nsDumpUtils.h
+++ b/xpcom/base/nsDumpUtils.h
@@ -85,17 +85,16 @@ public:
 
   NS_IMETHOD Observe(nsISupports* aSubject, const char* aTopic,
                      const char16_t* aData) override
   {
     MOZ_ASSERT(NS_IsMainThread());
     MOZ_ASSERT(!strcmp(aTopic, "xpcom-shutdown"));
 
     XRE_GetIOMessageLoop()->PostTask(
-      FROM_HERE,
       NewRunnableMethod(this, &FdWatcher::StopWatching));
 
     return NS_OK;
   }
 };
 
 typedef void (*FifoCallback)(const nsCString& aInputStr);
 struct FifoInfo
--- a/xpcom/base/nsMessageLoop.cpp
+++ b/xpcom/base/nsMessageLoop.cpp
@@ -23,23 +23,23 @@ namespace {
  * This Task runs its nsIRunnable when Run() is called, or after
  * aEnsureRunsAfterMS milliseconds have elapsed since the object was
  * constructed.
  *
  * Note that the MessageLoop owns this object and will delete it after it calls
  * Run().  Tread lightly.
  */
 class MessageLoopIdleTask
-  : public Task
+  : public Runnable
   , public SupportsWeakPtr<MessageLoopIdleTask>
 {
 public:
   MOZ_DECLARE_WEAKREFERENCE_TYPENAME(MessageLoopIdleTask)
   MessageLoopIdleTask(nsIRunnable* aTask, uint32_t aEnsureRunsAfterMS);
-  virtual void Run();
+  NS_IMETHOD Run() override;
 
 private:
   nsresult Init(uint32_t aEnsureRunsAfterMS);
 
   nsCOMPtr<nsIRunnable> mTask;
   nsCOMPtr<nsITimer> mTimer;
 
   virtual ~MessageLoopIdleTask() {}
@@ -97,32 +97,34 @@ MessageLoopIdleTask::Init(uint32_t aEnsu
 
   RefPtr<MessageLoopTimerCallback> callback =
     new MessageLoopTimerCallback(this);
 
   return mTimer->InitWithCallback(callback, aEnsureRunsAfterMS,
                                   nsITimer::TYPE_ONE_SHOT);
 }
 
-/* virtual */ void
+NS_IMETHODIMP
 MessageLoopIdleTask::Run()
 {
   // Null out our pointers because if Run() was called by the timer, this
   // object will be kept alive by the MessageLoop until the MessageLoop calls
   // Run().
 
   if (mTimer) {
     mTimer->Cancel();
     mTimer = nullptr;
   }
 
   if (mTask) {
     mTask->Run();
     mTask = nullptr;
   }
+
+  return NS_OK;
 }
 
 MessageLoopTimerCallback::MessageLoopTimerCallback(MessageLoopIdleTask* aTask)
   : mTask(aTask)
 {
 }
 
 NS_IMETHODIMP
@@ -145,18 +147,20 @@ NS_IMPL_ISUPPORTS(MessageLoopTimerCallba
 
 NS_IMPL_ISUPPORTS(nsMessageLoop, nsIMessageLoop)
 
 NS_IMETHODIMP
 nsMessageLoop::PostIdleTask(nsIRunnable* aTask, uint32_t aEnsureRunsAfterMS)
 {
   // The message loop owns MessageLoopIdleTask and deletes it after calling
   // Run().  Be careful...
-  MessageLoop::current()->PostIdleTask(FROM_HERE,
-    new MessageLoopIdleTask(aTask, aEnsureRunsAfterMS));
+  RefPtr<MessageLoopIdleTask> idle =
+    new MessageLoopIdleTask(aTask, aEnsureRunsAfterMS);
+  MessageLoop::current()->PostIdleTask(idle.forget());
+
   return NS_OK;
 }
 
 nsresult
 nsMessageLoopConstructor(nsISupports* aOuter,
                          const nsIID& aIID,
                          void** aInstancePtr)
 {