Backed out changesets 9beb53e53951, 4420bb4e5e7c, de1da65301a8, and cd9c2aaf1343 (bug 970307) for causing frequent B2G debug mochitest-11 crashes.
authorRyan VanderMeulen <ryanvm@gmail.com>
Mon, 24 Nov 2014 17:18:27 -0500
changeset 217191 5c4d07e2199ec4274377558c968fb899f8f467e5
parent 217190 3bd310ee5c22a1e0c10e257eec1fbebff471bc8d
child 217219 4771d3210ca253a919c00bee10470fe29f77d94f
child 217342 79da3cf175ea15b63f7e544f85a9c4cadb005714
push idunknown
push userunknown
push dateunknown
bugs970307
milestone36.0a1
backs out9beb53e53951d493766b172e38f79e8a78bbfd6f
4420bb4e5e7caa858bdd0e2daed565cc01a0be68
de1da65301a8222d31e71261e4b0713d35bf97fc
cd9c2aaf13432e8746497d6e04658bfa53279702
Backed out changesets 9beb53e53951, 4420bb4e5e7c, de1da65301a8, and cd9c2aaf1343 (bug 970307) for causing frequent B2G debug mochitest-11 crashes.
dom/apps/AppsServiceChild.jsm
dom/indexedDB/TransactionThreadPool.cpp
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
dom/ipc/jar.mn
dom/ipc/post-fork-preload.js
dom/ipc/preload.js
dom/ipc/tests/test_NuwaProcessCreation.html
dom/ipc/tests/test_NuwaProcessDeadlock.html
dom/wifi/WifiProxyService.cpp
dom/workers/WorkerPrivate.cpp
netwerk/base/src/nsSocketTransportService2.cpp
testing/mochitest/mochitest_options.py
widget/gonk/GonkMemoryPressureMonitoring.cpp
xpcom/glue/nsThreadUtils.cpp
xpcom/glue/nsThreadUtils.h
xpcom/threads/TimerThread.cpp
xpcom/threads/nsThread.cpp
xpcom/threads/nsThread.h
xpcom/threads/nsThreadManager.cpp
xpcom/threads/nsThreadManager.h
xpcom/threads/nsThreadPool.cpp
xpcom/threads/nsTimerImpl.cpp
--- a/dom/apps/AppsServiceChild.jsm
+++ b/dom/apps/AppsServiceChild.jsm
@@ -98,38 +98,33 @@ this.DOMApplicationRegistry = {
   init: function init() {
     this.cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
                   .getService(Ci.nsISyncMessageSender);
 
     APPS_IPC_MSG_NAMES.forEach((function(aMsgName) {
       this.cpmm.addMessageListener(aMsgName, this);
     }).bind(this));
 
-    this.resetList();
-
-    Services.obs.addObserver(this, "xpcom-shutdown", false);
-  },
-
-  resetList: function() {
     this.cpmm.sendAsyncMessage("Webapps:RegisterForMessages", {
       messages: APPS_IPC_MSG_NAMES
     });
 
     // We need to prime the cache with the list of apps.
     let list = this.cpmm.sendSyncMessage("Webapps:GetList", { })[0];
     this.webapps = list.webapps;
-
     // We need a fast mapping from localId -> app, so we add an index.
     // We also add the manifest to the app object.
     this.localIdIndex = { };
     for (let id in this.webapps) {
       let app = this.webapps[id];
       this.localIdIndex[app.localId] = app;
       app.manifest = list.manifests[id];
     }
+
+    Services.obs.addObserver(this, "xpcom-shutdown", false);
   },
 
   observe: function(aSubject, aTopic, aData) {
     // cpmm.addMessageListener causes the DOMApplicationRegistry object to
     // live forever if we don't clean up properly.
     this.webapps = null;
     this.DOMApps = null;
 
--- a/dom/indexedDB/TransactionThreadPool.cpp
+++ b/dom/indexedDB/TransactionThreadPool.cpp
@@ -14,17 +14,16 @@
 #include "nsIEventTarget.h"
 #include "nsIRunnable.h"
 #include "nsISupportsPriority.h"
 #include "nsIThreadPool.h"
 #include "nsThreadUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsXPCOMCIDInternal.h"
 #include "ProfilerHelpers.h"
-#include "nsThread.h"
 
 namespace mozilla {
 namespace dom {
 namespace indexedDB {
 
 using mozilla::ipc::AssertIsOnBackgroundThread;
 
 namespace {
@@ -168,20 +167,16 @@ public:
   void Dispatch(nsIRunnable* aRunnable);
 
   void Finish(FinishCallback* aFinishCallback);
 
 private:
   ~TransactionQueue()
   { }
 
-#ifdef MOZ_NUWA_PROCESS
-  nsThread* mThread;
-#endif
-
   NS_DECL_NSIRUNNABLE
 };
 
 struct TransactionThreadPool::TransactionInfo MOZ_FINAL
 {
   uint64_t transactionId;
   nsCString databaseId;
   nsRefPtr<TransactionQueue> queue;
@@ -791,19 +786,16 @@ TransactionQueue::TransactionQueue(Trans
                                    uint16_t aMode)
 : mMonitor("TransactionQueue::mMonitor"),
   mOwningThreadPool(aThreadPool),
   mTransactionId(aTransactionId),
   mDatabaseId(aDatabaseId),
   mObjectStoreNames(aObjectStoreNames),
   mMode(aMode),
   mShouldFinish(false)
-#ifdef MOZ_NUWA_PROCESS
-, mThread(nullptr)
-#endif
 {
   MOZ_ASSERT(aThreadPool);
   aThreadPool->AssertIsOnOwningThread();
 }
 
 void
 TransactionThreadPool::TransactionQueue::Unblock()
 {
@@ -819,22 +811,16 @@ void
 TransactionThreadPool::TransactionQueue::Dispatch(nsIRunnable* aRunnable)
 {
   MonitorAutoLock lock(mMonitor);
 
   NS_ASSERTION(!mShouldFinish, "Dispatch called after Finish!");
 
   mQueue.AppendElement(aRunnable);
 
-#ifdef MOZ_NUWA_PROCESS
-  if (mThread) {
-    mThread->SetWorking();
-  }
-#endif
-
   mMonitor.Notify();
 }
 
 void
 TransactionThreadPool::TransactionQueue::Finish(FinishCallback* aFinishCallback)
 {
   MonitorAutoLock lock(mMonitor);
 
@@ -858,32 +844,23 @@ TransactionThreadPool::TransactionQueue:
 
   IDB_PROFILER_MARK("IndexedDB Transaction %llu: Beginning database work",
                     "IDBTransaction[%llu] DT Start",
                     mTransaction->GetSerialNumber());
 
   nsAutoTArray<nsCOMPtr<nsIRunnable>, 10> queue;
   nsRefPtr<FinishCallback> finishCallback;
   bool shouldFinish = false;
-#ifdef MOZ_NUWA_PROCESS
-  mThread = static_cast<nsThread*>(NS_GetCurrentThread());
-  // Set ourself as working thread. We can reset later if we found
-  // our queue is empty.
-  mThread->SetWorking();
-#endif
 
   do {
     NS_ASSERTION(queue.IsEmpty(), "Should have cleared this!");
 
     {
       MonitorAutoLock lock(mMonitor);
       while (!mShouldFinish && mQueue.IsEmpty()) {
-#ifdef MOZ_NUWA_PROCESS
-        mThread->SetIdle();
-#endif
         if (NS_FAILED(mMonitor.Wait())) {
           NS_ERROR("Failed to wait!");
         }
       }
 
       mQueue.SwapElements(queue);
       if (mShouldFinish) {
         mFinishCallback.swap(finishCallback);
@@ -906,20 +883,16 @@ TransactionThreadPool::TransactionQueue:
       runnable = nullptr;
     }
 
     if (count) {
       queue.Clear();
     }
   } while (!shouldFinish);
 
-#ifdef MOZ_NUWA_PROCESS
-  mThread = nullptr;
-#endif
-
 #ifdef DEBUG
   if (kDEBUGThreadSleepMS) {
     MOZ_ALWAYS_TRUE(
       PR_Sleep(PR_MillisecondsToInterval(kDEBUGThreadSleepMS)) == PR_SUCCESS);
   }
 #endif // DEBUG
 
   IDB_PROFILER_MARK("IndexedDB Transaction %llu: Finished database work",
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -502,33 +502,26 @@ private:
         MOZ_CRASH("Failed to create a PBackgroundChild actor!");
     }
 };
 
 NS_IMPL_ISUPPORTS(BackgroundChildPrimer, nsIIPCBackgroundChildCreateCallback)
 
 ContentChild* ContentChild::sSingleton;
 
-static void
-PostForkPreload()
-{
-    TabChild::PostForkPreload();
-}
-
 // Performs initialization that is not fork-safe, i.e. that must be done after
 // forking from the Nuwa process.
 static void
 InitOnContentProcessCreated()
 {
 #ifdef MOZ_NUWA_PROCESS
     // Wait until we are forked from Nuwa
     if (IsNuwaProcess()) {
         return;
     }
-    PostForkPreload();
 #endif
 
     // This will register cross-process observer.
     mozilla::dom::time::InitializeDateCacheCleaner();
 }
 
 #if defined(MOZ_TASK_TRACER) && defined(MOZ_NUWA_PROCESS)
 static void
@@ -1240,16 +1233,17 @@ ContentChild::RecvPBrowserConstructor(PB
                                       const IPCTabContext& aContext,
                                       const uint32_t& aChromeFlags,
                                       const ContentParentId& aCpID,
                                       const bool& aIsForApp,
                                       const bool& aIsForBrowser)
 {
     // This runs after AllocPBrowserChild() returns and the IPC machinery for this
     // PBrowserChild has been set up.
+
     nsCOMPtr<nsIObserverService> os = services::GetObserverService();
     if (os) {
         nsITabChild* tc =
             static_cast<nsITabChild*>(static_cast<TabChild*>(aActor));
         os->NotifyObservers(tc, "tab-child-created", nullptr);
     }
 
     static bool hasRunOnce = false;
@@ -1987,21 +1981,18 @@ ContentChild::RecvScreenSizeChanged(cons
 #endif
     return true;
 }
 
 bool
 ContentChild::RecvFlushMemory(const nsString& reason)
 {
 #ifdef MOZ_NUWA_PROCESS
-    if (IsNuwaProcess() || ManagedPBrowserChild().Length() == 0) {
+    if (IsNuwaProcess()) {
         // Don't flush memory in the nuwa process: the GC thread could be frozen.
-        // If there's no PBrowser child, don't flush memory, either. GC writes
-        // to copy-on-write pages and makes preallocated process take more memory
-        // before it actually becomes an app.
         return true;
     }
 #endif
     nsCOMPtr<nsIObserverService> os =
         mozilla::services::GetObserverService();
     if (os)
         os->NotifyObservers(nullptr, "memory-pressure", reason.get());
     return true;
@@ -2079,45 +2070,30 @@ ContentChild::RecvAppInfo(const nsCStrin
 
     // If we're part of the mozbrowser machinery, go ahead and start
     // preloading things.  We can only do this for mozbrowser because
     // PreloadSlowThings() may set the docshell of the first TabChild
     // inactive, and we can only safely restore it to active from
     // BrowserElementChild.js.
     if ((mIsForApp || mIsForBrowser)
 #ifdef MOZ_NUWA_PROCESS
-        && IsNuwaProcess()
+        && !IsNuwaProcess()
 #endif
        ) {
         PreloadSlowThings();
-#ifndef MOZ_NUWA_PROCESS
-        PostForkPreload();
-#endif
     }
 
 #ifdef MOZ_NUWA_PROCESS
-    // Some modules are initialized in preloading. We need to wait until the
-    // tasks they dispatched to chrome process are done.
-    if (IsNuwaProcess()) {
-        SendNuwaWaitForFreeze();
-    }
-#endif
-    return true;
-}
-
-bool
-ContentChild::RecvNuwaFreeze()
-{
-#ifdef MOZ_NUWA_PROCESS
     if (IsNuwaProcess()) {
         ContentChild::GetSingleton()->RecvGarbageCollect();
         MessageLoop::current()->PostTask(
             FROM_HERE, NewRunnableFunction(OnFinishNuwaPreparation));
     }
 #endif
+
     return true;
 }
 
 bool
 ContentChild::RecvLastPrivateDocShellDestroyed()
 {
     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
     obs->NotifyObservers(nullptr, "last-pb-context-exited", nullptr);
@@ -2362,60 +2338,43 @@ DoNuwaFork()
  */
 static void
 RunNuwaFork()
 {
     if (NuwaCheckpointCurrentThread()) {
       DoNuwaFork();
     }
 }
-
-class NuwaForkCaller: public nsRunnable
-{
-public:
-    NS_IMETHODIMP
-    Run() {
-        // We want to ensure that the PBackground actor gets cloned in the Nuwa
-        // process before we freeze. Also, we have to do this to avoid deadlock.
-        // Protocols that are "opened" (e.g. PBackground, PCompositor) block the
-        // main thread to wait for the IPC thread during the open operation.
-        // NuwaSpawnWait() blocks the IPC thread to wait for the main thread when
-        // the Nuwa process is forked. Unless we ensure that the two cannot happen
-        // at the same time then we risk deadlock. Spinning the event loop here
-        // guarantees the ordering is safe for PBackground.
-        if (!BackgroundChild::GetForCurrentThread()) {
-            // Dispatch ourself again.
-            NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL);
-        } else {
-            MessageLoop* ioloop = XRE_GetIOMessageLoop();
-            ioloop->PostTask(FROM_HERE, NewRunnableFunction(RunNuwaFork));
-        }
-        return NS_OK;
-    }
-private:
-    virtual
-    ~NuwaForkCaller()
-    {
-    }
-};
-
 #endif
 
 bool
 ContentChild::RecvNuwaFork()
 {
 #ifdef MOZ_NUWA_PROCESS
     if (sNuwaForking) {           // No reentry.
         return true;
     }
     sNuwaForking = true;
 
-    nsRefPtr<NuwaForkCaller> runnable = new NuwaForkCaller();
-    NS_DispatchToMainThread(runnable, NS_DISPATCH_NORMAL);
+    // We want to ensure that the PBackground actor gets cloned in the Nuwa
+    // process before we freeze. Also, we have to do this to avoid deadlock.
+    // Protocols that are "opened" (e.g. PBackground, PCompositor) block the
+    // main thread to wait for the IPC thread during the open operation.
+    // NuwaSpawnWait() blocks the IPC thread to wait for the main thread when
+    // the Nuwa process is forked. Unless we ensure that the two cannot happen
+    // at the same time then we risk deadlock. Spinning the event loop here
+    // guarantees the ordering is safe for PBackground.
+    while (!BackgroundChild::GetForCurrentThread()) {
+        if (NS_WARN_IF(!NS_ProcessNextEvent())) {
+            return false;
+        }
+    }
 
+    MessageLoop* ioloop = XRE_GetIOMessageLoop();
+    ioloop->PostTask(FROM_HERE, NewRunnableFunction(RunNuwaFork));
     return true;
 #else
     return false; // Makes the underlying IPC channel abort.
 #endif
 }
 
 bool
 ContentChild::RecvOnAppThemeChanged()
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -345,18 +345,16 @@ public:
     virtual bool RecvMinimizeMemoryUsage() MOZ_OVERRIDE;
 
     virtual bool RecvLoadAndRegisterSheet(const URIParams& aURI,
                                           const uint32_t& aType) MOZ_OVERRIDE;
     virtual bool RecvUnregisterSheet(const URIParams& aURI, const uint32_t& aType) MOZ_OVERRIDE;
 
     virtual bool RecvNotifyPhoneStateChange(const nsString& state) MOZ_OVERRIDE;
 
-    virtual bool RecvNuwaFreeze() MOZ_OVERRIDE;
-
     void AddIdleObserver(nsIObserver* aObserver, uint32_t aIdleTimeInS);
     void RemoveIdleObserver(nsIObserver* aObserver, uint32_t aIdleTimeInS);
     virtual bool RecvNotifyIdleObserver(const uint64_t& aObserver,
                                         const nsCString& aTopic,
                                         const nsString& aData) MOZ_OVERRIDE;
 
     virtual bool RecvOnAppThemeChanged() MOZ_OVERRIDE;
 
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -117,17 +117,16 @@
 #include "nsIURIFixup.h"
 #include "nsIWindowWatcher.h"
 #include "nsIXULRuntime.h"
 #include "nsMemoryInfoDumper.h"
 #include "nsMemoryReporterManager.h"
 #include "nsServiceManagerUtils.h"
 #include "nsStyleSheetService.h"
 #include "nsThreadUtils.h"
-#include "nsThreadManager.h"
 #include "nsToolkitCompsCID.h"
 #include "nsWidgetsCID.h"
 #include "PreallocatedProcessManager.h"
 #include "ProcessPriorityManager.h"
 #include "SandboxHal.h"
 #include "ScreenManagerParent.h"
 #include "StructuredCloneUtils.h"
 #include "TabParent.h"
@@ -1366,38 +1365,16 @@ private:
 };
 
 StaticAutoPtr<LinkedList<SystemMessageHandledListener> >
     SystemMessageHandledListener::sListeners;
 
 NS_IMPL_ISUPPORTS(SystemMessageHandledListener,
                   nsITimerCallback)
 
-#ifdef MOZ_NUWA_PROCESS
-class NuwaFreezeListener : public nsThreadManager::AllThreadsWereIdleListener
-{
-public:
-    NuwaFreezeListener(ContentParent* parent)
-        : mParent(parent)
-    {
-    }
-
-    void OnAllThreadsWereIdle()
-    {
-        unused << mParent->SendNuwaFreeze();
-        nsThreadManager::get()->RemoveAllThreadsWereIdleListener(this);
-    }
-private:
-    nsRefPtr<ContentParent> mParent;
-    virtual ~NuwaFreezeListener()
-    {
-    }
-};
-#endif // MOZ_NUWA_PROCESS
-
 } // anonymous namespace
 
 void
 ContentParent::MaybeTakeCPUWakeLock(Element* aFrameElement)
 {
     // Take the CPU wake lock on behalf of this processs if it's expecting a
     // system message.  We'll release the CPU lock once the message is
     // delivered, or after some period of time, which ever comes first.
@@ -2075,18 +2052,16 @@ ContentParent::ContentParent(ContentPare
     // memory priority, which it has inherited from this process.
     ProcessPriority priority;
     if (IsPreallocated()) {
         priority = PROCESS_PRIORITY_PREALLOC;
     } else {
         priority = PROCESS_PRIORITY_FOREGROUND;
     }
 
-    mSendPermissionUpdates = aTemplate->mSendPermissionUpdates;
-
     InitInternal(priority,
                  false, /* Setup Off-main thread compositing */
                  false  /* Send registered chrome */);
 
     ContentProcessManager::GetSingleton()->AddContentProcess(this);
 }
 #endif  // MOZ_NUWA_PROCESS
 
@@ -2234,17 +2209,17 @@ ContentParent::IsAlive()
 bool
 ContentParent::IsForApp()
 {
     return !mAppManifestURL.IsEmpty();
 }
 
 #ifdef MOZ_NUWA_PROCESS
 bool
-ContentParent::IsNuwaProcess() const
+ContentParent::IsNuwaProcess()
 {
     return mIsNuwaProcess;
 }
 #endif
 
 int32_t
 ContentParent::Pid()
 {
@@ -2584,29 +2559,16 @@ ContentParent::RecvNuwaReady()
     return true;
 #else
     NS_ERROR("ContentParent::RecvNuwaReady() not implemented!");
     return false;
 #endif
 }
 
 bool
-ContentParent::RecvNuwaWaitForFreeze()
-{
-#ifdef MOZ_NUWA_PROCESS
-    nsRefPtr<NuwaFreezeListener> listener = new NuwaFreezeListener(this);
-    nsThreadManager::get()->AddAllThreadsWereIdleListener(listener);
-    return true;
-#else // MOZ_NUWA_PROCESS
-    NS_ERROR("ContentParent::RecvNuwaWaitForFreeze() not implemented!");
-    return false;
-#endif // MOZ_NUWA_PROCESS
-}
-
-bool
 ContentParent::RecvAddNewProcess(const uint32_t& aPid,
                                  const InfallibleTArray<ProtocolFdMapping>& aFds)
 {
 #ifdef MOZ_NUWA_PROCESS
     if (!IsNuwaProcess()) {
         NS_ERROR(
             nsPrintfCString(
                 "Terminating child process %d for unauthorized IPC message: "
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -201,35 +201,31 @@ public:
 
     bool IsAlive();
     virtual bool IsForApp() MOZ_OVERRIDE;
     virtual bool IsForBrowser() MOZ_OVERRIDE
     {
       return mIsForBrowser;
     }
 #ifdef MOZ_NUWA_PROCESS
-    bool IsNuwaProcess() const;
+    bool IsNuwaProcess();
 #endif
 
     GeckoChildProcessHost* Process() {
         return mSubprocess;
     }
 
     int32_t Pid();
 
     ContentParent* Opener() {
         return mOpener;
     }
 
     bool NeedsPermissionsUpdate() const {
-#ifdef MOZ_NUWA_PROCESS
-        return !IsNuwaProcess() && mSendPermissionUpdates;
-#else
         return mSendPermissionUpdates;
-#endif
     }
 
     bool NeedsDataStoreInfos() const {
         return mSendDataStoreInfos;
     }
 
     /**
      * Kill our subprocess and make sure it dies.  Should only be used
@@ -678,18 +674,16 @@ private:
     virtual bool RecvSpeakerManagerGetSpeakerStatus(bool* aValue) MOZ_OVERRIDE;
 
     virtual bool RecvSpeakerManagerForceSpeaker(const bool& aEnable) MOZ_OVERRIDE;
 
     virtual bool RecvSystemMessageHandled() MOZ_OVERRIDE;
 
     virtual bool RecvNuwaReady() MOZ_OVERRIDE;
 
-    virtual bool RecvNuwaWaitForFreeze() MOZ_OVERRIDE;
-
     virtual bool RecvAddNewProcess(const uint32_t& aPid,
                                    const InfallibleTArray<ProtocolFdMapping>& aFds) MOZ_OVERRIDE;
 
     virtual bool RecvCreateFakeVolume(const nsString& fsName, const nsString& mountPoint) MOZ_OVERRIDE;
 
     virtual bool RecvSetFakeVolumeState(const nsString& fsName, const int32_t& fsState) MOZ_OVERRIDE;
 
     virtual bool RecvKeywordToURI(const nsCString& aKeyword,
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -513,17 +513,16 @@ child:
      * Control the Gecko Profiler in the child process.
      */
     async StartProfiler(uint32_t aEntries, double aInterval, nsCString[] aFeatures,
                         nsCString[] aThreadNameFilters);
     async StopProfiler();
     intr GetProfile()
       returns (nsCString aProfile);
 
-    NuwaFreeze();
 parent:
     /**
      * Tell the parent process a new accessible document has been created.
      * aParentDoc is the accessible document it was created in if any, and
      * aParentAcc is the id of the accessible in that document the new document
      * is a child of.
      */
     PDocAccessible(nullable PDocAccessible aParentDoc, uint64_t aParentAcc);
@@ -724,19 +723,16 @@ parent:
                                nsCString aReason);
 
     sync GetVolumes() returns (VolumeInfo[] volumes);
 
     // Notify the parent that the child has finished handling a system message.
     async SystemMessageHandled();
 
     NuwaReady();
-    // Sent when nuwa finished its initialization process and is waiting for
-    // parent's signal to make it freeze.
-    NuwaWaitForFreeze();
 
     sync AddNewProcess(uint32_t pid, ProtocolFdMapping[] aFds);
 
     // called by the child (test code only) to propagate volume changes to the parent
     async CreateFakeVolume(nsString fsName, nsString mountPoint);
     async SetFakeVolumeState(nsString fsName, int32_t fsState);
 
     sync KeywordToURI(nsCString keyword)
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -828,31 +828,16 @@ TabChild::PreloadSlowThings()
         // work.
         presShell->MakeZombie();
     }
 
     sPreallocatedTab = tab;
     ClearOnShutdown(&sPreallocatedTab);
 }
 
-/*static*/ void
-TabChild::PostForkPreload()
-{
-    // Preallocated Tab can be null if we are forked directly from b2g. In such
-    // case we don't need to preload anything, just return.
-    if (!sPreallocatedTab) {
-        return;
-    }
-
-    // Rebuild connections to parent.
-    sPreallocatedTab->RecvLoadRemoteScript(
-      NS_LITERAL_STRING("chrome://global/content/post-fork-preload.js"),
-      true);
-}
-
 /*static*/ already_AddRefed<TabChild>
 TabChild::Create(nsIContentChild* aManager,
                  const TabId& aTabId,
                  const TabContext &aContext,
                  uint32_t aChromeFlags)
 {
     if (sPreallocatedTab &&
         sPreallocatedTab->mChromeFlags == aChromeFlags &&
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -263,17 +263,16 @@ public:
 
 public:
     /** 
      * This is expected to be called off the critical path to content
      * startup.  This is an opportunity to load things that are slow
      * on the critical path.
      */
     static void PreloadSlowThings();
-    static void PostForkPreload();
 
     /** Return a TabChild with the given attributes. */
     static already_AddRefed<TabChild>
     Create(nsIContentChild* aManager, const TabId& aTabId, const TabContext& aContext, uint32_t aChromeFlags);
 
     bool IsRootContentDocument();
 
     const TabId GetTabId() const {
--- a/dom/ipc/jar.mn
+++ b/dom/ipc/jar.mn
@@ -4,9 +4,8 @@
 
 toolkit.jar:
         content/global/test-ipc.xul (test.xul)
         content/global/remote-test-ipc.js (remote-test.js)
         content/global/BrowserElementChild.js (../browser-element/BrowserElementChild.js)
         content/global/BrowserElementChildPreload.js (../browser-element/BrowserElementChildPreload.js)
 *       content/global/BrowserElementPanning.js (../browser-element/BrowserElementPanning.js)
         content/global/preload.js (preload.js)
-        content/global/post-fork-preload.js (post-fork-preload.js)
deleted file mode 100644
--- a/dom/ipc/post-fork-preload.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/* 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/. */
-
-// Preload some things, in an attempt to make app startup faster.
-//
-// This script is run when the preallocated process starts.  It is injected as
-// a frame script.
-// If Nuwa process is enabled, this script will run in preallocated process
-// forked by Nuwa.
-
-(function (global) {
-  "use strict";
-
-  Components.utils.import("resource://gre/modules/AppsServiceChild.jsm");
-  Components.classes["@mozilla.org/network/protocol-proxy-service;1"].
-    getService(Ci["nsIProtocolProxyService"]);
-
-  DOMApplicationRegistry.resetList();
-})(this);
--- a/dom/ipc/preload.js
+++ b/dom/ipc/preload.js
@@ -1,17 +1,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/. */
 
 // Preload some things, in an attempt to make app startup faster.
 //
 // This script is run when the preallocated process starts.  It is injected as
 // a frame script.
-// If nuwa is enabled, this script will run in Nuwa process before frozen.
 
 const BrowserElementIsPreloaded = true;
 
 (function (global) {
   "use strict";
 
   let Cu = Components.utils;
   let Cc = Components.classes;
@@ -49,16 +48,17 @@ const BrowserElementIsPreloaded = true;
   Cc["@mozilla.org/message-loop;1"].getService(Ci["nsIMessageLoop"]);
   Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci["mozIJSSubScriptLoader"]);
   Cc["@mozilla.org/network/application-cache-service;1"].getService(Ci["nsIApplicationCacheService"]);
   Cc["@mozilla.org/network/dns-service;1"].getService(Ci["nsIDNSService"]);
   Cc["@mozilla.org/network/effective-tld-service;1"].getService(Ci["nsIEffectiveTLDService"]);
   Cc["@mozilla.org/network/idn-service;1"].getService(Ci["nsIIDNService"]);
   Cc["@mozilla.org/network/io-service;1"].getService(Ci["nsIIOService2"]);
   Cc["@mozilla.org/network/mime-hdrparam;1"].getService(Ci["nsIMIMEHeaderParam"]);
+  Cc["@mozilla.org/network/protocol-proxy-service;1"].getService(Ci["nsIProtocolProxyService"]);
   Cc["@mozilla.org/network/socket-transport-service;1"].getService(Ci["nsISocketTransportService"]);
   Cc["@mozilla.org/network/stream-transport-service;1"].getService(Ci["nsIStreamTransportService"]);
   Cc["@mozilla.org/network/url-parser;1?auth=maybe"].getService(Ci["nsIURLParser"]);
   Cc["@mozilla.org/network/url-parser;1?auth=no"].getService(Ci["nsIURLParser"]);
   Cc["@mozilla.org/network/url-parser;1?auth=yes"].getService(Ci["nsIURLParser"]);
   Cc["@mozilla.org/observer-service;1"].getService(Ci["nsIObserverService"]);
   Cc["@mozilla.org/permissionmanager;1"].getService(Ci["nsIPermissionManager"]);
   Cc["@mozilla.org/preferences-service;1"].getService(Ci["nsIPrefBranch"]);
--- a/dom/ipc/tests/test_NuwaProcessCreation.html
+++ b/dom/ipc/tests/test_NuwaProcessCreation.html
@@ -71,17 +71,17 @@ function runTest()
         is(seenNuwaReady, true, "Receive nuwa-add-new-process before nuwa-ready");
         testEnd();
       }
     }
   };
   let timeout = setTimeout(function() {
     ok(false, "Nuwa process is not launched");
     testEnd();
-  }, 240000);
+  }, 60000);
 
   function testEnd() {
     cpmm.removeMessageListener("TEST-ONLY:nuwa-ready", msgHandler);
     cpmm.removeMessageListener("TEST-ONLY:nuwa-add-new-process", msgHandler);
     clearTimeout(timeout);
     SimpleTest.finish();
   }
 
--- a/dom/ipc/tests/test_NuwaProcessDeadlock.html
+++ b/dom/ipc/tests/test_NuwaProcessDeadlock.html
@@ -72,17 +72,17 @@ function runTest()
         is(seenNuwaReady, true, "Receive nuwa-add-new-process before nuwa-ready");
         testEnd();
       }
     }
   };
   let timeout = setTimeout(function() {
     ok(false, "Nuwa process is not launched");
     testEnd();
-  }, 240000);
+  }, 90000);
 
   function testEnd() {
     cpmm.removeMessageListener("TEST-ONLY:nuwa-ready", msgHandler);
     cpmm.removeMessageListener("TEST-ONLY:nuwa-add-new-process", msgHandler);
     clearTimeout(timeout);
     setPref('dom.ipc.processPrelaunch.testMode', false);
     SimpleTest.finish();
   }
--- a/dom/wifi/WifiProxyService.cpp
+++ b/dom/wifi/WifiProxyService.cpp
@@ -60,19 +60,16 @@ public:
     : mInterface(aInterface)
   {
     MOZ_ASSERT(NS_IsMainThread());
   }
 
   NS_IMETHOD Run()
   {
     MOZ_ASSERT(!NS_IsMainThread());
-#ifdef MOZ_NUWA_PROCESS
-    NS_SetIgnoreStatusOfCurrentThread();
-#endif
     nsAutoString event;
     gWpaSupplicant->WaitForEvent(event, mInterface);
     if (!event.IsEmpty()) {
 #ifdef MOZ_TASK_TRACER
       // Make wifi initialization events to be the source events of TaskTracer,
       // and originate the rest correlation tasks from here.
       AutoSourceEvent taskTracerEvent(SourceEventType::Wifi);
       AddLabel("%s %s", mInterface.get(), NS_ConvertUTF16toUTF8(event).get());
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -60,17 +60,16 @@
 #include "nsDOMJSUtils.h"
 #include "nsHostObjectProtocolHandler.h"
 #include "nsJSEnvironment.h"
 #include "nsJSUtils.h"
 #include "nsNetUtil.h"
 #include "nsPrintfCString.h"
 #include "nsProxyRelease.h"
 #include "nsSandboxFlags.h"
-#include "nsThread.h"
 #include "xpcpublic.h"
 
 #ifdef ANDROID
 #include <android/log.h>
 #endif
 
 #ifdef DEBUG
 #include "nsThreadManager.h"
@@ -4162,27 +4161,16 @@ WorkerPrivate::DoRunLoop(JSContext* aCx)
     }
 
     Status currentStatus;
     bool normalRunnablesPending = false;
 
     {
       MutexAutoLock lock(mMutex);
 
-#ifdef MOZ_NUWA_PROCESS
-      {
-        nsThread *thr = static_cast<nsThread*>(NS_GetCurrentThread());
-        ReentrantMonitorAutoEnter mon(thr->ThreadStatusMonitor());
-        if (mControlQueue.IsEmpty() &&
-            !(normalRunnablesPending = NS_HasPendingEvents(mThread))) {
-          thr->SetIdle();
-        }
-      }
-#endif // MOZ_NUWA_PROCESS
-
       while (mControlQueue.IsEmpty() &&
              !(normalRunnablesPending = NS_HasPendingEvents(mThread))) {
         WaitForWorkerEvents();
       }
 
       ProcessAllControlRunnablesLocked();
 
       currentStatus = mStatus;
--- a/netwerk/base/src/nsSocketTransportService2.cpp
+++ b/netwerk/base/src/nsSocketTransportService2.cpp
@@ -696,17 +696,16 @@ nsSocketTransportService::Run()
     PR_SetCurrentThreadName("Socket Thread");
 
 #ifdef MOZ_NUWA_PROCESS
     if (IsNuwaProcess()) {
         NS_ASSERTION(NuwaMarkCurrentThread != nullptr,
                      "NuwaMarkCurrentThread is undefined!");
         NuwaMarkCurrentThread(nullptr, nullptr);
     }
-    NS_SetIgnoreStatusOfCurrentThread();
 #endif
 
     SOCKET_LOG(("STS thread init\n"));
 
     psm::InitializeSSLServerCertVerificationThreads();
 
     gSocketThread = PR_GetCurrentThread();
 
--- a/testing/mochitest/mochitest_options.py
+++ b/testing/mochitest/mochitest_options.py
@@ -800,17 +800,17 @@ class B2GOptions(MochitestOptions):
         defaults["httpPort"] = DEFAULT_PORTS['http']
         defaults["sslPort"] = DEFAULT_PORTS['https']
         defaults["logFile"] = "mochitest.log"
         defaults["autorun"] = True
         defaults["closeWhenDone"] = True
         defaults["testPath"] = ""
         defaults["extensionsToExclude"] = ["specialpowers"]
         # See dependencies of bug 1038943.
-        defaults["defaultLeakThreshold"] = 5308
+        defaults["defaultLeakThreshold"] = 5180
         self.set_defaults(**defaults)
 
     def verifyRemoteOptions(self, options):
         if options.remoteWebServer == None:
             if os.name != "nt":
                 options.remoteWebServer = moznetwork.get_ip()
             else:
                 self.error("You must specify a --remote-webserver=<ip address>")
--- a/widget/gonk/GonkMemoryPressureMonitoring.cpp
+++ b/widget/gonk/GonkMemoryPressureMonitoring.cpp
@@ -122,18 +122,16 @@ public:
 #ifdef MOZ_NUWA_PROCESS
     if (IsNuwaProcess()) {
       NS_ASSERTION(NuwaMarkCurrentThread != nullptr,
                    "NuwaMarkCurrentThread is undefined!");
       NuwaMarkCurrentThread(nullptr, nullptr);
     }
 #endif
 
-    NS_SetIgnoreStatusOfCurrentThread();
-
     int lowMemFd = open("/sys/kernel/mm/lowmemkiller/notify_trigger_active",
                         O_RDONLY | O_CLOEXEC);
     NS_ENSURE_STATE(lowMemFd != -1);
     ScopedClose autoClose(lowMemFd);
 
     nsresult rv = CheckForMemoryPressure(lowMemFd, nullptr);
     NS_ENSURE_SUCCESS(rv, rv);
 
--- a/xpcom/glue/nsThreadUtils.cpp
+++ b/xpcom/glue/nsThreadUtils.cpp
@@ -370,16 +370,8 @@ nsAutoLowPriorityIO::~nsAutoLowPriorityI
   }
 #elif defined(XP_MACOSX)
   if (MOZ_LIKELY(lowIOPrioritySet)) {
     setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_THREAD, oldPriority);
   }
 #endif
 }
 
-#ifdef MOZ_NUWA_PROCESS
-#ifdef MOZILLA_INTERNAL_API
-void
-NS_SetIgnoreStatusOfCurrentThread() {
-  nsThreadManager::get()->SetIgnoreThreadStatus();
-}
-#endif // MOZILLA_INTERNAL_API
-#endif // MOZ_NUWA_PROCESS
--- a/xpcom/glue/nsThreadUtils.h
+++ b/xpcom/glue/nsThreadUtils.h
@@ -560,24 +560,9 @@ private:
 #if defined(XP_MACOSX)
   int oldPriority;
 #endif
 };
 
 void
 NS_SetMainThread();
 
-/**
- * Helpers for thread to report their status when compiled with Nuwa.
- */
-#ifdef MOZILLA_INTERNAL_API
-#ifdef MOZ_NUWA_PROCESS
-extern void
-NS_SetIgnoreStatusOfCurrentThread();
-#else // MOZ_NUWA_PROCESS
-inline void
-NS_SetIgnoreStatusOfCurrentThread()
-{
-}
-#endif // MOZ_NUWA_PROCESS
-#endif // MOZILLA_INTERNAL_API
-
 #endif  // nsThreadUtils_h__
--- a/xpcom/threads/TimerThread.cpp
+++ b/xpcom/threads/TimerThread.cpp
@@ -202,17 +202,16 @@ TimerThread::Run()
 #ifdef MOZ_NUWA_PROCESS
   if (IsNuwaProcess()) {
     NS_ASSERTION(NuwaMarkCurrentThread,
                  "NuwaMarkCurrentThread is undefined!");
     NuwaMarkCurrentThread(nullptr, nullptr);
   }
 #endif
 
-  NS_SetIgnoreStatusOfCurrentThread();
   MonitorAutoLock lock(mMonitor);
 
   // We need to know how many microseconds give a positive PRIntervalTime. This
   // is platform-dependent and we calculate it at runtime, finding a value |v|
   // such that |PR_MicrosecondsToInterval(v) > 0| and then binary-searching in
   // the range [0, v) to find the ms-to-interval scale.
   uint32_t usForPosInterval = 1;
   while (PR_MicrosecondsToInterval(usForPosInterval) == 0) {
--- a/xpcom/threads/nsThread.cpp
+++ b/xpcom/threads/nsThread.cpp
@@ -8,16 +8,17 @@
 
 #include "base/message_loop.h"
 
 // Chromium's logging can sometimes leak through...
 #ifdef LOG
 #undef LOG
 #endif
 
+#include "mozilla/ReentrantMonitor.h"
 #include "nsMemoryPressure.h"
 #include "nsThreadManager.h"
 #include "nsIClassInfoImpl.h"
 #include "nsIProgrammingLanguage.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "pratom.h"
 #include "prlog.h"
@@ -323,20 +324,16 @@ SetupCurrentThreadForChaosMode()
 nsThread::ThreadFunc(void* aArg)
 {
   nsThread* self = static_cast<nsThread*>(aArg);  // strong reference
   self->mThread = PR_GetCurrentThread();
   SetupCurrentThreadForChaosMode();
 
   // Inform the ThreadManager
   nsThreadManager::get()->RegisterCurrentThread(self);
-#ifdef MOZ_NUWA_PROCESS
-  self->mThreadStatusInfo =
-    static_cast<void*>(nsThreadManager::get()->GetCurrentThreadStatusInfo());
-#endif
 
   mozilla::IOInterposer::RegisterCurrentThread();
 
   // Wait for and process startup event
   nsCOMPtr<nsIRunnable> event;
   if (!self->GetEvent(true, getter_AddRefs(event))) {
     NS_WARNING("failed waiting for thread startup event");
     return;
@@ -432,20 +429,16 @@ nsThread::nsThread(MainThreadFlag aMainT
   , mPriority(PRIORITY_NORMAL)
   , mThread(nullptr)
   , mRunningEvent(0)
   , mStackSize(aStackSize)
   , mShutdownContext(nullptr)
   , mShutdownRequired(false)
   , mEventsAreDoomed(false)
   , mIsMainThread(aMainThread)
-#ifdef MOZ_NUWA_PROCESS
-  , mThreadStatusMonitor("nsThread.mThreadStatusLock")
-  , mThreadStatusInfo(nullptr)
-#endif
 {
 }
 
 nsThread::~nsThread()
 {
 }
 
 nsresult
@@ -483,45 +476,32 @@ nsThread::Init()
 
 nsresult
 nsThread::InitCurrentThread()
 {
   mThread = PR_GetCurrentThread();
   SetupCurrentThreadForChaosMode();
 
   nsThreadManager::get()->RegisterCurrentThread(this);
-#ifdef MOZ_NUWA_PROCESS
-  mThreadStatusInfo =
-    static_cast<void*>(nsThreadManager::get()->GetCurrentThreadStatusInfo());
-#endif
-
   return NS_OK;
 }
 
 nsresult
 nsThread::PutEvent(nsIRunnable* aEvent, nsNestedEventTarget* aTarget)
 {
   nsCOMPtr<nsIThreadObserver> obs;
 
   {
     MutexAutoLock lock(mLock);
     nsChainedEventQueue* queue = aTarget ? aTarget->mQueue : &mEventsRoot;
     if (!queue || (queue == &mEventsRoot && mEventsAreDoomed)) {
       NS_WARNING("An event was posted to a thread that will never run it (rejected)");
       return NS_ERROR_UNEXPECTED;
     }
-#ifdef MOZ_NUWA_PROCESS
-    {
-      ReentrantMonitorAutoEnter mon(mThreadStatusMonitor);
-      SetWorking();
-#endif // MOZ_NUWA_PROCESS
-      queue->PutEvent(aEvent);
-#ifdef MOZ_NUWA_PROCESS
-    }
-#endif // MOZ_NUWA_PROCESS
+    queue->PutEvent(aEvent);
 
     // Make sure to grab the observer before dropping the lock, otherwise the
     // event that we just placed into the queue could run and eventually delete
     // this nsThread before the calling thread is scheduled again. We would then
     // crash while trying to access a dead nsThread.
     obs = mObserver;
   }
 
@@ -852,25 +832,16 @@ nsThread::ProcessNextEvent(bool aMayWait
       MOZ_ASSERT(ShuttingDown(),
                  "This should only happen when shutting down");
       rv = NS_ERROR_UNEXPECTED;
     }
   }
 
   --mRunningEvent;
 
-#ifdef MOZ_NUWA_PROCESS
-  {
-    ReentrantMonitorAutoEnter mon(mThreadStatusMonitor);
-    if ((!mEvents->GetEvent(false, nullptr)) && (mRunningEvent == 0)) {
-      SetIdle();
-    }
-  }
-#endif // MOZ_NUWA_PROCESS
-
   NOTIFY_EVENT_OBSERVERS(AfterProcessNextEvent,
                          (this, mRunningEvent, *aResult));
 
   if (obs) {
     obs->AfterProcessNextEvent(this, mRunningEvent, *aResult);
   }
 
   if (notifyMainThreadObserver && sMainThreadObserver) {
@@ -1070,32 +1041,16 @@ nsThread::SetMainThreadObserver(nsIThrea
   if (!NS_IsMainThread()) {
     return NS_ERROR_UNEXPECTED;
   }
 
   nsThread::sMainThreadObserver = aObserver;
   return NS_OK;
 }
 
-#ifdef MOZ_NUWA_PROCESS
-void
-nsThread::SetWorking()
-{
-  nsThreadManager::get()->SetThreadIsWorking(
-    static_cast<nsThreadManager::ThreadStatusInfo*>(mThreadStatusInfo), true);
-}
-
-void
-nsThread::SetIdle()
-{
-  nsThreadManager::get()->SetThreadIsWorking(
-    static_cast<nsThreadManager::ThreadStatusInfo*>(mThreadStatusInfo), false);
-}
-#endif
-
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 nsThreadSyncDispatch::Run()
 {
   if (mSyncTask) {
     mResult = mSyncTask->Run();
     mSyncTask = nullptr;
--- a/xpcom/threads/nsThread.h
+++ b/xpcom/threads/nsThread.h
@@ -11,17 +11,16 @@
 #include "nsIThreadInternal.h"
 #include "nsISupportsPriority.h"
 #include "nsEventQueue.h"
 #include "nsThreadUtils.h"
 #include "nsString.h"
 #include "nsTObserverArray.h"
 #include "mozilla/Attributes.h"
 #include "nsAutoPtr.h"
-#include "mozilla/ReentrantMonitor.h"
 
 // A native thread
 class nsThread
   : public nsIThreadInternal
   , public nsISupportsPriority
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
@@ -61,24 +60,16 @@ public:
   void ClearObservers()
   {
     mEventObservers.Clear();
   }
 
   static nsresult
   SetMainThreadObserver(nsIThreadObserver* aObserver);
 
-#ifdef MOZ_NUWA_PROCESS
-  void SetWorking();
-  void SetIdle();
-  mozilla::ReentrantMonitor& ThreadStatusMonitor() {
-    return mThreadStatusMonitor;
-  }
-#endif
-
 protected:
   static nsIThreadObserver* sMainThreadObserver;
 
   class nsChainedEventQueue;
 
   class nsNestedEventTarget;
   friend class nsNestedEventTarget;
 
@@ -186,22 +177,16 @@ protected:
   uint32_t  mStackSize;
 
   struct nsThreadShutdownContext* mShutdownContext;
 
   bool mShutdownRequired;
   // Set to true when events posted to this thread will never run.
   bool mEventsAreDoomed;
   MainThreadFlag mIsMainThread;
-#ifdef MOZ_NUWA_PROCESS
-  mozilla::ReentrantMonitor mThreadStatusMonitor;
-  // The actual type is defined in nsThreadManager.h which is not exposed to
-  // file out of thread module.
-  void* mThreadStatusInfo;
-#endif
 };
 
 //-----------------------------------------------------------------------------
 
 class nsThreadSyncDispatch : public nsRunnable
 {
 public:
   nsThreadSyncDispatch(nsIThread* aOrigin, nsIRunnable* aTask)
--- a/xpcom/threads/nsThreadManager.cpp
+++ b/xpcom/threads/nsThreadManager.cpp
@@ -6,17 +6,16 @@
 
 #include "nsThreadManager.h"
 #include "nsThread.h"
 #include "nsThreadUtils.h"
 #include "nsIClassInfoImpl.h"
 #include "nsTArray.h"
 #include "nsAutoPtr.h"
 #include "mozilla/ThreadLocal.h"
-#include "mozilla/ReentrantMonitor.h"
 #ifdef MOZ_CANARY
 #include <fcntl.h>
 #include <unistd.h>
 #endif
 
 using namespace mozilla;
 
 #ifdef XP_WIN
@@ -43,80 +42,24 @@ NS_SetMainThread()
     }
     sTLSIsMainThread.set(true);
   }
   MOZ_ASSERT(NS_IsMainThread());
 }
 
 typedef nsTArray<nsRefPtr<nsThread>> nsThreadArray;
 
-#ifdef MOZ_NUWA_PROCESS
-class NotifyAllThreadsWereIdle: public nsRunnable
-{
-public:
-
-  NotifyAllThreadsWereIdle(
-    nsTArray<nsRefPtr<nsThreadManager::AllThreadsWereIdleListener>>* aListeners)
-    : mListeners(aListeners)
-  {
-  }
-
-  virtual NS_IMETHODIMP
-  Run() {
-    // Copy listener array, which may be modified during call back.
-    nsTArray<nsRefPtr<nsThreadManager::AllThreadsWereIdleListener>> arr(*mListeners);
-    for (size_t i = 0; i < arr.Length(); i++) {
-      arr[i]->OnAllThreadsWereIdle();
-    }
-    return NS_OK;
-  }
-
-private:
-  // Raw pointer, since it's pointing to a  member of thread manager.
-  nsTArray<nsRefPtr<nsThreadManager::AllThreadsWereIdleListener>>* mListeners;
-};
-
-struct nsThreadManager::ThreadStatusInfo {
-  Atomic<bool> mWorking;
-  Atomic<bool> mWillBeWorking;
-  bool mIgnored;
-  nsThreadManager *mMgr;
-  ThreadStatusInfo(nsThreadManager *aManager)
-    : mWorking(false)
-    , mWillBeWorking(false)
-    , mIgnored(false)
-    , mMgr(aManager)
-  {
-    ReentrantMonitorAutoEnter mon(*(mMgr->mMonitor));
-    mMgr->mThreadStatusInfos.AppendElement(this);
-  }
-  ~ThreadStatusInfo()
-  {
-    ReentrantMonitorAutoEnter mon(*(mMgr->mMonitor));
-    mMgr->mThreadStatusInfos.RemoveElement(this);
-  }
-};
-#endif // MOZ_NUWA_PROCESS
-
 //-----------------------------------------------------------------------------
 
 static void
 ReleaseObject(void* aData)
 {
   static_cast<nsISupports*>(aData)->Release();
 }
 
-#ifdef MOZ_NUWA_PROCESS
-static void
-DeleteThreadStatusInfo(void* aData)
-{
-  delete static_cast<nsThreadManager::ThreadStatusInfo*>(aData);
-}
-#endif
-
 static PLDHashOperator
 AppendAndRemoveThread(PRThread* aKey, nsRefPtr<nsThread>& aThread, void* aArg)
 {
   nsThreadArray* threads = static_cast<nsThreadArray*>(aArg);
   threads->AppendElement(aThread);
   return PL_DHASH_REMOVE;
 }
 
@@ -148,27 +91,17 @@ nsThreadManager::Init()
   if (mInitialized) {
     return NS_OK;
   }
 
   if (PR_NewThreadPrivateIndex(&mCurThreadIndex, ReleaseObject) == PR_FAILURE) {
     return NS_ERROR_FAILURE;
   }
 
-#ifdef MOZ_NUWA_PROCESS
-  if (PR_NewThreadPrivateIndex(&mThreadStatusInfoIndex,
-                               DeleteThreadStatusInfo) == PR_FAILURE) {
-    return NS_ERROR_FAILURE;
-  }
-#endif // MOZ_NUWA_PROCESS
-
   mLock = new Mutex("nsThreadManager.mLock");
-#ifdef MOZ_NUWA_PROCESS
-  mMonitor = MakeUnique<ReentrantMonitor>("nsThreadManager.mMonitor");
-#endif // MOZ_NUWA_PROCESS
 
 #ifdef MOZ_CANARY
   const int flags = O_WRONLY | O_APPEND | O_CREAT | O_NONBLOCK;
   const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
   char* env_var_flag = getenv("MOZ_KILL_CANARIES");
   sCanaryOutputFD =
     env_var_flag ? (env_var_flag[0] ? open(env_var_flag, flags, mode) :
                                       STDERR_FILENO) :
@@ -256,19 +189,16 @@ nsThreadManager::Shutdown()
   mMainThread->ClearObservers();
 
   // Release main thread object.
   mMainThread = nullptr;
   mLock = nullptr;
 
   // Remove the TLS entry for the main thread.
   PR_SetThreadPrivate(mCurThreadIndex, nullptr);
-#ifdef MOZ_NUWA_PROCESS
-  PR_SetThreadPrivate(mThreadStatusInfoIndex, nullptr);
-#endif
 }
 
 void
 nsThreadManager::RegisterCurrentThread(nsThread* aThread)
 {
   MOZ_ASSERT(aThread->GetPRThread() == PR_GetCurrentThread(), "bad aThread");
 
   MutexAutoLock lock(*mLock);
@@ -291,19 +221,16 @@ nsThreadManager::UnregisterCurrentThread
 
   MutexAutoLock lock(*mLock);
 
   --mCurrentNumberOfThreads;
   mThreadsByPRThread.Remove(aThread->GetPRThread());
 
   PR_SetThreadPrivate(mCurThreadIndex, nullptr);
   // Ref-count balanced via ReleaseObject
-#ifdef MOZ_NUWA_PROCESS
-  PR_SetThreadPrivate(mThreadStatusInfoIndex, nullptr);
-#endif
 }
 
 nsThread*
 nsThreadManager::GetCurrentThread()
 {
   // read thread local storage
   void* data = PR_GetThreadPrivate(mCurThreadIndex);
   if (data) {
@@ -318,31 +245,16 @@ nsThreadManager::GetCurrentThread()
   nsRefPtr<nsThread> thread = new nsThread(nsThread::NOT_MAIN_THREAD, 0);
   if (!thread || NS_FAILED(thread->InitCurrentThread())) {
     return nullptr;
   }
 
   return thread.get();  // reference held in TLS
 }
 
-#ifdef MOZ_NUWA_PROCESS
-nsThreadManager::ThreadStatusInfo*
-nsThreadManager::GetCurrentThreadStatusInfo()
-{
-  void* data = PR_GetThreadPrivate(mThreadStatusInfoIndex);
-  if (!data) {
-    ThreadStatusInfo *thrInfo = new ThreadStatusInfo(this);
-    PR_SetThreadPrivate(mThreadStatusInfoIndex, thrInfo);
-    data = thrInfo;
-  }
-
-  return static_cast<ThreadStatusInfo*>(data);
-}
-#endif
-
 NS_IMETHODIMP
 nsThreadManager::NewThread(uint32_t aCreationFlags,
                            uint32_t aStackSize,
                            nsIThread** aResult)
 {
   // No new threads during Shutdown
   if (NS_WARN_IF(!mInitialized)) {
     return NS_ERROR_NOT_INITIALIZED;
@@ -425,132 +337,8 @@ nsThreadManager::GetIsMainThread(bool* a
 }
 
 uint32_t
 nsThreadManager::GetHighestNumberOfThreads()
 {
   MutexAutoLock lock(*mLock);
   return mHighestNumberOfThreads;
 }
-
-#ifdef MOZ_NUWA_PROCESS
-void
-nsThreadManager::SetIgnoreThreadStatus()
-{
-  GetCurrentThreadStatusInfo()->mIgnored = true;
-}
-
-void
-nsThreadManager::SetThreadIdle()
-{
-  SetThreadIsWorking(GetCurrentThreadStatusInfo(), false);
-}
-
-void
-nsThreadManager::SetThreadWorking()
-{
-  SetThreadIsWorking(GetCurrentThreadStatusInfo(), true);
-}
-
-void
-nsThreadManager::SetThreadIsWorking(ThreadStatusInfo* aInfo, bool aIsWorking)
-{
-  aInfo->mWillBeWorking = aIsWorking;
-  if (mThreadsIdledListeners.Length() > 0) {
-
-    // A race condition occurs since we don't want threads to try to enter the
-    // monitor (nsThreadManager::mMonitor) when no one cares about their status.
-    // And thus the race can happen when we put the first listener into
-    // |mThreadsIdledListeners|:
-    //
-    // (1) Thread A wants to dispatch a task to Thread B.
-    // (2) Thread A checks |mThreadsIdledListeners|, and nothing is in the
-    //     list. So Thread A decides not to enter |mMonitor| when updating B's
-    //     status.
-    // (3) Thread A is suspended just before it changed status of B.
-    // (4) A listener is added to |mThreadsIdledListeners|
-    // (5) Now is Thread C's turn to run. Thread C finds there's something in
-    //     |mThreadsIdledListeners|, so it enters |mMonitor| and check all
-    //     thread info structs in |mThreadStatusInfos| while A is in the middle
-    //     of changing B's status.
-    //
-    // Then C may find Thread B is an idle thread (which is not correct, because
-    // A attempted to change B's status prior to C starting to walk throught
-    // |mThreadStatusInfo|), but the fact that thread A is working (thread A
-    // hasn't finished dispatching a task to thread B) can prevent thread C from
-    // firing a bogus notification.
-    //
-    // If the state transition that happens outside the monitor is in the other
-    // direction, the race condition could be:
-    //
-    // (1) Thread D has just finished its jobs and wants to set its status to idle.
-    // (2) Thread D checks |mThreadsIdledListeners|, and nothing is in the list.
-    //     So Thread D decides not to enter |mMonitor|.
-    // (3) Thread D is is suspended before it updates its own status.
-    // (4) A listener is put into |mThreadsIdledListeners|.
-    // (5) Thread C wants to changes status of itself. It checks
-    //     |mThreadsIdledListeners| and finds something inside the list. Thread C
-    //     then enters |mMonitor|, updates its status and checks thread info in
-    //     |mThreadStatusInfos| while D is changing status of itself out of monitor.
-    //
-    // Thread C will find that thread D is working (D actually wants to change its
-    // status to idle before C starting to check), then C returns without firing
-    // any notification. Finding that thread D is working can make our checking
-    // mechanism miss a chance to fire a notification: because thread D thought
-    // there's nothing in |mThreadsIdledListeners| and thus won't check the
-    // |mThreadStatusInfos| after changing the status of itself.
-    //
-    // |mWillBeWorking| can be used to address this problem. We require each
-    // thread to put the value that is going to be set to |mWorking| to
-    // |mWillBeWorking| before the thread decide whether it should enter
-    // |mMonitor| to change status or not. Thus C finds that D is working while
-    // D's |mWillBeWorking| is false, and C realizes that D is just updating and
-    // can treat D as an idle thread.
-    //
-    // It doesn't matter whether D will check thread status after changing its
-    // own status or not. If D checks, which means D will enter the monitor
-    // before updating status, thus D must be blocked until C has finished
-    // dispatching the notification task to main thread, and D will find that main
-    // thread is working and will not fire an additional event. On the other hand,
-    // if D doesn't check |mThreadStatusInfos|, it's still ok, because C has
-    // treated D as an idle thread already.
-
-    bool hasWorkingThread = false;
-    ReentrantMonitorAutoEnter mon(*mMonitor);
-    // Get data structure of thread info.
-    aInfo->mWorking = aIsWorking;
-    for (size_t i = 0; i < mThreadStatusInfos.Length(); i++) {
-      ThreadStatusInfo *info = mThreadStatusInfos[i];
-      if (!info->mIgnored) {
-        if (info->mWorking) {
-          if (info->mWillBeWorking) {
-            hasWorkingThread = true;
-            break;
-          }
-        }
-      }
-    }
-    if (!hasWorkingThread) {
-      nsRefPtr<NotifyAllThreadsWereIdle> runnable =
-        new NotifyAllThreadsWereIdle(&mThreadsIdledListeners);
-      NS_DispatchToMainThread(runnable);
-    }
-  } else {
-    // Update thread info without holding any lock.
-    aInfo->mWorking = aIsWorking;
-  }
-}
-
-
-void
-nsThreadManager::AddAllThreadsWereIdleListener(AllThreadsWereIdleListener *listener)
-{
-  MOZ_ASSERT(GetCurrentThreadStatusInfo()->mWorking);
-  mThreadsIdledListeners.AppendElement(listener);
-}
-
-void
-nsThreadManager::RemoveAllThreadsWereIdleListener(AllThreadsWereIdleListener *listener)
-{
-  mThreadsIdledListeners.RemoveElement(listener);
-}
-
-#endif // MOZ_NUWA_PROCESS
--- a/xpcom/threads/nsThreadManager.h
+++ b/xpcom/threads/nsThreadManager.h
@@ -9,36 +9,19 @@
 
 #include "mozilla/Mutex.h"
 #include "nsIThreadManager.h"
 #include "nsRefPtrHashtable.h"
 #include "nsThread.h"
 
 class nsIRunnable;
 
-namespace mozilla {
-class ReentrantMonitor;
-}
-
 class nsThreadManager : public nsIThreadManager
 {
 public:
-#ifdef MOZ_NUWA_PROCESS
-  struct ThreadStatusInfo;
-  class AllThreadsWereIdleListener {
-  public:
-    NS_INLINE_DECL_REFCOUNTING(AllThreadsWereIdleListener);
-    virtual void OnAllThreadsWereIdle() = 0;
-  protected:
-    virtual ~AllThreadsWereIdleListener()
-    {
-    }
-  };
-#endif // MOZ_NUWA_PROCESS
-
   NS_DECL_ISUPPORTS
   NS_DECL_NSITHREADMANAGER
 
   static nsThreadManager* get()
   {
     static nsThreadManager sInstance;
     return &sInstance;
   }
@@ -66,61 +49,40 @@ public:
   uint32_t GetHighestNumberOfThreads();
 
   // This needs to be public in order to support static instantiation of this
   // class with older compilers (e.g., egcs-2.91.66).
   ~nsThreadManager()
   {
   }
 
-#ifdef MOZ_NUWA_PROCESS
-  void SetIgnoreThreadStatus();
-  void SetThreadIdle();
-  void SetThreadWorking();
-  void SetThreadIsWorking(ThreadStatusInfo* aInfo, bool aIsWorking);
-
-  void AddAllThreadsWereIdleListener(AllThreadsWereIdleListener *listener);
-  void RemoveAllThreadsWereIdleListener(AllThreadsWereIdleListener *listener);
-  ThreadStatusInfo* GetCurrentThreadStatusInfo();
-#endif // MOZ_NUWA_PROCESS
-
 private:
   nsThreadManager()
     : mCurThreadIndex(0)
     , mMainPRThread(nullptr)
     , mLock(nullptr)
     , mInitialized(false)
     , mCurrentNumberOfThreads(1)
     , mHighestNumberOfThreads(1)
-#ifdef MOZ_NUWA_PROCESS
-    , mMonitor(nullptr)
-#endif
   {
   }
 
   nsRefPtrHashtable<nsPtrHashKey<PRThread>, nsThread> mThreadsByPRThread;
   unsigned             mCurThreadIndex;  // thread-local-storage index
   nsRefPtr<nsThread>  mMainThread;
   PRThread*           mMainPRThread;
   // This is a pointer in order to allow creating nsThreadManager from
   // the static context in debug builds.
   nsAutoPtr<mozilla::Mutex> mLock;  // protects tables
   bool                mInitialized;
 
   // The current number of threads
   uint32_t            mCurrentNumberOfThreads;
   // The highest number of threads encountered so far during the session
   uint32_t            mHighestNumberOfThreads;
-
-#ifdef MOZ_NUWA_PROCESS
-  unsigned            mThreadStatusInfoIndex;
-  nsTArray<nsRefPtr<AllThreadsWereIdleListener>> mThreadsIdledListeners;
-  nsTArray<ThreadStatusInfo*> mThreadStatusInfos;
-  mozilla::UniquePtr<mozilla::ReentrantMonitor> mMonitor;
-#endif // MOZ_NUWA_PROCESS
 };
 
 #define NS_THREADMANAGER_CID                       \
 { /* 7a4204c6-e45a-4c37-8ebb-6709a22c917c */       \
   0x7a4204c6,                                      \
   0xe45a,                                          \
   0x4c37,                                          \
   {0x8e, 0xbb, 0x67, 0x09, 0xa2, 0x2c, 0x91, 0x7c} \
--- a/xpcom/threads/nsThreadPool.cpp
+++ b/xpcom/threads/nsThreadPool.cpp
@@ -145,16 +145,17 @@ nsThreadPool::ShutdownThread(nsIThread* 
   nsRefPtr<nsIRunnable> r = NS_NewRunnableMethod(aThread, &nsIThread::Shutdown);
   NS_DispatchToMainThread(r);
 }
 
 NS_IMETHODIMP
 nsThreadPool::Run()
 {
   LOG(("THRD-P(%p) enter\n", this));
+
   mThreadNaming.SetThreadPoolName(mName);
 
   nsCOMPtr<nsIThread> current;
   nsThreadManager::get()->GetCurrentThread(getter_AddRefs(current));
 
   bool shutdownThreadOnExit = false;
   bool exitThread = false;
   bool wasIdle = false;
@@ -202,31 +203,25 @@ nsThreadPool::Run()
         if (exitThread) {
           if (wasIdle) {
             --mIdleCount;
           }
           shutdownThreadOnExit = mThreads.RemoveObject(current);
         } else {
           PRIntervalTime delta = timeout - (now - idleSince);
           LOG(("THRD-P(%p) waiting [%d]\n", this, delta));
-#ifdef MOZ_NUWA_PROCESS
-          nsThreadManager::get()->SetThreadIdle();
-#endif // MOZ_NUWA_PROCESS
           mon.Wait(delta);
         }
       } else if (wasIdle) {
         wasIdle = false;
         --mIdleCount;
       }
     }
     if (event) {
       LOG(("THRD-P(%p) running [%p]\n", this, event.get()));
-#ifdef MOZ_NUWA_PROCESS
-      nsThreadManager::get()->SetThreadWorking();
-#endif // MOZ_NUWA_PROCESS
       event->Run();
     }
   } while (!exitThread);
 
   if (listener) {
     listener->OnThreadShuttingDown();
   }
 
--- a/xpcom/threads/nsTimerImpl.cpp
+++ b/xpcom/threads/nsTimerImpl.cpp
@@ -554,23 +554,16 @@ nsTimerImpl::SetTarget(nsIEventTarget* a
 
 void
 nsTimerImpl::Fire()
 {
   if (mCanceled) {
     return;
   }
 
-#ifdef MOZ_NUWA_PROCESS
-  if (IsNuwaProcess() && IsNuwaReady()) {
-    // A timer event fired after Nuwa frozen can freeze main thread.
-    return;
-  }
-#endif
-
   PROFILER_LABEL("Timer", "Fire",
                  js::ProfileEntry::Category::OTHER);
 
 #ifdef MOZ_TASK_TRACER
   // mTracedTask is an instance of FakeTracedTask created by
   // DispatchTracedTask(). AutoRunFakeTracedTask logs the begin/end time of the
   // timer/FakeTracedTask instance in ctor/dtor.
   mozilla::tasktracer::AutoRunFakeTracedTask runTracedTask(mTracedTask);